changeset 49:1ec0e2823891

Switch to using subrepo copies of qm-dsp, nnls-chroma, vamp-plugin-sdk; update Armadillo version; assume build without external BLAS/LAPACK
author Chris Cannam
date Thu, 13 Jun 2013 10:25:24 +0100
parents 69251e11a913
children 413c4582824a
files .hgignore .hgsub .hgsubstate Makefile.inc Makefile.linux64 Makefile.osx armadillo-2.4.4/CMakeLists.txt armadillo-2.4.4/LICENSE.txt armadillo-2.4.4/README.txt armadillo-2.4.4/build_aux/cmake/InstallFiles/ArmadilloConfig.cmake.in armadillo-2.4.4/build_aux/cmake/InstallFiles/ArmadilloConfigVersion.cmake.in armadillo-2.4.4/build_aux/cmake/Modules/ARMA_CheckMathProto.cmake armadillo-2.4.4/build_aux/cmake/Modules/ARMA_CheckProto.cmake armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindACML.cmake armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindACMLMP.cmake armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindBLAS.cmake armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindCBLAS.cmake armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindCLAPACK.cmake armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindLAPACK.cmake armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindMKL.cmake armadillo-2.4.4/build_aux/doxygen/blank_footer.html armadillo-2.4.4/build_aux/doxygen/doxygen.config armadillo-2.4.4/build_aux/doxygen/main.doxy armadillo-2.4.4/build_aux/rpm/armadillo.spec armadillo-2.4.4/configure armadillo-2.4.4/docs/armadillo_icon.png armadillo-2.4.4/docs/armadillo_nicta_2010.pdf armadillo-2.4.4/docs/index.html armadillo-2.4.4/docs/style.css armadillo-2.4.4/examples/Makefile.cmake armadillo-2.4.4/examples/example1.cpp armadillo-2.4.4/examples/example1_win32/example1_win32.sln armadillo-2.4.4/examples/example1_win32/example1_win32.vcproj armadillo-2.4.4/examples/example2.cpp armadillo-2.4.4/examples/example2_win32/example2_win32.sln armadillo-2.4.4/examples/example2_win32/example2_win32.vcproj armadillo-2.4.4/examples/example_lsq.cpp armadillo-2.4.4/examples/lib_win32/README.txt armadillo-2.4.4/examples/lib_win32/blas_win32_MT.dll armadillo-2.4.4/examples/lib_win32/blas_win32_MT.lib armadillo-2.4.4/examples/lib_win32/lapack_win32_MT.dll armadillo-2.4.4/examples/lib_win32/lapack_win32_MT.lib armadillo-2.4.4/include/armadillo armadillo-2.4.4/include/armadillo_bits/BaseCube_bones.hpp armadillo-2.4.4/include/armadillo_bits/BaseCube_meat.hpp armadillo-2.4.4/include/armadillo_bits/Base_bones.hpp armadillo-2.4.4/include/armadillo_bits/Base_meat.hpp armadillo-2.4.4/include/armadillo_bits/Col_bones.hpp armadillo-2.4.4/include/armadillo_bits/Col_meat.hpp armadillo-2.4.4/include/armadillo_bits/Cube_bones.hpp armadillo-2.4.4/include/armadillo_bits/Cube_meat.hpp armadillo-2.4.4/include/armadillo_bits/GenCube_bones.hpp armadillo-2.4.4/include/armadillo_bits/GenCube_meat.hpp armadillo-2.4.4/include/armadillo_bits/Gen_bones.hpp armadillo-2.4.4/include/armadillo_bits/Gen_meat.hpp armadillo-2.4.4/include/armadillo_bits/GlueCube_bones.hpp armadillo-2.4.4/include/armadillo_bits/GlueCube_meat.hpp armadillo-2.4.4/include/armadillo_bits/Glue_bones.hpp armadillo-2.4.4/include/armadillo_bits/Glue_meat.hpp armadillo-2.4.4/include/armadillo_bits/Mat_bones.hpp armadillo-2.4.4/include/armadillo_bits/Mat_meat.hpp armadillo-2.4.4/include/armadillo_bits/OpCube_bones.hpp armadillo-2.4.4/include/armadillo_bits/OpCube_meat.hpp armadillo-2.4.4/include/armadillo_bits/Op_bones.hpp armadillo-2.4.4/include/armadillo_bits/Op_meat.hpp armadillo-2.4.4/include/armadillo_bits/Proxy.hpp armadillo-2.4.4/include/armadillo_bits/ProxyCube.hpp armadillo-2.4.4/include/armadillo_bits/Row_bones.hpp armadillo-2.4.4/include/armadillo_bits/Row_meat.hpp armadillo-2.4.4/include/armadillo_bits/access.hpp armadillo-2.4.4/include/armadillo_bits/arma_config.hpp armadillo-2.4.4/include/armadillo_bits/arma_ostream_bones.hpp armadillo-2.4.4/include/armadillo_bits/arma_ostream_meat.hpp armadillo-2.4.4/include/armadillo_bits/arma_static_check.hpp armadillo-2.4.4/include/armadillo_bits/arma_version.hpp armadillo-2.4.4/include/armadillo_bits/arrayops_bones.hpp armadillo-2.4.4/include/armadillo_bits/arrayops_meat.hpp armadillo-2.4.4/include/armadillo_bits/atlas_bones.hpp armadillo-2.4.4/include/armadillo_bits/atlas_wrapper.hpp armadillo-2.4.4/include/armadillo_bits/auxlib_bones.hpp armadillo-2.4.4/include/armadillo_bits/auxlib_meat.hpp armadillo-2.4.4/include/armadillo_bits/blas_bones.hpp armadillo-2.4.4/include/armadillo_bits/blas_wrapper.hpp armadillo-2.4.4/include/armadillo_bits/cmath_wrap.hpp armadillo-2.4.4/include/armadillo_bits/compiler_setup.hpp armadillo-2.4.4/include/armadillo_bits/config.hpp.cmake armadillo-2.4.4/include/armadillo_bits/constants.hpp armadillo-2.4.4/include/armadillo_bits/debug.hpp armadillo-2.4.4/include/armadillo_bits/diagmat_proxy.hpp armadillo-2.4.4/include/armadillo_bits/diagview_bones.hpp armadillo-2.4.4/include/armadillo_bits/diagview_meat.hpp armadillo-2.4.4/include/armadillo_bits/diskio_bones.hpp armadillo-2.4.4/include/armadillo_bits/diskio_meat.hpp armadillo-2.4.4/include/armadillo_bits/eGlueCube_bones.hpp armadillo-2.4.4/include/armadillo_bits/eGlueCube_meat.hpp armadillo-2.4.4/include/armadillo_bits/eGlue_bones.hpp armadillo-2.4.4/include/armadillo_bits/eGlue_meat.hpp armadillo-2.4.4/include/armadillo_bits/eOpCube_bones.hpp armadillo-2.4.4/include/armadillo_bits/eOpCube_meat.hpp armadillo-2.4.4/include/armadillo_bits/eOp_bones.hpp armadillo-2.4.4/include/armadillo_bits/eOp_meat.hpp armadillo-2.4.4/include/armadillo_bits/eglue_core_bones.hpp armadillo-2.4.4/include/armadillo_bits/eglue_core_meat.hpp armadillo-2.4.4/include/armadillo_bits/eop_aux.hpp armadillo-2.4.4/include/armadillo_bits/eop_core_bones.hpp armadillo-2.4.4/include/armadillo_bits/eop_core_meat.hpp armadillo-2.4.4/include/armadillo_bits/field_bones.hpp armadillo-2.4.4/include/armadillo_bits/field_meat.hpp armadillo-2.4.4/include/armadillo_bits/fn_accu.hpp armadillo-2.4.4/include/armadillo_bits/fn_as_scalar.hpp armadillo-2.4.4/include/armadillo_bits/fn_chol.hpp armadillo-2.4.4/include/armadillo_bits/fn_conv.hpp armadillo-2.4.4/include/armadillo_bits/fn_conv_to.hpp armadillo-2.4.4/include/armadillo_bits/fn_cor.hpp armadillo-2.4.4/include/armadillo_bits/fn_cov.hpp armadillo-2.4.4/include/armadillo_bits/fn_cross.hpp armadillo-2.4.4/include/armadillo_bits/fn_cumsum.hpp armadillo-2.4.4/include/armadillo_bits/fn_det.hpp armadillo-2.4.4/include/armadillo_bits/fn_diagmat.hpp armadillo-2.4.4/include/armadillo_bits/fn_diagvec.hpp armadillo-2.4.4/include/armadillo_bits/fn_dot.hpp armadillo-2.4.4/include/armadillo_bits/fn_eig.hpp armadillo-2.4.4/include/armadillo_bits/fn_elem.hpp armadillo-2.4.4/include/armadillo_bits/fn_eps.hpp armadillo-2.4.4/include/armadillo_bits/fn_eye.hpp armadillo-2.4.4/include/armadillo_bits/fn_flip.hpp armadillo-2.4.4/include/armadillo_bits/fn_inv.hpp armadillo-2.4.4/include/armadillo_bits/fn_join.hpp armadillo-2.4.4/include/armadillo_bits/fn_kron.hpp armadillo-2.4.4/include/armadillo_bits/fn_log_det.hpp armadillo-2.4.4/include/armadillo_bits/fn_lu.hpp armadillo-2.4.4/include/armadillo_bits/fn_max.hpp armadillo-2.4.4/include/armadillo_bits/fn_mean.hpp armadillo-2.4.4/include/armadillo_bits/fn_median.hpp armadillo-2.4.4/include/armadillo_bits/fn_min.hpp armadillo-2.4.4/include/armadillo_bits/fn_misc.hpp armadillo-2.4.4/include/armadillo_bits/fn_norm.hpp armadillo-2.4.4/include/armadillo_bits/fn_ones.hpp armadillo-2.4.4/include/armadillo_bits/fn_pinv.hpp armadillo-2.4.4/include/armadillo_bits/fn_princomp.hpp armadillo-2.4.4/include/armadillo_bits/fn_prod.hpp armadillo-2.4.4/include/armadillo_bits/fn_qr.hpp armadillo-2.4.4/include/armadillo_bits/fn_randn.hpp armadillo-2.4.4/include/armadillo_bits/fn_randu.hpp armadillo-2.4.4/include/armadillo_bits/fn_rank.hpp armadillo-2.4.4/include/armadillo_bits/fn_repmat.hpp armadillo-2.4.4/include/armadillo_bits/fn_reshape.hpp armadillo-2.4.4/include/armadillo_bits/fn_resize.hpp armadillo-2.4.4/include/armadillo_bits/fn_shuffle.hpp armadillo-2.4.4/include/armadillo_bits/fn_solve.hpp armadillo-2.4.4/include/armadillo_bits/fn_sort.hpp armadillo-2.4.4/include/armadillo_bits/fn_sort_index.hpp armadillo-2.4.4/include/armadillo_bits/fn_stddev.hpp armadillo-2.4.4/include/armadillo_bits/fn_strans.hpp armadillo-2.4.4/include/armadillo_bits/fn_sum.hpp armadillo-2.4.4/include/armadillo_bits/fn_svd.hpp armadillo-2.4.4/include/armadillo_bits/fn_syl_lyap.hpp armadillo-2.4.4/include/armadillo_bits/fn_symmat.hpp armadillo-2.4.4/include/armadillo_bits/fn_toeplitz.hpp armadillo-2.4.4/include/armadillo_bits/fn_trace.hpp armadillo-2.4.4/include/armadillo_bits/fn_trans.hpp armadillo-2.4.4/include/armadillo_bits/fn_trig.hpp armadillo-2.4.4/include/armadillo_bits/fn_trimat.hpp armadillo-2.4.4/include/armadillo_bits/fn_trunc_exp.hpp armadillo-2.4.4/include/armadillo_bits/fn_trunc_log.hpp armadillo-2.4.4/include/armadillo_bits/fn_var.hpp armadillo-2.4.4/include/armadillo_bits/fn_zeros.hpp armadillo-2.4.4/include/armadillo_bits/format_wrap.hpp armadillo-2.4.4/include/armadillo_bits/forward_bones.hpp armadillo-2.4.4/include/armadillo_bits/gemm.hpp armadillo-2.4.4/include/armadillo_bits/gemm_mixed.hpp armadillo-2.4.4/include/armadillo_bits/gemv.hpp armadillo-2.4.4/include/armadillo_bits/glue_conv_bones.hpp armadillo-2.4.4/include/armadillo_bits/glue_conv_meat.hpp armadillo-2.4.4/include/armadillo_bits/glue_cor_bones.hpp armadillo-2.4.4/include/armadillo_bits/glue_cor_meat.hpp armadillo-2.4.4/include/armadillo_bits/glue_cov_bones.hpp armadillo-2.4.4/include/armadillo_bits/glue_cov_meat.hpp armadillo-2.4.4/include/armadillo_bits/glue_cross_bones.hpp armadillo-2.4.4/include/armadillo_bits/glue_cross_meat.hpp armadillo-2.4.4/include/armadillo_bits/glue_join_bones.hpp armadillo-2.4.4/include/armadillo_bits/glue_join_meat.hpp armadillo-2.4.4/include/armadillo_bits/glue_kron_bones.hpp armadillo-2.4.4/include/armadillo_bits/glue_kron_meat.hpp armadillo-2.4.4/include/armadillo_bits/glue_mixed_bones.hpp armadillo-2.4.4/include/armadillo_bits/glue_mixed_meat.hpp armadillo-2.4.4/include/armadillo_bits/glue_relational_bones.hpp armadillo-2.4.4/include/armadillo_bits/glue_relational_meat.hpp armadillo-2.4.4/include/armadillo_bits/glue_solve_bones.hpp armadillo-2.4.4/include/armadillo_bits/glue_solve_meat.hpp armadillo-2.4.4/include/armadillo_bits/glue_times_bones.hpp armadillo-2.4.4/include/armadillo_bits/glue_times_meat.hpp armadillo-2.4.4/include/armadillo_bits/glue_toeplitz_bones.hpp armadillo-2.4.4/include/armadillo_bits/glue_toeplitz_meat.hpp armadillo-2.4.4/include/armadillo_bits/include_atlas.hpp armadillo-2.4.4/include/armadillo_bits/injector_bones.hpp armadillo-2.4.4/include/armadillo_bits/injector_meat.hpp armadillo-2.4.4/include/armadillo_bits/itpp_wrap.hpp armadillo-2.4.4/include/armadillo_bits/lapack_bones.hpp armadillo-2.4.4/include/armadillo_bits/lapack_wrapper.hpp armadillo-2.4.4/include/armadillo_bits/mtGlueCube_bones.hpp armadillo-2.4.4/include/armadillo_bits/mtGlueCube_meat.hpp armadillo-2.4.4/include/armadillo_bits/mtGlue_bones.hpp armadillo-2.4.4/include/armadillo_bits/mtGlue_meat.hpp armadillo-2.4.4/include/armadillo_bits/mtOpCube_bones.hpp armadillo-2.4.4/include/armadillo_bits/mtOpCube_meat.hpp armadillo-2.4.4/include/armadillo_bits/mtOp_bones.hpp armadillo-2.4.4/include/armadillo_bits/mtOp_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_chol_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_chol_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_cor_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_cor_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_cov_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_cov_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_cumsum_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_cumsum_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_cx_scalar_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_cx_scalar_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_diagmat_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_diagmat_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_diagvec_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_diagvec_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_dot_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_dot_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_dotext_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_dotext_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_find_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_find_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_flip_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_flip_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_htrans_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_htrans_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_inv_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_inv_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_max_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_max_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_mean_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_mean_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_median_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_median_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_min_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_min_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_misc_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_misc_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_pinv_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_pinv_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_princomp_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_princomp_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_prod_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_prod_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_relational_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_relational_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_repmat_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_repmat_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_reshape_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_reshape_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_resize_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_resize_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_shuffle_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_shuffle_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_sort_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_sort_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_stddev_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_stddev_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_strans_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_strans_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_sum_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_sum_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_symmat_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_symmat_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_trimat_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_trimat_meat.hpp armadillo-2.4.4/include/armadillo_bits/op_var_bones.hpp armadillo-2.4.4/include/armadillo_bits/op_var_meat.hpp armadillo-2.4.4/include/armadillo_bits/operator_cube_div.hpp armadillo-2.4.4/include/armadillo_bits/operator_cube_minus.hpp armadillo-2.4.4/include/armadillo_bits/operator_cube_plus.hpp armadillo-2.4.4/include/armadillo_bits/operator_cube_relational.hpp armadillo-2.4.4/include/armadillo_bits/operator_cube_schur.hpp armadillo-2.4.4/include/armadillo_bits/operator_cube_times.hpp armadillo-2.4.4/include/armadillo_bits/operator_div.hpp armadillo-2.4.4/include/armadillo_bits/operator_minus.hpp armadillo-2.4.4/include/armadillo_bits/operator_ostream.hpp armadillo-2.4.4/include/armadillo_bits/operator_plus.hpp armadillo-2.4.4/include/armadillo_bits/operator_relational.hpp armadillo-2.4.4/include/armadillo_bits/operator_schur.hpp armadillo-2.4.4/include/armadillo_bits/operator_times.hpp armadillo-2.4.4/include/armadillo_bits/podarray_bones.hpp armadillo-2.4.4/include/armadillo_bits/podarray_meat.hpp armadillo-2.4.4/include/armadillo_bits/promote_type.hpp armadillo-2.4.4/include/armadillo_bits/restrictors.hpp armadillo-2.4.4/include/armadillo_bits/running_stat_bones.hpp armadillo-2.4.4/include/armadillo_bits/running_stat_meat.hpp armadillo-2.4.4/include/armadillo_bits/running_stat_vec_bones.hpp armadillo-2.4.4/include/armadillo_bits/running_stat_vec_meat.hpp armadillo-2.4.4/include/armadillo_bits/span.hpp armadillo-2.4.4/include/armadillo_bits/strip.hpp armadillo-2.4.4/include/armadillo_bits/subview_bones.hpp armadillo-2.4.4/include/armadillo_bits/subview_cube_bones.hpp armadillo-2.4.4/include/armadillo_bits/subview_cube_meat.hpp armadillo-2.4.4/include/armadillo_bits/subview_elem1_bones.hpp armadillo-2.4.4/include/armadillo_bits/subview_elem1_meat.hpp armadillo-2.4.4/include/armadillo_bits/subview_field_bones.hpp armadillo-2.4.4/include/armadillo_bits/subview_field_meat.hpp armadillo-2.4.4/include/armadillo_bits/subview_meat.hpp armadillo-2.4.4/include/armadillo_bits/traits.hpp armadillo-2.4.4/include/armadillo_bits/typedef.hpp armadillo-2.4.4/include/armadillo_bits/typedef_blas_int.hpp armadillo-2.4.4/include/armadillo_bits/typedef_fixed.hpp armadillo-2.4.4/include/armadillo_bits/undefine_conflicts.hpp armadillo-2.4.4/include/armadillo_bits/unwrap.hpp armadillo-2.4.4/include/armadillo_bits/unwrap_cube.hpp armadillo-2.4.4/include/armadillo_bits/upgrade_val.hpp armadillo-2.4.4/include/armadillo_bits/wall_clock_bones.hpp armadillo-2.4.4/include/armadillo_bits/wall_clock_meat.hpp armadillo-2.4.4/include/armadillo_itpp armadillo-2.4.4/index.html armadillo-2.4.4/licenses/GPL.txt armadillo-2.4.4/licenses/LGPL.txt armadillo-2.4.4/src/wrap_libs.cpp armadillo-3.900.4/CMakeLists.txt armadillo-3.900.4/LICENSE.txt armadillo-3.900.4/README.txt armadillo-3.900.4/armadillo_icon.png armadillo-3.900.4/armadillo_nicta_2010.pdf armadillo-3.900.4/build_aux/cmake/InstallFiles/ArmadilloConfig.cmake.in armadillo-3.900.4/build_aux/cmake/InstallFiles/ArmadilloConfigVersion.cmake.in armadillo-3.900.4/build_aux/cmake/Modules/ARMA_CheckMathProto.cmake armadillo-3.900.4/build_aux/cmake/Modules/ARMA_CheckProto.cmake armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindACML.cmake armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindACMLMP.cmake armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindBLAS.cmake armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindCBLAS.cmake armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindCLAPACK.cmake armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindLAPACK.cmake armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindMKL.cmake armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindOpenBLAS.cmake armadillo-3.900.4/build_aux/doxygen/blank_footer.html armadillo-3.900.4/build_aux/doxygen/doxygen.config armadillo-3.900.4/build_aux/doxygen/main.doxy armadillo-3.900.4/build_aux/rpm/armadillo.spec armadillo-3.900.4/configure armadillo-3.900.4/docs.html armadillo-3.900.4/examples/Makefile armadillo-3.900.4/examples/Makefile.cmake armadillo-3.900.4/examples/example1.cpp armadillo-3.900.4/examples/example1_win32/example1_win32.sln armadillo-3.900.4/examples/example1_win32/example1_win32.vcproj armadillo-3.900.4/examples/example2.cpp armadillo-3.900.4/examples/example2_win32/example2_win32.sln armadillo-3.900.4/examples/example2_win32/example2_win32.vcproj armadillo-3.900.4/examples/example_lsq.cpp armadillo-3.900.4/examples/lib_win32/README.txt armadillo-3.900.4/examples/lib_win32/blas_win32_MT.dll armadillo-3.900.4/examples/lib_win32/blas_win32_MT.lib armadillo-3.900.4/examples/lib_win32/lapack_win32_MT.dll armadillo-3.900.4/examples/lib_win32/lapack_win32_MT.lib armadillo-3.900.4/include/armadillo armadillo-3.900.4/include/armadillo_bits/BaseCube_bones.hpp armadillo-3.900.4/include/armadillo_bits/BaseCube_meat.hpp armadillo-3.900.4/include/armadillo_bits/Base_bones.hpp armadillo-3.900.4/include/armadillo_bits/Base_meat.hpp armadillo-3.900.4/include/armadillo_bits/Col_bones.hpp armadillo-3.900.4/include/armadillo_bits/Col_meat.hpp armadillo-3.900.4/include/armadillo_bits/Cube_bones.hpp armadillo-3.900.4/include/armadillo_bits/Cube_meat.hpp armadillo-3.900.4/include/armadillo_bits/GenCube_bones.hpp armadillo-3.900.4/include/armadillo_bits/GenCube_meat.hpp armadillo-3.900.4/include/armadillo_bits/Gen_bones.hpp armadillo-3.900.4/include/armadillo_bits/Gen_meat.hpp armadillo-3.900.4/include/armadillo_bits/GlueCube_bones.hpp armadillo-3.900.4/include/armadillo_bits/GlueCube_meat.hpp armadillo-3.900.4/include/armadillo_bits/Glue_bones.hpp armadillo-3.900.4/include/armadillo_bits/Glue_meat.hpp armadillo-3.900.4/include/armadillo_bits/Mat_bones.hpp armadillo-3.900.4/include/armadillo_bits/Mat_meat.hpp armadillo-3.900.4/include/armadillo_bits/OpCube_bones.hpp armadillo-3.900.4/include/armadillo_bits/OpCube_meat.hpp armadillo-3.900.4/include/armadillo_bits/Op_bones.hpp armadillo-3.900.4/include/armadillo_bits/Op_meat.hpp armadillo-3.900.4/include/armadillo_bits/Proxy.hpp armadillo-3.900.4/include/armadillo_bits/ProxyCube.hpp armadillo-3.900.4/include/armadillo_bits/Row_bones.hpp armadillo-3.900.4/include/armadillo_bits/Row_meat.hpp armadillo-3.900.4/include/armadillo_bits/SpBase_bones.hpp armadillo-3.900.4/include/armadillo_bits/SpBase_meat.hpp armadillo-3.900.4/include/armadillo_bits/SpCol_bones.hpp armadillo-3.900.4/include/armadillo_bits/SpCol_meat.hpp armadillo-3.900.4/include/armadillo_bits/SpGlue_bones.hpp armadillo-3.900.4/include/armadillo_bits/SpGlue_meat.hpp armadillo-3.900.4/include/armadillo_bits/SpMat_bones.hpp armadillo-3.900.4/include/armadillo_bits/SpMat_iterators_meat.hpp armadillo-3.900.4/include/armadillo_bits/SpMat_meat.hpp armadillo-3.900.4/include/armadillo_bits/SpOp_bones.hpp armadillo-3.900.4/include/armadillo_bits/SpOp_meat.hpp armadillo-3.900.4/include/armadillo_bits/SpProxy.hpp armadillo-3.900.4/include/armadillo_bits/SpRow_bones.hpp armadillo-3.900.4/include/armadillo_bits/SpRow_meat.hpp armadillo-3.900.4/include/armadillo_bits/SpSubview_bones.hpp armadillo-3.900.4/include/armadillo_bits/SpSubview_iterators_meat.hpp armadillo-3.900.4/include/armadillo_bits/SpSubview_meat.hpp armadillo-3.900.4/include/armadillo_bits/SpValProxy_bones.hpp armadillo-3.900.4/include/armadillo_bits/SpValProxy_meat.hpp armadillo-3.900.4/include/armadillo_bits/access.hpp armadillo-3.900.4/include/armadillo_bits/arma_config.hpp armadillo-3.900.4/include/armadillo_bits/arma_ostream_bones.hpp armadillo-3.900.4/include/armadillo_bits/arma_ostream_meat.hpp armadillo-3.900.4/include/armadillo_bits/arma_static_check.hpp armadillo-3.900.4/include/armadillo_bits/arma_version.hpp armadillo-3.900.4/include/armadillo_bits/arrayops_bones.hpp armadillo-3.900.4/include/armadillo_bits/arrayops_meat.hpp armadillo-3.900.4/include/armadillo_bits/atlas_bones.hpp armadillo-3.900.4/include/armadillo_bits/atlas_wrapper.hpp armadillo-3.900.4/include/armadillo_bits/auxlib_bones.hpp armadillo-3.900.4/include/armadillo_bits/auxlib_meat.hpp armadillo-3.900.4/include/armadillo_bits/blas_bones.hpp armadillo-3.900.4/include/armadillo_bits/blas_wrapper.hpp armadillo-3.900.4/include/armadillo_bits/cmath_wrap.hpp armadillo-3.900.4/include/armadillo_bits/compiler_setup.hpp armadillo-3.900.4/include/armadillo_bits/compiler_setup_post.hpp armadillo-3.900.4/include/armadillo_bits/cond_rel_bones.hpp armadillo-3.900.4/include/armadillo_bits/cond_rel_meat.hpp armadillo-3.900.4/include/armadillo_bits/config.hpp armadillo-3.900.4/include/armadillo_bits/config.hpp.cmake armadillo-3.900.4/include/armadillo_bits/constants.hpp armadillo-3.900.4/include/armadillo_bits/constants_compat.hpp armadillo-3.900.4/include/armadillo_bits/debug.hpp armadillo-3.900.4/include/armadillo_bits/diagmat_proxy.hpp armadillo-3.900.4/include/armadillo_bits/diagview_bones.hpp armadillo-3.900.4/include/armadillo_bits/diagview_meat.hpp armadillo-3.900.4/include/armadillo_bits/diskio_bones.hpp armadillo-3.900.4/include/armadillo_bits/diskio_meat.hpp armadillo-3.900.4/include/armadillo_bits/eGlueCube_bones.hpp armadillo-3.900.4/include/armadillo_bits/eGlueCube_meat.hpp armadillo-3.900.4/include/armadillo_bits/eGlue_bones.hpp armadillo-3.900.4/include/armadillo_bits/eGlue_meat.hpp armadillo-3.900.4/include/armadillo_bits/eOpCube_bones.hpp armadillo-3.900.4/include/armadillo_bits/eOpCube_meat.hpp armadillo-3.900.4/include/armadillo_bits/eOp_bones.hpp armadillo-3.900.4/include/armadillo_bits/eOp_meat.hpp armadillo-3.900.4/include/armadillo_bits/eglue_core_bones.hpp armadillo-3.900.4/include/armadillo_bits/eglue_core_meat.hpp armadillo-3.900.4/include/armadillo_bits/eop_aux.hpp armadillo-3.900.4/include/armadillo_bits/eop_core_bones.hpp armadillo-3.900.4/include/armadillo_bits/eop_core_meat.hpp armadillo-3.900.4/include/armadillo_bits/fft_engine.hpp armadillo-3.900.4/include/armadillo_bits/field_bones.hpp armadillo-3.900.4/include/armadillo_bits/field_meat.hpp armadillo-3.900.4/include/armadillo_bits/fn_accu.hpp armadillo-3.900.4/include/armadillo_bits/fn_as_scalar.hpp armadillo-3.900.4/include/armadillo_bits/fn_chol.hpp armadillo-3.900.4/include/armadillo_bits/fn_conv.hpp armadillo-3.900.4/include/armadillo_bits/fn_conv_to.hpp armadillo-3.900.4/include/armadillo_bits/fn_cor.hpp armadillo-3.900.4/include/armadillo_bits/fn_cov.hpp armadillo-3.900.4/include/armadillo_bits/fn_cross.hpp armadillo-3.900.4/include/armadillo_bits/fn_cumsum.hpp armadillo-3.900.4/include/armadillo_bits/fn_det.hpp armadillo-3.900.4/include/armadillo_bits/fn_diagmat.hpp armadillo-3.900.4/include/armadillo_bits/fn_diagvec.hpp armadillo-3.900.4/include/armadillo_bits/fn_dot.hpp armadillo-3.900.4/include/armadillo_bits/fn_eig.hpp armadillo-3.900.4/include/armadillo_bits/fn_elem.hpp armadillo-3.900.4/include/armadillo_bits/fn_eps.hpp armadillo-3.900.4/include/armadillo_bits/fn_eye.hpp armadillo-3.900.4/include/armadillo_bits/fn_fft.hpp armadillo-3.900.4/include/armadillo_bits/fn_flip.hpp armadillo-3.900.4/include/armadillo_bits/fn_hist.hpp armadillo-3.900.4/include/armadillo_bits/fn_histc.hpp armadillo-3.900.4/include/armadillo_bits/fn_inv.hpp armadillo-3.900.4/include/armadillo_bits/fn_join.hpp armadillo-3.900.4/include/armadillo_bits/fn_kron.hpp armadillo-3.900.4/include/armadillo_bits/fn_log_det.hpp armadillo-3.900.4/include/armadillo_bits/fn_lu.hpp armadillo-3.900.4/include/armadillo_bits/fn_max.hpp armadillo-3.900.4/include/armadillo_bits/fn_mean.hpp armadillo-3.900.4/include/armadillo_bits/fn_median.hpp armadillo-3.900.4/include/armadillo_bits/fn_min.hpp armadillo-3.900.4/include/armadillo_bits/fn_misc.hpp armadillo-3.900.4/include/armadillo_bits/fn_n_unique.hpp armadillo-3.900.4/include/armadillo_bits/fn_norm.hpp armadillo-3.900.4/include/armadillo_bits/fn_ones.hpp armadillo-3.900.4/include/armadillo_bits/fn_pinv.hpp armadillo-3.900.4/include/armadillo_bits/fn_princomp.hpp armadillo-3.900.4/include/armadillo_bits/fn_prod.hpp armadillo-3.900.4/include/armadillo_bits/fn_qr.hpp armadillo-3.900.4/include/armadillo_bits/fn_randn.hpp armadillo-3.900.4/include/armadillo_bits/fn_randu.hpp armadillo-3.900.4/include/armadillo_bits/fn_rank.hpp armadillo-3.900.4/include/armadillo_bits/fn_repmat.hpp armadillo-3.900.4/include/armadillo_bits/fn_reshape.hpp armadillo-3.900.4/include/armadillo_bits/fn_resize.hpp armadillo-3.900.4/include/armadillo_bits/fn_shuffle.hpp armadillo-3.900.4/include/armadillo_bits/fn_solve.hpp armadillo-3.900.4/include/armadillo_bits/fn_sort.hpp armadillo-3.900.4/include/armadillo_bits/fn_sort_index.hpp armadillo-3.900.4/include/armadillo_bits/fn_speye.hpp armadillo-3.900.4/include/armadillo_bits/fn_spones.hpp armadillo-3.900.4/include/armadillo_bits/fn_sprandn.hpp armadillo-3.900.4/include/armadillo_bits/fn_sprandu.hpp armadillo-3.900.4/include/armadillo_bits/fn_stddev.hpp armadillo-3.900.4/include/armadillo_bits/fn_strans.hpp armadillo-3.900.4/include/armadillo_bits/fn_sum.hpp armadillo-3.900.4/include/armadillo_bits/fn_svd.hpp armadillo-3.900.4/include/armadillo_bits/fn_syl_lyap.hpp armadillo-3.900.4/include/armadillo_bits/fn_symmat.hpp armadillo-3.900.4/include/armadillo_bits/fn_toeplitz.hpp armadillo-3.900.4/include/armadillo_bits/fn_trace.hpp armadillo-3.900.4/include/armadillo_bits/fn_trans.hpp armadillo-3.900.4/include/armadillo_bits/fn_trig.hpp armadillo-3.900.4/include/armadillo_bits/fn_trimat.hpp armadillo-3.900.4/include/armadillo_bits/fn_trunc_exp.hpp armadillo-3.900.4/include/armadillo_bits/fn_trunc_log.hpp armadillo-3.900.4/include/armadillo_bits/fn_unique.hpp armadillo-3.900.4/include/armadillo_bits/fn_var.hpp armadillo-3.900.4/include/armadillo_bits/fn_zeros.hpp armadillo-3.900.4/include/armadillo_bits/format_wrap.hpp armadillo-3.900.4/include/armadillo_bits/forward_bones.hpp armadillo-3.900.4/include/armadillo_bits/gemm.hpp armadillo-3.900.4/include/armadillo_bits/gemm_mixed.hpp armadillo-3.900.4/include/armadillo_bits/gemv.hpp armadillo-3.900.4/include/armadillo_bits/glue_conv_bones.hpp armadillo-3.900.4/include/armadillo_bits/glue_conv_meat.hpp armadillo-3.900.4/include/armadillo_bits/glue_cor_bones.hpp armadillo-3.900.4/include/armadillo_bits/glue_cor_meat.hpp armadillo-3.900.4/include/armadillo_bits/glue_cov_bones.hpp armadillo-3.900.4/include/armadillo_bits/glue_cov_meat.hpp armadillo-3.900.4/include/armadillo_bits/glue_cross_bones.hpp armadillo-3.900.4/include/armadillo_bits/glue_cross_meat.hpp armadillo-3.900.4/include/armadillo_bits/glue_hist_bones.hpp armadillo-3.900.4/include/armadillo_bits/glue_hist_meat.hpp armadillo-3.900.4/include/armadillo_bits/glue_histc_bones.hpp armadillo-3.900.4/include/armadillo_bits/glue_histc_meat.hpp armadillo-3.900.4/include/armadillo_bits/glue_join_bones.hpp armadillo-3.900.4/include/armadillo_bits/glue_join_meat.hpp armadillo-3.900.4/include/armadillo_bits/glue_kron_bones.hpp armadillo-3.900.4/include/armadillo_bits/glue_kron_meat.hpp armadillo-3.900.4/include/armadillo_bits/glue_mixed_bones.hpp armadillo-3.900.4/include/armadillo_bits/glue_mixed_meat.hpp armadillo-3.900.4/include/armadillo_bits/glue_relational_bones.hpp armadillo-3.900.4/include/armadillo_bits/glue_relational_meat.hpp armadillo-3.900.4/include/armadillo_bits/glue_solve_bones.hpp armadillo-3.900.4/include/armadillo_bits/glue_solve_meat.hpp armadillo-3.900.4/include/armadillo_bits/glue_times_bones.hpp armadillo-3.900.4/include/armadillo_bits/glue_times_meat.hpp armadillo-3.900.4/include/armadillo_bits/glue_toeplitz_bones.hpp armadillo-3.900.4/include/armadillo_bits/glue_toeplitz_meat.hpp armadillo-3.900.4/include/armadillo_bits/hdf5_misc.hpp armadillo-3.900.4/include/armadillo_bits/include_atlas.hpp armadillo-3.900.4/include/armadillo_bits/injector_bones.hpp armadillo-3.900.4/include/armadillo_bits/injector_meat.hpp armadillo-3.900.4/include/armadillo_bits/lapack_bones.hpp armadillo-3.900.4/include/armadillo_bits/lapack_wrapper.hpp armadillo-3.900.4/include/armadillo_bits/memory.hpp armadillo-3.900.4/include/armadillo_bits/mtGlueCube_bones.hpp armadillo-3.900.4/include/armadillo_bits/mtGlueCube_meat.hpp armadillo-3.900.4/include/armadillo_bits/mtGlue_bones.hpp armadillo-3.900.4/include/armadillo_bits/mtGlue_meat.hpp armadillo-3.900.4/include/armadillo_bits/mtOpCube_bones.hpp armadillo-3.900.4/include/armadillo_bits/mtOpCube_meat.hpp armadillo-3.900.4/include/armadillo_bits/mtOp_bones.hpp armadillo-3.900.4/include/armadillo_bits/mtOp_meat.hpp armadillo-3.900.4/include/armadillo_bits/mtSpOp_bones.hpp armadillo-3.900.4/include/armadillo_bits/mtSpOp_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_chol_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_chol_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_cor_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_cor_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_cov_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_cov_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_cumsum_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_cumsum_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_cx_scalar_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_cx_scalar_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_diagmat_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_diagmat_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_diagvec_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_diagvec_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_dot_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_dot_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_dotext_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_dotext_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_fft_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_fft_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_find_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_find_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_flip_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_flip_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_hist_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_hist_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_htrans_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_htrans_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_inv_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_inv_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_max_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_max_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_mean_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_mean_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_median_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_median_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_min_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_min_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_misc_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_misc_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_pinv_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_pinv_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_princomp_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_princomp_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_prod_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_prod_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_relational_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_relational_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_repmat_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_repmat_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_reshape_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_reshape_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_resize_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_resize_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_shuffle_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_shuffle_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_sort_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_sort_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_stddev_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_stddev_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_strans_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_strans_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_sum_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_sum_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_symmat_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_symmat_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_toeplitz_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_toeplitz_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_trimat_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_trimat_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_unique_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_unique_meat.hpp armadillo-3.900.4/include/armadillo_bits/op_var_bones.hpp armadillo-3.900.4/include/armadillo_bits/op_var_meat.hpp armadillo-3.900.4/include/armadillo_bits/operator_cube_div.hpp armadillo-3.900.4/include/armadillo_bits/operator_cube_minus.hpp armadillo-3.900.4/include/armadillo_bits/operator_cube_plus.hpp armadillo-3.900.4/include/armadillo_bits/operator_cube_relational.hpp armadillo-3.900.4/include/armadillo_bits/operator_cube_schur.hpp armadillo-3.900.4/include/armadillo_bits/operator_cube_times.hpp armadillo-3.900.4/include/armadillo_bits/operator_div.hpp armadillo-3.900.4/include/armadillo_bits/operator_minus.hpp armadillo-3.900.4/include/armadillo_bits/operator_ostream.hpp armadillo-3.900.4/include/armadillo_bits/operator_plus.hpp armadillo-3.900.4/include/armadillo_bits/operator_relational.hpp armadillo-3.900.4/include/armadillo_bits/operator_schur.hpp armadillo-3.900.4/include/armadillo_bits/operator_times.hpp armadillo-3.900.4/include/armadillo_bits/podarray_bones.hpp armadillo-3.900.4/include/armadillo_bits/podarray_meat.hpp armadillo-3.900.4/include/armadillo_bits/promote_type.hpp armadillo-3.900.4/include/armadillo_bits/restrictors.hpp armadillo-3.900.4/include/armadillo_bits/running_stat_bones.hpp armadillo-3.900.4/include/armadillo_bits/running_stat_meat.hpp armadillo-3.900.4/include/armadillo_bits/running_stat_vec_bones.hpp armadillo-3.900.4/include/armadillo_bits/running_stat_vec_meat.hpp armadillo-3.900.4/include/armadillo_bits/span.hpp armadillo-3.900.4/include/armadillo_bits/spglue_minus_bones.hpp armadillo-3.900.4/include/armadillo_bits/spglue_minus_meat.hpp armadillo-3.900.4/include/armadillo_bits/spglue_plus_bones.hpp armadillo-3.900.4/include/armadillo_bits/spglue_plus_meat.hpp armadillo-3.900.4/include/armadillo_bits/spglue_times_bones.hpp armadillo-3.900.4/include/armadillo_bits/spglue_times_meat.hpp armadillo-3.900.4/include/armadillo_bits/spop_htrans_bones.hpp armadillo-3.900.4/include/armadillo_bits/spop_htrans_meat.hpp armadillo-3.900.4/include/armadillo_bits/spop_max_bones.hpp armadillo-3.900.4/include/armadillo_bits/spop_max_meat.hpp armadillo-3.900.4/include/armadillo_bits/spop_mean_bones.hpp armadillo-3.900.4/include/armadillo_bits/spop_mean_meat.hpp armadillo-3.900.4/include/armadillo_bits/spop_min_bones.hpp armadillo-3.900.4/include/armadillo_bits/spop_min_meat.hpp armadillo-3.900.4/include/armadillo_bits/spop_misc_bones.hpp armadillo-3.900.4/include/armadillo_bits/spop_misc_meat.hpp armadillo-3.900.4/include/armadillo_bits/spop_strans_bones.hpp armadillo-3.900.4/include/armadillo_bits/spop_strans_meat.hpp armadillo-3.900.4/include/armadillo_bits/spop_sum_bones.hpp armadillo-3.900.4/include/armadillo_bits/spop_sum_meat.hpp armadillo-3.900.4/include/armadillo_bits/spop_var_bones.hpp armadillo-3.900.4/include/armadillo_bits/spop_var_meat.hpp armadillo-3.900.4/include/armadillo_bits/strip.hpp armadillo-3.900.4/include/armadillo_bits/subview_bones.hpp armadillo-3.900.4/include/armadillo_bits/subview_cube_bones.hpp armadillo-3.900.4/include/armadillo_bits/subview_cube_meat.hpp armadillo-3.900.4/include/armadillo_bits/subview_each_bones.hpp armadillo-3.900.4/include/armadillo_bits/subview_each_meat.hpp armadillo-3.900.4/include/armadillo_bits/subview_elem1_bones.hpp armadillo-3.900.4/include/armadillo_bits/subview_elem1_meat.hpp armadillo-3.900.4/include/armadillo_bits/subview_elem2_bones.hpp armadillo-3.900.4/include/armadillo_bits/subview_elem2_meat.hpp armadillo-3.900.4/include/armadillo_bits/subview_field_bones.hpp armadillo-3.900.4/include/armadillo_bits/subview_field_meat.hpp armadillo-3.900.4/include/armadillo_bits/subview_meat.hpp armadillo-3.900.4/include/armadillo_bits/traits.hpp armadillo-3.900.4/include/armadillo_bits/typedef.hpp armadillo-3.900.4/include/armadillo_bits/typedef_blas_int.hpp armadillo-3.900.4/include/armadillo_bits/typedef_fixed.hpp armadillo-3.900.4/include/armadillo_bits/undefine_conflicts.hpp armadillo-3.900.4/include/armadillo_bits/unwrap.hpp armadillo-3.900.4/include/armadillo_bits/unwrap_cube.hpp armadillo-3.900.4/include/armadillo_bits/unwrap_spmat.hpp armadillo-3.900.4/include/armadillo_bits/upgrade_val.hpp armadillo-3.900.4/include/armadillo_bits/wall_clock_bones.hpp armadillo-3.900.4/include/armadillo_bits/wall_clock_meat.hpp armadillo-3.900.4/include/armadillo_bits/xvec_htrans_bones.hpp armadillo-3.900.4/include/armadillo_bits/xvec_htrans_meat.hpp armadillo-3.900.4/index.html armadillo-3.900.4/rcpp_armadillo_csda_2013.pdf armadillo-3.900.4/src/wrap_libs.cpp lib_win32/README.txt lib_win32/blas_win32_MT.dll lib_win32/blas_win32_MT.lib lib_win32/lapack_win32_MT.dll lib_win32/lapack_win32_MT.lib segmentino/Makefile.linux64 segmentino/Makefile_ORIGINAL.osx segmentino/Segmentino.cpp segmentino/SongParts/BeatTrackerData.cpp segmentino/SongParts/BeatTrackerData.h segmentino/build/general/Makefile.inc segmentino/build/linux/amd64/atlas/atlas_buildinfo.h segmentino/build/linux/amd64/atlas/atlas_cNCmm.h segmentino/build/linux/amd64/atlas/atlas_cacheedge.h segmentino/build/linux/amd64/atlas/atlas_cmv.h segmentino/build/linux/amd64/atlas/atlas_cmvN.h segmentino/build/linux/amd64/atlas/atlas_cmvS.h segmentino/build/linux/amd64/atlas/atlas_cmvT.h segmentino/build/linux/amd64/atlas/atlas_cr1.h segmentino/build/linux/amd64/atlas/atlas_csNKB.h segmentino/build/linux/amd64/atlas/atlas_csysinfo.h segmentino/build/linux/amd64/atlas/atlas_ctrsmXover.h segmentino/build/linux/amd64/atlas/atlas_dNCmm.h segmentino/build/linux/amd64/atlas/atlas_dmv.h segmentino/build/linux/amd64/atlas/atlas_dmvN.h segmentino/build/linux/amd64/atlas/atlas_dmvS.h segmentino/build/linux/amd64/atlas/atlas_dmvT.h segmentino/build/linux/amd64/atlas/atlas_dr1.h segmentino/build/linux/amd64/atlas/atlas_dsysinfo.h segmentino/build/linux/amd64/atlas/atlas_dtrsmXover.h segmentino/build/linux/amd64/atlas/atlas_sNCmm.h segmentino/build/linux/amd64/atlas/atlas_smv.h segmentino/build/linux/amd64/atlas/atlas_smvN.h segmentino/build/linux/amd64/atlas/atlas_smvS.h segmentino/build/linux/amd64/atlas/atlas_smvT.h segmentino/build/linux/amd64/atlas/atlas_sr1.h segmentino/build/linux/amd64/atlas/atlas_ssysinfo.h segmentino/build/linux/amd64/atlas/atlas_strsmXover.h segmentino/build/linux/amd64/atlas/atlas_trsmNB.h segmentino/build/linux/amd64/atlas/atlas_type.h segmentino/build/linux/amd64/atlas/atlas_zNCmm.h segmentino/build/linux/amd64/atlas/atlas_zdNKB.h segmentino/build/linux/amd64/atlas/atlas_zmv.h segmentino/build/linux/amd64/atlas/atlas_zmvN.h segmentino/build/linux/amd64/atlas/atlas_zmvS.h segmentino/build/linux/amd64/atlas/atlas_zmvT.h segmentino/build/linux/amd64/atlas/atlas_zr1.h segmentino/build/linux/amd64/atlas/atlas_zsysinfo.h segmentino/build/linux/amd64/atlas/atlas_ztrsmXover.h segmentino/build/linux/amd64/atlas/cXover.h segmentino/build/linux/amd64/atlas/cmm.h segmentino/build/linux/amd64/atlas/dXover.h segmentino/build/linux/amd64/atlas/dmm.h segmentino/build/linux/amd64/atlas/sXover.h segmentino/build/linux/amd64/atlas/smm.h segmentino/build/linux/amd64/atlas/zXover.h segmentino/build/linux/amd64/atlas/zmm.h segmentino/build/linux/amd64/cblas.h segmentino/build/linux/amd64/clapack.h segmentino/build/linux/amd64/libatlas.a segmentino/build/linux/amd64/libcblas.a segmentino/build/linux/amd64/libf77blas.a segmentino/build/linux/amd64/liblapack.a segmentino/build/mingw32/atlas.lib segmentino/build/mingw32/cblas.lib segmentino/build/mingw32/f77blas.lib segmentino/build/mingw32/g2cstubs.c segmentino/build/mingw32/g2cstubs.lib segmentino/build/mingw32/lapack.lib segmentino/g2cstubs.c
diffstat 777 files changed, 119261 insertions(+), 86179 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,6 @@
+syntax: glob
+*.o
+*~
+*.so
+*.dll
+*.dylib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgsub	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,3 @@
+vamp-plugin-sdk = http://code.soundsoftware.ac.uk/hg/vamp-plugin-sdk
+qm-dsp = http://code.soundsoftware.ac.uk/hg/qm-dsp
+nnls-chroma = http://code.soundsoftware.ac.uk/hg/nnls-chroma
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgsubstate	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,3 @@
+2cd99c0810f28abe2fcbf2c50a29fee20b910ae4 nnls-chroma
+37449f085a4c4d1c8a0178378aeb088781219c32 qm-dsp
+ef49ec7b71be7fc2addc1d18bd82e68bda94bf47 vamp-plugin-sdk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile.inc	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,38 @@
+
+PLUGIN_EXT	?= .so
+PLUGIN	?= segmentino$(PLUGIN_EXT)
+CXX	?= g++
+CC	?= gcc
+
+CFLAGS		:= $(CFLAGS) -I. -Ivamp-plugin-sdk -Iqm-dsp -Iarmadillo-3.900.4/include
+CXXFLAGS	:= $(CXXFLAGS) $(CFLAGS)
+LDFLAGS		:= $(LDFLAGS)
+
+HEADERS := segmentino/Segmentino.h
+
+SOURCES := segmentino/Segmentino.cpp \
+           segmentino/libmain.cpp \
+           nnls-chroma/chromamethods.cpp \
+           nnls-chroma/nnls.c \
+	   vamp-plugin-sdk/src/vamp-sdk/PluginAdapter.cpp \
+	   vamp-plugin-sdk/src/vamp-sdk/RealTime.cpp \
+	   qm-dsp/dsp/onsets/DetectionFunction.cpp \
+	   qm-dsp/dsp/onsets/PeakPicking.cpp \
+	   qm-dsp/dsp/transforms/FFT.cpp \
+	   qm-dsp/dsp/rateconversion/Decimator.cpp \
+	   qm-dsp/dsp/tempotracking/TempoTrackV2.cpp \
+	   qm-dsp/dsp/tempotracking/DownBeat.cpp \
+	   qm-dsp/dsp/phasevocoder/PhaseVocoder.cpp \
+	   qm-dsp/maths/MathUtilities.cpp
+
+OBJECTS := $(SOURCES:.cpp=.o)
+OBJECTS := $(OBJECTS:.c=.o)
+
+$(PLUGIN):	$(OBJECTS)
+		$(CXX) -o $@ $^ $(LDFLAGS)
+
+clean:		
+		rm $(OBJECTS)
+
+distclean:	clean
+		rm $(PLUGIN)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile.linux64	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,13 @@
+
+#CFLAGS := -O3 -fPIC -ftree-vectorize -I../armadillo-2.4.4/include -I../../vamp-plugin-sdk -I../../qm-dsp
+
+CFLAGS := -Wall -g -fPIC 
+
+CXXFLAGS  := $(CFLAGS)
+
+LDFLAGS	  := -shared -Wl,-Bsymbolic -Wl,--version-script=segmentino/vamp-plugin.map
+
+PLUGIN_EXT   := .so
+
+include Makefile.inc
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile.osx	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,11 @@
+
+CFLAGS := -O3 -ftree-vectorize -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk -arch i386 -arch x86_64 -I../vamp-plugin-sdk -I/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/Headers/ -DUSE_PTHREADS
+
+CXXFLAGS  := $(CFLAGS)
+
+LDFLAGS	  := -isysroot /Developer/SDKs/MacOSX10.7.sdk -arch i386 -arch x86_64 -dynamiclib -framework Accelerate -lpthread -install_name qm-vamp-plugins.dylib
+
+PLUGIN_EXT   := .dylib
+
+include build/general/Makefile.inc
+
--- a/armadillo-2.4.4/CMakeLists.txt	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,378 +0,0 @@
-
-# Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-# Copyright (C) 2008-2011 Conrad Sanderson
-# Copyright (C)      2011 Clement Creusot
-# 
-# This file is part of the Armadillo C++ library.
-# It is provided without any warranty of fitness
-# for any purpose. You can redistribute this file
-# and/or modify it under the terms of the GNU
-# Lesser General Public License (LGPL) as published
-# by the Free Software Foundation, either version 3
-# of the License or (at your option) any later version.
-# (see http://www.opensource.org/licenses for more info)
-
-cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
-
-set(ARMA_MAJOR 2)
-set(ARMA_MINOR 4)
-set(ARMA_PATCH 4)
-
-message(STATUS "Configuring Armadillo ${ARMA_MAJOR}.${ARMA_MINOR}.${ARMA_PATCH}")
-
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/build_aux/cmake/Modules/")
-
-include(CheckIncludeFileCXX)
-include(CheckLibraryExists)
-include(FindBoost)
-include(ARMA_CheckProto)
-include(ARMA_CheckMathProto)
-
-project(armadillo CXX)
-
-#CMAKE_REQUIRED_FLAGS = string of compile command line flags
-#CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-#CMAKE_REQUIRED_LIBRARIES = list of libraries to link
-
-
-set(ARMA_USE_LAPACK  false)
-set(ARMA_USE_BLAS    false)
-set(ARMA_USE_ATLAS   false)
-set(ARMA_USE_BOOST   false)
-set(ARMA_USE_WRAPPER true )
-
-
-if(WIN32)
-  message(STATUS "")
-  message(STATUS "WARNING:")
-  message(STATUS "Automatic installation is currently not available for this platform.")
-  message(STATUS "Please use the manual installation, as described in the README.txt file.")
-  message(STATUS "You can also use the 'include' folder directly, but you may want to edit")
-  message(STATUS "'include/armadillo_bits/config.hpp' if you have LAPACK installed.")
-  message(STATUS "")
-endif()
-
-
-
-#
-# Find LAPACK and BLAS libraries, or their optimised versions
-#
-
-if(APPLE)
-  set(ARMA_OS macos)
-  
-  set(ARMA_USE_LAPACK true)
-  set(ARMA_USE_BLAS   true)
-  
-  # Under MacOS, the current version of ARMA_FindCLAPACK can get confused between
-  # two incompatible versions of "clapack.h" (one provided by the system and one
-  # provided by ATLAS).  As such, use of ATLAS under MacOS is disabled for now.
-  
-else()
-  set(ARMA_OS unix)
-  
-  include(ARMA_FindMKL)
-  include(ARMA_FindACMLMP)
-  include(ARMA_FindACML)
-  
-  message(STATUS "MKL_FOUND     = ${MKL_FOUND}")
-  message(STATUS "ACMLMP_FOUND  = ${ACMLMP_FOUND}")
-  message(STATUS "ACML_FOUND    = ${ACML_FOUND}")
-  
-  if(MKL_FOUND OR ACMLMP_FOUND OR ACML_FOUND)
-    
-    set(ARMA_USE_BLAS true)
-    set(ARMA_USE_LAPACK true)
-    
-    message(STATUS "*** If the MKL or ACML libraries are installed in a non-standard location,")
-    message(STATUS "*** make sure the run-time linker can find them.")
-    message(STATUS "*** On Linux systems this can be done by editing /etc/ld.so.conf")
-    message(STATUS "*** or modifying the LD_LIBRARY_PATH environment variable.")
-    message(STATUS "*** On systems with SELinux enabled (e.g. Fedora, RHEL),")
-    message(STATUS "*** you may need to change the SELinux type of all MKL/ACML libraries")
-    message(STATUS "*** to fix permission problems that may occur during run-time.")
-    message(STATUS "*** See README.txt for more information")
-    
-  else()
-    
-    include(ARMA_FindLAPACK)
-    include(ARMA_FindBLAS)
-    include(ARMA_FindCLAPACK)
-    include(ARMA_FindCBLAS)
-    
-    message(STATUS "LAPACK_FOUND  = ${LAPACK_FOUND}")
-    message(STATUS "BLAS_FOUND    = ${BLAS_FOUND}")
-    message(STATUS "CLAPACK_FOUND = ${CLAPACK_FOUND}")
-    message(STATUS "CBLAS_FOUND   = ${CBLAS_FOUND}")
-    
-    if(LAPACK_FOUND)
-      set(ARMA_USE_LAPACK true)
-    endif()
-    
-    if(BLAS_FOUND)
-      set(ARMA_USE_BLAS true)
-    endif()
-    
-    if(CLAPACK_FOUND AND CBLAS_FOUND)
-      message(STATUS "CLAPACK_INCLUDE_DIR = ${CLAPACK_INCLUDE_DIR}")
-      message(STATUS "CBLAS_INCLUDE_DIR   = ${CBLAS_INCLUDE_DIR}")
-      if(${CLAPACK_INCLUDE_DIR} STREQUAL ${CBLAS_INCLUDE_DIR})
-        set(ARMA_USE_ATLAS true)
-        set(ARMA_ATLAS_INCLUDE_DIR ${CLAPACK_INCLUDE_DIR})
-      endif()
-    endif()
-    
-  endif()
-  
-endif()
-
-
-if(MKL_FOUND OR ACMLMP_FOUND OR ACML_FOUND)
-  
-  if(MKL_FOUND)
-    set(ARMA_LIBS ${ARMA_LIBS} ${MKL_LIBRARIES})
-    
-    if(ACMLMP_FOUND OR ACML_FOUND)
-      message(STATUS "*** Intel MKL as well as AMD ACML libraries were found.")
-      message(STATUS "*** Using only the MKL library to avoid linking conflicts.")
-      message(STATUS "*** If you wish to use ACML instead, please link manually with")
-      message(STATUS "*** acml or acml_mp instead of the armadillo run-time component.")
-      message(STATUS "*** Alternatively, remove MKL from your system and rerun")
-      message(STATUS "*** Armadillo's configuration using ./configure") 
-    endif()
-    
-  else()
-    
-    if(ACMLMP_FOUND)
-      set(ARMA_LIBS ${ARMA_LIBS} ${ACMLMP_LIBRARIES})
-      
-      message(STATUS "*** Both single-core and multi-core ACML libraries were found.")
-      message(STATUS "*** Using only the multi-core library to avoid linking conflicts.")
-    else()
-      if(ACML_FOUND)
-        set(ARMA_LIBS ${ARMA_LIBS} ${ACML_LIBRARIES})
-      endif()
-    endif()
-    
-  endif()
-  
-else()
-  
-  if(ARMA_USE_BLAS STREQUAL true)
-    set(ARMA_LIBS ${ARMA_LIBS} ${BLAS_LIBRARIES})
-  endif()
-  
-  if(ARMA_USE_LAPACK STREQUAL true)
-    set(ARMA_LIBS ${ARMA_LIBS} ${LAPACK_LIBRARIES})
-  endif()
-  
-  if(ARMA_USE_ATLAS STREQUAL true)
-    set(ARMA_LIBS ${ARMA_LIBS} ${CBLAS_LIBRARIES})
-    set(ARMA_LIBS ${ARMA_LIBS} ${CLAPACK_LIBRARIES})
-  endif()
-  
-endif()
-
-
-if(APPLE)
-  set(ARMA_LIBS ${ARMA_LIBS} "-framework Accelerate")  # or "-framework accelerate" ?
-  message(STATUS "MacOS X detected. Added '-framework Accelerate' to compiler flags")
-endif()
-
-message(STATUS "*** ")
-message(STATUS "*** The Armadillo run-time library component will be an alias for the following libraries:")
-message(STATUS "*** ARMA_LIBS = ${ARMA_LIBS}")
-message(STATUS "*** ")
-
-find_package(Boost)
-
-if(Boost_FOUND)
-  
-  message(STATUS "Boost_MAJOR_VERSION = ${Boost_MAJOR_VERSION}")
-  message(STATUS "Boost_MINOR_VERSION = ${Boost_MINOR_VERSION}")
-  
-  if(Boost_MAJOR_VERSION GREATER 0)
-    if(Boost_MINOR_VERSION GREATER 33)
-      set(ARMA_USE_BOOST true)
-      message(STATUS "Boost_INCLUDE_DIR = ${Boost_INCLUDE_DIR}")
-    endif()
-  endif()
-  
-endif()
-
-if(ARMA_USE_BOOST STREQUAL false)
-  message(STATUS "Boost libraries either not found or their version is too low (version 1.34 or later is good).")
-  message(STATUS "( It's possible that CMake didn't find the particular version of Boost you may have. )")
-  message(STATUS "( If that's the case, please edit include/armadillo_bits/config.hpp manually. )")
-endif()
-
-
-# If Boost libraries were found, explicitly check if Boost's date_time library is also present.
-# This is due to the non-standard packaging of Boost libraries on Debian and Ubuntu systems,
-# where certain individual Boost libraries are packaged separately.
-
-if(ARMA_USE_BOOST STREQUAL true)
-  set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${Boost_INCLUDE_DIR})
-  CHECK_INCLUDE_FILE_CXX("boost/date_time/posix_time/posix_time.hpp" ARMA_USE_BOOST_DATE)
-endif()
-
-ARMA_CHECK_MATH_PROTO("isfinite" "std" "cmath"  ARMA_HAVE_STD_ISFINITE)
-ARMA_CHECK_MATH_PROTO("isinf"    "std" "cmath"  ARMA_HAVE_STD_ISINF)
-ARMA_CHECK_MATH_PROTO("isnan"    "std" "cmath"  ARMA_HAVE_STD_ISNAN)
-ARMA_CHECK_MATH_PROTO("log1p"    ""    "cmath"  ARMA_HAVE_LOG1P)
-
-ARMA_CHECK_PROTO("snprintf"     "std" "cstdio"     ARMA_HAVE_STD_SNPRINTF)
-ARMA_CHECK_PROTO("gettimeofday" ""    "sys/time.h" ARMA_HAVE_GETTIMEOFDAY)
-
-
-message(STATUS "Generating 'include/armadillo_bits/config.hpp'")
-configure_file(include/armadillo_bits/config.hpp.cmake include/armadillo_bits/config.hpp)
-
-message(STATUS "Generating 'examples/Makefile'")
-configure_file(examples/Makefile.cmake examples/Makefile)
-
-
-if(ARMA_USE_BOOST STREQUAL true)
-  include_directories(include ${Boost_INCLUDE_DIR})
-else()
-  include_directories(include)
-endif()
-
-
-## For any library that is not in a default location,
-## embed its path into the Armadillo runtime library.
-## Examples of default locations are "/lib", "/usr/lib",
-## or as specified in "/etc/ld.so.conf".
-##
-## Path embedding is not recommended unless you know
-## what you're doing.  It might be better to add the
-## path to the "/etc/ld.so.conf" file and then run "ldconfig".
-##
-#set(CMAKE_SKIP_BUILD_RPATH  FALSE)
-#set(CMAKE_BUILD_WITH_INSTALL_RPATH  FALSE)
-#set(CMAKE_INSTALL_RPATH_USE_LINK_PATH  TRUE)
-
-
-add_library( armadillo SHARED src/wrap_libs )
-target_link_libraries( armadillo ${ARMA_LIBS} )
-
-set_target_properties(armadillo PROPERTIES VERSION ${ARMA_MAJOR}.${ARMA_MINOR}.${ARMA_PATCH} SOVERSION 2)
-
-
-
-################################################################################
-# INSTALL CONFIGURATION
-
-
-# As Red Hat Enterprise Linux (and related systems such as Fedora)
-# does not search /usr/local/lib by default, we need to place the
-# library in either /usr/lib or /usr/lib64
-
-if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
-  set(CMAKE_INSTALL_PREFIX "/usr")
-endif()
-
-# Allow for the "lib" directory to be specified on the command line
-if(NOT INSTALL_LIB_DIR)
-  set(INSTALL_LIB_DIR "lib")
-  if(UNIX AND NOT APPLE)   # I don't know how Mac OS handles 64 bit systems
-    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
-      message(STATUS "Detected 64 bit system")
-        if(IS_DIRECTORY "${CMAKE_INSTALL_PREFIX}/lib64")
-          unset(INSTALL_LIB_DIR)
-          set(INSTALL_LIB_DIR "lib64")
-        endif()
-    endif()
-  endif()
-endif()
-
-# Allow for the "include" directory to be specified on the command line
-
-if(NOT INSTALL_INCLUDE_DIR)
-  set(INSTALL_INCLUDE_DIR "include")
-endif()
-
-# We use data dir to store files shared with other programs 
-# like the ArmadilloConfig.cmake file.
-if(NOT INSTALL_DATA_DIR)
-  set(INSTALL_DATA_DIR "share")
-endif()
-
-# Make relative paths absolute so we can write them in Config.cmake files
-foreach(p LIB INCLUDE DATA)
-  set(var INSTALL_${p}_DIR)
-  if(NOT IS_ABSOLUTE "${${var}}")
-    set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
-  endif()
-endforeach()
-
-message(STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}")
-message(STATUS "INSTALL_LIB_DIR      = ${INSTALL_LIB_DIR}"     )
-message(STATUS "INSTALL_INCLUDE_DIR  = ${INSTALL_INCLUDE_DIR}" )
-message(STATUS "INSTALL_DATA_DIR     = ${INSTALL_DATA_DIR}"    )
-
-
-# Note that the trailing / character in "include/" is critical
-
-install(DIRECTORY include/ DESTINATION ${INSTALL_INCLUDE_DIR}
-PATTERN ".svn" EXCLUDE
-PATTERN "*.cmake" EXCLUDE
-PATTERN "*~" EXCLUDE
-PATTERN "*orig" EXCLUDE
-)
-
-install(TARGETS armadillo 
-  DESTINATION ${INSTALL_LIB_DIR}
-  EXPORT ArmadilloLibraryDepends)
-
-# Export the package for use from the build-tree
-# (this registers the build-tree with a global CMake-registry)
-if(CMAKE_VERSION VERSION_GREATER "2.7")
- export(PACKAGE armadillo)
-endif()
-
-## LOCAL FILES
-# Create ArmadilloConfig.cmake file for the use from the build tree
-set(ARMADILLO_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}")
-set(ARMADILLO_LIB_DIR      "${PROJECT_BINARY_DIR}")
-set(ARMADILLO_CMAKE_DIR    "${PROJECT_BINARY_DIR}")
-
-
-message(STATUS "Generating '${PROJECT_BINARY_DIR}/ArmadilloConfig.cmake'")
-# copy/change config and configVersion file (modify only the @xyz@ variables)
-configure_file(build_aux/cmake/InstallFiles/ArmadilloConfig.cmake.in
-  "${PROJECT_BINARY_DIR}/ArmadilloConfig.cmake" @ONLY)
-
-message(STATUS "Generating '${PROJECT_BINARY_DIR}/ArmadilloConfigVersion.cmake'")
-configure_file(build_aux/cmake/InstallFiles/ArmadilloConfigVersion.cmake.in
-  "${PROJECT_BINARY_DIR}/ArmadilloConfigVersion.cmake" @ONLY)
-
-
-# Install the export set for use with the install-tree
-install(EXPORT ArmadilloLibraryDepends DESTINATION
-  "${INSTALL_DATA_DIR}/Armadillo/CMake"
-  COMPONENT dev)
-
-
-## GLOBAL INSTALL FILES
-# Create ArmadilloConfig.cmake file for the use from the install tree
-# and install it
-set(ARMADILLO_INCLUDE_DIRS "${INSTALL_INCLUDE_DIR}")
-set(ARMADILLO_LIB_DIR      "${INSTALL_LIB_DIR}")
-set(ARMADILLO_CMAKE_DIR    "${INSTALL_DATA_DIR}/Armadillo/CMake")
-
-
-message(STATUS "Generating '${PROJECT_BINARY_DIR}/InstallFiles/ArmadilloConfig.cmake'")
-# copy/change config and configVersion file (modify only the @xyz@ variables)
-configure_file(build_aux/cmake/InstallFiles/ArmadilloConfig.cmake.in
-  "${PROJECT_BINARY_DIR}/InstallFiles/ArmadilloConfig.cmake" @ONLY)
-
-message(STATUS "Generating '${PROJECT_BINARY_DIR}/InstallFiles/ArmadilloConfigVersion.cmake'")
-configure_file(build_aux/cmake/InstallFiles/ArmadilloConfigVersion.cmake.in
-  "${PROJECT_BINARY_DIR}/InstallFiles/ArmadilloConfigVersion.cmake" @ONLY)
-
-# Install files to be found by cmake users with find_package()
-install(FILES
-  "${PROJECT_BINARY_DIR}/InstallFiles/ArmadilloConfig.cmake"
-  "${PROJECT_BINARY_DIR}/InstallFiles/ArmadilloConfigVersion.cmake"
-  DESTINATION "${ARMADILLO_CMAKE_DIR}" COMPONENT dev)
--- a/armadillo-2.4.4/LICENSE.txt	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-The Armadillo C++ library is provided without any warranty
-of fitness for any purpose. You can redistribute the library
-and/or modify it under the terms of the GNU Lesser General
-Public License (LGPL) as published by the Free Software
-Foundation, either version 3 of the License or (at your option)
-any later version.
-
-Note that the LGPL v3 is formulated as an extension/modification 
-of the GPL v3 license, providing additional permissions.
-For example, programs that use Armadillo can be distributed under 
-a different license, provided some conditions are met.
-
-A copy of the LGPL and GPL licenses is provided in the 
-"licenses/LGPL.txt" and "licenses/GPL.txt" files, respectively.
-
-More info: http://www.opensource.org/licenses
--- a/armadillo-2.4.4/README.txt	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,455 +0,0 @@
-=== Contents ===
-
-1: Introduction
-   1.1: Citation Details
-
-2: Installation
-   2.0: Preliminaries
-   2.1: Manual Installation
-   2.2: Installation on Linux / Mac OS X
-   2.3: Installation on MS Windows
-
-3: Compiling Programs and Linking
-   3.0: Examples
-   3.1: Compiling & Linking on Linux / Mac OS X
-   3.2: Compiling & Linking on MS Windows
-
-4: Caveats
-   4.0: Support for ATLAS
-   4.1: Support for ACML and Intel MKL
-
-5: Documentation / Reference Manual
-
-6: FAQs and Bug Reports
-
-7: Credits
-
-8: License
-
-
-
-
-=== 1.0: Introduction ===
-
-Armadillo is a C++ linear algebra library (matrix maths)
-aiming towards a good balance between speed and ease of use.
-Integer, floating point and complex numbers are supported,
-as well as a subset of trigonometric and statistics functions.
-Various matrix decompositions are provided through optional
-integration with LAPACK or high-performance LAPACK-compatible
-libraries.
-
-A delayed evaluation approach is employed (during compile time)
-to combine several operations into one and reduce (or eliminate)
-the need for temporaries. This is accomplished through recursive
-templates and template meta-programming.
-
-This library is useful if C++ has been decided as the language
-of choice (due to speed and/or integration capabilities),
-rather than another language like Matlab or Octave.
-It is distributed under a license that is useful in both
-open-source and proprietary contexts.
-
-Armadillo is primarily developed at NICTA (Australia),
-with contributions from around the world.
-More information about NICTA can be obtained from:
-  http://nicta.com.au
-
-
-
-=== 1.1: Citation Details ===
-
-If you use Armadillo in your research and/or software,
-we would appreciate a citation to the following tech report:
-
-  Conrad Sanderson.
-  Armadillo: An Open Source C++ Linear Algebra Library for
-  Fast Prototyping and Computationally Intensive Experiments.
-  Technical Report, NICTA, 2010.
-
-
-
-=== 2.0: Installation: Preliminaries ===
-
-Armadillo makes extensive use of template meta-programming,
-recursive templates and template based function overloading.
-As such, C++ compilers which do not fully implement the C++
-standard may not work correctly.
-
-The functionality of Armadillo is partly dependent on other
-libraries -- mainly LAPACK and BLAS. Armadillo can work without
-LAPACK or BLAS, but its functionality will be reduced.
-In particular, basic functionality will be available
-(eg. matrix addition and multiplication), but things like
-eigen decomposition or will not be. Matrix multiplication
-(mainly for big matrices) may not be as fast.
-
-For manual installation on all systems, see section 2.1.
-
-For installation on Linux / Mac OS X systems, see section 2.2.
-The Linux installation is also likely to work on other Unix-like
-systems, such as FreeBSD, NetBSD, OpenBSD, Solaris, CygWin, etc.
-
-For installation on MS Windows, see section 2.3.
-
-
-
-=== 2.1: Manual Installation ===
-
-The manual installation is comprised of 3 steps:
-
-* Step 1:
-  Copy the entire "include" folder to a convenient location
-  and tell your compiler to use that location for header files
-  (in addition to the locations it uses already).
-  Alternatively, you can use the "include" folder directly.
-
-* Step 2:
-  Modify "include/armadillo_bits/config.hpp" to indicate 
-  which libraries are currently available on your system.
-  For example, if you have LAPACK and BLAS present, 
-  uncomment the following lines:
-  
-  #define ARMA_USE_LAPACK
-  #define ARMA_USE_BLAS
-
-* Step 3:
-  If you have LAPACK and/or BLAS present, configure your 
-  compiler to link with these libraries. 
-  
-  You can also link with the the equivalent of LAPACK and BLAS,
-  eg. Intel's MKL or AMD's ACML. Under Mac OS X, link using 
-  -framework Accelerate
-
-
-
-=== 2.2: Installation on Linux / Mac OS X ===
-
-If you have installed Armadillo using an RPM or DEB package,
-you don't need to do anything else. Otherwise read on.
-
-You can use the manual installation process as described in
-section 2.1, or the following CMake based automatic installation.
-
-* Step 1:
-  If CMake is not already be present on your system, download
-  it from http://www.cmake.org
-
-  On major Linux systems (such as Fedora, Ubuntu, Debian, etc),
-  cmake is available as a pre-built package, though it may need
-  to be explicitly installed (using a tool such as PackageKit,
-  yum, rpm, apt, aptitude, etc).
-  
-* Step 2:
-  If you have BLAS and/or LAPACK, install them before installing
-  Armadillo. Under Mac OS X this is not necessary.
-  
-  On Linux systems it is recommended that the following libraries
-  are present: LAPACK, BLAS, ATLAS and Boost. LAPACK and BLAS are
-  the most important. If you have ATLAS and Boost, it's also necessary
-  to have the corresponding header files installed.
-  
-* Step 3:
-  Open a shell (command line), change into the directory that was
-  created by unpacking the armadillo archive, and type the following
-  commands:
-  
-  cmake .
-  make 
-  
-  The full stop separated from "cmake" by a space is important.
-  CMake will figure out what other libraries are currently installed
-  and will modify Armadillo's configuration correspondingly.
-  CMake will also generate a run-time armadillo library, which is a 
-  combined alias for all the relevant libraries present on your system
-  (eg. BLAS, LAPACK and ATLAS).
-  
-  If you need to re-run cmake, it's a good idea to first delete the
-  "CMakeCache.txt" file (not "CMakeLists.txt").
-  
-* Step 4:
-  If you have access to root/administrator/superuser privileges,
-  first enable the privileges (eg. through "su" or "sudo")
-  and then type the following command:
-  
-  make install
-  
-  If you don't have root/administrator/superuser privileges, 
-  type the following command:
-  
-  make install DESTDIR=my_usr_dir
-  
-  where "my_usr_dir" is for storing C++ headers and library files.
-  Make sure your C++ compiler is configured to use the sub-directories
-  present within this directory.
-
-
-
-=== 2.3: Installation on MS Windows ===
-
-There is currently no automatic installation for Windows.
-Please use the manual installation process described in section 2.1.
-
-Pre-compiled 32 bit versions of BLAS and LAPACK libraries
-for Windows are provided in the "examples/libs_win32" folder.
-If the provided libraries don't work for you, see section 3.2.
-
-
-
-=== 3.0: Compiling Programs and Linking: Examples ===
-
-The "examples" directory contains several quick example programs
-that use the Armadillo library. If Armadillo was installed manually
-(ie. according to section 2.1), you will also need to explicitly
-link your programs with the libraries that were specified in
-"include/armadillo_bits/config.hpp".
-
-"example1.cpp" may require the BLAS library or its equivalent.
-"example2.cpp" requires the LAPACK library or its equivalent
-(eg. the Accelerate framework on Mac OS X).
-
-You may get errors at compile or run time if BLAS and/or LAPACK
-functions are not available.
-
-NOTE: As Armadillo is a template library, we recommended that
-      optimisation is enabled during compilation. For example,
-      for the GCC compiler use -O1 or -O2
-
-
-
-=== 3.1: Compiling & Linking on Linux / Mac OS X ===
-
-Please see "examples/Makefile", which may may need to be configured
-for your system. If Armadillo header files were installed in a
-non-standard location, you will need to modify "examples/Makefile"
-to tell the compiler where they are.
-
-In general, programs which use Armadillo are compiled along these lines:
-  g++ example1.cpp -o example1 -O1 -larmadillo
-
-(you may also need to specify the include directory via the -I switch)
-
-If you get linking errors, or if Armadillo was installed manually
-and you specified that LAPACK and BLAS are available, you will
-need to explicitly link with LAPACK and BLAS (or their equivalents),
-for example:
-  g++ example1.cpp -o example1 -O1 -llapack -lblas
-
-(you may also need to specify the library directory via the -L switch)
-
-Notes:
-
-  * under most Linux systems, using "-llapack -lblas" should be enough;
-    however, on Ubuntu and Debian you may need to add "-lgfortran"
-    
-  * under Mac OS X, try "-framework Accelerate" or "-llapack -lblas"
-    (the Accelerate option is usually the fastest)
-    
-  * under the Sun Studio compiler, try "-library=sunperf"
-
-
-
-=== 3.2: Compiling & Linking on MS Windows ===
-
-As a courtesy, we've provided pre-compiled 32 bit versions of
-LAPACK and BLAS for Windows, as well as MSVC project files to
-compile example1.cpp and example2.cpp.
-The project files are stored in the following folders:
-  examples/example1_win32
-  examples/example2_win32
-
-The LAPACK and BLAS libraries are stored in:
-  examples/lib_win32
-
-Note that on 64 bit systems (such as Windows 7), dedicated
-64 bit versions of BLAS and LAPACK are considerably faster.
-
-If you're not using MSVC, or you're getting "use of LAPACK needs
-to be enabled" messages, you will need to manually modify 
-"include/armadillo_bits/config.hpp" to enable the use of
-LAPACK and BLAS. Please see section 2.1 for more information.
-
-The MSCV project files were tested on 32 bit Windows XP with
-Visual C++ 2008 (Express Edition). You may need to make adaptations
-for 64 bit systems, later versions of Windows and/or the compiler.
-For example, you may have to enable or disable the ARMA_BLAS_LONG
-and ARMA_BLAS_UNDERSCORE macros in "armadillo_bits/config.hpp".
-
-To preserve our sanity, we (Armadillo developers) don't use Windows
-on a regular basis, and as such can't help you with the adaptations.
-For best results we recommend using an operating system that's
-more reliable and more suitable for heavy duty work,
-such as Linux or Mac OS X. 
-
-The pre-compiled versions of LAPACK and BLAS were downloaded from:
-  http://www.fi.muni.cz/~xsvobod2/misc/lapack/
-
-If the provided libraries don't work for you, try these versions:
-  http://www.stanford.edu/~vkl/code/libs.html
-  http://icl.cs.utk.edu/lapack-for-windows/lapack/
-  http://software.intel.com/en-us/intel-mkl/
-  http://www.amd.com/acml
-
-(the MKL and ACML libraries are generally the fastest)
-
-
-If you want to compile BLAS and LAPACK yourself, you can find
-the original sources at:
-  http://www.netlib.org/blas/
-  http://www.netlib.org/lapack/
-
-If you encounter issues with the MS Visual C++ compiler,
-the following high-quality compilers are useful alternatives:
-
-  * GCC (part MinGW)
-    http://www.mingw.org/
-
-  * GCC (part of CygWin)
-    http://www.cygwin.com/
-
-  * Intel's C++ compiler
-    http://software.intel.com/en-us/intel-compilers/
-
-If using GCC, you'll need version 4.0 or better.
-If using Intel's C++ compiler, you'll need version 10.0 or better.
-
-
-
-=== 4.0: Caveats: Support for ATLAS ===
-
-Armadillo can use the ATLAS library for faster versions of
-certain LAPACK and BLAS functions. Not all ATLAS functions are
-currently used, and as such LAPACK should still be installed.
-
-The minimum recommended version of ATLAS is 3.8.
-Old versions (eg. 3.6) can produce incorrect results
-as well as corrupting memory, leading to random crashes.
-
-Users of Ubuntu and Debian based systems should explicitly
-check that version 3.6 is not installed. It's better to
-remove the old version and use the standard LAPACK library.
-
-
-
-=== 4.1: Caveats: Support for ACML and Intel MKL ===
-
-Armadillo can work with AMD Core Math Library and Intel's
-Math Kernel Library (MKL), however there are several caveats.
-
-On Linux systems, ACML and MKL are typically installed in a
-non-standard location, which can cause problems during linking.
-
-Before installing Armadillo, the system should know where the ACML or MKL
-libraries are located (eg., "/opt/intel/mkl/10.2.2.025/lib/em64t/").
-This can be achieved by setting the LD_LIBRARY_PATH environment variable,
-or, for a more permanent solution, adding the location of the libraries
-to "/etc/ld.so.conf". It may also be possible to store a text file 
-with the location in the "/etc/ld.so.conf.d" directory.
-In the latter two cases you will need to run "ldconfig" afterwards.
-
-The default installations of ACML 4.4.0 and MKL 10.2.2.025 are known 
-to have issues with SELinux, which is turned on by default in Fedora
-(and possibly RHEL). The problem may manifest itself during run-time,
-where the run-time linker reports permission problems.
-It is possible to work around the problem by applying an appropriate
-SELinux type to all ACML and MKL libraries.
-
-If you have ACML or MKL installed and they are persistently giving
-you problems during linking, you can disable the support for them
-by editing the "CMakeLists.txt" file, deleting "CMakeCache.txt" and
-re-running the CMake based installation. Specifically, comment out
-the lines containing:
-  INCLUDE(ARMA_FindMKL)
-  INCLUDE(ARMA_FindACMLMP)
-  INCLUDE(ARMA_FindACML)
-
-
-
-=== 5: Documentation / Reference Manual ===
-
-A reference manual (user documentation) is available at
-http://arma.sourceforge.net or in the "docs" directory.
-Use a web browser to open the "docs/index.html" file.
-
-The user documentation explains how to use Armadillo's
-classes and functions, with snippets of example code.
-
-
-
-=== 6: FAQs and Bug Reports ===
-
-Answers to Frequently Asked Questions (FAQs) can be found at:
-  http://arma.sourceforge.net/faq.html
-
-This library has gone through extensive testing and
-has been successfully used in production environments.
-However, as with almost all software, it's impossible
-to guarantee 100% correct functionality.
-
-If you find a bug in the library (or the documentation),
-we are interested in hearing about it. Please make a small
-self-contained program which exposes the bug and send the
-program source (as well as the bug description) to the 
-developers. The developers' contact details are available at:
-  http://arma.sourceforge.net/contact.html
-
-
-
-=== 7: Credits ===
-
-Main sponsoring organisation:
-- NICTA
-  http://nicta.com.au
-
-Main developers:
-- Conrad Sanderson - http://itee.uq.edu.au/~conrad/
-- Ian Cullinan
-- Dimitrios Bouzas
-- Stanislav Funiak
-
-Contributors:
-- Eric R. Anderson
-- Benoît Bayol
-- Salim Bcoin
-- Justin Bedo
-- Darius Braziunas
-- Ted Campbell
-- Clement Creusot
-- Ryan Curtin
-- Chris Davey
-- Dirk Eddelbuettel
-- Romain Francois
-- Piotr Gawron
-- Charles Gretton
-- Benjamin Herzog
-- Edmund Highcock
-- Kshitij Kulshreshtha
-- Oka Kurniawan
-- Simen Kvaal
-- David Lawrence
-- Carlos Mendes
-- Artem Novikov
-- Martin Orlob
-- Ken Panici
-- Adam PiÄ…tyszek
-- Jayden Platell
-- Vikas Reddy
-- Ola Rinta-Koski
-- James Sanders
-- Alexander Scherbatey
-- Gerhard Schreiber
-- Shane Stainsby
-- Petter Strandmark
-- Paul Torfs
-- Simon Urbanek
-- Arnold Wiliem
-- Yong Kang Wong
-
-
-
-=== 8: License ===
-
-Please see the "LICENSE.txt" file.
-
-
-
--- a/armadillo-2.4.4/build_aux/cmake/InstallFiles/ArmadilloConfig.cmake.in	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-# - Config file for the Armadillo package
-# It defines the following variables
-#  ARMADILLO_INCLUDE_DIRS - include directories for Armadillo
-#  ARMADILLO_LIBRARY_DIRS - library directories for Armadillo (normally not used!)
-#  ARMADILLO_LIBRARIES    - libraries to link against
-
-# Tell the user project where to find our headers and libraries
-set(ARMADILLO_INCLUDE_DIRS "@ARMADILLO_INCLUDE_DIRS@")
-set(ARMADILLO_LIBRARY_DIRS "@ARMADILLO_LIB_DIR@")
-
-# Our library dependencies (contains definitions for IMPORTED targets)
-include("@ARMADILLO_CMAKE_DIR@/ArmadilloLibraryDepends.cmake")
-
-# These are IMPORTED targets created by ArmadilloLibraryDepends.cmake
-set(ARMADILLO_LIBRARIES armadillo)
-
--- a/armadillo-2.4.4/build_aux/cmake/InstallFiles/ArmadilloConfigVersion.cmake.in	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-set(PACKAGE_VERSION "@ARMADILLO_VERSION@")
-
-# Check whether the requested PACKAGE_FIND_VERSION is compatible
-if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
-  set(PACKAGE_VERSION_COMPATIBLE FALSE)
-else()
-  set(PACKAGE_VERSION_COMPATIBLE TRUE)
-  if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
-    set(PACKAGE_VERSION_EXACT TRUE)
-  endif()
-endif()
--- a/armadillo-2.4.4/build_aux/cmake/Modules/ARMA_CheckMathProto.cmake	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-# - Check if the prototype for a single argument math function exists.
-# ARMA_CHECK_MATH_PROTO (FUNCTION NAMESPACE HEADER VARIABLE)
-#
-#  FUNCTION  - the name of the single argument math function you are looking for
-#  NAMESPACE - the name of the namespace
-#  HEADER    - the header(s) where the prototype should be declared
-#  VARIABLE  - variable to store the result
-#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
-#
-#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
-#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-#  CMAKE_REQUIRED_INCLUDES = list of include directories
-
-# adapted from "CheckPrototypeExists.cmake"
-# ( http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/CheckPrototypeExists.cmake )
-# on 2009-06-19 by Conrad Sanderson (conradsand at ieee dot org)
-
-# original copyright for "CheckPrototypeExists.cmake":
-#
-# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
-#
-# Redistribution and use is allowed according to the terms of the BSD license.
-# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
-
-
-INCLUDE(CheckCXXSourceCompiles)
-
-MACRO (ARMA_CHECK_MATH_PROTO _SYMBOL _NAMESPACE _HEADER _RESULT)
-
-  SET(_INCLUDE_FILES)
-
-  FOREACH (it ${_HEADER})
-    SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
-  ENDFOREACH (it)
-   
-  SET(_TMP_SOURCE_CODE "
-${_INCLUDE_FILES}
-int main()
-  {
-  #if !defined(${_SYMBOL})
-    int i = (${_NAMESPACE}::${_SYMBOL})(1.0);
-  #endif
-  return 0;
-  }
-")
-
-  CHECK_CXX_SOURCE_COMPILES("${_TMP_SOURCE_CODE}" ${_RESULT})
-
-ENDMACRO (ARMA_CHECK_MATH_PROTO _SYMBOL _NAMESPACE _HEADER _RESULT)
--- a/armadillo-2.4.4/build_aux/cmake/Modules/ARMA_CheckProto.cmake	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-# - Check if the prototype for a non-overloaded function exists in a specified namespace.
-# ARMA_CHECK_PROTO (FUNCTION NAMESPACE HEADER VARIABLE)
-#
-#  FUNCTION  - the name of the function you are looking for
-#  NAMESPACE - the name of the namespace
-#  HEADER    - the header(s) where the prototype should be declared
-#  VARIABLE  - variable to store the result
-#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
-#
-#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
-#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-#  CMAKE_REQUIRED_INCLUDES = list of include directories
-
-# adapted from "CheckPrototypeExists.cmake"
-# ( http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/CheckPrototypeExists.cmake )
-# on 2009-06-19 by Conrad Sanderson (conradsand at ieee dot org)
-
-# original copyright for "CheckPrototypeExists.cmake":
-# 
-# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
-#
-# Redistribution and use is allowed according to the terms of the BSD license.
-# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
-
-
-INCLUDE(CheckCXXSourceCompiles)
-
-MACRO (ARMA_CHECK_PROTO _SYMBOL _NAMESPACE _HEADER _RESULT)
-
-  SET(_INCLUDE_FILES)
-
-  FOREACH (it ${_HEADER})
-    SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
-  ENDFOREACH (it)
-
-  SET(_TMP_SOURCE_CODE "
-${_INCLUDE_FILES}
-int
-main()
-  {
-  #if !defined(${_SYMBOL})
-    int i = sizeof(&(${_NAMESPACE}::${_SYMBOL}));
-  #endif
-  return 0;
-  }
-")
-
-  CHECK_CXX_SOURCE_COMPILES("${_TMP_SOURCE_CODE}" ${_RESULT})
-
-ENDMACRO (ARMA_CHECK_PROTO _SYMBOL _NAMESPACE _HEADER _RESULT)
-
--- a/armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindACML.cmake	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-# - Find AMD's ACML library (no includes) which provides optimised BLAS and LAPACK functions
-# This module defines
-#  ACML_LIBRARIES, the libraries needed to use ACML.
-#  ACML_FOUND, If false, do not try to use ACML.
-# also defined, but not for general use are
-#  ACML_LIBRARY, where to find the ACML library.
-
-SET(ACML_NAMES ${ACML_NAMES} acml)
-FIND_LIBRARY(ACML_LIBRARY
-  NAMES ${ACML_NAMES}
-  PATHS /usr/lib64 /usr/lib /usr/*/lib64 /usr/*/lib /usr/*/gfortran64/lib/ /usr/*/gfortran32/lib/ /usr/local/lib64 /usr/local/lib /opt/lib64 /opt/lib /opt/*/lib64 /opt/*/lib /opt/*/gfortran64/lib/ /opt/*/gfortran32/lib/
-  )
-
-IF (ACML_LIBRARY)
-  SET(ACML_LIBRARIES ${ACML_LIBRARY})
-  SET(ACML_FOUND "YES")
-ELSE (ACML_LIBRARY)
-  SET(ACML_FOUND "NO")
-ENDIF (ACML_LIBRARY)
-
-
-IF (ACML_FOUND)
-   IF (NOT ACML_FIND_QUIETLY)
-      MESSAGE(STATUS "Found the ACML library: ${ACML_LIBRARIES}")
-   ENDIF (NOT ACML_FIND_QUIETLY)
-ELSE (ACML_FOUND)
-   IF (ACML_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find the ACML library")
-   ENDIF (ACML_FIND_REQUIRED)
-ENDIF (ACML_FOUND)
-
-# Deprecated declarations.
-GET_FILENAME_COMPONENT (NATIVE_ACML_LIB_PATH ${ACML_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  ACML_LIBRARY
-  )
--- a/armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindACMLMP.cmake	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-# - Find AMD's ACMLMP library (no includes) which provides optimised and parallelised BLAS and LAPACK functions
-# This module defines
-#  ACMLMP_LIBRARIES, the libraries needed to use ACMLMP.
-#  ACMLMP_FOUND, If false, do not try to use ACMLMP.
-# also defined, but not for general use are
-#  ACMLMP_LIBRARY, where to find the ACMLMP library.
-
-SET(ACMLMP_NAMES ${ACMLMP_NAMES} acml_mp)
-FIND_LIBRARY(ACMLMP_LIBRARY
-  NAMES ${ACMLMP_NAMES}
-  PATHS /usr/lib64 /usr/lib /usr/*/lib64 /usr/*/lib /usr/*/gfortran64_mp/lib/ /usr/*/gfortran32_mp/lib/ /usr/local/lib64 /usr/local/lib /opt/lib64 /opt/lib /opt/*/lib64 /opt/*/lib /opt/*/gfortran64_mp/lib/ /opt/*/gfortran32_mp/lib/
-  )
-
-IF (ACMLMP_LIBRARY)
-  SET(ACMLMP_LIBRARIES ${ACMLMP_LIBRARY})
-  SET(ACMLMP_FOUND "YES")
-ELSE (ACMLMP_LIBRARY)
-  SET(ACMLMP_FOUND "NO")
-ENDIF (ACMLMP_LIBRARY)
-
-
-IF (ACMLMP_FOUND)
-   IF (NOT ACMLMP_FIND_QUIETLY)
-      MESSAGE(STATUS "Found the ACMLMP library: ${ACMLMP_LIBRARIES}")
-   ENDIF (NOT ACMLMP_FIND_QUIETLY)
-ELSE (ACMLMP_FOUND)
-   IF (ACMLMP_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find the ACMLMP library")
-   ENDIF (ACMLMP_FIND_REQUIRED)
-ENDIF (ACMLMP_FOUND)
-
-# Deprecated declarations.
-GET_FILENAME_COMPONENT (NATIVE_ACMLMP_LIB_PATH ${ACMLMP_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  ACMLMP_LIBRARY
-  )
--- a/armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindBLAS.cmake	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-# - Find a BLAS library (no includes)
-# This module defines
-#  BLAS_LIBRARIES, the libraries needed to use BLAS.
-#  BLAS_FOUND, If false, do not try to use BLAS.
-# also defined, but not for general use are
-#  BLAS_LIBRARY, where to find the BLAS library.
-
-SET(BLAS_NAMES ${BLAS_NAMES} blas)
-FIND_LIBRARY(BLAS_LIBRARY
-  NAMES ${BLAS_NAMES}
-  PATHS /usr/lib64/atlas /usr/lib/atlas /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib
-  )
-
-IF (BLAS_LIBRARY)
-  SET(BLAS_LIBRARIES ${BLAS_LIBRARY})
-  SET(BLAS_FOUND "YES")
-ELSE (BLAS_LIBRARY)
-  SET(BLAS_FOUND "NO")
-ENDIF (BLAS_LIBRARY)
-
-
-IF (BLAS_FOUND)
-   IF (NOT BLAS_FIND_QUIETLY)
-      MESSAGE(STATUS "Found a BLAS library: ${BLAS_LIBRARIES}")
-   ENDIF (NOT BLAS_FIND_QUIETLY)
-ELSE (BLAS_FOUND)
-   IF (BLAS_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find a BLAS library")
-   ENDIF (BLAS_FIND_REQUIRED)
-ENDIF (BLAS_FOUND)
-
-# Deprecated declarations.
-GET_FILENAME_COMPONENT (NATIVE_BLAS_LIB_PATH ${BLAS_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  BLAS_LIBRARY
-  )
--- a/armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindCBLAS.cmake	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-# - Find CBLAS (includes and library)
-# This module defines
-#  CBLAS_INCLUDE_DIR
-#  CBLAS_LIBRARIES
-#  CBLAS_FOUND
-# also defined, but not for general use are
-#  CBLAS_LIBRARY, where to find the library.
-
-FIND_PATH(CBLAS_INCLUDE_DIR cblas.h
-/usr/include/atlas/
-/usr/local/include/atlas/
-/usr/include/
-/usr/local/include/
-)
-
-SET(CBLAS_NAMES ${CBLAS_NAMES} cblas)
-FIND_LIBRARY(CBLAS_LIBRARY
-  NAMES ${CBLAS_NAMES}
-  PATHS /usr/lib64/atlas /usr/lib/atlas /usr/local/lib64/atlas /usr/local/lib/atlas /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib
-  )
-
-IF (CBLAS_LIBRARY AND CBLAS_INCLUDE_DIR)
-    SET(CBLAS_LIBRARIES ${CBLAS_LIBRARY})
-    SET(CBLAS_FOUND "YES")
-ELSE (CBLAS_LIBRARY AND CBLAS_INCLUDE_DIR)
-  SET(CBLAS_FOUND "NO")
-ENDIF (CBLAS_LIBRARY AND CBLAS_INCLUDE_DIR)
-
-
-IF (CBLAS_FOUND)
-   IF (NOT CBLAS_FIND_QUIETLY)
-      MESSAGE(STATUS "Found a CBLAS library: ${CBLAS_LIBRARIES}")
-   ENDIF (NOT CBLAS_FIND_QUIETLY)
-ELSE (CBLAS_FOUND)
-   IF (CBLAS_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find a CBLAS library")
-   ENDIF (CBLAS_FIND_REQUIRED)
-ENDIF (CBLAS_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_CBLAS_INCLUDE_PATH ${CBLAS_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_CBLAS_LIB_PATH ${CBLAS_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  CBLAS_LIBRARY
-  CBLAS_INCLUDE_DIR
-  )
--- a/armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindCLAPACK.cmake	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-# - Find a version of CLAPACK (includes and library)
-# This module defines
-#  CLAPACK_INCLUDE_DIR
-#  CLAPACK_LIBRARIES
-#  CLAPACK_FOUND
-# also defined, but not for general use are
-#  CLAPACK_LIBRARY, where to find the library.
-
-FIND_PATH(CLAPACK_INCLUDE_DIR clapack.h
-/usr/include/atlas/
-/usr/local/include/atlas/
-/usr/include/
-/usr/local/include/
-)
-
-SET(CLAPACK_NAMES ${CLAPACK_NAMES} lapack_atlas)
-SET(CLAPACK_NAMES ${CLAPACK_NAMES} clapack)
-FIND_LIBRARY(CLAPACK_LIBRARY
-  NAMES ${CLAPACK_NAMES}
-  PATHS /usr/lib64/atlas /usr/lib/atlas /usr/local/lib64/atlas /usr/local/lib/atlas /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib
-  )
-
-IF (CLAPACK_LIBRARY AND CLAPACK_INCLUDE_DIR)
-    SET(CLAPACK_LIBRARIES ${CLAPACK_LIBRARY})
-    SET(CLAPACK_FOUND "YES")
-ELSE (CLAPACK_LIBRARY AND CLAPACK_INCLUDE_DIR)
-  SET(CLAPACK_FOUND "NO")
-ENDIF (CLAPACK_LIBRARY AND CLAPACK_INCLUDE_DIR)
-
-
-IF (CLAPACK_FOUND)
-   IF (NOT CLAPACK_FIND_QUIETLY)
-      MESSAGE(STATUS "Found a CLAPACK library: ${CLAPACK_LIBRARIES}")
-   ENDIF (NOT CLAPACK_FIND_QUIETLY)
-ELSE (CLAPACK_FOUND)
-   IF (CLAPACK_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find a CLAPACK library")
-   ENDIF (CLAPACK_FIND_REQUIRED)
-ENDIF (CLAPACK_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_CLAPACK_INCLUDE_PATH ${CLAPACK_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_CLAPACK_LIB_PATH ${CLAPACK_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  CLAPACK_LIBRARY
-  CLAPACK_INCLUDE_DIR
-  )
--- a/armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindLAPACK.cmake	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-# - Find a LAPACK library (no includes)
-# This module defines
-#  LAPACK_LIBRARIES, the libraries needed to use LAPACK.
-#  LAPACK_FOUND, If false, do not try to use LAPACK.
-# also defined, but not for general use are
-#  LAPACK_LIBRARY, where to find the LAPACK library.
-
-SET(LAPACK_NAMES ${LAPACK_NAMES} lapack)
-FIND_LIBRARY(LAPACK_LIBRARY
-  NAMES ${LAPACK_NAMES}
-  PATHS /usr/lib64/atlas /usr/lib/atlas /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib
-  )
-
-IF (LAPACK_LIBRARY)
-  SET(LAPACK_LIBRARIES ${LAPACK_LIBRARY})
-  SET(LAPACK_FOUND "YES")
-ELSE (LAPACK_LIBRARY)
-  SET(LAPACK_FOUND "NO")
-ENDIF (LAPACK_LIBRARY)
-
-
-IF (LAPACK_FOUND)
-   IF (NOT LAPACK_FIND_QUIETLY)
-      MESSAGE(STATUS "Found a LAPACK library: ${LAPACK_LIBRARIES}")
-   ENDIF (NOT LAPACK_FIND_QUIETLY)
-ELSE (LAPACK_FOUND)
-   IF (LAPACK_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find a LAPACK library")
-   ENDIF (LAPACK_FIND_REQUIRED)
-ENDIF (LAPACK_FOUND)
-
-# Deprecated declarations.
-GET_FILENAME_COMPONENT (NATIVE_LAPACK_LIB_PATH ${LAPACK_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  LAPACK_LIBRARY
-  )
--- a/armadillo-2.4.4/build_aux/cmake/Modules/ARMA_FindMKL.cmake	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-# - Find the MKL libraries (no includes)
-# This module defines
-#  MKL_LIBRARIES, the libraries needed to use Intel's implementation of BLAS & LAPACK.
-#  MKL_FOUND, If false, do not try to use MKL.
-
-SET(MKL_NAMES ${MKL_NAMES} mkl_lapack)
-SET(MKL_NAMES ${MKL_NAMES} mkl_intel_thread)
-SET(MKL_NAMES ${MKL_NAMES} mkl_core)
-SET(MKL_NAMES ${MKL_NAMES} guide)
-SET(MKL_NAMES ${MKL_NAMES} mkl)
-
-IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
-  SET(MKL_NAMES ${MKL_NAMES} mkl_intel_lp64)
-ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8)
-  SET(MKL_NAMES ${MKL_NAMES} mkl_intel)
-ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
-
-FOREACH (MKL_NAME ${MKL_NAMES})
-  FIND_LIBRARY(${MKL_NAME}_LIBRARY
-    NAMES ${MKL_NAME}
-    PATHS /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /opt/intel/mkl/lib/lib64 /opt/intel/mkl/lib/ia32 /opt/intel/mkl/lib /opt/intel/*/mkl/lib/intel64 /opt/intel/*/mkl/lib/ia32/ /opt/mkl/*/lib/em64t /opt/mkl/*/lib/32 /opt/intel/mkl/*/lib/em64t /opt/intel/mkl/*/lib/32
-    )
-
-  SET(TMP_LIBRARY ${${MKL_NAME}_LIBRARY})
-
-  IF(TMP_LIBRARY)
-    SET(MKL_LIBRARIES ${MKL_LIBRARIES} ${TMP_LIBRARY})
-  ENDIF(TMP_LIBRARY)
-ENDFOREACH(MKL_NAME)
-
-IF (MKL_LIBRARIES)
-  SET(MKL_FOUND "YES")
-ELSE (MKL_LIBRARIES)
-  SET(MKL_FOUND "NO")
-ENDIF (MKL_LIBRARIES)
-
-IF (MKL_FOUND)
-  IF (NOT MKL_FIND_QUIETLY)
-    MESSAGE(STATUS "Found MKL libraries: ${MKL_LIBRARIES}")
-  ENDIF (NOT MKL_FIND_QUIETLY)
-ELSE (MKL_FOUND)
-  IF (MKL_FIND_REQUIRED)
-    MESSAGE(FATAL_ERROR "Could not find MKL libraries")
-  ENDIF (MKL_FIND_REQUIRED)
-ENDIF (MKL_FOUND)
-
-# MARK_AS_ADVANCED(MKL_LIBRARY)
--- a/armadillo-2.4.4/build_aux/doxygen/blank_footer.html	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-</BODY>
-</HTML>
--- a/armadillo-2.4.4/build_aux/doxygen/doxygen.config	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,298 +0,0 @@
-# Doxyfile 1.5.8
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-DOXYFILE_ENCODING      = UTF-8
-PROJECT_NAME           = "Armadillo Technical"
-PROJECT_NUMBER         = ""
-OUTPUT_DIRECTORY       = 
-CREATE_SUBDIRS         = NO
-OUTPUT_LANGUAGE        = English
-BRIEF_MEMBER_DESC      = YES
-REPEAT_BRIEF           = YES
-ABBREVIATE_BRIEF       = 
-ALWAYS_DETAILED_SEC    = YES
-INLINE_INHERITED_MEMB  = NO
-FULL_PATH_NAMES        = NO
-STRIP_FROM_PATH        = 
-STRIP_FROM_INC_PATH    = 
-SHORT_NAMES            = YES
-JAVADOC_AUTOBRIEF      = NO
-QT_AUTOBRIEF           = NO
-MULTILINE_CPP_IS_BRIEF = YES
-INHERIT_DOCS           = YES
-SEPARATE_MEMBER_PAGES  = NO
-TAB_SIZE               = 2
-ALIASES                = 
-OPTIMIZE_OUTPUT_FOR_C  = NO
-OPTIMIZE_OUTPUT_JAVA   = NO
-OPTIMIZE_FOR_FORTRAN   = NO
-OPTIMIZE_OUTPUT_VHDL   = NO
-EXTENSION_MAPPING      = 
-BUILTIN_STL_SUPPORT    = YES
-CPP_CLI_SUPPORT        = NO
-SIP_SUPPORT            = NO
-IDL_PROPERTY_SUPPORT   = YES
-DISTRIBUTE_GROUP_DOC   = NO
-SUBGROUPING            = YES
-TYPEDEF_HIDES_STRUCT   = NO
-SYMBOL_CACHE_SIZE      = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-EXTRACT_ALL            = YES
-EXTRACT_PRIVATE        = YES
-EXTRACT_STATIC         = YES
-EXTRACT_LOCAL_CLASSES  = YES
-EXTRACT_LOCAL_METHODS  = NO
-EXTRACT_ANON_NSPACES   = YES
-HIDE_UNDOC_MEMBERS     = NO
-HIDE_UNDOC_CLASSES     = NO
-HIDE_FRIEND_COMPOUNDS  = NO
-HIDE_IN_BODY_DOCS      = NO
-INTERNAL_DOCS          = NO
-CASE_SENSE_NAMES       = NO
-HIDE_SCOPE_NAMES       = NO
-SHOW_INCLUDE_FILES     = YES
-INLINE_INFO            = YES
-SORT_MEMBER_DOCS       = NO
-SORT_BRIEF_DOCS        = NO
-SORT_GROUP_NAMES       = NO
-SORT_BY_SCOPE_NAME     = NO
-GENERATE_TODOLIST      = YES
-GENERATE_TESTLIST      = YES
-GENERATE_BUGLIST       = YES
-GENERATE_DEPRECATEDLIST= YES
-ENABLED_SECTIONS       = 
-MAX_INITIALIZER_LINES  = 30
-SHOW_USED_FILES        = NO
-SHOW_DIRECTORIES       = YES
-SHOW_FILES             = YES
-SHOW_NAMESPACES        = YES
-FILE_VERSION_FILTER    = 
-LAYOUT_FILE            = 
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-QUIET                  = YES
-WARNINGS               = NO
-WARN_IF_UNDOCUMENTED   = YES
-WARN_IF_DOC_ERROR      = YES
-WARN_NO_PARAMDOC       = NO
-WARN_FORMAT            = "$file:$line: $text"
-WARN_LOGFILE           = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-INPUT                  = build_aux/doxygen/ \
-                         include/ \
-                         include/armadillo_bits
-
-INPUT_ENCODING         = UTF-8
-
-FILE_PATTERNS          = armadillo \
-                         armadillo_itpp \
-                         *.hpp \
-                         *.doxy
-
-RECURSIVE              = NO
-EXCLUDE                = 
-EXCLUDE_SYMLINKS       = NO
-EXCLUDE_PATTERNS       = 
-EXCLUDE_SYMBOLS        = 
-EXAMPLE_PATH           = 
-EXAMPLE_PATTERNS       = 
-EXAMPLE_RECURSIVE      = NO
-IMAGE_PATH             = 
-INPUT_FILTER           = 
-FILTER_PATTERNS        = 
-FILTER_SOURCE_FILES    = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-SOURCE_BROWSER         = YES
-INLINE_SOURCES         = YES
-STRIP_CODE_COMMENTS    = NO
-REFERENCED_BY_RELATION = YES
-REFERENCES_RELATION    = YES
-REFERENCES_LINK_SOURCE = YES
-USE_HTAGS              = NO
-VERBATIM_HEADERS       = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-ALPHABETICAL_INDEX     = YES
-COLS_IN_ALPHA_INDEX    = 5
-IGNORE_PREFIX          = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-GENERATE_HTML          = YES
-HTML_OUTPUT            = docs_tech
-HTML_FILE_EXTENSION    = .html
-HTML_HEADER            = 
-HTML_FOOTER            = build_aux/doxygen/blank_footer.html
-HTML_STYLESHEET        = 
-HTML_ALIGN_MEMBERS     = YES
-HTML_DYNAMIC_SECTIONS  = NO
-GENERATE_DOCSET        = NO
-DOCSET_FEEDNAME        = "Doxygen generated docs"
-DOCSET_BUNDLE_ID       = org.doxygen.Project
-GENERATE_HTMLHELP      = NO
-CHM_FILE               = 
-HHC_LOCATION           = 
-GENERATE_CHI           = NO
-CHM_INDEX_ENCODING     = 
-BINARY_TOC             = NO
-TOC_EXPAND             = NO
-GENERATE_QHP           = NO
-QCH_FILE               = 
-QHP_NAMESPACE          = 
-QHP_VIRTUAL_FOLDER     = doc
-QHP_CUST_FILTER_NAME   = 
-QHP_CUST_FILTER_ATTRS  = 
-QHP_SECT_FILTER_ATTRS  = 
-QHG_LOCATION           = 
-DISABLE_INDEX          = NO
-ENUM_VALUES_PER_LINE   = 4
-GENERATE_TREEVIEW      = YES
-TREEVIEW_WIDTH         = 250
-FORMULA_FONTSIZE       = 10
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-GENERATE_LATEX         = NO
-LATEX_OUTPUT           = latex
-LATEX_CMD_NAME         = latex
-MAKEINDEX_CMD_NAME     = makeindex
-COMPACT_LATEX          = NO
-PAPER_TYPE             = a4wide
-EXTRA_PACKAGES         = 
-LATEX_HEADER           = 
-PDF_HYPERLINKS         = NO
-USE_PDFLATEX           = NO
-LATEX_BATCHMODE        = NO
-LATEX_HIDE_INDICES     = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-GENERATE_RTF           = NO
-RTF_OUTPUT             = rtf
-COMPACT_RTF            = NO
-RTF_HYPERLINKS         = NO
-RTF_STYLESHEET_FILE    = 
-RTF_EXTENSIONS_FILE    = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-GENERATE_MAN           = NO
-MAN_OUTPUT             = man
-MAN_EXTENSION          = .3
-MAN_LINKS              = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-GENERATE_XML           = NO
-XML_OUTPUT             = xml
-XML_SCHEMA             = 
-XML_DTD                = 
-XML_PROGRAMLISTING     = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-GENERATE_AUTOGEN_DEF   = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-GENERATE_PERLMOD       = NO
-PERLMOD_LATEX          = NO
-PERLMOD_PRETTY         = YES
-PERLMOD_MAKEVAR_PREFIX = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor   
-#---------------------------------------------------------------------------
-
-ENABLE_PREPROCESSING   = NO
-MACRO_EXPANSION        = YES
-EXPAND_ONLY_PREDEF     = YES
-SEARCH_INCLUDES        = YES
-INCLUDE_PATH           = 
-INCLUDE_FILE_PATTERNS  = 
-PREDEFINED             = 
-EXPAND_AS_DEFINED      = 
-SKIP_FUNCTION_MACROS   = NO
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references   
-#---------------------------------------------------------------------------
-
-TAGFILES               = 
-GENERATE_TAGFILE       = 
-ALLEXTERNALS           = NO
-EXTERNAL_GROUPS        = YES
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool   
-#---------------------------------------------------------------------------
-
-CLASS_DIAGRAMS         = YES
-MSCGEN_PATH            = 
-HIDE_UNDOC_RELATIONS   = NO
-HAVE_DOT               = NO
-DOT_FONTNAME           = FreeSans
-DOT_FONTSIZE           = 10
-DOT_FONTPATH           = 
-CLASS_GRAPH            = YES
-COLLABORATION_GRAPH    = YES
-GROUP_GRAPHS           = YES
-UML_LOOK               = NO
-TEMPLATE_RELATIONS     = YES
-INCLUDE_GRAPH          = YES
-INCLUDED_BY_GRAPH      = YES
-CALL_GRAPH             = NO
-CALLER_GRAPH           = NO
-GRAPHICAL_HIERARCHY    = YES
-DIRECTORY_GRAPH        = YES
-DOT_IMAGE_FORMAT       = png
-DOT_PATH               = 
-DOTFILE_DIRS           = 
-DOT_GRAPH_MAX_NODES    = 50
-MAX_DOT_GRAPH_DEPTH    = 0
-DOT_TRANSPARENT        = YES
-DOT_MULTI_TARGETS      = NO
-GENERATE_LEGEND        = YES
-DOT_CLEANUP            = YES
-
-#---------------------------------------------------------------------------
-# Options related to the search engine
-#---------------------------------------------------------------------------
-
-SEARCHENGINE           = NO
--- a/armadillo-2.4.4/build_aux/doxygen/main.doxy	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-/*!
-\mainpage
-
-\htmlonly
-
-<br>
-See the associated technical report for an overview of the internal architecture:
-<br>
-<ul>
-Conrad Sanderson.
-<br>Armadillo: An Open Source C++ Linear Algebra Library for Fast Prototyping and Computationally Intensive Experiments.
-<br>Technical Report, NICTA, 2010. 
-</ul>
-
-\endhtmlonly
-*/
--- a/armadillo-2.4.4/build_aux/rpm/armadillo.spec	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,227 +0,0 @@
-Name:           armadillo
-Version:        1.2.0
-Release:        1%{?dist}
-Summary:        Fast C++ matrix library with interfaces to LAPACK and ATLAS
-
-Group:          Development/Libraries
-License:        LGPLv3+
-URL:            http://arma.sourceforge.net/
-Source:         http://sourceforge.net/projects/arma/files/%{name}-%{version}.tar.gz
-BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-BuildRequires:  cmake, boost-devel, blas-devel, lapack-devel, atlas-devel
-
-%description
-Armadillo is a C++ linear algebra library (matrix maths)
-aiming towards a good balance between speed and ease of use.
-Integer, floating point and complex numbers are supported,
-as well as a subset of trigonometric and statistics functions.
-Various matrix decompositions are provided through optional
-integration with LAPACK and ATLAS libraries.
-A delayed evaluation approach is employed (during compile time)
-to combine several operations into one and reduce (or eliminate) 
-the need for temporaries. This is accomplished through recursive
-templates and template meta-programming.
-This library is useful if C++ has been decided as the language
-of choice (due to speed and/or integration capabilities), rather
-than another language like Matlab or Octave.
-
-
-%package devel
-Summary:        Development headers and documentation for the Armadillo C++ library
-Group:          Development/Libraries
-Requires:       %{name} = %{version}-%{release}
-Requires:       boost-devel, blas-devel, lapack-devel, atlas-devel, libstdc++-devel
-
-# The header files of Armadillo include some Boost and ATLAS header files,
-# delivered within the boost-devel and atlas-devel sub-packages, respectively.
-# However, since there is no explicit dependency on Boost or ATLAS libraries
-# (most of Boost is delivered as header files only), the RPM building process 
-# does not detect these dependencies.  These dependencies must therefore be 
-# added manually.
-
-%description devel
-This package contains files necessary for development using the
-Armadillo C++ library. It contains header files, example programs,
-and user documentation (reference guide).
-
-
-%prep
-%setup -q
-
-# convert DOS end-of-line to UNIX end-of-line
-
-for file in README.txt; do
-  sed 's/\r//' $file >$file.new && \
-  touch -r $file $file.new && \
-  mv $file.new $file
-done
-
-%build
-%{cmake}
-%{__make} VERBOSE=1 %{?_smp_mflags}
-
-
-%install
-rm -rf $RPM_BUILD_ROOT
-%{__make} install DESTDIR=$RPM_BUILD_ROOT
-rm -rf   $RPM_BUILD_ROOT/%{_docdir}/%{name}-%{version}/
-mkdir -p $RPM_BUILD_ROOT/%{_docdir}/%{name}-%{version}/
-rm -f examples/Makefile.cmake
-rm -rf examples/example1_win32
-rm -rf examples/example2_win32
-rm -rf examples/lib_win32
-cp -r LICENSE.txt licenses README.txt index.html examples docs $RPM_BUILD_ROOT/%{_docdir}/%{name}-%{version}/
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-
-%post -p /sbin/ldconfig
-
-%postun -p /sbin/ldconfig
-
-
-%files
-%defattr(-,root,root,-)
-%{_libdir}/*.so.*
-%dir %{_docdir}/%{name}-%{version}/
-%doc %{_docdir}/%{name}-%{version}/LICENSE.txt
-%doc %{_docdir}/%{name}-%{version}/licenses/
-
-%files devel
-%defattr(-,root,root,-)
-%{_libdir}/*.so
-%{_includedir}/armadillo
-%{_includedir}/armadillo_bits/
-%{_includedir}/armadillo_itpp
-%doc %{_docdir}/%{name}-%{version}/README.txt
-%doc %{_docdir}/%{name}-%{version}/index.html
-%doc %{_docdir}/%{name}-%{version}/examples/
-%doc %{_docdir}/%{name}-%{version}/docs/
-%{_datadir}/Armadillo/
-
-%changelog
-* Mon Apr 18 2011 Conrad Sanderson - 1.2.0-1
-- spec updated for Armadillo 1.2.0
-
-* Mon Nov 15 2010 Conrad Sanderson - 1.0.0-1
-- spec updated for Armadillo 1.0.0
-
-* Thu Oct 14 2010 Conrad Sanderson - 0.9.90-1
-- spec updated for Armadillo 0.9.90
-
-* Tue Sep 21 2010 Conrad Sanderson - 0.9.80-1
-- spec updated for Armadillo 0.9.80
-
-* Wed Sep 01 2010 Conrad Sanderson - 0.9.70-1
-- spec updated for Armadillo 0.9.70
-
-* Wed Aug 04 2010 Conrad Sanderson - 0.9.60-1
-- spec updated for Armadillo 0.9.60
-
-* Wed Jul 14 2010 Conrad Sanderson - 0.9.52-1
-- spec updated for Armadillo 0.9.52
-
-* Wed Jul 07 2010 Conrad Sanderson - 0.9.50-1
-- spec updated for Armadillo 0.9.50
-
-* Wed Jun 02 2010 Conrad Sanderson - 0.9.10-1
-- spec updated for Armadillo 0.9.10
-
-* Fri May 14 2010 Conrad Sanderson - 0.9.8-1
-- spec updated for Armadillo 0.9.8
-
-* Tue Apr 28 2010 Conrad Sanderson - 0.9.6-1
-- spec updated for Armadillo 0.9.6
-
-* Tue Mar 16 2010 Conrad Sanderson - 0.9.4-1
-- spec updated for Armadillo 0.9.4
-
-* Tue Mar 02 2010 Conrad Sanderson - 0.9.2-2
-- added explicit dependencies to the devel package
-
-* Tue Mar 02 2010 Conrad Sanderson - 0.9.2-1
-- spec updated for Armadillo 0.9.2
-
-* Fri Feb 05 2010 Conrad Sanderson - 0.9.0-1
-- spec updated for Armadillo 0.9.0
-
-* Mon Jan 27 2010 Conrad Sanderson - 0.8.2-1
-- spec updated for Armadillo 0.8.2
-
-* Mon Dec 14 2009 Conrad Sanderson - 0.8.0-1
-- spec updated for Armadillo 0.8.0
-
-* Fri Oct 23 2009 Conrad Sanderson - 0.7.2-1
-- spec updated for Armadillo 0.7.2
-
-* Mon Oct 05 2009 Conrad Sanderson - 0.7.0-1
-- spec updated for Armadillo 0.7.0
-
-* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.12-3
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
-
-* Wed Jul 06 2009  Conrad Sanderson - 0.6.12-2
-- added conversion of DOS end-of-line to UNIX end-of-line for README.txt
-
-* Wed Jun 22 2009  Conrad Sanderson - 0.6.12-1
-- spec updated for Armadillo 0.6.12
-
-* Wed Jun 15 2009  Conrad Sanderson - 0.6.11-8
-- cleanup of dependencies
-- explanation as to why boost-devel and atlas-devel are required by armadillo-devel
-
-* Wed Jun 09 2009  Conrad Sanderson - 0.6.11-7
-- explicit declaration of doc directory in the main package
-- explicitly marked doc files in both packages
-
-* Wed Jun 09 2009  Conrad Sanderson - 0.6.11-6
-- removed symlinks
-- placed all documentation and license files into one directory that is shared by both packages
-
-* Wed Jun 09 2009  Conrad Sanderson - 0.6.11-5
-- added symlinks to LICENSE.txt and licenses in the devel package
-
-* Wed Jun 08 2009  Conrad Sanderson - 0.6.11-4
-- added LICENSE.txt to the main package
-
-* Wed May 22 2009  Conrad Sanderson - 0.6.11-3
-- using cmake macro instead of directly calling cmake
-
-* Wed May 21 2009  Conrad Sanderson - 0.6.11-2
-- moved all text files to devel package to retain consistency with the layout in the original .tar.gz
-
-* Wed May 08 2009  Conrad Sanderson - 0.6.10-2
-- Removed several explicit build dependencies that are provided by default in Fedora
-- Simplified handling of doc files
-
-* Wed May 02 2009  Conrad Sanderson - 0.6.10-1
-- Updated spec file for Armadillo 0.6.10
-
-* Wed Apr 02 2009  Conrad Sanderson
-- Updated list of files in 0.6.7 release
-
-* Wed Apr 02 2009  Conrad Sanderson
-- Updated description
-
-* Wed Mar 24 2009  Conrad Sanderson
-- Added explicit dependence on libstdc++-devel
-
-* Wed Mar 17 2009  Conrad Sanderson
-- Simplified specification of directories
-- Removed library packages specified by "Requires", as library dependencies are detected automatically
-
-* Wed Mar 12 2009  Conrad Sanderson
-- Modified to generate separate devel package (subsumes previous doc package)
-- Removed redundant packages specified by "BuildRequires"
-- Added CMake installation prefixes to allow for x86_64
-
-* Wed Feb  4 2009  Conrad Sanderson
-- Modified to generate separate doc package
-
-* Thu Jan 28 2009  Conrad Sanderson
-- Added argument to cmake: -DCMAKE_INSTALL_PREFIX=/usr 
-
-* Thu Jan 22 2009  Conrad Sanderson
-- Initial spec file prepared
-
--- a/armadillo-2.4.4/configure	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#!/bin/sh
-
-ABORT=no
-
-check_cmake()
-  {
-  (cmake --version) </dev/null >/dev/null 2>&1 ||
-    {
-    echo "error: cmake 2.6 must be present to configure and install Armadillo"
-    echo ""
-    echo "cmake might be available as a package for your system,"
-    echo "or can be downloaded from http://cmake.org"
-    ABORT=yes
-    }
-  }
-
-check_cmake
-
-test "$ABORT" = yes && exit -1
-
-rm -f CMakeCache.txt
-cmake .
-
Binary file armadillo-2.4.4/docs/armadillo_icon.png has changed
Binary file armadillo-2.4.4/docs/armadillo_nicta_2010.pdf has changed
--- a/armadillo-2.4.4/docs/index.html	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9667 +0,0 @@
-<!-- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -->
-<html>
-<head>
-  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
-  <title>Armadillo: C++ linear algebra library</title>
-  <link type="text/css" rel="stylesheet" href="style.css">
-  <link rel="icon" href="armadillo_icon.png" type="image/png">
-</head>
-<body>
-<center>
-<table style="text-align: left; width: 80%; margin-left: auto; margin-right: auto;" border="0" cellpadding="0" cellspacing="0">
-<tbody>
-<tr>
-<td style="vertical-align: top;">
-
-<table style="text-align: left; width: 100%;" border="0" cellpadding="0" cellspacing="0">
-  <tbody>
-    <tr>
-      <td style="text-align: left; vertical-align: top;">
-        <font size=+2><b>Reference for Armadillo 2.4.4</b></font>
-        <br>
-        <font size=-1><b>(Loco Lounge Lizard)</b></font>
-      </td>
-      <td style="text-align: right; vertical-align: top;">
-        <b><a href="http://arma.sourceforge.net">to Armadillo home page</a></b>
-        <br>
-        <b><a href="http://nicta.com.au">to NICTA home page</a></b>
-      </td>
-    </tr>
-  </tbody>
-</table>
-<hr>
-<br>
-<br>
-<a name="top"></a>
-<a style="display:scroll; position:fixed; bottom:5px; right:5px;" href="#top"><font size=-1>[top]</font></a> 
-
-
-<!-- BEGIN CONTENT -->
-
-
-<b>Preamble</b>
-<br>
-<br>
-<table border="0" cellpadding="0" cellspacing="0">
-<tbody>
-<tr>
-<td style="text-align: left; vertical-align: top; width: 50%;">
-<ul>
-<li>
-To aid the conversion of Matlab/Octave programs,
-there is a <a href="#syntax">syntax conversion table</a>
-</li>
-<br>
-<li>
-First time users may want to have a look at a short <a href="#example_prog">example program</a>
-</li>
-<br>
-<li>
-If you find any bugs or regressions, please <a href="http://arma.sourceforge.net/faq.html">report them</a>
-</li>
-<br>
-<li>
-<b>Caveat:</b> the API for version 2.x has <a href="#api_changes">changes &amp; additions</a> compared to version 1.2;
-see also the list of <a href="#deprecated">deprecated</a> functionality
-</li>
-</ul>
-</td>
-<td>
-&nbsp;
-</td>
-<td class="line" style="vertical-align: top;">
-<br>
-</td>
-<td style="text-align: left; vertical-align: top; width: 45%;">
-<ul>
-<li>
-If you use Armadillo in your research and/or software,
-we would appreciate a citation to the following tech report:
-<br>
-<br>
-<font size=-1>
-Conrad Sanderson.
-<br>
-<i><a href="armadillo_nicta_2010.pdf">Armadillo: An Open Source C++ Linear Algebra Library for Fast Prototyping and Computationally Intensive Experiments</a></i>.
-<br>
-Technical Report, NICTA, 2010.
-</font>
-</li>
-</ul>
-</td>
-</tr>
-</tbody>
-</table>
-
-<br>
-<br>
-
-<b>Matrix, Vector, Cube and Field Classes</b>
-<ul>
-<a href="#Mat">Mat&lt;<i>type</i>&gt;, mat and cx_mat</a>&nbsp;&middot;
-<a href="#Col">Col&lt;<i>type</i>&gt;, colvec and vec</a>&nbsp;&middot;
-<a href="#Row">Row&lt;<i>type</i>&gt;, rowvec</a>&nbsp;&middot;
-<a href="#Cube">Cube&lt;<i>type</i>&gt;, cube</a>&nbsp;&middot;
-<a href="#field">field&lt;<i>object&nbsp;type</i>&gt;</a>
-</ul>
-<br>
-
-<b>Member Functions &amp; Variables</b>
-<ul>
-<a href="#attributes">attributes</a>&nbsp;&middot;
-<a href="#colptr">colptr</a>&nbsp;&middot;
-<a href="#copy_size">copy_size</a>&nbsp;&middot;
-<a href="#diag">diag</a>&nbsp;&middot;
-<a href="#element_access">element&nbsp;access</a>&nbsp;&middot;
-<a href="#element_initialisation">element&nbsp;initialisation</a>&nbsp;&middot;
-<a href="#eye_member">eye</a>&nbsp;&middot;
-<a href="#fill">fill</a>&nbsp;&middot;
-<a href="#insert">insert rows/cols/slices</a>&nbsp;&middot;
-<a href="#in_range">in_range</a>&nbsp;&middot;
-<a href="#is_empty">is_empty</a>&nbsp;&middot;
-<a href="#is_finite">is_finite</a>&nbsp;&middot;
-<a href="#is_square">is_square</a>&nbsp;&middot;
-<a href="#is_vec">is_vec</a>&nbsp;&middot;
-<a href="#iterators_mat">iterators (matrices)</a>&nbsp;&middot;
-<a href="#iterators_cube">iterators (cubes)</a>&nbsp;&middot;
-<a href="#memptr">memptr</a>&nbsp;&middot;
-<a href="#min_and_max_member">min/max</a>&nbsp;&middot;
-<a href="#ones_member">ones</a>&nbsp;&middot;
-<a href="#operators">operators</a>&nbsp;&middot;
-<a href="#print">print</a>&nbsp;&middot;
-<a href="#raw_print">raw_print</a>&nbsp;&middot;
-<a href="#randu_randn_member">randu/randn</a>&nbsp;&middot;
-<a href="#reset">reset</a>&nbsp;&middot;
-<a href="#reshape_member">reshape</a>&nbsp;&middot;
-<a href="#resize_member">resize</a>&nbsp;&middot;
-<a href="#save_load_mat">save/load (matrices &amp; cubes)</a>&nbsp;&middot;
-<a href="#save_load_field">save/load (fields)</a>&nbsp;&middot;
-<a href="#set_imag">set_imag/real</a>&nbsp;&middot;
-<a href="#set_size">set_size</a>&nbsp;&middot;
-<a href="#shed">shed rows/cols/slices</a>&nbsp;&middot;
-<a href="#stl_container_fns">STL container functions</a>&nbsp;&middot;
-<a href="#submat">submatrix&nbsp;views</a>&nbsp;&middot;
-<a href="#subcube">subcube&nbsp;views</a>&nbsp;&middot;
-<a href="#subfield">subfield&nbsp;views</a>&nbsp;&middot;
-<a href="#swap_rows">swap_rows/cols</a>&nbsp;&middot;
-<a href="#t_st_members">t/st (transpose)</a>&nbsp;&middot;
-<a href="#zeros_member">zeros</a>
-</ul>
-<br>
-
-<b>Other Classes</b>
-<ul>
-<a href="#running_stat">running_stat&lt;<i>type</i>&gt;</a>&nbsp;&middot;
-<a href="#running_stat_vec">running_stat_vec&lt;<i>type</i>&gt;</a>&nbsp;&middot;
-<a href="#wall_clock">wall_clock</a>
-</ul>
-<br>
-
-<b>Generated Vectors/Matrices/Cubes</b>
-<ul>
-<a href="#eye_standalone">eye</a>&nbsp;&middot;
-<a href="#linspace">linspace</a>&nbsp;&middot;
-<a href="#ones_standalone">ones</a>&nbsp;&middot;
-<a href="#randu_randn_standalone">randu/randn</a>&nbsp;&middot;
-<a href="#repmat">repmat</a>&nbsp;&middot;
-<a href="#toeplitz">toeplitz/toeplitz_circ</a>&nbsp;&middot;
-<a href="#zeros_standalone">zeros</a>
-</ul>
-<br>
-
-<b>Functions Individually Applied to Each Element of a Matrix/Cube</b>
-<ul>
-<a href="#abs">abs</a>&nbsp;&middot;
-<a href="#eps">eps</a>&nbsp;&middot;
-<a href="#misc_fns">misc functions (exp, log, pow, sqrt, ...)</a>&nbsp;&middot;
-<a href="#trig_fns">trigonometric functions (cos, sin, ...)</a>
-</ul>
-<br>
-
-<b>Scalar Valued Functions of Vectors/Matrices/Cubes</b>
-<ul>
-<a href="#accu">accu</a>&nbsp;&middot;
-<a href="#as_scalar">as_scalar</a>&nbsp;&middot;
-<a href="#det">det</a>&nbsp;&middot;
-<a href="#dot">dot/cdot/norm_dot</a>&nbsp;&middot;
-<a href="#log_det">log_det</a>&nbsp;&middot;
-<a href="#norm">norm</a>&nbsp;&middot;
-<a href="#rank">rank</a>&nbsp;&middot;
-<a href="#trace">trace</a>
-</ul>
-<br>
-
-<b>Scalar/Vector Valued Functions of Vectors/Matrices</b>
-<ul>
-<a href="#diagvec">diagvec</a>&nbsp;&middot;
-<a href="#min_and_max">min/max</a>&nbsp;&middot;
-<a href="#prod">prod</a>&nbsp;&middot;
-<a href="#sum">sum</a>&nbsp;&middot;
-<a href="#stats_fns">statistics (mean, stddev, ...)</a>
-</ul>
-<br>
-
-<b>Vector/Matrix/Cube Valued Functions of Vectors/Matrices/Cubes</b>
-<ul>
-<a href="#conv">conv</a>&nbsp;&middot;
-<a href="#conv_to">conv_to</a>&nbsp;&middot;
-<a href="#conj">conj</a>&nbsp;&middot;
-<a href="#cor">cor</a>&nbsp;&middot;
-<a href="#cov">cov</a>&nbsp;&middot;
-<a href="#cross">cross</a>&nbsp;&middot;
-<a href="#cumsum">cumsum</a>&nbsp;&middot;
-<a href="#diagmat">diagmat</a>&nbsp;&middot;
-<a href="#find">find</a>&nbsp;&middot;
-<a href="#flip">fliplr/flipud</a>&nbsp;&middot;
-<a href="#imag_real">imag/real</a>&nbsp;&middot;
-<a href="#join">join&nbsp;rows/cols/slices</a>&nbsp;&middot;
-<a href="#kron">kron</a>&nbsp;&middot;
-<a href="#reshape">reshape</a>&nbsp;&middot;
-<a href="#resize">resize</a>&nbsp;&middot;
-<a href="#shuffle">shuffle</a>&nbsp;&middot;
-<a href="#sort">sort</a>&nbsp;&middot;
-<a href="#sort_index">sort_index</a>&nbsp;&middot;
-<a href="#symmat">symmatu/symmatl</a>&nbsp;&middot;
-<a href="#strans">strans</a>&nbsp;&middot;
-<a href="#trans">trans</a>&nbsp;&middot;
-<a href="#trimat">trimatu/trimatl</a>
-</ul>
-<br>
-
-<b>Decompositions, Inverses and Equation Solvers</b>
-<ul>
-<a href="#chol">chol</a>&nbsp;&middot;
-<a href="#eig_sym">eig_sym</a>&nbsp;&middot;
-<a href="#eig_gen">eig_gen</a>&nbsp;&middot;
-<a href="#inv">inv</a>&nbsp;&middot;
-<a href="#lu">lu</a>&nbsp;&middot;
-<a href="#pinv">pinv</a>&nbsp;&middot;
-<a href="#princomp">princomp</a>&nbsp;&middot;
-<a href="#qr">qr</a>&nbsp;&middot;
-<a href="#solve">solve</a>&nbsp;&middot;
-<a href="#svd">svd</a>&nbsp;&middot;
-<a href="#svd_econ">svd_econ</a>&nbsp;&middot;
-<a href="#syl">syl</a>
-</ul>
-<br>
-
-<b>Miscellaneous</b>
-<ul>
-<a href="#is_finite_standalone">is_finite()</a>&nbsp;&middot;
-<a href="#logging">logging of errors/warnings</a>&nbsp;&middot;
-<a href="#math_constants">math constants (pi, ...)</a>&nbsp;&middot;
-<a href="#phys_constants">physical constants (speed of light, ...)</a>&nbsp;&middot;
-<a href="#log_add">log_add</a>&nbsp;&middot;
-<a href="#uword">uword/sword</a>&nbsp;&middot;
-<a href="#cx_float_double">cx_float/cx_double</a>&nbsp;&middot;
-<a href="#syntax">Matlab/Armadillo syntax differences</a>&nbsp;&middot;
-<a href="#example_prog">example program</a>&nbsp;&middot;
-<!--<a href="#catching_exceptions">catching exceptions</a>&nbsp;&middot;-->
-<a href="#api_changes">API changes</a>
-</ul>
-<br>
-
-<br>
-<br>
-<hr class="greyline">
-<hr class="greyline">
-<br>
-<br>
-<font size=+1><b>Matrix, Vector, Cube and Field Classes</b></font>
-<br>
-<br>
-<hr class="greyline">
-<br>
-
-<a name="Mat"></a><b>Mat&lt;</b><i>type</i><b>&gt;</b>
-<br><b>mat</b>
-<br><b>cx_mat</b>
-<ul>
-<li>
-The root template matrix class is <b>Mat&lt;</b><i>type</i><b>&gt;</b>, where <i>type</i> can be one of:
-<i>char</i>, <i>int</i>, <i>float</i>, <i>double</i>, <i>std::complex&lt;double&gt;</i>, etc.
-</li>
-<br>
-<li>
-For convenience the following typedefs have been defined:
-<ul>
-<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;">
-      umat
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Mat&lt;<a href="#uword">uword</a>&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      imat
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Mat&lt;<a href="#uword">sword</a>&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      fmat
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Mat&lt;float&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      mat
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Mat&lt;double&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      cx_fmat
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Mat&lt;<a href="#cx_float_double">cx_float</a>&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      cx_mat
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Mat&lt;<a href="#cx_float_double">cx_double</a>&gt;
-      </td>
-    </tr>
-  </tbody>
-</table>
-</ul>
-</li>
-<br>
-<li>
-In this documentation the <i>mat</i> type is used for convenience;
-it is possible to use other types instead, eg. <i>fmat</i>
-</li>
-<br>
-<li>
-Functions which are wrappers for LAPACK or ATLAS functions (generally matrix decompositions) are only valid for the following types:
-<i>fmat</i>, <i>mat</i>, <i>cx_fmat</i>, <i>cx_mat</i>
-</li>
-<br>
-<li>
-Elements are stored with column-major ordering (ie. column by column)
-</li>
-<br>
-<a name="constructors_mat"></a>
-<li>
-Constructors:
-<ul>
-<li>mat()</li>
-<li>mat(n_rows, n_cols)</li>
-<li>mat(mat)</li>
-<li>mat(vec)</li>
-<li>mat(rowvec)</li>
-<li>mat(string)</li>
-<li>mat(initialiser_list) &nbsp; (C++11 only)</li>
-<li>cx_mat(mat,mat) &nbsp; (for constructing a complex matrix out of two real matrices)</li>
-</ul>
-</li>
-<br>
-<li>
-The string format for the constructor is elements separated by spaces, and rows denoted by semicolons.
-For example, the 2x2 identity matrix can be created using the format string <code>"1 0; 0 1"</code>.
-While string based initialisation is compact, directly setting the elements or using <a href="#element_initialisation">element initialisation</a> is considerably faster.
-</li>
-<br>
-<a name="adv_constructors_mat"></a>
-<li>
-Advanced constructors:
-<br>
-<br>
-<ul>
-<li>mat(aux_mem*, n_rows, n_cols, copy_aux_mem = true, strict = true)
-<br>
-<br>
-<ul>
-Create a matrix using data from writeable auxiliary memory.
-By default the matrix allocates its own memory and copies data from the auxiliary memory (for safety).
-However, if <i>copy_aux_mem</i> is set to <i>false</i>,
-the matrix will instead directly use the auxiliary memory (ie. no copying).
-This is faster, but can be dangerous unless you know what you're doing!
-<br>
-<br>
-The <i>strict</i> variable comes into effect only if <i>copy_aux_mem</i> is set to <i>false</i>
-(ie. the matrix is directly using auxiliary memory).
-If <i>strict</i> is set to <i>true</i>,
-the matrix will be bound to the auxiliary memory for its lifetime;
-the number of elements in the matrix can't be changed (directly or indirectly).
-If <i>strict</i> is set to <i>false</i>, the matrix will not be bound to the auxiliary memory for its lifetime,
-ie., the size of the matrix can be changed.
-If the requested number of elements is different to the size of the auxiliary memory,
-new memory will be allocated and the auxiliary memory will no longer be used.
-</ul>
-</li>
-<br>
-<li>mat(const aux_mem*, n_rows, n_cols)
-<br>
-<br>
-<ul>
-Create a matrix by copying data from read-only auxiliary memory.
-</ul>
-</li>
-<a name="adv_constructors_mat_fixed"></a>
-<br>
-<li>mat::fixed&lt;n_rows, n_cols&gt;
-<br>
-<br>
-<ul>
-Create a fixed size matrix, with the size specified via template arguments.
-Memory for the matrix is allocated at compile time.
-This is generally faster than dynamic memory allocation, but the size of the matrix can't be changed afterwards (directly or indirectly).
-<br>
-<br>
-For convenience, there are several pre-defined typedefs for each matrix type
-(where the types are: <i>umat</i>, <i>imat</i>, <i>fmat</i>, <i>mat</i>, <i>cx_fmat</i>, <i>cx_mat</i>).
-The typedefs specify a square matrix size, ranging from 2x2 to 9x9.
-The typedefs were defined by simply appending a two digit form of the size to the matrix type
--- for example, <i>mat33</i> is equivalent to <i>mat::fixed&lt;3,3&gt;</i>,
-while <i>cx_mat44</i> is equivalent to <i>cx_mat::fixed&lt;4,4&gt;</i>.
-</ul>
-</li>
-<br>
-<li>mat::fixed&lt;n_rows, n_cols&gt;(const aux_mem*)
-<br>
-<br>
-<ul>
-Create a fixed size matrix, with the size specified via template arguments,
-and copying data from auxiliary memory.
-</ul>
-</li>
-</ul>
-</li>
-<br>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-double x = A(1,2);
-
-mat B = A + A;
-mat C = A * B;
-mat D = A % B;
-
-cx_mat X(A,B);
-
-B.zeros();
-B.set_size(10,10);
-B.zeros(5,6);
-
-//
-// fixed size matrices:
-
-mat::fixed&lt;5,6&gt; F;
-F.ones();
-
-mat44 G;
-G.randn();
-
-cout &lt;&lt; mat22().randu() &lt;&lt; endl;
-
-//
-// constructing matrices from
-// auxiliary (external) memory:
-
-double aux_mem[24];
-mat H(aux_mem, 4, 6, false);
-</pre>
-</ul>
-</li>
-<br>
-<li><b>Caveat:</b>
-For mathematical correctness, scalars are treated as 1x1 matrices during initialisation.
-As such, the code below <b>will not</b> generate a 5x5 matrix with every element equal to 123.0:
-<ul>
-<pre>
-mat A(5,5);
-A = 123.0;
-</pre>
-</ul>
-Use the following code instead:
-<ul>
-<pre>
-mat A(5,5);
-A.fill(123.0);
-</pre>
-</ul>
-Or:
-<ul>
-<pre>
-mat A = 123.0 * ones&lt;mat&gt;(5,5);
-</pre>
-</ul>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#attributes">matrix attributes</a></li>
-<li><a href="#element_access">accessing elements</a></li>
-<li><a href="#element_initialisation">initialising elements</a></li>
-<li><a href="#operators">math &amp; relational operators</a></li>
-<li><a href="#submat">submatrix views</a></li>
-<li><a href="#save_load_mat">saving &amp; loading matrices</a></li>
-<li><a href="#print">printing matrices</a></li>
-<li><a href="#iterators_mat">STL-style element iterators</a></li>
-<li><a href="http://www.cplusplus.com/doc/tutorial/other_data_types/">explanation of <i>typedef</i></a> (cplusplus.com)
-<li><a href="#Col">Col class</a></li>
-<li><a href="#Row">Row class</a></li>
-<li><a href="#Cube">Cube class</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline">
-<br>
-
-<a name="Col"></a><b>Col&lt;</b><i>type</i><b>&gt;</b>
-<br><b>colvec</b>
-<br><b>vec</b>
-<ul>
-<li>
-Classes for column vectors (matrices with one column)
-</li>
-<br>
-<li>The <b>Col&lt;</b><i>type</i><b>&gt;</b> class is derived from the <b>Mat&lt;</b><i>type</i><b>&gt;</b> class
-and inherits most of the member functions
-</li>
-<br>
-<li>
-For convenience the following typedefs have been defined:
-<ul>
-<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;">
-      uvec, ucolvec
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Col&lt;<a href="#uword">uword</a>&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      ivec, icolvec
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Col&lt;<a href="#uword">sword</a>&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      fvec, fcolvec
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Col&lt;float&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      vec, colvec
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Col&lt;double&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      cx_fvec, cx_fcolvec
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Col&lt;<a href="#cx_float_double">cx_float</a>&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      cx_vec, cx_colvec
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Col&lt;<a href="#cx_float_double">cx_double</a>&gt;
-      </td>
-    </tr>
-  </tbody>
-</table>
-</ul>
-</li>
-<br>
-<li>
-In this documentation, the <b><i>vec</i></b> and <b><i>colvec</i></b> types have the <b>same meaning</b> and are used <b>interchangeably</b>
-</li>
-<br>
-<li>
-In this documentation, the types <i>vec</i> or <i>colvec</i> are used for convenience; it is possible to use other types instead, eg.&nbsp;<i>fvec</i>, <i>fcolvec</i>
-</li>
-<br>
-<li>
-Functions which take <i>Mat</i> as input can generally also take <i>Col</i> as input.
-Main exceptions are functions which require square matrices
-</li>
-<br>
-<li>
-Constructors
-<ul>
-<li>vec(n_elem=0)</li>
-<li>vec(vec)</li>
-<li>vec(mat) &nbsp; (a <i>std::logic_error</i> exception is thrown if the given matrix has more than one column)</li>
-<li>vec(string) &nbsp; (elements separated by spaces)</li>
-<li>vec(initialiser_list) &nbsp; (C++11 only)</li>
-</ul>
-</li>
-<br>
-<a name="adv_constructors_col"></a>
-<li>
-Advanced constructors:
-<br>
-<br>
-<ul>
-<li>vec(aux_mem*, number_of_elements, copy_aux_mem = true, strict = true)
-<br>
-<br>
-<ul>
-Create a column vector using data from writeable auxiliary memory.
-By default the vector allocates its own memory and copies data from the auxiliary memory (for safety).
-However, if <i>copy_aux_mem</i> is set to <i>false</i>,
-the vector will instead directly use the auxiliary memory (ie. no copying).
-This is faster, but can be dangerous unless you know what you're doing!
-<br>
-<br>
-The <i>strict</i> variable comes into effect only if <i>copy_aux_mem</i> is set to <i>false</i>
-(ie. the vector is directly using auxiliary memory).
-If <i>strict</i> is set to <i>true</i>,
-the vector will be bound to the auxiliary memory for its lifetime;
-the number of elements in the vector can't be changed (directly or indirectly).
-If <i>strict</i> is set to <i>false</i>, the vector will not be bound to the auxiliary memory for its lifetime,
-ie., the vector's size can be changed.
-If the requested number of elements is different to the size of the auxiliary memory,
-new memory will be allocated and the auxiliary memory will no longer be used.
-</ul>
-</li>
-<br>
-<li>vec(const aux_mem*, number_of_elements)
-<br>
-<br>
-<ul>
-Create a column vector by copying data from read-only auxiliary memory.
-</ul>
-</li>
-<br>
-<li>vec::fixed&lt;number_of_elements&gt;
-<br>
-<br>
-<ul>
-Create a fixed size column vector, with the size specified via the template argument.
-Memory for the vector is allocated at compile time.
-This is generally faster than dynamic memory allocation, but the size of the vector can't be changed afterwards (directly or indirectly).
-<br>
-<br>
-For convenience, there are several pre-defined typedefs for each vector type
-(where the types are: <i>uvec</i>, <i>ivec</i>, <i>fvec</i>, <i>vec</i>, <i>cx_fvec</i>, <i>cx_vec</i> as well as the corresponding <i>colvec</i> versions).
-The pre-defined typedefs specify vector sizes ranging from 2 to 9.
-The typedefs were defined by simply appending a single digit form of the size to the vector type
--- for example, <i>vec3</i> is equivalent to <i>vec::fixed&lt;3&gt;</i>,
-while <i>cx_vec4</i> is equivalent to <i>cx_vec::fixed&lt;4&gt;</i>.
-</ul>
-</li>
-<br>
-<li>vec::fixed&lt;number_of_elements&gt;(const aux_mem*)
-<br>
-<br>
-<ul>
-Create a fixed size column vector, with the size specified via the template argument,
-and copying data from auxiliary memory.
-</ul>
-</li>
-</ul>
-</li>
-<br>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-vec x(10);
-vec y = zeros&lt;vec&gt;(10,1);
-
-mat A = randu&lt;mat&gt;(10,10);
-vec z = A.col(5); // extract a column vector
-</pre>
-</ul>
-</li>
-<br>
-<li><b>Caveat:</b>
-For mathematical correctness, scalars are treated as 1x1 matrices during initialisation.
-As such, the code below <b>will not</b> generate a column vector with every element equal to 123.0:
-<ul>
-<pre>
-vec q(5);
-q = 123.0;
-</pre>
-</ul>
-Use the following code instead:
-<ul>
-<pre>
-vec q(5);
-q.fill(123.0);
-</pre>
-</ul>
-Or:
-<ul>
-<pre>
-vec q = 123.0 * ones&lt;vec&gt;(5,1);
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#Mat">Mat class</a></li>
-<li><a href="#Row">Row class</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="Row"></a>
-<b>Row&lt;</b><i>type</i><b>&gt;</b>
-<br><b>rowvec</b>
-<ul>
-<li>
-Classes for row vectors (matrices with one row)
-</li>
-<br>
-<li>The template <b>Row&lt;</b><i>type</i><b>&gt;</b> class is derived from the <b>Mat&lt;</b><i>type</i><b>&gt;</b> class
-and inherits most of the member functions
-</li>
-<br>
-<li>
-For convenience the following typedefs have been defined:
-<ul>
-<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;">
-      urowvec
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Row&lt;<a href="#uword">uword</a>&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      irowvec
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Row&lt;<a href="#uword">sword</a>&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      frowvec
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Row&lt;float&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      rowvec
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Row&lt;double&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      cx_frowvec
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Row&lt;<a href="#cx_float_double">cx_float</a>&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      cx_rowvec
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Row&lt;<a href="#cx_float_double">cx_double</a>&gt;
-      </td>
-    </tr>
-  </tbody>
-</table>
-</ul>
-</li>
-<br>
-<li>
-In this documentation, the <i>rowvec</i> type is used for convenience;
-it is possible to use other types instead, eg. <i>frowvec</i>
-</li>
-<br>
-<li>
-Functions which take <i>Mat</i> as input can generally also take <i>Row</i> as input.
-Main exceptions are functions which require square matrices
-</li>
-<br>
-<li>
-Constructors
-<ul>
-<li>rowvec(n_elem=0)</li>
-<li>rowvec(rowvec)</li>
-<li>rowvec(mat) &nbsp; (a <i>std::logic_error</i> exception is thrown if the given matrix has more than one row)</li>
-<li>rowvec(string) &nbsp; (elements separated by spaces)</li>
-<li>rowvec(initialiser_list) &nbsp; (C++11 only)</li>
-</ul>
-</li>
-<br>
-<a name="adv_constructors_row"></a>
-<li>
-Advanced constructors:
-<br>
-<br>
-<ul>
-<li>rowvec(aux_mem*, number_of_elements, copy_aux_mem = true, strict = true)
-<br>
-<br>
-<ul>
-Create a row vector using data from writeable auxiliary memory.
-By default the vector allocates its own memory and copies data from the auxiliary memory (for safety).
-However, if <i>copy_aux_mem</i> is set to <i>false</i>,
-the vector will instead directly use the auxiliary memory (ie. no copying).
-This is faster, but can be dangerous unless you know what you're doing!
-<br>
-<br>
-The <i>strict</i> variable comes into effect only if <i>copy_aux_mem</i> is set to <i>false</i>
-(ie. the vector is directly using auxiliary memory).
-If <i>strict</i> is set to <i>true</i>,
-the vector will be bound to the auxiliary memory for its lifetime;
-the number of elements in the vector can't be changed (directly or indirectly).
-If <i>strict</i> is set to <i>false</i>, the vector will not be bound to the auxiliary memory for its lifetime,
-ie., the vector's size can be changed.
-If the requested number of elements is different to the size of the auxiliary memory,
-new memory will be allocated and the auxiliary memory will no longer be used.
-</ul>
-</li>
-<br>
-<li>rowvec(const aux_mem*, number_of_elements)
-<br>
-<br>
-<ul>
-Create a row vector by copying data from read-only auxiliary memory.
-</ul>
-</li>
-<br>
-<li>rowvec::fixed&lt;number_of_elements&gt;
-<br>
-<br>
-<ul>
-Create a fixed size row vector, with the size specified via the template argument.
-Memory for the vector is allocated at compile time.
-This is generally faster than dynamic memory allocation, but the size of the vector can't be changed afterwards (directly or indirectly).
-<br>
-<br>
-For convenience, there are several pre-defined typedefs for each vector type
-(where the types are: <i>urowvec</i>, <i>irowvec</i>, <i>frowvec</i>, <i>rowvec</i>, <i>cx_frowvec</i>, <i>cx_rowvec</i>).
-The pre-defined typedefs specify vector sizes ranging from 2 to 9.
-The typedefs were defined by simply appending a single digit form of the size to the vector type
--- for example, <i>rowvec3</i> is equivalent to <i>rowvec::fixed&lt;3&gt;</i>,
-while <i>cx_rowvec4</i> is equivalent to <i>cx_rowvec::fixed&lt;4&gt;</i>.
-</ul>
-</li>
-<br>
-<li>rowvec::fixed&lt;number_of_elements&gt;(const aux_mem*)
-<br>
-<br>
-<ul>
-Create a fixed size row vector, with the size specified via the template argument,
-and copying data from auxiliary memory.
-</ul>
-</li>
-</ul>
-</li>
-<br>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-rowvec x(10);
-rowvec y = zeros&lt;mat&gt;(1,10);
-
-mat A = randu&lt;mat&gt;(10,10);
-rowvec z = A.row(5); // extract a row vector
-</pre>
-</ul>
-</li>
-<br>
-<li>
-<b>Caveat:</b>
-For mathematical correctness, scalars are treated as 1x1 matrices during initialisation.
-As such, the code below <b>will not</b> generate a row vector with every element equal to 123.0:
-<ul>
-<pre>
-rowvec r(5);
-r = 123.0;
-</pre>
-</ul>
-Use the following code instead:
-<ul>
-<pre>
-rowvec r(5);
-r.fill(123.0);
-</pre>
-</ul>
-Or:
-<ul>
-<pre>
-rowvec r = 123.0 * ones&lt;rowvec&gt;(1,5);
-</pre>
-</ul>
-<br>
-<li>See also:
-<ul>
-<li><a href="#Mat">Mat class</a></li>
-<li><a href="#Col">Col class</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline">
-<br>
-
-<a name="Cube"></a>
-<b>Cube&lt;</b><i>type</i><b>&gt;</b>
-<br><b>cube</b>
-<br><b>cx_cube</b>
-<ul>
-<li>
-Classes for cubes, also known as "3D matrices"
-</li>
-<br>
-<li>
-The root template cube class is <b>Cube&lt;</b><i>type</i><b>&gt;</b>, where <i>type</i> can be one of:
-<i>char</i>, <i>int</i>, <i>float</i>, <i>double</i>, <i>std::complex&lt;double&gt;</i>, etc
-</li>
-<br>
-<li>
-For convenience the following typedefs have been defined:
-<ul>
-<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;">
-      ucube
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Cube&lt;<a href="#uword">uword</a>&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      icube
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Cube&lt;<a href="#uword">sword</a>&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      fcube
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Cube&lt;float&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      cube
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Cube&lt;double&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      cx_fcube
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Cube&lt;<a href="#cx_float_double">cx_float</a>&gt;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      cx_cube
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;=&nbsp;
-      </td>
-      <td style="vertical-align: top;">
-      Cube&lt;<a href="#cx_float_double">cx_double</a>&gt;
-      </td>
-    </tr>
-  </tbody>
-</table>
-</ul>
-</li>
-<br>
-<li>
-In this documentation the <i>cube</i> type is used for convenience;
-it is possible to use other types instead, eg. <i>fcube</i>
-</li>
-<br>
-<li>
-Cube data is stored as a set of slices (matrices) stored contiguously within memory.
-Within each slice, elements are stored with column-major ordering (ie. column by column)
-</li>
-<br>
-<li>
-Each slice can be interpreted as a matrix, hence functions which take <i>Mat</i> as input can generally also take cube slices as input
-</li>
-<br>
-<a name="constructors_cube"></a>
-<li>
-Constructors:
-<ul>
-cube()
-<br>cube(cube)
-<br>cube(n_rows, n_cols, n_slices)
-<br>cx_cube(cube, cube) (for constructing a complex cube out of two real cubes)
-</ul>
-</li>
-<br>
-
-<a name="adv_constructors_cube"></a>
-<li>
-Advanced constructors:
-<br>
-<br>
-<ul>
-<li>
-cube::fixed&lt;n_rows, n_cols, n_slices&gt;
-<br>
-<br>
-<ul>
-Create a fixed size cube, with the size specified via template arguments.
-Memory for the cube is allocated at compile time.
-This is generally faster than dynamic memory allocation, but the size of the cube can't be changed afterwards (directly or indirectly).
-</ul>
-</li>
-<br>
-<li>cube(aux_mem*, n_rows, n_cols, n_slices, copy_aux_mem = true, strict = true)
-<br>
-<br>
-<ul>
-Create a cube using data from writeable auxiliary memory.
-By default the cube allocates its own memory and copies data from the auxiliary memory (for safety).
-However, if <i>copy_aux_mem</i> is set to <i>false</i>,
-the cube will instead directly use the auxiliary memory (ie. no copying).
-This is faster, but can be dangerous unless you know what you're doing!
-<br>
-<br>
-The <i>strict</i> variable comes into effect only if <i>copy_aux_mem</i> is set to <i>false</i>
-(ie. the cube is directly using auxiliary memory).
-If <i>strict</i> is set to <i>true</i>,
-the cube will be bound to the auxiliary memory for its lifetime;
-the number of elements in the cube can't be changed (directly or indirectly).
-If <i>strict</i> is set to <i>false</i>, the cube will not be bound to the auxiliary memory for its lifetime,
-ie., the size of the cube can be changed.
-If the requested number of elements is different to the size of the auxiliary memory,
-new memory will be allocated and the auxiliary memory will no longer be used.
-</ul>
-</li>
-<br>
-<li>cube(const aux_mem*, n_rows, n_cols, n_slices)
-<br>
-<br>
-<ul>
-Create a cube by copying data from read-only auxiliary memory.
-</ul>
-</li>
-</ul>
-</li>
-<br>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-cube x(1,2,3);
-cube y = randu&lt;cube&gt;(4,5,6);
-
-mat A = y.slice(1);  // extract a slice from the cube
-                     // (each slice is a matrix)
-
-mat B = randu&lt;mat&gt;(4,5);
-y.slice(2) = B;     // set a slice in the cube
-
-cube q = y + y;     // cube addition
-cube r = y % y;     // element-wise cube multiplication
-
-cube::fixed&lt;4,5,6&gt; f;
-f.ones();
-</pre>
-</ul>
-</li>
-<br>
-<li>
-<b>Caveats</b>
-<br>
-<br>
-<ul>
-<li>
-The size of individual slices can't be changed.
-For example, the following <b>will not</b> work:
-<ul>
-<pre>
-cube c(5,6,7);
-c.slice(0) = randu&lt;mat&gt;(10,20); // wrong size
-</pre>
-</ul>
-</li>
-<li>
-For mathematical correctness, scalars are treated as 1x1x1 cubes during initialisation.
-As such, the code below <b>will not</b> generate a cube with every element equal to 123.0:
-<ul>
-<pre>
-cube c(5,6,7);
-c = 123.0;
-</pre>
-</ul>
-Use the following code instead:
-<ul>
-<pre>
-cube c(5,6,7);
-c.fill(123.0);
-</pre>
-</ul>
-Or:
-<ul>
-<pre>
-cube c = 123.0 * ones&lt;cube&gt;(5,6,7);
-</pre>
-</ul>
-</li>
-</ul>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#attributes">cube attributes</a></li>
-<li><a href="#element_access">accessing elements</a></li>
-<li><a href="#operators">math &amp; relational operators</a></li>
-<li><a href="#subcube">subcube views and slices</a></li>
-<li><a href="#save_load_mat">saving &amp; loading cubes</a></li>
-<li><a href="#iterators_cube">STL-style element iterators</a></li>
-<li><a href="#Mat">Mat class</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline">
-<br>
-
-<a name="field"></a>
-<b>field&lt;</b><i>object type</i><b>&gt;</b>
-<ul>
-<li>
-Class for one and two dimensional fields of arbitrary objects
-</li>
-<br>
-<li>
-Constructors (where <i>object type</i> is another class, eg. <i>std::string</i>, <i>mat</i>, <i>vec</i>, <i>rowvec</i>, etc):
-<ul>
-field&lt;<i>object type</i>&gt;(n_elem=0)
-<br>field&lt;<i>object type</i>&gt;(n_rows, n_cols)
-<br>field&lt;<i>object type</i>&gt;(field&lt;<i>object type</i>&gt;)
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-// create a field of strings
-field&lt;std::string&gt; S(3,2);
-
-S(0,0) = "hello";
-S(1,0) = "there";
-
-// string fields can be saved as plain text files
-S.save("string_field");
-
-// create a vec field with 3 rows and 2 columns
-field&lt;vec&gt; F(3,2);
-
-// access components of the field
-F(0,0) = vec(5);
-F(1,1) = randu&lt;vec&gt;(6);
-F(2,0).set_size(7);
-
-// access element 1 of the vec stored at 2,0
-double x = F(2,0)(1);
-
-// copy rows
-F.row(0) = F.row(2);
-
-// extract a row of vecs from F
-field&lt;vec&gt; G = F.row(1);
-
-// print the field to the standard output
-G.print("G =");
-
-// save the field to a binary file
-G.save("vec_field");
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#attributes">field attributes</a></li>
-<li><a href="#subfield">subfield views</a></li>
-<li><a href="#save_load_field">saving/loading fields</a></li>
-<li><a href="http://cplusplus.com/reference/string/string/">string class in the standard C++ library</a> (cplusplus.com)</li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline">
-<hr class="greyline">
-<br>
-<br>
-<font size=+1><b>Member Functions &amp; Variables</b></font>
-<br>
-<br>
-<hr class="greyline">
-<br>
-
-<a name="attributes"></a>
-
-<b>attributes</b>
-<ul>
-<table style="text-align: left;" border="0" cellpadding="0" cellspacing="0">
-<tbody>
-<tr>
-<td>
-<b>.n_rows</b>
-</td>
-<td>&nbsp;&nbsp;</td>
-<td>
-(number of rows)
-</td>
-</tr>
-<tr>
-<td>
-<b>.n_cols</b>
-</td>
-<td>&nbsp;&nbsp;</td>
-<td>
-(number of columns)
-</td>
-</tr>
-<tr>
-<td>
-<b>.n_elem</b>
-</td>
-<td>&nbsp;&nbsp;</td>
-<td>
-(total number of elements)
-</td>
-</tr>
-<tr>
-<td>
-<b>.n_slices</b>
-</td>
-<td>&nbsp;&nbsp;</td>
-<td>
-(number of slices)
-</td>
-</tr>
-</tbody>
-</table>
-</ul>
-<br>
-<ul>
-<li>
-Member variables which are read-only;
-to change the size, use
-<a href="#set_size">.set_size()</a>,
-<a href="#copy_size">.copy_size()</a>,
-<a href="#zeros_member">.zeros()</a>,
-<a href="#ones_member">.ones()</a>,
-or
-<a href="#reset">.reset()</a>
-</li>
-<br>
-<li><i>n_rows</i>, <i>n_cols</i> and <i>n_elem</i> are applicable to <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i> classes</li>
-<br>
-<li><i>n_slices</i> is applicable only to the <i>Cube</i> class</li>
-<br>
-<li>
-For the <i>Col</i> and <i>Row</i> classes, <i>n_elem</i> also indicates vector length</li>
-<br>
-<li>The variables are of type <a href="#uword">uword</a></li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat X(4,5);
-cout &lt;&lt; "X has " &lt;&lt; X.n_cols &lt;&lt; " columns" &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#set_size">.set_size()</a></li>
-<li><a href="#copy_size">.copy_size()</a></li>
-<li><a href="#zeros_member">.zeros()</a></li>
-<li><a href="#ones_member">.ones()</a></li>
-<li><a href="#reset">.reset()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="colptr"></a>
-<b>.colptr(col_number)</b>
-<ul>
-<li>
-Member function of <i>Mat</i>
-</li>
-<br>
-<li>
-Obtain a raw pointer to the memory used by the specified column
-</li>
-<br>
-<li>
-As soon as the size of the matrix is changed, the pointer is no longer valid
-</li>
-<br>
-<li>This function is not recommended for use unless you know what you're doing
--- you may wish to use <a href="#submat">submatrix views</a> instead
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-
-double* mem = A.colptr(2);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#memptr">.memptr()</a></li>
-<li><a href="#submat">submatrix access</a></li>
-<li><a href="#iterators_mat">iterators (matrices)</a></li>
-<li><a href="#adv_constructors_mat">advanced constructors (matrices)</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="copy_size"></a>
-<b>.copy_size(A)</b>
-<ul>
-<li>
-Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i>
-</li>
-<br>
-<li>
-Set the size to be the same as object <i>A</i>
-</li>
-<br>
-<li>
-Object <i>A</i> must be of the same root type as the object being modified
-(eg. you can't set the size of a matrix by providing a cube)
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,6);
-mat B;
-B.copy_size(A);
-
-cout &lt;&lt; B.n_rows &lt;&lt; endl;
-cout &lt;&lt; B.n_cols &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="diag"></a>
-<b>.diag(k=0)</b>
-<ul>
-<li>
-Member function of <i>Mat</i>.
-</li>
-<br>
-<li>
-Read/write access to the <i>k</i>-th diagonal in a matrix
-</li>
-<br>
-<li>The argument <i>k</i> is optional -- by default the main diagonal is accessed (<i>k=0</i>)</li>
-<br>
-<li>For <i>k &gt; 0</i>, the <i>k</i>-th super-diagonal is accessed (top-right corner)</li>
-<br>
-<li>For <i>k &lt; 0</i>, the <i>k</i>-th sub-diagonal is accessed (bottom-left corner)</li>
-<br>
-<li>
-An extracted diagonal is interpreted as a column vector
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat    X = randu&lt;mat&gt;(5,5);
-
-vec a = X.diag();
-vec b = X.diag(1);
-vec c = X.diag(-2);
-
-X.diag()  = randu&lt;vec&gt;(5);
-X.diag() += 6;
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#diagvec">diagvec()</a></li>
-<li><a href="#submat">submatrix views</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="element_access"></a>
-<b>element/object access via (), [] and .at()</b>
-<ul>
-<li>
-Provide access to individual elements or objects stored in a container object
-(ie., <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i>, <i>field</i>)<br>
-                    <br>
-<ul>
-                    <table style="text-align: left; width: 100%;"
- border="0" cellpadding="2" cellspacing="2">
-                      <tbody>
-                        <tr>
-                          <td style="vertical-align: top;">
-                          <pre>(n)</pre>
-                          </td>
-                          <td style="vertical-align: top;">&nbsp;<br>
-                          </td>
-                          <td style="vertical-align: top;">
-For <i>vec</i> and <i>rowvec</i>, access the <i>n</i>-th element.
-For <i>mat</i>, <i>cube</i> and <i>field</i>, access the <i>n</i>-th element/object under the assumption of a flat layout,
-with column-major ordering of data (ie. column by column).
-A <i>std::logic_error</i> exception is thrown if the requested element is out of bounds.
-The bounds check can be optionally disabled at compile-time (see below).
-                          </td>
-                        </tr>
-<tr>
-<td>&nbsp;</td>
-<td>&nbsp;</td>
-<td>&nbsp;</td>
-</tr>
-                        <tr>
-                          <td style="vertical-align: top;">
-                          <pre>.at(n) and [n]</pre>
-                          </td>
-                          <td style="vertical-align: top;"><br>
-                          </td>
-                          <td style="vertical-align: top;">
-As for <i>(n)</i>, but without a bounds check.
-Not recommended for use unless your code has been thoroughly debugged.
-                          </td>
-                        </tr>
-<tr>
-<td>&nbsp;</td>
-<td>&nbsp;</td>
-<td>&nbsp;</td>
-</tr>
-                        <tr>
-                          <td style="vertical-align: top;">
-                          <pre>(i,j)</pre>
-                          </td>
-                          <td style="vertical-align: top;"><br>
-                          </td>
-                          <td style="vertical-align: top;">
-For <i>mat</i> and <i>field</i> classes, access the element/object stored at the <i>i</i>-th row and <i>j</i>-th column.
-A <i>std::logic_error</i> exception is thrown if the requested element is out of bounds.
-The bounds check can be optionally disabled at compile-time (see below).
-                          </td>
-                        </tr>
-<tr>
-<td>&nbsp;</td>
-<td>&nbsp;</td>
-<td>&nbsp;</td>
-</tr>
-                        <tr>
-                          <td style="vertical-align: top;">
-                          <pre>.at(i,j)</pre>
-                          </td>
-                          <td style="vertical-align: top;"><br>
-                          </td>
-                          <td style="vertical-align: top;">
-As for <i>(i,j)</i>, but without a bounds check.
-Not recommended for use unless your code has been thoroughly debugged.
-</td>
-                          <td style="vertical-align: top;"><br>
-                          </td>
-                        </tr>
-<tr>
-<td>&nbsp;</td>
-<td>&nbsp;</td>
-<td>&nbsp;</td>
-</tr>
-                        <tr>
-                          <td style="vertical-align: top;">
-                          <pre>(i,j,k)</pre>
-                          </td>
-                          <td style="vertical-align: top;"><br>
-                          </td>
-                          <td style="vertical-align: top;">
-Cube only: access the element stored at the <i>i</i>-th row, <i>j</i>-th column and <i>k</i>-th slice.
-A <i>std::logic_error</i> exception is thrown if the requested element is out of bounds.
-The bounds check can be optionally disabled at compile-time (see below).
-                          </td>
-                        </tr>
-<tr>
-<td>&nbsp;</td>
-<td>&nbsp;</td>
-<td>&nbsp;</td>
-</tr>
-                        <tr>
-                          <td style="vertical-align: top;">
-                          <pre>.at(i,j,k)</pre>
-                          </td>
-                          <td style="vertical-align: top;"><br>
-                          </td>
-                          <td style="vertical-align: top;">
-As for <i>(i,j,k)</i>, but without a bounds check.
-Not recommended for use unless your code has been thoroughly debugged.</td>
-                        </tr>
-                      </tbody>
-                    </table>
-</ul>
-</li>
-<br>
-<li>
-The bounds checks used by the <i>(n)</i>, <i>(i,j)</i> and <i>(i,j,k)</i> access forms
-can be disabled by defining <i>ARMA_NO_DEBUG</i> or <i>NDEBUG</i> macros 
-before including the <i>armadillo</i> header file (eg. <i>#define ARMA_NO_DEBUG</i>).
-Disabling the bounds checks is not recommended until your code has been thoroughly debugged
--- it's better to write correct code first, and then maximise its speed.
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(10,10);
-A(9,9) = 123.0;
-double x = A.at(9,9);
-double y = A[99];
-
-vec p = randu&lt;vec&gt;(10,1);
-p(9) = 123.0;
-double z = p[9];
-</pre>
-</ul>
-</li>                  
-<br>
-<li>See also:
-<ul>
-<li><a href="#in_range">.in_range()</a></li>
-<li><a href="#iterators_mat">iterators (matrices)</a></li>
-<li><a href="#iterators_cube">iterators (cubes)</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="element_initialisation"></a>
-<b>element initialisation</b>
-<ul>
-<li>
-Instances of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>field</i> classes can be initialised via repeated use of the &lt;&lt; operator
-</li>
-<br>
-<li>
-Special element <i>endr</i> indicates "end of row" (conceptually similar to <i>std::endl</i>)
-</li>
-<br>
-<li>
-Setting elements via &lt;&lt; is a bit slower than directly <a href="#element_access">accessing</a> the elements,
-but code using &lt;&lt; is generally more readable as well as being easier to write
-</li>
-<br>
-<li>
-If you have a C++11 compiler, instances of <i>Mat</i>, <i>Col</i> and <i>Row</i> classes can be also initialised via initialiser lists;
-this requires support for the C++11 standard to be <a href="#added_in_24">explicitly enabled</a>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A;
-
-A &lt;&lt; 1 &lt;&lt; 2 &lt;&lt; 3 &lt;&lt; endr
-  &lt;&lt; 4 &lt;&lt; 5 &lt;&lt; 6 &lt;&lt; endr;
-
-mat B = { 1, 2, 3, 4, 5, 6 };  // C++11 only
-B.reshape(2,3);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#element_access">element access</a></li>
-<li><a href="#print">.print()</a></li>
-<li><a href="#save_load_mat">saving &amp; loading matrices</a></li>
-<li><a href="#adv_constructors_mat">advanced constructors (matrices)</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="eye_member"></a>
-<b>.eye()</b>
-<br>
-<b>.eye(n_rows, n_cols)</b>
-<ul>
-<li>
-Set the elements along the main diagonal to one and off-diagonal elements set to zero,
-optionally first resizing to specified dimensions
-</li>
-<br>
-<li>
-An identity matrix is generated when <i>n_rows</i> = <i>n_cols</i>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A(5,5);
-A.eye();
-
-mat B;
-B.eye(5,5);
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#eye_standalone">eye()</a> (standalone function)</li>
-<li><a href="#diagmat">diagmat()</a></li>
-<li><a href="#diagvec">diagvec()</a></li>
-<li><a href="#ones_member">.ones()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="fill"></a>
-<b>.fill(value)</b>
-<ul>
-<li>
-Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i> classes.
-</li>
-<br>
-<li>Sets the elements to a specified value.
-The type of value must match the type of elements used by the container object
-(eg. for <i>mat</i> the type is double)
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A(5,5);
-A.fill(123.0);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#ones_member">.ones()</a></li>
-<li><a href="#zeros_member">.zeros()</a></li>
-<li><a href="#randu_randn_member">.randu() &amp; .randn()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="in_range"></a>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;"><b>.in_range(</b> i <b>)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i>)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.in_range( span(</b>start<b>,</b> end<b>) )</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i>)
-      </td>
-    </tr>
-    <tr>
-      <td>
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.in_range(</b> row<b>,</b> col <b>)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>field</i>)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.in_range( <font size=-1>span(</b>start_row<b>,</b> end_row<b>), span(</b>start_col<b>,</b> end_col<b>)</font> )</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>field</i>)
-      </td>
-    </tr>
-    <tr>
-      <td>
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.in_range(</b> row<b>,</b> col<b>,</b> slice <b>)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member of <i>Cube</i>)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.in_range( <font size=-1>span(</b>start_row<b>,</b> end_row<b>), span(</b>start_col<b>,</b> end_col<b>), span(</b>start_slice<b>,</b> end_slice<b>)</font> )</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member of <i>Cube</i>)
-      </td>
-    </tr>
-  </tbody>
-</table>
-<br>
-<ul>
-<li>Returns <i>true</i> if the given location or span is currently valid
-</li>
-<br>
-<li>Returns <i>false</i> if the object is empty, the location is out of bounds, or the span is out of bounds
-</li>
-<br>
-<li>
-Instances of <i>span(a,b)</i> can be replaced by:
-<ul>
-<li><i>span()</i> or <i>span::all</i>, to indicate the entire range</li>
-<li><i>span(a)</i>, to indicate a particular row, column or slice</li>
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(4,5);
-
-cout &lt;&lt; A.in_range(0,0) &lt;&lt; endl;  // true
-cout &lt;&lt; A.in_range(3,4) &lt;&lt; endl;  // true
-cout &lt;&lt; A.in_range(4,5) &lt;&lt; endl;  // false
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#element_access">element access</a></li>
-<li><a href="#submat">submatrix views</a></li>
-<li><a href="#subcube">subcube views</a></li>
-<li><a href="#subfield">subfield views</a></li>
-<li><a href="#set_size">.set_size()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="is_empty"></a>
-<b>.is_empty()</b>
-<ul>
-<li>
-Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i> classes
-</li>
-<br>
-<li>Returns true if the object has no elements
-</li>
-<br>
-<li>Returns false if the object has one or more elements
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-cout &lt;&lt; A.is_empty() &lt;&lt; endl;
-
-A.reset();
-cout &lt;&lt; A.is_empty() &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#is_square">.is_square()</a></li>
-<li><a href="#is_vec">.is_vec()</a></li>
-<li><a href="#reset">.reset()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="is_finite"></a>
-<b>.is_finite()</b>
-<ul>
-<li>
-Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i> classes
-</li>
-<br>
-<li>Returns <i>true</i> if all elements of the object are finite
-</li>
-<br>
-<li>Returns <i>false</i> if at least one of the elements of the object is non-finite (&plusmn;infinity or NaN)
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-mat B = randu&lt;mat&gt;(5,5);
-
-B(1,1) = math::nan()
-
-cout &lt;&lt; A.is_finite() &lt;&lt; endl;
-cout &lt;&lt; B.is_finite() &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#math_constants">math::nan()</a></li>
-<li><a href="#math_constants">math::inf()</a></li>
-<li><a href="#is_finite_standalone">is_finite()</a> (standalone function)</li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="is_square"></a>
-<b>.is_square()</b>
-<ul>
-<li>
-Member function of the <i>Mat</i> class
-</li>
-<br>
-<li>Returns <i>true</i> if the matrix is square, ie., number of rows is equal to the number of columns
-</li>
-<br>
-<li>Returns <i>false</i> if the matrix is not square
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-mat B = randu&lt;mat&gt;(6,7);
-
-cout &lt;&lt; A.is_square() &lt;&lt; endl;
-cout &lt;&lt; B.is_square() &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#is_empty">.is_empty()</a></li>
-<li><a href="#is_vec">.is_vec()</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="is_vec"></a>
-<b>.is_vec()</b>
-<br><b>.is_colvec()</b>
-<br><b>.is_rowvec()</b>
-<ul>
-<li>
-Member functions of the <i>Mat</i> class
-</li>
-<br>
-
-<li>.is_vec():
-<ul>
-<li>Returns <i>true</i> if the matrix can be interpreted as a vector (either column or row vector)
-</li>
-<li>Returns <i>false</i> if the matrix does not have exactly one column or one row
-</li>
-</ul>
-</li>
-<br>
-
-<li>.is_colvec():
-<ul>
-<li>Returns <i>true</i> if the matrix can be interpreted as a column vector
-</li>
-<li>Returns <i>false</i> if the matrix does not have exactly one column
-</li>
-</ul>
-</li>
-<br>
-
-<li>.is_rowvec():
-<ul>
-<li>Returns <i>true</i> if the matrix can be interpreted as a row vector
-</li>
-<li>Returns <i>false</i> if the matrix does not have exactly one row
-</li>
-</ul>
-</li>
-<br>
-
-<li><b>Caveat:</b> do not assume that the vector has elements if these functions return <i>true</i> -- it is possible to have an empty vector (eg. 0x1)
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(1,5);
-mat B = randu&lt;mat&gt;(5,1);
-mat C = randu&lt;mat&gt;(5,5);
-
-cout &lt;&lt; A.is_vec() &lt;&lt; endl;
-cout &lt;&lt; B.is_vec() &lt;&lt; endl;
-cout &lt;&lt; C.is_vec() &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#is_empty">.is_empty()</a></li>
-<li><a href="#is_square">.is_square()</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="insert"></a>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.insert_rows(&nbsp;</b>row_number, X<b>&nbsp;)</b>
-      <br>
-      <b>.insert_rows(&nbsp;</b>row_number, number_of_rows, set_to_zero&nbsp;=&nbsp;true<b>&nbsp;)</b>
-      </td>
-      <td style="vertical-align: top;"><br></td>
-      <td style="vertical-align: top;">(member functions of <i>Mat</i> and <i>Col</i>)
-      </td>
-    </tr>
-    <tr>
-    <td>&nbsp;</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.insert_cols(&nbsp;</b>col_number, X<b>&nbsp;)</b>
-      <br>
-      <b>.insert_cols(&nbsp;</b>col_number, number_of_cols, set_to_zero&nbsp;=&nbsp;true<b>&nbsp;)</b>
-      </td>
-      <td style="vertical-align: top;"><br></td>
-      <td style="vertical-align: top;">(member functions of <i>Mat</i> and <i>Row</i>)
-      </td>
-    </tr>
-    <tr>
-    <td>&nbsp;</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.insert_slices(&nbsp;</b>slice_number, X<b>&nbsp;)</b>
-      <br>
-      <b>.insert_slices(&nbsp;</b>slice_number, number_of_slices, set_to_zero&nbsp;=&nbsp;true<b>&nbsp;)</b>
-      </td>
-      <td style="vertical-align: top;"><br></td>
-      <td style="vertical-align: top;">(member functions of <i>Cube</i>)
-      </td>
-    </tr>
-  </tbody>
-</table>
-<br>
-<ul>
-<li>
-Functions with the <i>X</i> argument: insert a copy of X at the specified row/column/slice
-<ul>
-<li>if inserting rows, X must have the same number of columns as the recipient object</li>
-<li>if inserting columns, X must have the same number of rows as the recipient object</li>
-<li>if inserting slices, X must have the same number of rows and columns as the recipient object (ie. all slices must have the same size)</li>
-</ul>
-</li>
-<br>
-<li>
-Functions with the <i>number_of_...</i> argument: expand the object by creating new rows/columns/slices.
-By default, the new rows/columns/slices are set to zero.
-If <i>set_to_zero</i> is <i>false</i>, the memory used by the new rows/columns/slices will not be initialised.
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,10);
-mat B = ones&lt;mat&gt;(5,2);
-
-// at column 2, insert a copy of B;
-// A will now have 12 columns
-A.insert_cols(2, B);
-
-// at column 1, insert 5 zeroed columns;
-// B will now have 7 columns
-B.insert_cols(1, 5);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#shed">shed rows/columns/slices</a></li>
-<li><a href="#join">join rows/columns/slices</a></li>
-<li><a href="#resize_member">.resize()</a></li>
-<li><a href="#submat">submatrix views</a></li>
-<li><a href="#subcube">subcube views</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="iterators_mat"></a>
-<b>iterators (matrices &amp; vectors)</b>
-<ul>
-<li>
-STL-style iterators and associated member functions of the <i>Mat</i>, <i>Col</i> and <i>Row</i> classes
-</li>
-<br>
-<li>
-iterator types:
-<br>
-<br>
-<ul>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>mat::iterator</b>
-      <br>
-      <b>vec::iterator</b>
-      <br>
-      <b>rowvec::iterator</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        random access iterators, for read/write access to elements
-        (which are stored column by column)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>mat::const_iterator</b>
-      <br>
-      <b>vec::const_iterator</b>
-      <br>
-      <b>rowvec::const_iterator</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        random access iterators, for read-only access to elements
-        (which are stored column by column)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>mat::col_iterator</b>
-      <br>
-      <b>vec::col_iterator</b>
-      <br>
-      <b>rowvec::col_iterator</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        random access iterators, for read/write access to the elements of a specific column
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>mat::const_col_iterator</b>
-      <br>
-      <b>vec::const_col_iterator</b>
-      <br>
-      <b>rowvec::const_col_iterator</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        random access iterators, for read-only access to the elements of a specific column
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>mat::row_iterator</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        rudimentary forward iterator, for read/write access to the elements of a specific row
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>mat::const_row_iterator</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        rudimentary forward iterator, for read-only access to the elements of a specific row
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>vec::row_iterator</b>
-      <br>
-      <b>rowvec::row_iterator</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        random access iterators, for read/write access to the elements of a specific row
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>vec::const_row_iterator</b>
-      <br>
-      <b>rowvec::const_row_iterator</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        random access iterators, for read-only access to the elements of a specific row
-      </td>
-    </tr>
-  </tbody>
-</table>
-</ul>
-</li>
-<br>
-<br>
-<li>
-Member functions:
-<br>
-<br>
-<ul>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.begin()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        iterator referring to the first element
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.end()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        iterator referring to the <i>past-the-end</i> element
-      </td>
-    </tr>
-    <tr>
-      <td>
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.begin_row(</b><i>row_number</i><b>)</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        iterator referring to the first element of the specified row
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.end_row(</b><i>row_number</i><b>)</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        iterator referring to the <i>past-the-end</i> element of the specified row
-      </td>
-    </tr>
-    <tr>
-      <td>
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.begin_col(</b><i>col_number</i><b>)</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        iterator referring to the first element of the specified column
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.end_col(</b><i>col_number</i><b>)</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        iterator referring to the <i>past-the-end</i> element of the specified column
-      </td>
-    </tr>
-  </tbody>
-</table>
-</ul>
-</li>
-<br>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat X = randu&lt;mat&gt;(5,5);
-
-
-mat::iterator a = X.begin();
-mat::iterator b = X.end();
-
-for(mat::iterator i=a; i!=b; ++i)
-  {
-  cout &lt;&lt; *i &lt;&lt; endl;
-  }
-
-
-mat::col_iterator c = X.begin_col(1);  // start of column 1
-mat::col_iterator d = X.end_col(3);    // end of column 3
-
-for(mat::col_iterator i=c; i!=d; ++i)
-  {
-  cout &lt;&lt; *i &lt;&lt; endl;
-  (*i) = 123.0;
-  }
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#stl_container_fns">STL container functions</a></li>
-<li><a href="http://cplusplus.com/reference/std/iterator/">iterator at cplusplus.com</a></li>
-<li><a href="#element_access">element access</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="iterators_cube"></a>
-<b>iterators (cubes)</b>
-<ul>
-<li>
-STL-style iterators and associated member functions of the <i>Cube</i> class
-</li>
-<br>
-<li>
-iterator types:
-<br>
-<br>
-<ul>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>cube::iterator</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        random access iterator, for read/write access to elements;
-        the elements are ordered slice by slice;
-        the elements within each slice are ordered column by column
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>cube::const_iterator</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        random access iterators, for read-only access to elements
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>cube::slice_iterator</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        random access iterator, for read/write access to the elements of a particular slice;
-        the elements are ordered column by column
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>cube::const_slice_iterator</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        random access iterators, for read-only access to the elements of a particular slice
-      </td>
-    </tr>
-  </tbody>
-</table>
-</ul>
-</li>
-<br>
-<br>
-<li>
-Member functions:
-<br>
-<br>
-<ul>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.begin()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        iterator referring to the first element
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.end()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        iterator referring to the <i>past-the-end</i> element
-      </td>
-    </tr>
-    <tr>
-      <td>
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.begin_slice(</b><i>slice_number</i><b>)</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        iterator referring to the first element of the specified slice
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.end_slice(</b><i>slice_number</i><b>)</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        iterator referring to the <i>past-the-end</i> element of the specified slice
-      </td>
-    </tr>
-  </tbody>
-</table>
-</ul>
-</li>
-<br>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-cube X = randu&lt;cube&gt;(2,3,4);
-
-
-cube::iterator a = X.begin();
-cube::iterator b = X.end();
-
-for(cube::iterator i=a; i!=b; ++i)
-  {
-  cout &lt;&lt; *i &lt;&lt; endl;
-  }
-
-
-cube::slice_iterator c = X.begin_slice(1);  // start of slice 1
-cube::slice_iterator d = X.end_slice(2);    // end of slice 2
-
-for(cube::slice_iterator i=c; i!=d; ++i)
-  {
-  cout &lt;&lt; *i &lt;&lt; endl;
-  (*i) = 123.0;
-  }
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="http://cplusplus.com/reference/std/iterator/">iterator at cplusplus.com</a></li>
-<li><a href="#element_access">element access</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="memptr"></a>
-<b>.memptr()</b>
-<ul>
-<li>
-Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i> classes
-</li>
-<br>
-<li>
-Obtain a raw pointer to the memory used for storing elements. Not recommended for use unless you know what you're doing!
-</li>
-<br>
-<li>
-The function can be used for interfacing with libraries such as <a href="http://www.fftw.org/">FFTW</a>
-</li>
-<br>
-<li>
-As soon as the size of the matrix/vector/cube is changed, the pointer is no longer valid
-</li>
-<br>
-<li>
-Data for matrices is stored in a column-by-column order
-</li>
-<br>
-<li>
-Data for cubes is stored in a slice-by-slice (matrix-by-matrix) order
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-      mat A = randu&lt;mat&gt;(5,5);
-const mat B = randu&lt;mat&gt;(5,5);
-
-      double* A_mem = A.memptr();
-const double* B_mem = B.memptr();
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#colptr">.colptr()</a></li>
-<li><a href="#iterators_mat">iterators (matrices)</a></li>
-<li><a href="#iterators_cube">iterators (cubes)</a></li>
-<li><a href="#adv_constructors_mat">advanced constructors (matrices)</a></li>
-<li><a href="#adv_constructors_cube">advanced constructors (cubes)</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="min_and_max_member"></a>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;"><b>.min()</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member functions of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i>)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.max()</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">&nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">&nbsp;</td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">&nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.min(</b>&nbsp;index_of_min_val&nbsp;<b>)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member functions of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i>)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.max(</b>&nbsp;index_of_max_val&nbsp;<b>)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">&nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">&nbsp;</td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">&nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.min(</b>&nbsp;row_of_min_val<b>,</b> col_of_min_val&nbsp;<b>)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member functions of <i>Mat</i>)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.max(</b>&nbsp;row_of_max_val<b>,</b> col_of_max_val&nbsp;<b>)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">&nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">&nbsp;</td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">&nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.min(</b>&nbsp;row_of_min_val<b>,</b> col_of_min_val<b>,</b> slice_of_min_val&nbsp;<b>)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member functions of <i>Cube</i>)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.max(</b>&nbsp;row_of_max_val<b>,</b> col_of_max_val<b>,</b> slice_of_max_val&nbsp;<b>)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">&nbsp;
-      </td>
-    </tr>
-  </tbody>
-</table>
-<ul>
-<br>
-<li>
-Without arguments: return the extremum value of an object
-</li>
-<br>
-<li>
-With one or more arguments: return the extremum value of an object and store the location of the extremum value in the provided variable(s)
-</li>
-<br>
-<li>
-The provided variables must be of type <a href="#uword">uword</a>.
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-vec v = randu&lt;vec&gt;(10);
-
-cout &lt;&lt; "min value is " &lt;&lt; v.min() &lt;&lt; endl;
-
-
-uword  index;
-double min_val = v.min(index);
-
-cout &lt;&lt; "index of min value is " &lt;&lt; index &lt;&lt; endl;
-
-
-mat A = randu&lt;mat&gt;(5,5);
-
-uword  row;
-uword  col;
-double min_val2 = A.max(row,col);
-
-cout &lt;&lt; "max value is at " &lt;&lt; row &lt;&lt; ',' &lt;&lt; col &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#min_and_max">min() &amp; max()</a> (standalone functions)</li>
-<li><a href="#running_stat">running_stat</a></li>
-<li><a href="#running_stat_vec">running_stat_vec</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="ones_member"></a>
-<b>.ones()</b>
-<br><b>.ones(n_elem)</b>
-<br><b>.ones(n_rows, n_cols)</b>
-<br><b>.ones(n_rows, n_cols, n_slices)</b>
-<ul>
-<li>
-Set the elements of an object to one, optionally first resizing to specified dimensions
-</li>
-<br>
-<li>
-<i>.ones()</i> and <i>.ones(n_elem)</i> are member functions of <i>Col</i> and <i>Row</i>
-</li>
-<br>
-<li>
-<i>.ones()</i> and <i>.ones(n_rows, n_cols)</i> are member functions of <i>Mat</i>
-</li>
-<br>
-<li>
-<i>.ones()</i> and <i>.ones(n_rows, n_cols, n_slices)</i> are member functions of <i>Cube</i>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,10);
-A.ones();      // sets all elements to one
-A.ones(10,20); // sets the size to 10 rows and 20 columns
-               // followed by setting all elements to one
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#ones_standalone">ones()</a> (standalone function)</li>
-<li><a href="#zeros_member">.zeros()</a></li>
-<li><a href="#fill">.fill()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="operators"></a>
-<b>operators: &nbsp; + &nbsp; - &nbsp; * &nbsp; / &nbsp; % &nbsp; == &nbsp; != &nbsp; &lt;= &nbsp; &gt;= &nbsp; &lt; &nbsp; &gt;</b>
-<ul>
-<li>
-Overloaded operators for <i>mat</i>, <i>vec</i>, <i>rowvec</i> and <i>cube</i> classes
-</li>
-<br>
-<li>
-Meanings:
-<br>
-<br>
-<ul>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;"><b>+</b></td>
-      <td style="vertical-align: top;">&nbsp;&nbsp;&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">Addition of two objects</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>-</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">Subtraction of one object from another or negation of an object</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>/</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">Element-wise division of an object by another object or a scalar</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>*</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">Matrix multiplication of two objects; not applicable to the <i>cube</i> class unless multiplying a cube by a scalar</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>%</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;"><a name="schur_product"></a>Schur product: element-wise multiplication of two objects</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>==</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">Element-wise equality evaluation of two objects; generates a matrix of type <i>umat</i> with entries that indicate whether at a given position the two elements from the two objects are equal (1) or not equal (0)</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>!=</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">Element-wise non-equality evaluation of two objects</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>&gt;=</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">As for ==, but the check is for "greater than or equal to"</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>&lt;=</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">As for ==, but the check is for "less than or equal to"</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>&gt;</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">As for ==, but the check is for "greater than"</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>&lt;</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">As for ==, but the check is for "less than"</td>
-    </tr>
-  </tbody>
-</table>
-</ul>
-</li>
-<br>
-<li>
-A <i>std::logic_error</i> exception is thrown if incompatible object sizes are used
-</li>
-<br>
-<li>
-If the +, - and % operators are chained, Armadillo will try to avoid the generation of temporaries;
-no temporaries are generated if all given objects are of the same type and size
-</li>
-<br>
-<li>
-If the * operator is chained, Armadillo will try to find an efficient ordering of the matrix multiplications
-</li>
-<br>
-<li>
-<b>Caveat:</b> operators involving an equality comparison (ie., ==, !=, &gt;=, &lt;=)
-may not work as expected for floating point element types (ie., <i>float</i>, <i>double</i>)
-due to the necessarily limited precision of these types;
-in other words, these operators are (in general) not recommended for matrices of type <i>mat</i> or <i>fmat</i>
-</li>
-<br>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,10);
-mat B = randu&lt;mat&gt;(5,10);
-mat C = randu&lt;mat&gt;(10,5);
-
-mat P = A + B;
-mat Q = A - B;
-mat R = -B;
-mat S = A / 123.0;
-mat T = A % B;
-mat U = A * C;
-
-// V is constructed without temporaries
-mat V = A + B + A + B;
-
-imat AA = "1 2 3; 4 5 6; 7 8 9;";
-imat BB = "3 2 1; 6 5 4; 9 8 7;";
-
-// compare elements
-umat ZZ = (AA >= BB);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#accu">accu()</a></li>
-<li><a href="#as_scalar">as_scalar()</a></li>
-<li><a href="#find">find()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="print"></a>
-<b>.print(header="")</b>
-<br><b>.print(stream, header="")</b>
-<ul>
-<li>
-Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i>
-</li>
-<br>
-<li>
-The first form prints the contents of an object to the <i>std::cout</i> stream, with an optional header line
-</li>
-<br>
-<li>
-The second form prints to a user specified stream
-</li>
-<br>
-<li>
-It's also possible to print objects using the &lt;&lt; stream operator
-</li>
-<br>
-<li>
-Elements of a field can only be printed if there is an associated <i>operator&lt;&lt;</i> function defined
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-mat B = randu&lt;mat&gt;(6,6);
-
-A.print();
-
-// print a transposed version of A
-A.t().print();
-
-// "B:" is the optional header line
-B.print("B:");
-
-cout &lt;&lt; A &lt;&lt; endl;
-cout &lt;&lt; "B:" &lt;&lt; endl &lt;&lt; B &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#raw_print">.raw_print()</a></li>
-<li><a href="#save_load_mat">saving &amp; loading matrices</a></li>
-<li><a href="#element_initialisation">initialising elements</a></li>
-<li><a href="#logging">logging of errors and warnings</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="raw_print"></a>
-<b>.raw_print(header="")</b>
-<br><b>.raw_print(stream, header="")</b>
-<ul>
-<li>
-Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i>
-</li>
-<br>
-<li>
-Similar to the <a href="#print">.print()</a> member function,
-with the difference being that no formatting of the output is done -- ie. the user can set the stream's parameters such as precision, cell width, etc.
-</li>
-<br>
-<li>
-If the cell width is set to zero, a space is printed between the elements
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-
-cout.precision(11);
-cout.setf(ios::fixed);
-
-A.raw_print(cout, "A =");
-</pre>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="randu_randn_member"></a>
-<b>.randu()</b>
-<br><b>.randu(n_elem)</b>
-<br><b>.randu(n_rows, n_cols)</b>
-<br><b>.randu(n_rows, n_cols, n_slices)</b>
-<br>
-<br>
-<b>.randn()</b>
-<br><b>.randn(n_elem)</b>
-<br><b>.randn(n_rows, n_cols)</b>
-<br><b>.randn(n_rows, n_cols, n_slices)</b>
-<ul>
-<li>
-Fill an object with random values, optionally first resizing to specified dimensions
-</li>
-<br>
-<li><i>.randu()</i> uses a uniform distribution in the [0,1] interval
-</li>
-<br>
-<li><i>.randn()</i> uses a normal/Gaussian distribution with zero mean and unit variance
-</li>
-<br>
-<li>
-To change the seed, use the <a href="http://cplusplus.com/reference/clibrary/cstdlib/srand/">std::srand()</a> function
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A(4,5);
-A.randu();
-
-mat B;
-B.randu(6,7);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#randu_randn_standalone">randu() &amp; randn()</a> (standalone functions)</li>
-<li><a href="#fill">.fill()</a></li>
-<li><a href="#ones_member">.ones()</a></li>
-<li><a href="#zeros_member">.zeros()</a></li>
-<li><a href="http://cplusplus.com/reference/clibrary/cstdlib/srand/">std::srand()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="reset"></a>
-<b>
-.reset()
-</b>
-<ul>
-<li>
-Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i>
-</li>
-<br>
-<li>
-Causes an object to have no elements
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5, 5);
-A.reset();
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#set_size">.set_size()</a></li>
-<li><a href="#is_empty">.is_empty()</a></li>
-<li><a href="#zeros_member">.zeros()</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="reshape_member"></a>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;"><b>.reshape(n_rows, n_cols, dim=0)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.reshape(n_rows, n_cols, n_slices, dim=0)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member function of <i>Cube</i>)
-      </td>
-    </tr>
-  </tbody>
-</table>
-<br>
-<ul>
-<li>
-Recreate the object according to given size specifications,
-with the elements taken from the previous version of the object,
-either column-wise (dim=0) or row-wise (dim=1);
-the elements in the generated object are placed column-wise (ie. the first column is filled up before filling the second column)
-</li>
-<br>
-<li>
-The layout of the elements in the recreated object will be different to the layout in the previous version of the object
-</li>
-<br>
-<li>
-This function can be used to vectorise a matrix (ie. concatenate all the columns or rows)
-</li>
-<br>
-<li>
-The new total number of elements (according to the specified size) doesn't have to be the same as the previous total number of elements in the object
-</li>
-<br>
-<li>
-If the total number of elements in the previous version of the object is less than the specified size,
-the extra elements in the recreated object are set to zero
-</li>
-<br>
-<li>
-If the total number of elements in the previous version of the object is greater than the specified size,
-only a subset of the elements is taken
-</li>
-<br>
-<li>
-<b>Caveat:</b>
-.reshape() is slower than <a href="#set_size">.set_size()</a>, which doesn't preserve data
-</li>
-<br>
-<li>
-<b>Caveat:</b>
-if you wish to grow/shrink the object while preserving the elements <b>as well as</b> the layout of the elements,
-use <a href="#resize_member">.resize()</a> instead
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(4,5);
-A.reshape(5,4);
-
-// vectorise A into a column vector:
-A.reshape(A.n_elem, 1);
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#resize_member">.resize()</a></li>
-<li><a href="#set_size">.set_size()</a></li>
-<li><a href="#reset">.reset()</a></li>
-<li><a href="#reshape">reshape()</a> (standalone function)</li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="resize_member"></a>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;"><b>.resize(n_elem)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member function of <i>Col</i>, <i>Row</i>)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.resize(n_rows, n_cols)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member function of <i>Mat</i>)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.resize(n_rows, n_cols, n_slices)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member function of <i>Cube</i>)
-      </td>
-    </tr>
-  </tbody>
-</table>
-<br>
-<ul>
-<li>
-Recreate the object according to given size specifications, while preserving the elements as well as the layout of the elements
-</li>
-<br>
-<li>
-Can be used for growing or shrinking an object (ie. adding/removing rows, and/or columns, and/or slices)
-</li>
-<br>
-<li>
-<b>Caveat:</b>
-.resize() is slower than <a href="#set_size">.set_size()</a>, which doesn't preserve data
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(4,5);
-A.resize(7,6);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-This function was added in version 2.4.1
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#reshape_member">.reshape()</a></li>
-<li><a href="#set_size">.set_size()</a></li>
-<li><a href="#reset">.reset()</a></li>
-<li><a href="#insert">insert rows/cols/slices</a></li>
-<li><a href="#shed">shed rows/cols/slices</a></li>
-<li><a href="#resize">resize()</a> (standalone function)</li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="save_load_mat"></a>
-<b>
-.save(name, file_type = arma_binary)
-<br>
-.save(stream, file_type = arma_binary)
-<br>
-<br>
-.load(name, file_type = auto_detect)
-<br>
-.load(stream, file_type = auto_detect)
-<br>
-<br>
-.quiet_save(name, file_type = arma_binary)
-<br>
-.quiet_save(stream, file_type = arma_binary)
-<br>
-<br>
-.quiet_load(name, file_type = auto_detect)
-<br>
-.quiet_load(stream, file_type = auto_detect)
-</b>
-<ul>
-<li>Member functions of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i> classes</li>
-<br>
-<li>Store/retrieve data in files or streams</li>
-<br>
-<li>On success, <i>save()</i>, <i>load()</i>, <i>quiet_save()</i>, and <i>quite_load()</i> will return a <i>bool</i> set to <i>true</i></li>
-<br>
-<li><i>save()</i> and <i>quiet_save()</i> will return a <i>bool</i> set to <i>false</i> if the saving process fails</li>
-<br>
-<li>
-<i>load()</i> and <i>quiet_load()</i> will return a <i>bool</i> set to <i>false</i> if the loading process fails;
-additionally, the object will be reset so it has no elements
-</li>
-<br>
-<li><i>load()</i> and <i>save()</i> will print warning messages if any problems are encountered</li>
-<br>
-<li><i>quiet_load()</i> and <i>quiet_save()</i> do not print any error messages</li>
-<br>
-<li>
-The following file formats are supported:
-<br>
-<br>
-<ul>
-                  <table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-                    <tbody>
-                      <tr>
-                        <td style="vertical-align: top;"><b>auto_detect</b></td>
-                        <td style="vertical-align: top;"><br>
-                        </td>
-                        <td style="vertical-align: top;">
-for <i>load()</i> and <i>quiet_load()</i>:
-try to automatically detect the file type as one of the formats described below.
-This is the default operation.
-<br>
-<br>
-                        </td>
-                      </tr>
-                      <tr>
-                        <td style="vertical-align: top;"><b>raw_ascii</b></td>
-                        <td style="vertical-align: top;"><br>
-                        </td>
-                        <td style="vertical-align: top;">
-Numerical data stored in raw ASCII format, without a header.
-The numbers are separated by whitespace.
-The number of columns must be the same in each row.
-Data which was saved in Matlab/Octave using the <i>-ascii</i> option can be read in Armadillo, except for complex numbers.
-Complex numbers are stored in standard C++ notation (a tuple surrounded by brackets: eg. (1.23,4.56) indicates 1.24&nbsp;+&nbsp;4.56i).
-Cubes are loaded as one slice.
-<br>
-<br>
-                        </td>
-                      </tr>
-                      <tr>
-                        <td style="vertical-align: top;"><b>raw_binary</b></td>
-                        <td style="vertical-align: top;"><br>
-                        </td>
-                        <td style="vertical-align: top;">
-Numerical data stored in machine dependent raw binary format, without a header.
-Matrices are loaded to have one column,
-while cubes are loaded to have one slice with one column.
-The <a href="#reshape_member">.reshape()</a> function can be used to alter the size of the loaded matrix/cube without losing data.
-<br>
-<br>
-                        </td>
-                      </tr>
-                      <tr>
-                        <td style="vertical-align: top;"><b>arma_ascii</b></td>
-                        <td style="vertical-align: top;"><br>
-                        </td>
-                        <td style="vertical-align: top;">
-Numerical data stored in human readable text format, with a simple header to speed up loading.
-The header indicates the type of matrix as well as the number of rows and columns.
-For cubes, the header additionally specifies the number of slices.
-<br>
-<br>
-                        </td>
-                      </tr>
-                      <tr>
-                        <td style="vertical-align: top;"><b>arma_binary</b></td>
-                        <td style="vertical-align: top;"><br>
-                        </td>
-                        <td style="vertical-align: top;">
-Numerical data stored in machine dependent binary format, with a simple header to speed up loading.
-The header indicates the type of matrix as well as the number of rows and columns.
-For cubes, the header additionally specifies the number of slices.
-<br>
-<br>
-                        </td>
-                      </tr>
-                      <tr>
-                        <td style="vertical-align: top;"><b>csv_ascii</b></td>
-                        <td style="vertical-align: top;"><br>
-                        </td>
-                        <td style="vertical-align: top;">
-Numerical data stored in comma separated value (CSV) text format, without a header.
-Applicable to <i>Mat</i> only.
-<br>
-<br>
-                        </td>
-                      </tr>
-                      <tr>
-                        <td style="vertical-align: top;"><b>pgm_binary</b></td>
-                        <td style="vertical-align: top;"><br>
-                        </td>
-                        <td style="vertical-align: top;">
-Image data stored in Portable Gray Map (PGM) format.
-Applicable to <i>Mat</i> only.
-Saving <i>int</i>, <i>float</i> or <i>double</i> matrices is a lossy operation, as each element is copied and converted to an 8 bit representation.
-As such the matrix should have values in the [0,255] interval, otherwise the resulting image may not display correctly.
-<br>
-<br>
-                        </td>
-                      </tr>
-                      <tr>
-                        <td style="vertical-align: top;"><b>ppm_binary</b></td>
-                        <td style="vertical-align: top;"><br>
-                        </td>
-                        <td style="vertical-align: top;">
-Image data stored in Portable Pixel Map (PPM) format.
-Applicable to <i>Cube</i> only.
-Saving <i>int</i>, <i>float</i> or <i>double</i> matrices is a lossy operation, as each element is copied and converted to an 8 bit representation.
-As such the cube/field should have values in the [0,255] interval, otherwise the resulting image may not display correctly.
-                        </td>
-                      </tr>
-                    </tbody>
-                  </table>
-</ul>
-</li>
-<br>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-
-A.save("A1.mat");  // default save format is arma_binary
-A.save("A2.mat", arma_ascii);
-
-mat B;
-// automatically detect format type
-B.load("A1.mat");
-
-mat C;
-// force loading in the arma_ascii format
-C.load("A2.mat", arma_ascii);
-
-
-// example of saving/loading using a stream
-std::stringstream s;
-A.save(s);
-
-mat D;
-D.load(s);
-
-
-// example of testing for success
-mat E;
-bool status = E.load("A2.mat");
-
-if(status == true)
-  {
-  cout &lt;&lt; "loaded okay" &lt;&lt; endl;
-  }
-else
-  {
-  cout &lt;&lt; "problem with loading" &lt;&lt; endl;
-  }
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#save_load_field">saving/loading fields</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="save_load_field"></a>
-<b>
-.save(name, file_type = arma_binary)
-<br>
-.save(stream, file_type = arma_binary)
-<br>
-<br>
-.load(name, file_type = auto_detect)
-<br>
-.load(stream, file_type = auto_detect)
-<br>
-<br>
-.quiet_save(name, file_type = arma_binary)
-<br>
-.quiet_save(stream, file_type = arma_binary)
-<br>
-<br>
-.quiet_load(name, file_type = auto_detect)
-<br>
-.quiet_load(stream, file_type = auto_detect)
-</b>
-<ul>
-<li>Member functions of the <i>field</i> class</li>
-<br>
-<li>Store/retrieve fields in files or stream</li>
-<br>
-<li>On success, save(), load(), quiet_save(), and quite_load() will return a <i>bool</i> set to <i>true</i></li>
-<br>
-<li>save() and quiet_save() will return a <i>bool</i> set to <i>false</i> if the saving process fails</li>
-<br>
-<li>
-load() and quiet_load() will return a <i>bool</i> set to <i>false</i> if the loading process fails;
-additionally, the field will be reset so it has no elements
-</li>
-<br>
-<li>load() and save() will print warning messages if any problems are encountered</li>
-<br>
-<li>quiet_load() and quiet_save() do not print any error messages</li>
-<br>
-<li>
-Fields with objects of type <i>std::string</i> are saved and loaded as raw text files.
-The text files do not have a header.
-Each string is separated by a whitespace.
-load() and quiet_load() will only accept text files that have the same number of strings on each line.
-The strings can have variable lengths.
-</li>
-<br>
-<li>
-Other than storing string fields as text files, the following file formats are supported:
-<br>
-<br>
-<ul>
-                  <table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-                    <tbody>
-                      <tr>
-                        <td style="vertical-align: top;"><b>auto_detect</b></td>
-                        <td style="vertical-align: top;"><br>
-                        </td>
-                        <td style="vertical-align: top;">
-<br>
-<li>
-load(): try to automatically detect the field format type as one of the formats described below.
-This is the default operation.
-</li>
-<br>
-                        </td>
-                      </tr>
-                      <tr>
-                        <td style="vertical-align: top;"><b>arma_binary</b></td>
-                        <td style="vertical-align: top;"><br>
-                        </td>
-                        <td style="vertical-align: top;">
-<br>
-<li>
-Objects are stored in machine dependent binary format.
-<li>
-Default type for fields of type <i>Mat</i>, <i>Col</i> or <i>Row</i>.
-</li>
-<li>
-Only applicable to fields of type <i>Mat</i>, <i>Col</i> or <i>Row</i>.
-</li>
-<br>
-                        </td>
-                      </tr>
-                      <tr>
-                        <td style="vertical-align: top;"><b>ppm_binary</b></td>
-                        <td style="vertical-align: top;"><br>
-                        </td>
-                        <td style="vertical-align: top;">
-<br>
-<li>
-Image data stored in Portable Pixmap Map (PPM) format.
-</li>
-<li>
-Only applicable to fields of type <i>Mat</i>, <i>Col</i> or <i>Row</i>.
-</li>
-<li>
-.load(): Loads the specified image and stores the red, green and blue components as three separate matrices.
-The resulting field is comprised of the three matrices,
-with the red, green and blue components in the first, second and third matrix, respectively.
-</li>
-<li>
-.save(): Saves a field with exactly three matrices of equal size as an image.
-It is assumed that the red, green and blue components are stored in the first, second and third matrix, respectively.
-Saving <i>int</i>, <i>float</i> or <i>double</i> matrices is a lossy operation,
-as each matrix element is copied and converted to an 8 bit representation.
-</li>
-
-                        </td>
-                      </tr>
-                    </tbody>
-                  </table>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#save_load_mat">saving/loading matrices and cubes</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="set_imag"></a>
-<b>.set_imag(X)</b>
-<br>
-<b>.set_real(X)</b>
-<br>  
-<ul>
-<li>Member functions of Mat, Col, Row and Cube</li>
-<br>
-<li>
-Set the imaginary/real part of an object
-</li>
-<br>
-<li>
-<i>X</i> must have the same size as the recipient object
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-   mat A = randu&lt;mat&gt;(4,5);
-   mat B = randu&lt;mat&gt;(4,5);
-
-cx_mat C = zeros&lt;mat&gt;(4,5);
-
-C.set_real(A);
-C.set_imag(B);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-<b>Caveat:</b>
-if you want to directly construct a complex matrix out of two real matrices,
-the following code is faster:
-<ul>
-<pre>
-   mat A = randu&lt;mat&gt;(4,5);
-   mat B = randu&lt;mat&gt;(4,5);
-
-cx_mat C = cx_mat(A,B);
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#constructors_mat">matrix constructors</a></li>
-<li><a href="#constructors_cube">cube constructors</a></li>
-<li><a href="#imag_real">imag()&nbsp;/&nbsp;real()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="set_size"></a>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;"><b>.set_size(n_elem)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member function of <i>Col</i>, <i>Row</i>, and <i>field</i>)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.set_size(n_rows, n_cols)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member function of <i>Mat</i> and <i>field</i>)
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;"><b>.set_size(n_rows, n_cols, n_slices)</b></td>
-      <td style="vertical-align: top;"><br>
-      </td>
-      <td style="vertical-align: top;">(member function of <i>Cube</i>)
-      </td>
-    </tr>
-  </tbody>
-</table>
-<br>  
-<ul>
-<li>Changes the size of an object</li>
-<br>
-<li>
-If the requested number of elements is equal to the old number of elements, existing memory is reused
-</li>
-<br>
-<li>
-If the requested number of elements is not equal to the old number of elements, new memory is used
-</li>
-<br>
-<li>
-If you need to explicitly preserve data, use <a href="#reshape_member">.reshape()</a> or <a href="#resize_member">.resize()</a>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A;
-A.set_size(5,10);
-
-vec q;
-q.set_size(100);
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#reset">.reset()</a></li>
-<li><a href="#reshape_member">.reshape()</a></li>
-<li><a href="#resize_member">.resize()</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="shed"></a>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.shed_row(&nbsp;</b>row_number<b>&nbsp;)</b>
-      <br>
-      <b>.shed_rows(&nbsp;</b>first_row, last_row<b>&nbsp;)</b>
-      </td>
-      <td style="vertical-align: top;"><br></td>
-      <td style="vertical-align: top;">(member functions of <i>Mat</i> and <i>Col</i>)
-      </td>
-    </tr>
-    <tr>
-    <td>&nbsp;</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.shed_col(&nbsp;</b>column_number<b>&nbsp;)</b>
-      <br>
-      <b>.shed_cols(&nbsp;</b>first_column, last_column<b>&nbsp;)</b>
-      </td>
-      <td style="vertical-align: top;"><br></td>
-      <td style="vertical-align: top;">(member functions of <i>Mat</i> and <i>Row</i>)
-      </td>
-    </tr>
-    <tr>
-    <td>&nbsp;</td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.shed_slice(&nbsp;</b>slice_number<b>&nbsp;)</b>
-      <br>
-      <b>.shed_slices(&nbsp;</b>first_slice, last_slice<b>&nbsp;)</b>
-      </td>
-      <td style="vertical-align: top;"><br></td>
-      <td style="vertical-align: top;">(member functions of <i>Cube</i>)
-      </td>
-    </tr>
-  </tbody>
-</table>
-<br>
-<ul>
-<li>
-Single argument functions:
-remove the specified row/column/slice
-</li>
-<br>
-<li>
-Two argument functions:
-remove the specified range of rows/columns/slices
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,10);
-
-A.shed_row(2);
-A.shed_cols(2,4);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#insert">insert rows/columns/slices</a></li>
-<li><a href="#join">join rows/columns/slices</a></li>
-<li><a href="#resize_member">.resize()</a></li>
-<li><a href="#submat">submatrix views</a></li>
-<li><a href="#subcube">subcube views</a></li>
-<li><a href="http://thesaurus.com/browse/shed"><i>shed</i> in thesaurus.com</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="stl_container_fns"></a>
-<b>STL container functions</b>
-<ul>
-<li><i>Mat</i>, <i>Col</i> and <i>Row</i> classes provide the following member functions that mimic the containers in the C++ Standard Template Library:<br>
-<br>
-
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.clear()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        causes an object to have no elements
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.empty()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        returns true if the object has no elements; returns false if the object has one or more elements
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      &nbsp;
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.size()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-        returns the total number of elements
-      </td>
-    </tr>
-  </tbody>
-</table>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-cout &lt;&lt; A.size() &lt;&lt; endl;
-
-A.clear();
-cout &lt;&lt; A.empty() &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#iterators_mat">iterators (matrices)</a></li>
-<li><a href="#attributes">matrix and vector attributes</a></li>
-<li><a href="#is_empty">.is_empty()</a></li>
-<li><a href="#reset">.reset()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="submat"></a>
-<b>submatrix views</b>
-<ul>
-<li>A collection of member functions of <i>Mat</i>, <i>Col</i> and <i>Row</i> classes that provide submatrix views<br>
-<br>
-<li>For a matrix or vector <i>X</i>, the subviews are accessed as:</li>
-<br>
-<ul>
-X.<b>col(&nbsp;</b>col_number<b>&nbsp;)</b><br>
-X<b>(</b>&nbsp;<b>span::all,</b> col_number&nbsp;<b>)</b><br>
-X<b>(</b>&nbsp;<b>span(</b>first_row<b>,</b> last_row<b>),</b> col_number&nbsp;<b>)</b><br>
-<br>
-X.<b>unsafe_col(&nbsp;</b>col_number<b>&nbsp;)</b><br>
-<br>
-X.<b>row(&nbsp;</b>row_number<b>&nbsp;)</b><br>
-X<b>(</b>&nbsp;row_number<b>,</b> <b>span::all</b>&nbsp;<b>)</b><br>
-X<b>(</b>&nbsp;row_number<b>,</b> <b>span(</b>first_col<b>,</b> last_col<b>)&nbsp;)</b><br>
-<br>
-X.<b>cols(&nbsp;</b>first_col<b>,</b> last_col<b>&nbsp;)</b><br>
-X.<b>rows(&nbsp;</b>first_row<b>,</b> last_row<b>&nbsp;)</b><br>
-<br>
-X.<b>submat(&nbsp;</b>first_row<b>,</b> first_col<b>,</b> last_row<b>,</b> last_col<b>&nbsp;)</b><br>
-X.<b>submat(&nbsp;span(</b>first_row<b>,</b> last_row<b>), span(</b>first_col<b>,</b> last_col<b>)&nbsp;)</b><br>
-<br>
-X<b>(&nbsp;span(</b>first_row<b>,</b> last_row<b>), span(</b>first_col<b>,</b> last_col<b>)&nbsp;)</b><br>
-<br>
-X.<b>elem(</b>&nbsp;vector_of_indices&nbsp;<b>)</b>
-</ul>
-</li>
-<br>
-<li>For a vector <i>V</i> (column or row vector), there is an additional method:</li>
-<!-- <li>For a vector <i>V</i> (column or row vector), there are three additional methods:</li> -->
-<br>
-<ul>
-V.<b>subvec(&nbsp;</b>first_index<b>,</b> last_index<b>&nbsp;)</b><br>
-<!--
-V.<b>subvec(&nbsp;span(</b>first_index<b>,</b> last_index<b>)&nbsp;)</b><br>
-<br>
-V<b>(&nbsp;span(</b>first_index<b>,</b> last_index<b>)&nbsp;)</b><br>
--->
-</ul>
-<br>
-<li>
-Instances of <i>span::all</i>, to indicate an entire range, can be replaced by <i>span()</i>, where no number is specified
-</li>
-<br>
-<li>
-In the function <i>X.elem(vector_of_indices)</i>,
-elements specified in <i>vector_of_indices</i> are accessed.
-<i>X</i> is interpreted as one long vector,
-with column-by-column ordering of the elements of <i>X</i>.
-The <i>vector_of_indices</i> must evaluate to be a vector of type <i><a href="#Col">uvec</a></i>
-(eg., generated by <i><a href="#find">find()</a></i>).
-The aggregate set of the specified elements is treated as a column vector
-(eg., the output of <i>X.elem()</i> is always a column vector).
-</li>
-<br>
-<li>
-The function <i>.unsafe_col()</i> is provided for speed reasons and should be used only if you know what you're doing.
-The function creates a seemingly independent <i>Col</i> vector object (eg. <i>vec</i>),
-but the vector actually uses memory from the existing matrix object.
-As such, the created <i>Col</i> vector is currently not alias safe
-and does not take into account that the parent matrix object could be deleted.
-If deleted memory is accessed through the created <i>Col</i> vector,
-it will cause memory corruption and/or a crash.
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = zeros&lt;mat&gt;(5,10);
-
-A.submat(0,1,2,3) = randu&lt;mat&gt;(3,3);
-
-// the following three statements
-// access the same part of A
-mat B = A.submat(0,1,2,3);
-mat C = A.submat( span(0,2), span(1,3) );
-mat D = A( span(0,2), span(1,3) );
-
-// the following two statements
-// access the same part of A
-A.col(1)        = randu&lt;mat&gt;(5,1);
-A(span::all, 1) = randu&lt;mat&gt;(5,1);
-
-mat X = randu&lt;mat&gt;(5,5);
-
-// get all elements of X that are greater than 0.5
-vec q = X.elem( find(X > 0.5) );
-
-// set four specific elements of X to 1
-uvec indices;
-indices &lt;&lt; 2 &lt;&lt; 3 &lt;&lt; 6 &lt;&lt; 8;
-
-X.elem(indices) = ones&lt;vec&gt;(4);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#diag">.diag()</a></li>
-<li><a href="#colptr">.colptr()</a></li>
-<li><a href="#in_range">.in_range()</a></li>
-<li><a href="#find">find()</a></li>
-<li><a href="#join">join rows/columns/slices</a></li>
-<li><a href="#shed">shed rows/columns/slices</a></li>
-<li><a href="#insert">insert rows/columns/slices</a></li>
-<li><a href="#subcube">subcube views</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="subcube"></a>
-<b>subcube views and slices</b>
-<ul>
-<li>A collection of member functions of the <i>Cube</i> class that provide subcube views<br>
-<br>
-<li>For a cube <i>Q</i>, the subviews are accessed as:</li>
-<br>
-<ul>
-Q.<b>slice(&nbsp;</b>slice_number&nbsp;<b>)</b><br>
-Q.<b>slices(&nbsp;</b>first_slice<b>,</b> last_slice&nbsp;<b>)</b><br>
-<br>
-Q.<b>subcube(&nbsp;</b>first_row<b>,</b> first_col<b>,</b> first_slice<b>, </b>last_row<b>,</b> last_col<b>, </b>last_slice&nbsp;<b>)</b><br>
-Q.<b>subcube(&nbsp;span(</b>first_row<b>,</b> last_row<b>), span(</b>first_col<b>,</b> last_col<b>), span(</b>first_slice<b>,</b> last_slice<b>)&nbsp;)</b><br>
-<br>
-Q<b>(&nbsp;span(</b>first_row<b>,</b> last_row<b>), span(</b>first_col<b>,</b> last_col<b>), span(</b>first_slice<b>,</b> last_slice<b>)&nbsp;)</b><br>
-</ul>
-</li>
-<br>
-<li>
-Instances of <i>span(a,b)</i> can be replaced by:
-<ul>
-<li><i>span()</i> or <i>span::all</i>, to indicate the entire range</li>
-<li><i>span(a)</i>, to indicate a particular row, column or slice</li>
-</ul>
-</li>
-<br>
-<li>
-An individual slice, accessed via <i>.slice()</i>, is an instance of the <i>Mat</i> class
-(a reference to a matrix is provided)
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-cube A = randu&lt;cube&gt;(2,3,4);
-mat B = A.slice(1);
-
-A.slice(0) = randu&lt;mat&gt;(2,3);
-A.slice(0)(1,2) = 99.0;
-
-A.subcube(0,0,1,  1,1,2) = randu&lt;cube&gt;(2,2,2);
-A( span(0,1), span(0,1), span(1,2) ) = randu&lt;cube&gt;(2,2,2);
-
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#in_range">.in_range()</a></li>
-<li><a href="#join">join slices</a></li>
-<li><a href="#shed">shed slices</a></li>
-<li><a href="#insert">insert slices</a></li>
-<li><a href="#submat">submatrix views</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="subfield"></a>
-<b>subfield views</b>
-<ul>
-<li>A collection of member functions of the <i>field</i> class that provide subfield views<br>
-<br>
-<li>For a field <i>F</i>, the subfields are accessed as:</li>
-<br>
-<ul>
-F.<b>row(&nbsp;</b>row_number&nbsp;<b>)</b><br>
-F.<b>col(&nbsp;</b>col_number&nbsp;<b>)</b><br>
-<br>
-F.<b>rows(&nbsp;</b>first_row<b>,</b> last_row&nbsp;<b>)</b><br>
-F.<b>cols(&nbsp;</b>first_col<b>,</b> last_col&nbsp;<b>)</b><br>
-<br>
-F.<b>subfield(&nbsp;</b>first_row<b>,</b>&nbsp;first_col<b>,</b> last_row<b>,</b>&nbsp;last_col <b>)</b><br>
-F.<b>subfield(&nbsp;span(</b>first_row<b>,</b>&nbsp;last_row<b>), span(</b>first_col<b>,</b>&nbsp;last_col<b>) )</b><br>
-<br>
-F<b>(&nbsp;span(</b>first_row<b>,</b> last_row<b>), span(</b>first_col<b>,</b>&nbsp;last_col<b>) )</b><br>
-</ul>
-</li>
-<br>
-<li>
-Instances of <i>span(a,b)</i> can be replaced by:
-<ul>
-<li><i>span()</i> or <i>span::all</i>, to indicate the entire range</li>
-<li><i>span(a)</i>, to indicate a particular row or column</li>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#in_range">.in_range()</a></li>
-<li><a href="#submat">submatrix views</a></li>
-<li><a href="#subcube">subcube views</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="swap_rows"></a>
-<b>
-.swap_rows(row1, row2)
-<br>.swap_cols(col1, col2)
-</b>
-<ul>
-<li>
-Member functions of <i>Mat</i>, <i>Col</i> and <i>Row</i> classes
-</li>
-<br>
-<li>
-Swap the contents of specified rows or columns
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat X = randu&lt;mat&gt;(5,5);
-X.swap_rows(0,4);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#flip">fliplr() &amp; flipud()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="t_st_members"></a>
-<b>
-.t()
-<br>.st()
-</b>
-<ul>
-<li>
-Member functions of any expression involving matrices or vectors
-</li>
-<br>
-<li>
-<i>.t()</i> provides a transposed copy of the object; if a given object has complex elements, a Hermitian transpose is done (ie. the conjugate of the elements is taken during the transpose operation) 
-</li>
-<br>
-<li>
-<i>.st()</i> provides a transposed copy of the object, without taking the conjugate of the elements (complex matrices)
-</li>
-<br>
-<li>
-For non-complex objects, the <i>.t()</i> and <i>.st()</i> functions are equivalent
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(4,5);
-mat B = A.t();
-</pre>
-</ul>
-</li>
-<br>
-<li>
-The <i>.t()</i> and <i>.st()</i> functions were added in version 2.4
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#trans">trans()</a></li>
-<li><a href="#strans">strans()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="zeros_member"></a>
-<b>.zeros()</b>
-<br><b>.zeros(n_elem)</b>
-<br><b>.zeros(n_rows, n_cols)</b>
-<br><b>.zeros(n_rows, n_cols, n_slices)</b>
-<ul>
-<li>
-Set the elements of an object to zero, optionally first resizing to specified dimensions
-</li>
-<br>
-<li>
-<i>.zeros()</i> and <i>.zeros(n_elem)</i> are member function of <i>Col</i> and <i>Row</i>
-</li>
-<br>
-<li>
-<i>.zeros()</i> and <i>.zeros(n_rows, n_cols)</i> are member functions of <i>Mat</i>
-</li>
-<br>
-<li>
-<i>.zeros()</i> and <i>.zeros(n_rows, n_cols, n_slices)</i> are member functions of <i>Cube</i>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,10);
-A.zeros();      // sets all elements to zero
-A.zeros(10,20); // sets the size to 10 rows and 20 columns
-                // followed by setting all elements to zero
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#zeros_standalone">zeros()</a> (standalone function)</li>
-<li><a href="#ones_member">.ones()</a></li>
-<li><a href="#fill">.fill()</a></li>
-<li><a href="#reset">.reset()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline">
-
-
-<hr class="greyline">
-<br>
-<br>
-<font size=+1><b>Other Classes</b></font>
-<br>
-<br>
-<hr class="greyline">
-<br>
-
-<a name="running_stat"></a>
-<b>running_stat&lt;</b><i>type</i><b>&gt;</b>
-<ul>
-<li>
-Class for keeping statistics of a continuously sampled one dimensional process/signal.
-Useful if the storage of individual samples (scalars) is not necessary or desired.
-Also useful if the number of samples is not known beforehand or exceeds available memory.
-</li>
-<br>
-<li>
-<i>type</i> should be one of: <i>float</i>, <i>double</i>, <i><a href="#cx_float_double">cx_float</a></i>, <i><a href="#cx_float_double">cx_double</a></i>
-</li>
-<br>
-<li>
-Member functions:
-<ul>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.operator()(</b>scalar<b>)</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      update the statistics so far using the given scalar
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.mean()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      get the mean or average value so far
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.var(</b>norm_type=0<b>)</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      get the variance so far
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.stddev(</b>norm_type=0<b>)</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      get the standard deviation so far
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.min()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      get the minimum value so far
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.max()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      get the maximum value so far
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.reset()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      reset all statistics and set the number of samples to zero
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.count()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      get the number of samples so far
-      </td>
-    </tr>
-  </tbody>
-</table>
-</ul>
-</li>
-<br>
-<li>
-For the .var() and .stddev() functions, the default <i>norm_type=0</i> performs normalisation using <i>N-1</i>
-(where <i>N</i> is the number of samples so far),
-providing the best unbiased estimator.
-Using <i>norm_type=1</i> causes normalisation to be done using <i>N</i>, which provides the second moment around the mean.
-</li>
-<br>
-<li>
-The return type of .count() depends on the underlying form of <i>type</i>: it is either <i>float</i> or <i>double</i>.
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-running_stat&lt;double&gt; stats;
-
-for(uword i=0; i&lt;10000; ++i)
-  {
-  double sample = double(rand())/RAND_MAX;
-  stats(sample);
-  }
-
-cout &lt;&lt; "mean = " &lt;&lt; stats.mean() &lt;&lt; endl;
-cout &lt;&lt; "var  = " &lt;&lt; stats.var()  &lt;&lt; endl;
-cout &lt;&lt; "min  = " &lt;&lt; stats.min()  &lt;&lt; endl;
-cout &lt;&lt; "max  = " &lt;&lt; stats.max()  &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#stats_fns">statistics functions</a></li>
-<li><a href="#running_stat_vec">running_stat_vec</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="running_stat_vec"></a>
-<b>running_stat_vec&lt;</b><i>type</i><b>&gt;(calc_cov = false)</b>
-<ul>
-<li>
-Class for keeping statistics of a continuously sampled multi-dimensional process/signal.
-Useful if the storage of individual samples is not necessary or desired.
-Also useful if the number of samples is not known beforehand or exceeds available memory.
-</li>
-<br>
-<li>
-This class is similar to <i>running_stat</i>, with the difference being that vectors are processed instead of single values.
-</li>
-<br>
-<li>
-<i>type</i> must match the element type used by the sample vectors
-(ie. it must be one of <i>float</i>, <i>double</i>, <i><a href="#cx_float_double">cx_float</a></i>, <i><a href="#cx_float_double">cx_double</a></i>)
-</li>
-<br>
-<li>
-<i>type</i> can be inferred via the use of the <i>elem_type</i> member typedef of a vector class.
-For example, <i>fvec::elem_type</i> will be interpreted as <i>float</i>,
-while <i>cx_vec::elem_type</i> will be interpreted as <i><a href="#cx_float_double">cx_double</a></i>.
-</li>
-<br>
-<li>
-Member functions:
-<ul>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-  <tbody>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.operator()(</b>vector<b>)</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      update the statistics so far using the given vector
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.mean()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      get the mean vector so far
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.var(</b>norm_type=0<b>)</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      get the vector of variances so far
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.stddev(</b>norm_type=0<b>)</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      get the vector of standard deviations so far
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.min()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      get the vector of minimum values so far
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.max()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      get the vector of maximum values so far
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.cov(</b>norm_type=0<b>)</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      get the covariance matrix so far
-      <br>NOTE: this only works if <i>calc_cov</i> is set to <i>true</i> during the construction of the class
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.reset()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      reset all statistics and set the number of samples to zero
-      </td>
-    </tr>
-    <tr>
-      <td style="vertical-align: top;">
-      <b>.count()</b>
-      </td>
-      <td style="vertical-align: top;">&nbsp;<br>
-      </td>
-      <td style="vertical-align: top;">
-      get the number of samples so far
-      </td>
-    </tr>
-  </tbody>
-</table>
-</ul>
-</li>
-<br>
-<li>
-For the .var() and .stddev() functions, the default <i>norm_type=0</i> performs normalisation using <i>N-1</i>
-(where <i>N</i> is the number of samples so far),
-providing the best unbiased estimator.
-Using <i>norm_type=1</i> causes normalisation to be done using <i>N</i>, which provides the second moment around the mean.
-</li>
-<br>
-<li>
-The return type of .count() depends on the underlying form of <i>type</i>: it is either <i>float</i> or <i>double</i>.
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-running_stat_vec&lt;rowvec::elem_type&gt; stats;
-
-rowvec sample;
-
-for(uword i=0; i&lt;10000; ++i)
-  {
-  sample = randu&lt;rowvec&gt;(5);
-  stats(sample);
-  }
-
-cout &lt;&lt; "mean = " &lt;&lt; stats.mean() &lt;&lt; endl;
-cout &lt;&lt; "var  = " &lt;&lt; stats.var()  &lt;&lt; endl;
-cout &lt;&lt; "min  = " &lt;&lt; stats.min()  &lt;&lt; endl;
-cout &lt;&lt; "max  = " &lt;&lt; stats.max()  &lt;&lt; endl;
-
-//
-//
-
-running_stat_vec&lt;rowvec::elem_type&gt; more_stats(true);
-
-for(uword i=0; i&lt;20; ++i)
-  {
-  sample = randu&lt;rowvec&gt;(3);
-  
-  sample(1) -= sample(0);
-  sample(2) += sample(1);
-  
-  more_stats(sample);
-  }
-
-cout &lt;&lt; "covariance matrix = " &lt;&lt; endl;
-cout &lt;&lt; more_stats.cov() &lt;&lt; endl;
-
-rowvec sd = more_stats.stddev();
-
-cout &lt;&lt; "correlations = " &lt;&lt; endl;
-cout &lt;&lt; more_stats.cov() / (trans(sd) * sd);
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#cov">cov()</a></li>
-<li><a href="#cor">cor()</a></li>
-<li><a href="#running_stat">running_stat</a></li>
-<li><a href="#stats_fns">statistics functions</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="wall_clock"></a>
-<b>wall_clock</b>
-<ul>
-<li>
-Simple wall clock timer class, for measuring the number of elapsed seconds between two intervals
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-wall_clock timer;
-
-mat A = randu&lt;mat&gt;(4,4);
-mat B = randu&lt;mat&gt;(4,4);
-mat C;
-
-timer.tic();
-for(uword i=0; i&lt;100000; ++i)
-  C = A + B + A + B;
-
-double n_secs = timer.toc();
-cout &lt;&lt; "took " &lt;&lt; n_secs &lt;&lt; " seconds" &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline">
-
-<hr class="greyline">
-<br>
-<br>
-<font size=+1><b>Generated Vectors/Matrices</b></font>
-<br>
-<br>
-<hr class="greyline">
-<br>
-
-<a name="eye_standalone"></a>
-<b>eye(n_rows, n_cols)</b>
-<ul>
-<li>
-Generate a matrix with the elements along the main diagonal set to one
-and off-diagonal elements set to zero
-</li>
-<br>
-<li>
-An identity matrix is generated when <i>n_rows</i> = <i>n_cols</i>
-</li>
-<br>
-<li>
-Usage:
-<ul>
-<li>
-<i>matrix_type</i> X = eye&lt;<i>matrix_type</i>&gt;(n_rows, n_cols)
-</li>
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = eye&lt;mat&gt;(5,5);
-mat B = 123.0 * eye&lt;mat&gt;(5,5);
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#eye_member">.eye()</a> (member function of Mat)</li>
-<li><a href="#ones_standalone">ones()</a></li>
-<li><a href="#diagmat">diagmat()</a></li>
-<li><a href="#diagvec">diagvec()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="linspace"></a>
-<b>linspace(start, end, N=100)</b>
-<ul>
-<li>
-Generate a vector with <i>N</i> elements;
-the values of the elements linearly increase from <i>start</i> upto (and including) <i>end</i>
-<br>
-</li>
-<br>
-<li>
-Usage:
-<ul>
-<li><i>vector_type</i> v = linspace&lt;<i>vector_type</i>&gt;(start, end, N)</li>
-<li><i>matrix_type</i> X = linspace&lt;<i>matrix_type</i>&gt;(start, end, N)</li>
-</ul>
-</li>
-<br>
-<li>
-If a <i>matrix_type</i> is specified, the resultant matrix will have one column
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-vec v = linspace&lt;vec&gt;(10, 20, 5);
-mat X = linspace&lt;mat&gt;(10, 20, 5);
-</pre>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="ones_standalone"></a>
-<b>
-ones(n_elem)
-<br>ones(n_rows, n_cols)
-<br>ones(n_rows, n_cols, n_slices)
-</b>
-<ul>
-<li>
-Generate a vector, matrix or cube with all elements set to one
-</li>
-<br>
-<li>
-Usage:
-<ul>
-<li><i>vector_type</i> v = ones&lt;<i>vector_type</i>&gt;(n_elem)</li>
-<li><i>matrix_type</i> X = ones&lt;<i>matrix_type</i>&gt;(n_rows, n_cols)</li>
-<li><i>cube_type</i> Q = ones&lt;<i>cube_type</i>&gt;(n_rows, n_cols, n_slices)</li>
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-vec  v = ones&lt;vec&gt;(10);
-mat  A = ones&lt;mat&gt;(5,6);
-cube Q = ones&lt;cube&gt;(5,6,7);
-
-mat  B = 123.0 * ones&lt;mat&gt;(5,6);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#ones_member">.ones()</a> (member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i>)</li>
-<li><a href="#eye_standalone">eye()</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="randu_randn_standalone"></a>
-<b>randu(n_elem)</b> 
-<br><b>randu(n_rows, n_cols)</b>
-<br><b>randu(n_rows, n_cols, n_slices)</b>
-<br>
-<br><b>randn(n_elem)</b>
-<br><b>randn(n_rows, n_cols)</b>
-<br><b>randn(n_rows, n_cols, n_slices)</b>
-<ul>
-<li>
-Generate a vector, matrix or cube with the elements set to random values
-</li>
-<br>
-<li><i>randu()</i> uses a uniform distribution in the [0,1] interval
-</li>
-<br>
-<li><i>randn()</i> uses a normal/Gaussian distribution with zero mean and unit variance
-</li>
-<br>
-<li>
-Usage:
-<ul>
-<li><i>vector_type</i> v = randu&lt;<i>vector_type</i>&gt;(n_elem)</li>
-<li><i>matrix_type</i> X = randu&lt;<i>matrix_type</i>&gt;(n_rows, n_cols)</li>
-<li><i>cube_type</i> Q = randu&lt;<i>cube_type</i>&gt;(n_rows, n_cols, n_slices)</li>
-</ul>
-</li>
-<br>
-<li>
-To change the seed, use the <a href="http://cplusplus.com/reference/clibrary/cstdlib/srand/">std::srand()</a> function.
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-vec  v = randu&lt;vec&gt;(5);
-mat  A = randu&lt;mat&gt;(5,6);
-cube Q = randu&lt;cube&gt;(5,6,7);
-</pre>
-</ul>
-</li>
-<li>See also:
-<ul>
-<li><a href="#randu_randn_member">.randu() &amp; .randn()</a> (member functions)</li>
-<li><a href="#ones_standalone">ones()</a></li>
-<li><a href="#zeros_standalone">zeros()</a></li>
-<li><a href="#shuffle">shuffle()</a></li>
-<li><a href="http://cplusplus.com/reference/clibrary/cstdlib/srand/">std::srand()</a></li>
-<li><a href="#api_changes">API changes</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="repmat"></a>
-<b>repmat(A, num_copies_per_row, num_copies_per_col)</b>
-<ul>
-<li>Generate a matrix by replicating matrix A in a block-like fashion</li>
-<br>
-<li>The generated matrix has the following size:
-<ul>
-rows = num_copies_per_row * A.n_rows
-<br>
-cols = num_copies_per_col * A.n_cols
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(2, 3);
-
-mat B = repmat(A, 4, 5);
-</pre>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline">
-<br>
-
-<a name="toeplitz"></a>
-<b>toeplitz(A)</b>
-<br><b>toeplitz(A,B)</b>
-<br><b>circ_toeplitz(A)</b>
-<ul>
-<li>
-toeplitz(): generate a Toeplitz matrix, with the first column specified by <i>A</i>, and (optionally) the first row specified by <i>B</i>
-</li>
-<br>
-<li>
-circ_toeplitz(): generate a circulant Toeplitz matrix
-</li>
-<br>
-<li>
-A and B must be vectors
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-vec A = randu&lt;vec&gt;(5);
-mat X = toeplitz(A);
-mat Y = circ_toeplitz(A);
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="http://mathworld.wolfram.com/ToeplitzMatrix.html">Toeplitz matrix in MathWorld</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Toeplitz_matrix">Toeplitz matrix in Wikipedia</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Circulant_matrix">Circulant matrix in Wikipedia</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline">
-<br>
-
-<a name="zeros_standalone"></a>
-<b>zeros(n_elem)</b>
-<br><b>zeros(n_rows, n_cols)</b>
-<br><b>zeros(n_rows, n_cols, n_slices)</b>
-<ul>
-<li>
-Generate a vector, matrix or cube with the elements set to zero
-</li>
-<br>
-<li>
-Usage:
-<ul>
-<li><i>vector_type</i> v = zeros&lt;<i>vector_type</i>&gt;(n_elem)</li>
-<li><i>matrix_type</i> X = zeros&lt;<i>matrix_type</i>&gt;(n_rows, n_cols)</li>
-<li><i>cube_type</i> X = zeros&lt;<i>cube_type</i>&gt;(n_rows, n_cols, n_slices)</li>
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-vec  v = zeros&lt;vec&gt;(5);
-mat  A = zeros&lt;mat&gt;(5,6);
-cube Q = zeros&lt;cube&gt;(5,6,7);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#zeros_member">.zeros()</a> (member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i>)</li>
-<li><a href="#ones_member">.ones()</a> (member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i>)</li>
-<li><a href="#ones_standalone">ones()</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline">
-
-<hr class="greyline">
-<br>
-<br>
-<font size=+1><b>Functions Individually Applied to Each Element of a Matrix/Cube</b></font>
-<br>
-<br>
-<hr class="greyline">
-<br>
-
-<a name="abs"></a>
-<b>abs(mat)</b>
-<br><b>abs(cube)</b>
-<br><b>abs(cx_mat)</b>
-<br><b>abs(cx_cube)</b>
-<ul>
-<li>
-Obtain the magnitude of each element
-</li>
-<br>
-<li>
-Usage for non-complex matrices:
-<ul>
-<li><i>matrix_type</i> Y = abs(X)</li>
-<li>X and Y must have the same <i>matrix_type</i></li>
-</ul>
-</li>
-<br>
-<li>
-Usage for non-complex cubes:
-<ul>
-<li><i>cube_type</i> Y = abs(X)</li>
-<li>X and Y must have the same <i>cube_type</i></li>
-</ul>
-</li>
-<br>
-<li>
-Usage for complex matrices:
-<ul>
-<li><i>non_complex_matrix_type</i> Y = abs(X)</li>
-<li>X must be a have complex matrix type, eg., <i>cx_mat</i> or <i>cx_fmat</i></li>
-<li>The type of Y must be related to the type of X,
-eg., if X has the type <i>cx_mat</i>, then the type of Y must be <i>mat</i>
-</ul>
-</li>
-<br>
-<li>
-Usage for complex cubes:
-<ul>
-<li><i>non_complex_cube_type</i> Y = abs(X)</li>
-<li>X must be a have complex cube type, eg., <i>cx_cube</i> or <i>cx_fcube</i></li>
-<li>The type of Y must be related to the type of X,
-eg., if X has the type <i>cx_cube</i>, then the type of Y must be <i>cube</i>
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-mat B = abs(A); 
-
-cx_mat X = randu&lt;cx_mat&gt;(5,5);
-mat    Y = abs(X);
-</pre>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="eps"></a>
-<b>eps(X)</b>
-<ul>
-<li>
-Obtain the positive distance of the absolute value of each element of <i>X</i> to the next largest representable floating point number
-</li>
-<br>
-<li>
-<i>X</i> can be a scalar (eg. <i>double</i>), vector or matrix
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(4,5);
-mat B = eps(A);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#math_constants">math::eps()</a></li>
-<li><a href="http://mathworld.wolfram.com/Floating-PointArithmetic.html">Floating-Point Arithmetic in MathWorld</a></li>
-<li><a href="http://en.wikipedia.org/wiki/IEEE_754-2008">IEEE Standard for Floating-Point Arithmetic in Wikipedia</a></li>
-
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="misc_fns"></a>
-<b>
-miscellaneous functions:
-<br>&nbsp; exp, exp2, exp10, trunc_exp, 
-<br>&nbsp; log, log2, log10, trunc_log,
-<br>&nbsp; pow, sqrt, square
-<br>&nbsp; floor, ceil
-</b>
-<br>
-<ul>
-<li>
-Apply a function to each element
-</li>
-<br>
-<li>
-Usage:
-<ul>
-<li>
-<i>matrix_type</i> B = misc_fn(A)
-</li>
-<li>
-<i>cube_type</i> B = misc_fn(A)
-</li>
-<li>
-A and B must have the same <i>matrix_type/cube_type</i>
-</li>
-<li>
-misc_fn(A) is one of:
-<ul>
-
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-<tbody>
-  <tr>
-    <td style="vertical-align: top;">
-       exp(A)<sup>&nbsp;</sup>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      base-e exponential, <i>e<sup>x</sup></i>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-       exp2(A)<sup>&nbsp;</sup>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      base-2 exponential, <i>2<sup>x</sup></i>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-       exp10(A)<sup>&nbsp;</sup>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      base-10 exponential, <i>10<sup>x</sup></i>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      trunc_exp(A)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      base-e exponential,
-      truncated to avoid infinity
-      <br>
-      <font size=-1>(only for elements with type <i>float</i> or <i>double</i>)</font>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-       log(A)<sub>&nbsp;</sub>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      natural log, <i>log<sub>e</sub>&nbsp;x</i>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-       log2(A)<sub>&nbsp;</sub>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      base-2 log, <i>log<sub>2</sub>&nbsp;x</i>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-       log10(A)<sub>&nbsp;</sub>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      base-10 log, <i>log<sub>10</sub>&nbsp;x</i>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      trunc_log(A)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      natural log,
-      truncated to avoid &plusmn;infinity
-      <br>
-      <font size=-1>(only for elements with type <i>float</i> or <i>double</i>)</font>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-       pow(A, p)<sup>&nbsp;</sup>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      raise to the power of p, <i>x<sup>p</sup></i>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-       sqrt(A)<sup>&nbsp;</sup>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      square root, <i>x<sup>&frac12;</sup></i>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      square(A)<sup>&nbsp;</sup>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      square, <i>x<sup>2</sup></i>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      floor(A)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      largest integral value that is not greater than the input value
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      ceil(A)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      smallest integral value that is not less than the input value
-    </td>
-  </tr>
-</tbody>
-</table>
-
-
-</ul>
-</li>
-
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-mat B = exp(A);
-</pre>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="trig_fns"></a>
-<b>trigonometric functions (cos, sin, tan, ...)</b>
-<ul>
-<li>
-Apply a trigonometric function to each element
-</li>
-<br>
-<li>
-Usage:
-<ul>
-<li>
-<i>matrix_type</i> Y = trig_fn(X)
-</li>
-<li>
-<i>cube_type</i> Y = trig_fn(X)
-</li>
-<li>
-X and Y must have the same <i>matrix_type/cube_type</i>
-</li>
-<li>
-trig_fn is one of:
-<ul>
-<li>
-cos family: <i>cos</i>, <i>acos</i>, <i>cosh</i>, <i>acosh</i>
-</li>
-<li>
-sin family: <i>sin</i>, <i>asin</i>, <i>sinh</i>, <i>asinh</i>
-</li>
-<li>
-tan family: <i>tan</i>, <i>atan</i>, <i>tanh</i>, <i>atanh</i>
-</li>
-</ul>
-</li>
-
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat X = randu&lt;mat&gt;(5,5);
-mat Y = cos(X);
-</pre>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline">
-
-<hr class="greyline">
-<br>
-<br>
-<font size=+1><b>Scalar Valued Functions of Vectors/Matrices/Cubes</b></font>
-<br>
-<br>
-<hr class="greyline">
-<br>
-
-<a name="accu"></a>
-<b>accu(mat)</b>
-<br><b>accu(cube)</b>
-<ul>
-<li>
-Accumulate (sum) all elements
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-double x = accu(A);
-
-mat B = randu&lt;mat&gt;(5,5);
-double y = accu(A % B);
-
-// operator % performs element-wise multiplication,
-// hence accu(A % B) is a "multiply-and-accumulate"
-// operation
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#sum">sum()</a></li>
-<li><a href="#cumsum">cumsum()</a></li>
-<li><a href="#as_scalar">as_scalar()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="as_scalar"></a>
-<b>as_scalar(expression)</b>
-<ul>
-<li>
-Evaluate an expression that results in a 1x1 matrix,
-followed by converting the 1x1 matrix to a pure scalar
-</li>
-<br>
-<li>
-If a binary or trinary expression is given (ie. 2 or 3 terms),
-the function will try to exploit the fact that the result is a 1x1 matrix
-by using optimised expression evaluations
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-rowvec r = randu&lt;rowvec&gt;(5);
-colvec q = randu&lt;colvec&gt;(5);
-mat    X = randu&lt;mat&gt;(5,5);
-
-// examples of some expressions
-// for which optimised implementations exist
-
-double a = as_scalar(r*q);
-double b = as_scalar(r*X*q);
-double c = as_scalar(r*diagmat(X)*q);
-double d = as_scalar(r*inv(diagmat(X))*q);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#accu">accu()</a></li>
-<li><a href="#conv_to">conv_to()</a></li>
-<li><a href="#dot">dot()</a></li>
-<li><a href="#norm">norm()</a></li>
-<li><a href="#reshape">reshape()</a></li>
-<li><a href="#resize">resize()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-                  
-<a name="det"></a>
-<b>det(A, slow = <i>false</i>)</b>
-<ul>
-<li>
-Determinant of square matrix <i>A</i>
-</li>
-<br>
-<li>
-If <i>A</i> is not square, a <i>std::logic_error</i> exception is thrown 
-</li>
-<br>
-<li>
-<b>Caveat</b>: for large matrices you may want to use <a href="#log_det">log_det()</a> instead
-</li>
-<br>
-<li>
-For matrix sizes &le; 4x4, a fast algorithm is used by default.
-In rare instances, the fast algorithm might be less precise than the standard algorithm.
-To force the use of the standard algorithm, set the <i>slow</i> argument to <i>true</i>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat    A = randu&lt;mat&gt;(5,5);
-double x = det(A);
-
-mat44  B = randu&lt;mat&gt;(4,4);
-
-double y = det(B);       // use fast algorithm by default
-double z = det(B, true); // use slow algorithm
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#log_det">log_det()</a></li>
-<li><a href="http://mathworld.wolfram.com/Determinant.html">determinant in MathWorld</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Determinant">determinant in Wikipedia</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="dot"></a>
-<b>dot(A, B)</b>
-<br><b>cdot(A, B)</b>
-<br><b>norm_dot(A, B)</b>
-<ul>
-<li>
-<i>dot(A,B)</i>: dot product of A and B, under the assumption that A and B are vectors with the same number of elements
-</li>
-<br>
-<li>
-<i>cdot(A,B)</i>: as per <i>dot(A,B)</i>, but the complex conjugate of A is used
-</li>
-<br>
-<li>
-<i>norm_dot(A,B)</i>: normalised version of <i>dot(A,B)</i>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-vec a = randu&lt;vec&gt;(10);
-vec b = randu&lt;vec&gt;(10);
-
-double x = dot(a,b);
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#as_scalar">as_scalar()</a></li>
-<li><a href="#cross">cross()</a></li>
-<li><a href="#conj">conj()</a></li>
-<li><a href="#norm">norm()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="log_det"></a>
-<b>log_det(val, sign, A)</b>
-<ul>
-<li>
-Log determinant of square matrix <i>A</i>, such that the determinant is equal to <i>exp(val)*sign</i>
-</li>
-<br>
-<li>
-If <i>A</i> is not square, a <i>std::logic_error</i> exception is thrown 
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-
-double val;
-double sign;
-
-log_det(val, sign, A);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#det">det()</a></li>
-<li><a href="http://mathworld.wolfram.com/Determinant.html">determinant in MathWorld</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Determinant">determinant in Wikipedia</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="norm"></a>
-<b>
-norm(X, p)
-</b>
-<ul>
-<li>
-Compute the <i>p</i>-norm of <i>X</i>, where <i>X</i> can be a vector or a matrix
-</li>
-<br>
-<li>
-For vectors, <i>p</i> is an integer &ge;1, or one of: "-inf", "inf", "fro"
-</li>
-<br>
-<li>
-For matrices, <i>p</i> is one of: 1, 2, "inf", "fro"
-</li>
-<br>
-<li>
-"-inf" is the minimum norm, "inf" is the maximum norm, while "fro" is the Frobenius norm
-</li>
-<br>
-<li>
-To obtain the zero norm or Hamming norm (ie. the number of non-zero elements),
-you may want to use this expression: <a href="#accu">accu</a>(X&nbsp;!=&nbsp;0).
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-vec    q = randu&lt;vec&gt;(5);
-double x = norm(q, 2);
-double y = norm(q, "inf");
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#dot">dot()</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Norm_(mathematics)">Vector Norm in Wikipedia</a></li>
-<li><a href="http://mathworld.wolfram.com/VectorNorm.html">Vector Norm in MathWorld</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Matrix_norm">Matrix Norm in Wikipedia</a></li>
-<li><a href="http://mathworld.wolfram.com/MatrixNorm.html">Matrix Norm in MathWorld</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="rank"></a>
-<b>rank(X, tolerance = default)</b>
-
-<ul>
-<li>Returns the rank of matrix <i>X</i></li><br>
-<li>Any singular values less than default tolerance are treated as zero</li><br>
-<li>The default tolerance is <i>max(X.n_rows, X.n_cols)*eps(sigma)</i>,
-where <i>sigma</i> is the largest singular value of <i>X</i>
-</li><br>
-<li>The computation is based on singular value decomposition;
-if the decomposition fails, a <i>std::runtime_error</i> exception is thrown</li><br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(4,5);
-uword r = rank(A);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#eps">eps()</a></li>
-<li><a href="http://mathworld.wolfram.com/MatrixRank.html">Rank in MathWorld</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Rank_(linear_algebra)">Rank in Wikipedia</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="trace"></a>
-<b>trace(mat)</b>
-<ul>
-<li>
-Sum of the diagonal elements of a square matrix
-</li>
-<br>
-<li>
-A <i>std::logic_error</i> exception is thrown if the given matrix is not square
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-double x = trace(A);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#diag">.diag()</a></li>
-<li><a href="#diagvec">diagvec()</a></li>
-<li><a href="#sum">sum()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline">
-
-<hr class="greyline">
-<br>
-<br>
-<font size=+1><b>Scalar/Vector Valued Functions of Vectors/Matrices</b></font>
-<br>
-<br>
-<hr class="greyline">
-<br>
-
-<a name="diagvec"></a>
-<b>diagvec(A, k=0)</b>
-<ul>
-<li>
-Extract the <i>k</i>-th diagonal from matrix <i>A</i>
-</li>
-<br>
-<li>
-The argument <i>k</i> is optional -- by default the main diagonal is extracted (<i>k=0</i>)
-</li>
-<br>
-<li>For <i>k &gt; 0</i>, the <i>k</i>-th super-diagonal is extracted (top-right corner)</li>
-<br>
-<li>For <i>k &lt; 0</i>, the <i>k</i>-th sub-diagonal is extracted (bottom-left corner)</li>
-<br>
-<li>
-An extracted a diagonal is interpreted as a column vector
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-vec d = diagvec(A);
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#diag">.diag()</a></li>
-<li><a href="#diagmat">diagmat()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline">
-<br>
-
-<a name="min_and_max"></a>
-<b>min(mat, dim=0)</b>
-<br><b>min(rowvec)</b>
-<br><b>min(colvec)</b>
-<br>
-<br><b>max(mat, dim=0)</b>
-<br><b>max(rowvec)</b>
-<br><b>max(colvec)</b>
-<ul>
-<li>
-For a matrix argument, return the extremum value for each column (dim=0), or each row (dim=1)
-</li>
-<br>
-<li>
-For a vector argument, return the extremum value
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-colvec q = randu&lt;colvec&gt;(10,1);
-double x = max(q);
-
-mat    A = randu&lt;mat&gt;(10,10);
-rowvec b = max(A);
-
-// same result as max(A)
-// the 0 explicitly indicates
-// "traverse across rows"
-rowvec c = max(A,0); 
-
-// the 1 explicitly indicates
-// "traverse across columns"
-colvec d = max(A,1);
-
-// find the overall maximum value
-double y = max(max(A));
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#min_and_max_member">.min() &amp; .max()</a> (member functions of Mat and Cube)</li>
-<li><a href="#running_stat">running_stat</a></li>
-<li><a href="#running_stat_vec">running_stat_vec</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="prod"></a>
-<b>prod(mat, dim=0)</b>
-<br><b>prod(rowvec)</b>
-<br><b>prod(colvec)</b>
-<ul>
-<li>
-For a matrix argument, return the product of elements in each column (dim=0), or each row (dim=1)
-</li>
-<br>
-<li>
-For a vector argument, return the product of all elements
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-colvec q = randu&lt;colvec&gt;(10,1);
-double x = prod(q);
-
-mat    A = randu&lt;mat&gt;(10,10);
-rowvec b = prod(A);
-
-// same result as prod(A)
-// the 0 explicitly indicates
-// "traverse across rows"
-rowvec c = prod(A,0);
-
-// the 1 explicitly indicates
-// "traverse across columns"
-colvec d = prod(A,1);
-
-// find the overall product
-double y = prod(prod(A));
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#schur_product">Schur product</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-
-<a name="sum"></a>
-<b>sum(mat, dim=0)</b>
-<br><b>sum(rowvec)</b>
-<br><b>sum(colvec)</b>
-<ul>
-<li>
-For a matrix argument, return the sum of elements in each column (dim=0), or each row (dim=1)
-</li>
-<br>
-<li>
-For a vector argument, return the sum of all elements
-</li>
-<br>
-<li>
-To get a sum of all the elements regardless of the argument type (ie. matrix or vector),
-you may wish to use <a href="#accu">accu()</a> instead
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-colvec q = randu&lt;colvec&gt;(10,1);
-double x = sum(q);
-
-mat    A = randu&lt;mat&gt;(10,10);
-rowvec b = sum(A);
-
-// same result as sum(A)
-// the 0 explicitly indicates
-// "traverse across rows"
-rowvec c = sum(A,0);
-
-// the 1 explicitly indicates
-// "traverse across columns"
-colvec d = sum(A,1);
-
-// find the overall sum
-double y = sum(sum(A));
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#accu">accu()</a></li>
-<li><a href="#cumsum">cumsum()</a></li>
-<li><a href="#trace">trace()</a></li>
-<li><a href="#as_scalar">as_scalar()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-
-<a name="stats_fns"></a>
-<b>statistics: mean, median, stddev, var</b>
-
-<ul>
-<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
-<tbody>
-  <tr>
-    <td style="vertical-align: top;">
-       <b>mean(mat, dim=0)</b>
-       <br><b>mean(colvec)</b>
-       <br><b>mean(rowvec)</b>
-       <br>
-       <br>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      mean (average value)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-       <b>median(mat, dim=0)</b>
-       <br><b>median(colvec)</b>
-       <br><b>median(rowvec)</b>
-       <br>
-       <br>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      median
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-       <b>stddev(mat, norm_type=0, dim=0)</b>
-       <br><b>stddev(colvec, norm_type=0)</b>
-       <br><b>stddev(rowvec, norm_type=0)</b>
-       <br>
-       <br>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      standard deviation
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-       <b>var(mat, norm_type=0, dim=0)</b>
-       <br><b>var(colvec, norm_type=0)</b>
-       <br><b>var(rowvec, norm_type=0)</b>
-       <br>
-       <br>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      variance
-    </td>
-  </tr>
-</tbody>
-</table>
-<br>
-<li>
-For a matrix argument, find a particular statistic for each column (<i>dim=0</i>), or each row (<i>dim=1</i>)
-</li>
-<br>
-<li>
-For a vector argument, return a particular statistic calculated using all the elements of the vector
-</li>
-<br>
-<li>
-For the var() and stddev() functions, the default <i>norm_type=0</i> performs normalisation using <i>N-1</i> (where <i>N</i> is the number of samples),
-providing the best unbiased estimator.
-Using <i>norm_type=1</i> causes normalisation to be done using <i>N</i>, which provides the second moment around the mean
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A    = randu&lt;mat&gt;(5,5);
-mat B    = mean(A);
-mat C    = var(A);
-double m = mean(mean(A));
-
-vec    q = randu&lt;vec&gt;(5);
-double v = var(q);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#cov">cov()</a></li>
-<li><a href="#cor">cor()</a></li>
-<li><a href="#running_stat">running_stat</a></li>
-<li><a href="#running_stat_vec">running_stat_vec</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline">
-
-<hr class="greyline">
-<br>
-<br>
-<font size=+1><b>Vector/Matrix/Cube Valued Functions of Vectors/Matrices/Cubes</b></font>
-<br>
-<br>
-<hr class="greyline">
-<br>
-
-<a name="conv"></a>
-<b>
-C = conv(A, B)
-</b>
-<ul>
-<li>
-Convolution of vectors A and B.
-</li>
-<br>
-<li>
-If A and B are polynomial coefficient vectors, convolving them is equivalent to multiplying the two polynomials
-</li>
-<br>
-<li>
-The convolution operation is also equivalent to FIR filtering
-</li>
-<br>
-<li>
-The orientation of the result vector is the same as the orientation of A (ie. column or row vector)
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-vec A = randu&lt;vec&gt;(128) - 0.5;
-vec B = randu&lt;vec&gt;(128) - 0.5;
-
-vec C = conv(A,B);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="http://mathworld.wolfram.com/Convolution.html">Convolution in MathWorld</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Convolution">Convolution in Wikipedia</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Finite_impulse_response">FIR filter in Wikipedia</a></li>
-<li><a href="#cor">cor()</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="conv_to"></a>
-<b>
-conv_to&lt;<i>type</i>&gt;::from(X)
-</b>
-<ul>
-<li>
-A form of casting
-</li>
-<br>
-<li>
-Convert between matrix/vector types (eg. <i>mat</i> to <i>fmat</i>), as well as cube types (eg. <i>cube</i> to <i>fcube</i>)
-</li>
-<br>
-<li>
-Conversion between <i>std::vector</i> and Armadillo matrices/vectors is also possible
-</li>
-<br>
-<li>
-Conversion of a <i>mat</i> object into <i>colvec</i>, <i>rowvec</i> or <i>std::vector</i> is possible if the object can be interpreted as a vector
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat  A = randu&lt;mat&gt;(5,5);
-fmat B = conv_to&lt;fmat&gt;::from(A);
-
-typedef std::vector&lt;double&gt; stdvec;
-
-stdvec x(3);
-x[0] = 0.0; x[1] = 1.0;  x[2] = 2.0;
-
-colvec y = conv_to&lt; colvec &gt;::from(x);
-stdvec z = conv_to&lt; stdvec &gt;::from(y); 
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#as_scalar">as_scalar()</a></li>
-<li><a href="#reshape">reshape()</a></li>
-<li><a href="#resize">resize()</a></li>
-<li><a href="#adv_constructors_mat">advanced constructors (matrices)</a></li>
-<li><a href="#adv_constructors_cube">advanced constructors (cubes)</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="conj"></a>
-<b>conj(cx_mat)</b>
-<br><b>conj(cx_cube)</b>
-<ul>
-<li>
-Obtain the complex conjugate of each element in a complex matrix/cube
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-cx_mat X = randu&lt;cx_mat&gt;(5,5);
-cx_mat Y = conj(X);
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#trans">trans()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="cor"></a>
-<b>cor(X, Y, norm_type=0)</b>
-<br><b>cor(X, norm_type=0)</b>
-<ul>
-<li>
-For two matrix arguments <i>X</i> and <i>Y</i>,
-if each row of <i>X</i> and <i>Y</i>  is an observation and each column is a variable,
-the <i>(i,j)</i>-th entry of <i>cor(X,Y)</i> is the correlation coefficient between the <i>i</i>-th variable in <i>X</i> and the <i>j</i>-th variable in <i>Y</i>
-</li>
-<br>
-<li>
-For vector arguments, the type of vector is ignored and each element in the vector is treated as an observation 
-</li>
-<br>
-<li>
-For matrices, <i>X</i> and <i>Y</i> must have the same dimensions
-</li>
-<br>
-<li>
-For vectors, <i>X</i> and <i>Y</i> must have the same number of elements
-</li>
-<br>
-<li>
-<i>cor(X)</i> is equivalent to <i>cor(X, X)</i>, also called autocorrelation
-</li>
-<br>
-<li>
-The default <i>norm_type=0</i> performs normalisation of the correlation matrix using <i>N-1</i> (where <i>N</i> is the number of observations).
-Using <i>norm_type=1</i> causes normalisation to be done using <i>N</i>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat X = randu&lt;mat&gt;(4,5);
-mat Y = randu&lt;mat&gt;(4,5);
-
-mat R = cor(X,Y);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also: 
-<ul>
-<li><a href="http://mathworld.wolfram.com/Correlation.html">Correlation in MathWorld</a></li>
-<li><a href="http://mathworld.wolfram.com/Autocorrelation.html">Autocorrelation in MathWorld</a></li>
-<li><a href="#cov">cov()</a></li>
-<li><a href="#conv">conv()</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="cov"></a>
-<b>cov(X, Y, norm_type=0)</b>
-<br><b>cov(X, norm_type=0)</b>
-<ul>
-<li>
-For two matrix arguments <i>X</i> and <i>Y</i>,
-if each row of <i>X</i> and <i>Y</i>  is an observation and each column is a variable,
-the <i>(i,j)</i>-th entry of <i>cov(X,Y)</i> is the covariance between the <i>i</i>-th variable in <i>X</i> and the <i>j</i>-th variable in <i>Y</i>
-</li>
-<br>
-<li>
-For vector arguments, the type of vector is ignored and each element in the vector is treated as an observation
-</li>
-<br>
-<li>
-For matrices, <i>X</i> and <i>Y</i> must have the same dimensions
-</li>
-<br>
-<li>
-For vectors, <i>X</i> and <i>Y</i> must have the same number of elements
-</li>
-<br>
-<li>
-<i>cov(X)</i> is equivalent to <i>cov(X, X)</i>
-</li>
-<br>
-<li>
-The default <i>norm_type=0</i> performs normalisation using <i>N-1</i> (where <i>N</i> is the number of observations),
-providing the best unbiased estimation of the covariance matrix (if the observations are from a normal distribution).
-Using <i>norm_type=1</i> causes normalisation to be done using <i>N</i>, which provides the second moment matrix of the observations about their mean
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat X = randu&lt;mat&gt;(4,5);
-mat Y = randu&lt;mat&gt;(4,5);
-
-mat C = cov(X,Y);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#running_stat_vec">running_stat_vec</a></li>
-<li><a href="#stats_fns">statistics functions</a></li>
-<li><a href="http://mathworld.wolfram.com/Covariance.html">Covariance in MathWorld</a></li>
-<li><a href="#cor">cor()</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="cross"></a>
-<b>cross(A, B)</b>
-<ul>
-<li>
-Calculate the cross product between A and B, under the assumption that A and B are 3 dimensional vectors
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-vec a = randu&lt;vec&gt;(3);
-vec b = randu&lt;vec&gt;(3);
-
-vec c = cross(a,b);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#dot">dot()</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Cross_product">Cross product in Wikipedia</a></li>
-<li><a href="http://mathworld.wolfram.com/CrossProduct.html">Cross product in MathWorld</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="cumsum"></a>
-<b>cumsum(mat, dim=0)</b>
-<br><b>cumsum(rowvec)</b>
-<br><b>cumsum(colvec)</b>
-<ul>
-<li>
-For a matrix argument, return a matrix containing the cumulative sum of elements in each column (dim=0, the default), or each row (dim=1)
-</li>
-<br>
-<li>
-For a vector argument, return a vector of the same orientation, containing the cumulative sum of elements
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-mat B = cumsum(A);
-
-vec x = randu&lt;vec&gt;(10);
-vec y = cumsum(x);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#accu">accu()</a></li>
-<li><a href="#sum">sum()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="diagmat"></a>
-<b>diagmat(mat)</b>
-<br><b>diagmat(rowvec)</b>
-<br><b>diagmat(colvec)</b>
-<ul>
-<li>
-Interpret a matrix or vector as a diagonal matrix
-</li>
-<br>
-<li>
-For <i>mat</i>, given matrix must be square; the main diagonal is copied and all other elements in the generated matrix are set to zero
-</li>
-<br>
-<li>
-For <i>colvec</i> and <i>rowvec</i>, elements of the vector are placed on the main diagonal in the generated matrix and all other elements are set to zero
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-mat B = diagmat(A);
-mat C = A*diagmat(A);
-
-rowvec q = randu&lt;rowvec&gt;(5);
-colvec r = randu&lt;colvec&gt;(5);
-mat    X = diagmat(q)*diagmat(r);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#diagvec">diagvec()</a></li>
-<li><a href="#trimat">trimatu() / trimatl()</a></li>
-<li><a href="#symmat">symmatu() / symmatl()</a></li>
-<li><a href="#reshape">reshape()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline">
-<br>
-
-<a name="find"></a>
-<b>find(X, k=0, s="first")</b>
-<ul>
-<li>Return a column vector of the indices of non-zero elements of <i>X</i></li>
-<br>
-<li>The output vector must have the type <a href="#Col">uvec</a> or <a href="#Mat">umat</a>
-(ie. the indices are stored as unsigned integers of type <a href="#uword">uword</a>)
-</li>
-<br>
-<li>
-The input matrix <i>X</i> is interpreted as a vector, with column-by-column ordering of the elements of <i>X</i>
-</li>
-<br>
-<li>Relational operators can be used instead of <i>X</i>, eg.&nbsp;<i>A&nbsp;&gt;&nbsp;0.5</i>
-</li>
-<br>
-<li>If <i>k=0</i> (default), return the indices of all non-zero elements, otherwise return at most <i>k</i> of their indices</li>
-<br>
-<li>If <i>s="first"</i> (default), return at most the first <i>k</i> indices of the non-zero elements
-</li>
-<br>
-<li>If <i>s="last"</i>, return at most the last <i>k</i> indices of the non-zero elements
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat  A  = randu&lt;mat&gt;(5,5);
-mat  B  = randu&lt;mat&gt;(5,5);
-
-uvec q1 = find(A &gt; B);
-uvec q2 = find(A &gt; 0.5);
-uvec q3 = find(A &gt; 0.5, 3, "last");
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#conv_to">conv_to()</a> (convert between matrix/vector types)</li>
-<li><a href="#submat">submatrix views</a></li>
-<li><a href="#sort_index">sort_index()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline">
-<br>
-
-<a name="flip"></a>
-<b>fliplr(mat)</b>
-<br><b>flipud(mat)</b>
-<ul>
-<li>
-fliplr(): generate a copy of the input matrix, with the order of the columns reversed
-</li>
-<br>
-<li>
-flipud(): generate a copy of the input matrix, with the order of the rows reversed
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-
-mat B = fliplr(A);
-mat C = flipud(A);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#swap_rows">.swap_rows() &amp; .swap_cols()</a> (member functions of <i>Mat</i>, <i>Col</i> and <i>Row</i> classes)</li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="imag_real"></a>
-<b>imag(cx_mat)</b>
-<br><b>imag(cx_cube)</b>
-<br>
-<br><b>real(cx_mat)</b>
-<br><b>real(cx_cube)</b>
-<ul>
-<li>
-Extract the imaginary/real part of a complex matrix/cube
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-cx_mat C = randu&lt;cx_mat&gt;(5,5);
-
-mat    A = imag(C);
-mat    B = real(C);
-</pre>
-</ul>
-</li>
-<br>
-<li><b>Caveat:</b> versions 4.4, 4.5 and 4.6 of the GCC C++ compiler have a bug when using the <i>-std=c++0x</i> compiler option (ie. experimental support for C++11);
-to work around this bug, preface Armadillo's imag() and real() with the <i>arma</i> namespace qualification, eg. arma::imag(C)
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#set_imag">set_imag()&nbsp;/&nbsp;set_real()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="join"></a>
-<b>join_rows(mat A, mat B)</b>
-<br><b>join_cols(mat A, mat B)</b>
-<br><b>join_slices(cube A, cube B)</b>
-<ul>
-<li>
-join_rows():
-for two matrices A and B, append each row of B to its respective row of A;
-matrices A and B must have the same number of rows
-</li>
-<br>
-<li>
-join_cols():
-for two matrices A and B, append each column of B to its respective column of A;
-matrices A and B must have the same number of columns
-</li>
-<br>
-<li>
-join_slices():
-for two cubes A and B, append the slices of B to the slices of A;
-cubes A and B have the same number of rows and columns (ie. all slices must have the same size)
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(4,5);
-mat B = randu&lt;mat&gt;(4,6);
-mat C = randu&lt;mat&gt;(6,5);
-
-mat X = join_rows(A,B);
-mat Y = join_cols(A,C);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#shed">shed rows/columns/slices</a></li>
-<li><a href="#insert">insert rows/columns/slices</a></li>
-<li><a href="#submat">submatrix views</a></li>
-<li><a href="#subcube">subcube views</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="kron"></a>
-<b>kron(A,B)</b>
-
-<ul>
-<li>Kronecker tensor product.</li>
-<br>
-<li>Using matrix <i>A</i> (with <i>n</i> rows and <i>p</i> columns) and matrix <i>B</i> (with <i>m</i> rows and <i>q</i> columns),
-<i>kron(A,B)</i> returns a matrix (with <i>nm</i> rows and <i>pq</i> columns) which denotes the tensor product of <i>A</i> and <i>B</i>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(4,5);
-mat B = randu&lt;mat&gt;(5,4);
-
-mat K = kron(A,B);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="http://mathworld.wolfram.com/KroneckerProduct.html">Kronecker Product in MathWorld</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="reshape"></a>
-<b>reshape(mat, n_rows, n_cols, dim=0)</b>
-<br><b>reshape(cube, n_rows, n_cols, n_slices, dim=0)</b>
-<ul>
-<li>
-Generate a matrix/cube sized according to given size specifications,
-whose elements are taken from the given matrix/cube, either column-wise (dim=0) or row-wise (dim=1);
-the elements in the generated object are placed column-wise (ie. the first column is filled up before filling the second column)
-</li>
-<br>
-<li>
-The layout of the elements in the generated object will be different to the layout in the given object
-</li>
-<br>
-<li>
-This function can be used to create a vector representation of a matrix (ie. concatenate all the columns or rows)
-</li>
-<br>
-<li>
-The total number of elements in the generated matrix/cube doesn't have to be the same as the total number of elements in the given matrix/cube
-</li>
-<br>
-<li>
-If the total number of elements in the given matrix/cube is less than the specified size,
-the remaining elements in the generated matrix/cube are set to zero
-</li>
-<br>
-<li>
-If the total number of elements in the given matrix/cube is greater than the specified size,
-only a subset of elements is taken from the given matrix/cube
-</li>
-<br>
-<li>
-<b>Caveat:</b>
-reshape() is slower than <a href="#set_size">.set_size()</a>, which doesn't preserve data
-</li>
-<br>
-<li>
-<b>Caveat:</b>
-if you wish to grow/shrink a matrix while preserving the elements <b>as well as</b> the layout of the elements,
-use <a href="#resize">resize()</a> instead
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(10, 5);
-mat B = reshape(A, 5, 10);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#reshape_member">.reshape()</a> (member function of Mat and Cube)</li>
-<li><a href="#set_size">.set_size()</a> (member function of Mat and Cube)</li>
-<li><a href="#resize">resize()</a></li>
-<li><a href="#as_scalar">as_scalar()</a></li>
-<li><a href="#conv_to">conv_to()</a></li>
-<li><a href="#diagmat">diagmat()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="resize"></a>
-<b>resize(mat, n_rows, n_cols)</b>
-<br><b>resize(cube, n_rows, n_cols, n_slices)</b>
-<ul>
-<li>
-Generate a matrix/cube sized according to given size specifications,
-whose elements as well as the layout of the elements are taken from the given matrix/cube
-</li>
-<br>
-<li>
-<b>Caveat:</b>
-resize() is slower than <a href="#set_size">.set_size()</a>, which doesn't preserve data
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(4, 5);
-mat B = resize(A, 7, 6);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-This function was added in version 2.4.1
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#resize_member">.resize()</a> (member function of Mat and Cube)</li>
-<li><a href="#set_size">.set_size()</a> (member function of Mat and Cube)</li>
-<li><a href="#reshape">reshape()</a></li>
-<li><a href="#as_scalar">as_scalar()</a></li>
-<li><a href="#conv_to">conv_to()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="shuffle"></a>
-<b>shuffle(mat, dim=0)</b>
-<br><b>shuffle(rowvec, dim=0)</b>
-<br><b>shuffle(colvec, dim=0)</b>
-<ul>
-<li>
-Shuffle the rows (dim=0) or columns (dim=1) of a matrix or vector
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(4,5);
-mat B = shuffle(A);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#randu_randn_standalone">randu() / randn()</a></li>
-<li><a href="#sort">sort()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="sort"></a>
-<b>sort(mat, sort_type=0, dim=0)</b>
-<br><b>sort(rowvec, sort_type=0)</b>
-<br><b>sort(colvec, sort_type=0)</b>
-<ul>
-<li>For a matrix argument, return a matrix with the elements of the input matrix sorted in each column (<i>dim=0</i>), or each row (<i>dim=1</i>)</li>
-<br>
-<li><i>sort_type=0</i> (default) indicates an ascending sort</li>
-<br>
-<li><i>sort_type=1</i> indicates a descending sort</li>
-<br>
-<li>For a vector argument, return a vector which is a sorted version of the input vector</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(10,10);
-mat B = sort(A);
-</pre>
-</ul>
-</li>
-<li>
-See also:
-<ul>
-<li><a href="#sort_index">sort_index()</a></li>
-<li><a href="#shuffle">shuffle()</a></li>
-<li><a href="#randu_randn_standalone">randu() / randn()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="sort_index"></a>
-<b>sort_index(colvec, sort_type=0)</b>
-<br><b>sort_index(rowvec, sort_type=0)</b>
-<ul>
-<li>Return a vector which describes the sorted order of the given vector's elements 
-(ie. it contains the indices of the given vector's elements)
-</li>
-<br>
-<li>The output vector must have the type <a href="#Col">uvec</a> or <a href="#Mat">umat</a>
-(ie. the indices are stored as unsigned integers of type <a href="#uword">uword</a>)
-</li>
-<br>
-<li><i>sort_type=0</i> (default) indicates an ascending sort</li>
-<br>
-<li><i>sort_type=1</i> indicates a descending sort</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-vec  q       = randu&lt;vec&gt;(10);
-uvec indices = sort_index(q);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#find">find()</a></li>
-<li><a href="#sort">sort()</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="symmat"></a>
-<b>symmatu(A)</b>
-<br><b>symmatl(A)</b>
-<ul>
-<li>
-<i>symmatu(A)</i>: interpret square matrix <i>A</i> as symmetric, reflecting the upper triangle to the lower triangle
-</li>
-<br>
-<li>
-<i>symmatl(A)</i>: interpret square matrix <i>A</i> as symmetric, reflecting the lower triangle to the upper triangle
-</li>
-<br>
-<li>
-If <i>A</i> is non-square, a <i>std::logic_error</i> exception is thrown
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-
-mat B = symmatu(A);
-mat C = symmatl(A);
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#diagmat">diagmat()</a></li>
-<li><a href="#trimat">trimatu() / trimatl()</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Symmetric_matrix">Symmetric matrix in Wikipedia</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="strans"></a>
-<b>strans(mat)</b>
-<br><b>strans(colvec)</b>
-<br><b>strans(rowvec)</b>
-<ul>
-<li>
-Simple matrix transpose, without taking the conjugate of the elements (complex matrices)
-</li>
-<br>
-<li>
-Use <a href="#trans">trans()</a> instead, unless you explicitly need to take the transpose of a complex matrix without taking the conjugate of the elements
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#t_st_members">.st()</a></li>
-<li><a href="#trans">trans()</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-
-<a name="trans"></a>
-<b>trans(mat)</b>
-<br><b>trans(colvec)</b>
-<br><b>trans(rowvec)</b>
-<ul>
-<li>
-Matrix transpose / Hermitian transpose
-</li>
-<br>
-<li>
-If a given object has real elements, a normal transpose is done
-</li>
-<br>
-<li>
-If a given object has complex elements, a Hermitian transpose is done (ie. the conjugate of the elements is taken during the transpose operation)
-</li>
-<br>
-<li>
-<b>Caveat:</b> for complex matrices, the functionality of trans() has changed in version 2.0:
-<ul>
-<li>in version 1.2.x and earlier, trans() does not take the conjugate of complex elements</li>
-<li>in version 1.2.x and earlier, the deprecated htrans() function is used for the Hermitian transpose</li>
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>mat A = randu&lt;mat&gt;(5,10);
-mat B = trans(A);
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#t_st_members">.t()</a></li>
-<li><a href="#strans">strans()</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-
-<a name="trimat"></a>
-<b>trimatu(A)</b>
-<br><b>trimatl(A)</b>
-<ul>
-<li>
-trimatu(A): interpret square matrix A as upper triangular
-</li>
-<br>
-<li>
-trimatl(A): interpret square matrix A as lower triangular
-</li>
-<br>
-<li>
-A <i>std::logic_error</i> exception is thrown if A is non-square
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>mat A = randu&lt;mat&gt;(5,5);
-mat U = trimatu(A);
-mat L = trimatl(A);
-
-// tell the inv() function to look only
-// at the upper triangular part
-mat X = inv( trimatu(U) );
-</pre>
-</ul>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="#symmat">symmatu() / symmatl()</a></li>
-<li><a href="#diagmat">diagmat()</a></li>
-<li><a href="#inv">inv()</a></li>
-<li><a href="#solve">solve()</a></li>
-<li><a href="http://mathworld.wolfram.com/TriangularMatrix.html">Triangular matrix in MathWorld</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Triangular_matrix">Triangular matrix in Wikipedia</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline">
-
-
-<hr class="greyline">
-<br>
-<br>
-<font size=+1><b>Decompositions, Inverses and Equation Solvers</b></font>
-<br>
-<br>
-<hr class="greyline">
-<br>
-
-<a name="chol"></a>
-<b>R = chol(X)</b>
-<br><b>chol(R, X)</b>
-<ul>
-<li>
-Cholesky decomposition of <i>X</i>, such that <i>trans(R)*R = X</i>
-</li>
-<br>
-<li>
-X must be a symmetric, positive-definite matrix
-</li>
-<br>
-<li>If the decomposition fails, <i>R</i> is reset and:
-<ul>
-<li><i>chol(X)</i> throws a <i>std::runtime_error</i> exception</li>
-<li><i>chol(R,X)</i> returns a bool set to <i>false</i></li>
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat X = randu&lt;mat&gt;(5,5);
-mat Y = trans(X)*X;
-
-mat R = chol(Y);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="http://mathworld.wolfram.com/CholeskyDecomposition.html">Cholesky decomposition in MathWorld</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="eig_sym"></a>
-<b>vec eigval = eig_sym(mat X)</b>
-<br><b>vec eigval = eig_sym(cx_mat X)</b>
-<br>
-<br><b>eig_sym(vec eigval, mat X)</b>
-<br><b>eig_sym(vec eigval, cx_mat X)</b>
-<br>
-<br><b>eig_sym(vec eigval, mat eigvec, mat X)</b>
-<br><b>eig_sym(vec eigval, cx_mat eigvec, cx_mat X)</b>
-<ul>
-<li>
-Eigen decomposition of symmetric/hermitian matrix <i>X</i></li>
-<br>
-<li>The eigenvalues and corresponding eigenvectors are stored in <i>eigval</i> and <i>eigvec</i>, respectively</li>
-<br>
-<li>
-The eigenvalues are in ascending order
-</li>
-<br>
-<li>If <i>X</i> is not square, a <i>std::logic_error</i> exception is thrown</li>
-<br>
-<li>If the decomposition fails, the output objects are reset and:
-<ul>
-<li><i>eig_sym(X)</i> throws a <i>std::runtime_error</i> exception</li>
-<li><i>eig_sym(eigval, X)</i> and <i>eig_sym(eigval, eigvec, X)</i> return a bool set to <i>false</i></li>
-</ul>
-</li>
-<br>
-<li>There is currently no check whether <i>X</i> is symmetric</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(10,10);
-mat B = trans(A)*A;  // generate a symmetric matrix
-
-vec eigval;
-mat eigvec;
-
-eig_sym(eigval, eigvec, B);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#eig_gen">eig_gen()</a></li>
-<li><a href="#svd">svd()</a></li>
-<li><a href="#svd_econ">svd_econ()</a></li>
-<li><a href="http://mathworld.wolfram.com/EigenDecomposition.html">eigen decomposition in MathWorld</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="eig_gen"></a>
-<b>eig_gen(cx_vec eigval, cx_mat eigvec, mat X, side='r')</b>
-<br>
-<b>eig_gen(cx_vec eigval, cx_mat eigvec, cx_mat X, side='r')</b>
-<br>
-<br>
-<b>eig_gen(cx_vec eigval, mat l_eigvec, mat r_eigvec, mat X)</b>
-<br>
-<b>eig_gen(cx_vec eigval, cx_mat l_eigvec, cx_mat r_eigvec, cx_mat X)</b>
-<ul>
-<li>
-Eigen decomposition of general (non-symmetric/non-hermitian) square matrix <i>X</i></li>
-<br>
-<li>The eigenvalues and corresponding eigenvectors are stored in <i>eigval</i> and <i>eigvec</i>, respectively</li>
-<br>
-<li>
-For the first two forms, <i>side='r'</i> (default) specifies that right eigenvectors are computed,
-while <i>side='l'</i> specifies that left eigenvectors are computed
-</li>
-<br>
-<li>For the last two forms, both left and right eigenvectors are computed</li>
-<br>
-<li>
-The eigenvalues are not guaranteed to be ordered
-</li>
-<br>
-<li>If <i>X</i> is not square, a <i>std::logic_error</i> exception is thrown</li>
-<br>
-<li>If the decomposition fails, the output objects are reset and <i>eig_gen()</i> returns a bool set to <i>false</i></li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(10,10);
-
-cx_vec eigval;
-cx_mat eigvec;
-
-eig_gen(eigval, eigvec, A);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#eig_sym">eig_sym()</a></li>
-<li><a href="#svd">svd()</a></li>
-<li><a href="#svd_econ">svd_econ()</a></li>
-<li><a href="http://mathworld.wolfram.com/EigenDecomposition.html">eigen decomposition in MathWorld</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="inv"></a>
-<b>B = inv(A, slow = <i>false</i>)</b>
-<br>
-<b>inv(B, A, slow = <i>false</i>)</b>
-<ul>
-<li>
-Inverse of square matrix <i>A</i>
-</li>
-<br>
-<li>
-If <i>A</i> is known to be a triangular matrix,
-the inverse can be computed faster by explicitly marking the matrix as triangular
-through <a href="#trimat">trimatu()</a> or <a href="#trimat">trimatl()</a>
-</li>
-<br>
-<li>
-If <i>A</i> is known to be a positive-definite symmetric matrix,
-the inverse can be computed faster by explicitly marking the matrix using sympd()
-</li>
-<br>
-<li>
-If <i>A</i> is not square, a <i>std::logic_error</i> exception is thrown
-</li>
-<br>
-<li>If <i>A</i> appears to be singular, <i>B</i> is reset and:
-<ul>
-<li><i>inv(A)</i> throws a <i>std::runtime_error</i> exception</li>
-<li><i>inv(B,A)</i> returns a bool set to <i>false</i></li>
-</ul>
-</li>
-<br>
-<li>
-If you want to solve a system of linear equations, eg., <i>X = inv(A)*B</i>,
-the <a href="#solve">solve()</a> function is generally more efficient
-</li>
-<br>
-<li>
-For matrix sizes &le; 4x4, a fast inverse algorithm is used by default.
-In rare instances, the fast algorithm might be less precise than the standard algorithm.
-To force the use of the standard algorithm, set the <i>slow</i> argument to <i>true</i>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-mat B = inv(A);
-
-
-// Diagonal elements in C are set to the
-// reciprocal of the corresponding elements in A.
-// Off-diagonal elements in C are set to zero.
-mat C = inv( diagmat(A) );
-
-
-// tell inv() to look only at the upper triangular part of A
-mat D = inv( trimatu(A) );
-
-
-// tell inv() that AA is a symmetric positive definite matrix
-mat AA = A*trans(A);
-mat E  = inv( sympd(AA) );
-
-
-mat44 F = randu&lt;mat&gt;(4,4);
-
-mat G = inv(F);       // use fast algorithm by default
-mat H = inv(F, true); // use slow algorithm
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also: 
-<ul>
-<li><a href="#pinv">pinv()</a>
-<li><a href="#solve">solve()</a></li>
-<li><a href="#trimat">trimatu() / trimatl()</a></li>
-<li><a href="http://mathworld.wolfram.com/MatrixInverse.html">matrix inverse in MathWorld</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Invertible_matrix">invertible matrix in Wikipedia</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-
-
-<a name="lu"></a>
-<b>lu(mat L, mat U, mat P, mat X)</b>
-<br>
-<b>lu(mat L, mat U, mat X)</b>
-<ul>
-<li>
-Lower-upper decomposition (with partial pivoting) of matrix <i>X</i>
-</li>
-<br>
-<li>
-The first form provides 
-a lower-triangular matrix <i>L</i>,
-an upper-triangular matrix <i>U</i>,
-and a permutation matrix <i>P</i>,
-such that <i>trans(P)*L*U&nbsp;=&nbsp;X</i>
-</li>
-<br>
-<li>
-The second form provides permuted <i>L</i> and <i>U</i>, such that <i>L*U = X</i>.
-Note that in this case <i>L</i> is generally not lower-triangular
-</li>
-<br>
-<li>
-If the decomposition fails, the output objects are reset and <i>lu()</i> returns a bool set to <i>false</i>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-
-mat L, U, P;
-
-lu(L, U, P, A);
-
-mat B = trans(P)*L*U;
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="http://en.wikipedia.org/wiki/LU_decomposition">LU decomposition in Wikipedia</a></li>
-<li><a href="http://mathworld.wolfram.com/LUDecomposition.html">LU decomposition in MathWorld</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="pinv"></a>
-<b>B = pinv(A, tolerance = default)</b>
-<br><b>pinv(B, A, tolerance = default)</b>
-<ul>
-<li>Moore-Penrose pseudo-inverse of matrix <i>A</i></li>
-<br>
-<li>The computation is based on singular value decomposition;
-if the decomposition fails, <i>B</i> is reset and:
-<ul>
-<li><i>pinv(A)</i> throws a <i>std::runtime_error</i> exception</li>
-<li><i>pinv(B,A)</i> returns a bool set to <i>false</i></li>
-</ul>
-<br>
-<li>Any singular values less than <i>tol</i> are treated as zero</li>
-<br>
-<li>For matrix <i>A</i> with <i>m</i> rows and <i>n</i> columns,
-the default tolerance is <i>max(m,n)*norm(A)*math::eps()</i>,
-where <i>math::eps()</i> denotes the difference between 1 and the least value greater than 1 that is representable</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(4,5);
-mat B = pinv(A);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#inv">inv()</a></li>
-<li><a href="#math_constants">math::eps()</a></li>
-<li><a href="http://mathworld.wolfram.com/Pseudoinverse.html">Pseudoinverse in MathWorld</a></li>
-<li><a href="http://mathworld.wolfram.com/Moore-PenroseMatrixInverse.html">Moore-Penrose Matrix Inverse in MathWorld</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Moore-Penrose_pseudoinverse">Moore-Penrose pseudoinverse in Wikipedia</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="princomp"></a>
-<b>mat coeff = princomp(mat X)</b>
-<br><b>cx_mat coeff = princomp(cx_mat X)</b><br>
-
-<br><b>princomp(mat coeff, mat X)</b>
-<br><b>princomp(cx_mat coeff, cx_mat X)</b><br>
-
-<br><b>princomp(mat coeff, mat score, mat X)</b>
-<br><b>princomp(cx_mat coeff, cx_mat score, cx_mat X)</b><br>
-
-<br><b>princomp(mat coeff, mat score, vec latent, mat X)</b>
-<br><b>princomp(cx_mat coeff, cx_mat score, vec latent, cx_mat X)</b><br>
-
-<br><b>princomp(mat coeff, mat score, vec latent, vec tsquared, mat X)</b>
-<br><b>princomp(cx_mat coeff, cx_mat score, vec latent, cx_vec tsquared, cx_mat X)</b><br>
-<br>
-<ul>
-<li>Principal component analysis of matrix <i>X</i></li><br>
-<li>Each row of <i>X</i> is an observation and each column is a variable</li><br>
-<li>output objects:
-<ul>
-<li><i>coeff</i>: principal component coefficients</li>
-<li><i>score</i>: projected data</li>
-<li><i>latent</i>: eigenvalues of the covariance matrix of <i>X</i></li>
-<li><i>tsquared</i>: Hotteling's statistic for each sample</li>
-</ul>
-</li>
-<br>
-<li>The computation is based on singular value decomposition;
-if the decomposition fails, the output objects are reset and:
-<ul>
-<li><i>princomp(X)</i> throws a <i>std::runtime_error</i> exception</li>
-<li>remaining forms of <i>princomp()</i> return a bool set to <i>false</i></li>
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,4);
-
-mat coeff;
-mat score;
-vec latent;
-vec tsquared;
-
-princomp(coeff, score, latent, tsquared, A);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="http://en.wikipedia.org/wiki/Principal_component_analysis">principal components analysis in Wikipedia</a></li>
-<li><a href="http://mathworld.wolfram.com/PrincipalComponentAnalysis.html">principal components analysis in MathWorld</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="qr"></a>
-<b>qr(Q,R,X)</b>
-<ul>
-<li>
-Decomposition of matrix <i>X</i> into an orthogonal (<i>Q</i>) and a right triangular matrix (<i>R</i>), such that <i>Q*R = X</i>
-</li>
-<br>
-<li>
-If the decomposition fails, <i>Q</i> and <i>R</i> are reset and the function returns a bool set to <i>false</i>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat X = randu&lt;mat&gt;(5,5);
-mat Q, R;
-
-qr(Q,R,X);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="http://mathworld.wolfram.com/QRDecomposition.html">QR decomposition in MathWorld</a></li>
-<li><a href="http://octave.sourceforge.net/octave/function/qr.html">QR decomposition in Octave</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="solve"></a>
-<b>X = solve(A, B, slow = false)</b>
-<br><b>solve(X, A, B, slow = false)</b>
-<ul>
-<li>Solve a system of linear equations, ie., <i>A*X = B</i>, where <i>X</i> is unknown</li>
-<br>
-<li>For a square matrix <i>A</i>, this function is conceptually the same as <i>X = inv(A)*B</i>, but is more efficient</li>
-<br>
-<li>Similar functionality to the "\" (left division operator) operator in Matlab/Octave, ie. <i>X&nbsp;=&nbsp;A&nbsp;\&nbsp;B</i></li>
-<br>
-<li>The number of rows in <i>A</i> and <i>B</i> must be the same</li>
-<br>
-<li>
-If <i>A</i> is known to be a triangular matrix,
-the solution can be computed faster by explicitly marking the matrix as triangular
-through <a href="#trimat">trimatu()</a> or <a href="#trimat">trimatl()</a>
-</li>
-<br>
-<li>
-If <i>A</i> is non-square (and hence also non-triangular),
-solve() will also try to provide approximate solutions to under-determined as well as over-determined systems</li>
-<br>
-<li>
-If no solution is found, <i>X</i> is reset and:
-<ul>
-<li><i>solve(A,B)</i> throws a <i>std::runtime_error</i> exception</li>
-<li><i>solve(X,A,B)</i> returns a bool set to <i>false</i></li>
-</ul>
-</li>
-<br>
-<li>
-For matrix sizes &le; 4x4, a fast algorithm is used by default.
-In rare instances, the fast algorithm might be less precise than the standard algorithm.
-To force the use of the standard algorithm, set the <i>slow</i> argument to <i>true</i>
-</li>
-<br>
-<li>
-<b>NOTE:</b> Old versions of the ATLAS library (eg.&nbsp;3.6) can corrupt memory and crash your program;
-the standard LAPACK library and later versions of ATLAS (eg.&nbsp;3.8) work without problems
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-vec b = randu&lt;vec&gt;(5);
-mat B = randu&lt;mat&gt;(5,5);
-
-vec x = solve(A, b);
-mat X = solve(A, B);
-
-vec x2;
-solve(x2, A, b);
-
-// tell solve() to look only at the upper triangular part of A
-mat Y = solve( trimatu(A), B );
-
-
-mat44 C = randu&lt;mat&gt;(4,4);
-mat44 D = randu&lt;mat&gt;(4,4);
-
-mat E = solve(C, D);       // use fast algorithm by default
-mat F = solve(C, D, true); // use slow algorithm
-
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#inv">inv()</a></li>
-<li><a href="#syl">syl()</a></li>
-<li><a href="#trimat">trimatu() / trimatl()</a></li>
-<li><a href="http://mathworld.wolfram.com/LinearSystemofEquations.html">linear system of equations in MathWorld</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Linear_system_of_equations">system of linear equations in Wikipedia</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-
-<a name="svd"></a>
-<b>vec s = svd(mat X)</b>
-<br><b>vec s = svd(cx_mat X)</b>
-<br>
-<br><b>svd(vec s, mat X)</b>, 
-<br><b>svd(vec s, cx_mat X)</b> 
-<br>
-<br><b>svd(mat U, vec s, mat V, mat X)</b>
-<br><b>svd(cx_mat U, vec s, cx_mat V, cx_mat X)</b>
-<ul>
-<li>
-The single and two argument versions compute the singular values of <i>X</i>
-</li>
-<br>
-<li>
-The four argument version computes the full singular value decomposition of <i>X</i>
-</li>
-<br>
-<li>If <i>X</i> is square, it can be reconstructed using <i>X = U*diagmat(s)*trans(V)</i>
-</li>
-<br>
-<li>
-The singular values are in descending order
-</li>
-<br>
-<li>
-If the decomposition fails, the output objects are reset and:
-<ul>
-<li><i>svd(X)</i> throws a <i>std::runtime_error</i> exception</li>
-<li><i>svd(s,X)</i> and <i>svd(U,s,V,X)</i> return a bool set to <i>false</i></li>
-</ul>
-</li>
-<br>
-<li>
-<b>NOTE:</b> Old versions of the ATLAS library (eg.&nbsp;3.6) can corrupt memory and crash your program;
-the standard LAPACK library and later versions of ATLAS (eg.&nbsp;3.8) work without problems
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat X = randu&lt;mat&gt;(5,5);
-
-mat U;
-vec s;
-mat V;
-svd(U,s,V,X);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#svd_econ">svd_econ()</a></li>
-<li><a href="#eig_gen">eig_gen()</a></li>
-<li><a href="#eig_sym">eig_sym()</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Singular_value_decomposition">singular value decomposition in Wikipedia</a></li>
-<li><a href="http://mathworld.wolfram.com/SingularValueDecomposition.html">singular value decomposition in MathWorld</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline">
-<br>
-
-<a name="svd_econ"></a>
-<b>svd_econ(mat U, vec s, mat V, mat X, mode = 'b')</b>
-<br><b>svd_econ(cx_mat U, vec s, cx_mat V, cx_mat X, mode = 'b')</b>
-<ul>
-<li>
-Economical singular value decomposition of <i>X</i>
-</li>
-<br>
-<li>
-mode is one of:
-<ul>
-<li><i>'l'</i>: compute only left singular vectors</li>
-<li><i>'r'</i>: compute only right singular vectors</li>
-<li><i>'b'</i>: compute both left and right singular vectors (default)</li>
-</ul>
-</li>
-<br>
-<li>
-The singular values are in descending order
-</li>
-<br>
-<li>
-If the decomposition fails, the output objects are reset and bool set to <i>false</i> is returned
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat X = randu&lt;mat&gt;(4,5);
-
-mat U;
-vec s;
-mat V;
-svd_econ(U, s, V, X, 'l');
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#svd">svd()</a></li>
-<li><a href="#eig_gen">eig_gen()</a></li>
-<li><a href="#eig_sym">eig_sym()</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Singular_value_decomposition">singular value decomposition in Wikipedia</a></li>
-<li><a href="http://mathworld.wolfram.com/SingularValueDecomposition.html">singular value decomposition in MathWorld</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline">
-<br>
-
-<a name="syl"></a>
-<b>X = syl(A, B, C)</b>
-<br><b>syl(X, A, B, C)</b>
-<ul>
-<li>Solve the Sylvester equation, ie., <i>AX + XB + C = 0</i>, where <i>X</i> is unknown.</li>
-<br>
-<li>Matrices <i>A</i>, <i>B</i> and <i>C</i> must be square sized.</li>
-<br>
-<li>
-If no solution is found, <i>X</i> is reset and:
-<ul>
-<li><i>syl(A,B,C)</i> throws a <i>std::runtime_error</i> exception</li>
-<li><i>svd(X,A,B,C)</i> returns a bool set to <i>false</i></li>
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-mat B = randu&lt;mat&gt;(5,5);
-mat C = randu&lt;mat&gt;(5,5);
-
-mat X1 = syl(A, B, C);
-
-mat X2;
-syl(X2, A, B, C);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#solve">solve()</a></li>
-<li><a href="http://en.wikipedia.org/wiki/Sylvester_equation">Sylvester equation in Wikipedia</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline">
-
-
-<hr class="greyline">
-<br>
-<br>
-<font size=+1><b>Miscellaneous</b></font>
-<br>
-<br>
-<hr class="greyline">
-<br>
-
-<a name="is_finite_standalone"></a>
-<b>is_finite(X)</b>
-<ul>
-<li>
-Returns <i>true</i> if all elements in <i>X</i> are finite
-</li>
-<br>
-<li>
-Returns <i>false</i> if at least one element in <i>X</i> is non-finite (&plusmn;infinity or NaN)
-</li>
-<br>
-<li>
-<i>X</i> can be a scalar (eg. <i>double</i>), vector, matrix or cube
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-mat A = randu&lt;mat&gt;(5,5);
-mat B = randu&lt;mat&gt;(5,5);
-
-B(1,1) = math::nan();
-
-cout &lt;&lt; is_finite(A) &lt;&lt; endl;
-cout &lt;&lt; is_finite(B) &lt;&lt; endl;
-
-cout &lt;&lt; is_finite( 0.123456789 ) &lt;&lt; endl;
-cout &lt;&lt; is_finite( math::nan() ) &lt;&lt; endl;
-cout &lt;&lt; is_finite( math::inf() ) &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#math_constants">math::nan()</a></li>
-<li><a href="#math_constants">math::inf()</a></li>
-<li><a href="#is_finite">.is_finite()</a> (member function of <i>Mat</i> and <i>Cube</i>)</li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="logging"></a>
-<b>logging of warnings and errors</b>
-<br>
-<br>
-<b>set_stream_err1(user_stream)</b><br>
-<b>set_stream_err2(user_stream)</b><br>
-<br>
-<b>std::ostream&amp; x = get_stream_err1()</b>
-<br>
-<b>std::ostream&amp; x = get_stream_err2()</b>
-<br>
-<ul>
-<li>
-By default, Armadillo prints warnings and messages associated with <i>std::logic_error</i> and <i>std::runtime_error</i> exceptions to the <i>std::cout</i> stream
-</li>
-<br>
-<li><b>set_stream_err1()</b>: change the stream for messages associated with <i>std::logic_error</i> exceptions (eg. out of bounds accesses)</li>
-<br>
-<li><b>set_stream_err2()</b>: change the stream for warnings and messages associated with <i>std::runtime_error</i> exceptions (eg. failed decompositions)</li>
-<br>
-<li><b>get_stream_err1()</b>: get a reference to the stream for messages associated with <i>std::logic_error</i> exceptions</li>
-<br>
-<li><b>get_stream_err2()</b>: get a reference to the stream for warnings and messages associated with <i>std::runtime_error</i> exceptions</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-// print "hello" to the current err1 stream
-get_stream_err1() &lt;&lt; "hello" &lt;&lt; endl;
-
-// change the err2 stream to be a file
-ofstream f("my_log.txt");
-set_stream_err2(f);
-
-// trying to invert a singular matrix
-// will print a message to the err2 stream
-// and throw an exception
-mat X = zeros&lt;mat&gt;(5,5);
-mat Y = inv(X);
-
-// disable messages being printed to the err2 stream
-std::ostream nullstream(0);
-set_stream_err2(nullstream);
-</pre>
-</ul>
-</li>
-<br>
-<li>
-<b>Caveat</b>: set_stream_err1() and set_stream_err2() will not change the stream used by .print()
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="#print">.print()</a></li>
-<li><a href="http://cplusplus.com/reference/iostream/cout/">std::cout</a></li>
-<li><a href="http://cplusplus.com/reference/iostream/ostream/">std::ostream</a></li>
-<li><a href="http://cplusplus.com/reference/std/stdexcept/logic_error/">std::logic_error</a></li>
-<li><a href="http://cplusplus.com/reference/std/stdexcept/runtime_error/">std::runtime_error</a></li>
-<li><a href="http://cplusplus.com/doc/tutorial/exceptions/">tutorial on exceptions</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline">
-
-
-
-<a name="math_constants"></a>
-<b>math constants (pi, e, euler, gratio, sqrt2, eps, log_min, log_max, nan, inf)</b>
-<br>
-<ul>
-<li>
-Collection of constants, with their precision and/or value dependant on the numerical type and/or machine used.
-</li>
-<br>
-<li>
-The constants are stored as static functions in the <i>Math&lt;type&gt;</i> class,
-where <i>type</i> is either <i>float</i> or <i>double</i>.
-</li>
-<br>
-<li>
-For convenience, <i>Math&lt;float&gt;</i> has been typedefed as <i>fmath</i>,
-while <i>Math&lt;double&gt;</i> has been typedefed as <i>math</i>.
-</li>
-<br>
-<li>
-Meaning of the constants:
-<ul>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-<tbody>
-  <tr>
-    <td style="vertical-align: top;">
-      math::pi()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &pi;, the ratio of any circle's circumference to its diameter
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      math::e()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      base of the natural logarithm
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      math::euler()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Euler's constant, aka Euler-Mascheroni constant
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      math::gratio()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      golden ratio
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      math::sqrt2()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      square root of 2
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      math::eps()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      the difference between 1 and the least value greater than 1 that is representable
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      math::log_min()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      log of minimum non-zero value
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      math::log_max()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      log of maximum value
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      math::nan()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &ldquo;not a number&rdquo; (NaN)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      math::inf()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      infinity
-    </td>
-  </tr>
-</tbody>
-</table>
-</ul>
-</li>
-<br>
-<li>
-<b>Caveat:</b>
-nan() is not equal to anything, even itself;
-if you wish to check whether a given number <i>x</i> is finite,
-use <a href="#is_finite_standalone">is_finite</a>(<i>x</i>).
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-cout &lt;&lt; "2.0 * pi = " &lt;&lt; 2.0 * math::pi() &lt;&lt; endl;
-
-cout &lt;&lt; "log_max for floats = ";
-cout &lt;&lt; fmath::log_max() &lt;&lt; endl;
-
-cout &lt;&lt; "log_max for doubles = ";
-cout &lt;&lt; math::log_max() &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-<li>
-See also:
-<ul>
-<li><a href="#phys_constants">physical constants</a></li>
-<li><a href="#is_finite_standalone">is_finite()</a></li>
-<li><a href="http://en.wikipedia.org/wiki/NaN">Wikipedia entry for NaN</a></li>
-<li><a href="http://cplusplus.com/reference/std/limits/numeric_limits/">std::numeric_limits</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="phys_constants"></a>
-<b>physical constants (speed of light, etc)</b>
-<br>
-<ul>
-<li>
-Collection of fundamental physical constants,
-mainly taken from
-<a href="http://physics.nist.gov/cuu/Constants">NIST</a>
-and some from
-<a href="http://www.wolframalpha.com">WolframAlpha</a>
-on 2009-06-23.
-</li>
-<br>
-<li>
-Constants from NIST are in turn sourced from the <a href="http://physics.nist.gov/cuu/Constants/papers.html">2006 CODATA values</a>.
-</li>
-<br>
-<li>
-The constants are stored as static functions in the <i>Phy&lt;type&gt;</i> class,
-where <i>type</i> is either <i>float</i> or <i>double</i>.
-</li>
-<br>
-<li>
-For convenience, <i>Phy&lt;float&gt;</i> has been typedefed as <i>fphy</i>,
-while <i>Phy&lt;double&gt;</i> has been typedefed as <i>phy</i>.
-</li>
-<br>
-<li>
-Meaning of the constants:
-<ul>
-<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
-<tbody>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::m_u()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      atomic mass constant (in kg)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::N_A()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Avogadro constant
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::k()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Boltzmann constant (in joules per kelvin)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::k_evk()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Boltzmann constant (in eV/K)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::a_0()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Bohr radius (in meters)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::mu_B()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Bohr magneton
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::Z_0()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      characteristic impedance of vacuum (in ohms)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::G_0()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      conductance quantum (in siemens)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::k_e()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Coulomb's constant (in meters per farad)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::eps_0()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      electric constant (in farads per meter)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::m_e()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      electron mass (in kg)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::eV()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      electron volt (in joules)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::e()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      elementary charge (in coulombs)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::F()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Faraday constant (in coulombs)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::alpha()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      fine-structure constant
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::alpha_inv()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      inverse fine-structure constant
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::K_J()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Josephson constant
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::mu_0()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      magnetic constant (in henries per meter)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::phi_0() 
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      magnetic flux quantum (in webers)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::R()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      molar gas constant (in joules per mole kelvin)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::G()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Newtonian constant of gravitation (in newton square meters per kilogram squared)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::h() 
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Planck constant (in joule seconds)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::h_bar()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Planck constant over 2 pi, aka reduced Planck constant (in joule seconds)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::m_p()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      proton mass (in kg)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::R_inf()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Rydberg constant (in reciprocal meters)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::c_0()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      speed of light in vacuum (in meters per second)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::sigma()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Stefan-Boltzmann constant
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::R_k()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      von Klitzing constant (in ohms)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      phy::b()
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Wien wavelength displacement law constant
-    </td>
-  </tr>
-</tbody>
-</table>
-</ul>
-</li>
-<br>
-<li>
-Examples:
-<ul>
-<pre>
-cout &lt;&lt; "speed of light = " &lt;&lt; phy::c_0() &lt;&lt; endl;
-</pre>
-</ul>
-</li>
-<br>
-<li>
-See also:
-<ul>
-<li><a href="http://en.wikipedia.org/wiki/Physical_constant">physical constant</a> entry in Wikipedia</li>
-<li><a href="#math_constants">math constants</a></li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="log_add"></a>
-<b>log_add(log_a, log_b)</b>
-<ul>
-<li>
-Safe replacement for log(exp(log_a) + exp(log_b))
-</li>
-<br>
-<li>
-Usage:
-<ul>
-<li>
-<i>scalar_type</i> log_c = log_add(log_a, log_b)
-</li>
-<li>
-<i>scalar_type</i> is either <i>float</i> or <i>double</i>
-</li>
-<li>
-log_a, log_b and log_c must have the same type
-</li>
-</ul>
-</li>
-</ul>
-<br>
-<hr class="greyline"><br>
-
-<a name="uword"></a>
-<b>uword</b>, <b>sword</b>
-<ul>
-<li>
-<i>uword</i> is a typedef for an unsigned integer with a minimum width of 32 bits; if <i>ARMA_64BIT_WORD</i> is enabled, the minimum width is 64 bits
-</li>
-<br>
-<li>
-<i>sword</i> is a typedef for a signed integer with a minimum width of 32 bits; if <i>ARMA_64BIT_WORD</i> is enabled, the minimum width is 64 bits
-</li>
-<br>
-<li>
-<i>ARMA_64BIT_WORD</i> can be enabled via editing <i>include/armadillo_bits/config.hpp</i>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="http://cplusplus.com/doc/tutorial/variables/">C++ variable types</a></li>
-<li><a href="http://www.cplusplus.com/doc/tutorial/other_data_types/">explanation of <i>typedef</i></a></li>
-<li><a href="#Mat">imat &amp; umat</a> matrix types
-<li><a href="#Col">ivec &amp; uvec</a> vector types
-</ul>
-</li>
-<br>
-</ul>
-<hr class="greyline"><br>
-
-<a name="cx_float_double"></a>
-<b>cx_float</b>, <b>cx_double</b>
-<ul>
-<li>
-cx_float is a typedef for <i>std::complex&lt;float&gt;</i>
-</li>
-<br>
-<li>
-cx_double is a typedef for <i>std::complex&lt;double&gt;</i>
-</li>
-<br>
-<li>See also:
-<ul>
-<li><a href="http://cplusplus.com/reference/std/complex/">complex numbers in the standard C++ library</a></li>
-<li><a href="http://www.cplusplus.com/doc/tutorial/other_data_types/">explanation of <i>typedef</i></a></li>
-<li><a href="#Mat">cx_mat</a> matrix type
-<li><a href="#Col">cx_vec</a> vector type
-</ul>
-</li>
-<br>
-</ul>
-
-<a name="syntax"></a>
-<hr class="greyline">
-<br>
-<b>
-Examples of Matlab/Octave syntax and conceptually corresponding Armadillo syntax
-</b>
-<br>
-<br>
-<ul>
-<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
-<tbody>
-  <tr>
-    <td style="vertical-align: top;">
-      <b>Matlab/Octave</b>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <b>Armadillo</b>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <b>Notes</b>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A(1, 1)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A(0, 0)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      indexing in Armadillo starts at 0
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A(k, k)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A(k-1, k-1)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      size(A,1)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A<a href="#attributes">.n_rows</a>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      read only
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      size(A,2)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A<a href="#attributes">.n_cols</a>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      size(Q,3)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Q<a href="#attributes">.n_slices</a>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Q is a <a href="#Cube">cube</a> (3D array)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      numel(A)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A<a href="#attributes">.n_elem</a>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A(:, k)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A<a href="#submat">.col</a>(k)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-this is a conceptual example only; 
-exact conversion from Matlab/Octave to Armadillo syntax
-will require taking into account that indexing starts at 0
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A(k, :)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A<a href="#submat">.row</a>(k)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A(:, p:q)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A<a href="#submat">.cols</a>(p, q)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A(p:q, :)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A<a href="#submat">.rows</a>(p, q)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A(p:q, r:s)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <font size=-1>
-      A<a href="#submat">.submat</a>(p, r, q, s)
-      </font>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <font size=-1>
-      A.submat(first_row, first_col, last_row, last_col)
-      </font>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <font size=-1>
-      or
-      </font>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <font size=-1>
-      A(&nbsp;<a href="#submat">span</a>(p,q),&nbsp;<a href="#submat">span</a>(r,s)&nbsp;)
-      </font>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <font size=-1>
-      A(&nbsp;span(first_row,&nbsp;last_row), span(first_col,&nbsp;last_col)&nbsp;)
-      </font>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      Q(:, :, k)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Q<a href="#subcube">.slice</a>(k)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Q is a <a href="#Cube">cube</a> (3D array)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      Q(:, :, t:u)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Q<a href="#subcube">.slices</a>(t, u)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      Q(p:q, r:s, t:u)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <font size=-1>
-      Q<a href="#subcube">.subcube</a>(p,&nbsp;r,&nbsp;t,&nbsp;q,&nbsp;s,&nbsp;u)
-      </font>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <font size=-1>
-      .subcube(first_row, first_col, first_slice, last_row, last_col, last_slice)
-      </font>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <font size=-1>
-      or
-      </font>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <font size=-1>
-      Q(&nbsp;<a href="#subcube">span</a>(p,q),&nbsp;<a href="#subcube">span</a>(r,s),&nbsp;<a href="#subcube">span</a>(t,u)&nbsp;)
-      </font>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A'
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A<a href="#t_st_members">.t()</a> or <a href="#trans">trans</a>(A)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      matrix transpose / Hermitian transpose
-      <br>
-      (for complex matrices, the conjugate of each element is taken)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A.'
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-       A<a href="#t_st_members">.st()</a> or <a href="#strans">strans</a>(A)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      simple matrix transpose
-      <br>
-      (for complex matrices, the conjugate of each element is not taken)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A = zeros(size(A))
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A<a href="#zeros_member">.zeros()</a>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A = ones(size(A))
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A.<a href="#ones_member">ones()</a>
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A = zeros(k)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A = <a href="#zeros_standalone">zeros</a>&lt;mat&gt;(k,k)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A = ones(k)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A = <a href="#ones_standalone">ones</a>&lt;mat&gt;(k,k)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      C = complex(A,B)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      cx_mat C = <a href="#Mat">cx_mat</a>(A,B)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A .* B
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A % B
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <a href="#operators">element-wise multiplication</a>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A ./ B
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A / B
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <a href="#operators">element-wise division</a>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A \ B
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <a href="#solve">solve</a>(A,B)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      conceptually similar to <a href="#inv">inv</a>(A)*B, but more efficient
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A = A + 1;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A++
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A = A - 1;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A--
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A = [ 1 2; 3 4; ]
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-A&nbsp;<font size=-1>&lt;&lt;</font> 1 <font size=-1>&lt;&lt;</font> 2 <font size=-1>&lt;&lt;</font> endr<br>
-&nbsp;&nbsp;&nbsp;<font size=-1>&lt;&lt;</font> 3 <font size=-1>&lt;&lt;</font> 4 <font size=-1>&lt;&lt;</font> endr;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <a href="#element_initialisation">element initialisation</a>,
-      with special element <i>endr</i> indicating <i>end of row</i>
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      X = [&nbsp;A&nbsp;&nbsp;B&nbsp;]
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      X = <a href="#join">join_rows</a>(A,B)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      X = [&nbsp;A;&nbsp;B&nbsp;]
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      X = <a href="#join">join_cols</a>(A,B)
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      A
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      cout <font size=-1>&lt;&lt;</font> A <font size=-1>&lt;&lt;</font> endl;
-      <br>or
-      <br>A<a href="#print">.print</a>("A =");
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      save&nbsp;-ascii&nbsp;'A.dat'&nbsp;A
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A<a href="#save_load_mat">.save</a>("A.dat",&nbsp;raw_ascii);
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      Matlab/Octave matrices saved as ascii are readable by Armadillo (and vice-versa)
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      load&nbsp;-ascii&nbsp;'A.dat'
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      A<a href="#save_load_mat">.load</a>("A.dat",&nbsp;raw_ascii);
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-  </tr>
-  <tr>
-    <td style="vertical-align: top;">
-      S&nbsp;=&nbsp;{&nbsp;'abc';&nbsp;'def'&nbsp;}
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <a href="#field">field</a>&lt;std::string&gt; S(2);
-      <br>S(0) = "abc";
-      <br>S(1) = "def";
-    </td>
-    <td style="vertical-align: top;">
-      &nbsp;
-    </td>
-    <td style="vertical-align: top;">
-      <a href="#field">fields</a> can store arbitrary objects, in a 1D or 2D layout
-    </td>
-  </tr>
-</tbody>
-</table>
-</ul>
-<br>
-
-<a name="example_prog"></a>
-<hr class="greyline">
-<br>
-<b>example program</b>
-<br>
-<br>
-<ul>
-<li>
-If you save the program below as <i>example.cpp</i>,
-under Linux you can compile it using:
-<br>
-g++ example.cpp -o example -O1 -larmadillo
-</li>
-<ul>
-<pre>
-#include &lt;iostream&gt;
-#include &lt;armadillo&gt;
-
-using namespace std;
-using namespace arma;
-
-int main(int argc, char** argv)
-  {
-  mat A = randu&lt;mat&gt;(4,5);
-  mat B = randu&lt;mat&gt;(4,5);
-  
-  cout &lt;&lt; A*trans(B) &lt;&lt; endl;
-  
-  return 0;
-  }
-</pre>
-</ul>
-<li>
-You may also want to have a look at the example programs that come with the Armadillo archive.
-</li>
-<br>
-<li>
-As Armadillo is a template library, we strongly recommended to have optimisation enabled when compiling programs
-(eg. when compiling with GCC, use the -O1 or -O2 options).
-</li>
-</ul>
-<br>
-
-
-<!--
-<a name="catching_exceptions"></a>
-<hr class="greyline">
-<br>
-<b>how to catch std::runtime_error exceptions</b>
-<br>
-<br>
-<ul>
-<li>
-If a function such as <a href="#inv">inv()</a> fails to find a solution,
-an error message is printed and a <i>std::runtime_error</i> exception is thrown.
-If the exception is not caught, the program typically terminates.
-Below is an example of how to catch exceptions:
-<ul>
-<pre>
-#include &lt;iostream&gt;
-#include &lt;armadillo&gt;
-
-using namespace std;
-using namespace arma;
-
-int main(int argc, char** argv)
-  {
-  // create a non-invertible matrix
-  mat A = zeros&lt;mat&gt;(5,5);
-  
-  mat B;
-  
-  try
-    {
-    B = inv(A);
-    }
-  catch (std::runtime_error&amp; x)
-    {
-    cout &lt;&lt; "caught an exception" &lt;&lt; endl;
-    }
-  
-  return 0;
-  }
-</pre>
-</ul>
-<li>
-See also:
-<ul>
-<li><a href="#logging">logging of warnings and errors</a></li>
-<li><a href="http://cplusplus.com/doc/tutorial/exceptions/">tutorial on exceptions</a></li>
-<li><a href="http://cplusplus.com/reference/std/stdexcept/runtime_error/">std::runtime_error</a></li>
-</ul>
-</li>
-<br>
-</ul>
-<br>
--->
-
-<a name="api_changes"></a>
-<hr class="greyline">
-<br>
-<b>API Changes, Additions and Deprecations</b>
-<br>
-<br>
-Armadillo's version number is X.Y.Z, where X is a major version, Y is a minor version, and Z is the patch level (indicating bug fixes).
-<br>
-<br>
-Within each major version (eg. 2.x), minor versions with an even number (eg. 2.2) are backwards compatible with earlier even minor versions (eg. 2.0).
-For example, code written for version 2.0 will work with version 2.2.
-However, as each minor version may have more features (ie. API extensions) than earlier versions,
-code written for version 2.2 doesn't necessarily work with 2.0.
-<br>
-<br>
-An odd minor version number (eg. 2.3) indicates an experimental version.
-Experimental versions are generally faster and have more functionality,
-but their APIs have not been finalised yet.
-<br>
-<br>
-In general, we don't like changes to existing APIs and prefer not to break any user software.
-However, to allow evolution and help code maintenance, we reserve the right to change the APIs in future major versions of Armadillo,
-while remaining backwards compatible wherever possible
-(eg. 3.0 may have slightly different APIs than 2.x).
-Also, in a rare instance the user API may need to be altered if a bug fix absolutely requires it.
-<br>
-<br>
-<br>
-<a name="deprecated"></a>
-Below is a list of deprecated functionality; this functionality will be <b>removed</b> in version 3.0:
-<ul>
-<li>
-<i>.print_trans()</i> and <i>.raw_print_trans()</i> are deprecated;
-<br>instead, you can chain <i>.t()</i> and <i>.print()</i> to achieve a similar result: <i>.t().print()</i>
-<br>&nbsp;
-</li>
-<li>
-support for tying writeable auxiliary (external) memory to fixed size matrices is deprecated;
-<br>instead, you can use standard matrices with <a href="#adv_constructors_mat">writeable auxiliary memory</a>,
-or initialise fixed size matrices by <a href="#adv_constructors_mat">copying the memory</a>.
-Using auxiliary memory with standard matrices is unaffected.
-<br>&nbsp;
-</li>
-</ul>
-<br>
-<br>
-Below is a list of additions and changes since prior versions of Armadillo:
-<ul>
-<a name="added_in_24"></a>
-<li>Added in 2.4:
-<ul>
-<li>shorter forms of transposes: <a href="#t_st_members">.t()</a> and <a href="#t_st_members">.st()</a></li>
-<li><a href="#resize_member">.resize()</a> and <a href="#resize">resize()</a> (added in 2.4.1)</li>
-<li>optional use of 64 bit indices (allowing matrices to have more than 4 billion elements),
-<br>enabled via ARMA_64BIT_WORD in <i>include/armadillo_bits/config.hpp</i></li>
-<li>experimental support for C++11 initialiser lists, enabled via ARMA_USE_CXX11 in <i>include/armadillo_bits/config.hpp</i></li>
-</ul>
-<br>
-<li>Changed in 2.4:
-<ul>
-<li>refactored code to eliminate warnings when using the Clang C++ compiler</li>
-<li><a href="#Mat">umat</a>, <a href="#Col">uvec</a>, <a href="#min_and_max_member">.min()</a> and <a href="#min_and_max_member">.max()</a>
-have been changed to use the <a href="#uword"><i>uword</i></a> type instead of the <i>u32</i> type;
-by default the <i>uword</i> and <i>u32</i> types are equivalent (ie. unsigned integer type with a minimum width 32 bits);
-however, when the use of 64 bit indices is enabled via ARMA_64BIT_WORD in <i>include/armadillo_bits/config.hpp</i>,
-the <i>uword</i> type then has a minimum width of 64 bits
-</ul>
-</li>
-<br>
-<li>Added in 2.2:
-<ul>
-<li><a href="#svd_econ">svd_econ()</a></li>
-<li><a href="#toeplitz">circ_toeplitz()</a></li>
-<li><a href="#is_vec">.is_colvec()</a> and <a href="#is_vec">.is_rowvec()</a></li>
-</ul>
-<br>
-<li>Changed in 2.0:
-<ul>
-<li><a href="#trans">trans()</a> now takes the complex conjugate when transposing a complex matrix</li>
-<li>Forms of
-<a href="#chol">chol()</a>, <a href="#eig_sym">eig_sym()</a>, <a href="#eig_gen">eig_gen()</a>,
-<a href="#inv">inv()</a>, <a href="#lu">lu()</a>, <a href="#pinv">pinv()</a>, <a href="#princomp">princomp()</a>,
-<a href="#qr">qr()</a>, <a href="#solve">solve()</a>, <a href="#svd">svd()</a>, <a href="#syl">syl()</a>
-that do not return a bool indicating success now throw <i>std::runtime_error</i> exceptions when failures are detected</li>
-<li>princomp_cov() has been removed; <a href="#eig_sym">eig_sym()</a> in conjunction with <a href="#cov">cov()</a> can be used instead</li>
-<li><a href="#is_vec">.is_vec()</a> now outputs <i>true</i> for empty vectors (eg. 0x1)</li>
-<li>set_log_stream() &amp; get_log_stream() have been replaced by <a href="#logging">set_stream_err1()</a> &amp; <a href="#logging">get_stream_err1()</a></li>
-</ul>
-<br>
-<li>Added in 2.0:
-<ul>
-<li><a href="#det">det()</a>, <a href="#inv">inv()</a> and <a href="#solve">solve()</a> can be forced to use more precise algorithms for tiny matrices (&le;&nbsp;4x4)</li>
-<li><a href="#syl">syl()</a>, for solving Sylvester's equation</li>
-<li><a href="#strans">strans()</a>, for transposing a complex matrix without taking the complex conjugate</li>
-<li><a href="#symmat">symmatu()</a> and <a href="#symmat">symmatl()</a></li>
-<li>submatrices of <a href="#submat">submatrices</a></li>
-<li>faster <a href="#inv">inverse</a> of symmetric positive definite matrices</li>
-<li>faster element access for <a href="#adv_constructors_mat_fixed">fixed size</a> matrices</li>
-<li>faster multiplication of tiny matrices (eg. 4x4)</li>
-<li>faster compound expressions containing <a href="#submat">submatrices</a></li>
-<li>handling of arbitrarily sized empty matrices (eg. 5x0)</li>
-<li>.count() member function in <a href="#running_stat">running_stat</a> and <a href="#running_stat_vec">running_stat_vec</a></li>
-<li><a href="#save_load_mat">loading &amp; saving</a> of matrices as CSV text files</li>
-</ul>
-<br>
-<li>Added in 1.2:
-<ul>
-<li><a href="#min_and_max_member">.min() &amp; .max()</a> member functions of Mat and Cube</li>
-<li><a href="#misc_fns">floor()</a> and <a href="#misc_fns">ceil()</a></li>
-<li>representation of &ldquo;not a number&rdquo;: <a href="#math_constants">math::nan()</a></li>
-<li>representation of infinity: <a href="#math_constants">math::inf()</a></li>
-<li>standalone <a href="#is_finite_standalone">is_finite()</a></li>
-<li><a href="#in_range">.in_range()</a> can use <b>span()</b> arguments</li>
-<li><a href="#adv_constructors_mat">fixed size</a> matrices and vectors can use auxiliary (external) memory</li>
-<li><a href="#submat">submatrices</a> and <a href="#subfield">subfields</a> can be accessed via <i><b>X(</b>&nbsp;<b>span(</b>a,b<b>)</b>,&nbsp;<b>span(</b>c,d<b>)</b>&nbsp;<b>)</b></i></li>
-<li><a href="#subcube">subcubes</a> can be accessed via <i><b>X(</b>&nbsp;<b>span(</b>a,b<b>)</b>,&nbsp;<b>span(</b>c,d<b>)</b>,&nbsp;<b>span(</b>e,f<b>)</b>&nbsp;<b>)</b></i></li>
-<li>the two argument version of <i><b>span</b></i> can be replaced by
-<i><b>span::all</b></i> or <i><b>span()</b></i>, to indicate an entire range
-</li>
-<li>for cubes, the two argument version of <i><b>span</b></i> can be replaced by
-a single argument version, <i><b>span(</b>a<b>)</b></i>, to indicate a single column, row or slice
-</li>
-<li>arbitrary "flat" subcubes can be interpreted as matrices; for example:
-<ul>
-<pre>
-cube Q = randu&lt;cube&gt;(5,3,4);
-mat  A = Q(&nbsp;span(1),&nbsp;span(1,2),&nbsp;span::all&nbsp;);
-// A has a size of 2x4
-
-vec v = ones&lt;vec&gt;(4);
-Q(&nbsp;span(1),&nbsp;span(1),&nbsp;span::all&nbsp;)&nbsp;=&nbsp;v;
-</pre>
-</ul>
-</li>
-<li>interpretation of matrices as triangular through <a href="#trimat">trimatu() / trimatl()</a></li>
-<li>explicit handling of triangular matrices by <a href="#solve">solve()</a> and <a href="#inv">inv()</a></li>
-<li>extended syntax for <a href="#submat">submatrices</a>, including access to elements whose indices are specified in a vector</li>
-<li>ability to change the stream used for <a href="#logging">logging</a> of errors and warnings</li>
-<li>ability to <a href="#save_load_mat">save/load matrices</a> in raw binary format</li>
-<li>cumulative sum function: <a href="#cumsum">cumsum()</a></li>
-</ul>
-</li>
-<br>
-<li>
-Changed in 1.0 (compared to earlier 0.x development versions):
-<ul>
-<li>
-the 3 argument version of <a href="#lu">lu()</a>,
-eg. lu(L,U,X),
-provides L and U which should be the same as produced by Octave 3.2
-(this was not the case in versions prior to 0.9.90)
-</li>
-<br>
-<li>
-rand() has been replaced by <a href="#randu_randn_standalone">randu()</a>;
-this has been done to avoid confusion with <a href="http://cplusplus.com/reference/clibrary/cstdlib/rand/">std::rand()</a>,
-which generates random numbers in a different interval
-</li>
-<br>
-<li>
-In versions earlier than 0.9.0,
-some multiplication operations directly converted result matrices with a size of 1x1 into scalars.
-This is no longer the case.
-If you know the result of an expression will be a 1x1 matrix and wish to treat it as a pure scalar,
-use the <a href="#as_scalar">as_scalar()</a> wrapping function
-</li>
-<br>
-<li>
-Almost all functions have been placed in the delayed operations framework (for speed purposes).
-This may affect code which assumed that the output of some functions was a pure matrix.
-The solution is easy, as explained below.
-<br>
-<br>
-In general, Armadillo queues operations before executing them.
-As such, the direct output of an operation or function cannot be assumed to be a directly accessible matrix.
-The queued operations are executed when the output needs to be stored in a matrix,
-eg. <i>mat&nbsp;B&nbsp;=&nbsp;trans(A)</i> or <i>mat&nbsp;B(trans(A))</i>.
-If you need to force the execution of the delayed operations,
-place the operation or function inside the corresponding Mat constructor.
-For example, if your code assumed that the output of some functions was a pure matrix,
-eg. <i>chol(m).diag()</i>, change the code to <i>mat(chol(m)).diag()</i>.
-Similarly, if you need to pass the result of an operation such as <i>A+B</i> to one of your own functions,
-use <i>my_function(&nbsp;mat(A+B)&nbsp;)</i>.
-</li>
-</ul>
-</li>
-<br>
-</ul>
-<br>
-<br>
-
-
-<!-- END CONTENT -->
-
-
-<hr>
-<br>
-<br>
-
-</td>
-</tr>
-</tbody>
-</table>
-</center>
-</body>
-</html>
--- a/armadillo-2.4.4/docs/style.css	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-body
-  {
-  font-family: "Trebuchet MS", Trebuchet, "DejaVu Sans", "Luxi Sans", "Liberation Sans", Arial, Helvetica, sans-serif;
-  color: #000000;
-  background-color: #FFFFFF;
-  /* font-size: 10pt; */
-  /* line-height: 120%; */
-  height: 110%;
-  }
-
-/* In the above, "height: 110%;" is a hack for stylistic purposes.
-   It typically makes the browser place a scroll bar on the left,
-   thereby reducing the overall width of the page. This is necessary,
-   as some pages do not have enough content (height wise) to make
-   the scrollbar appear, while other pages are long enough to have
-   the scrollbar.  When content is centered for stylistic purposes,
-   the content on "short" pages will be in a different place than
-   the content on "long" pages. This can be visually annoying when
-   navigating from a "short" page to a "long" page, or vice versa.
-   Forcing the scrollbar to always appear removes this problem.
-*/  
-
-pre
-  {
-  font-family: "DejaVu Sans Mono", "Liberation Mono", "Andale Mono", "Bitstream Vera Sans Mono", "Luxi Mono", monospace;
-  font-size: smaller;
-  color: #666666;
-  }
-
-a
-  {
-  text-decoration: none;
-  color: #57a706;
-  }
-
-a:hover
-  {
-  text-decoration: underline;
-  color: #57a706;
-  }
-
-a.menu
-  {
-  text-decoration: none;
-  color: #CCCCCC;
-  }
-
-a.menu:hover
-  {
-  text-decoration: none;
-  color: #57a706;
-  }
-
-a.hidden, a.hidden:hover, a.hidden:active, a.hidden:link, a.hidden:visited
-  {
-  text-decoration: none;
-  border-bottom: 0px
-  }
-
-table
-  {
-  /* border: 1px solid #000; */
-  /* display: block; */
-  border-collapse: collapse;
-  }
-
-td.line
-  {
-  border-left: 2px solid rgb(204, 204, 204);
-  }
-
--- a/armadillo-2.4.4/examples/Makefile.cmake	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-# The generated "Makefile" from "Makefile.cmake" is only usable after
-# the Armadillo library has been configured and installed by CMake.
-
-CXX=g++
-#CXX=g++-4.2
-## Under MacOS you may have an old compiler as default (e.g. GCC 4.0).
-## However, GCC 4.2 or later is available and preferable due to better
-## handling of template code.
-
-#CXX=CC
-## When using the Sun Studio compiler
-
-
-# flags configured by CMake
-ifeq (${ARMA_OS},macos)
-  EXTRA_LIB_FLAGS = -framework Accelerate
-endif
-
-#EXTRA_LIB_FLAGS = -library=sunperf
-## When using the Sun Studio compiler
-
-
-ifeq (${ARMA_USE_BOOST},true)
-  BOOST_INCLUDE_FLAG = -I ${Boost_INCLUDE_DIR}
-endif
-
-
-
-LIB_FLAGS = -larmadillo $(EXTRA_LIB_FLAGS)
-## NOTE: on Ubuntu and Debian based systems you may need to add 
-## -lgfortran to LIB_FLAGS
-
-
-
-OPT = -O1
-## As the Armadillo library uses recursive templates,
-## compilation times depend on the level of optimisation:
-##
-## -O0: quick compilation, but the resulting program will be slow
-## -O1: produces programs which achieve most of the possible speedup
-## -O3: produces programs which have almost all possible speedups,
-##      but compilation takes considerably longer
-
-
-#OPT = -xO4 -xannotate=no
-## When using the Sun Studio compiler
-
-
-#EXTRA_OPT = -fwhole-program
-## Uncomment the above line if you're compiling 
-## all source files into one program in a single hit.
-
-
-#DEBUG = -DARMA_EXTRA_DEBUG
-## Uncomment the above line to enable low-level
-## debugging.  Lots of debugging information will
-## be printed when a compiled program is run.
-## Please enable this option when reporting bugs.
-
-
-#FINAL = -DARMA_NO_DEBUG
-## Uncomment the above line to disable Armadillo's checks.
-## DANGEROUS!  Not recommended unless your code has been
-## thoroughly tested.
-
-
-#
-#
-#
-
-CXXFLAGS = $(BOOST_INCLUDE_FLAG) $(DEBUG) $(FINAL) $(OPT) $(EXTRA_OPT)
-
-all: example1 example2
-
-example1: example1.cpp
-	$(CXX) $(CXXFLAGS)  -o $@  $<  $(LIB_FLAGS)
-
-example2: example2.cpp
-	$(CXX) $(CXXFLAGS)  -o $@  $<  $(LIB_FLAGS)
-
-
-.PHONY: clean
-
-clean:
-	rm -f example1 example2
-
--- a/armadillo-2.4.4/examples/example1.cpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,183 +0,0 @@
-#include <iostream>
-
-#include "armadillo"
-
-using namespace arma;
-using namespace std;
-
-
-int main(int argc, char** argv)
-  {
-  cout << "Armadillo version: " << arma_version::as_string() << endl;
-  
-  // directly specify the matrix size (elements are uninitialised)
-  mat A(2,3);
-  
-  // .n_rows = number of rows    (read only)
-  // .n_cols = number of columns (read only)
-  cout << "A.n_rows = " << A.n_rows << endl;
-  cout << "A.n_cols = " << A.n_cols << endl;
-  
-  // directly access an element (indexing starts at 0)
-  A(1,2) = 456.0;
-  
-  A.print("A:");
-  
-  // scalars are treated as a 1x1 matrix,
-  // hence the code below will set A to have a size of 1x1
-  A = 5.0;
-  A.print("A:");
-  
-  // if you want a matrix with all elements set to a particular value
-  // the .fill() member function can be used
-  A.set_size(3,3);
-  A.fill(5.0);
-  A.print("A:");
-  
-  
-  mat B;
-  
-  // endr indicates "end of row"
-  B << 0.555950 << 0.274690 << 0.540605 << 0.798938 << endr
-    << 0.108929 << 0.830123 << 0.891726 << 0.895283 << endr
-    << 0.948014 << 0.973234 << 0.216504 << 0.883152 << endr
-    << 0.023787 << 0.675382 << 0.231751 << 0.450332 << endr;
-  
-  // print to the cout stream
-  // with an optional string before the contents of the matrix
-  B.print("B:");
-  
-  // the << operator can also be used to print the matrix
-  // to an arbitrary stream (cout in this case) 
-  cout << "B:" << endl << B << endl;
-  
-  // save to disk
-  B.save("B.txt", raw_ascii);
-  
-  // load from disk
-  mat C;
-  C.load("B.txt");
-  
-  C += 2.0 * B;
-  C.print("C:");
-  
-  
-  // submatrix types:
-  //
-  // .submat(first_row, first_column, last_row, last_column)
-  // .row(row_number)
-  // .col(column_number)
-  // .cols(first_column, last_column)
-  // .rows(first_row, last_row)
-  
-  cout << "C.submat(0,0,3,1) =" << endl;
-  cout << C.submat(0,0,3,1) << endl;
-  
-  // generate the identity matrix
-  mat D = eye<mat>(4,4);
-  
-  D.submat(0,0,3,1) = C.cols(1,2);
-  D.print("D:");
-  
-  // transpose
-  cout << "trans(B) =" << endl;
-  cout << trans(B) << endl;
-  
-  // maximum from each column (traverse along rows)
-  cout << "max(B) =" << endl;
-  cout << max(B) << endl;
-  
-  // maximum from each row (traverse along columns)
-  cout << "max(B,1) =" << endl;
-  cout << max(B,1) << endl;
-  
-  // maximum value in B
-  cout << "max(max(B)) = " << max(max(B)) << endl;
-  
-  // sum of each column (traverse along rows)
-  cout << "sum(B) =" << endl;
-  cout << sum(B) << endl;
-  
-  // sum of each row (traverse along columns)
-  cout << "sum(B,1) =" << endl;
-  cout << sum(B,1) << endl;
-  
-  // sum of all elements
-  cout << "sum(sum(B)) = " << sum(sum(B)) << endl;
-  cout << "accu(B)     = " << accu(B) << endl;
-  
-  // trace = sum along diagonal
-  cout << "trace(B)    = " << trace(B) << endl;
-  
-  // random matrix -- values are uniformly distributed in the [0,1] interval
-  mat E = randu<mat>(4,4);
-  E.print("E:");
-  
-  cout << endl;
-  
-  // row vectors are treated like a matrix with one row
-  rowvec r;
-  r << 0.59499 << 0.88807 << 0.88532 << 0.19968;
-  r.print("r:");
-  
-  // column vectors are treated like a matrix with one column
-  colvec q;
-  q << 0.81114 << 0.06256 << 0.95989 << 0.73628;
-  q.print("q:");
-  
-  // dot or inner product
-  cout << "as_scalar(r*q) = " << as_scalar(r*q) << endl;
-  
-  
-  // outer product
-  cout << "q*r =" << endl;
-  cout << q*r << endl;
-  
-  // multiply-and-accumulate operation
-  // (no temporary matrices are created)
-  cout << "accu(B % C) = " << accu(B % C) << endl;
-  
-  // sum of three matrices (no temporary matrices are created)
-  mat F = B + C + D;
-  F.print("F:");
-  
-  // imat specifies an integer matrix
-  imat AA;
-  imat BB;
-  
-  AA << 1 << 2 << 3 << endr << 4 << 5 << 6 << endr << 7 << 8 << 9;
-  BB << 3 << 2 << 1 << endr << 6 << 5 << 4 << endr << 9 << 8 << 7;
-  
-  // comparison of matrices (element-wise)
-  // output of a relational operator is a umat
-  umat ZZ = (AA >= BB);
-  ZZ.print("ZZ =");
-  
-  
-  // 2D field of arbitrary length row vectors
-  // (fields can also store abitrary objects, e.g. instances of std::string)
-  field<rowvec> xyz(3,2);
-  
-  xyz(0,0) = randu(1,2);
-  xyz(1,0) = randu(1,3);
-  xyz(2,0) = randu(1,4);
-  xyz(0,1) = randu(1,5);
-  xyz(1,1) = randu(1,6);
-  xyz(2,1) = randu(1,7);
-  
-  cout << "xyz:" << endl;
-  cout << xyz << endl;
-  
-  
-  // cubes ("3D matrices")
-  cube Q( B.n_rows, B.n_cols, 2 );
-  
-  Q.slice(0) = B;
-  Q.slice(1) = 2.0 * B;
-  
-  Q.print("Q:");
-  
-  
-  return 0;
-  }
-
--- a/armadillo-2.4.4/examples/example1_win32/example1_win32.sln	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual C++ Express 2008
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example1_win32", "example1_win32.vcproj", "{3D5424A0-4AFB-4477-9D2B-792D5FE32734}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Release|Win32 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Debug|Win32.ActiveCfg = Debug|Win32
-		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Debug|Win32.Build.0 = Debug|Win32
-		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Release|Win32.ActiveCfg = Release|Win32
-		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Release|Win32.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
--- a/armadillo-2.4.4/examples/example1_win32/example1_win32.vcproj	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9.00"
-	Name="example1_win32"
-	ProjectGUID="{3D5424A0-4AFB-4477-9D2B-792D5FE32734}"
-	RootNamespace="example1_win32"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
-			ConfigurationType="1"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\..\include"
-				PreprocessorDefinitions="ARMA_USE_LAPACK;ARMA_USE_BLAS"
-				MinimalRebuild="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="3"
-				WarningLevel="3"
-				DebugInformationFormat="4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="lapack_win32_MT.lib blas_win32_MT.lib"
-				OutputFile="$(OutDir)\example1.exe"
-				AdditionalLibraryDirectories="..\lib_win32"
-				GenerateDebugInformation="true"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				Description="Copy .DLL to output directory"
-				CommandLine="copy ..\lib_win32\*.dll $(ConfigurationName)"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
-			ConfigurationType="1"
-			CharacterSet="2"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories="..\..\include"
-				PreprocessorDefinitions="ARMA_USE_LAPACK;ARMA_USE_BLAS"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				WarningLevel="3"
-				DebugInformationFormat="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="lapack_win32_MT.lib blas_win32_MT.lib"
-				OutputFile="$(OutDir)\example1.exe"
-				AdditionalLibraryDirectories="..\lib_win32"
-				GenerateDebugInformation="true"
-				OptimizeReferences="2"
-				EnableCOMDATFolding="2"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				Description="Copy .DLL to output directory"
-				CommandLine="copy ..\lib_win32\*.dll $(ConfigurationName)"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
-			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
-			>
-			<File
-				RelativePath="..\example1.cpp"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl;inc;xsd"
-			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
-			>
-		</Filter>
-		<Filter
-			Name="Resource Files"
-			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
-			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
-			>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
--- a/armadillo-2.4.4/examples/example2.cpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-#include <iostream>
-
-#include "armadillo"
-
-using namespace arma;
-using namespace std;
-
-
-int main(int argc, char** argv)
-  {
-  cout << "Armadillo version: " << arma_version::as_string() << endl;
-  
-  mat A;
-  
-  A << 0.165300 << 0.454037 << 0.995795 << 0.124098 << 0.047084 << endr
-    << 0.688782 << 0.036549 << 0.552848 << 0.937664 << 0.866401 << endr
-    << 0.348740 << 0.479388 << 0.506228 << 0.145673 << 0.491547 << endr
-    << 0.148678 << 0.682258 << 0.571154 << 0.874724 << 0.444632 << endr
-    << 0.245726 << 0.595218 << 0.409327 << 0.367827 << 0.385736 << endr;
-  
-  A.print("A =");
-  
-  // determinant
-  cout << "det(A) = " << det(A) << endl;
-  
-  // inverse
-  cout << "inv(A) = " << endl << inv(A) << endl;
-  
-  
-  //
-  
-  double k = 1.23;
-  
-  mat    B = randu<mat>(5,5);
-  mat    C = randu<mat>(5,5);
-  
-  rowvec r = randu<rowvec>(5);
-  colvec q = randu<colvec>(5);
-  
-  
-  // examples of some expressions
-  // for which optimised implementations exist
-  
-  // optimised implementation of a trinary expression
-  // that results in a scalar
-  cout << "as_scalar( r*inv(diagmat(B))*q ) = ";
-  cout << as_scalar( r*inv(diagmat(B))*q ) << endl;
-  
-  // example of an expression which is optimised 
-  // as a call to the dgemm() function in BLAS:
-  cout << "k*trans(B)*C = " << endl << k*trans(B)*C;
-  
-  
-  // If you want to see a trace of how Armadillo
-  // evaluates expressions, compile with the
-  // ARMA_EXTRA_DEBUG macro defined.
-  // This was designed to work with the GCC compiler,
-  // but it may also work with other compilers
-  // if you have the Boost libraries installed
-  // and told Armadillo to use them.
-  // 
-  // Example for GCC:
-  // g++ example2.cpp -o example2 -larmadillo -DARMA_EXTRA_DEBUG
-  // 
-  // Running example2 will now produce a truckload of messages,
-  // so you may want to redirect the output to a log file.
-  
-  return 0;
-  }
-
--- a/armadillo-2.4.4/examples/example2_win32/example2_win32.sln	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual C++ Express 2008
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example2_win32", "example2_win32.vcproj", "{3D5424A0-4AFB-4477-9D2B-792D5FE32734}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Release|Win32 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Debug|Win32.ActiveCfg = Debug|Win32
-		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Debug|Win32.Build.0 = Debug|Win32
-		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Release|Win32.ActiveCfg = Release|Win32
-		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Release|Win32.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
--- a/armadillo-2.4.4/examples/example2_win32/example2_win32.vcproj	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9.00"
-	Name="example2_win32"
-	ProjectGUID="{3D5424A0-4AFB-4477-9D2B-792D5FE32734}"
-	RootNamespace="example1_win32"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
-			ConfigurationType="1"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\..\include"
-				PreprocessorDefinitions="ARMA_USE_LAPACK;ARMA_USE_BLAS"
-				MinimalRebuild="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="3"
-				WarningLevel="3"
-				DebugInformationFormat="4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="lapack_win32_MT.lib blas_win32_MT.lib"
-				OutputFile="$(OutDir)\example2.exe"
-				AdditionalLibraryDirectories="..\lib_win32"
-				GenerateDebugInformation="true"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				Description="Copy .DLL to output directory"
-				CommandLine="copy ..\lib_win32\*.dll $(ConfigurationName)"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
-			ConfigurationType="1"
-			CharacterSet="2"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories="..\..\include"
-				PreprocessorDefinitions="ARMA_USE_LAPACK;ARMA_USE_BLAS"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				WarningLevel="3"
-				DebugInformationFormat="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="lapack_win32_MT.lib blas_win32_MT.lib"
-				OutputFile="$(OutDir)\example2.exe"
-				AdditionalLibraryDirectories="..\lib_win32"
-				GenerateDebugInformation="true"
-				OptimizeReferences="2"
-				EnableCOMDATFolding="2"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				Description="Copy .DLL to output directory"
-				CommandLine="copy ..\lib_win32\*.dll $(ConfigurationName)"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
-			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
-			>
-			<File
-				RelativePath="..\example2.cpp"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl;inc;xsd"
-			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
-			>
-		</Filter>
-		<Filter
-			Name="Resource Files"
-			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
-			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
-			>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
--- a/armadillo-2.4.4/examples/example_lsq.cpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-// Tutorial for linear least square fitting
-// Author: Pierre Moulon
-// Date: 8 December 2009
-// Objective:
-// Fit a 2D line with to a set of points
-// Specifically, find a and b in the model y = ax + b
-// 
-// Direct application of the example in:
-// http://en.wikipedia.org/wiki/Linear_least_squares#Motivational_example
-
-
-#include <iostream>
-
-#include "armadillo"
-
-using namespace arma;
-using namespace std;
-
-
-
-int main(int argc, char** argv)
-  {
-  // points to which we will fit the line
-  mat data = "1 6; 2 5; 3 7; 4 10";
-
-  cout << "Points used for the estimation:" << endl;
-  cout << data << endl;
-
-  // Build matrices to solve Ax = b problem:
-  vec b(data.n_rows);
-  mat C(data.n_rows, 2);
-
-  for(u32 i=0; i<data.n_rows; ++i)
-    {
-    b(i)   = data(i,1);
-    
-    C(i,0) = 1;
-    C(i,1) = data(i,0);
-    }
-  
-  cout << "b:" << endl;
-  cout << b << endl;
-  
-  cout << "Constraint matrix:" << endl;
-  cout << C << endl;
-  
-  // Compute least-squares solution:
-  vec solution = solve(C,b);
-  
-  // solution should be "3.5; 1.4"
-  cout << "solution:" << endl;
-  cout << solution << endl;
-  
-
-  cout << "Reprojection error:" << endl;
-  
-  for(u32 i=0; i<data.n_rows; ++i)
-    {
-    cout << "  residual: " << ( data(i,1) - (solution(0) + solution(1) * data(i,0)) ) << endl;
-    }
-    
-  return 0;
-  }
-
--- a/armadillo-2.4.4/examples/lib_win32/README.txt	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-The lib and dll files in this folder are for 32 bit Windows XP.
-They are compiled versions of the BLAS and LAPACK libraries,
-which are distributed under a BSD license.
-
-The compiled versions were downloaded from:
-http://www.fi.muni.cz/~xsvobod2/misc/lapack/
-
-Sources for BLAS and LAPACK can be found at:
-http://www.netlib.org/blas/
-http://www.netlib.org/lapack/
Binary file armadillo-2.4.4/examples/lib_win32/blas_win32_MT.dll has changed
Binary file armadillo-2.4.4/examples/lib_win32/blas_win32_MT.lib has changed
Binary file armadillo-2.4.4/examples/lib_win32/lapack_win32_MT.dll has changed
Binary file armadillo-2.4.4/examples/lib_win32/lapack_win32_MT.lib has changed
--- a/armadillo-2.4.4/include/armadillo	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,437 +0,0 @@
-// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2012 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-#ifndef ARMA_INCLUDES
-#define ARMA_INCLUDES
-
-
-#include <cstdlib>
-#include <cstring>
-#include <climits>
-#include <cmath>
-
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <stdexcept>
-#include <limits>
-#include <algorithm>
-#include <complex>
-#include <vector>
-
-
-#include "armadillo_bits/config.hpp"
-#include "armadillo_bits/compiler_setup.hpp"
-#include "armadillo_bits/undefine_conflicts.hpp"
-
-
-#if defined(ARMA_USE_CXX11)
-  #include <initializer_list>
-#endif
-
-
-#if !defined(ARMA_HAVE_GETTIMEOFDAY) && !defined(ARMA_USE_BOOST_DATE)
-  #include <ctime>
-#endif
-
-#if defined(ARMA_HAVE_GETTIMEOFDAY)
-  #include <sys/time.h>
-  #undef ARMA_USE_BOOST_DATE
-#endif
-
-
-#if defined(ARMA_USE_BOOST_DATE)
-  #include <boost/date_time/posix_time/posix_time.hpp>
-#endif
-
-
-#if defined(ARMA_HAVE_STD_TR1)
-  // TODO: add handling of this functionality when use of C++11 is enabled
-  #include <tr1/cmath>
-  #include <tr1/complex>
-#elif defined(ARMA_USE_BOOST)
-  #include <boost/math/complex.hpp>
-  #include <boost/math/special_functions/acosh.hpp>
-  #include <boost/math/special_functions/asinh.hpp>
-  #include <boost/math/special_functions/atanh.hpp>
-#endif
-
-
-#if defined(ARMA_USE_BOOST)
-  #if defined(ARMA_EXTRA_DEBUG)
-    #include <boost/format.hpp>
-    #include <boost/current_function.hpp>
-    #define ARMA_USE_BOOST_FORMAT
-  #endif
-#endif
-
-
-#include "armadillo_bits/include_atlas.hpp"
-#include "armadillo_bits/itpp_wrap.hpp"
-
-
-//! \namespace arma namespace for Armadillo classes and functions
-namespace arma
-  {
-  
-  // preliminaries
-  
-  #include "armadillo_bits/forward_bones.hpp"
-  #include "armadillo_bits/arma_static_check.hpp"
-  #include "armadillo_bits/typedef.hpp"
-  #include "armadillo_bits/typedef_blas_int.hpp"
-  #include "armadillo_bits/format_wrap.hpp"
-  #include "armadillo_bits/arma_version.hpp"
-  #include "armadillo_bits/arma_config.hpp"
-  #include "armadillo_bits/traits.hpp"
-  #include "armadillo_bits/promote_type.hpp"
-  #include "armadillo_bits/upgrade_val.hpp"
-  #include "armadillo_bits/restrictors.hpp"
-  #include "armadillo_bits/access.hpp"
-  #include "armadillo_bits/span.hpp"
-  #include "armadillo_bits/constants.hpp"
-  
-  
-  //
-  // class prototypes
-  
-  #include "armadillo_bits/Base_bones.hpp"
-  #include "armadillo_bits/BaseCube_bones.hpp"
-  
-  #include "armadillo_bits/blas_bones.hpp"
-  #include "armadillo_bits/lapack_bones.hpp"
-  #include "armadillo_bits/atlas_bones.hpp"
-  
-  #include "armadillo_bits/blas_wrapper.hpp"
-  #include "armadillo_bits/lapack_wrapper.hpp"
-  #include "armadillo_bits/atlas_wrapper.hpp"
-  
-  #include "armadillo_bits/arrayops_bones.hpp"
-  #include "armadillo_bits/podarray_bones.hpp"
-  #include "armadillo_bits/auxlib_bones.hpp"
-  
-  #include "armadillo_bits/injector_bones.hpp"
-  
-  #include "armadillo_bits/Mat_bones.hpp"
-  #include "armadillo_bits/Col_bones.hpp"
-  #include "armadillo_bits/Row_bones.hpp"
-  #include "armadillo_bits/Cube_bones.hpp"
-  
-  #include "armadillo_bits/typedef_fixed.hpp"
-  
-  #include "armadillo_bits/field_bones.hpp"
-  #include "armadillo_bits/subview_bones.hpp"
-  #include "armadillo_bits/subview_elem1_bones.hpp"
-  #include "armadillo_bits/subview_field_bones.hpp"
-  #include "armadillo_bits/subview_cube_bones.hpp"
-  #include "armadillo_bits/diagview_bones.hpp"
-  
-  
-  #include "armadillo_bits/diskio_bones.hpp"
-  #include "armadillo_bits/wall_clock_bones.hpp"
-  #include "armadillo_bits/running_stat_bones.hpp"
-  #include "armadillo_bits/running_stat_vec_bones.hpp"
-  
-  #include "armadillo_bits/Op_bones.hpp"
-  #include "armadillo_bits/OpCube_bones.hpp"
-  
-  #include "armadillo_bits/eOp_bones.hpp"
-  #include "armadillo_bits/eOpCube_bones.hpp"
-  
-  #include "armadillo_bits/mtOp_bones.hpp"
-  #include "armadillo_bits/mtOpCube_bones.hpp"
-  
-  #include "armadillo_bits/Glue_bones.hpp"
-  #include "armadillo_bits/eGlue_bones.hpp"
-  #include "armadillo_bits/mtGlue_bones.hpp"
-  
-  #include "armadillo_bits/GlueCube_bones.hpp"
-  #include "armadillo_bits/eGlueCube_bones.hpp"
-  #include "armadillo_bits/mtGlueCube_bones.hpp"
-  
-  #include "armadillo_bits/eop_core_bones.hpp"
-  #include "armadillo_bits/eglue_core_bones.hpp"
-  
-  #include "armadillo_bits/Gen_bones.hpp"
-  #include "armadillo_bits/GenCube_bones.hpp"
-  
-  #include "armadillo_bits/op_diagmat_bones.hpp"
-  #include "armadillo_bits/op_diagvec_bones.hpp"
-  #include "armadillo_bits/op_dot_bones.hpp"
-  #include "armadillo_bits/op_inv_bones.hpp"
-  #include "armadillo_bits/op_htrans_bones.hpp"
-  #include "armadillo_bits/op_max_bones.hpp"
-  #include "armadillo_bits/op_min_bones.hpp"
-  #include "armadillo_bits/op_mean_bones.hpp"
-  #include "armadillo_bits/op_median_bones.hpp"
-  #include "armadillo_bits/op_sort_bones.hpp"
-  #include "armadillo_bits/op_sum_bones.hpp"
-  #include "armadillo_bits/op_stddev_bones.hpp"
-  #include "armadillo_bits/op_strans_bones.hpp"
-  #include "armadillo_bits/op_var_bones.hpp"
-  #include "armadillo_bits/op_repmat_bones.hpp"
-  #include "armadillo_bits/op_reshape_bones.hpp"
-  #include "armadillo_bits/op_resize_bones.hpp"
-  #include "armadillo_bits/op_cov_bones.hpp"
-  #include "armadillo_bits/op_cor_bones.hpp"
-  #include "armadillo_bits/op_shuffle_bones.hpp"
-  #include "armadillo_bits/op_prod_bones.hpp"
-  #include "armadillo_bits/op_pinv_bones.hpp"
-  #include "armadillo_bits/op_dotext_bones.hpp"
-  #include "armadillo_bits/op_flip_bones.hpp"
-  #include "armadillo_bits/op_princomp_bones.hpp"
-  #include "armadillo_bits/op_misc_bones.hpp"
-  #include "armadillo_bits/op_relational_bones.hpp"
-  #include "armadillo_bits/op_find_bones.hpp"
-  #include "armadillo_bits/op_chol_bones.hpp"
-  #include "armadillo_bits/op_cx_scalar_bones.hpp"
-  #include "armadillo_bits/op_trimat_bones.hpp"
-  #include "armadillo_bits/op_cumsum_bones.hpp"
-  #include "armadillo_bits/op_symmat_bones.hpp"
-  
-  #include "armadillo_bits/glue_times_bones.hpp"
-  #include "armadillo_bits/glue_mixed_bones.hpp"
-  #include "armadillo_bits/glue_cov_bones.hpp"
-  #include "armadillo_bits/glue_cor_bones.hpp"
-  #include "armadillo_bits/glue_kron_bones.hpp"
-  #include "armadillo_bits/glue_cross_bones.hpp"
-  #include "armadillo_bits/glue_join_bones.hpp"
-  #include "armadillo_bits/glue_relational_bones.hpp"
-  #include "armadillo_bits/glue_solve_bones.hpp"
-  #include "armadillo_bits/glue_conv_bones.hpp"
-  #include "armadillo_bits/glue_toeplitz_bones.hpp"
-  
-  //
-  // debugging functions
-  
-  #include "armadillo_bits/debug.hpp"
-  
-  //
-  //
-  
-  #include "armadillo_bits/cmath_wrap.hpp"
-  
-  //
-  // classes that underlay metaprogramming 
-  
-  #include "armadillo_bits/Proxy.hpp"
-  #include "armadillo_bits/ProxyCube.hpp"
-  
-  #include "armadillo_bits/diagmat_proxy.hpp"
-
-  #include "armadillo_bits/unwrap.hpp"
-  #include "armadillo_bits/unwrap_cube.hpp"
-
-  #include "armadillo_bits/strip.hpp"
-  
-  #include "armadillo_bits/Op_meat.hpp"
-  #include "armadillo_bits/OpCube_meat.hpp"
-  
-  #include "armadillo_bits/mtOp_meat.hpp"
-  #include "armadillo_bits/mtOpCube_meat.hpp"
-  
-  #include "armadillo_bits/Glue_meat.hpp"
-  #include "armadillo_bits/GlueCube_meat.hpp"
-  
-  #include "armadillo_bits/eop_aux.hpp"
-  
-  #include "armadillo_bits/eOp_meat.hpp"
-  #include "armadillo_bits/eOpCube_meat.hpp"
-  
-  #include "armadillo_bits/eGlue_meat.hpp"
-  #include "armadillo_bits/eGlueCube_meat.hpp"
-
-  #include "armadillo_bits/mtGlue_meat.hpp"
-  #include "armadillo_bits/mtGlueCube_meat.hpp"
-  
-  #include "armadillo_bits/Base_meat.hpp"
-  #include "armadillo_bits/BaseCube_meat.hpp"
-  
-  #include "armadillo_bits/Gen_meat.hpp"
-  #include "armadillo_bits/GenCube_meat.hpp"
-  
-  
-  //
-  // ostream
-  
-  #include "armadillo_bits/arma_ostream_bones.hpp"
-  #include "armadillo_bits/arma_ostream_meat.hpp"
-  
-  
-  //
-  // operators
-  
-  #include "armadillo_bits/operator_plus.hpp"
-  #include "armadillo_bits/operator_minus.hpp"
-  #include "armadillo_bits/operator_times.hpp"
-  #include "armadillo_bits/operator_schur.hpp"
-  #include "armadillo_bits/operator_div.hpp"
-  #include "armadillo_bits/operator_relational.hpp"
-  
-  #include "armadillo_bits/operator_cube_plus.hpp"
-  #include "armadillo_bits/operator_cube_minus.hpp"
-  #include "armadillo_bits/operator_cube_times.hpp"
-  #include "armadillo_bits/operator_cube_schur.hpp"
-  #include "armadillo_bits/operator_cube_div.hpp"
-  #include "armadillo_bits/operator_cube_relational.hpp"
-  
-  #include "armadillo_bits/operator_ostream.hpp"
-  
-  
-  //
-  // user accessible functions
-  
-  // the order of the fn_*.hpp include files matters,
-  // as some files require functionality given in preceding files
-  
-  #include "armadillo_bits/fn_conv_to.hpp"
-  #include "armadillo_bits/fn_min.hpp"
-  #include "armadillo_bits/fn_max.hpp"
-  #include "armadillo_bits/fn_accu.hpp"
-  #include "armadillo_bits/fn_sum.hpp"
-  #include "armadillo_bits/fn_diagmat.hpp"
-  #include "armadillo_bits/fn_diagvec.hpp"
-  #include "armadillo_bits/fn_inv.hpp"
-  #include "armadillo_bits/fn_trace.hpp"
-  #include "armadillo_bits/fn_trans.hpp"
-  #include "armadillo_bits/fn_det.hpp"
-  #include "armadillo_bits/fn_log_det.hpp"
-  #include "armadillo_bits/fn_eig.hpp"
-  #include "armadillo_bits/fn_lu.hpp"
-  #include "armadillo_bits/fn_zeros.hpp"
-  #include "armadillo_bits/fn_ones.hpp"
-  #include "armadillo_bits/fn_eye.hpp"
-  #include "armadillo_bits/fn_misc.hpp"
-  #include "armadillo_bits/fn_elem.hpp"
-  #include "armadillo_bits/fn_norm.hpp"
-  #include "armadillo_bits/fn_dot.hpp"
-  #include "armadillo_bits/fn_randu.hpp"
-  #include "armadillo_bits/fn_randn.hpp"
-  #include "armadillo_bits/fn_trig.hpp"
-  #include "armadillo_bits/fn_mean.hpp"
-  #include "armadillo_bits/fn_median.hpp"
-  #include "armadillo_bits/fn_stddev.hpp"
-  #include "armadillo_bits/fn_var.hpp"
-  #include "armadillo_bits/fn_sort.hpp"
-  #include "armadillo_bits/fn_sort_index.hpp"
-  #include "armadillo_bits/fn_strans.hpp"
-  #include "armadillo_bits/fn_chol.hpp"
-  #include "armadillo_bits/fn_qr.hpp"
-  #include "armadillo_bits/fn_svd.hpp"
-  #include "armadillo_bits/fn_solve.hpp"
-  #include "armadillo_bits/fn_repmat.hpp"
-  #include "armadillo_bits/fn_reshape.hpp"
-  #include "armadillo_bits/fn_resize.hpp"
-  #include "armadillo_bits/fn_cov.hpp"
-  #include "armadillo_bits/fn_cor.hpp"
-  #include "armadillo_bits/fn_shuffle.hpp"
-  #include "armadillo_bits/fn_prod.hpp"
-  #include "armadillo_bits/fn_eps.hpp"
-  #include "armadillo_bits/fn_pinv.hpp"
-  #include "armadillo_bits/fn_rank.hpp"
-  #include "armadillo_bits/fn_kron.hpp"
-  #include "armadillo_bits/fn_flip.hpp"
-  #include "armadillo_bits/fn_as_scalar.hpp"
-  #include "armadillo_bits/fn_princomp.hpp"
-  #include "armadillo_bits/fn_cross.hpp"
-  #include "armadillo_bits/fn_join.hpp"
-  #include "armadillo_bits/fn_conv.hpp"
-  #include "armadillo_bits/fn_trunc_exp.hpp"
-  #include "armadillo_bits/fn_trunc_log.hpp"
-  #include "armadillo_bits/fn_toeplitz.hpp"
-  #include "armadillo_bits/fn_trimat.hpp"
-  #include "armadillo_bits/fn_cumsum.hpp"
-  #include "armadillo_bits/fn_symmat.hpp"
-  #include "armadillo_bits/fn_syl_lyap.hpp"
-  
-  //
-  // class meat
-  
-  #include "armadillo_bits/gemv.hpp"
-  #include "armadillo_bits/gemm.hpp"
-  #include "armadillo_bits/gemm_mixed.hpp"
-  
-  #include "armadillo_bits/eop_core_meat.hpp"
-  #include "armadillo_bits/eglue_core_meat.hpp"
-  
-  #include "armadillo_bits/arrayops_meat.hpp"
-  #include "armadillo_bits/podarray_meat.hpp"
-  #include "armadillo_bits/auxlib_meat.hpp"
-  
-  #include "armadillo_bits/injector_meat.hpp"
-  
-  #include "armadillo_bits/Mat_meat.hpp"
-  #include "armadillo_bits/Col_meat.hpp"
-  #include "armadillo_bits/Row_meat.hpp"
-  #include "armadillo_bits/Cube_meat.hpp"
-  #include "armadillo_bits/field_meat.hpp"
-  #include "armadillo_bits/subview_meat.hpp"
-  #include "armadillo_bits/subview_elem1_meat.hpp"
-  #include "armadillo_bits/subview_field_meat.hpp"
-  #include "armadillo_bits/subview_cube_meat.hpp"
-  #include "armadillo_bits/diagview_meat.hpp"
-  
-  #include "armadillo_bits/diskio_meat.hpp"
-  #include "armadillo_bits/wall_clock_meat.hpp"
-  #include "armadillo_bits/running_stat_meat.hpp"
-  #include "armadillo_bits/running_stat_vec_meat.hpp"
-  
-  #include "armadillo_bits/op_diagmat_meat.hpp"
-  #include "armadillo_bits/op_diagvec_meat.hpp"
-  #include "armadillo_bits/op_dot_meat.hpp"
-  #include "armadillo_bits/op_inv_meat.hpp"
-  #include "armadillo_bits/op_htrans_meat.hpp"
-  #include "armadillo_bits/op_max_meat.hpp"
-  #include "armadillo_bits/op_min_meat.hpp"
-  #include "armadillo_bits/op_mean_meat.hpp"
-  #include "armadillo_bits/op_median_meat.hpp"
-  #include "armadillo_bits/op_sort_meat.hpp"
-  #include "armadillo_bits/op_sum_meat.hpp"
-  #include "armadillo_bits/op_stddev_meat.hpp"
-  #include "armadillo_bits/op_strans_meat.hpp"
-  #include "armadillo_bits/op_var_meat.hpp"
-  #include "armadillo_bits/op_repmat_meat.hpp"
-  #include "armadillo_bits/op_reshape_meat.hpp"
-  #include "armadillo_bits/op_resize_meat.hpp"
-  #include "armadillo_bits/op_cov_meat.hpp"
-  #include "armadillo_bits/op_cor_meat.hpp"
-  #include "armadillo_bits/op_shuffle_meat.hpp"
-  #include "armadillo_bits/op_prod_meat.hpp"
-  #include "armadillo_bits/op_pinv_meat.hpp"
-  #include "armadillo_bits/op_dotext_meat.hpp"
-  #include "armadillo_bits/op_flip_meat.hpp"
-  #include "armadillo_bits/op_princomp_meat.hpp"
-  #include "armadillo_bits/op_misc_meat.hpp"
-  #include "armadillo_bits/op_relational_meat.hpp"
-  #include "armadillo_bits/op_find_meat.hpp"
-  #include "armadillo_bits/op_chol_meat.hpp"
-  #include "armadillo_bits/op_cx_scalar_meat.hpp"
-  #include "armadillo_bits/op_trimat_meat.hpp"
-  #include "armadillo_bits/op_cumsum_meat.hpp"
-  #include "armadillo_bits/op_symmat_meat.hpp"
-  
-  #include "armadillo_bits/glue_times_meat.hpp"
-  #include "armadillo_bits/glue_mixed_meat.hpp"
-  #include "armadillo_bits/glue_cov_meat.hpp"
-  #include "armadillo_bits/glue_cor_meat.hpp"
-  #include "armadillo_bits/glue_kron_meat.hpp"
-  #include "armadillo_bits/glue_cross_meat.hpp"
-  #include "armadillo_bits/glue_join_meat.hpp"
-  #include "armadillo_bits/glue_relational_meat.hpp"
-  #include "armadillo_bits/glue_solve_meat.hpp"
-  #include "armadillo_bits/glue_conv_meat.hpp"
-  #include "armadillo_bits/glue_toeplitz_meat.hpp"
-  }
-  
-#endif
-
--- a/armadillo-2.4.4/include/armadillo_bits/BaseCube_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup BaseCube
-//! @{
-
-
-
-//! Analog of the Base class, intended for cubes
-template<typename elem_type, typename derived>
-struct BaseCube
-  {
-  arma_inline const derived& get_ref() const;
-  
-  inline void print(const std::string extra_text = "") const;
-  inline void print(std::ostream& user_stream, const std::string extra_text = "") const;
-  
-  inline void raw_print(const std::string extra_text = "") const;
-  inline void raw_print(std::ostream& user_stream, const std::string extra_text = "") const;
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/BaseCube_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup BaseCube
-//! @{
-
-
-
-template<typename elem_type, typename derived>
-arma_inline
-const derived&
-BaseCube<elem_type,derived>::get_ref() const
-  {
-  return static_cast<const derived&>(*this);
-  }
-
-
-
-template<typename elem_type, typename derived>
-inline
-void
-BaseCube<elem_type,derived>::print(const std::string extra_text) const
-  {
-  const unwrap_cube<derived> tmp( (*this).get_ref() );
-  
-  tmp.M.impl_print(extra_text);
-  }
-
-
-
-template<typename elem_type, typename derived>
-inline
-void
-BaseCube<elem_type,derived>::print(std::ostream& user_stream, const std::string extra_text) const
-  {
-  const unwrap_cube<derived> tmp( (*this).get_ref() );
-  
-  tmp.M.impl_print(user_stream, extra_text);
-  }
-  
-
-
-template<typename elem_type, typename derived>
-inline
-void
-BaseCube<elem_type,derived>::raw_print(const std::string extra_text) const
-  {
-  const unwrap_cube<derived> tmp( (*this).get_ref() );
-  
-  tmp.M.impl_raw_print(extra_text);
-  }
-
-
-
-template<typename elem_type, typename derived>
-inline
-void
-BaseCube<elem_type,derived>::raw_print(std::ostream& user_stream, const std::string extra_text) const
-  {
-  const unwrap_cube<derived> tmp( (*this).get_ref() );
-  
-  tmp.M.impl_raw_print(user_stream, extra_text);
-  }
-  
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Base_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2012 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Base
-//! @{
-
-
-
-//! Class for static polymorphism, modelled after the "Curiously Recurring Template Pattern" (CRTP).
-//! Used for type-safe downcasting in functions that restrict their input(s) to be classes that are
-//! derived from Base (e.g. Mat, Op, Glue, diagview, subview).
-//! A Base object can be converted to a Mat object by the unwrap class.
-
-template<typename elem_type, typename derived>
-struct Base
-  {
-  arma_inline const derived& get_ref() const;
-  
-  arma_inline const Op<derived,op_htrans>  t() const;
-  arma_inline const Op<derived,op_htrans> ht() const;
-  arma_inline const Op<derived,op_strans> st() const;
-  
-  inline void print(const std::string extra_text = "") const;
-  inline void print(std::ostream& user_stream, const std::string extra_text = "") const;
-  
-  inline void raw_print(const std::string extra_text = "") const;
-  inline void raw_print(std::ostream& user_stream, const std::string extra_text = "") const;
-  
-  arma_deprecated inline void print_trans(const std::string extra_text = "") const;
-  arma_deprecated inline void print_trans(std::ostream& user_stream, const std::string extra_text = "") const;
-  
-  arma_deprecated inline void raw_print_trans(const std::string extra_text = "") const;
-  arma_deprecated inline void raw_print_trans(std::ostream& user_stream, const std::string extra_text = "") const;
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Base_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2012 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Base
-//! @{
-
-
-
-template<typename elem_type, typename derived>
-arma_inline
-const derived&
-Base<elem_type,derived>::get_ref() const
-  {
-  return static_cast<const derived&>(*this);
-  }
-
-
-
-template<typename elem_type, typename derived>
-arma_inline
-const Op<derived,op_htrans>
-Base<elem_type,derived>::t() const
-  {
-  return Op<derived,op_htrans>( (*this).get_ref() );
-  }
-
-
-
-template<typename elem_type, typename derived>
-arma_inline
-const Op<derived,op_htrans>
-Base<elem_type,derived>::ht() const
-  {
-  return Op<derived,op_htrans>( (*this).get_ref() );
-  }
-
-
-
-template<typename elem_type, typename derived>
-arma_inline
-const Op<derived,op_strans>
-Base<elem_type,derived>::st() const
-  {
-  return Op<derived,op_strans>( (*this).get_ref() );
-  }
-
-
-
-template<typename elem_type, typename derived>
-inline
-void
-Base<elem_type,derived>::print(const std::string extra_text) const
-  {
-  const unwrap<derived> tmp( (*this).get_ref() );
-  
-  tmp.M.impl_print(extra_text);
-  }
-
-
-
-template<typename elem_type, typename derived>
-inline
-void
-Base<elem_type,derived>::print(std::ostream& user_stream, const std::string extra_text) const
-  {
-  const unwrap<derived> tmp( (*this).get_ref() );
-  
-  tmp.M.impl_print(user_stream, extra_text);
-  }
-  
-
-
-template<typename elem_type, typename derived>
-inline
-void
-Base<elem_type,derived>::print_trans(const std::string extra_text) const
-  {
-  const unwrap<derived> tmp( (*this).get_ref() );
-  
-  tmp.M.impl_print_trans(extra_text);
-  }
-
-
-
-template<typename elem_type, typename derived>
-inline
-void
-Base<elem_type,derived>::print_trans(std::ostream& user_stream, const std::string extra_text) const
-  {
-  const unwrap<derived> tmp( (*this).get_ref() );
-  
-  tmp.M.impl_print_trans(user_stream, extra_text);
-  }
-  
-
-
-template<typename elem_type, typename derived>
-inline
-void
-Base<elem_type,derived>::raw_print(const std::string extra_text) const
-  {
-  const unwrap<derived> tmp( (*this).get_ref() );
-  
-  tmp.M.impl_raw_print(extra_text);
-  }
-
-
-
-template<typename elem_type, typename derived>
-inline
-void
-Base<elem_type,derived>::raw_print(std::ostream& user_stream, const std::string extra_text) const
-  {
-  const unwrap<derived> tmp( (*this).get_ref() );
-  
-  tmp.M.impl_raw_print(user_stream, extra_text);
-  }
-  
-
-
-template<typename elem_type, typename derived>
-inline
-void
-Base<elem_type,derived>::raw_print_trans(const std::string extra_text) const
-  {
-  const unwrap<derived> tmp( (*this).get_ref() );
-  
-  tmp.M.impl_raw_print_trans(extra_text);
-  }
-
-
-
-template<typename elem_type, typename derived>
-inline
-void
-Base<elem_type,derived>::raw_print_trans(std::ostream& user_stream, const std::string extra_text) const
-  {
-  const unwrap<derived> tmp( (*this).get_ref() );
-  
-  tmp.M.impl_raw_print_trans(user_stream, extra_text);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Col_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Col
-//! @{
-
-//! Class for column vectors (matrices with only one column)
-
-template<typename eT>
-class Col : public Mat<eT>
-  {
-  public:
-  
-  typedef eT                                elem_type;
-  typedef typename get_pod_type<eT>::result pod_type;
-  
-  
-  inline          Col();
-  inline          Col(const Col<eT>& X);
-  inline explicit Col(const uword n_elem);
-  inline          Col(const uword in_rows, const uword in_cols);
-  
-  inline                  Col(const char*        text);
-  inline const Col& operator=(const char*        text);
-  
-  inline                  Col(const std::string& text);
-  inline const Col& operator=(const std::string& text);
-  
-  #if defined(ARMA_USE_CXX11)
-  inline                  Col(const std::initializer_list<eT>& list);
-  inline const Col& operator=(const std::initializer_list<eT>& list);
-  #endif
-  
-  
-  inline const Col& operator=(const eT val);
-    
-  template<typename T1> inline                   Col(const Base<eT,T1>& X);
-  template<typename T1> inline const Col&  operator=(const Base<eT,T1>& X);
-  
-  inline Col(      eT* aux_mem, const uword aux_length, const bool copy_aux_mem = true, const bool strict = true);
-  inline Col(const eT* aux_mem, const uword aux_length);
-  
-  template<typename T1, typename T2>
-  inline explicit Col(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
-  
-  template<typename T1> inline                  Col(const BaseCube<eT,T1>& X);
-  template<typename T1> inline const Col& operator=(const BaseCube<eT,T1>& X);
-  
-  inline                  Col(const subview_cube<eT>& X);
-  inline const Col& operator=(const subview_cube<eT>& X);
-  
-  inline mat_injector<Col> operator<<(const eT val);
-  
-  arma_inline eT& row(const uword row_num);
-  arma_inline eT  row(const uword row_num) const;
-  
-  arma_inline       subview_col<eT> rows(const uword in_row1, const uword in_row2);
-  arma_inline const subview_col<eT> rows(const uword in_row1, const uword in_row2) const;
-  
-  arma_inline       subview_col<eT> subvec(const uword in_row1, const uword in_row2);
-  arma_inline const subview_col<eT> subvec(const uword in_row1, const uword in_row2) const;
-  
-  arma_inline       subview_col<eT> subvec(const span& row_span);
-  arma_inline const subview_col<eT> subvec(const span& row_span) const;
-  
-  //arma_inline       subview_col<eT> operator()(const span& row_span);
-  //arma_inline const subview_col<eT> operator()(const span& row_span) const;
-  
-  
-  inline void shed_row (const uword row_num);
-  inline void shed_rows(const uword in_row1, const uword in_row2);
-  
-                        inline void insert_rows(const uword row_num, const uword N, const bool set_to_zero = true);
-  template<typename T1> inline void insert_rows(const uword row_num, const Base<eT,T1>& X);
-  
-  
-  typedef       eT*       row_iterator;
-  typedef const eT* const_row_iterator;
-  
-  inline       row_iterator begin_row(const uword row_num);
-  inline const_row_iterator begin_row(const uword row_num) const;
-  
-  inline       row_iterator end_row  (const uword row_num);
-  inline const_row_iterator end_row  (const uword row_num) const;
-  
-  
-  template<uword fixed_n_elem>
-  class fixed : public Col<eT>
-    {
-    private:
-    
-    static const bool use_extra = (fixed_n_elem > arma_config::mat_prealloc);
-    
-    arma_aligned eT mem_local_extra[ (use_extra) ? fixed_n_elem : 1 ];
-    
-    arma_inline void mem_setup();
-    arma_inline void change_to_row();
-    
-    
-    public:
-    
-    static const uword n_rows = fixed_n_elem;
-    static const uword n_cols = 1;
-    static const uword n_elem = fixed_n_elem;
-    
-    arma_inline fixed();
-    arma_inline fixed(const fixed<fixed_n_elem>& X);
-         inline fixed(const subview_cube<eT>& X);
-    
-    template<typename T1>              inline fixed(const Base<eT,T1>& A);
-    template<typename T1, typename T2> inline fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
-    
-    inline fixed(      eT* aux_mem, const bool copy_aux_mem = true);
-    inline fixed(const eT* aux_mem);
-    
-    inline fixed(const char*        text);
-    inline fixed(const std::string& text);
-    
-    template<typename T1> inline const Col& operator=(const Base<eT,T1>& A);
-    
-    inline const Col& operator=(const eT val);
-    inline const Col& operator=(const char*        text);
-    inline const Col& operator=(const std::string& text);
-    inline const Col& operator=(const subview_cube<eT>& X);
-    
-    inline       subview_row<eT> operator()(const uword   row_num,  const span& col_span);
-    inline const subview_row<eT> operator()(const uword   row_num,  const span& col_span) const;
-    
-    inline       subview_col<eT> operator()(const span& row_span, const uword   col_num );
-    inline const subview_col<eT> operator()(const span& row_span, const uword   col_num ) const;
-    
-    inline       subview<eT>     operator()(const span& row_span, const span& col_span);
-    inline const subview<eT>     operator()(const span& row_span, const span& col_span) const;
-    
-    arma_inline arma_warn_unused eT& operator[] (const uword i);
-    arma_inline arma_warn_unused eT  operator[] (const uword i) const;
-    arma_inline arma_warn_unused eT& at         (const uword i);
-    arma_inline arma_warn_unused eT  at         (const uword i) const;
-    arma_inline arma_warn_unused eT& operator() (const uword i);
-    arma_inline arma_warn_unused eT  operator() (const uword i) const;
-    
-    arma_inline arma_warn_unused eT& at         (const uword in_row, const uword in_col);
-    arma_inline arma_warn_unused eT  at         (const uword in_row, const uword in_col) const;
-    arma_inline arma_warn_unused eT& operator() (const uword in_row, const uword in_col);
-    arma_inline arma_warn_unused eT  operator() (const uword in_row, const uword in_col) const;
-    
-    arma_hot inline const Col<eT>& fill(const eT val);
-    arma_hot inline const Col<eT>& zeros();
-    arma_hot inline const Col<eT>& ones();
-    };
-  
-  
-  #ifdef ARMA_EXTRA_COL_PROTO
-    #include ARMA_INCFILE_WRAP(ARMA_EXTRA_COL_PROTO)
-  #endif
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Col_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1187 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Col
-//! @{
-
-
-//! construct an empty column vector
-template<typename eT>
-inline
-Col<eT>::Col()
-  : Mat<eT>(0, 1)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  }
-
-
-
-template<typename eT>
-inline
-Col<eT>::Col(const Col<eT>& X)
-  : Mat<eT>(X.n_elem, 1)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  
-  arrayops::copy((*this).memptr(), X.memptr(), X.n_elem);
-  }
-
-
-
-//! construct a column vector with the specified number of n_elem
-template<typename eT>
-inline
-Col<eT>::Col(const uword in_n_elem)
-  : Mat<eT>(in_n_elem, 1)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  }
-
-
-
-template<typename eT>
-inline
-Col<eT>::Col(const uword in_n_rows, const uword in_n_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  
-  Mat<eT>::init_warm(in_n_rows, in_n_cols);
-  }
-
-
-
-//! construct a column vector from specified text
-template<typename eT>
-inline
-Col<eT>::Col(const char* text)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::operator=(text);
-  
-  std::swap( access::rw(Mat<eT>::n_rows), access::rw(Mat<eT>::n_cols) );
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  }
-
-
-
-//! construct a column vector from specified text
-template<typename eT>
-inline
-const Col<eT>&
-Col<eT>::operator=(const char* text)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::operator=(text);
-  
-  std::swap( access::rw(Mat<eT>::n_rows), access::rw(Mat<eT>::n_cols) );
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  
-  return *this;
-  }
-
-
-
-//! construct a column vector from specified text
-template<typename eT>
-inline
-Col<eT>::Col(const std::string& text)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::operator=(text);
-  
-  std::swap( access::rw(Mat<eT>::n_rows), access::rw(Mat<eT>::n_cols) );
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  }
-
-
-
-//! construct a column vector from specified text
-template<typename eT>
-inline
-const Col<eT>&
-Col<eT>::operator=(const std::string& text)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::operator=(text);
-  
-  std::swap( access::rw(Mat<eT>::n_rows), access::rw(Mat<eT>::n_cols) );
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  
-  return *this;
-  }
-
-
-
-#if defined(ARMA_USE_CXX11)
-
-template<typename eT>
-inline
-Col<eT>::Col(const std::initializer_list<eT>& list)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::operator=(list);
-  
-  std::swap( access::rw(Mat<eT>::n_rows), access::rw(Mat<eT>::n_cols) );
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  }
-
-
-
-template<typename eT>
-inline
-const Col<eT>&
-Col<eT>::operator=(const std::initializer_list<eT>& list)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::operator=(list);
-  
-  std::swap( access::rw(Mat<eT>::n_rows), access::rw(Mat<eT>::n_cols) );
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  
-  return *this;
-  }
-
-#endif
-
-
-
-template<typename eT>
-inline
-const Col<eT>&
-Col<eT>::operator=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(val);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-Col<eT>::Col(const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  
-  Mat<eT>::operator=(X.get_ref());
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Col<eT>&
-Col<eT>::operator=(const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(X.get_ref());
-  
-  return *this;
-  }
-
-
-
-//! construct a column vector from a given auxiliary array of eTs
-template<typename eT>
-inline
-Col<eT>::Col(eT* aux_mem, const uword aux_length, const bool copy_aux_mem, const bool strict)
-  : Mat<eT>(aux_mem, aux_length, 1, copy_aux_mem, strict)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  }
-
-
-
-//! construct a column vector from a given auxiliary array of eTs
-template<typename eT>
-inline
-Col<eT>::Col(const eT* aux_mem, const uword aux_length)
-  : Mat<eT>(aux_mem, aux_length, 1)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  }
-
-
-
-template<typename eT>
-template<typename T1, typename T2>
-inline
-Col<eT>::Col
-  (
-  const Base<typename Col<eT>::pod_type, T1>& A,
-  const Base<typename Col<eT>::pod_type, T2>& B
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  
-  Mat<eT>::init(A,B);
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-Col<eT>::Col(const BaseCube<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  
-  Mat<eT>::operator=(X);
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Col<eT>&
-Col<eT>::operator=(const BaseCube<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-Col<eT>::Col(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 1;
-  
-  Mat<eT>::operator=(X);
-  }
-
-
-
-template<typename eT>
-inline
-const Col<eT>&
-Col<eT>::operator=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-mat_injector< Col<eT> >
-Col<eT>::operator<<(const eT val)
-  {
-  return mat_injector< Col<eT> >(*this, val);
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT&
-Col<eT>::row(const uword row_num)
-  {
-  arma_debug_check( (row_num >= Mat<eT>::n_rows), "Col::row(): out of bounds" );
-  
-  return access::rw(Mat<eT>::mem[row_num]);
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT
-Col<eT>::row(const uword row_num) const
-  {
-  arma_debug_check( (row_num >= Mat<eT>::n_rows), "Col::row(): out of bounds" );
-  
-  return Mat<eT>::mem[row_num];
-  }
-
-
-
-template<typename eT>
-arma_inline
-subview_col<eT>
-Col<eT>::rows(const uword in_row1, const uword in_row2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= Mat<eT>::n_rows) ), "Col::rows(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  
-  return subview_col<eT>(*this, 0, in_row1, subview_n_rows);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const subview_col<eT>
-Col<eT>::rows(const uword in_row1, const uword in_row2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= Mat<eT>::n_rows) ), "Col::rows(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  
-  return subview_col<eT>(*this, 0, in_row1, subview_n_rows);
-  }
-
-
-
-template<typename eT>
-arma_inline
-subview_col<eT>
-Col<eT>::subvec(const uword in_row1, const uword in_row2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= Mat<eT>::n_rows) ), "Col::subvec(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  
-  return subview_col<eT>(*this, 0, in_row1, subview_n_rows);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const subview_col<eT>
-Col<eT>::subvec(const uword in_row1, const uword in_row2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= Mat<eT>::n_rows) ), "Col::subvec(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  
-  return subview_col<eT>(*this, 0, in_row1, subview_n_rows);
-  }
-
-
-
-template<typename eT>
-arma_inline
-subview_col<eT>
-Col<eT>::subvec(const span& row_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all = row_span.whole;
-
-  const uword local_n_rows = Mat<eT>::n_rows;
-  
-  const uword in_row1       = row_all ? 0            : row_span.a;
-  const uword in_row2       =                          row_span.b;
-  const uword subvec_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
-
-  arma_debug_check( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ), "Col::subvec(): indices out of bounds or incorrectly used");
-  
-  return subview_col<eT>(*this, 0, in_row1, subvec_n_rows);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const subview_col<eT>
-Col<eT>::subvec(const span& row_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all = row_span.whole;
-
-  const uword local_n_rows = Mat<eT>::n_rows;
-  
-  const uword in_row1       = row_all ? 0            : row_span.a;
-  const uword in_row2       =                          row_span.b;
-  const uword subvec_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
-
-  arma_debug_check( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ), "Col::subvec(): indices out of bounds or incorrectly used");
-  
-  return subview_col<eT>(*this, 0, in_row1, subvec_n_rows);
-  }
-
-
-
-// template<typename eT>
-// arma_inline
-// subview_col<eT>
-// Col<eT>::operator()(const span& row_span)
-//   {
-//   arma_extra_debug_sigprint();
-//   
-//   return subvec(row_span);
-//   }
-// 
-// 
-// 
-// template<typename eT>
-// arma_inline
-// const subview_col<eT>
-// Col<eT>::operator()(const span& row_span) const
-//   {
-//   arma_extra_debug_sigprint();
-//   
-//   return subvec(row_span);
-//   }
-
-
-
-//! remove specified row
-template<typename eT>
-inline
-void
-Col<eT>::shed_row(const uword row_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( row_num >= Mat<eT>::n_rows, "Col::shed_row(): out of bounds");
-  
-  shed_rows(row_num, row_num);
-  }
-
-
-
-//! remove specified rows
-template<typename eT>
-inline
-void
-Col<eT>::shed_rows(const uword in_row1, const uword in_row2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 > in_row2) || (in_row2 >= Mat<eT>::n_rows),
-    "Col::shed_rows(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword n_keep_front = in_row1;
-  const uword n_keep_back  = Mat<eT>::n_rows - (in_row2 + 1);
-  
-  Col<eT> X(n_keep_front + n_keep_back);
-  
-        eT* X_mem = X.memptr();
-  const eT* t_mem = (*this).memptr();
-  
-  if(n_keep_front > 0)
-    {
-    arrayops::copy( X_mem, t_mem, n_keep_front );
-    }
-  
-  if(n_keep_back > 0)
-    {
-    arrayops::copy( &(X_mem[n_keep_front]), &(t_mem[in_row2+1]), n_keep_back);
-    }
-  
-  Mat<eT>::steal_mem(X);
-  }
-
-
-
-//! insert N rows at the specified row position,
-//! optionally setting the elements of the inserted rows to zero
-template<typename eT>
-inline
-void
-Col<eT>::insert_rows(const uword row_num, const uword N, const bool set_to_zero)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword t_n_rows = Mat<eT>::n_rows;
-  
-  const uword A_n_rows = row_num;
-  const uword B_n_rows = t_n_rows - row_num;
-  
-  // insertion at row_num == n_rows is in effect an append operation
-  arma_debug_check( (row_num > t_n_rows), "Col::insert_rows(): out of bounds");
-  
-  if(N > 0)
-    {
-    Col<eT> out(t_n_rows + N);
-    
-          eT* out_mem = out.memptr();
-    const eT*   t_mem = (*this).memptr();
-    
-    if(A_n_rows > 0)
-      {
-      arrayops::copy( out_mem, t_mem, A_n_rows );
-      }
-    
-    if(B_n_rows > 0)
-      {
-      arrayops::copy( &(out_mem[row_num + N]), &(t_mem[row_num]), B_n_rows );
-      }
-    
-    if(set_to_zero == true)
-      {
-      arrayops::inplace_set( &(out_mem[row_num]), eT(0), N );
-      }
-    
-    Mat<eT>::steal_mem(out);
-    }
-  }
-
-
-
-//! insert the given object at the specified row position; 
-//! the given object must have one column
-template<typename eT>
-template<typename T1>
-inline
-void
-Col<eT>::insert_rows(const uword row_num, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::insert_rows(row_num, X);
-  }
-
-
-
-template<typename eT>
-inline
-typename Col<eT>::row_iterator
-Col<eT>::begin_row(const uword row_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= Mat<eT>::n_rows), "begin_row(): index out of bounds");
-  
-  return Mat<eT>::memptr() + row_num;
-  }
-
-
-
-template<typename eT>
-inline
-typename Col<eT>::const_row_iterator
-Col<eT>::begin_row(const uword row_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= Mat<eT>::n_rows), "begin_row(): index out of bounds");
-  
-  return Mat<eT>::memptr() + row_num;
-  }
-
-
-
-template<typename eT>
-inline
-typename Col<eT>::row_iterator
-Col<eT>::end_row(const uword row_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= Mat<eT>::n_rows), "end_row(): index out of bounds");
-  
-  return Mat<eT>::memptr() + row_num + 1;
-  }
-
-
-
-template<typename eT>
-inline
-typename Col<eT>::const_row_iterator
-Col<eT>::end_row(const uword row_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= Mat<eT>::n_rows), "end_row(): index out of bounds");
-  
-  return Mat<eT>::memptr() + row_num + 1;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-void
-Col<eT>::fixed<fixed_n_elem>::mem_setup()
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::n_rows)    = fixed_n_elem;
-  access::rw(Mat<eT>::n_cols)    = 1;
-  access::rw(Mat<eT>::n_elem)    = fixed_n_elem;
-  access::rw(Mat<eT>::vec_state) = 1;
-  access::rw(Mat<eT>::mem_state) = 3;
-  access::rw(Mat<eT>::mem)       = (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-void
-Col<eT>::fixed<fixed_n_elem>::change_to_row()
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::n_cols) = fixed_n_elem;
-  access::rw(Mat<eT>::n_rows) = 1;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-Col<eT>::fixed<fixed_n_elem>::fixed()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-Col<eT>::fixed<fixed_n_elem>::fixed(const fixed<fixed_n_elem>& X)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  eT* dest = (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
-  
-  arrayops::copy( dest, X.mem, fixed_n_elem );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-Col<eT>::fixed<fixed_n_elem>::fixed(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  Col<eT>::operator=(X);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-template<typename T1>
-inline
-Col<eT>::fixed<fixed_n_elem>::fixed(const Base<eT,T1>& A)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  Col<eT>::operator=(A.get_ref());
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-template<typename T1, typename T2>
-inline
-Col<eT>::fixed<fixed_n_elem>::fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  Col<eT>::init(A,B);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-Col<eT>::fixed<fixed_n_elem>::fixed(eT* aux_mem, const bool copy_aux_mem)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  access::rw(Mat<eT>::n_rows)    = fixed_n_elem;
-  access::rw(Mat<eT>::n_cols)    = 1;
-  access::rw(Mat<eT>::n_elem)    = fixed_n_elem;
-  access::rw(Mat<eT>::vec_state) = 1;
-  access::rw(Mat<eT>::mem_state) = 3;
-  
-  if(copy_aux_mem == true)
-    {
-    eT* dest = (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
-    
-    access::rw(Mat<eT>::mem) = dest;
-    
-    arrayops::copy( dest, aux_mem, fixed_n_elem );
-    }
-  else
-    {
-    access::rw(Mat<eT>::mem) = aux_mem;
-    }
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-Col<eT>::fixed<fixed_n_elem>::fixed(const eT* aux_mem)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  arrayops::copy( const_cast<eT*>(Mat<eT>::mem), aux_mem, fixed_n_elem );
-  }
-
-
-
-//! NOTE: this function relies on
-//! Col::operator=(text), to change vec_state as well as swapping n_rows and n_cols,
-//! and Mat::init(), to check that the given vector will not have a different size than fixed_n_elem.
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-Col<eT>::fixed<fixed_n_elem>::fixed(const char* text)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  change_to_row();
-  
-  Col<eT>::operator=(text);
-  }
-
-
-
-//! NOTE: this function relies on
-//! Col::operator=(text), to change vec_state as well as swapping n_rows and n_cols,
-//! and Mat::init(), to check that the given vector will not have a different size than fixed_n_elem.
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-Col<eT>::fixed<fixed_n_elem>::fixed(const std::string& text)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  change_to_row();
-  
-  Col<eT>::operator=(text);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-template<typename T1>
-const Col<eT>&
-Col<eT>::fixed<fixed_n_elem>::operator=(const Base<eT,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  Col<eT>::operator=(A.get_ref());
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-const Col<eT>&
-Col<eT>::fixed<fixed_n_elem>::operator=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  Col<eT>::operator=(val);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-const Col<eT>&
-Col<eT>::fixed<fixed_n_elem>::operator=(const char* text)
-  {
-  arma_extra_debug_sigprint();
-  
-  change_to_row();
-  
-  Col<eT>::operator=(text);
-  
-  return *this; 
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-const Col<eT>&
-Col<eT>::fixed<fixed_n_elem>::operator=(const std::string& text)
-  {
-  arma_extra_debug_sigprint();
-  
-  change_to_row();
-  
-  Col<eT>::operator=(text);
-  
-  return *this; 
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-const Col<eT>&
-Col<eT>::fixed<fixed_n_elem>::operator=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Col<eT>::operator=(X);
-  
-  return *this; 
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-subview_row<eT>
-Col<eT>::fixed<fixed_n_elem>::operator()(const uword row_num, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_num, col_span);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-const subview_row<eT>
-Col<eT>::fixed<fixed_n_elem>::operator()(const uword row_num, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_num, col_span);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-subview_col<eT>
-Col<eT>::fixed<fixed_n_elem>::operator()(const span& row_span, const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_span, col_num);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-const subview_col<eT>
-Col<eT>::fixed<fixed_n_elem>::operator()(const span& row_span, const uword col_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_span, col_num);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-subview<eT>
-Col<eT>::fixed<fixed_n_elem>::operator()(const span& row_span, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_span, col_span);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-const subview<eT>
-Col<eT>::fixed<fixed_n_elem>::operator()(const span& row_span, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_span, col_span);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT&
-Col<eT>::fixed<fixed_n_elem>::operator[] (const uword i)
-  {
-  return access::rw( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT
-Col<eT>::fixed<fixed_n_elem>::operator[] (const uword i) const
-  {
-  return ( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT&
-Col<eT>::fixed<fixed_n_elem>::at(const uword i)
-  {
-  return access::rw( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT
-Col<eT>::fixed<fixed_n_elem>::at(const uword i) const
-  {
-  return ( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT&
-Col<eT>::fixed<fixed_n_elem>::operator() (const uword i)
-  {
-  arma_debug_check( (i >= fixed_n_elem), "Col::fixed::operator(): out of bounds");
-  
-  return access::rw( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT
-Col<eT>::fixed<fixed_n_elem>::operator() (const uword i) const
-  {
-  arma_debug_check( (i >= fixed_n_elem), "Col::fixed::operator(): out of bounds");
-  
-  return ( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT&
-Col<eT>::fixed<fixed_n_elem>::at(const uword in_row, const uword in_col)
-  {
-  return access::rw( Mat<eT>::mem[in_row] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT
-Col<eT>::fixed<fixed_n_elem>::at(const uword in_row, const uword in_col) const
-  {
-  return ( Mat<eT>::mem[in_row] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT&
-Col<eT>::fixed<fixed_n_elem>::operator() (const uword in_row, const uword in_col)
-  {
-  arma_debug_check( ((in_row >= fixed_n_elem) || (in_col >= 1)), "Col::fixed::operator(): out of bounds" );
-  
-  return access::rw( Mat<eT>::mem[in_row] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT
-Col<eT>::fixed<fixed_n_elem>::operator() (const uword in_row, const uword in_col) const
-  {
-  arma_debug_check( ((in_row >= fixed_n_elem) || (in_col >= 1)), "Col::fixed::operator(): out of bounds" );
-  
-  return ( Mat<eT>::mem[in_row] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_hot
-inline
-const Col<eT>&
-Col<eT>::fixed<fixed_n_elem>::fill(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_set( const_cast<eT*>(Mat<eT>::mem), val, fixed_n_elem );
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_hot
-inline
-const Col<eT>&
-Col<eT>::fixed<fixed_n_elem>::zeros()
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_set( const_cast<eT*>(Mat<eT>::mem), eT(0), fixed_n_elem );
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_hot
-inline
-const Col<eT>&
-Col<eT>::fixed<fixed_n_elem>::ones()
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_set( const_cast<eT*>(Mat<eT>::mem), eT(1), fixed_n_elem );
-  
-  return *this;
-  }
-
-
-
-#ifdef ARMA_EXTRA_COL_MEAT
-  #include ARMA_INCFILE_WRAP(ARMA_EXTRA_COL_MEAT)
-#endif
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Cube_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,365 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Cube
-//! @{
-
-
-
-struct Cube_prealloc
-  {
-  static const uword mat_ptrs_size = 4;
-  static const uword mem_n_elem    = 64;
-  };
-
-
-
-//! Dense cube class
-
-template<typename eT>
-class Cube : public BaseCube< eT, Cube<eT> >
-  {
-  public:
-  
-  typedef eT                                elem_type; //!< the type of elements stored in the cube
-  typedef typename get_pod_type<eT>::result pod_type;  //!< if eT is non-complex, pod_type is same as eT. otherwise, pod_type is the underlying type used by std::complex
-  
-  const uword  n_rows;       //!< number of rows in each slice (read-only)
-  const uword  n_cols;       //!< number of columns in each slice (read-only)
-  const uword  n_elem_slice; //!< number of elements in each slice (read-only)
-  const uword  n_slices;     //!< number of slices in the cube (read-only)
-  const uword  n_elem;       //!< number of elements in the cube (read-only)
-  const uword  mem_state;
-  
-  // mem_state = 0: normal cube that can be resized; 
-  // mem_state = 1: use auxiliary memory until change in the number of elements is requested;  
-  // mem_state = 2: use auxiliary memory and don't allow the number of elements to be changed; 
-  // mem_state = 3: fixed size (e.g. via template based size specification).
-  
-  
-  arma_aligned const Mat<eT>** const mat_ptrs; //!< pointer to an array containing pointers to Mat instances (one for each slice)
-  arma_aligned const eT*       const mem;      //!< pointer to the memory used by the cube (memory is read-only)
-  
-  protected:
-  arma_aligned Mat<eT>* mat_ptrs_local[ Cube_prealloc::mat_ptrs_size ];
-  arma_aligned eT            mem_local[ Cube_prealloc::mem_n_elem    ];
-  
-  
-  public:
-  
-  inline ~Cube();
-  inline  Cube();
-  
-  inline Cube(const uword in_rows, const uword in_cols, const uword in_slices);
-  
-  inline Cube(      eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices, const bool copy_aux_mem = true, const bool strict = true);
-  inline Cube(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices);
-  
-  arma_inline const Cube&  operator=(const eT val);
-  arma_inline const Cube& operator+=(const eT val);
-  arma_inline const Cube& operator-=(const eT val);
-  arma_inline const Cube& operator*=(const eT val);
-  arma_inline const Cube& operator/=(const eT val);
-  
-  inline                   Cube(const Cube& m);
-  inline const Cube&  operator=(const Cube& m);
-  inline const Cube& operator+=(const Cube& m);
-  inline const Cube& operator-=(const Cube& m);
-  inline const Cube& operator%=(const Cube& m);
-  inline const Cube& operator/=(const Cube& m);
-  
-  template<typename T1, typename T2>
-  inline explicit Cube(const BaseCube<pod_type,T1>& A, const BaseCube<pod_type,T2>& B);
-  
-  inline                   Cube(const subview_cube<eT>& X);
-  inline const Cube&  operator=(const subview_cube<eT>& X);
-  inline const Cube& operator+=(const subview_cube<eT>& X);
-  inline const Cube& operator-=(const subview_cube<eT>& X);
-  inline const Cube& operator%=(const subview_cube<eT>& X);
-  inline const Cube& operator/=(const subview_cube<eT>& X);
-  
-  arma_inline       Mat<eT>& slice(const uword in_slice);
-  arma_inline const Mat<eT>& slice(const uword in_slice) const;
-  
-  arma_inline       subview_cube<eT> slices(const uword in_slice1, const uword in_slice2);
-  arma_inline const subview_cube<eT> slices(const uword in_slice1, const uword in_slice2) const;
-  
-  arma_inline       subview_cube<eT> subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2);
-  arma_inline const subview_cube<eT> subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2) const;
-  
-  inline            subview_cube<eT> subcube(const span& row_span, const span& col_span, const span& slice_span);
-  inline      const subview_cube<eT> subcube(const span& row_span, const span& col_span, const span& slice_span) const;
-  
-  inline            subview_cube<eT> operator()(const span& row_span, const span& col_span, const span& slice_span);
-  inline      const subview_cube<eT> operator()(const span& row_span, const span& col_span, const span& slice_span) const;
-  
-  
-  inline void shed_slice(const uword slice_num);
-  
-  inline void shed_slices(const uword in_slice1, const uword in_slice2);
-  
-  inline void insert_slices(const uword slice_num, const uword N, const bool set_to_zero = true);
-  
-  template<typename T1>
-  inline void insert_slices(const uword row_num, const BaseCube<eT,T1>& X);
-  
-  
-  template<typename gen_type> inline                   Cube(const GenCube<eT, gen_type>& X);
-  template<typename gen_type> inline const Cube&  operator=(const GenCube<eT, gen_type>& X);
-  template<typename gen_type> inline const Cube& operator+=(const GenCube<eT, gen_type>& X);
-  template<typename gen_type> inline const Cube& operator-=(const GenCube<eT, gen_type>& X);
-  template<typename gen_type> inline const Cube& operator%=(const GenCube<eT, gen_type>& X);
-  template<typename gen_type> inline const Cube& operator/=(const GenCube<eT, gen_type>& X);
-  
-  template<typename T1, typename op_type> inline                   Cube(const OpCube<T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Cube&  operator=(const OpCube<T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Cube& operator+=(const OpCube<T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Cube& operator-=(const OpCube<T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Cube& operator%=(const OpCube<T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Cube& operator/=(const OpCube<T1, op_type>& X);
-  
-  template<typename T1, typename eop_type> inline                   Cube(const eOpCube<T1, eop_type>& X);
-  template<typename T1, typename eop_type> inline const Cube&  operator=(const eOpCube<T1, eop_type>& X);
-  template<typename T1, typename eop_type> inline const Cube& operator+=(const eOpCube<T1, eop_type>& X);
-  template<typename T1, typename eop_type> inline const Cube& operator-=(const eOpCube<T1, eop_type>& X);
-  template<typename T1, typename eop_type> inline const Cube& operator%=(const eOpCube<T1, eop_type>& X);
-  template<typename T1, typename eop_type> inline const Cube& operator/=(const eOpCube<T1, eop_type>& X);
-  
-  template<typename T1, typename op_type> inline                   Cube(const mtOpCube<eT, T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Cube&  operator=(const mtOpCube<eT, T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Cube& operator+=(const mtOpCube<eT, T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Cube& operator-=(const mtOpCube<eT, T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Cube& operator%=(const mtOpCube<eT, T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Cube& operator/=(const mtOpCube<eT, T1, op_type>& X);
-  
-  template<typename T1, typename T2, typename glue_type> inline                   Cube(const GlueCube<T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Cube&  operator=(const GlueCube<T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Cube& operator+=(const GlueCube<T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Cube& operator-=(const GlueCube<T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Cube& operator%=(const GlueCube<T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Cube& operator/=(const GlueCube<T1, T2, glue_type>& X);
-  
-  template<typename T1, typename T2, typename eglue_type> inline                   Cube(const eGlueCube<T1, T2, eglue_type>& X);
-  template<typename T1, typename T2, typename eglue_type> inline const Cube&  operator=(const eGlueCube<T1, T2, eglue_type>& X);
-  template<typename T1, typename T2, typename eglue_type> inline const Cube& operator+=(const eGlueCube<T1, T2, eglue_type>& X);
-  template<typename T1, typename T2, typename eglue_type> inline const Cube& operator-=(const eGlueCube<T1, T2, eglue_type>& X);
-  template<typename T1, typename T2, typename eglue_type> inline const Cube& operator%=(const eGlueCube<T1, T2, eglue_type>& X);
-  template<typename T1, typename T2, typename eglue_type> inline const Cube& operator/=(const eGlueCube<T1, T2, eglue_type>& X);
-  
-  template<typename T1, typename T2, typename glue_type> inline                   Cube(const mtGlueCube<eT, T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Cube&  operator=(const mtGlueCube<eT, T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Cube& operator+=(const mtGlueCube<eT, T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Cube& operator-=(const mtGlueCube<eT, T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Cube& operator%=(const mtGlueCube<eT, T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Cube& operator/=(const mtGlueCube<eT, T1, T2, glue_type>& X);
-  
-  
-  arma_inline arma_warn_unused eT& operator[] (const uword i);
-  arma_inline arma_warn_unused eT  operator[] (const uword i) const;
-  
-  arma_inline arma_warn_unused eT& at(const uword i);
-  arma_inline arma_warn_unused eT  at(const uword i) const;
-  
-  arma_inline arma_warn_unused eT& operator() (const uword i);
-  arma_inline arma_warn_unused eT  operator() (const uword i) const;
-  
-  arma_inline arma_warn_unused eT& at         (const uword in_row, const uword in_col, const uword in_slice);
-  arma_inline arma_warn_unused eT  at         (const uword in_row, const uword in_col, const uword in_slice) const;
-  
-  arma_inline arma_warn_unused eT& operator() (const uword in_row, const uword in_col, const uword in_slice);
-  arma_inline arma_warn_unused eT  operator() (const uword in_row, const uword in_col, const uword in_slice) const;
-  
-  arma_inline const Cube& operator++();
-  arma_inline void        operator++(int);
-  
-  arma_inline const Cube& operator--();
-  arma_inline void        operator--(int);
-  
-  arma_inline arma_warn_unused bool is_finite() const;
-  arma_inline arma_warn_unused bool is_empty()  const;
-  
-  arma_inline arma_warn_unused bool in_range(const uword i) const;
-  arma_inline arma_warn_unused bool in_range(const span& x) const;
-  
-  arma_inline arma_warn_unused bool in_range(const uword   in_row, const uword   in_col, const uword   in_slice) const;
-       inline arma_warn_unused bool in_range(const span& row_span, const span& col_span, const span& slice_span) const;
-  
-  arma_inline arma_warn_unused       eT* memptr();
-  arma_inline arma_warn_unused const eT* memptr() const;
-  
-  arma_inline arma_warn_unused       eT* slice_memptr(const uword slice);
-  arma_inline arma_warn_unused const eT* slice_memptr(const uword slice) const;
-  
-  arma_inline arma_warn_unused       eT* slice_colptr(const uword in_slice, const uword in_col);
-  arma_inline arma_warn_unused const eT* slice_colptr(const uword in_slice, const uword in_col) const;
-  
-  inline void impl_print(const std::string& extra_text) const;
-  inline void impl_print(std::ostream& user_stream, const std::string& extra_text) const;
-  
-  inline void impl_raw_print(const std::string& extra_text) const;
-  inline void impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const;
-  
-  inline void  set_size(const uword in_rows, const uword in_cols, const uword in_slices);
-  inline void   reshape(const uword in_rows, const uword in_cols, const uword in_slices, const uword dim = 0);
-  inline void    resize(const uword in_rows, const uword in_cols, const uword in_slices);
-  
-  template<typename eT2> inline void copy_size(const Cube<eT2>& m);
-  
-  inline const Cube& fill(const eT val);
-  
-  inline const Cube& zeros();
-  inline const Cube& zeros(const uword in_rows, const uword in_cols, const uword in_slices);
-  
-  inline const Cube& ones();
-  inline const Cube& ones(const uword in_rows, const uword in_cols, const uword in_slices);
-  
-  inline const Cube& randu();
-  inline const Cube& randu(const uword in_rows, const uword in_cols, const uword in_slices);
-  
-  inline const Cube& randn();
-  inline const Cube& randn(const uword in_rows, const uword in_cols, const uword in_slices);
-  
-  inline void reset();
-  
-  
-  template<typename T1> inline void set_real(const BaseCube<pod_type,T1>& X);
-  template<typename T1> inline void set_imag(const BaseCube<pod_type,T1>& X);
-  
-  
-  inline arma_warn_unused eT min() const;
-  inline arma_warn_unused eT max() const;
-  
-  inline eT min(uword& index_of_min_val) const;
-  inline eT max(uword& index_of_max_val) const;
-  
-  inline eT min(uword& row_of_min_val, uword& col_of_min_val, uword& slice_of_min_val) const;
-  inline eT max(uword& row_of_max_val, uword& col_of_max_val, uword& slice_of_max_val) const;
-  
-  
-  inline bool save(const std::string   name, const file_type type = arma_binary, const bool print_status = true) const;
-  inline bool save(      std::ostream& os,   const file_type type = arma_binary, const bool print_status = true) const;
-  
-  inline bool load(const std::string   name, const file_type type = auto_detect, const bool print_status = true);
-  inline bool load(      std::istream& is,   const file_type type = auto_detect, const bool print_status = true);
-  
-  inline bool quiet_save(const std::string   name, const file_type type = arma_binary) const;
-  inline bool quiet_save(      std::ostream& os,   const file_type type = arma_binary) const;
-  
-  inline bool quiet_load(const std::string   name, const file_type type = auto_detect);
-  inline bool quiet_load(      std::istream& is,   const file_type type = auto_detect);
-  
-  
-  // iterators
-  
-  typedef       eT*       iterator;
-  typedef const eT* const_iterator;
-  
-  typedef       eT*       slice_iterator;
-  typedef const eT* const_slice_iterator;
-  
-  inline       iterator begin();
-  inline const_iterator begin() const;
-  
-  inline       iterator end();
-  inline const_iterator end()   const;
-  
-  inline       slice_iterator begin_slice(const uword slice_num);
-  inline const_slice_iterator begin_slice(const uword slice_num) const;
-  
-  inline       slice_iterator end_slice(const uword slice_num);
-  inline const_slice_iterator end_slice(const uword slice_num)   const;
-
-
-  template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
-  class fixed : public Cube<eT>
-    {
-    private:
-    
-    static const uword fixed_n_elem = fixed_n_rows * fixed_n_cols * fixed_n_slices;
-    
-    arma_aligned Mat<eT>* mat_ptrs_local_extra[ (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? fixed_n_slices : 1 ];
-    arma_aligned eT       mem_local_extra     [ (fixed_n_elem   > Cube_prealloc::mem_n_elem)    ? fixed_n_elem   : 1 ];
-    
-    arma_inline void mem_setup();
-    
-    
-    public:
-    
-    inline fixed() { mem_setup(); }
-    
-    inline const Cube& operator=(const eT val) { mem_setup(); Cube<eT>::operator=(val); return *this; }
-    
-    template<typename T1>
-    inline fixed(const BaseCube<eT,T1>& A) { mem_setup(); Cube<eT>::operator=(A.get_ref()); }
-    
-    template<typename T1>
-    inline const Cube& operator=(const BaseCube<eT,T1>& A) { Cube<eT>::operator=(A.get_ref()); return *this; }
-    
-    template<typename T1, typename T2>
-    inline explicit fixed(const BaseCube<pod_type,T1>& A, const BaseCube<pod_type,T2>& B) { mem_setup(); Cube<eT>::init(A,B); }
-    };
-  
-  
-  protected:
-  
-  inline void init_cold();
-  inline void init_warm(const uword in_rows, const uword in_cols, const uword in_slices);
-  
-  template<typename T1, typename T2>
-  inline void init(const BaseCube<pod_type,T1>& A, const BaseCube<pod_type,T2>& B);
-  
-  inline void steal_mem(Cube& X);
-  
-  inline void delete_mat();
-  inline void create_mat();
-  
-  friend class glue_join;
-  friend class op_reshape;
-  friend class op_resize;
-  
-  
-  public:
-  
-  #ifdef ARMA_EXTRA_CUBE_PROTO
-    #include ARMA_INCFILE_WRAP(ARMA_EXTRA_CUBE_PROTO)
-  #endif
-  };
-
-
-
-class Cube_aux
-  {
-  public:
-  
-  template<typename eT> arma_inline static void prefix_pp(Cube<eT>& x);
-  template<typename T>  arma_inline static void prefix_pp(Cube< std::complex<T> >& x);
-  
-  template<typename eT> arma_inline static void postfix_pp(Cube<eT>& x);
-  template<typename T>  arma_inline static void postfix_pp(Cube< std::complex<T> >& x);
-  
-  template<typename eT> arma_inline static void prefix_mm(Cube<eT>& x);
-  template<typename T>  arma_inline static void prefix_mm(Cube< std::complex<T> >& x);
-  
-  template<typename eT> arma_inline static void postfix_mm(Cube<eT>& x);
-  template<typename T>  arma_inline static void postfix_mm(Cube< std::complex<T> >& x);
-  
-  template<typename eT, typename T1> inline static void set_real(Cube<eT>&                out, const BaseCube<eT,T1>& X);
-  template<typename eT, typename T1> inline static void set_imag(Cube<eT>&                out, const BaseCube<eT,T1>& X);
-  
-  template<typename T,  typename T1> inline static void set_real(Cube< std::complex<T> >& out, const BaseCube< T,T1>& X);
-  template<typename T,  typename T1> inline static void set_imag(Cube< std::complex<T> >& out, const BaseCube< T,T1>& X);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Cube_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3405 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Cube
-//! @{
-
-
-template<typename eT>
-inline
-Cube<eT>::~Cube()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  delete_mat();
-  
-  if(mem_state == 0)
-    {
-    if(n_elem > Cube_prealloc::mem_n_elem)
-      {
-      #if defined(ARMA_USE_TBB_ALLOC)
-        scalable_free((void *)(mem));
-      #else
-        delete [] mem;
-      #endif
-      }
-    }
-  
-  if(arma_config::debug == true)
-    {
-    // try to expose buggy user code that accesses deleted objects
-    access::rw(n_rows)   = 0;
-    access::rw(n_cols)   = 0;
-    access::rw(n_slices) = 0;
-    access::rw(n_elem)   = 0;
-    access::rw(mat_ptrs) = 0;
-    access::rw(mem)      = 0;
-    }
-  
-  arma_type_check(( is_supported_elem_type<eT>::value == false ));
-  }
-
-
-
-template<typename eT>
-inline
-Cube<eT>::Cube()
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem_slice(0)
-  , n_slices(0)
-  , n_elem(0)
-  , mem_state(0)
-  , mat_ptrs()
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  }
-
-
-
-//! construct the cube to have user specified dimensions
-template<typename eT>
-inline
-Cube<eT>::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices)
-  : n_rows(in_n_rows)
-  , n_cols(in_n_cols)
-  , n_elem_slice(in_n_rows*in_n_cols)
-  , n_slices(in_n_slices)
-  , n_elem(in_n_rows*in_n_cols*in_n_slices)
-  , mem_state(0)
-  , mat_ptrs()
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init_cold();
-  }
-
-
-
-template<typename eT>
-inline
-void
-Cube<eT>::init_cold()
-  {
-  arma_extra_debug_sigprint( arma_boost::format("n_rows = %d, n_cols = %d, n_slices = %d") % n_rows % n_cols % n_slices );
-  
-  arma_debug_check
-    (
-      (
-      ( (n_rows > 0x0FFF) || (n_cols > 0x0FFF) || (n_slices > 0xFF) )
-        ? ( (float(n_rows) * float(n_cols) * float(n_slices)) > float(ARMA_MAX_UWORD) )
-        : false
-      ),
-    "Cube::init(): requested size is too large"
-    );
-  
-  if(n_elem <= Cube_prealloc::mem_n_elem)
-    {
-    access::rw(mem) = mem_local;
-    }
-  else
-    {
-    arma_extra_debug_print("Cube::init(): allocating memory");
-    
-    #if defined(ARMA_USE_TBB_ALLOC)
-      access::rw(mem) = (eT *)scalable_malloc(sizeof(eT)*n_elem);
-    #else
-      access::rw(mem) = new(std::nothrow) eT[n_elem];
-    #endif
-    
-    arma_check_bad_alloc( (mem == 0), "Cube::init(): out of memory" );
-    }
-  
-  
-  if(n_elem == 0)
-    {
-    access::rw(n_rows)       = 0;
-    access::rw(n_cols)       = 0;
-    access::rw(n_elem_slice) = 0;
-    access::rw(n_slices)     = 0;
-    }
-  else
-    {
-    create_mat();
-    }
-  }
-
-
-
-//! internal cube construction; if the requested size is small enough, memory from the stack is used.
-//! otherwise memory is allocated via 'new'
-template<typename eT>
-inline
-void
-Cube<eT>::init_warm(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices)
-  {
-  arma_extra_debug_sigprint( arma_boost::format("in_n_rows = %d, in_n_cols = %d, in_n_slices = %d") % in_n_rows % in_n_cols % in_n_slices );
-  
-  if( (n_rows == in_n_rows) && (n_cols == in_n_cols) && (n_slices == in_n_slices) )
-    {
-    return;
-    }
-  
-  const uword t_mem_state = mem_state;
-  
-  bool  err_state = false;
-  char* err_msg   = 0;
-  
-  arma_debug_set_error
-    (
-    err_state,
-    err_msg,
-    (t_mem_state == 3),
-    "Cube::init(): size is fixed and hence cannot be changed"
-    );
-  
-  arma_debug_set_error
-    (
-    err_state,
-    err_msg,
-      (
-      ( (in_n_rows > 0x0FFF) || (in_n_cols > 0x0FFF) || (in_n_slices > 0xFF) )
-        ? ( (float(in_n_rows) * float(in_n_cols) * float(in_n_slices)) > float(ARMA_MAX_UWORD) )
-        : false
-      ),
-    "Cube::init(): requested size is too large"
-    );
-  
-  arma_debug_check(err_state, err_msg);
-  
-  const uword old_n_elem = n_elem;
-  const uword new_n_elem = in_n_rows * in_n_cols * in_n_slices;
-  
-  if(old_n_elem == new_n_elem)
-    {
-    delete_mat();
-    
-    if(new_n_elem > 0)
-      {
-      access::rw(n_rows)       = in_n_rows;
-      access::rw(n_cols)       = in_n_cols;
-      access::rw(n_elem_slice) = in_n_rows*in_n_cols;
-      access::rw(n_slices)     = in_n_slices;
-      
-      create_mat();
-      }
-    }
-  else
-    {
-    arma_debug_check( (t_mem_state == 2), "Cube::init(): requested size is not compatible with the size of auxiliary memory" );
-    
-    delete_mat();
-    
-    if(t_mem_state == 0)
-      {
-      if(n_elem > Cube_prealloc::mem_n_elem )
-        {
-        arma_extra_debug_print("Cube::init(): freeing memory");
-        
-        #if defined(ARMA_USE_TBB_ALLOC)
-          scalable_free((void *)(mem));
-        #else
-          delete [] mem;
-        #endif
-        }
-      }
-    
-    access::rw(mem_state) = 0;
-    
-    if(new_n_elem <= Cube_prealloc::mem_n_elem)
-      {
-      access::rw(mem) = mem_local;
-      }
-    else
-      {
-      arma_extra_debug_print("Cube::init(): allocating memory");
-      
-      #if defined(ARMA_USE_TBB_ALLOC)
-        access::rw(mem) = (eT *)scalable_malloc(sizeof(eT)*new_n_elem);
-      #else
-        access::rw(mem) = new(std::nothrow) eT[new_n_elem];
-      #endif
-      
-      arma_check_bad_alloc( (mem == 0), "Cube::init(): out of memory" );
-      }
-    
-    if(new_n_elem > 0)
-      {
-      access::rw(n_rows)       = in_n_rows;
-      access::rw(n_cols)       = in_n_cols;
-      access::rw(n_elem_slice) = in_n_rows*in_n_cols;
-      access::rw(n_slices)     = in_n_slices;
-      access::rw(n_elem)       = new_n_elem;
-      
-      create_mat();
-      }
-    }
-  
-  
-  if(new_n_elem == 0)
-    {
-    access::rw(n_rows)       = 0;
-    access::rw(n_cols)       = 0;
-    access::rw(n_elem_slice) = 0;
-    access::rw(n_slices)     = 0;
-    access::rw(n_elem)       = 0;
-    }
-  }
-
-
-
-//! for constructing a complex cube out of two non-complex cubes
-template<typename eT>
-template<typename T1, typename T2>
-inline
-void
-Cube<eT>::init
-  (
-  const BaseCube<typename Cube<eT>::pod_type,T1>& A,
-  const BaseCube<typename Cube<eT>::pod_type,T2>& B
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type          T;
-  typedef typename ProxyCube<T1>::ea_type ea_type1;
-  typedef typename ProxyCube<T2>::ea_type ea_type2;
-  
-  arma_type_check(( is_complex<eT>::value == false ));   //!< compile-time abort if eT isn't std::complex
-  arma_type_check(( is_complex< T>::value == true  ));   //!< compile-time abort if T is std::complex
-  
-  arma_type_check(( is_same_type< std::complex<T>, eT >::value == false ));   //!< compile-time abort if types are not compatible
-  
-  const ProxyCube<T1> X(A.get_ref());
-  const ProxyCube<T2> Y(B.get_ref());
-  
-  arma_assert_same_size(X, Y, "Cube()");
-  
-  init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices());
-  
-  const uword      N       = n_elem;
-        eT*      out_mem = memptr();
-        ea_type1 PX      = X.get_ea();
-        ea_type2 PY      = Y.get_ea();
-  
-  for(uword i=0; i<N; ++i)
-    {
-    out_mem[i] = std::complex<T>(PX[i], PY[i]);
-    }
-  }
-
-
-
-//! try to steal the memory from a given cube; 
-//! if memory can't be stolen, copy the given cube
-template<typename eT>
-inline
-void
-Cube<eT>::steal_mem(Cube<eT>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(this != &x)
-    {
-    if( (x.mem_state == 0) && (x.n_elem > Cube_prealloc::mem_n_elem) )
-      {
-      reset();
-      
-      const uword x_n_slices = x.n_slices;
-      
-      access::rw(n_rows)       = x.n_rows;
-      access::rw(n_cols)       = x.n_cols;
-      access::rw(n_elem_slice) = x.n_elem_slice;
-      access::rw(n_slices)     = x_n_slices;
-      access::rw(n_elem)       = x.n_elem;
-      access::rw(mem)          = x.mem;
-      
-      if(x_n_slices > Cube_prealloc::mat_ptrs_size)
-        {
-        access::rw(  mat_ptrs) = x.mat_ptrs;
-        access::rw(x.mat_ptrs) = 0;
-        }
-      else
-        {
-        access::rw(mat_ptrs) = const_cast< const Mat<eT>** >(mat_ptrs_local);
-        
-        for(uword i=0; i < x_n_slices; ++i)
-          {
-            mat_ptrs[i] = x.mat_ptrs[i];
-          x.mat_ptrs[i] = 0;
-          }
-        }
-      
-      access::rw(x.n_rows)       = 0;
-      access::rw(x.n_cols)       = 0;
-      access::rw(x.n_elem_slice) = 0;
-      access::rw(x.n_slices)     = 0;
-      access::rw(x.n_elem)       = 0;
-      access::rw(x.mem)          = 0;
-      }
-    else
-      {
-      (*this).operator=(x);
-      }
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-Cube<eT>::delete_mat()
-  {
-  arma_extra_debug_sigprint();
-  
-  for(uword slice = 0; slice < n_slices; ++slice)
-    {
-    delete access::rw(mat_ptrs[slice]);
-    }
-  
-  if(mem_state <= 2)
-    {
-    if(n_slices > Cube_prealloc::mat_ptrs_size)
-      {
-      delete [] mat_ptrs;
-      }
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-Cube<eT>::create_mat()
-  {
-  arma_extra_debug_sigprint();
-  
-  if(mem_state <= 2)
-    {
-    if(n_slices <= Cube_prealloc::mat_ptrs_size)
-      {
-      access::rw(mat_ptrs) = const_cast< const Mat<eT>** >(mat_ptrs_local);
-      }
-    else
-      {
-      access::rw(mat_ptrs) = new(std::nothrow) const Mat<eT>*[n_slices];
-      
-      arma_check_bad_alloc( (mat_ptrs == 0), "Cube::create_mat(): out of memory" );
-      }
-    }
-  
-  for(uword slice = 0; slice < n_slices; ++slice)
-    {
-    mat_ptrs[slice] = new Mat<eT>('j', slice_memptr(slice), n_rows, n_cols);
-    }
-  }
-
-
-
-//! Set the cube to be equal to the specified scalar.
-//! NOTE: the size of the cube will be 1x1x1
-template<typename eT>
-arma_inline
-const Cube<eT>&
-Cube<eT>::operator=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  init_warm(1,1,1);
-  access::rw(mem[0]) = val;
-  return *this;
-  }
-
-
-
-//! In-place addition of a scalar to all elements of the cube
-template<typename eT>
-arma_inline
-const Cube<eT>&
-Cube<eT>::operator+=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_plus( memptr(), val, n_elem );
-  
-  return *this;
-  }
-
-
-
-//! In-place subtraction of a scalar from all elements of the cube
-template<typename eT>
-arma_inline
-const Cube<eT>&
-Cube<eT>::operator-=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_minus( memptr(), val, n_elem );
-  
-  return *this;
-  }
-
-
-
-//! In-place multiplication of all elements of the cube with a scalar
-template<typename eT>
-arma_inline
-const Cube<eT>&
-Cube<eT>::operator*=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_mul( memptr(), val, n_elem );
-  
-  return *this;
-  }
-
-
-
-//! In-place division of all elements of the cube with a scalar
-template<typename eT>
-arma_inline
-const Cube<eT>&
-Cube<eT>::operator/=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_div( memptr(), val, n_elem );
-  
-  return *this;
-  }
-
-
-
-//! construct a cube from a given cube
-template<typename eT>
-inline
-Cube<eT>::Cube(const Cube<eT>& x)
-  : n_rows(x.n_rows)
-  , n_cols(x.n_cols)
-  , n_elem_slice(x.n_elem_slice)
-  , n_slices(x.n_slices)
-  , n_elem(x.n_elem)
-  , mem_state(0)
-  , mat_ptrs()
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  arma_extra_debug_sigprint(arma_boost::format("this = %x   in_cube = %x") % this % &x);
-  
-  init_cold();
-  
-  arrayops::copy( memptr(), x.mem, n_elem );
-  }
-
-
-
-//! construct a cube from a given cube
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::operator=(const Cube<eT>& x)
-  {
-  arma_extra_debug_sigprint(arma_boost::format("this = %x   in_cube = %x") % this % &x);
-  
-  if(this != &x)
-    {
-    init_warm(x.n_rows, x.n_cols, x.n_slices);
-    
-    arrayops::copy( memptr(), x.mem, n_elem );
-    }
-  
-  return *this;
-  }
-
-
-
-//! construct a cube from a given auxiliary array of eTs.
-//! if copy_aux_mem is true, new memory is allocated and the array is copied.
-//! if copy_aux_mem is false, the auxiliary array is used directly (without allocating memory and copying).
-//! note that in the latter case 
-//! the default is to copy the array.
-
-template<typename eT>
-inline
-Cube<eT>::Cube(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices, const bool copy_aux_mem, const bool strict)
-  : n_rows      ( aux_n_rows                          )
-  , n_cols      ( aux_n_cols                          )
-  , n_elem_slice( aux_n_rows*aux_n_cols               )
-  , n_slices    ( aux_n_slices                        )
-  , n_elem      ( aux_n_rows*aux_n_cols*aux_n_slices  )
-  , mem_state   ( copy_aux_mem ? 0 : (strict ? 2 : 1) )
-  , mat_ptrs    ( 0                                   )
-  , mem         ( copy_aux_mem ? 0 : aux_mem          )
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  if(copy_aux_mem == true)
-    {
-    init_cold();
-    
-    arrayops::copy( memptr(), aux_mem, n_elem );
-    }
-  else
-    {
-    create_mat();
-    }
-  }
-
-
-
-//! construct a cube from a given auxiliary read-only array of eTs.
-//! the array is copied.
-template<typename eT>
-inline
-Cube<eT>::Cube(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices)
-  : n_rows(aux_n_rows)
-  , n_cols(aux_n_cols)
-  , n_elem_slice(aux_n_rows*aux_n_cols)
-  , n_slices(aux_n_slices)
-  , n_elem(aux_n_rows*aux_n_cols*aux_n_slices)
-  , mem_state(0)
-  , mat_ptrs()
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init_cold();
-  
-  arrayops::copy( memptr(), aux_mem, n_elem );
-  }
-
-
-
-//! in-place cube addition
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::operator+=(const Cube<eT>& m)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(*this, m, "cube addition");
-  
-  arrayops::inplace_plus( memptr(), m.memptr(), n_elem );
-  
-  return *this;
-  }
-
-
-
-//! in-place cube subtraction
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::operator-=(const Cube<eT>& m)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(*this, m, "cube subtraction");
-  
-  arrayops::inplace_minus( memptr(), m.memptr(), n_elem );
-  
-  return *this;
-  }
-
-
-
-//! in-place element-wise cube multiplication
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::operator%=(const Cube<eT>& m)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(*this, m, "element-wise cube multiplication");
-  
-  arrayops::inplace_mul( memptr(), m.memptr(), n_elem );
-  
-  return *this;
-  }
-
-
-
-//! in-place element-wise cube division
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::operator/=(const Cube<eT>& m)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(*this, m, "element-wise cube division");
-  
-  arrayops::inplace_div( memptr(), m.memptr(), n_elem );
-  
-  return *this;
-  }
-
-
-
-//! for constructing a complex cube out of two non-complex cubes
-template<typename eT>
-template<typename T1, typename T2>
-inline
-Cube<eT>::Cube
-  (
-  const BaseCube<typename Cube<eT>::pod_type,T1>& A,
-  const BaseCube<typename Cube<eT>::pod_type,T2>& B
-  )
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem_slice(0)
-  , n_slices(0)
-  , n_elem(0)
-  , mem_state(0)
-  , mat_ptrs()
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init(A,B);
-  }
-
-
-
-//! construct a cube from a subview_cube instance (e.g. construct a cube from a delayed subcube operation)
-template<typename eT>
-inline
-Cube<eT>::Cube(const subview_cube<eT>& X)
-  : n_rows(X.n_rows)
-  , n_cols(X.n_cols)
-  , n_elem_slice(X.n_elem_slice)
-  , n_slices(X.n_slices)
-  , n_elem(X.n_elem)
-  , mem_state(0)
-  , mat_ptrs()
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init_cold();
-  
-  subview_cube<eT>::extract(*this, X);
-  }
-
-
-
-//! construct a cube from a subview_cube instance (e.g. construct a cube from a delayed subcube operation)
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::operator=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool alias = (this == &(X.m));
-  
-  if(alias == false)
-    {
-    init_warm(X.n_rows, X.n_cols, X.n_slices);
-    
-    subview_cube<eT>::extract(*this, X);
-    }
-  else
-    {
-    Cube<eT> tmp(X);
-    
-    steal_mem(tmp);
-    }
-  
-  return *this;
-  }
-
-
-
-//! in-place cube addition (using a subcube on the right-hand-side)
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::operator+=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_cube<eT>::plus_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place cube subtraction (using a subcube on the right-hand-side)
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::operator-=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_cube<eT>::minus_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place element-wise cube mutiplication (using a subcube on the right-hand-side)
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::operator%=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_cube<eT>::schur_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place element-wise cube division (using a subcube on the right-hand-side)
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::operator/=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_cube<eT>::div_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! provide the reference to the matrix representing a single slice
-template<typename eT>
-arma_inline
-Mat<eT>&
-Cube<eT>::slice(const uword in_slice)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_slice >= n_slices),
-    "Cube::slice(): index out of bounds"
-    );
-  
-  return const_cast< Mat<eT>& >( *(mat_ptrs[in_slice]) );
-  }
-
-
-
-//! provide the reference to the matrix representing a single slice
-template<typename eT>
-arma_inline
-const Mat<eT>&
-Cube<eT>::slice(const uword in_slice) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_slice >= n_slices),
-    "Cube::slice(): index out of bounds"
-    );
-   
-  return *(mat_ptrs[in_slice]);
-  }
-
-
-
-//! creation of subview_cube (subcube comprised of specified slices)
-template<typename eT>
-arma_inline
-subview_cube<eT>
-Cube<eT>::slices(const uword in_slice1, const uword in_slice2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_slice1 > in_slice2) || (in_slice2 >= n_slices),
-    "Cube::slices(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subcube_n_slices = in_slice2 - in_slice1 + 1;
-  
-  return subview_cube<eT>(*this, 0, 0, in_slice1, n_rows, n_cols, subcube_n_slices);
-  }
-
-
-
-//! creation of subview_cube (subcube comprised of specified slices)
-template<typename eT>
-arma_inline
-const subview_cube<eT>
-Cube<eT>::slices(const uword in_slice1, const uword in_slice2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_slice1 > in_slice2) || (in_slice2 >= n_slices),
-    "Cube::rows(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subcube_n_slices = in_slice2 - in_slice1 + 1;
-  
-  return subview_cube<eT>(*this, 0, 0, in_slice1, n_rows, n_cols, subcube_n_slices);
-  }
-
-
-
-//! creation of subview_cube (generic subcube)
-template<typename eT>
-arma_inline
-subview_cube<eT>
-Cube<eT>::subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 >  in_row2) || (in_col1 >  in_col2) || (in_slice1 >  in_slice2) ||
-    (in_row2 >= n_rows)  || (in_col2 >= n_cols)  || (in_slice2 >= n_slices),
-    "Cube::subcube(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subcube_n_rows   = in_row2   - in_row1   + 1;
-  const uword subcube_n_cols   = in_col2   - in_col1   + 1;
-  const uword subcube_n_slices = in_slice2 - in_slice1 + 1;
-  
-  return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices);
-  }
-
-
-
-//! creation of subview_cube (generic subcube)
-template<typename eT>
-arma_inline
-const subview_cube<eT>
-Cube<eT>::subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 >  in_row2) || (in_col1 >  in_col2) || (in_slice1 >  in_slice2) ||
-    (in_row2 >= n_rows)  || (in_col2 >= n_cols)  || (in_slice2 >= n_slices),
-    "Cube::subcube(): indices out of bounds or incorrectly used"
-    );
-    
-  const uword subcube_n_rows   = in_row2   - in_row1   + 1;
-  const uword subcube_n_cols   = in_col2   - in_col1   + 1;
-  const uword subcube_n_slices = in_slice2 - in_slice1 + 1;
-  
-  return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices);
-  }
-
-
-
-//! creation of subview_cube (generic subcube)
-template<typename eT>
-inline
-subview_cube<eT>
-Cube<eT>::subcube(const span& row_span, const span& col_span, const span& slice_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all   = row_span.whole;
-  const bool col_all   = col_span.whole;
-  const bool slice_all = slice_span.whole;
-  
-  const uword local_n_rows   = n_rows;
-  const uword local_n_cols   = n_cols;
-  const uword local_n_slices = n_slices;
-  
-  const uword in_row1          = row_all   ? 0              : row_span.a;
-  const uword in_row2          =                              row_span.b;
-  const uword subcube_n_rows   = row_all   ? local_n_rows   : in_row2 - in_row1 + 1;
-  
-  const uword in_col1          = col_all   ? 0              : col_span.a;
-  const uword in_col2          =                              col_span.b;
-  const uword subcube_n_cols   = col_all   ? local_n_cols   : in_col2 - in_col1 + 1;
-  
-  const uword in_slice1        = slice_all ? 0              : slice_span.a;
-  const uword in_slice2        =                              slice_span.b;
-  const uword subcube_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1;
-  
-  arma_debug_check
-    (
-    ( row_all   ? false : ((in_row1   >  in_row2)   || (in_row2   >= local_n_rows))   )
-    ||
-    ( col_all   ? false : ((in_col1   >  in_col2)   || (in_col2   >= local_n_cols))   )
-    ||
-    ( slice_all ? false : ((in_slice1 >  in_slice2) || (in_slice2 >= local_n_slices)) )
-    ,
-    "Cube::subcube(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices);
-  }
-
-
-
-//! creation of subview_cube (generic subcube)
-template<typename eT>
-inline
-const subview_cube<eT>
-Cube<eT>::subcube(const span& row_span, const span& col_span, const span& slice_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all   = row_span.whole;
-  const bool col_all   = col_span.whole;
-  const bool slice_all = slice_span.whole;
-  
-  const uword local_n_rows   = n_rows;
-  const uword local_n_cols   = n_cols;
-  const uword local_n_slices = n_slices;
-  
-  const uword in_row1          = row_all   ? 0              : row_span.a;
-  const uword in_row2          =                              row_span.b;
-  const uword subcube_n_rows   = row_all   ? local_n_rows   : in_row2 - in_row1 + 1;
-  
-  const uword in_col1          = col_all   ? 0              : col_span.a;
-  const uword in_col2          =                              col_span.b;
-  const uword subcube_n_cols   = col_all   ? local_n_cols   : in_col2 - in_col1 + 1;
-  
-  const uword in_slice1        = slice_all ? 0              : slice_span.a;
-  const uword in_slice2        =                              slice_span.b;
-  const uword subcube_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1;
-  
-  arma_debug_check
-    (
-    ( row_all   ? false : ((in_row1   >  in_row2)   || (in_row2   >= local_n_rows))   )
-    ||
-    ( col_all   ? false : ((in_col1   >  in_col2)   || (in_col2   >= local_n_cols))   )
-    ||
-    ( slice_all ? false : ((in_slice1 >  in_slice2) || (in_slice2 >= local_n_slices)) )
-    ,
-    "Cube::subcube(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices);
-  }
-
-
-
-template<typename eT>
-inline
-subview_cube<eT>
-Cube<eT>::operator()(const span& row_span, const span& col_span, const span& slice_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).subcube(row_span, col_span, slice_span);
-  }
-
-
-
-template<typename eT>
-inline
-const subview_cube<eT>
-Cube<eT>::operator()(const span& row_span, const span& col_span, const span& slice_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).subcube(row_span, col_span, slice_span);
-  }
-
-
-
-//! remove specified slice
-template<typename eT>
-inline
-void
-Cube<eT>::shed_slice(const uword slice_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( slice_num >= n_slices, "Cube::shed_slice(): out of bounds");
-  
-  shed_slices(slice_num, slice_num);
-  }
-
-
-
-//! remove specified slices
-template<typename eT>
-inline
-void
-Cube<eT>::shed_slices(const uword in_slice1, const uword in_slice2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_slice1 > in_slice2) || (in_slice2 >= n_slices),
-    "Cube::shed_slices(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword n_keep_front = in_slice1;
-  const uword n_keep_back  = n_slices - (in_slice2 + 1);
-  
-  Cube<eT> X(n_rows, n_cols, n_keep_front + n_keep_back);
-  
-  if(n_keep_front > 0)
-    {
-    X.slices( 0, (n_keep_front-1) ) = slices( 0, (in_slice1-1) );
-    }
-  
-  if(n_keep_back > 0)
-    {
-    X.slices( n_keep_front,  (n_keep_front+n_keep_back-1) ) = slices( (in_slice2+1), (n_slices-1) );
-    }
-  
-  steal_mem(X);
-  }
-
-
-
-//! insert N slices at the specified slice position,
-//! optionally setting the elements of the inserted slices to zero
-template<typename eT>
-inline
-void
-Cube<eT>::insert_slices(const uword slice_num, const uword N, const bool set_to_zero)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword t_n_slices = n_slices;
-  
-  const uword A_n_slices = slice_num;
-  const uword B_n_slices = t_n_slices - slice_num;
-  
-  // insertion at slice_num == n_slices is in effect an append operation
-  arma_debug_check( (slice_num > t_n_slices), "Cube::insert_slices(): out of bounds");
-  
-  if(N > 0)
-    {
-    Cube<eT> out(n_rows, n_cols, t_n_slices + N);
-    
-    if(A_n_slices > 0)
-      {
-      out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1);
-      }
-    
-    if(B_n_slices > 0)
-      {
-      out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices-1);
-      }
-    
-    if(set_to_zero == true)
-      {
-      //out.slices(slice_num, slice_num + N - 1).zeros();
-      
-      for(uword i=slice_num; i < (slice_num + N); ++i)
-        {
-        out.slice(i).zeros();
-        }
-      }
-    
-    steal_mem(out);
-    }
-  }
-
-
-
-//! insert the given object at the specified slice position; 
-//! the given object must have the same number of rows and columns as the cube
-template<typename eT>
-template<typename T1>
-inline
-void
-Cube<eT>::insert_slices(const uword slice_num, const BaseCube<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap_cube<T1> tmp(X.get_ref());
-  const Cube<eT>& C   = tmp.M;
-  
-  const uword N = C.n_slices;
-  
-  const uword t_n_slices = n_slices;
-  
-  const uword A_n_slices = slice_num;
-  const uword B_n_slices = t_n_slices - slice_num;
-  
-  // insertion at slice_num == n_slices is in effect an append operation
-  arma_debug_check( (slice_num  >  t_n_slices), "Cube::insert_slices(): out of bounds");
-  
-  arma_debug_check
-    (
-    ( (C.n_rows != n_rows) || (C.n_cols != n_cols) ),
-    "Cube::insert_slices(): given object has an incompatible dimensions"
-    );
-  
-  if(N > 0)
-    {
-    Cube<eT> out(n_rows, n_cols, t_n_slices + N);
-    
-    if(A_n_slices > 0)
-      {
-      out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1);
-      }
-    
-    if(B_n_slices > 0)
-      {
-      out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices - 1);
-      }
-    
-    out.slices(slice_num, slice_num + N - 1) = C;
-    
-    steal_mem(out);
-    }
-  }
-
-
-
-//! create a cube from OpCube, i.e. run the previously delayed unary operations
-template<typename eT>
-template<typename gen_type>
-inline
-Cube<eT>::Cube(const GenCube<eT, gen_type>& X)
-  : n_rows(X.n_rows)
-  , n_cols(X.n_cols)
-  , n_elem_slice(X.n_rows*X.n_cols)
-  , n_slices(X.n_slices)
-  , n_elem(X.n_rows*X.n_cols*X.n_slices)
-  , mem_state(0)
-  , mat_ptrs()
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init_cold();
-  
-  X.apply(*this);
-  }
-
-
-
-template<typename eT>
-template<typename gen_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator=(const GenCube<eT, gen_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  init_warm(X.n_rows, X.n_cols, X.n_slices);
-  
-  X.apply(*this);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename gen_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator+=(const GenCube<eT, gen_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  X.apply_inplace_plus(*this);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename gen_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator-=(const GenCube<eT, gen_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  X.apply_inplace_minus(*this);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename gen_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator%=(const GenCube<eT, gen_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  X.apply_inplace_schur(*this);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename gen_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator/=(const GenCube<eT, gen_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  X.apply_inplace_div(*this);
-  
-  return *this;
-  }
-
-
-
-//! create a cube from OpCube, i.e. run the previously delayed unary operations
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-Cube<eT>::Cube(const OpCube<T1, op_type>& X)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem_slice(0)
-  , n_slices(0)
-  , n_elem(0)
-  , mem_state(0)
-  , mat_ptrs()
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  op_type::apply(*this, X);
-  }
-
-
-
-//! create a cube from OpCube, i.e. run the previously delayed unary operations
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator=(const OpCube<T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  op_type::apply(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place cube addition, with the right-hand-side operand having delayed operations
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator+=(const OpCube<T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator+=(m);
-  }
-
-
-
-//! in-place cube subtraction, with the right-hand-side operand having delayed operations
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator-=(const OpCube<T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator-=(m);
-  }
-
-
-
-//! in-place cube element-wise multiplication, with the right-hand-side operand having delayed operations
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator%=(const OpCube<T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator%=(m);
-  }
-
-
-
-//! in-place cube element-wise division, with the right-hand-side operand having delayed operations
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator/=(const OpCube<T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator/=(m);
-  }
-
-
-
-//! create a cube from eOpCube, i.e. run the previously delayed unary operations
-template<typename eT>
-template<typename T1, typename eop_type>
-inline
-Cube<eT>::Cube(const eOpCube<T1, eop_type>& X)
-  : n_rows(X.get_n_rows())
-  , n_cols(X.get_n_cols())
-  , n_elem_slice(X.get_n_elem_slice())
-  , n_slices(X.get_n_slices())
-  , n_elem(X.get_n_elem())
-  , mem_state(0)
-  , mat_ptrs()
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  init_cold();
-  
-  eop_type::apply(*this, X);
-  }
-
-
-
-//! create a cube from eOpCube, i.e. run the previously delayed unary operations
-template<typename eT>
-template<typename T1, typename eop_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator=(const eOpCube<T1, eop_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  const bool bad_alias = ( X.P.has_subview  &&  X.P.is_alias(*this) );
-  
-  if(bad_alias == false)
-    {
-    init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices());
-    
-    eop_type::apply(*this, X);
-    }
-  else
-    {
-    Cube<eT> tmp(X);
-    
-    steal_mem(tmp);
-    }
-  
-  return *this;
-  }
-
-
-
-//! in-place cube addition, with the right-hand-side operand having delayed operations
-template<typename eT>
-template<typename T1, typename eop_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator+=(const eOpCube<T1, eop_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  eop_type::apply_inplace_plus(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place cube subtraction, with the right-hand-side operand having delayed operations
-template<typename eT>
-template<typename T1, typename eop_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator-=(const eOpCube<T1, eop_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  eop_type::apply_inplace_minus(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place cube element-wise multiplication, with the right-hand-side operand having delayed operations
-template<typename eT>
-template<typename T1, typename eop_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator%=(const eOpCube<T1, eop_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-
-  eop_type::apply_inplace_schur(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place cube element-wise division, with the right-hand-side operand having delayed operations
-template<typename eT>
-template<typename T1, typename eop_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator/=(const eOpCube<T1, eop_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-
-  eop_type::apply_inplace_div(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-Cube<eT>::Cube(const mtOpCube<eT, T1, op_type>& X)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem_slice(0)
-  , n_slices(0)
-  , n_elem(0)
-  , mem_state(0)
-  , mat_ptrs()
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  op_type::apply(*this, X);
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator=(const mtOpCube<eT, T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  op_type::apply(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator+=(const mtOpCube<eT, T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator+=(m);
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator-=(const mtOpCube<eT, T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator-=(m);
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator%=(const mtOpCube<eT, T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator%=(m);
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator/=(const mtOpCube<eT, T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator/=(m);
-  }
-
-
-
-//! create a cube from Glue, i.e. run the previously delayed binary operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-Cube<eT>::Cube(const GlueCube<T1, T2, glue_type>& X)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem_slice(0)
-  , n_slices(0)
-  , n_elem(0)
-  , mem_state(0)
-  , mat_ptrs()
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  this->operator=(X);
-  }
-
-
-
-//! create a cube from Glue, i.e. run the previously delayed binary operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator=(const GlueCube<T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  glue_type::apply(*this, X);
-  
-  return *this;
-  }
-
-
-//! in-place cube addition, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator+=(const GlueCube<T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator+=(m);
-  }
-
-
-
-//! in-place cube subtraction, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator-=(const GlueCube<T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator-=(m);
-  }
-
-
-
-//! in-place cube element-wise multiplication, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator%=(const GlueCube<T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator%=(m);
-  }
-
-
-
-//! in-place cube element-wise division, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator/=(const GlueCube<T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator/=(m);
-  }
-
-
-
-//! create a cube from eGlue, i.e. run the previously delayed binary operations
-template<typename eT>
-template<typename T1, typename T2, typename eglue_type>
-inline
-Cube<eT>::Cube(const eGlueCube<T1, T2, eglue_type>& X)
-  : n_rows(X.get_n_rows())
-  , n_cols(X.get_n_cols())
-  , n_elem_slice(X.get_n_elem_slice())
-  , n_slices(X.get_n_slices())
-  , n_elem(X.get_n_elem())
-  , mem_state(0)
-  , mat_ptrs()
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  init_cold();
-  
-  eglue_type::apply(*this, X);
-  }
-
-
-
-//! create a cube from Glue, i.e. run the previously delayed binary operations
-template<typename eT>
-template<typename T1, typename T2, typename eglue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator=(const eGlueCube<T1, T2, eglue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  const bool bad_alias = ( (X.P1.has_subview  &&  X.P1.is_alias(*this))  ||  (X.P2.has_subview  &&  X.P2.is_alias(*this)) );
-  
-  if(bad_alias == false)
-    {
-    init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices());
-    
-    eglue_type::apply(*this, X);
-    }
-  else
-    {
-    Cube<eT> tmp(X);
-    
-    steal_mem(tmp);
-    }
-  
-  return *this;
-  }
-
-
-
-//! in-place cube addition, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename eglue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator+=(const eGlueCube<T1, T2, eglue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  eglue_type::apply_inplace_plus(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place cube subtraction, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename eglue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator-=(const eGlueCube<T1, T2, eglue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  eglue_type::apply_inplace_minus(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place cube element-wise multiplication, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename eglue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator%=(const eGlueCube<T1, T2, eglue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  eglue_type::apply_inplace_schur(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place cube element-wise division, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename eglue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator/=(const eGlueCube<T1, T2, eglue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  eglue_type::apply_inplace_div(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-Cube<eT>::Cube(const mtGlueCube<eT, T1, T2, glue_type>& X)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem_slice(0)
-  , n_slices(0)
-  , n_elem(0)
-  , mem_state(0)
-  , mat_ptrs()
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  glue_type::apply(*this, X);
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator=(const mtGlueCube<eT, T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  glue_type::apply(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator+=(const mtGlueCube<eT, T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator+=(m);
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator-=(const mtGlueCube<eT, T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator-=(m);
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator%=(const mtGlueCube<eT, T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator%=(m);
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Cube<eT>&
-Cube<eT>::operator/=(const mtGlueCube<eT, T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Cube<eT> m(X);
-  
-  return (*this).operator/=(m);
-  }
-
-
-
-//! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT&
-Cube<eT>::operator() (const uword i)
-  {
-  arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds");
-  return access::rw(mem[i]);
-  }
-
-
-
-//! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT
-Cube<eT>::operator() (const uword i) const
-  {
-  arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds");
-  return mem[i];
-  }
-
-
-//! linear element accessor (treats the cube as a vector); no bounds check.  
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT&
-Cube<eT>::operator[] (const uword i)
-  {
-  return access::rw(mem[i]);
-  }
-
-
-
-//! linear element accessor (treats the cube as a vector); no bounds check
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT
-Cube<eT>::operator[] (const uword i) const
-  {
-  return mem[i];
-  }
-
-
-
-//! linear element accessor (treats the cube as a vector); no bounds check.  
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT&
-Cube<eT>::at(const uword i)
-  {
-  return access::rw(mem[i]);
-  }
-
-
-
-//! linear element accessor (treats the cube as a vector); no bounds check
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT
-Cube<eT>::at(const uword i) const
-  {
-  return mem[i];
-  }
-
-
-
-//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT&
-Cube<eT>::operator() (const uword in_row, const uword in_col, const uword in_slice)
-  {
-  arma_debug_check
-    (
-    (in_row >= n_rows) ||
-    (in_col >= n_cols) ||
-    (in_slice >= n_slices)
-    ,
-    "Cube::operator(): index out of bounds"
-    );
-
-  return access::rw(mem[in_slice*n_elem_slice + in_col*n_rows + in_row]);
-  }
-
-
-
-//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT
-Cube<eT>::operator() (const uword in_row, const uword in_col, const uword in_slice) const
-  {
-  arma_debug_check
-    (
-    (in_row >= n_rows) ||
-    (in_col >= n_cols) ||
-    (in_slice >= n_slices)
-    ,
-    "Cube::operator(): index out of bounds"
-    );
-
-  return mem[in_slice*n_elem_slice + in_col*n_rows + in_row];
-  }
-
-
-
-//! element accessor; no bounds check
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT&
-Cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice)
-  {
-  return access::rw( mem[in_slice*n_elem_slice + in_col*n_rows + in_row] );
-  }
-
-
-
-//! element accessor; no bounds check
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT
-Cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice) const
-  {
-  return mem[in_slice*n_elem_slice + in_col*n_rows + in_row];
-  }
-
-
-
-//! prefix ++
-template<typename eT>
-arma_inline
-const Cube<eT>&
-Cube<eT>::operator++()
-  {
-  Cube_aux::prefix_pp(*this);
-  return *this;
-  }
-
-
-
-//! postfix ++  (must not return the object by reference)
-template<typename eT>
-arma_inline
-void
-Cube<eT>::operator++(int)
-  {
-  Cube_aux::postfix_pp(*this);
-  }
-
-
-
-//! prefix --
-template<typename eT>
-arma_inline
-const Cube<eT>&
-Cube<eT>::operator--()
-  {
-  Cube_aux::prefix_mm(*this);
-  return *this;
-  }
-
-
-
-//! postfix --  (must not return the object by reference)
-template<typename eT>
-arma_inline
-void
-Cube<eT>::operator--(int)
-  {
-  Cube_aux::postfix_mm(*this);
-  }
-
-
-
-//! returns true if all of the elements are finite
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Cube<eT>::is_finite() const
-  {
-  return arrayops::is_finite( memptr(), n_elem );
-  }
-
-
-
-//! returns true if the cube has no elements
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Cube<eT>::is_empty() const
-  {
-  return (n_elem == 0);
-  }
-
-
-
-//! returns true if the given index is currently in range
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Cube<eT>::in_range(const uword i) const
-  {
-  return (i < n_elem);
-  }
-
-
-
-//! returns true if the given start and end indices are currently in range
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Cube<eT>::in_range(const span& x) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(x.whole == true)
-    {
-    return true;
-    }
-  else
-    {
-    const uword a = x.a;
-    const uword b = x.b;
-    
-    return ( (a <= b) && (b < n_elem) );
-    }
-  }
-
-
-
-//! returns true if the given location is currently in range
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Cube<eT>::in_range(const uword in_row, const uword in_col, const uword in_slice) const
-  {
-  return ( (in_row < n_rows) && (in_col < n_cols) && (in_slice < n_slices) );
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-bool
-Cube<eT>::in_range(const span& row_span, const span& col_span, const span& slice_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword in_row1   = row_span.a;
-  const uword in_row2   = row_span.b;
-  
-  const uword in_col1   = col_span.a;
-  const uword in_col2   = col_span.b;
-  
-  const uword in_slice1 = slice_span.a;
-  const uword in_slice2 = slice_span.b;
-  
-  
-  const bool rows_ok   = row_span.whole   ? true : ( (in_row1   <= in_row2)   && (in_row2   < n_rows)   );
-  const bool cols_ok   = col_span.whole   ? true : ( (in_col1   <= in_col2)   && (in_col2   < n_cols)   );
-  const bool slices_ok = slice_span.whole ? true : ( (in_slice1 <= in_slice2) && (in_slice2 < n_slices) );
-  
-  
-  return ( (rows_ok == true) && (cols_ok == true) && (slices_ok == true) );
-  }
-
-
-
-//! returns a pointer to array of eTs used by the cube
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT*
-Cube<eT>::memptr()
-  {
-  return const_cast<eT*>(mem);
-  }
-
-
-
-//! returns a pointer to array of eTs used by the cube
-template<typename eT>
-arma_inline
-arma_warn_unused
-const eT*
-Cube<eT>::memptr() const
-  {
-  return mem;
-  }
-
-
-
-//! returns a pointer to array of eTs used by the specified slice in the cube
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT*
-Cube<eT>::slice_memptr(const uword slice)
-  {
-  return const_cast<eT*>( &mem[ slice*n_elem_slice ] );
-  }
-
-
-
-//! returns a pointer to array of eTs used by the specified slice in the cube
-template<typename eT>
-arma_inline
-arma_warn_unused
-const eT*
-Cube<eT>::slice_memptr(const uword slice) const
-  {
-  return &mem[ slice*n_elem_slice ];
-  }
-
-
-
-//! returns a pointer to array of eTs used by the specified slice in the cube
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT*
-Cube<eT>::slice_colptr(const uword slice, const uword col)
-  {
-  return const_cast<eT*>( &mem[ slice*n_elem_slice + col*n_rows] );
-  }
-
-
-
-//! returns a pointer to array of eTs used by the specified slice in the cube
-template<typename eT>
-arma_inline
-arma_warn_unused
-const eT*
-Cube<eT>::slice_colptr(const uword slice, const uword col) const
-  {
-  return &mem[ slice*n_elem_slice + col*n_rows ];
-  }
-
-
-
-//! print contents of the cube (to the cout stream),
-//! optionally preceding with a user specified line of text.
-//! the precision and cell width are modified.
-//! on return, the stream's state are restored to their original values.
-template<typename eT>
-inline
-void
-Cube<eT>::impl_print(const std::string& extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(extra_text.length() != 0)
-    {
-    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
-    }
-  
-  arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, true);
-  }
-
-
-//! print contents of the cube to a user specified stream,
-//! optionally preceding with a user specified line of text.
-//! the precision and cell width are modified.
-//! on return, the stream's state are restored to their original values.
-template<typename eT>
-inline
-void
-Cube<eT>::impl_print(std::ostream& user_stream, const std::string& extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(extra_text.length() != 0)
-    {
-    user_stream << extra_text << '\n';
-    }
-  
-  arma_ostream::print(user_stream, *this, true);
-  }
-
-
-
-//! print contents of the cube (to the cout stream),
-//! optionally preceding with a user specified line of text.
-//! the stream's state are used as is and are not modified
-//! (i.e. the precision and cell width are not modified).
-template<typename eT>
-inline
-void
-Cube<eT>::impl_raw_print(const std::string& extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(extra_text.length() != 0)
-    {
-    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
-    }
-  
-  arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, false);
-  }
-
-
-
-//! print contents of the cube to a user specified stream,
-//! optionally preceding with a user specified line of text.
-//! the stream's state are used as is and are not modified.
-//! (i.e. the precision and cell width are not modified).
-template<typename eT>
-inline
-void
-Cube<eT>::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(extra_text.length() != 0)
-    {
-    user_stream << extra_text << '\n';
-    }
-  
-  arma_ostream::print(user_stream, *this, false);
-  }
-
-
-
-//! change the cube to have user specified dimensions (data is not preserved)
-template<typename eT>
-inline
-void
-Cube<eT>::set_size(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices)
-  {
-  arma_extra_debug_sigprint();
-  
-  init_warm(in_n_rows, in_n_cols, in_n_slices);
-  }
-
-
-
-//! change the cube to have user specified dimensions (data is preserved)
-template<typename eT>
-inline
-void
-Cube<eT>::reshape(const uword in_rows, const uword in_cols, const uword in_slices, const uword dim)
-  {
-  arma_extra_debug_sigprint();
-  
-  *this = arma::reshape(*this, in_rows, in_cols, in_slices, dim);
-  }
-
-
-
-//! change the cube to have user specified dimensions (data is preserved)
-template<typename eT>
-inline
-void
-Cube<eT>::resize(const uword in_rows, const uword in_cols, const uword in_slices)
-  {
-  arma_extra_debug_sigprint();
-  
-  *this = arma::resize(*this, in_rows, in_cols, in_slices);
-  }
-
-
-
-//! change the cube (without preserving data) to have the same dimensions as the given cube 
-template<typename eT>
-template<typename eT2>
-inline
-void
-Cube<eT>::copy_size(const Cube<eT2>& m)
-  {
-  arma_extra_debug_sigprint();
-  
-  init_warm(m.n_rows, m.n_cols, m.n_slices);
-  }
-
-
-
-//! fill the cube with the specified value
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::fill(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_set( memptr(), val, n_elem );
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::zeros()
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).fill(eT(0));
-  }
-
-
-
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::zeros(const uword in_rows, const uword in_cols, const uword in_slices)
-  {
-  arma_extra_debug_sigprint();
-  
-  set_size(in_rows, in_cols, in_slices);
-  
-  return (*this).fill(eT(0));
-  }
-
-
-
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::ones()
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).fill(eT(1));
-  }
-
-
-
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::ones(const uword in_rows, const uword in_cols, const uword in_slices)
-  {
-  arma_extra_debug_sigprint();
-  
-  set_size(in_rows, in_cols, in_slices);
-  
-  return (*this).fill(eT(1));
-  }
-
-
-
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::randu()
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword N   = n_elem;
-        eT*   ptr = memptr();
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<N; i+=2, j+=2)
-    {
-    ptr[i] = eT(eop_aux_randu<eT>());
-    ptr[j] = eT(eop_aux_randu<eT>());
-    }
-  
-  if(i < N)
-    {
-    ptr[i] = eT(eop_aux_randu<eT>());
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::randu(const uword in_rows, const uword in_cols, const uword in_slices)
-  {
-  arma_extra_debug_sigprint();
-  
-  set_size(in_rows, in_cols, in_slices);
-  
-  return (*this).randu();
-  }
-
-
-
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::randn()
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword N   = n_elem;
-        eT*   ptr = memptr();
-  
-  for(uword i=0; i<N; ++i)
-    {
-    ptr[i] = eT(eop_aux_randn<eT>());
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-const Cube<eT>&
-Cube<eT>::randn(const uword in_rows, const uword in_cols, const uword in_slices)
-  {
-  arma_extra_debug_sigprint();
-  
-  set_size(in_rows, in_cols, in_slices);
-  
-  return (*this).randn();
-  }
-
-
-
-template<typename eT>
-inline
-void
-Cube<eT>::reset()
-  {
-  arma_extra_debug_sigprint();
-  
-  init_warm(0,0,0);
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-Cube<eT>::set_real(const BaseCube<typename Cube<eT>::pod_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Cube_aux::set_real(*this, X);
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-Cube<eT>::set_imag(const BaseCube<typename Cube<eT>::pod_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Cube_aux::set_imag(*this, X);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-Cube<eT>::min() const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (n_elem == 0), "min(): object has no elements" );
-  
-  return op_min::direct_min(memptr(), n_elem);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-Cube<eT>::max() const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (n_elem == 0), "max(): object has no elements" );
-  
-  return op_max::direct_max(memptr(), n_elem);
-  }
-
-
-
-template<typename eT>
-inline
-eT
-Cube<eT>::min(uword& index_of_min_val) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (n_elem == 0), "min(): object has no elements" );
-  
-  return op_min::direct_min(memptr(), n_elem, index_of_min_val);
-  }
-
-
-
-template<typename eT>
-inline
-eT
-Cube<eT>::max(uword& index_of_max_val) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (n_elem == 0), "max(): object has no elements" );
-  
-  return op_max::direct_max(memptr(), n_elem, index_of_max_val);
-  }
-
-
-
-template<typename eT>
-inline
-eT
-Cube<eT>::min(uword& row_of_min_val, uword& col_of_min_val, uword& slice_of_min_val) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (n_elem == 0), "min(): object has no elements" );
-  
-  uword i;
-  
-  eT val = op_min::direct_min(memptr(), n_elem, i);
-  
-  const uword in_slice = i / n_elem_slice;
-  const uword offset   = in_slice * n_elem_slice;
-  const uword j        = i - offset;
-  
-    row_of_min_val = j % n_rows;
-    col_of_min_val = j / n_rows;
-  slice_of_min_val = in_slice;
-  
-  return val;
-  }
-
-
-
-template<typename eT>
-inline
-eT
-Cube<eT>::max(uword& row_of_max_val, uword& col_of_max_val, uword& slice_of_max_val) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (n_elem == 0), "max(): object has no elements" );
-  
-  uword i;
-  
-  eT val = op_max::direct_max(memptr(), n_elem, i);
-  
-  const uword in_slice = i / n_elem_slice;
-  const uword offset   = in_slice * n_elem_slice;
-  const uword j        = i - offset;
-  
-    row_of_max_val = j % n_rows;
-    col_of_max_val = j / n_rows;
-  slice_of_max_val = in_slice;
-  
-  return val;
-  }
-
-
-
-//! save the cube to a file
-template<typename eT>
-inline
-bool
-Cube<eT>::save(const std::string name, const file_type type, const bool print_status) const
-  {
-  arma_extra_debug_sigprint();
-  
-  bool save_okay;
-  
-  switch(type)
-    {
-    case raw_ascii:
-      save_okay = diskio::save_raw_ascii(*this, name);
-      break;
-    
-    case arma_ascii:
-      save_okay = diskio::save_arma_ascii(*this, name);
-      break;
-    
-    case raw_binary:
-      save_okay = diskio::save_raw_binary(*this, name);
-      break;
-    
-    case arma_binary:
-      save_okay = diskio::save_arma_binary(*this, name);
-      break;
-    
-    case ppm_binary:
-      save_okay = diskio::save_ppm_binary(*this, name);
-      break;
-    
-    default:
-      arma_warn(print_status, "Cube::save(): unsupported file type");
-      save_okay = false;
-    }
-  
-  arma_warn( (print_status && (save_okay == false)), "Cube::save(): couldn't write to ", name);
-  
-  return save_okay;
-  }
-
-
-
-//! save the cube to a stream
-template<typename eT>
-inline
-bool
-Cube<eT>::save(std::ostream& os, const file_type type, const bool print_status) const
-  {
-  arma_extra_debug_sigprint();
-  
-  bool save_okay;
-  
-  switch(type)
-    {
-    case raw_ascii:
-      save_okay = diskio::save_raw_ascii(*this, os);
-      break;
-    
-    case arma_ascii:
-      save_okay = diskio::save_arma_ascii(*this, os);
-      break;
-    
-    case raw_binary:
-      save_okay = diskio::save_raw_binary(*this, os);
-      break;
-    
-    case arma_binary:
-      save_okay = diskio::save_arma_binary(*this, os);
-      break;
-    
-    case ppm_binary:
-      save_okay = diskio::save_ppm_binary(*this, os);
-      break;
-    
-    default:
-      arma_warn(print_status, "Cube::save(): unsupported file type");
-      save_okay = false;
-    }
-  
-  arma_warn( (print_status && (save_okay == false)), "Cube::save(): couldn't write to given stream");
-  
-  return save_okay;
-  }
-
-
-
-//! load a cube from a file
-template<typename eT>
-inline
-bool
-Cube<eT>::load(const std::string name, const file_type type, const bool print_status)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool load_okay;
-  std::string err_msg;
-  
-  switch(type)
-    {
-    case auto_detect:
-      load_okay = diskio::load_auto_detect(*this, name, err_msg);
-      break;
-    
-    case raw_ascii:
-      load_okay = diskio::load_raw_ascii(*this, name, err_msg);
-      break;
-    
-    case arma_ascii:
-      load_okay = diskio::load_arma_ascii(*this, name, err_msg);
-      break;
-    
-    case raw_binary:
-      load_okay = diskio::load_raw_binary(*this, name, err_msg);
-      break;
-    
-    case arma_binary:
-      load_okay = diskio::load_arma_binary(*this, name, err_msg);
-      break;
-    
-    case ppm_binary:
-      load_okay = diskio::load_ppm_binary(*this, name, err_msg);
-      break;
-    
-    default:
-      arma_warn(print_status, "Cube::load(): unsupported file type");
-      load_okay = false;
-    }
-  
-  if( (print_status == true) && (load_okay == false) )
-    {
-    if(err_msg.length() > 0)
-      {
-      arma_warn(true, "Cube::load(): ", err_msg, name);
-      }
-    else
-      {
-      arma_warn(true, "Cube::load(): couldn't read ", name);
-      }
-    }
-  
-  if(load_okay == false)
-    {
-    (*this).reset();
-    }
-    
-  return load_okay;
-  }
-
-
-
-//! load a cube from a stream
-template<typename eT>
-inline
-bool
-Cube<eT>::load(std::istream& is, const file_type type, const bool print_status)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool load_okay;
-  std::string err_msg;
-  
-  switch(type)
-    {
-    case auto_detect:
-      load_okay = diskio::load_auto_detect(*this, is, err_msg);
-      break;
-    
-    case raw_ascii:
-      load_okay = diskio::load_raw_ascii(*this, is, err_msg);
-      break;
-    
-    case arma_ascii:
-      load_okay = diskio::load_arma_ascii(*this, is, err_msg);
-      break;
-    
-    case raw_binary:
-      load_okay = diskio::load_raw_binary(*this, is, err_msg);
-      break;
-    
-    case arma_binary:
-      load_okay = diskio::load_arma_binary(*this, is, err_msg);
-      break;
-    
-    case ppm_binary:
-      load_okay = diskio::load_ppm_binary(*this, is, err_msg);
-      break;
-    
-    default:
-      arma_warn(print_status, "Cube::load(): unsupported file type");
-      load_okay = false;
-    }
-  
-  
-  if( (print_status == true) && (load_okay == false) )
-    {
-    if(err_msg.length() > 0)
-      {
-      arma_warn(true, "Cube::load(): ", err_msg, "the given stream");
-      }
-    else
-      {
-      arma_warn(true, "Cube::load(): couldn't load from the given stream");
-      }
-    }
-  
-  if(load_okay == false)
-    {
-    (*this).reset();
-    }
-    
-  return load_okay;
-  }
-
-
-
-//! save the cube to a file, without printing any error messages
-template<typename eT>
-inline
-bool
-Cube<eT>::quiet_save(const std::string name, const file_type type) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).save(name, type, false);
-  }
-
-
-
-//! save the cube to a stream, without printing any error messages
-template<typename eT>
-inline
-bool
-Cube<eT>::quiet_save(std::ostream& os, const file_type type) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).save(os, type, false);
-  }
-
-
-
-//! load a cube from a file, without printing any error messages
-template<typename eT>
-inline
-bool
-Cube<eT>::quiet_load(const std::string name, const file_type type)
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).load(name, type, false);
-  }
-
-
-
-//! load a cube from a stream, without printing any error messages
-template<typename eT>
-inline
-bool
-Cube<eT>::quiet_load(std::istream& is, const file_type type)
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).load(is, type, false);
-  }
-
-
-
-template<typename eT>
-inline
-typename Cube<eT>::iterator
-Cube<eT>::begin()
-  {
-  arma_extra_debug_sigprint();
-  
-  return memptr();
-  }
-
-
-
-template<typename eT>
-inline
-typename Cube<eT>::const_iterator
-Cube<eT>::begin() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return memptr();
-  }
-
-
-
-template<typename eT>
-inline
-typename Cube<eT>::iterator
-Cube<eT>::end()
-  {
-  arma_extra_debug_sigprint();
-  
-  return memptr() + n_elem;
-  }
-
-
-
-template<typename eT>
-inline
-typename Cube<eT>::const_iterator
-Cube<eT>::end() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return memptr() + n_elem;
-  }
-  
-
-
-template<typename eT>
-inline
-typename Cube<eT>::slice_iterator
-Cube<eT>::begin_slice(const uword slice_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds");
-  
-  return slice_memptr(slice_num);
-  }
-
-
-
-template<typename eT>
-inline
-typename Cube<eT>::const_slice_iterator
-Cube<eT>::begin_slice(const uword slice_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds");
-  
-  return slice_memptr(slice_num);
-  }
-
-
-
-template<typename eT>
-inline
-typename Cube<eT>::slice_iterator
-Cube<eT>::end_slice(const uword slice_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds");
-  
-  return slice_memptr(slice_num) + n_elem_slice;
-  }
-
-
-
-template<typename eT>
-inline
-typename Cube<eT>::const_slice_iterator
-Cube<eT>::end_slice(const uword slice_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds");
-  
-  return slice_memptr(slice_num) + n_elem_slice;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
-arma_inline
-void
-Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::mem_setup()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  if(fixed_n_elem > 0)
-    {
-    access::rw(Cube<eT>::n_rows)       = fixed_n_rows;
-    access::rw(Cube<eT>::n_cols)       = fixed_n_cols;
-    access::rw(Cube<eT>::n_elem_slice) = fixed_n_rows * fixed_n_cols;
-    access::rw(Cube<eT>::n_slices)     = fixed_n_slices;
-    access::rw(Cube<eT>::n_elem)       = fixed_n_elem;
-    access::rw(Cube<eT>::mem_state)    = 3;
-    access::rw(Cube<eT>::mat_ptrs)     = const_cast< const Mat<eT>** >( \
-                                         (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? mat_ptrs_local_extra : mat_ptrs_local );
-    access::rw(Cube<eT>::mem)          = (fixed_n_elem   > Cube_prealloc::mem_n_elem)    ? mem_local_extra      : mem_local;
-    
-    create_mat();
-    }
-  else
-    {
-    access::rw(Cube<eT>::n_rows)       = 0;
-    access::rw(Cube<eT>::n_cols)       = 0;
-    access::rw(Cube<eT>::n_elem_slice) = 0;
-    access::rw(Cube<eT>::n_slices)     = 0;
-    access::rw(Cube<eT>::n_elem)       = 0;
-    access::rw(Cube<eT>::mem_state)    = 3;
-    access::rw(Cube<eT>::mat_ptrs)     = 0;
-    access::rw(Cube<eT>::mem)          = 0;
-    }
-  }
-
-
-
-//! prefix ++
-template<typename eT>
-arma_inline
-void
-Cube_aux::prefix_pp(Cube<eT>& x)
-  {
-        eT*   memptr = x.memptr();
-  const uword n_elem = x.n_elem;
-  
-  uword i,j;
-
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    ++(memptr[i]);
-    ++(memptr[j]);
-    }
-  
-  if(i < n_elem)
-    {
-    ++(memptr[i]);
-    }
-  }
-
-
-
-//! prefix ++ for complex numbers (work around for limitations of the std::complex class)
-template<typename T>
-arma_inline
-void
-Cube_aux::prefix_pp(Cube< std::complex<T> >& x)
-  {
-  x += T(1);
-  }
-
-
-
-//! postfix ++
-template<typename eT>
-arma_inline
-void
-Cube_aux::postfix_pp(Cube<eT>& x)
-  {
-        eT* memptr = x.memptr();
-  const uword n_elem = x.n_elem;
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    (memptr[i])++;
-    (memptr[j])++;
-    }
-  
-  if(i < n_elem)
-    {
-    (memptr[i])++;
-    }
-  }
-
-
-
-//! postfix ++ for complex numbers (work around for limitations of the std::complex class)
-template<typename T>
-arma_inline
-void
-Cube_aux::postfix_pp(Cube< std::complex<T> >& x)
-  {
-  x += T(1);
-  }
-
-
-
-//! prefix --
-template<typename eT>
-arma_inline
-void
-Cube_aux::prefix_mm(Cube<eT>& x)
-  {
-        eT* memptr = x.memptr();
-  const uword n_elem = x.n_elem;
-
-  uword i,j;
-
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    --(memptr[i]);
-    --(memptr[j]);
-    }
-  
-  if(i < n_elem)
-    {
-    --(memptr[i]);
-    }
-  }
-
-
-
-//! prefix -- for complex numbers (work around for limitations of the std::complex class)
-template<typename T>
-arma_inline
-void
-Cube_aux::prefix_mm(Cube< std::complex<T> >& x)
-  {
-  x -= T(1);
-  }
-
-
-
-//! postfix --
-template<typename eT>
-arma_inline
-void
-Cube_aux::postfix_mm(Cube<eT>& x)
-  {
-        eT* memptr = x.memptr();
-  const uword n_elem = x.n_elem;
-
-  uword i,j;
-
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    (memptr[i])--;
-    (memptr[j])--;
-    }
-  
-  if(i < n_elem)
-    {
-    (memptr[i])--;
-    }
-  }
-
-
-
-//! postfix ++ for complex numbers (work around for limitations of the std::complex class)
-template<typename T>
-arma_inline
-void
-Cube_aux::postfix_mm(Cube< std::complex<T> >& x)
-  {
-  x -= T(1);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-Cube_aux::set_real(Cube<eT>& out, const BaseCube<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap_cube<T1> tmp(X.get_ref());
-  const Cube<eT>& A   = tmp.M;
-  
-  arma_debug_assert_same_size( out, A, "Cube::set_real()" );
-  
-  out = A;
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-Cube_aux::set_imag(Cube<eT>& out, const BaseCube<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T, typename T1>
-inline
-void
-Cube_aux::set_real(Cube< std::complex<T> >& out, const BaseCube<T,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T>        eT;
-  typedef typename ProxyCube<T1>::ea_type ea_type;
-  
-  const ProxyCube<T1> A(X.get_ref());
-  
-  arma_debug_assert_same_size
-    (
-    out.n_rows, out.n_cols, out.n_slices,
-    A.get_n_rows(), A.get_n_cols(), A.get_n_slices(),
-    "Cube::set_real()"
-    );
-  
-  const uword   n_elem  = out.n_elem;
-        eT*     out_mem = out.memptr();
-        ea_type PA      = A.get_ea();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    //out_mem[i].real() = PA[i];
-    out_mem[i] = std::complex<T>( PA[i], out_mem[i].imag() );
-    }
-  }
-
-
-
-template<typename T, typename T1>
-inline
-void
-Cube_aux::set_imag(Cube< std::complex<T> >& out, const BaseCube<T,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T>        eT;
-  typedef typename ProxyCube<T1>::ea_type ea_type;
-  
-  const ProxyCube<T1> A(X.get_ref());
-  
-  arma_debug_assert_same_size
-    (
-    out.n_rows, out.n_cols, out.n_slices,
-    A.get_n_rows(), A.get_n_cols(), A.get_n_slices(),
-    "Cube::set_imag()"
-    );
-  
-  const uword   n_elem  = out.n_elem;
-        eT*     out_mem = out.memptr();
-        ea_type PA      = A.get_ea();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    //out_mem[i].imag() = PA[i];
-    out_mem[i] = std::complex<T>( out_mem[i].real(), PA[i] );
-    }
-  }
-
-
-
-#ifdef ARMA_EXTRA_CUBE_MEAT
-  #include ARMA_INCFILE_WRAP(ARMA_EXTRA_CUBE_MEAT)
-#endif
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/GenCube_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup GenCube
-//! @{
-
-
-//! support class for generator functions (eg. zeros, randu, randn, ...)
-template<typename eT, typename gen_type>
-class GenCube : public BaseCube<eT, GenCube<eT, gen_type> >
-  {
-  public:
-  
-  typedef          eT                              elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  static const bool prefer_at_accessor = false;
-  
-  arma_aligned const uword n_rows;
-  arma_aligned const uword n_cols;
-  arma_aligned const uword n_slices;
-  
-  arma_inline  GenCube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices);
-  arma_inline ~GenCube();
-  
-  arma_inline static eT generate();
-  
-  arma_inline eT operator[] (const uword i)                                       const;
-  arma_inline eT at         (const uword row, const uword col, const uword slice) const;
-  
-  inline void apply              (Cube<eT>& out) const;
-  inline void apply_inplace_plus (Cube<eT>& out) const;
-  inline void apply_inplace_minus(Cube<eT>& out) const;
-  inline void apply_inplace_schur(Cube<eT>& out) const;
-  inline void apply_inplace_div  (Cube<eT>& out) const;
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/GenCube_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,224 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Gen
-//! @{
-
-
-
-template<typename eT, typename gen_type>
-arma_inline
-GenCube<eT, gen_type>::GenCube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices)
-  : n_rows  (in_n_rows  )
-  , n_cols  (in_n_cols  )
-  , n_slices(in_n_slices)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT, typename gen_type>
-arma_inline
-GenCube<eT, gen_type>::~GenCube()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT, typename gen_type>
-arma_inline
-eT
-GenCube<eT, gen_type>::generate()
-  {
-       if(is_same_type<gen_type, gen_ones_full>::value == true) { return eT(1);                   }
-  else if(is_same_type<gen_type, gen_zeros    >::value == true) { return eT(0);                   }
-  else if(is_same_type<gen_type, gen_randu    >::value == true) { return eT(eop_aux_randu<eT>()); }
-  else if(is_same_type<gen_type, gen_randn    >::value == true) { return eT(eop_aux_randn<eT>()); }
-  else                                                          { return eT();                    }
-  }
-
-
-
-template<typename eT, typename gen_type>
-arma_inline
-eT
-GenCube<eT, gen_type>::operator[](const uword) const
-  {
-  return GenCube<eT, gen_type>::generate();
-  }
-
-
-
-template<typename eT, typename gen_type>
-arma_inline
-eT
-GenCube<eT, gen_type>::at(const uword, const uword, const uword) const
-  {
-  return GenCube<eT, gen_type>::generate();
-  }
-
-
-
-template<typename eT, typename gen_type>
-inline
-void
-GenCube<eT, gen_type>::apply(Cube<eT>& out) const
-  {
-  arma_extra_debug_sigprint();
-  
-  // NOTE: we're assuming that the cube has already been set to the correct size;
-  // this is done by either the Cube contructor or operator=()
-  
-       if(is_same_type<gen_type, gen_ones_full>::value == true) { out.ones();  }
-  else if(is_same_type<gen_type, gen_zeros    >::value == true) { out.zeros(); }
-  else if(is_same_type<gen_type, gen_randu    >::value == true) { out.randu(); }
-  else if(is_same_type<gen_type, gen_randn    >::value == true) { out.randn(); }
-  }
-
-
-
-template<typename eT, typename gen_type>
-inline
-void
-GenCube<eT, gen_type>::apply_inplace_plus(Cube<eT>& out) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "addition");
-  
-  
-        eT*   out_mem = out.memptr();
-  const uword n_elem  = out.n_elem;
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = GenCube<eT, gen_type>::generate();
-    const eT tmp_j = GenCube<eT, gen_type>::generate();
-    
-    out_mem[i] += tmp_i;
-    out_mem[j] += tmp_j;
-    }
-  
-  if(i < n_elem)
-    {
-    out_mem[i] += GenCube<eT, gen_type>::generate();
-    }
-  }
-
-
-
-
-template<typename eT, typename gen_type>
-inline
-void
-GenCube<eT, gen_type>::apply_inplace_minus(Cube<eT>& out) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "subtraction");
-  
-  
-        eT*   out_mem = out.memptr();
-  const uword n_elem  = out.n_elem;
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = GenCube<eT, gen_type>::generate();
-    const eT tmp_j = GenCube<eT, gen_type>::generate();
-    
-    out_mem[i] -= tmp_i;
-    out_mem[j] -= tmp_j;
-    }
-  
-  if(i < n_elem)
-    {
-    out_mem[i] -= GenCube<eT, gen_type>::generate();
-    }
-  }
-
-
-
-
-template<typename eT, typename gen_type>
-inline
-void
-GenCube<eT, gen_type>::apply_inplace_schur(Cube<eT>& out) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise multiplication");
-  
-  
-        eT*   out_mem = out.memptr();
-  const uword n_elem  = out.n_elem;
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = GenCube<eT, gen_type>::generate();
-    const eT tmp_j = GenCube<eT, gen_type>::generate();
-    
-    out_mem[i] *= tmp_i;
-    out_mem[j] *= tmp_j;
-    }
-  
-  if(i < n_elem)
-    {
-    out_mem[i] *= GenCube<eT, gen_type>::generate();
-    }
-  }
-
-
-
-
-template<typename eT, typename gen_type>
-inline
-void
-GenCube<eT, gen_type>::apply_inplace_div(Cube<eT>& out) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise division");
-  
-  
-        eT*   out_mem = out.memptr();
-  const uword n_elem  = out.n_elem;
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = GenCube<eT, gen_type>::generate();
-    const eT tmp_j = GenCube<eT, gen_type>::generate();
-    
-    out_mem[i] /= tmp_i;
-    out_mem[j] /= tmp_j;
-    }
-  
-  if(i < n_elem)
-    {
-    out_mem[i] /= GenCube<eT, gen_type>::generate();
-    }
-  }
-
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Gen_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Gen
-//! @{
-
-
-//! support class for generator functions (eg. zeros, randu, randn, ...)
-template<typename eT, typename gen_type>
-class Gen : public Base<eT, Gen<eT, gen_type> >
-  {
-  public:
-  
-  typedef          eT                              elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  static const bool prefer_at_accessor = (is_same_type<gen_type, gen_ones_diag>::value) ? true : false;
-  
-  arma_aligned const uword n_rows;
-  arma_aligned const uword n_cols;
-  
-  arma_inline  Gen(const uword in_n_rows, const uword in_n_cols);
-  arma_inline ~Gen();
-  
-  arma_inline static eT generate();
-  
-  arma_inline eT operator[] (const uword i)                    const;
-  arma_inline eT at         (const uword row, const uword col) const;
-  
-  inline void apply              (Mat<eT>& out) const;
-  inline void apply_inplace_plus (Mat<eT>& out) const;
-  inline void apply_inplace_minus(Mat<eT>& out) const;
-  inline void apply_inplace_schur(Mat<eT>& out) const;
-  inline void apply_inplace_div  (Mat<eT>& out) const;
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Gen_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,294 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Gen
-//! @{
-
-
-
-template<typename eT, typename gen_type>
-arma_inline
-Gen<eT, gen_type>::Gen(const uword in_n_rows, const uword in_n_cols)
-  : n_rows(in_n_rows)
-  , n_cols(in_n_cols)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT, typename gen_type>
-arma_inline
-Gen<eT, gen_type>::~Gen()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT, typename gen_type>
-arma_inline
-eT
-Gen<eT, gen_type>::generate()
-  {
-       if(is_same_type<gen_type, gen_ones_full>::value == true) { return eT(1);                   }
-  else if(is_same_type<gen_type, gen_zeros    >::value == true) { return eT(0);                   }
-  else if(is_same_type<gen_type, gen_randu    >::value == true) { return eT(eop_aux_randu<eT>()); }
-  else if(is_same_type<gen_type, gen_randn    >::value == true) { return eT(eop_aux_randn<eT>()); }
-  else                                                          { return eT();                    }
-  }
-
-
-
-template<typename eT, typename gen_type>
-arma_inline
-eT
-Gen<eT, gen_type>::operator[](const uword i) const
-  {
-  if(is_same_type<gen_type, gen_ones_diag>::value == true)
-    {
-    return ((i % n_rows) == (i / n_rows)) ? eT(1) : eT(0);
-    }
-  else
-    {
-    return Gen<eT, gen_type>::generate();
-    }
-  }
-
-
-
-template<typename eT, typename gen_type>
-arma_inline
-eT
-Gen<eT, gen_type>::at(const uword row, const uword col) const
-  {
-  if(is_same_type<gen_type, gen_ones_diag>::value == true)
-    {
-    return (row == col) ? eT(1) : eT(0);
-    }
-  else
-    {
-    return Gen<eT, gen_type>::generate();
-    }
-  }
-
-
-
-template<typename eT, typename gen_type>
-inline
-void
-Gen<eT, gen_type>::apply(Mat<eT>& out) const
-  {
-  arma_extra_debug_sigprint();
-  
-  // NOTE: we're assuming that the matrix has already been set to the correct size;
-  // this is done by either the Mat contructor or operator=()
-  
-       if(is_same_type<gen_type, gen_ones_diag>::value == true) { out.eye();   }
-  else if(is_same_type<gen_type, gen_ones_full>::value == true) { out.ones();  }
-  else if(is_same_type<gen_type, gen_zeros    >::value == true) { out.zeros(); }
-  else if(is_same_type<gen_type, gen_randu    >::value == true) { out.randu(); }
-  else if(is_same_type<gen_type, gen_randn    >::value == true) { out.randn(); }
-  }
-
-
-
-template<typename eT, typename gen_type>
-inline
-void
-Gen<eT, gen_type>::apply_inplace_plus(Mat<eT>& out) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "addition");
-  
-  
-  if(is_same_type<gen_type, gen_ones_diag>::value == true)
-    {
-    const uword N = (std::min)(n_rows, n_cols);
-    
-    for(uword i=0; i<N; ++i)
-      {
-      out.at(i,i) += eT(1);
-      }
-    }
-  else
-    {
-          eT*   out_mem = out.memptr();
-    const uword n_elem  = out.n_elem;
-    
-    uword i,j;
-    
-    for(i=0, j=1; j<n_elem; i+=2, j+=2)
-      {
-      const eT tmp_i = Gen<eT, gen_type>::generate();
-      const eT tmp_j = Gen<eT, gen_type>::generate();
-      
-      out_mem[i] += tmp_i;
-      out_mem[j] += tmp_j;
-      }
-    
-    if(i < n_elem)
-      {
-      out_mem[i] += Gen<eT, gen_type>::generate();
-      }
-    }
-  
-  }
-
-
-
-
-template<typename eT, typename gen_type>
-inline
-void
-Gen<eT, gen_type>::apply_inplace_minus(Mat<eT>& out) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "subtraction");
-  
-  
-  if(is_same_type<gen_type, gen_ones_diag>::value == true)
-    {
-    const uword N = (std::min)(n_rows, n_cols);
-    
-    for(uword i=0; i<N; ++i)
-      {
-      out.at(i,i) -= eT(1);
-      }
-    }
-  else
-    {
-          eT*   out_mem = out.memptr();
-    const uword n_elem  = out.n_elem;
-    
-    uword i,j;
-    
-    for(i=0, j=1; j<n_elem; i+=2, j+=2)
-      {
-      const eT tmp_i = Gen<eT, gen_type>::generate();
-      const eT tmp_j = Gen<eT, gen_type>::generate();
-      
-      out_mem[i] -= tmp_i;
-      out_mem[j] -= tmp_j;
-      }
-    
-    if(i < n_elem)
-      {
-      out_mem[i] -= Gen<eT, gen_type>::generate();
-      }
-    }
-  
-  }
-
-
-
-
-template<typename eT, typename gen_type>
-inline
-void
-Gen<eT, gen_type>::apply_inplace_schur(Mat<eT>& out) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise multiplication");
-  
-  
-  if(is_same_type<gen_type, gen_ones_diag>::value == true)
-    {
-    const uword N = (std::min)(n_rows, n_cols);
-    
-    for(uword i=0; i<N; ++i)
-      {
-      for(uword row=0;   row<i;      ++row) { out.at(row,i) = eT(0); }
-      for(uword row=i+1; row<n_rows; ++row) { out.at(row,i) = eT(0); }
-      }
-    }
-  else
-    {
-          eT*   out_mem = out.memptr();
-    const uword n_elem  = out.n_elem;
-    
-    uword i,j;
-    
-    for(i=0, j=1; j<n_elem; i+=2, j+=2)
-      {
-      const eT tmp_i = Gen<eT, gen_type>::generate();
-      const eT tmp_j = Gen<eT, gen_type>::generate();
-      
-      out_mem[i] *= tmp_i;
-      out_mem[j] *= tmp_j;
-      }
-    
-    if(i < n_elem)
-      {
-      out_mem[i] *= Gen<eT, gen_type>::generate();
-      }
-    }
-  
-  }
-
-
-
-
-template<typename eT, typename gen_type>
-inline
-void
-Gen<eT, gen_type>::apply_inplace_div(Mat<eT>& out) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise division");
-  
-  
-  if(is_same_type<gen_type, gen_ones_diag>::value == true)
-    {
-    const uword N = (std::min)(n_rows, n_cols);
-    
-    for(uword i=0; i<N; ++i)
-      {
-      const eT zero = eT(0);
-      
-      for(uword row=0;   row<i;      ++row) { out.at(row,i) /= zero; }
-      for(uword row=i+1; row<n_rows; ++row) { out.at(row,i) /= zero; }
-      }
-    }
-  else
-    {
-          eT*   out_mem = out.memptr();
-    const uword n_elem  = out.n_elem;
-    
-    uword i,j;
-    
-    for(i=0, j=1; j<n_elem; i+=2, j+=2)
-      {
-      const eT tmp_i = Gen<eT, gen_type>::generate();
-      const eT tmp_j = Gen<eT, gen_type>::generate();
-      
-      out_mem[i] /= tmp_i;
-      out_mem[j] /= tmp_j;
-      }
-    
-    if(i < n_elem)
-      {
-      out_mem[i] /= Gen<eT, gen_type>::generate();
-      }
-    }
-  
-  }
-
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/GlueCube_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup GlueCube
-//! @{
-
-
-
-//! analog of the Glue class, intended for Cube objects
-template<typename T1, typename T2, typename glue_type>
-class GlueCube : public BaseCube<typename T1::elem_type, GlueCube<T1, T2, glue_type> >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-
-  arma_inline  GlueCube(const BaseCube<typename T1::elem_type, T1>& in_A, const BaseCube<typename T1::elem_type, T2>& in_B);
-  arma_inline ~GlueCube();
-  
-  const T1& A;  //!< first operand
-  const T2& B;  //!< second operand
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/GlueCube_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup GlueCube
-//! @{
-
-
-
-template<typename T1, typename T2, typename glue_type>
-inline
-GlueCube<T1,T2,glue_type>::GlueCube(const BaseCube<typename T1::elem_type, T1>& in_A, const BaseCube<typename T1::elem_type, T2>& in_B)
-  : A(in_A.get_ref())
-  , B(in_B.get_ref())
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename T2, typename glue_type>
-inline
-GlueCube<T1,T2,glue_type>::~GlueCube()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Glue_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Glue
-//! @{
-
-
-
-//! Class for storing data required for delayed binary operations,
-//! such as the operands (e.g. two matrices) and the binary operator (e.g. addition).
-//! The operands are stored as references (which can be optimised away),
-//! while the operator is "stored" through the template definition (glue_type).
-//! The operands can be 'Mat', 'Row', 'Col', 'Op', and 'Glue'.
-//! Note that as 'Glue' can be one of the operands, more than two matrices can be stored.
-//!
-//! For example, we could have: Glue<Mat, Mat, glue_times>
-//! 
-//! Another example is: Glue< Op<Mat, op_htrans>, Op<Mat, op_inv>, glue_times >
-
-
-
-template<typename T1, typename T2, typename glue_type>
-class Glue : public Base<typename T1::elem_type, Glue<T1, T2, glue_type> >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  arma_inline  Glue(const T1& in_A, const T2& in_B);
-  arma_inline  Glue(const T1& in_A, const T2& in_B, const uword in_aux_uword);
-  arma_inline ~Glue();
-  
-  const T1&   A;          //!< first operand
-  const T2&   B;          //!< second operand
-        uword aux_uword;  //!< storage of auxiliary data, uword format
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Glue_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Glue
-//! @{
-
-
-
-template<typename T1, typename T2, typename glue_type>
-inline
-Glue<T1,T2,glue_type>::Glue(const T1& in_A, const T2& in_B)
-  : A(in_A)
-  , B(in_B)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename T2, typename glue_type>
-inline
-Glue<T1,T2,glue_type>::Glue(const T1& in_A, const T2& in_B, const uword in_aux_uword)
-  : A(in_A)
-  , B(in_B)
-  , aux_uword(in_aux_uword)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename T2, typename glue_type>
-inline
-Glue<T1,T2,glue_type>::~Glue()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Mat_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,575 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Mat
-//! @{
-
-
-
-//! Dense matrix class
-
-template<typename eT>
-class Mat : public Base< eT, Mat<eT> >
-  {
-  public:
-  
-  typedef eT                                elem_type;  //!< the type of elements stored in the matrix
-  typedef typename get_pod_type<eT>::result pod_type;   //!< if eT is non-complex, pod_type is same as eT. otherwise, pod_type is the underlying type used by std::complex
-  
-  const uword  n_rows;    //!< number of rows in the matrix (read-only)
-  const uword  n_cols;    //!< number of columns in the matrix (read-only)
-  const uword  n_elem;    //!< number of elements in the matrix (read-only)
-  const uhword vec_state; //!< 0: matrix layout; 1: column vector layout; 2: row vector layout
-  const uhword mem_state;
-  
-  // mem_state = 0: normal matrix that can be resized; 
-  // mem_state = 1: use auxiliary memory until change in the number of elements is requested;  
-  // mem_state = 2: use auxiliary memory and don't allow the number of elements to be changed; 
-  // mem_state = 3: fixed size (e.g. via template based size specification).
-  
-  arma_aligned const eT* const mem;  //!< pointer to the memory used by the matrix (memory is read-only)
-  
-  protected:
-  arma_aligned eT mem_local[ arma_config::mat_prealloc ];
-  
-  
-  public:
-  
-  inline ~Mat();
-  inline  Mat();
-  
-  inline Mat(const uword in_rows, const uword in_cols);
-  
-  inline                  Mat(const char*        text);
-  inline const Mat& operator=(const char*        text);
-  
-  inline                  Mat(const std::string& text);
-  inline const Mat& operator=(const std::string& text);
-  
-  #if defined(ARMA_USE_CXX11)
-  inline                  Mat(const std::initializer_list<eT>& list);
-  inline const Mat& operator=(const std::initializer_list<eT>& list);
-  #endif
-  
-  inline Mat(      eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const bool copy_aux_mem = true, const bool strict = true);
-  inline Mat(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols);
-  
-  arma_inline const Mat&  operator=(const eT val);
-  arma_inline const Mat& operator+=(const eT val);
-  arma_inline const Mat& operator-=(const eT val);
-  arma_inline const Mat& operator*=(const eT val);
-  arma_inline const Mat& operator/=(const eT val);
-  
-  inline                   Mat(const Mat& m);
-  inline const Mat&  operator=(const Mat& m);
-  inline const Mat& operator+=(const Mat& m);
-  inline const Mat& operator-=(const Mat& m);
-  inline const Mat& operator*=(const Mat& m);
-  inline const Mat& operator%=(const Mat& m);
-  inline const Mat& operator/=(const Mat& m);
-  
-  template<typename T1> inline                   Mat(const BaseCube<eT,T1>& X);
-  template<typename T1> inline const Mat&  operator=(const BaseCube<eT,T1>& X);
-  template<typename T1> inline const Mat& operator+=(const BaseCube<eT,T1>& X);
-  template<typename T1> inline const Mat& operator-=(const BaseCube<eT,T1>& X);
-  template<typename T1> inline const Mat& operator*=(const BaseCube<eT,T1>& X);
-  template<typename T1> inline const Mat& operator%=(const BaseCube<eT,T1>& X);
-  template<typename T1> inline const Mat& operator/=(const BaseCube<eT,T1>& X);
-  
-  template<typename T1, typename T2>
-  inline explicit Mat(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
-
-  inline                   Mat(const subview<eT>& X);
-  inline const Mat&  operator=(const subview<eT>& X);
-  inline const Mat& operator+=(const subview<eT>& X);
-  inline const Mat& operator-=(const subview<eT>& X);
-  inline const Mat& operator*=(const subview<eT>& X);
-  inline const Mat& operator%=(const subview<eT>& X);
-  inline const Mat& operator/=(const subview<eT>& X);
-
-  //inline explicit          Mat(const subview_cube<eT>& X);
-  inline                   Mat(const subview_cube<eT>& X);
-  inline const Mat&  operator=(const subview_cube<eT>& X);
-  inline const Mat& operator+=(const subview_cube<eT>& X);
-  inline const Mat& operator-=(const subview_cube<eT>& X);
-  inline const Mat& operator*=(const subview_cube<eT>& X);
-  inline const Mat& operator%=(const subview_cube<eT>& X);
-  inline const Mat& operator/=(const subview_cube<eT>& X);
-
-  //inline explicit          Mat(const diagview<eT>& X);
-  inline                   Mat(const diagview<eT>& X);
-  inline const Mat&  operator=(const diagview<eT>& X);
-  inline const Mat& operator+=(const diagview<eT>& X);
-  inline const Mat& operator-=(const diagview<eT>& X);
-  inline const Mat& operator*=(const diagview<eT>& X);
-  inline const Mat& operator%=(const diagview<eT>& X);
-  inline const Mat& operator/=(const diagview<eT>& X);
-  
-  template<typename T1> inline                   Mat(const subview_elem1<eT,T1>& X);
-  template<typename T1> inline const Mat& operator= (const subview_elem1<eT,T1>& X);
-  template<typename T1> inline const Mat& operator+=(const subview_elem1<eT,T1>& X);
-  template<typename T1> inline const Mat& operator-=(const subview_elem1<eT,T1>& X);
-  template<typename T1> inline const Mat& operator*=(const subview_elem1<eT,T1>& X);
-  template<typename T1> inline const Mat& operator%=(const subview_elem1<eT,T1>& X);
-  template<typename T1> inline const Mat& operator/=(const subview_elem1<eT,T1>& X);
-  
-  
-  inline mat_injector<Mat> operator<<(const eT val);
-  inline mat_injector<Mat> operator<<(const injector_end_of_row& x);
-  
-  
-  arma_inline       subview_row<eT> row(const uword row_num);
-  arma_inline const subview_row<eT> row(const uword row_num) const;
-  
-  inline            subview_row<eT> operator()(const uword row_num, const span& col_span);
-  inline      const subview_row<eT> operator()(const uword row_num, const span& col_span) const;
-  
-  
-  arma_inline       subview_col<eT> col(const uword col_num);
-  arma_inline const subview_col<eT> col(const uword col_num) const;
-  
-  inline            subview_col<eT> operator()(const span& row_span, const uword col_num);
-  inline      const subview_col<eT> operator()(const span& row_span, const uword col_num) const;
-  
-  inline            Col<eT>  unsafe_col(const uword col_num);
-  inline      const Col<eT>  unsafe_col(const uword col_num) const;
-  
-  
-  arma_inline       subview<eT> rows(const uword in_row1, const uword in_row2);
-  arma_inline const subview<eT> rows(const uword in_row1, const uword in_row2) const;
-  
-  arma_inline       subview<eT> cols(const uword in_col1, const uword in_col2);
-  arma_inline const subview<eT> cols(const uword in_col1, const uword in_col2) const;
-  
-  arma_inline       subview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2);
-  arma_inline const subview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const;
-  
-  
-  inline            subview<eT> submat    (const span& row_span, const span& col_span);
-  inline      const subview<eT> submat    (const span& row_span, const span& col_span) const;
-  
-  inline            subview<eT> operator()(const span& row_span, const span& col_span);
-  inline      const subview<eT> operator()(const span& row_span, const span& col_span) const;
-  
-  
-  template<typename T1> arma_inline       subview_elem1<eT,T1> elem(const Base<uword,T1>& a);
-  template<typename T1> arma_inline const subview_elem1<eT,T1> elem(const Base<uword,T1>& a) const;
-  
-  // template<typename T1, typename T2> arma_inline       subview_elem2<eT,T1,T2> submat(const Base<uword,T1>& a, const Base<uword,T2>& b);
-  // template<typename T1, typename T2> arma_inline const subview_elem2<eT,T1,T2> submat(const Base<uword,T1>& a, const Base<uword,T2>& b) const;
-  
-  
-  arma_inline       diagview<eT> diag(const sword in_id = 0);
-  arma_inline const diagview<eT> diag(const sword in_id = 0) const;
-  
-  
-  inline void swap_rows(const uword in_row1, const uword in_row2);
-  inline void swap_cols(const uword in_col1, const uword in_col2);
-  
-  inline void shed_row(const uword row_num);
-  inline void shed_col(const uword col_num);
-  
-  inline void shed_rows(const uword in_row1, const uword in_row2);
-  inline void shed_cols(const uword in_col1, const uword in_col2);
-  
-  inline void insert_rows(const uword row_num, const uword N, const bool set_to_zero = true);
-  inline void insert_cols(const uword col_num, const uword N, const bool set_to_zero = true);
-  
-  template<typename T1> inline void insert_rows(const uword row_num, const Base<eT,T1>& X);
-  template<typename T1> inline void insert_cols(const uword col_num, const Base<eT,T1>& X);
-  
-  
-  template<typename gen_type> inline                   Mat(const Gen<eT, gen_type>& X);
-  template<typename gen_type> inline const Mat&  operator=(const Gen<eT, gen_type>& X);
-  template<typename gen_type> inline const Mat& operator+=(const Gen<eT, gen_type>& X);
-  template<typename gen_type> inline const Mat& operator-=(const Gen<eT, gen_type>& X);
-  template<typename gen_type> inline const Mat& operator*=(const Gen<eT, gen_type>& X);
-  template<typename gen_type> inline const Mat& operator%=(const Gen<eT, gen_type>& X);
-  template<typename gen_type> inline const Mat& operator/=(const Gen<eT, gen_type>& X);
-  
-  template<typename T1, typename op_type> inline                   Mat(const Op<T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Mat&  operator=(const Op<T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Mat& operator+=(const Op<T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Mat& operator-=(const Op<T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Mat& operator*=(const Op<T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Mat& operator%=(const Op<T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Mat& operator/=(const Op<T1, op_type>& X);
-  
-  template<typename T1, typename eop_type> inline                   Mat(const eOp<T1, eop_type>& X);
-  template<typename T1, typename eop_type> inline const Mat&  operator=(const eOp<T1, eop_type>& X);
-  template<typename T1, typename eop_type> inline const Mat& operator+=(const eOp<T1, eop_type>& X);
-  template<typename T1, typename eop_type> inline const Mat& operator-=(const eOp<T1, eop_type>& X);
-  template<typename T1, typename eop_type> inline const Mat& operator*=(const eOp<T1, eop_type>& X);
-  template<typename T1, typename eop_type> inline const Mat& operator%=(const eOp<T1, eop_type>& X);
-  template<typename T1, typename eop_type> inline const Mat& operator/=(const eOp<T1, eop_type>& X);
-  
-  template<typename T1, typename op_type> inline                   Mat(const mtOp<eT, T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Mat&  operator=(const mtOp<eT, T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Mat& operator+=(const mtOp<eT, T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Mat& operator-=(const mtOp<eT, T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Mat& operator*=(const mtOp<eT, T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Mat& operator%=(const mtOp<eT, T1, op_type>& X);
-  template<typename T1, typename op_type> inline const Mat& operator/=(const mtOp<eT, T1, op_type>& X);
-  
-  template<typename T1, typename T2, typename glue_type> inline                   Mat(const Glue<T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Mat&  operator=(const Glue<T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Mat& operator+=(const Glue<T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Mat& operator-=(const Glue<T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Mat& operator*=(const Glue<T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Mat& operator%=(const Glue<T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Mat& operator/=(const Glue<T1, T2, glue_type>& X);
-  
-  template<typename T1, typename T2>                     inline const Mat& operator+=(const Glue<T1, T2, glue_times>& X);
-  template<typename T1, typename T2>                     inline const Mat& operator-=(const Glue<T1, T2, glue_times>& X);
-  
-  template<typename T1, typename T2, typename eglue_type> inline                   Mat(const eGlue<T1, T2, eglue_type>& X);
-  template<typename T1, typename T2, typename eglue_type> inline const Mat&  operator=(const eGlue<T1, T2, eglue_type>& X);
-  template<typename T1, typename T2, typename eglue_type> inline const Mat& operator+=(const eGlue<T1, T2, eglue_type>& X);
-  template<typename T1, typename T2, typename eglue_type> inline const Mat& operator-=(const eGlue<T1, T2, eglue_type>& X);
-  template<typename T1, typename T2, typename eglue_type> inline const Mat& operator*=(const eGlue<T1, T2, eglue_type>& X);
-  template<typename T1, typename T2, typename eglue_type> inline const Mat& operator%=(const eGlue<T1, T2, eglue_type>& X);
-  template<typename T1, typename T2, typename eglue_type> inline const Mat& operator/=(const eGlue<T1, T2, eglue_type>& X);
-  
-  template<typename T1, typename T2, typename glue_type> inline                   Mat(const mtGlue<eT, T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Mat&  operator=(const mtGlue<eT, T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Mat& operator+=(const mtGlue<eT, T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Mat& operator-=(const mtGlue<eT, T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Mat& operator*=(const mtGlue<eT, T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Mat& operator%=(const mtGlue<eT, T1, T2, glue_type>& X);
-  template<typename T1, typename T2, typename glue_type> inline const Mat& operator/=(const mtGlue<eT, T1, T2, glue_type>& X);
-  
-  
-  arma_inline arma_warn_unused eT& operator[] (const uword i);
-  arma_inline arma_warn_unused eT  operator[] (const uword i) const;
-  arma_inline arma_warn_unused eT& at         (const uword i);
-  arma_inline arma_warn_unused eT  at         (const uword i) const;
-  arma_inline arma_warn_unused eT& operator() (const uword i);
-  arma_inline arma_warn_unused eT  operator() (const uword i) const;
-  
-  arma_inline arma_warn_unused eT& at         (const uword in_row, const uword in_col);
-  arma_inline arma_warn_unused eT  at         (const uword in_row, const uword in_col) const;
-  arma_inline arma_warn_unused eT& operator() (const uword in_row, const uword in_col);
-  arma_inline arma_warn_unused eT  operator() (const uword in_row, const uword in_col) const;
-  
-  arma_inline const Mat& operator++();
-  arma_inline void       operator++(int);
-  
-  arma_inline const Mat& operator--();
-  arma_inline void       operator--(int);
-  
-  arma_inline arma_warn_unused bool is_empty()  const;
-  arma_inline arma_warn_unused bool is_vec()    const;
-  arma_inline arma_warn_unused bool is_rowvec() const;
-  arma_inline arma_warn_unused bool is_colvec() const;
-  arma_inline arma_warn_unused bool is_square() const;
-       inline arma_warn_unused bool is_finite() const;
-  
-  arma_inline arma_warn_unused bool in_range(const uword i) const;
-  arma_inline arma_warn_unused bool in_range(const span& x) const;
-  
-  arma_inline arma_warn_unused bool in_range(const uword   in_row, const uword   in_col) const;
-  arma_inline arma_warn_unused bool in_range(const span& row_span, const uword   in_col) const;
-  arma_inline arma_warn_unused bool in_range(const uword   in_row, const span& col_span) const;
-  arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span) const;
-  
-  arma_inline arma_warn_unused       eT* colptr(const uword in_col);
-  arma_inline arma_warn_unused const eT* colptr(const uword in_col) const;
-  
-  arma_inline arma_warn_unused       eT* memptr();
-  arma_inline arma_warn_unused const eT* memptr() const;
-  
-  
-  inline void impl_print(const std::string& extra_text) const;
-  inline void impl_print(std::ostream& user_stream, const std::string& extra_text) const;
-  
-  inline void impl_print_trans(const std::string& extra_text) const;
-  inline void impl_print_trans(std::ostream& user_stream, const std::string& extra_text) const;
-  
-  inline void impl_raw_print(const std::string& extra_text) const;
-  inline void impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const;
-  
-  inline void impl_raw_print_trans(const std::string& extra_text) const;
-  inline void impl_raw_print_trans(std::ostream& user_stream, const std::string& extra_text) const;
-  
-  
-  template<typename eT2>
-  inline void copy_size(const Mat<eT2>& m);
-  
-  inline void set_size(const uword in_elem);
-  inline void set_size(const uword in_rows, const uword in_cols);
-  
-  inline void   resize(const uword in_elem);
-  inline void   resize(const uword in_rows, const uword in_cols);
-  inline void  reshape(const uword in_rows, const uword in_cols, const uword dim = 0);
-  
-  
-  arma_hot inline const Mat& fill(const eT val);
-  
-  inline const Mat& zeros();
-  inline const Mat& zeros(const uword in_elem);
-  inline const Mat& zeros(const uword in_rows, const uword in_cols);
-  
-  inline const Mat& ones();
-  inline const Mat& ones(const uword in_elem);
-  inline const Mat& ones(const uword in_rows, const uword in_cols);
-  
-  inline const Mat& randu();
-  inline const Mat& randu(const uword in_elem);
-  inline const Mat& randu(const uword in_rows, const uword in_cols);
-  
-  inline const Mat& randn();
-  inline const Mat& randn(const uword in_elem);
-  inline const Mat& randn(const uword in_rows, const uword in_cols);
-  
-  inline const Mat& eye();
-  inline const Mat& eye(const uword in_rows, const uword in_cols);
-  
-  inline void reset();
-  
-  
-  template<typename T1> inline void set_real(const Base<pod_type,T1>& X);
-  template<typename T1> inline void set_imag(const Base<pod_type,T1>& X);
-  
-  
-  inline arma_warn_unused eT min() const;
-  inline arma_warn_unused eT max() const;
-  
-  inline eT min(uword& index_of_min_val) const;
-  inline eT max(uword& index_of_max_val) const;
-  
-  inline eT min(uword& row_of_min_val, uword& col_of_min_val) const;
-  inline eT max(uword& row_of_max_val, uword& col_of_max_val) const;
-  
-  
-  inline bool save(const std::string   name, const file_type type = arma_binary, const bool print_status = true) const;
-  inline bool save(      std::ostream& os,   const file_type type = arma_binary, const bool print_status = true) const;
-  
-  inline bool load(const std::string   name, const file_type type = auto_detect, const bool print_status = true);
-  inline bool load(      std::istream& is,   const file_type type = auto_detect, const bool print_status = true);
-  
-  inline bool quiet_save(const std::string   name, const file_type type = arma_binary) const;
-  inline bool quiet_save(      std::ostream& os,   const file_type type = arma_binary) const;
-  
-  inline bool quiet_load(const std::string   name, const file_type type = auto_detect);
-  inline bool quiet_load(      std::istream& is,   const file_type type = auto_detect);
-  
-  
-  // for container-like functionality
-  
-  typedef eT    value_type;
-  typedef uword size_type;
-  
-  typedef       eT*       iterator;
-  typedef const eT* const_iterator;
-  
-  typedef       eT*       col_iterator;
-  typedef const eT* const_col_iterator;
-  
-  class row_iterator
-    {
-    public:
-    
-    inline row_iterator(Mat<eT>& in_M, const uword in_row);
-    
-    inline eT& operator* ();
-    
-    inline row_iterator& operator++();
-    inline void          operator++(int);
-    
-    inline row_iterator& operator--();
-    inline void          operator--(int);
-    
-    inline bool operator!=(const row_iterator& X) const;
-    inline bool operator==(const row_iterator& X) const;
-    
-    arma_aligned Mat<eT>& M;
-    arma_aligned uword    row;
-    arma_aligned uword    col;
-    };
-  
-  
-  class const_row_iterator
-    {
-    public:
-    
-    const_row_iterator(const Mat<eT>& in_M, const uword in_row);
-    const_row_iterator(const row_iterator& X);
-    
-    inline eT operator*() const;
-    
-    inline const_row_iterator& operator++();
-    inline void                operator++(int);
-    
-    inline const_row_iterator& operator--();
-    inline void                operator--(int);
-    
-    inline bool operator!=(const const_row_iterator& X) const;
-    inline bool operator==(const const_row_iterator& X) const;
-    
-    arma_aligned const Mat<eT>& M;
-    arma_aligned       uword    row;
-    arma_aligned       uword    col;
-    };
-  
-  inline       iterator begin();
-  inline const_iterator begin() const;
-  
-  inline       iterator end();
-  inline const_iterator end()   const;
-  
-  inline       col_iterator begin_col(const uword col_num);
-  inline const_col_iterator begin_col(const uword col_num) const;
-  
-  inline       col_iterator end_col  (const uword col_num);
-  inline const_col_iterator end_col  (const uword col_num) const;
-  
-  inline       row_iterator begin_row(const uword row_num);
-  inline const_row_iterator begin_row(const uword row_num) const;
-  
-  inline       row_iterator end_row  (const uword row_num);
-  inline const_row_iterator end_row  (const uword row_num) const;
-  
-  inline void  clear();
-  inline bool  empty() const;
-  inline uword size()  const;
-  
-  template<uword fixed_n_rows, uword fixed_n_cols>
-  class fixed : public Mat<eT>
-    {
-    private:
-    
-    static const uword fixed_n_elem = fixed_n_rows * fixed_n_cols;
-    static const bool  use_extra    = (fixed_n_elem > arma_config::mat_prealloc);
-    
-    arma_aligned eT mem_local_extra[ (use_extra) ? fixed_n_elem : 1 ];
-    
-    arma_inline void mem_setup();
-    
-    
-    public:
-    
-    static const uword n_rows = fixed_n_rows;
-    static const uword n_cols = fixed_n_cols;
-    static const uword n_elem = fixed_n_elem;
-    
-    
-    arma_inline fixed();
-    arma_inline fixed(const fixed<fixed_n_rows, fixed_n_cols>& X);
-    
-    template<typename T1>              inline fixed(const Base<eT,T1>& A);
-    template<typename T1, typename T2> inline fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
-    
-    inline fixed(      eT* aux_mem, const bool copy_aux_mem = true);
-    inline fixed(const eT* aux_mem);
-    
-    inline fixed(const char*        text);
-    inline fixed(const std::string& text);
-    
-    // TODO: handling of initializer_list ?
-    
-    template<typename T1> inline const Mat& operator=(const Base<eT,T1>& A);
-    
-    inline const Mat& operator=(const eT val);
-    inline const Mat& operator=(const char*        text);
-    inline const Mat& operator=(const std::string& text);
-    
-    
-    inline       subview_row<eT> operator()(const uword  row_num, const span& col_span);
-    inline const subview_row<eT> operator()(const uword  row_num, const span& col_span) const;
-    
-    inline       subview_col<eT> operator()(const span& row_span, const uword col_num);
-    inline const subview_col<eT> operator()(const span& row_span, const uword col_num) const;
-    
-    inline       subview<eT>     operator()(const span& row_span, const span& col_span);
-    inline const subview<eT>     operator()(const span& row_span, const span& col_span) const;
-    
-    
-    arma_inline arma_warn_unused eT& operator[] (const uword i);
-    arma_inline arma_warn_unused eT  operator[] (const uword i) const;
-    arma_inline arma_warn_unused eT& at         (const uword i);
-    arma_inline arma_warn_unused eT  at         (const uword i) const;
-    arma_inline arma_warn_unused eT& operator() (const uword i);
-    arma_inline arma_warn_unused eT  operator() (const uword i) const;
-    
-    arma_inline arma_warn_unused eT& at         (const uword in_row, const uword in_col);
-    arma_inline arma_warn_unused eT  at         (const uword in_row, const uword in_col) const;
-    arma_inline arma_warn_unused eT& operator() (const uword in_row, const uword in_col);
-    arma_inline arma_warn_unused eT  operator() (const uword in_row, const uword in_col) const;
-    
-    
-    arma_hot inline const Mat<eT>& fill(const eT val);
-    arma_hot inline const Mat<eT>& zeros();
-    arma_hot inline const Mat<eT>& ones();
-    };
-  
-  
-  protected:
-  
-  inline void init_cold();
-  inline void init_warm(uword in_rows, uword in_cols);
-  
-  inline void init(const std::string& text);
-  
-  #if defined(ARMA_USE_CXX11)
-  inline void init(const std::initializer_list<eT>& list);
-  #endif
-  
-  template<typename T1, typename T2>
-  inline void init(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
-  
-  inline void steal_mem(Mat& X);
-  
-  inline Mat(const char junk, const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols);
-  
-  friend class Cube<eT>;
-  friend class glue_join;
-  friend class op_strans;
-  friend class op_htrans;
-  friend class op_resize;
-  
-  
-  public:
-  
-  #ifdef ARMA_EXTRA_MAT_PROTO
-    #include ARMA_INCFILE_WRAP(ARMA_EXTRA_MAT_PROTO)
-  #endif
-  };
-
-
-
-class Mat_aux
-  {
-  public:
-
-  template<typename eT> arma_inline static void prefix_pp(Mat<eT>& x);
-  template<typename T>  arma_inline static void prefix_pp(Mat< std::complex<T> >& x);
-  
-  template<typename eT> arma_inline static void postfix_pp(Mat<eT>& x);
-  template<typename T>  arma_inline static void postfix_pp(Mat< std::complex<T> >& x);
-  
-  template<typename eT> arma_inline static void prefix_mm(Mat<eT>& x);
-  template<typename T>  arma_inline static void prefix_mm(Mat< std::complex<T> >& x);
-  
-  template<typename eT> arma_inline static void postfix_mm(Mat<eT>& x);
-  template<typename T>  arma_inline static void postfix_mm(Mat< std::complex<T> >& x);
-  
-  template<typename eT, typename T1> inline static void set_real(Mat<eT>&                out, const Base<eT,T1>& X);
-  template<typename T,  typename T1> inline static void set_real(Mat< std::complex<T> >& out, const Base< T,T1>& X);
-  
-  template<typename eT, typename T1> inline static void set_imag(Mat<eT>&                out, const Base<eT,T1>& X);
-  template<typename T,  typename T1> inline static void set_imag(Mat< std::complex<T> >& out, const Base< T,T1>& X);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Mat_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6096 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Mat
-//! @{
-
-
-template<typename eT>
-inline
-Mat<eT>::~Mat()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  if(mem_state == 0)
-    {
-    if(n_elem > arma_config::mat_prealloc)
-      {
-      #if defined(ARMA_USE_TBB_ALLOC)
-        scalable_free((void *)(mem));
-      #else
-        delete [] mem;
-      #endif
-      }
-    }
-    
-  if(arma_config::debug == true)
-    {
-    // try to expose buggy user code that accesses deleted objects
-    access::rw(n_rows) = 0;
-    access::rw(n_cols) = 0;
-    access::rw(n_elem) = 0;
-    access::rw(mem)    = 0;
-    }
-  
-  arma_type_check(( is_supported_elem_type<eT>::value == false ));
-  }
-
-
-
-template<typename eT>
-inline
-Mat<eT>::Mat()
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  }
-
-
-
-//! construct the matrix to have user specified dimensions
-template<typename eT>
-inline
-Mat<eT>::Mat(const uword in_n_rows, const uword in_n_cols)
-  : n_rows(in_n_rows)
-  , n_cols(in_n_cols)
-  , n_elem(in_n_rows*in_n_cols)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init_cold();
-  }
-
-
-
-template<typename eT>
-inline
-void
-Mat<eT>::init_cold()
-  {
-  arma_extra_debug_sigprint( arma_boost::format("n_rows = %d, n_cols = %d") % n_rows % n_cols );
-  
-  // ensure that n_elem can hold the result of (n_rows * n_cols)
-  
-  arma_debug_check
-    (
-      (
-      ( (n_rows > ARMA_MAX_UHWORD) || (n_cols > ARMA_MAX_UHWORD) )
-        ? ( (float(n_rows) * float(n_cols)) > float(ARMA_MAX_UWORD) )
-        : false
-      ),
-    "Mat::init(): requested size is too large"
-    );
-  
-  if(n_elem <= arma_config::mat_prealloc)
-    {
-    access::rw(mem) = mem_local;
-    }
-  else
-    {
-    arma_extra_debug_print("Mat::init(): allocating memory");
-    
-    #if defined(ARMA_USE_TBB_ALLOC)
-      access::rw(mem) = (eT *) scalable_malloc(sizeof(eT)*n_elem);
-    #else
-      access::rw(mem) = new(std::nothrow) eT[n_elem];
-    #endif
-    
-    arma_check_bad_alloc( (mem == 0), "Mat::init(): out of memory" );
-    }
-  }
-
-
-
-//! internal matrix construction; if the requested size is small enough, memory from the stack is used. otherwise memory is allocated via 'new'
-template<typename eT>
-inline
-void
-Mat<eT>::init_warm(uword in_n_rows, uword in_n_cols)
-  {
-  arma_extra_debug_sigprint( arma_boost::format("in_n_rows = %d, in_n_cols = %d") % in_n_rows % in_n_cols );
-  
-  if( (n_rows == in_n_rows) && (n_cols == in_n_cols) )
-    {
-    return;
-    }
-  
-  bool  err_state = false;
-  char* err_msg   = 0;
-  
-  const uhword t_vec_state = vec_state;
-  const uhword t_mem_state = mem_state;
-  
-  arma_debug_set_error
-    (
-    err_state,
-    err_msg,
-    (t_mem_state == 3),
-    "Mat::init(): size is fixed and hence cannot be changed"
-    );
-  
-  if(t_vec_state > 0)
-    {
-    if( (in_n_rows == 0) && (in_n_cols == 0) )
-      {
-      if(t_vec_state == 1)
-        {
-        in_n_cols = 1;
-        }
-      else
-      if(t_vec_state == 2)
-        {
-        in_n_rows = 1;
-        }
-      }
-    else
-      {
-      arma_debug_set_error
-        (
-        err_state,
-        err_msg,
-        ( ((t_vec_state == 1) && (in_n_cols != 1)) || ((t_vec_state == 2) && (in_n_rows != 1)) ),
-        "Mat::init(): object is a vector; requested size is not compatible"
-        );
-      }
-    }
-  
-  // ensure that n_elem can hold the result of (n_rows * n_cols)
-  
-  arma_debug_set_error
-    (
-    err_state,
-    err_msg,
-      (
-      ( (in_n_rows > ARMA_MAX_UHWORD) || (in_n_cols > ARMA_MAX_UHWORD) )
-        ? ( (float(in_n_rows) * float(in_n_cols)) > float(ARMA_MAX_UWORD) )
-        : false
-      ),
-    "Mat::init(): requested size is too large"
-    );
-  
-  arma_debug_check(err_state, err_msg);
-  
-  const uword old_n_elem = n_elem;
-  const uword new_n_elem = in_n_rows * in_n_cols;
-  
-  if(old_n_elem == new_n_elem)
-    {
-    arma_extra_debug_print("Mat::init(): reusing memory");
-    
-    access::rw(n_rows) = in_n_rows;
-    access::rw(n_cols) = in_n_cols;
-    }
-  else
-    {
-    arma_debug_check
-      (
-      (t_mem_state == 2),
-      "Mat::init(): mismatch between size of auxiliary memory and requested size"
-      );
-    
-    if(t_mem_state == 0)
-      {
-      if(old_n_elem > arma_config::mat_prealloc)
-        {
-        arma_extra_debug_print("Mat::init(): freeing memory");
-        
-        #if defined(ARMA_USE_TBB_ALLOC)
-          scalable_free((void *)(mem));
-        #else
-          delete [] mem;
-        #endif
-        }
-      }
-    
-    
-    if(new_n_elem <= arma_config::mat_prealloc)
-      {
-      access::rw(mem) = mem_local;
-      }
-    else
-      {
-      arma_extra_debug_print("Mat::init(): allocating memory");
-      
-      #if defined(ARMA_USE_TBB_ALLOC)
-        access::rw(mem) = (eT *) scalable_malloc(sizeof(eT)*new_n_elem);
-      #else
-        access::rw(mem) = new(std::nothrow) eT[new_n_elem];
-      #endif
-      
-      arma_check_bad_alloc( (mem == 0), "Mat::init(): out of memory" );
-      }
-    
-    access::rw(n_rows)    = in_n_rows;
-    access::rw(n_cols)    = in_n_cols;
-    access::rw(n_elem)    = new_n_elem;
-    access::rw(mem_state) = 0;
-    }
-  }
-
-
-
-//! create the matrix from a textual description
-template<typename eT>
-inline
-Mat<eT>::Mat(const char* text)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init( std::string(text) );
-  }
-  
-  
-  
-//! create the matrix from a textual description
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const char* text)
-  {
-  arma_extra_debug_sigprint();
-  
-  init( std::string(text) );
-  return *this;
-  }
-  
-  
-
-//! create the matrix from a textual description
-template<typename eT>
-inline
-Mat<eT>::Mat(const std::string& text)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init(text);
-  }
-  
-  
-  
-//! create the matrix from a textual description
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const std::string& text)
-  {
-  arma_extra_debug_sigprint();
-  
-  init(text);
-  return *this;
-  }
-
-
-
-//! internal function to create the matrix from a textual description
-template<typename eT>
-inline 
-void
-Mat<eT>::init(const std::string& text)
-  {
-  arma_extra_debug_sigprint();
-  
-  //
-  // work out the size
-  
-  uword t_n_rows = 0;
-  uword t_n_cols = 0;
-  
-  bool t_n_cols_found = false;
-  
-  std::string token;
-  
-  std::string::size_type line_start = 0;
-  std::string::size_type   line_end = 0;
-  
-  while( line_start < text.length() )
-    {
-    
-    line_end = text.find(';', line_start);
-    
-    if(line_end == std::string::npos)
-      line_end = text.length()-1;
-    
-    std::string::size_type line_len = line_end - line_start + 1;
-    std::stringstream line_stream( text.substr(line_start,line_len) );
-    
-    
-    uword line_n_cols = 0;
-    while(line_stream >> token)
-      {
-      ++line_n_cols;
-      }
-    
-    
-    if(line_n_cols > 0)
-      {
-      if(t_n_cols_found == false)
-        {
-        t_n_cols = line_n_cols;
-        t_n_cols_found = true;
-        }
-      else
-        arma_check( (line_n_cols != t_n_cols), "Mat::init(): inconsistent number of columns in given string");
-      
-      ++t_n_rows;
-      }
-    line_start = line_end+1;
-    
-    }
-    
-  Mat<eT>& x = *this;
-  x.set_size(t_n_rows, t_n_cols);
-  
-  line_start = 0;
-  line_end = 0;
-  
-  uword row = 0;
-  
-  while( line_start < text.length() )
-    {
-    
-    line_end = text.find(';', line_start);
-    
-    if(line_end == std::string::npos)
-      line_end = text.length()-1;
-    
-    std::string::size_type line_len = line_end - line_start + 1;
-    std::stringstream line_stream( text.substr(line_start,line_len) );
-    
-//     uword col = 0;
-//     while(line_stream >> token)
-//       {
-//       x.at(row,col) = strtod(token.c_str(), 0);
-//       ++col;
-//       }
-    
-    uword col = 0;
-    eT val;
-    while(line_stream >> val)
-      {
-      x.at(row,col) = val;
-      ++col;
-      }
-    
-    ++row;
-    line_start = line_end+1;
-    }
-  
-  }
-
-
-
-#if defined(ARMA_USE_CXX11)
-
-template<typename eT>
-inline
-Mat<eT>::Mat(const std::initializer_list<eT>& list)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init(list);
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const std::initializer_list<eT>& list)
-  {
-  arma_extra_debug_sigprint();
-  
-  init(list);
-  
-  return *this;
-  }
-  
-#endif
-  
-
-
-//! Set the matrix to be equal to the specified scalar.
-//! NOTE: the size of the matrix will be 1x1
-template<typename eT>
-arma_inline
-const Mat<eT>&
-Mat<eT>::operator=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  init_warm(1,1);
-  access::rw(mem[0]) = val;
-  return *this;
-  }
-
-
-
-//! In-place addition of a scalar to all elements of the matrix
-template<typename eT>
-arma_inline
-const Mat<eT>&
-Mat<eT>::operator+=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_plus( memptr(), val, n_elem );
-  
-  return *this;
-  }
-
-
-
-//! In-place subtraction of a scalar from all elements of the matrix
-template<typename eT>
-arma_inline
-const Mat<eT>&
-Mat<eT>::operator-=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_minus( memptr(), val, n_elem );
-  
-  return *this;
-  }
-
-
-
-//! In-place multiplication of all elements of the matrix with a scalar
-template<typename eT>
-arma_inline
-const Mat<eT>&
-Mat<eT>::operator*=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_mul( memptr(), val, n_elem );
-  
-  return *this;
-  }
-
-
-
-//! In-place division of all elements of the matrix with a scalar
-template<typename eT>
-arma_inline
-const Mat<eT>&
-Mat<eT>::operator/=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_div( memptr(), val, n_elem );
-  
-  return *this;
-  }
-
-
-
-//! construct a matrix from a given matrix
-template<typename eT>
-inline
-Mat<eT>::Mat(const Mat<eT>& in_mat)
-  : n_rows(in_mat.n_rows)
-  , n_cols(in_mat.n_cols)
-  , n_elem(in_mat.n_elem)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint(arma_boost::format("this = %x   in_mat = %x") % this % &in_mat);
-  
-  init_cold();
-  
-  arrayops::copy( memptr(), in_mat.mem, in_mat.n_elem );
-  }
-
-
-
-//! construct a matrix from a given matrix
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const Mat<eT>& in_mat)
-  {
-  arma_extra_debug_sigprint(arma_boost::format("this = %x   in_mat = %x") % this % &in_mat);
-  
-  if(this != &in_mat)
-    {
-    init_warm(in_mat.n_rows, in_mat.n_cols);
-    
-    arrayops::copy( memptr(), in_mat.mem, in_mat.n_elem );
-    }
-  
-  return *this;
-  }
-
-
-
-#if defined(ARMA_USE_CXX11)
-
-template<typename eT>
-inline
-void
-Mat<eT>::init(const std::initializer_list<eT>& list)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword N = list.size();
-  
-  set_size(1, N);
-  
-  arrayops::copy( memptr(), list.begin(), N );
-  }
-
-#endif
-
-
-
-//! for constructing a complex matrix out of two non-complex matrices
-template<typename eT>
-template<typename T1, typename T2>
-inline
-void
-Mat<eT>::init
-  (
-  const Base<typename Mat<eT>::pod_type, T1>& A,
-  const Base<typename Mat<eT>::pod_type, T2>& B
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type      T;
-  typedef typename Proxy<T1>::ea_type ea_type1;
-  typedef typename Proxy<T2>::ea_type ea_type2;
-  
-  arma_type_check(( is_complex<eT>::value == false ));   //!< compile-time abort if eT isn't std::complex
-  arma_type_check(( is_complex< T>::value == true  ));   //!< compile-time abort if T is std::complex
-  
-  arma_type_check(( is_same_type< std::complex<T>, eT >::value == false ));   //!< compile-time abort if types are not compatible
-  
-  const Proxy<T1> X(A.get_ref());
-  const Proxy<T2> Y(B.get_ref());
-  
-  arma_assert_same_size(X, Y, "Mat()");
-  
-  init_warm(X.get_n_rows(), X.get_n_cols());
-  
-  const uword    N       = n_elem;
-        eT*      out_mem = memptr();
-        ea_type1 PX      = X.get_ea();
-        ea_type2 PY      = Y.get_ea();
-  
-  for(uword i=0; i<N; ++i)
-    {
-    out_mem[i] = std::complex<T>(PX[i], PY[i]);
-    }
-  }
-
-
-
-//! try to steal the memory from a given matrix; 
-//! if memory can't be stolen, copy the given matrix
-template<typename eT>
-inline
-void
-Mat<eT>::steal_mem(Mat<eT>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(this != &x)
-    {
-    const uword x_n_rows    = x.n_rows;
-    const uword x_n_cols    = x.n_cols;
-    const uword x_n_elem    = x.n_elem;
-    const uword x_vec_state = x.vec_state;
-    const uword x_mem_state = x.mem_state;
-    
-    const uword t_vec_state = vec_state;
-    
-    bool layout_ok = false;
-    
-    if(t_vec_state == x_vec_state)
-      {
-      layout_ok = true;
-      }
-    else
-      {
-      if( (t_vec_state == 1) && ( x_n_cols == 1) )
-        {
-        layout_ok = true;
-        }
-      
-      if( (t_vec_state == 2) && ( x_n_rows == 1) )
-        {
-        layout_ok = true;
-        }
-      }
-    
-    
-    if( (x_mem_state == 0) && (x_n_elem > arma_config::mat_prealloc) && (layout_ok == true) )
-      {
-      reset();
-      // note: calling reset() also prevents fixed size matrices from changing size or using non-local memory
-      
-      access::rw(n_rows) = x_n_rows;
-      access::rw(n_cols) = x_n_cols;
-      access::rw(n_elem) = x_n_elem;
-      access::rw(mem)    = x.mem;
-      
-      access::rw(x.n_rows) = 0;
-      access::rw(x.n_cols) = 0;
-      access::rw(x.n_elem) = 0;
-      access::rw(x.mem)    = 0;
-      }
-    else
-      {
-      (*this).operator=(x);
-      }
-    }
-  }
-
-
-
-//! construct a matrix from a given auxiliary array of eTs.
-//! if copy_aux_mem is true, new memory is allocated and the array is copied.
-//! if copy_aux_mem is false, the auxiliary array is used directly (without allocating memory and copying).
-//! the default is to copy the array.
-
-template<typename eT>
-inline
-Mat<eT>::Mat(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const bool copy_aux_mem, const bool strict)
-  : n_rows   ( aux_n_rows                            )
-  , n_cols   ( aux_n_cols                            )
-  , n_elem   ( aux_n_rows*aux_n_cols                 )
-  , vec_state( 0                                     )
-  , mem_state( copy_aux_mem ? 0 : ( strict ? 2 : 1 ) )
-  , mem      ( copy_aux_mem ? 0 : aux_mem            )
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  if(copy_aux_mem == true)
-    {
-    init_cold();
-    
-    arrayops::copy( memptr(), aux_mem, n_elem );
-    }
-  }
-
-
-
-//! construct a matrix from a given auxiliary read-only array of eTs.
-//! the array is copied.
-template<typename eT>
-inline
-Mat<eT>::Mat(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols)
-  : n_rows(aux_n_rows)
-  , n_cols(aux_n_cols)
-  , n_elem(aux_n_rows*aux_n_cols)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init_cold();
-  
-  arrayops::copy( memptr(), aux_mem, n_elem );
-  }
-
-
-
-//! DANGEROUS! Construct a temporary matrix, using auxiliary memory.
-//! This constructor is NOT intended for usage by user code.
-//! Its sole purpose is to be used by the Cube class.
-
-template<typename eT>
-inline
-Mat<eT>::Mat(const char junk, const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols)
-  : n_rows   (aux_n_rows           )
-  , n_cols   (aux_n_cols           )
-  , n_elem   (aux_n_rows*aux_n_cols)
-  , vec_state(0                    )
-  , mem_state(3                    )
-  , mem      (aux_mem              )
-  {
-  arma_extra_debug_sigprint_this(this);
-  arma_ignore(junk);
-  }
-
-
-
-//! in-place matrix addition
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const Mat<eT>& m)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(*this, m, "addition");
-  
-  arrayops::inplace_plus( memptr(), m.memptr(), n_elem );
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix subtraction
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const Mat<eT>& m)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(*this, m, "subtraction");
-  
-  arrayops::inplace_minus( memptr(), m.memptr(), n_elem );
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix multiplication
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator*=(const Mat<eT>& m)
-  {
-  arma_extra_debug_sigprint();
-  
-  glue_times::apply_inplace(*this, m);
-  
-  return *this;
-  }
-
-
-
-//! in-place element-wise matrix multiplication
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator%=(const Mat<eT>& m)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(*this, m, "element-wise multiplication");
-  
-  arrayops::inplace_mul( memptr(), m.memptr(), n_elem );
-  
-  return *this;
-  }
-
-
-
-//! in-place element-wise matrix division
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator/=(const Mat<eT>& m)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(*this, m, "element-wise division");
-  
-  arrayops::inplace_div( memptr(), m.memptr(), n_elem );
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-Mat<eT>::Mat(const BaseCube<eT,T1>& X)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  (*this).operator=(X);
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const BaseCube<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>& out = *this;
-  
-  const unwrap_cube<T1> tmp(X.get_ref());
-  const Cube<eT>& in  = tmp.M;
-  
-  arma_debug_assert_cube_as_mat(out, in, "copy into matrix", false);
-  
-  const uword in_n_rows   = in.n_rows;
-  const uword in_n_cols   = in.n_cols;
-  const uword in_n_slices = in.n_slices;
-  
-  const uword out_vec_state = out.vec_state;
-  
-  if(in_n_slices == 1)
-    {
-    out.set_size(in_n_rows, in_n_cols);
-    
-    for(uword col=0; col < in_n_cols; ++col)
-      {
-      arrayops::copy( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
-      }
-    }
-  else
-    {
-    if(out_vec_state == 0)
-      {
-      if(in_n_cols == 1)
-        {
-        out.set_size(in_n_rows, in_n_slices);
-        
-        for(uword i=0; i < in_n_slices; ++i)
-          {
-          arrayops::copy( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
-          }
-        }
-      else
-      if(in_n_rows == 1)
-        {
-        out.set_size(in_n_cols, in_n_slices);
-        
-        for(uword slice=0; slice < in_n_slices; ++slice)
-          {
-          eT* out_colptr = out.colptr(slice);
-          
-          uword i,j;
-          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
-            {
-            const eT tmp_i = in.at(0, i, slice);
-            const eT tmp_j = in.at(0, j, slice);
-            
-            out_colptr[i] = tmp_i;
-            out_colptr[j] = tmp_j;
-            }
-          
-          if(i < in_n_cols)
-            {
-            out_colptr[i] = in.at(0, i, slice);
-            }
-          }
-        }
-      }
-    else
-      {
-      out.set_size(in_n_slices);
-      
-      eT* out_mem = out.memptr();
-      
-      for(uword i=0; i<in_n_slices; ++i)
-        {
-        out_mem[i] = in.at(0, 0, i);
-        }
-      }
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const BaseCube<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>& out = *this;
-  
-  const unwrap_cube<T1> tmp(X.get_ref());
-  const Cube<eT>& in  = tmp.M;
-  
-  arma_debug_assert_cube_as_mat(out, in, "addition", true);
-  
-  const uword in_n_rows   = in.n_rows;
-  const uword in_n_cols   = in.n_cols;
-  const uword in_n_slices = in.n_slices;
-  
-  const uword out_n_rows    = out.n_rows;
-  const uword out_n_cols    = out.n_cols;
-  const uword out_vec_state = out.vec_state;
-  
-  if(in_n_slices == 1)
-    {
-    for(uword col=0; col < in_n_cols; ++col)
-      {
-      arrayops::inplace_plus( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
-      }
-    }
-  else
-    {
-    if(out_vec_state == 0)
-      {
-      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
-        {
-        for(uword i=0; i < in_n_slices; ++i)
-          {
-          arrayops::inplace_plus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
-          }
-        }
-      else
-      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
-        {
-        for(uword slice=0; slice < in_n_slices; ++slice)
-          {
-          eT* out_colptr = out.colptr(slice);
-          
-          uword i,j;
-          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
-            {
-            const eT tmp_i = in.at(0, i, slice);
-            const eT tmp_j = in.at(0, j, slice);
-            
-            out_colptr[i] += tmp_i;
-            out_colptr[j] += tmp_j;
-            }
-          
-          if(i < in_n_cols)
-            {
-            out_colptr[i] += in.at(0, i, slice);
-            }
-          }
-        }
-      }
-    else
-      {
-      eT* out_mem = out.memptr();
-      
-      for(uword i=0; i<in_n_slices; ++i)
-        {
-        out_mem[i] += in.at(0, 0, i);
-        }
-      }
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const BaseCube<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>& out = *this;
-  
-  const unwrap_cube<T1> tmp(X.get_ref());
-  const Cube<eT>& in  = tmp.M;
-  
-  arma_debug_assert_cube_as_mat(out, in, "subtraction", true);
-  
-  const uword in_n_rows   = in.n_rows;
-  const uword in_n_cols   = in.n_cols;
-  const uword in_n_slices = in.n_slices;
-  
-  const uword out_n_rows    = out.n_rows;
-  const uword out_n_cols    = out.n_cols;
-  const uword out_vec_state = out.vec_state;
-  
-  if(in_n_slices == 1)
-    {
-    for(uword col=0; col < in_n_cols; ++col)
-      {
-      arrayops::inplace_minus( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
-      }
-    }
-  else
-    {
-    if(out_vec_state == 0)
-      {
-      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
-        {
-        for(uword i=0; i < in_n_slices; ++i)
-          {
-          arrayops::inplace_minus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
-          }
-        }
-      else
-      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
-        {
-        for(uword slice=0; slice < in_n_slices; ++slice)
-          {
-          eT* out_colptr = out.colptr(slice);
-          
-          uword i,j;
-          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
-            {
-            const eT tmp_i = in.at(0, i, slice);
-            const eT tmp_j = in.at(0, j, slice);
-            
-            out_colptr[i] -= tmp_i;
-            out_colptr[j] -= tmp_j;
-            }
-          
-          if(i < in_n_cols)
-            {
-            out_colptr[i] -= in.at(0, i, slice);
-            }
-          }
-        }
-      }
-    else
-      {
-      eT* out_mem = out.memptr();
-      
-      for(uword i=0; i<in_n_slices; ++i)
-        {
-        out_mem[i] -= in.at(0, 0, i);
-        }
-      }
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Mat<eT>&
-Mat<eT>::operator*=(const BaseCube<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> B(X);
-  
-  (*this).operator*=(B);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Mat<eT>&
-Mat<eT>::operator%=(const BaseCube<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>& out = *this;
-  
-  const unwrap_cube<T1> tmp(X.get_ref());
-  const Cube<eT>& in  = tmp.M;
-  
-  arma_debug_assert_cube_as_mat(out, in, "element-wise multiplication", true);
-  
-  const uword in_n_rows   = in.n_rows;
-  const uword in_n_cols   = in.n_cols;
-  const uword in_n_slices = in.n_slices;
-  
-  const uword out_n_rows    = out.n_rows;
-  const uword out_n_cols    = out.n_cols;
-  const uword out_vec_state = out.vec_state;
-  
-  if(in_n_slices == 1)
-    {
-    for(uword col=0; col < in_n_cols; ++col)
-      {
-      arrayops::inplace_mul( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
-      }
-    }
-  else
-    {
-    if(out_vec_state == 0)
-      {
-      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
-        {
-        for(uword i=0; i < in_n_slices; ++i)
-          {
-          arrayops::inplace_mul( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
-          }
-        }
-      else
-      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
-        {
-        for(uword slice=0; slice < in_n_slices; ++slice)
-          {
-          eT* out_colptr = out.colptr(slice);
-          
-          uword i,j;
-          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
-            {
-            const eT tmp_i = in.at(0, i, slice);
-            const eT tmp_j = in.at(0, j, slice);
-            
-            out_colptr[i] *= tmp_i;
-            out_colptr[j] *= tmp_j;
-            }
-          
-          if(i < in_n_cols)
-            {
-            out_colptr[i] *= in.at(0, i, slice);
-            }
-          }
-        }
-      }
-    else
-      {
-      eT* out_mem = out.memptr();
-      
-      for(uword i=0; i<in_n_slices; ++i)
-        {
-        out_mem[i] *= in.at(0, 0, i);
-        }
-      }
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Mat<eT>&
-Mat<eT>::operator/=(const BaseCube<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>& out = *this;
-  
-  const unwrap_cube<T1> tmp(X.get_ref());
-  const Cube<eT>& in  = tmp.M;
-  
-  arma_debug_assert_cube_as_mat(out, in, "element-wise division", true);
-  
-  const uword in_n_rows   = in.n_rows;
-  const uword in_n_cols   = in.n_cols;
-  const uword in_n_slices = in.n_slices;
-  
-  const uword out_n_rows    = out.n_rows;
-  const uword out_n_cols    = out.n_cols;
-  const uword out_vec_state = out.vec_state;
-  
-  if(in_n_slices == 1)
-    {
-    for(uword col=0; col < in_n_cols; ++col)
-      {
-      arrayops::inplace_div( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
-      }
-    }
-  else
-    {
-    if(out_vec_state == 0)
-      {
-      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
-        {
-        for(uword i=0; i < in_n_slices; ++i)
-          {
-          arrayops::inplace_div( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
-          }
-        }
-      else
-      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
-        {
-        for(uword slice=0; slice < in_n_slices; ++slice)
-          {
-          eT* out_colptr = out.colptr(slice);
-          
-          uword i,j;
-          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
-            {
-            const eT tmp_i = in.at(0, i, slice);
-            const eT tmp_j = in.at(0, j, slice);
-            
-            out_colptr[i] /= tmp_i;
-            out_colptr[j] /= tmp_j;
-            }
-          
-          if(i < in_n_cols)
-            {
-            out_colptr[i] /= in.at(0, i, slice);
-            }
-          }
-        }
-      }
-    else
-      {
-      eT* out_mem = out.memptr();
-      
-      for(uword i=0; i<in_n_slices; ++i)
-        {
-        out_mem[i] /= in.at(0, 0, i);
-        }
-      }
-    }
-  
-  return *this;
-  }
-
-
-
-//! for constructing a complex matrix out of two non-complex matrices
-template<typename eT>
-template<typename T1, typename T2>
-inline
-Mat<eT>::Mat
-  (
-  const Base<typename Mat<eT>::pod_type,T1>& A,
-  const Base<typename Mat<eT>::pod_type,T2>& B
-  )
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init(A,B);
-  }
-
-
-
-//! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation)
-template<typename eT>
-inline
-Mat<eT>::Mat(const subview<eT>& X)
-  : n_rows(X.n_rows)
-  , n_cols(X.n_cols)
-  , n_elem(X.n_elem)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init_cold();
-  
-  subview<eT>::extract(*this, X);
-  }
-
-
-
-//! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const subview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool alias = (this == &(X.m));
-  
-  if(alias == false)
-    {
-    init_warm(X.n_rows, X.n_cols);
-    
-    subview<eT>::extract(*this, X);
-    }
-  else
-    {
-    Mat<eT> tmp(X);
-    
-    steal_mem(tmp);
-    }
-  
-  return *this;
-  }
-
-
-//! in-place matrix addition (using a submatrix on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const subview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview<eT>::plus_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-//! in-place matrix subtraction (using a submatrix on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const subview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview<eT>::minus_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix mutiplication (using a submatrix on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator*=(const subview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  glue_times::apply_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place element-wise matrix mutiplication (using a submatrix on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator%=(const subview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview<eT>::schur_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place element-wise matrix division (using a submatrix on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator/=(const subview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview<eT>::div_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! construct a matrix from a subview_cube instance
-template<typename eT>
-inline
-Mat<eT>::Mat(const subview_cube<eT>& x)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  this->operator=(x);
-  }
-
-
-
-//! construct a matrix from a subview_cube instance
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_cube<eT>::extract(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix addition (using a single-slice subcube on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-
-  subview_cube<eT>::plus_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix subtraction (using a single-slice subcube on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_cube<eT>::minus_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix mutiplication (using a single-slice subcube on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator*=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-
-  const Mat<eT> tmp(X);
-  glue_times::apply_inplace(*this, tmp);
-  
-  return *this;
-  }
-
-
-
-//! in-place element-wise matrix mutiplication (using a single-slice subcube on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator%=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_cube<eT>::schur_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place element-wise matrix division (using a single-slice subcube on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator/=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_cube<eT>::div_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation)
-template<typename eT>
-inline
-Mat<eT>::Mat(const diagview<eT>& X)
-  : n_rows(X.n_rows)
-  , n_cols(X.n_cols)
-  , n_elem(X.n_elem)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init_cold();
-  
-  diagview<eT>::extract(*this, X);
-  }
-
-
-
-//! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool alias = (this == &(X.m));
-  
-  if(alias == false)
-    {
-    init_warm(X.n_rows, X.n_cols);
-    
-    diagview<eT>::extract(*this, X);
-    }
-  else
-    {
-    Mat<eT> tmp(X);
-    
-    steal_mem(tmp);
-    }
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix addition (using a diagview on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  diagview<eT>::plus_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-//! in-place matrix subtraction (using a diagview on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  diagview<eT>::minus_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix mutiplication (using a diagview on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator*=(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  glue_times::apply_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place element-wise matrix mutiplication (using a diagview on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator%=(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  diagview<eT>::schur_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place element-wise matrix division (using a diagview on the right-hand-side)
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::operator/=(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  diagview<eT>::div_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-Mat<eT>::Mat(const subview_elem1<eT,T1>& X)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  this->operator=(X);
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const subview_elem1<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_elem1<eT,T1>::extract(*this, X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const subview_elem1<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_elem1<eT,T1>::plus_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const subview_elem1<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_elem1<eT,T1>::minus_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Mat<eT>&
-Mat<eT>::operator*=(const subview_elem1<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  glue_times::apply_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Mat<eT>&
-Mat<eT>::operator%=(const subview_elem1<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_elem1<eT,T1>::schur_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Mat<eT>&
-Mat<eT>::operator/=(const subview_elem1<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_elem1<eT,T1>::div_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-mat_injector< Mat<eT> >
-Mat<eT>::operator<<(const eT val)
-  {
-  return mat_injector< Mat<eT> >(*this, val);
-  }
-
-
-
-template<typename eT>
-inline
-mat_injector< Mat<eT> >
-Mat<eT>::operator<<(const injector_end_of_row& x)
-  {
-  return mat_injector< Mat<eT> >(*this, x);
-  }
-
-
-
-//! creation of subview (row vector)
-template<typename eT>
-arma_inline
-subview_row<eT>
-Mat<eT>::row(const uword row_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( row_num >= n_rows, "Mat::row(): out of bounds" );
-  
-  return subview_row<eT>(*this, row_num);
-  }
-
-
-
-//! creation of subview (row vector)
-template<typename eT>
-arma_inline
-const subview_row<eT>
-Mat<eT>::row(const uword row_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( row_num >= n_rows, "Mat::row(): out of bounds" );
-  
-  return subview_row<eT>(*this, row_num);
-  }
-
-
-
-template<typename eT>
-inline
-subview_row<eT>
-Mat<eT>::operator()(const uword row_num, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool col_all = col_span.whole;
-  
-  const uword local_n_cols = n_cols;
-  
-  const uword in_col1       = col_all ? 0            : col_span.a;
-  const uword in_col2       =                          col_span.b;
-  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
-  
-  arma_debug_check
-    (
-    (row_num >= n_rows)
-    ||
-    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
-    ,
-    "Mat::operator(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview_row<eT>(*this, row_num, in_col1, submat_n_cols);
-  }
-
-
-
-template<typename eT>
-inline
-const subview_row<eT>
-Mat<eT>::operator()(const uword row_num, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool col_all = col_span.whole;
-  
-  const uword local_n_cols = n_cols;
-  
-  const uword in_col1       = col_all ? 0            : col_span.a;
-  const uword in_col2       =                          col_span.b;
-  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
-  
-  arma_debug_check
-    (
-    (row_num >= n_rows)
-    ||
-    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
-    ,
-    "Mat::operator(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview_row<eT>(*this, row_num, in_col1, submat_n_cols);
-  }
-
-
-
-//! creation of subview (column vector)
-template<typename eT>
-arma_inline
-subview_col<eT>
-Mat<eT>::col(const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( col_num >= n_cols, "Mat::col(): out of bounds");
-  
-  return subview_col<eT>(*this, col_num);
-  }
-
-
-
-//! creation of subview (column vector)
-template<typename eT>
-arma_inline
-const subview_col<eT>
-Mat<eT>::col(const uword col_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( col_num >= n_cols, "Mat::col(): out of bounds");
-  
-  return subview_col<eT>(*this, col_num);
-  }
-
-
-
-template<typename eT>
-inline
-subview_col<eT>
-Mat<eT>::operator()(const span& row_span, const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all = row_span.whole;
-  
-  const uword local_n_rows = n_rows;
-  
-  const uword in_row1       = row_all ? 0            : row_span.a;
-  const uword in_row2       =                          row_span.b;
-  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
-  
-  arma_debug_check
-    (
-    (col_num >= n_cols)
-    ||
-    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
-    ,
-    "Mat::operator(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview_col<eT>(*this, col_num, in_row1, submat_n_rows);
-  }
-
-
-
-template<typename eT>
-inline
-const subview_col<eT>
-Mat<eT>::operator()(const span& row_span, const uword col_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all = row_span.whole;
-  
-  const uword local_n_rows = n_rows;
-  
-  const uword in_row1       = row_all ? 0            : row_span.a;
-  const uword in_row2       =                          row_span.b;
-  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
-  
-  arma_debug_check
-    (
-    (col_num >= n_cols)
-    ||
-    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
-    ,
-    "Mat::operator(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview_col<eT>(*this, col_num, in_row1, submat_n_rows);
-  }
-
-
-
-//! create a Col object which uses memory from an existing matrix object.
-//! this approach is currently not alias safe
-//! and does not take into account that the parent matrix object could be deleted.
-//! if deleted memory is accessed by the created Col object,
-//! it will cause memory corruption and/or a crash
-template<typename eT>
-inline
-Col<eT>
-Mat<eT>::unsafe_col(const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( col_num >= n_cols, "Mat::unsafe_col(): out of bounds");
-  
-  return Col<eT>(colptr(col_num), n_rows, false, true);
-  }
-
-
-
-//! create a Col object which uses memory from an existing matrix object.
-//! this approach is currently not alias safe
-//! and does not take into account that the parent matrix object could be deleted.
-//! if deleted memory is accessed by the created Col object,
-//! it will cause memory corruption and/or a crash
-template<typename eT>
-inline
-const Col<eT>
-Mat<eT>::unsafe_col(const uword col_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( col_num >= n_cols, "Mat::unsafe_col(): out of bounds");
-  
-  typedef const Col<eT> out_type;
-  
-  return out_type(const_cast<eT*>(colptr(col_num)), n_rows, false, true);
-  }
-
-
-
-//! creation of subview (submatrix comprised of specified row vectors)
-template<typename eT>
-arma_inline
-subview<eT>
-Mat<eT>::rows(const uword in_row1, const uword in_row2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 > in_row2) || (in_row2 >= n_rows),
-    "Mat::rows(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  
-  return subview<eT>(*this, in_row1, 0, subview_n_rows, n_cols );
-  }
-
-
-
-//! creation of subview (submatrix comprised of specified row vectors)
-template<typename eT>
-arma_inline
-const subview<eT>
-Mat<eT>::rows(const uword in_row1, const uword in_row2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 > in_row2) || (in_row2 >= n_rows),
-    "Mat::rows(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  
-  return subview<eT>(*this, in_row1, 0, subview_n_rows, n_cols );
-  }
-
-
-
-//! creation of subview (submatrix comprised of specified column vectors)
-template<typename eT>
-arma_inline
-subview<eT>
-Mat<eT>::cols(const uword in_col1, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_col1 > in_col2) || (in_col2 >= n_cols),
-    "Mat::cols(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  return subview<eT>(*this, 0, in_col1, n_rows, subview_n_cols);
-  }
-
-
-
-//! creation of subview (submatrix comprised of specified column vectors)
-template<typename eT>
-arma_inline
-const subview<eT>
-Mat<eT>::cols(const uword in_col1, const uword in_col2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_col1 > in_col2) || (in_col2 >= n_cols),
-    "Mat::cols(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  return subview<eT>(*this, 0, in_col1, n_rows, subview_n_cols);
-  }
-
-
-
-//! creation of subview (submatrix)
-template<typename eT>
-arma_inline
-subview<eT>
-Mat<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
-    "Mat::submat(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  return subview<eT>(*this, in_row1, in_col1, subview_n_rows, subview_n_cols);
-  }
-
-
-
-//! creation of subview (generic submatrix)
-template<typename eT>
-arma_inline
-const subview<eT>
-Mat<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
-    "Mat::submat(): indices out of bounds or incorrectly used"
-    );
-    
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  return subview<eT>(*this, in_row1, in_col1, subview_n_rows, subview_n_cols);
-  }
-
-
-
-//! creation of subview (submatrix)
-template<typename eT>
-inline
-subview<eT>
-Mat<eT>::submat(const span& row_span, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all = row_span.whole;
-  const bool col_all = col_span.whole;
-  
-  const uword local_n_rows = n_rows;
-  const uword local_n_cols = n_cols;
-  
-  const uword in_row1       = row_all ? 0            : row_span.a;
-  const uword in_row2       =                          row_span.b;
-  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
-  
-  const uword in_col1       = col_all ? 0            : col_span.a;
-  const uword in_col2       =                          col_span.b;
-  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
-  
-  arma_debug_check
-    (
-    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
-    ||
-    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
-    ,
-    "Mat::submat(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview<eT>(*this, in_row1, in_col1, submat_n_rows, submat_n_cols);
-  }
-
-
-
-//! creation of subview (generic submatrix)
-template<typename eT>
-inline
-const subview<eT>
-Mat<eT>::submat(const span& row_span, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all = row_span.whole;
-  const bool col_all = col_span.whole;
-  
-  const uword local_n_rows = n_rows;
-  const uword local_n_cols = n_cols;
-  
-  const uword in_row1       = row_all ? 0            : row_span.a;
-  const uword in_row2       =                          row_span.b;
-  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
-  
-  const uword in_col1       = col_all ? 0            : col_span.a;
-  const uword in_col2       =                          col_span.b;
-  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
-  
-  arma_debug_check
-    (
-    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
-    ||
-    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
-    ,
-    "Mat::submat(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview<eT>(*this, in_row1, in_col1, submat_n_rows, submat_n_cols);
-  }
-
-
-
-template<typename eT>
-inline
-subview<eT>
-Mat<eT>::operator()(const span& row_span, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).submat(row_span, col_span);
-  }
-
-
-
-template<typename eT>
-inline
-const subview<eT>
-Mat<eT>::operator()(const span& row_span, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).submat(row_span, col_span);
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-arma_inline
-subview_elem1<eT,T1>
-Mat<eT>::elem(const Base<uword,T1>& a)
-  {
-  arma_extra_debug_sigprint();
-  
-  return subview_elem1<eT,T1>(*this, a);
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-arma_inline
-const subview_elem1<eT,T1>
-Mat<eT>::elem(const Base<uword,T1>& a) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return subview_elem1<eT,T1>(*this, a);
-  }
-
-
-
-// template<typename eT>
-// template<typename T1, typename T2>
-// arma_inline
-// subview_elem2<eT,T1,T2>
-// Mat<eT>::elem(const Base<uword,T1>& a, const Base<uword,T2>& b)
-//   {
-//   arma_extra_debug_sigprint();
-//   
-//   return subview_elem2<eT,T1,T2>(*this, a, b);
-//   }
-// 
-// 
-// 
-// template<typename eT>
-// template<typename T1, typename T2>
-// arma_inline
-// const subview_elem2<eT,T1,T2>
-// Mat<eT>::elem(const Base<uword,T1>& a, const Base<uword,T2>& b) const
-//   {
-//   arma_extra_debug_sigprint();
-//   
-//   return subview_elem2<eT,T1,T2>(*this, a, b);
-//   }
-
-
-
-//! creation of diagview (diagonal)
-template<typename eT>
-arma_inline
-diagview<eT>
-Mat<eT>::diag(const sword in_id)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword row_offset = (in_id < 0) ? uword(-in_id) : 0;
-  const uword col_offset = (in_id > 0) ? uword( in_id) : 0;
-  
-  arma_debug_check
-    (
-    ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
-    "Mat::diag(): requested diagonal out of bounds"
-    );
-  
-  const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
-  
-  return diagview<eT>(*this, row_offset, col_offset, len);
-  }
-
-
-
-//! creation of diagview (diagonal)
-template<typename eT>
-arma_inline
-const diagview<eT>
-Mat<eT>::diag(const sword in_id) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword row_offset = (in_id < 0) ? -in_id : 0;
-  const uword col_offset = (in_id > 0) ?  in_id : 0;
-  
-  arma_debug_check
-    (
-    ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
-    "Mat::diag(): requested diagonal out of bounds"
-    );
-  
-  const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
-  
-  return diagview<eT>(*this, row_offset, col_offset, len);
-  }
-
-
-
-template<typename eT>
-inline
-void
-Mat<eT>::swap_rows(const uword in_row1, const uword in_row2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 >= n_rows) || (in_row2 >= n_rows),
-    "Mat::swap_rows(): out of bounds"
-    );
-  
-  for(uword col=0; col<n_cols; ++col)
-    {
-    const uword offset = col*n_rows;
-    const uword pos1   = in_row1 + offset;
-    const uword pos2   = in_row2 + offset;
-    
-    const eT tmp          = mem[pos1];
-    access::rw(mem[pos1]) = mem[pos2];
-    access::rw(mem[pos2]) = tmp;
-    }
-  
-  }
-
-
-
-template<typename eT>
-inline
-void
-Mat<eT>::swap_cols(const uword in_col1, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_col1 >= n_cols) || (in_col2 >= n_cols),
-    "Mat::swap_cols(): out of bounds"
-    );
-  
-  if(n_elem > 0)
-    {
-    eT* ptr1 = colptr(in_col1);
-    eT* ptr2 = colptr(in_col2);
-    
-    for(uword row=0; row<n_rows; ++row)
-      {
-      const eT tmp = ptr1[row];
-      ptr1[row]    = ptr2[row];
-      ptr2[row]    = tmp;
-      }
-    }
-  }
-
-
-
-//! remove specified row
-template<typename eT>
-inline
-void
-Mat<eT>::shed_row(const uword row_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( row_num >= n_rows, "Mat::shed_row(): out of bounds");
-  
-  shed_rows(row_num, row_num);
-  }
-
-
-
-//! remove specified column
-template<typename eT>
-inline
-void
-Mat<eT>::shed_col(const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( col_num >= n_cols, "Mat::shed_col(): out of bounds");
-  
-  shed_cols(col_num, col_num);
-  }
-
-
-
-//! remove specified rows
-template<typename eT>
-inline
-void
-Mat<eT>::shed_rows(const uword in_row1, const uword in_row2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 > in_row2) || (in_row2 >= n_rows),
-    "Mat::shed_rows(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword n_keep_front = in_row1;
-  const uword n_keep_back  = n_rows - (in_row2 + 1);
-  
-  Mat<eT> X(n_keep_front + n_keep_back, n_cols);
-  
-  if(n_keep_front > 0)
-    {
-    X.rows( 0, (n_keep_front-1) ) = rows( 0, (in_row1-1) );
-    }
-  
-  if(n_keep_back > 0)
-    {
-    X.rows( n_keep_front,  (n_keep_front+n_keep_back-1) ) = rows( (in_row2+1), (n_rows-1) );
-    }
-  
-  steal_mem(X);
-  }
-
-
-
-//! remove specified columns
-template<typename eT>
-inline
-void
-Mat<eT>::shed_cols(const uword in_col1, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_col1 > in_col2) || (in_col2 >= n_cols),
-    "Mat::shed_cols(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword n_keep_front = in_col1;
-  const uword n_keep_back  = n_cols - (in_col2 + 1);
-  
-  Mat<eT> X(n_rows, n_keep_front + n_keep_back);
-  
-  if(n_keep_front > 0)
-    {
-    X.cols( 0, (n_keep_front-1) ) = cols( 0, (in_col1-1) );
-    }
-  
-  if(n_keep_back > 0)
-    {
-    X.cols( n_keep_front,  (n_keep_front+n_keep_back-1) ) = cols( (in_col2+1), (n_cols-1) );
-    }
-  
-  steal_mem(X);
-  }
-
-
-
-//! insert N rows at the specified row position,
-//! optionally setting the elements of the inserted rows to zero
-template<typename eT>
-inline
-void
-Mat<eT>::insert_rows(const uword row_num, const uword N, const bool set_to_zero)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword t_n_rows = n_rows;
-  const uword t_n_cols = n_cols;
-  
-  const uword A_n_rows = row_num;
-  const uword B_n_rows = t_n_rows - row_num;
-  
-  // insertion at row_num == n_rows is in effect an append operation
-  arma_debug_check( (row_num > t_n_rows), "Mat::insert_rows(): out of bounds");
-  
-  if(N > 0)
-    {
-    Mat<eT> out(t_n_rows + N, t_n_cols);
-    
-    if(A_n_rows > 0)
-      {
-      out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1);
-      }
-    
-    if(B_n_rows > 0)
-      {
-      out.rows(row_num + N, t_n_rows + N - 1) = rows(row_num, t_n_rows-1);
-      }
-    
-    if(set_to_zero == true)
-      {
-      out.rows(row_num, row_num + N - 1).zeros();
-      }
-    
-    steal_mem(out);
-    }
-  }
-
-
-
-//! insert N columns at the specified column position,
-//! optionally setting the elements of the inserted columns to zero
-template<typename eT>
-inline
-void
-Mat<eT>::insert_cols(const uword col_num, const uword N, const bool set_to_zero)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword t_n_rows = n_rows;
-  const uword t_n_cols = n_cols;
-  
-  const uword A_n_cols = col_num;
-  const uword B_n_cols = t_n_cols - col_num;
-  
-  // insertion at col_num == n_cols is in effect an append operation
-  arma_debug_check( (col_num > t_n_cols), "Mat::insert_cols(): out of bounds");
-  
-  if(N > 0)
-    {
-    Mat<eT> out(t_n_rows, t_n_cols + N);
-    
-    if(A_n_cols > 0)
-      {
-      out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1);
-      }
-    
-    if(B_n_cols > 0)
-      {
-      out.cols(col_num + N, t_n_cols + N - 1) = cols(col_num, t_n_cols-1);
-      }
-    
-    if(set_to_zero == true)
-      {
-      out.cols(col_num, col_num + N - 1).zeros();
-      }
-    
-    steal_mem(out);
-    }
-  }
-
-
-
-//! insert the given object at the specified row position; 
-//! the given object must have the same number of columns as the matrix
-template<typename eT>
-template<typename T1>
-inline
-void
-Mat<eT>::insert_rows(const uword row_num, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1>   tmp(X.get_ref());
-  const Mat<eT>& C = tmp.M;
-  
-  const uword C_n_rows = C.n_rows;
-  const uword C_n_cols = C.n_cols;
-  
-  const uword t_n_rows = n_rows;
-  const uword t_n_cols = n_cols;
-  
-  const uword A_n_rows = row_num;
-  const uword B_n_rows = t_n_rows - row_num;
-  
-  bool  err_state = false;
-  char* err_msg   = 0;
-  
-  // insertion at row_num == n_rows is in effect an append operation
-  
-  arma_debug_set_error
-    (
-    err_state,
-    err_msg,
-    (row_num > t_n_rows),
-    "Mat::insert_rows(): out of bounds"
-    );
-  
-  arma_debug_set_error
-    (
-    err_state,
-    err_msg,
-    ( (C_n_cols != t_n_cols) && ( (t_n_rows > 0) || (t_n_cols > 0) ) && ( (C_n_rows > 0) || (C_n_cols > 0) ) ),
-    "Mat::insert_rows(): given object has an incompatible number of columns"
-    );
-  
-  arma_debug_check(err_state, err_msg);
-  
-  if(C_n_rows > 0)
-    {
-    Mat<eT> out( t_n_rows + C_n_rows, (std::max)(t_n_cols, C_n_cols) );
-    
-    if(t_n_cols > 0)
-      {
-      if(A_n_rows > 0)
-        {
-        out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1);
-        }
-      
-      if( (t_n_cols > 0) && (B_n_rows > 0) )
-        {
-        out.rows(row_num + C_n_rows, t_n_rows + C_n_rows - 1) = rows(row_num, t_n_rows - 1);
-        }
-      }
-    
-    if(C_n_cols > 0)
-      {
-      out.rows(row_num, row_num + C_n_rows - 1) = C;
-      }
-    
-    steal_mem(out);
-    }
-  }
-
-
-
-//! insert the given object at the specified column position; 
-//! the given object must have the same number of rows as the matrix
-template<typename eT>
-template<typename T1>
-inline
-void
-Mat<eT>::insert_cols(const uword col_num, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1>   tmp(X.get_ref());
-  const Mat<eT>& C = tmp.M;
-  
-  const uword C_n_rows = C.n_rows;
-  const uword C_n_cols = C.n_cols;
-  
-  const uword t_n_rows = n_rows;
-  const uword t_n_cols = n_cols;
-  
-  const uword A_n_cols = col_num;
-  const uword B_n_cols = t_n_cols - col_num;
-  
-  bool  err_state = false;
-  char* err_msg   = 0;
-  
-  // insertion at col_num == n_cols is in effect an append operation
-  
-  arma_debug_set_error
-    (
-    err_state,
-    err_msg,
-    (col_num > t_n_cols),
-    "Mat::insert_cols(): out of bounds"
-    );
-  
-  arma_debug_set_error
-    (
-    err_state,
-    err_msg,
-    ( (C_n_rows != t_n_rows) && ( (t_n_rows > 0) || (t_n_cols > 0) ) && ( (C_n_rows > 0) || (C_n_cols > 0) ) ),
-    "Mat::insert_cols(): given object has an incompatible number of rows"
-    );
-  
-  arma_debug_check(err_state, err_msg);
-  
-  if(C_n_cols > 0)
-    {
-    Mat<eT> out( (std::max)(t_n_rows, C_n_rows), t_n_cols + C_n_cols );
-    
-    if(t_n_rows > 0)
-      {
-      if(A_n_cols > 0)
-        {
-        out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1);
-        }
-      
-      if(B_n_cols > 0)
-        {
-        out.cols(col_num + C_n_cols, t_n_cols + C_n_cols - 1) = cols(col_num, t_n_cols - 1);
-        }
-      }
-    
-    if(C_n_rows > 0)
-      {
-      out.cols(col_num, col_num + C_n_cols - 1) = C;
-      }
-    
-    steal_mem(out);
-    }
-  }
-
-
-
-template<typename eT>
-template<typename gen_type>
-inline
-Mat<eT>::Mat(const Gen<eT, gen_type>& X)
-  : n_rows(X.n_rows)
-  , n_cols(X.n_cols)
-  , n_elem(n_rows*n_cols)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init_cold();
-  
-  X.apply(*this);
-  }
-
-
-
-template<typename eT>
-template<typename gen_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const Gen<eT, gen_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  init_warm(X.n_rows, X.n_cols);
-  
-  X.apply(*this);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename gen_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const Gen<eT, gen_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  X.apply_inplace_plus(*this);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename gen_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const Gen<eT, gen_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  X.apply_inplace_minus(*this);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename gen_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator*=(const Gen<eT, gen_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> tmp(X);
-  
-  return (*this).operator*=(tmp);
-  }
-
-
-
-template<typename eT>
-template<typename gen_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator%=(const Gen<eT, gen_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  X.apply_inplace_schur(*this);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename gen_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator/=(const Gen<eT, gen_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  X.apply_inplace_div(*this);
-  
-  return *this;
-  }
-
-
-
-//! create a matrix from Op, i.e. run the previously delayed unary operations
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-Mat<eT>::Mat(const Op<T1, op_type>& X)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  op_type::apply(*this, X);
-  }
-
-
-
-//! create a matrix from Op, i.e. run the previously delayed unary operations
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const Op<T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  op_type::apply(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix addition, with the right-hand-side operand having delayed operations
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const Op<T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator+=(m);
-  }
-
-
-
-//! in-place matrix subtraction, with the right-hand-side operand having delayed operations
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const Op<T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator-=(m);
-  }
-
-
-
-//! in-place matrix multiplication, with the right-hand-side operand having delayed operations
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator*=(const Op<T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  glue_times::apply_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix element-wise multiplication, with the right-hand-side operand having delayed operations
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator%=(const Op<T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator%=(m);
-  }
-
-
-
-//! in-place matrix element-wise division, with the right-hand-side operand having delayed operations
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator/=(const Op<T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator/=(m);
-  }
-
-
-
-//! create a matrix from eOp, i.e. run the previously delayed unary operations
-template<typename eT>
-template<typename T1, typename eop_type>
-inline
-Mat<eT>::Mat(const eOp<T1, eop_type>& X)
-  : n_rows(X.get_n_rows())
-  , n_cols(X.get_n_cols())
-  , n_elem(X.get_n_elem())
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  init_cold();
-  
-  eop_type::apply(*this, X);
-  }
-
-
-
-//! create a matrix from eOp, i.e. run the previously delayed unary operations
-template<typename eT>
-template<typename T1, typename eop_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const eOp<T1, eop_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  const bool bad_alias = (X.P.has_subview  &&  X.P.is_alias(*this));
-  
-  if(bad_alias == false)
-    {
-    init_warm(X.get_n_rows(), X.get_n_cols());
-    
-    eop_type::apply(*this, X);
-    }
-  else
-    {
-    Mat<eT> tmp(X);
-    
-    steal_mem(tmp);
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1, typename eop_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const eOp<T1, eop_type>& X)
-  {
-  arma_extra_debug_sigprint();
-
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  eop_type::apply_inplace_plus(*this, X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1, typename eop_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const eOp<T1, eop_type>& X)
-  {
-  arma_extra_debug_sigprint();
-
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  eop_type::apply_inplace_minus(*this, X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1, typename eop_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator*=(const eOp<T1, eop_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  glue_times::apply_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1, typename eop_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator%=(const eOp<T1, eop_type>& X)
-  {
-  arma_extra_debug_sigprint();
-
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  eop_type::apply_inplace_schur(*this, X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1, typename eop_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator/=(const eOp<T1, eop_type>& X)
-  {
-  arma_extra_debug_sigprint();
-
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  
-  eop_type::apply_inplace_div(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-Mat<eT>::Mat(const mtOp<eT, T1, op_type>& X)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  op_type::apply(*this, X);
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const mtOp<eT, T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  op_type::apply(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const mtOp<eT, T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator+=(m);
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const mtOp<eT, T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator-=(m);
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator*=(const mtOp<eT, T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator*=(m);
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator%=(const mtOp<eT, T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator%=(m);
-  }
-
-
-
-//! EXPERIMENTAL
-template<typename eT>
-template<typename T1, typename op_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator/=(const mtOp<eT, T1, op_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator/=(m);
-  }
-
-
-
-//! create a matrix from Glue, i.e. run the previously delayed binary operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-Mat<eT>::Mat(const Glue<T1, T2, glue_type>& X)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  glue_type::apply(*this, X);
-  }
-
-
-
-//! create a matrix from Glue, i.e. run the previously delayed binary operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const Glue<T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  glue_type::apply(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix addition, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const Glue<T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator+=(m);
-  }
-
-
-
-//! in-place matrix subtraction, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const Glue<T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator-=(m);
-  }
-
-
-
-//! in-place matrix multiplications, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator*=(const Glue<T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  glue_times::apply_inplace(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix element-wise multiplication, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator%=(const Glue<T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator%=(m);
-  }
-
-
-
-//! in-place matrix element-wise division, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator/=(const Glue<T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator/=(m);
-  }
-
-
-
-template<typename eT>
-template<typename T1, typename T2>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const Glue<T1, T2, glue_times>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  glue_times::apply_inplace_plus(*this, X, sword(+1));
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1, typename T2>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const Glue<T1, T2, glue_times>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  glue_times::apply_inplace_plus(*this, X, sword(-1));
-  
-  return *this;
-  }
-
-
-
-//! create a matrix from eGlue, i.e. run the previously delayed binary operations
-template<typename eT>
-template<typename T1, typename T2, typename eglue_type>
-inline
-Mat<eT>::Mat(const eGlue<T1, T2, eglue_type>& X)
-  : n_rows(X.get_n_rows())
-  , n_cols(X.get_n_cols())
-  , n_elem(X.get_n_elem())
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  init_cold();
-  
-  eglue_type::apply(*this, X);
-  }
-
-
-
-//! create a matrix from eGlue, i.e. run the previously delayed binary operations
-template<typename eT>
-template<typename T1, typename T2, typename eglue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const eGlue<T1, T2, eglue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  const bool bad_alias = ( (X.P1.has_subview  &&  X.P1.is_alias(*this))  ||  ( X.P2.has_subview  &&  X.P2.is_alias(*this)) );
-  
-  if(bad_alias == false)
-    {
-    init_warm(X.get_n_rows(), X.get_n_cols());
-    
-    eglue_type::apply(*this, X);
-    }
-  else
-    {
-    Mat<eT> tmp(X);
-    
-    steal_mem(tmp);
-    }
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix addition, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename eglue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const eGlue<T1, T2, eglue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  eglue_type::apply_inplace_plus(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! in-place matrix subtraction, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename eglue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const eGlue<T1, T2, eglue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  eglue_type::apply_inplace_minus(*this, X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1, typename T2, typename eglue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator*=(const eGlue<T1, T2, eglue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  glue_times::apply_inplace(*this, X);
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1, typename T2, typename eglue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator%=(const eGlue<T1, T2, eglue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  eglue_type::apply_inplace_schur(*this, X);
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1, typename T2, typename eglue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator/=(const eGlue<T1, T2, eglue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
-  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
-  
-  eglue_type::apply_inplace_div(*this, X);
-  return *this;
-  }
-
-
-
-//! EXPERIMENTAL: create a matrix from mtGlue, i.e. run the previously delayed binary operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-Mat<eT>::Mat(const mtGlue<eT, T1, T2, glue_type>& X)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , vec_state(0)
-  , mem_state(0)
-  , mem()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  glue_type::apply(*this, X);
-  }
-
-
-
-//! EXPERIMENTAL: create a matrix from Glue, i.e. run the previously delayed binary operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator=(const mtGlue<eT, T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  glue_type::apply(*this, X);
-  
-  return *this;
-  }
-
-
-
-//! EXPERIMENTAL: in-place matrix addition, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator+=(const mtGlue<eT, T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator+=(m);
-  }
-
-
-
-//! EXPERIMENTAL: in-place matrix subtraction, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator-=(const mtGlue<eT, T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator-=(m);
-  }
-
-
-
-//! EXPERIMENTAL: in-place matrix multiplications, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator*=(const mtGlue<eT, T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> m(X);
-  
-  glue_times::apply_inplace(*this, m);
-  
-  return *this;
-  }
-
-
-
-//! EXPERIMENTAL: in-place matrix element-wise multiplication, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator%=(const mtGlue<eT, T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator%=(m);
-  }
-
-
-
-//! EXPERIMENTAL: in-place matrix element-wise division, with the right-hand-side operands having delayed operations
-template<typename eT>
-template<typename T1, typename T2, typename glue_type>
-inline
-const Mat<eT>&
-Mat<eT>::operator/=(const mtGlue<eT, T1, T2, glue_type>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> m(X);
-  
-  return (*this).operator/=(m);
-  }
-
-
-
-//! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT&
-Mat<eT>::operator() (const uword i)
-  {
-  arma_debug_check( (i >= n_elem), "Mat::operator(): out of bounds");
-  return access::rw(mem[i]);
-  }
-
-
-
-//! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT
-Mat<eT>::operator() (const uword i) const
-  {
-  arma_debug_check( (i >= n_elem), "Mat::operator(): out of bounds");
-  return mem[i];
-  }
-
-
-//! linear element accessor (treats the matrix as a vector); no bounds check.  
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT&
-Mat<eT>::operator[] (const uword i)
-  {
-  return access::rw(mem[i]);
-  }
-
-
-
-//! linear element accessor (treats the matrix as a vector); no bounds check
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT
-Mat<eT>::operator[] (const uword i) const
-  {
-  return mem[i];
-  }
-
-
-
-//! linear element accessor (treats the matrix as a vector); no bounds check.  
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT&
-Mat<eT>::at(const uword i)
-  {
-  return access::rw(mem[i]);
-  }
-
-
-
-//! linear element accessor (treats the matrix as a vector); no bounds check
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT
-Mat<eT>::at(const uword i) const
-  {
-  return mem[i];
-  }
-
-
-
-//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT&
-Mat<eT>::operator() (const uword in_row, const uword in_col)
-  {
-  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): out of bounds");
-  return access::rw(mem[in_row + in_col*n_rows]);
-  }
-
-
-
-//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT
-Mat<eT>::operator() (const uword in_row, const uword in_col) const
-  {
-  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): out of bounds");
-  return mem[in_row + in_col*n_rows];
-  }
-
-
-
-//! element accessor; no bounds check
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT&
-Mat<eT>::at(const uword in_row, const uword in_col)
-  {
-  return access::rw( mem[in_row + in_col*n_rows] );
-  }
-
-
-
-//! element accessor; no bounds check
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT
-Mat<eT>::at(const uword in_row, const uword in_col) const
-  {
-  return mem[in_row + in_col*n_rows];
-  }
-
-
-
-//! prefix ++
-template<typename eT>
-arma_inline
-const Mat<eT>&
-Mat<eT>::operator++()
-  {
-  Mat_aux::prefix_pp(*this);
-  return *this;
-  }
-
-
-
-//! postfix ++  (must not return the object by reference)
-template<typename eT>
-arma_inline
-void
-Mat<eT>::operator++(int)
-  {
-  Mat_aux::postfix_pp(*this);
-  }
-
-
-
-//! prefix --
-template<typename eT>
-arma_inline
-const Mat<eT>&
-Mat<eT>::operator--()
-  {
-  Mat_aux::prefix_mm(*this);
-  return *this;
-  }
-
-
-
-//! postfix --  (must not return the object by reference)
-template<typename eT>
-arma_inline
-void
-Mat<eT>::operator--(int)
-  {
-  Mat_aux::postfix_mm(*this);
-  }
-
-
-
-//! returns true if the matrix has no elements
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Mat<eT>::is_empty() const
-  {
-  return (n_elem == 0);
-  }
-
-
-
-//! returns true if the object can be interpreted as a column or row vector
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Mat<eT>::is_vec() const
-  {
-  return ( (n_rows == 1) || (n_cols == 1) );
-  }
-
-
-
-//! returns true if the object can be interpreted as a row vector
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Mat<eT>::is_rowvec() const
-  {
-  return (n_rows == 1);
-  }
-
-
-
-//! returns true if the object can be interpreted as a column vector
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Mat<eT>::is_colvec() const
-  {
-  return (n_cols == 1);
-  }
-
-
-
-//! returns true if the object has the same number of non-zero rows and columnns
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Mat<eT>::is_square() const
-  {
-  return (n_rows == n_cols);
-  }
-
-
-
-//! returns true if all of the elements are finite
-template<typename eT>
-inline
-arma_warn_unused
-bool
-Mat<eT>::is_finite() const
-  {
-  return arrayops::is_finite( memptr(), n_elem );
-  }
-
-
-
-//! returns true if the given index is currently in range
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Mat<eT>::in_range(const uword i) const
-  {
-  return (i < n_elem);
-  }
-
-
-
-//! returns true if the given start and end indices are currently in range
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Mat<eT>::in_range(const span& x) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(x.whole == true)
-    {
-    return true;
-    }
-  else
-    {
-    const uword a = x.a;
-    const uword b = x.b;
-    
-    return ( (a <= b) && (b < n_elem) );
-    }
-  }
-
-
-
-//! returns true if the given location is currently in range
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Mat<eT>::in_range(const uword in_row, const uword in_col) const
-  {
-  return ( (in_row < n_rows) && (in_col < n_cols) );
-  }
-
-
-
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Mat<eT>::in_range(const span& row_span, const uword in_col) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(row_span.whole == true)
-    {
-    return (in_col < n_cols);
-    }
-  else
-    {
-    const uword in_row1 = row_span.a;
-    const uword in_row2 = row_span.b;
-    
-    return ( (in_row1 <= in_row2) && (in_row2 < n_rows) && (in_col < n_cols) );
-    }
-  }
-
-
-
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Mat<eT>::in_range(const uword in_row, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(col_span.whole == true)
-    {
-    return (in_row < n_rows);
-    }
-  else
-    {
-    const uword in_col1 = col_span.a;
-    const uword in_col2 = col_span.b;
-  
-    return ( (in_row < n_rows) && (in_col1 <= in_col2) && (in_col2 < n_cols) );
-    }
-  }
-
-
-
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-Mat<eT>::in_range(const span& row_span, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword in_row1 = row_span.a;
-  const uword in_row2 = row_span.b;
-  
-  const uword in_col1 = col_span.a;
-  const uword in_col2 = col_span.b;
-  
-  const bool rows_ok = row_span.whole ? true : ( (in_row1 <= in_row2) && (in_row2 < n_rows) );
-  const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2) && (in_col2 < n_cols) );
-  
-  return ( (rows_ok == true) && (cols_ok == true) );
-  }
-
-
-
-//! returns a pointer to array of eTs for a specified column; no bounds check
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT*
-Mat<eT>::colptr(const uword in_col)
-  {
-  return & access::rw(mem[in_col*n_rows]);
-  }
-
-
-
-//! returns a pointer to array of eTs for a specified column; no bounds check
-template<typename eT>
-arma_inline
-arma_warn_unused
-const eT*
-Mat<eT>::colptr(const uword in_col) const
-  {
-  return & mem[in_col*n_rows];
-  }
-
-
-
-//! returns a pointer to array of eTs used by the matrix
-template<typename eT>
-arma_inline
-arma_warn_unused
-eT*
-Mat<eT>::memptr()
-  {
-  return const_cast<eT*>(mem);
-  }
-
-
-
-//! returns a pointer to array of eTs used by the matrix
-template<typename eT>
-arma_inline
-arma_warn_unused
-const eT*
-Mat<eT>::memptr() const
-  {
-  return mem;
-  }
-
-
-
-//! print contents of the matrix (to the cout stream),
-//! optionally preceding with a user specified line of text.
-//! the precision and cell width are modified.
-//! on return, the stream's state are restored to their original values.
-template<typename eT>
-inline
-void
-Mat<eT>::impl_print(const std::string& extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(extra_text.length() != 0)
-    {
-    const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width();
-    
-    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
-  
-    ARMA_DEFAULT_OSTREAM.width(orig_width);
-    }
-  
-  arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, true);
-  }
-
-
-
-//! print contents of the matrix to a user specified stream,
-//! optionally preceding with a user specified line of text.
-//! the precision and cell width are modified.
-//! on return, the stream's state are restored to their original values.
-template<typename eT>
-inline
-void
-Mat<eT>::impl_print(std::ostream& user_stream, const std::string& extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(extra_text.length() != 0)
-    {
-    const std::streamsize orig_width = user_stream.width();
-    
-    user_stream << extra_text << '\n';
-    
-    user_stream.width(orig_width);
-    }
-  
-  arma_ostream::print(user_stream, *this, true);
-  }
-
-
-
-//! DEPRECATED FUNCTION
-template<typename eT>
-inline
-void
-Mat<eT>::impl_print_trans(const std::string& extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT> tmp;
-  op_strans::apply_noalias(tmp, *this);
-  
-  tmp.impl_print(extra_text);
-  }
-
-
-
-//! DEPRECATED FUNCTION
-template<typename eT>
-inline
-void
-Mat<eT>::impl_print_trans(std::ostream& user_stream, const std::string& extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT> tmp;
-  op_strans::apply_noalias(tmp, *this);
-  
-  tmp.impl_print(user_stream, extra_text);
-  }
-
-
-
-//! print contents of the matrix (to the cout stream),
-//! optionally preceding with a user specified line of text.
-//! the stream's state are used as is and are not modified
-//! (i.e. the precision and cell width are not modified).
-template<typename eT>
-inline
-void
-Mat<eT>::impl_raw_print(const std::string& extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(extra_text.length() != 0)
-    {
-    const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width();
-    
-    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
-  
-    ARMA_DEFAULT_OSTREAM.width(orig_width);
-    }
-  
-  arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, false);
-  }
-
-
-
-//! print contents of the matrix to a user specified stream,
-//! optionally preceding with a user specified line of text.
-//! the stream's state are used as is and are not modified.
-//! (i.e. the precision and cell width are not modified).
-template<typename eT>
-inline
-void
-Mat<eT>::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(extra_text.length() != 0)
-    {
-    const std::streamsize orig_width = user_stream.width();
-  
-    user_stream << extra_text << '\n';
-  
-    user_stream.width(orig_width);
-    }
-  
-  arma_ostream::print(user_stream, *this, false);
-  }
-
-
-
-//! DEPRECATED FUNCTION
-template<typename eT>
-inline
-void
-Mat<eT>::impl_raw_print_trans(const std::string& extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT> tmp;
-  op_strans::apply_noalias(tmp, *this);
-  
-  tmp.impl_raw_print(extra_text);
-  }
-
-
-
-//! DEPRECATED FUNCTION
-template<typename eT>
-inline
-void
-Mat<eT>::impl_raw_print_trans(std::ostream& user_stream, const std::string& extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT> tmp;
-  op_strans::apply_noalias(tmp, *this);
-  
-  tmp.impl_raw_print(user_stream, extra_text);
-  }
-
-
-
-//! change the matrix to have user specified dimensions (data is not preserved)
-template<typename eT>
-inline
-void
-Mat<eT>::set_size(const uword in_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(vec_state)
-    {
-    case 0:
-    case 1:
-      init_warm(in_elem, 1);
-      break;
-    
-    case 2:
-      init_warm(1, in_elem);
-      break;
-      
-    default:
-      ;
-    }
-  }
-
-
-
-//! change the matrix to have user specified dimensions (data is not preserved)
-template<typename eT>
-inline
-void
-Mat<eT>::set_size(const uword in_rows, const uword in_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  init_warm(in_rows, in_cols);
-  }
-
-
-
-//! change the matrix to have user specified dimensions (data is preserved)
-template<typename eT>
-inline
-void
-Mat<eT>::resize(const uword in_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(vec_state)
-    {
-    case 0:
-    case 1:
-      (*this).resize(in_elem, 1);
-      break;
-    
-    case 2:
-      (*this).resize(1, in_elem);
-      break;
-      
-    default:
-      ;
-    }
-  }
-
-
-
-//! change the matrix to have user specified dimensions (data is preserved)
-template<typename eT>
-inline
-void
-Mat<eT>::resize(const uword in_rows, const uword in_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  *this = arma::resize(*this, in_rows, in_cols);
-  }
-
-
-
-//! change the matrix to have user specified dimensions (data is preserved)
-template<typename eT>
-inline
-void
-Mat<eT>::reshape(const uword in_rows, const uword in_cols, const uword dim)
-  {
-  arma_extra_debug_sigprint();
-  
-  *this = arma::reshape(*this, in_rows, in_cols, dim);
-  }
-
-
-
-//! change the matrix (without preserving data) to have the same dimensions as the given matrix 
-template<typename eT>
-template<typename eT2>
-inline
-void
-Mat<eT>::copy_size(const Mat<eT2>& m)
-  {
-  arma_extra_debug_sigprint();
-  
-  init_warm(m.n_rows, m.n_cols);
-  }
-
-
-
-//! fill the matrix with the specified value
-template<typename eT>
-arma_hot
-inline
-const Mat<eT>&
-Mat<eT>::fill(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_set( memptr(), val, n_elem );
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::zeros()
-  {
-  arma_extra_debug_sigprint();
-  
-  return fill(eT(0));
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::zeros(const uword in_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  set_size(in_elem);
-  
-  return fill(eT(0));
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::zeros(const uword in_rows, const uword in_cols)
-  {
-  arma_extra_debug_sigprint();
-
-  set_size(in_rows, in_cols);
-  
-  return fill(eT(0));
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::ones()
-  {
-  arma_extra_debug_sigprint();
-  
-  return fill(eT(1));
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::ones(const uword in_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  set_size(in_elem);
-  
-  return fill(eT(1));
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::ones(const uword in_rows, const uword in_cols)
-  {
-  arma_extra_debug_sigprint();
-
-  set_size(in_rows, in_cols);
-  
-  return fill(eT(1));
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::randu()
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword N   = n_elem;
-        eT*   ptr = memptr();
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<N; i+=2, j+=2)
-    {
-    const eT tmp_i = eT(eop_aux_randu<eT>());
-    const eT tmp_j = eT(eop_aux_randu<eT>());
-    
-    ptr[i] = tmp_i;
-    ptr[j] = tmp_j;
-    }
-  
-  if(i < N)
-    {
-    ptr[i] = eT(eop_aux_randu<eT>());
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::randu(const uword in_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  set_size(in_elem);
-  
-  return (*this).randu();
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::randu(const uword in_rows, const uword in_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  set_size(in_rows, in_cols);
-  
-  return (*this).randu();
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::randn()
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword N   = n_elem;
-        eT*   ptr = memptr();
-  
-  for(uword i=0; i<N; ++i)
-    {
-    ptr[i] = eT(eop_aux_randn<eT>());
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::randn(const uword in_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  set_size(in_elem);
-  
-  return (*this).randn();
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::randn(const uword in_rows, const uword in_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  set_size(in_rows, in_cols);
-  
-  return (*this).randn();
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::eye()
-  {
-  arma_extra_debug_sigprint();
-  
-  fill(eT(0));
-  
-  const uword N = (std::min)(n_rows, n_cols);
-  
-  for(uword i=0; i<N; ++i)
-    {
-    at(i,i) = eT(1);
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-const Mat<eT>&
-Mat<eT>::eye(const uword in_rows, const uword in_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  set_size(in_rows, in_cols);
-  
-  return (*this).eye();
-  }
-
-
-
-template<typename eT>
-inline
-void
-Mat<eT>::reset()
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(vec_state)
-    {
-    default:
-      init_warm(0, 0);
-      break;
-      
-    case 1:
-      init_warm(0, 1);
-      break;
-    
-    case 2:
-      init_warm(1, 0);
-      break;
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-Mat<eT>::set_real(const Base<typename Mat<eT>::pod_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat_aux::set_real(*this, X);
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-Mat<eT>::set_imag(const Base<typename Mat<eT>::pod_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat_aux::set_imag(*this, X);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-Mat<eT>::min() const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (n_elem == 0), "min(): object has no elements" );
-  
-  return op_min::direct_min(memptr(), n_elem);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-Mat<eT>::max() const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (n_elem == 0), "max(): object has no elements" );
-  
-  return op_max::direct_max(memptr(), n_elem);
-  }
-
-
-
-template<typename eT>
-inline
-eT
-Mat<eT>::min(uword& index_of_min_val) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (n_elem == 0), "min(): object has no elements" );
-  
-  return op_min::direct_min(memptr(), n_elem, index_of_min_val);
-  }
-
-
-
-template<typename eT>
-inline
-eT
-Mat<eT>::max(uword& index_of_max_val) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (n_elem == 0), "max(): object has no elements" );
-  
-  return op_max::direct_max(memptr(), n_elem, index_of_max_val);
-  }
-
-
-
-template<typename eT>
-inline
-eT
-Mat<eT>::min(uword& row_of_min_val, uword& col_of_min_val) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (n_elem == 0), "min(): object has no elements" );
-  
-  uword i;
-  
-  eT val = op_min::direct_min(memptr(), n_elem, i);
-  
-  row_of_min_val = i % n_rows;
-  col_of_min_val = i / n_rows;
-  
-  return val;
-  }
-
-
-
-template<typename eT>
-inline
-eT
-Mat<eT>::max(uword& row_of_max_val, uword& col_of_max_val) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (n_elem == 0), "max(): object has no elements" );
-  
-  uword i;
-  
-  eT val = op_max::direct_max(memptr(), n_elem, i);
-  
-  row_of_max_val = i % n_rows;
-  col_of_max_val = i / n_rows;
-  
-  return val;
-  }
-
-
-
-//! save the matrix to a file
-template<typename eT>
-inline
-bool
-Mat<eT>::save(const std::string name, const file_type type, const bool print_status) const
-  {
-  arma_extra_debug_sigprint();
-  
-  bool save_okay;
-  
-  switch(type)
-    {
-    case raw_ascii:
-      save_okay = diskio::save_raw_ascii(*this, name);
-      break;
-    
-    case arma_ascii:
-      save_okay = diskio::save_arma_ascii(*this, name);
-      break;
-    
-    case csv_ascii:
-      save_okay = diskio::save_csv_ascii(*this, name);
-      break;
-    
-    case raw_binary:
-      save_okay = diskio::save_raw_binary(*this, name);
-      break;
-    
-    case arma_binary:
-      save_okay = diskio::save_arma_binary(*this, name);
-      break;
-      
-    case pgm_binary:
-      save_okay = diskio::save_pgm_binary(*this, name);
-      break;
-    
-    default:
-      arma_warn(print_status, "Mat::save(): unsupported file type");
-      save_okay = false;
-    }
-  
-  arma_warn( (print_status && (save_okay == false)), "Mat::save(): couldn't write to ", name);
-  
-  return save_okay;
-  }
-
-
-
-//! save the matrix to a stream
-template<typename eT>
-inline
-bool
-Mat<eT>::save(std::ostream& os, const file_type type, const bool print_status) const
-  {
-  arma_extra_debug_sigprint();
-  
-  bool save_okay;
-  
-  switch(type)
-    {
-    case raw_ascii:
-      save_okay = diskio::save_raw_ascii(*this, os);
-      break;
-    
-    case arma_ascii:
-      save_okay = diskio::save_arma_ascii(*this, os);
-      break;
-    
-    case csv_ascii:
-      save_okay = diskio::save_csv_ascii(*this, os);
-      break;
-    
-    case raw_binary:
-      save_okay = diskio::save_raw_binary(*this, os);
-      break;
-    
-    case arma_binary:
-      save_okay = diskio::save_arma_binary(*this, os);
-      break;
-      
-    case pgm_binary:
-      save_okay = diskio::save_pgm_binary(*this, os);
-      break;
-    
-    default:
-      arma_warn(print_status, "Mat::save(): unsupported file type");
-      save_okay = false;
-    }
-  
-  arma_warn( (print_status && (save_okay == false)), "Mat::save(): couldn't write to the given stream");
-  
-  return save_okay;
-  }
-
-
-
-//! load a matrix from a file
-template<typename eT>
-inline
-bool
-Mat<eT>::load(const std::string name, const file_type type, const bool print_status)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool load_okay;
-  std::string err_msg;
-  
-  switch(type)
-    {
-    case auto_detect:
-      load_okay = diskio::load_auto_detect(*this, name, err_msg);
-      break;
-    
-    case raw_ascii:
-      load_okay = diskio::load_raw_ascii(*this, name, err_msg);
-      break;
-    
-    case arma_ascii:
-      load_okay = diskio::load_arma_ascii(*this, name, err_msg);
-      break;
-    
-    case csv_ascii:
-      load_okay = diskio::load_csv_ascii(*this, name, err_msg);
-      break;
-    
-    case raw_binary:
-      load_okay = diskio::load_raw_binary(*this, name, err_msg);
-      break;
-    
-    case arma_binary:
-      load_okay = diskio::load_arma_binary(*this, name, err_msg);
-      break;
-      
-    case pgm_binary:
-      load_okay = diskio::load_pgm_binary(*this, name, err_msg);
-      break;
-    
-    default:
-      arma_warn(print_status, "Mat::load(): unsupported file type");
-      load_okay = false;
-    }
-  
-  if( (print_status == true) && (load_okay == false) )
-    {
-    if(err_msg.length() > 0)
-      {
-      arma_warn(true, "Mat::load(): ", err_msg, name);
-      }
-    else
-      {
-      arma_warn(true, "Mat::load(): couldn't read ", name);
-      }
-    }
-  
-  if(load_okay == false)
-    {
-    (*this).reset();
-    }
-    
-  return load_okay;
-  }
-
-
-
-//! load a matrix from a stream
-template<typename eT>
-inline
-bool
-Mat<eT>::load(std::istream& is, const file_type type, const bool print_status)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool load_okay;
-  std::string err_msg;
-  
-  switch(type)
-    {
-    case auto_detect:
-      load_okay = diskio::load_auto_detect(*this, is, err_msg);
-      break;
-    
-    case raw_ascii:
-      load_okay = diskio::load_raw_ascii(*this, is, err_msg);
-      break;
-    
-    case arma_ascii:
-      load_okay = diskio::load_arma_ascii(*this, is, err_msg);
-      break;
-    
-    case csv_ascii:
-      load_okay = diskio::load_csv_ascii(*this, is, err_msg);
-      break;
-    
-    case raw_binary:
-      load_okay = diskio::load_raw_binary(*this, is, err_msg);
-      break;
-    
-    case arma_binary:
-      load_okay = diskio::load_arma_binary(*this, is, err_msg);
-      break;
-      
-    case pgm_binary:
-      load_okay = diskio::load_pgm_binary(*this, is, err_msg);
-      break;
-    
-    default:
-      arma_warn(print_status, "Mat::load(): unsupported file type");
-      load_okay = false;
-    }
-  
-  
-  if( (print_status == true) && (load_okay == false) )
-    {
-    if(err_msg.length() > 0)
-      {
-      arma_warn(true, "Mat::load(): ", err_msg, "the given stream");
-      }
-    else
-      {
-      arma_warn(true, "Mat::load(): couldn't load from the given stream");
-      }
-    }
-  
-  if(load_okay == false)
-    {
-    (*this).reset();
-    }
-    
-  return load_okay;
-  }
-
-
-
-//! save the matrix to a file, without printing any error messages
-template<typename eT>
-inline
-bool
-Mat<eT>::quiet_save(const std::string name, const file_type type) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).save(name, type, false);
-  }
-
-
-
-//! save the matrix to a stream, without printing any error messages
-template<typename eT>
-inline
-bool
-Mat<eT>::quiet_save(std::ostream& os, const file_type type) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).save(os, type, false);
-  }
-
-
-
-//! load a matrix from a file, without printing any error messages
-template<typename eT>
-inline
-bool
-Mat<eT>::quiet_load(const std::string name, const file_type type)
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).load(name, type, false);
-  }
-
-
-
-//! load a matrix from a stream, without printing any error messages
-template<typename eT>
-inline
-bool
-Mat<eT>::quiet_load(std::istream& is, const file_type type)
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).load(is, type, false);
-  }
-
-
-
-template<typename eT>
-inline
-Mat<eT>::row_iterator::row_iterator(Mat<eT>& in_M, const uword in_row)
-  : M  (in_M  )
-  , row(in_row)
-  , col(0     )
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-eT&
-Mat<eT>::row_iterator::operator*()
-  {
-  return M.at(row,col);
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::row_iterator&
-Mat<eT>::row_iterator::operator++()
-  {
-  ++col;
-  
-  if(col >= M.n_cols)
-    {
-    col = 0;
-    ++row;
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-void
-Mat<eT>::row_iterator::operator++(int)
-  {
-  operator++();
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::row_iterator&
-Mat<eT>::row_iterator::operator--()
-  {
-  if(col > 0)
-    {
-    --col;
-    }
-  else
-    {
-    if(row > 0)
-      {
-      col = M.n_cols - 1;
-      --row;
-      }
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-void
-Mat<eT>::row_iterator::operator--(int)
-  {
-  operator--();
-  }
-
-
-
-template<typename eT>
-inline
-bool
-Mat<eT>::row_iterator::operator!=(const typename Mat<eT>::row_iterator& X) const
-  {
-  return ( (row != X.row) || (col != X.col) ) ? true : false;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-Mat<eT>::row_iterator::operator==(const typename Mat<eT>::row_iterator& X) const
-  {
-  return ( (row == X.row) && (col == X.col) ) ? true : false;
-  }
-
-
-
-template<typename eT>
-inline
-Mat<eT>::const_row_iterator::const_row_iterator(const Mat<eT>& in_M, const uword in_row)
-  : M  (in_M  )
-  , row(in_row)
-  , col(0     )
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-Mat<eT>::const_row_iterator::const_row_iterator(const typename Mat<eT>::row_iterator& X)
-  : M  (X.M)
-  , row(X.row)
-  , col(X.col)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-eT
-Mat<eT>::const_row_iterator::operator*() const
-  {
-  return M.at(row,col);
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::const_row_iterator&
-Mat<eT>::const_row_iterator::operator++()
-  {
-  ++col;
-  
-  if(col >= M.n_cols)
-    {
-    col = 0;
-    ++row;
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-void
-Mat<eT>::const_row_iterator::operator++(int)
-  {
-  operator++();
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::const_row_iterator&
-Mat<eT>::const_row_iterator::operator--()
-  {
-  if(col > 0)
-    {
-    --col;
-    }
-  else
-    {
-    if(row > 0)
-      {
-      col = M.n_cols - 1;
-      --row;
-      }
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-void
-Mat<eT>::const_row_iterator::operator--(int)
-  {
-  operator--();
-  }
-
-
-
-template<typename eT>
-inline
-bool
-Mat<eT>::const_row_iterator::operator!=(const typename Mat<eT>::const_row_iterator& X) const
-  {
-  return ( (row != X.row) || (col != X.col) ) ? true : false;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-Mat<eT>::const_row_iterator::operator==(const typename Mat<eT>::const_row_iterator& X) const
-  {
-  return ( (row == X.row) && (col == X.col) ) ? true : false;
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::iterator
-Mat<eT>::begin()
-  {
-  arma_extra_debug_sigprint();
-  
-  return memptr();
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::const_iterator
-Mat<eT>::begin() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return memptr();
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::iterator
-Mat<eT>::end()
-  {
-  arma_extra_debug_sigprint();
-  
-  return memptr() + n_elem;
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::const_iterator
-Mat<eT>::end() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return memptr() + n_elem;
-  }
-  
-
-
-template<typename eT>
-inline
-typename Mat<eT>::col_iterator
-Mat<eT>::begin_col(const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (col_num >= n_cols), "begin_col(): index out of bounds");
-  
-  return colptr(col_num);
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::const_col_iterator
-Mat<eT>::begin_col(const uword col_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (col_num >= n_cols), "begin_col(): index out of bounds");
-  
-  return colptr(col_num);
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::col_iterator
-Mat<eT>::end_col(const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (col_num >= n_cols), "end_col(): index out of bounds");
-  
-  return colptr(col_num) + n_rows;
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::const_col_iterator
-Mat<eT>::end_col(const uword col_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (col_num >= n_cols), "end_col(): index out of bounds");
-  
-  return colptr(col_num) + n_rows;
-  }
-  
-
-
-template<typename eT>
-inline
-typename Mat<eT>::row_iterator
-Mat<eT>::begin_row(const uword row_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" );
-  
-  return typename Mat<eT>::row_iterator(*this, row_num);
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::const_row_iterator
-Mat<eT>::begin_row(const uword row_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" );
-  
-  return typename Mat<eT>::const_row_iterator(*this, row_num);
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::row_iterator
-Mat<eT>::end_row(const uword row_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of bounds" );
-  
-  return typename Mat<eT>::row_iterator(*this, row_num + 1);
-  }
-
-
-
-template<typename eT>
-inline
-typename Mat<eT>::const_row_iterator
-Mat<eT>::end_row(const uword row_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of bounds" );
-  
-  return typename Mat<eT>::const_row_iterator(*this, row_num + 1);
-  }
-
-
-
-//! resets this matrix to an empty matrix
-template<typename eT>
-inline
-void
-Mat<eT>::clear()
-  {
-  reset();
-  }
-
-
-
-//! returns true if the matrix has no elements
-template<typename eT>
-inline
-bool
-Mat<eT>::empty() const
-  {
-  return (n_elem == 0);
-  }
-
-
-
-//! returns the number of elements in this matrix
-template<typename eT>
-inline
-uword
-Mat<eT>::size() const
-  {
-  return n_elem;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_inline
-void
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::mem_setup()
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::n_rows)    = fixed_n_rows;
-  access::rw(Mat<eT>::n_cols)    = fixed_n_cols;
-  access::rw(Mat<eT>::n_elem)    = fixed_n_elem;
-  access::rw(Mat<eT>::vec_state) = 0;
-  access::rw(Mat<eT>::mem_state) = 3;
-  access::rw(Mat<eT>::mem)       = (use_extra) ? mem_local_extra : mem_local;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_inline
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_inline
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const fixed<fixed_n_rows, fixed_n_cols>& X)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  eT* dest = (use_extra) ? mem_local_extra : mem_local;
-  
-  arrayops::copy( dest, X.mem, fixed_n_elem );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-template<typename T1>
-inline
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const Base<eT,T1>& A)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  Mat<eT>::operator=(A.get_ref()); 
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-template<typename T1, typename T2>
-inline
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  Mat<eT>::init(A,B);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-inline
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(eT* aux_mem, const bool copy_aux_mem)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  access::rw(Mat<eT>::n_rows)    = fixed_n_rows;
-  access::rw(Mat<eT>::n_cols)    = fixed_n_cols;
-  access::rw(Mat<eT>::n_elem)    = fixed_n_elem;
-  access::rw(Mat<eT>::vec_state) = 0;
-  access::rw(Mat<eT>::mem_state) = 3;
-  
-  if(copy_aux_mem == true)
-    {
-    eT* dest = (use_extra) ? mem_local_extra : mem_local;
-    
-    access::rw(Mat<eT>::mem) = dest;
-    
-    arrayops::copy( dest, aux_mem, fixed_n_elem );
-    }
-  else
-    {
-    access::rw(Mat<eT>::mem) = aux_mem;
-    }
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-inline
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const eT* aux_mem)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  arrayops::copy( const_cast<eT*>(Mat<eT>::mem), aux_mem, fixed_n_elem );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-inline
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const char* text)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  Mat<eT>::operator=(text);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-inline
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const std::string& text)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  Mat<eT>::operator=(text);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-template<typename T1>
-inline
-const Mat<eT>&
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const Base<eT,T1>& A)
-  {
-  Mat<eT>::operator=(A.get_ref());
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-inline
-const Mat<eT>&
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(val);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-inline
-const Mat<eT>&
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const char* text)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(text);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-inline
-const Mat<eT>&
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const std::string& text)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(text);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-inline
-subview_row<eT>
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator()(const uword row_num, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_num, col_span);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-inline
-const subview_row<eT>
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator()(const uword row_num, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_num, col_span);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-inline
-subview_col<eT>
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator()(const span& row_span, const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_span, col_num);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-inline
-const subview_col<eT>
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator()(const span& row_span, const uword col_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_span, col_num);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-inline
-subview<eT>
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator()(const span& row_span, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_span, col_span);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-inline
-const subview<eT>
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator()(const span& row_span, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_span, col_span);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_inline
-arma_warn_unused
-eT&
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator[] (const uword i)
-  {
-  return access::rw( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_inline
-arma_warn_unused
-eT
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator[] (const uword i) const
-  {
-  return ( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_inline
-arma_warn_unused
-eT&
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword i)
-  {
-  return access::rw( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_inline
-arma_warn_unused
-eT
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword i) const
-  {
-  return ( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_inline
-arma_warn_unused
-eT&
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword i)
-  {
-  arma_debug_check( (i >= fixed_n_elem), "Mat::fixed::operator(): out of bounds");
-  
-  return access::rw( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_inline
-arma_warn_unused
-eT
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword i) const
-  {
-  arma_debug_check( (i >= fixed_n_elem), "Mat::fixed::operator(): out of bounds");
-  
-  return ( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_inline
-arma_warn_unused
-eT&
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword in_row, const uword in_col)
-  {
-  const uword i = in_row + in_col*fixed_n_rows;
-  
-  return access::rw( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_inline
-arma_warn_unused
-eT
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword in_row, const uword in_col) const
-  {
-  const uword i = in_row + in_col*fixed_n_rows;
-  
-  return ( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_inline
-arma_warn_unused
-eT&
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword in_row, const uword in_col)
-  {
-  arma_debug_check( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::fixed::operator(): out of bounds");
-  
-  const uword i = in_row + in_col*fixed_n_rows;
-  
-  return access::rw( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_inline
-arma_warn_unused
-eT
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword in_row, const uword in_col) const
-  {
-  arma_debug_check( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::fixed::operator(): out of bounds");
-  
-  const uword i = in_row + in_col*fixed_n_rows;
-  
-  return ( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_hot
-inline
-const Mat<eT>&
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fill(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_set( const_cast<eT*>(Mat<eT>::mem), val, fixed_n_elem );
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_hot
-inline
-const Mat<eT>&
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::zeros()
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_set( const_cast<eT*>(Mat<eT>::mem), eT(0), fixed_n_elem );
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_rows, uword fixed_n_cols>
-arma_hot
-inline
-const Mat<eT>&
-Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::ones()
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_set( const_cast<eT*>(Mat<eT>::mem), eT(1), fixed_n_elem );
-  
-  return *this;
-  }
-
-
-
-//! prefix ++
-template<typename eT>
-arma_inline
-void
-Mat_aux::prefix_pp(Mat<eT>& x)
-  {
-        eT*   memptr = x.memptr();
-  const uword n_elem = x.n_elem;
-  
-  uword i,j;
-
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    ++(memptr[i]);
-    ++(memptr[j]);
-    }
-  
-  if(i < n_elem)
-    {
-    ++(memptr[i]);
-    }
-  }
-
-
-
-//! prefix ++ for complex numbers (work around for limitations of the std::complex class)
-template<typename T>
-arma_inline
-void
-Mat_aux::prefix_pp(Mat< std::complex<T> >& x)
-  {
-  x += T(1);
-  }
-
-
-
-//! postfix ++
-template<typename eT>
-arma_inline
-void
-Mat_aux::postfix_pp(Mat<eT>& x)
-  {
-        eT*   memptr = x.memptr();
-  const uword n_elem = x.n_elem;
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    (memptr[i])++;
-    (memptr[j])++;
-    }
-  
-  if(i < n_elem)
-    {
-    (memptr[i])++;
-    }
-  }
-
-
-
-//! postfix ++ for complex numbers (work around for limitations of the std::complex class)
-template<typename T>
-arma_inline
-void
-Mat_aux::postfix_pp(Mat< std::complex<T> >& x)
-  {
-  x += T(1);
-  }
-
-
-
-//! prefix --
-template<typename eT>
-arma_inline
-void
-Mat_aux::prefix_mm(Mat<eT>& x)
-  {
-        eT*   memptr = x.memptr();
-  const uword n_elem = x.n_elem;
-
-  uword i,j;
-
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    --(memptr[i]);
-    --(memptr[j]);
-    }
-  
-  if(i < n_elem)
-    {
-    --(memptr[i]);
-    }
-  }
-
-
-
-//! prefix -- for complex numbers (work around for limitations of the std::complex class)
-template<typename T>
-arma_inline
-void
-Mat_aux::prefix_mm(Mat< std::complex<T> >& x)
-  {
-  x -= T(1);
-  }
-
-
-
-//! postfix --
-template<typename eT>
-arma_inline
-void
-Mat_aux::postfix_mm(Mat<eT>& x)
-  {
-        eT*   memptr = x.memptr();
-  const uword n_elem = x.n_elem;
-
-  uword i,j;
-
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    (memptr[i])--;
-    (memptr[j])--;
-    }
-  
-  if(i < n_elem)
-    {
-    (memptr[i])--;
-    }
-  }
-
-
-
-//! postfix ++ for complex numbers (work around for limitations of the std::complex class)
-template<typename T>
-arma_inline
-void
-Mat_aux::postfix_mm(Mat< std::complex<T> >& x)
-  {
-  x -= T(1);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-Mat_aux::set_real(Mat<eT>& out, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1>   tmp(X.get_ref());
-  const Mat<eT>& A = tmp.M;
-  
-  arma_debug_assert_same_size( out, A, "Mat::set_real()" );
-  
-  out = A;
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-Mat_aux::set_imag(Mat<eT>& out, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T, typename T1>
-inline
-void
-Mat_aux::set_real(Mat< std::complex<T> >& out, const Base<T,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T>    eT;
-  typedef typename Proxy<T1>::ea_type ea_type;
-  
-  const Proxy<T1> A(X.get_ref());
-  
-  arma_debug_assert_same_size( out, A, "Mat::set_real()" );
-  
-  const uword   n_elem  = out.n_elem;
-        eT*     out_mem = out.memptr();
-        ea_type PA      = A.get_ea();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    //out_mem[i].real() = PA[i];
-    out_mem[i] = std::complex<T>( PA[i], out_mem[i].imag() );
-    }
-  }
-
-
-
-template<typename T, typename T1>
-inline
-void
-Mat_aux::set_imag(Mat< std::complex<T> >& out, const Base<T,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T>    eT;
-  typedef typename Proxy<T1>::ea_type ea_type;
-  
-  const Proxy<T1> A(X.get_ref());
-  
-  arma_debug_assert_same_size( out, A, "Mat::set_imag()" );
-  
-  const uword   n_elem  = out.n_elem;
-        eT*     out_mem = out.memptr();
-        ea_type PA      = A.get_ea();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    //out_mem[i].imag() = PA[i];
-    out_mem[i] = std::complex<T>( out_mem[i].real(), PA[i] );
-    }
-  }
-
-
-
-#ifdef ARMA_EXTRA_MAT_MEAT
-  #include ARMA_INCFILE_WRAP(ARMA_EXTRA_MAT_MEAT)
-#endif
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/OpCube_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup OpCube
-//! @{
-
-
-//! Analog of the Op class, intended for cubes
-
-template<typename T1, typename op_type>
-class OpCube : public BaseCube<typename T1::elem_type, OpCube<T1, op_type> >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  
-  inline explicit OpCube(const BaseCube<typename T1::elem_type, T1>& in_m);
-  inline          OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const elem_type in_aux);
-  inline          OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
-  inline          OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
-  inline          OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
-  inline          OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const uword in_aux_uword_d, const char junk);
-  inline         ~OpCube();
-  
-  arma_aligned const T1&       m;            //!< storage of reference to the operand (e.g. a cube)
-  arma_aligned       elem_type aux;          //!< storage of auxiliary data, user defined format
-  arma_aligned       uword     aux_uword_a;  //!< storage of auxiliary data, uword format
-  arma_aligned       uword     aux_uword_b;  //!< storage of auxiliary data, uword format
-  arma_aligned       uword     aux_uword_c;  //!< storage of auxiliary data, uword format
-  arma_aligned       uword     aux_uword_d;  //!< storage of auxiliary data, uword format
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/OpCube_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup OpCube
-//! @{
-
-
-
-template<typename T1, typename op_type>
-OpCube<T1, op_type>::OpCube(const BaseCube<typename T1::elem_type, T1>& in_m)
-  : m(in_m.get_ref())
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename op_type>
-OpCube<T1, op_type>::OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const typename T1::elem_type in_aux)
-  : m(in_m.get_ref())
-  , aux(in_aux)
-  {
-  arma_extra_debug_sigprint();
-  }
-  
-
-template<typename T1, typename op_type>
-OpCube<T1, op_type>::OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const typename T1::elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c)
-  : m(in_m.get_ref())
-  , aux(in_aux)
-  , aux_uword_a(in_aux_uword_a)
-  , aux_uword_b(in_aux_uword_b)
-  , aux_uword_c(in_aux_uword_c)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-
-template<typename T1, typename op_type>
-OpCube<T1, op_type>::OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b)
-  : m(in_m.get_ref())
-  , aux_uword_a(in_aux_uword_a)
-  , aux_uword_b(in_aux_uword_b)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename op_type>
-OpCube<T1, op_type>::OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c)
-  : m(in_m.get_ref())
-  , aux_uword_a(in_aux_uword_a)
-  , aux_uword_b(in_aux_uword_b)
-  , aux_uword_c(in_aux_uword_c)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename op_type>
-OpCube<T1, op_type>::OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const uword in_aux_uword_d, const char)
-  : m(in_m.get_ref())
-  , aux_uword_a(in_aux_uword_a)
-  , aux_uword_b(in_aux_uword_b)
-  , aux_uword_c(in_aux_uword_c)
-  , aux_uword_d(in_aux_uword_d)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename op_type>
-OpCube<T1, op_type>::~OpCube()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Op_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Op
-//! @{
-
-
-
-//! Class for storing data required for delayed unary operations,
-//! such as the operand (e.g. the matrix to which the operation is to be applied) and the unary operator (e.g. inverse).
-//! The operand is stored as a reference (which can be optimised away),
-//! while the operator is "stored" through the template definition (op_type).
-//! The operands can be 'Mat', 'Row', 'Col', 'Op', and 'Glue'.
-//! Note that as 'Glue' can be one of the operands, more than one matrix can be stored.
-//!
-//! For example, we could have:
-//! Op< Glue< Mat, Mat, glue_times >, op_htrans >
-
-template<typename T1, typename op_type>
-class Op : public Base<typename T1::elem_type, Op<T1, op_type> >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  inline explicit Op(const T1& in_m);
-  inline          Op(const T1& in_m, const elem_type in_aux);
-  inline          Op(const T1& in_m, const elem_type in_aux,         const uword in_aux_uword_a, const uword in_aux_uword_b);
-  inline          Op(const T1& in_m, const uword     in_aux_uword_a, const uword in_aux_uword_b);
-  inline          Op(const T1& in_m, const uword     in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const char junk);
-  inline         ~Op();
-    
-  
-  arma_aligned const T1&       m;            //!< storage of reference to the operand (eg. a matrix)
-  arma_aligned       elem_type aux;          //!< storage of auxiliary data, user defined format
-  arma_aligned       uword     aux_uword_a;  //!< storage of auxiliary data, uword format
-  arma_aligned       uword     aux_uword_b;  //!< storage of auxiliary data, uword format
-  arma_aligned       uword     aux_uword_c;  //!< storage of auxiliary data, uword format
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Op_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Op
-//! @{
-
-
-
-template<typename T1, typename op_type>
-inline
-Op<T1, op_type>::Op(const T1& in_m)
-  : m(in_m)
-  {
-  arma_extra_debug_sigprint();
-  }
-  
-
-
-template<typename T1, typename op_type>
-inline
-Op<T1, op_type>::Op(const T1& in_m, const typename T1::elem_type in_aux)
-  : m(in_m)
-  , aux(in_aux)
-  {
-  arma_extra_debug_sigprint();
-  }
-  
-
-
-template<typename T1, typename op_type>
-inline
-Op<T1, op_type>::Op(const T1& in_m, const typename T1::elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b)
-  : m(in_m)
-  , aux(in_aux)
-  , aux_uword_a(in_aux_uword_a)
-  , aux_uword_b(in_aux_uword_b)
-  {
-  arma_extra_debug_sigprint();
-  }
-  
-
-
-template<typename T1, typename op_type>
-inline
-Op<T1, op_type>::Op(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b)
-  : m(in_m)
-  , aux_uword_a(in_aux_uword_a)
-  , aux_uword_b(in_aux_uword_b)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename op_type>
-inline
-Op<T1, op_type>::Op(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const char)
-  : m(in_m)
-  , aux_uword_a(in_aux_uword_a)
-  , aux_uword_b(in_aux_uword_b)
-  , aux_uword_c(in_aux_uword_c)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename op_type>
-inline
-Op<T1, op_type>::~Op()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Proxy.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,503 +0,0 @@
-// Copyright (C) 2010-2012 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2012 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Proxy
-//! @{
-
-
-
-template<typename T1>
-class Proxy
-  {
-  public:
-  inline Proxy(const T1& A)
-    {
-    arma_type_check(( is_arma_type<T1>::value == false ));
-    }
-  };
-
-
-
-// ea_type is the "element accessor" type,
-// which can provide access to elements via operator[]
-
-template<typename eT>
-class Proxy< Mat<eT> >
-  {
-  public:
-  
-  typedef eT                                       elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef Mat<eT>                                  stored_type;
-  typedef const eT*                                ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Mat<eT>& Q;
-  
-  inline explicit Proxy(const Mat<eT>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows() const { return Q.n_rows; }
-  arma_inline uword get_n_cols() const { return Q.n_cols; }
-  arma_inline uword get_n_elem() const { return Q.n_elem; }
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
-  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
-  
-  arma_inline ea_type get_ea() const { return Q.memptr(); }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
-  };
-
-
-
-template<typename eT>
-class Proxy< Col<eT> >
-  {
-  public:
-  
-  typedef eT                                       elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef Col<eT>                                  stored_type;
-  typedef const eT*                                ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Col<eT>& Q;
-  
-  inline explicit Proxy(const Col<eT>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows() const { return Q.n_rows; }
-  arma_inline uword get_n_cols() const { return 1;        }
-  arma_inline uword get_n_elem() const { return Q.n_elem; }
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
-  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
-  
-  arma_inline ea_type get_ea() const { return Q.memptr(); }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
-  };
-
-
-
-template<typename eT>
-class Proxy< Row<eT> >
-  {
-  public:
-  
-  typedef eT                                       elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef Row<eT>                                  stored_type;
-  typedef const eT*                                ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Row<eT>& Q;
-  
-  inline explicit Proxy(const Row<eT>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows() const { return 1;        }
-  arma_inline uword get_n_cols() const { return Q.n_cols; }
-  arma_inline uword get_n_elem() const { return Q.n_elem; }
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
-  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
-  
-  arma_inline ea_type get_ea() const { return Q.memptr(); }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
-  };
-
-
-
-template<typename eT, typename gen_type>
-class Proxy< Gen<eT, gen_type > >
-  {
-  public:
-  
-  typedef          eT                              elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef Gen<eT, gen_type>                        stored_type;
-  typedef const Gen<eT, gen_type>&                 ea_type;
-  
-  static const bool prefer_at_accessor = Gen<eT, gen_type>::prefer_at_accessor;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Gen<eT, gen_type>& Q;
-  
-  inline explicit Proxy(const Gen<eT, gen_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows() const { return Q.n_rows;          }
-  arma_inline uword get_n_cols() const { return Q.n_cols;          }
-  arma_inline uword get_n_elem() const { return Q.n_rows*Q.n_cols; }
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
-  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
-  
-  arma_inline ea_type get_ea() const { return Q; }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
-  };
-
-
-
-template<typename T1, typename op_type>
-class Proxy< Op<T1, op_type> >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef Mat<elem_type>                           stored_type;
-  typedef const elem_type*                         ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Mat<elem_type> Q;
-  
-  inline explicit Proxy(const Op<T1, op_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows() const { return Q.n_rows; }
-  arma_inline uword get_n_cols() const { return Q.n_cols; }
-  arma_inline uword get_n_elem() const { return Q.n_elem; }
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
-  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
-  
-  arma_inline ea_type get_ea() const { return Q.memptr(); }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
-  };
-
-
-
-template<typename T1, typename T2, typename glue_type>
-class Proxy< Glue<T1, T2, glue_type> >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef Mat<elem_type>                           stored_type;
-  typedef const elem_type*                         ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Mat<elem_type> Q;
-  
-  inline explicit Proxy(const Glue<T1, T2, glue_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-
-  arma_inline uword get_n_rows() const { return Q.n_rows; }
-  arma_inline uword get_n_cols() const { return Q.n_cols; }
-  arma_inline uword get_n_elem() const { return Q.n_elem; }
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
-  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
-  
-  arma_inline ea_type get_ea() const { return Q.memptr(); }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
-  };
-
-
-
-template<typename eT>
-class Proxy< subview<eT> >
-  {
-  public:
-  
-  typedef eT                                       elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef subview<eT>                              stored_type;
-  typedef const subview<eT>&                       ea_type;
-  
-  static const bool prefer_at_accessor = true;
-  static const bool has_subview        = true;
-  
-  arma_aligned const subview<eT>& Q;
-  
-  inline explicit Proxy(const subview<eT>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows() const { return Q.n_rows; }
-  arma_inline uword get_n_cols() const { return Q.n_cols; }
-  arma_inline uword get_n_elem() const { return Q.n_elem; }
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
-  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
-  
-  arma_inline ea_type get_ea() const { return Q; }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&(Q.m)) == void_ptr(&X)); }
-  };
-
-
-
-template<typename eT, typename T1>
-class Proxy< subview_elem1<eT,T1> >
-  {
-  public:
-  
-  typedef eT                                       elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef Mat<eT>                                  stored_type;
-  typedef const eT*                                ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Mat<eT> Q;
-  
-  inline explicit Proxy(const subview_elem1<eT,T1>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows() const { return Q.n_rows; }
-  arma_inline uword get_n_cols() const { return 1;        }
-  arma_inline uword get_n_elem() const { return Q.n_elem; }
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
-  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
-  
-  arma_inline ea_type get_ea() const { return Q.memptr(); }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
-  };
-
-
-
-template<typename eT>
-class Proxy< diagview<eT> >
-  {
-  public:
-  
-  typedef eT                                       elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef diagview<eT>                             stored_type;
-  typedef const diagview<eT>&                      ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = true;
-  
-  arma_aligned const diagview<eT>& Q;
-  
-  inline explicit Proxy(const diagview<eT>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows() const { return Q.n_rows; }
-  arma_inline uword get_n_cols() const { return 1;        }
-  arma_inline uword get_n_elem() const { return Q.n_elem; }
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
-  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
-  
-  arma_inline ea_type get_ea() const { return Q; }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&(Q.m)) == void_ptr(&X)); }
-  };
-
-
-
-
-template<typename T1, typename eop_type>
-class Proxy< eOp<T1, eop_type > >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef eOp<T1, eop_type>                        stored_type;
-  typedef const eOp<T1, eop_type>&                 ea_type;
-  
-  static const bool prefer_at_accessor = eOp<T1, eop_type>::prefer_at_accessor;
-  static const bool has_subview        = eOp<T1, eop_type>::has_subview;
-  
-  arma_aligned const eOp<T1, eop_type>& Q;
-  
-  inline explicit Proxy(const eOp<T1, eop_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows() const { return Q.get_n_rows(); }
-  arma_inline uword get_n_cols() const { return Q.get_n_cols(); }
-  arma_inline uword get_n_elem() const { return Q.get_n_elem(); }
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
-  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
-  
-  arma_inline ea_type get_ea() const { return Q; }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Mat<eT2>& X) const { return Q.P.is_alias(X); }
-  };
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-class Proxy< eGlue<T1, T2, eglue_type > >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef eGlue<T1, T2, eglue_type>                stored_type;
-  typedef const eGlue<T1, T2, eglue_type>&         ea_type;
-  
-  static const bool prefer_at_accessor = eGlue<T1, T2, eglue_type>::prefer_at_accessor;
-  static const bool has_subview        = eGlue<T1, T2, eglue_type>::has_subview;
-  
-  arma_aligned const eGlue<T1, T2, eglue_type>& Q;
-  
-  inline explicit Proxy(const eGlue<T1, T2, eglue_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows() const { return Q.get_n_rows(); }
-  arma_inline uword get_n_cols() const { return Q.get_n_cols(); }
-  arma_inline uword get_n_elem() const { return Q.get_n_elem(); }
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
-  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
-  
-  arma_inline ea_type get_ea() const { return Q; }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Mat<eT2>& X) const { return (Q.P1.is_alias(X) || Q.P2.is_alias(X)); }
-  };
-
-
-
-template<typename out_eT, typename T1, typename op_type>
-class Proxy< mtOp<out_eT, T1, op_type> >
-  {
-  public:
-  
-  typedef          out_eT                       elem_type;
-  typedef typename get_pod_type<out_eT>::result pod_type;
-  typedef          Mat<out_eT>                  stored_type;
-  typedef          const elem_type*             ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Mat<out_eT> Q;
-  
-  inline explicit Proxy(const mtOp<out_eT, T1, op_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows() const { return Q.n_rows; }
-  arma_inline uword get_n_cols() const { return Q.n_cols; }
-  arma_inline uword get_n_elem() const { return Q.n_elem; }
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];          }
-  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row,col); }
-  
-  arma_inline ea_type get_ea() const { return Q.memptr(); }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
-  };
-
-
-
-template<typename out_eT, typename T1, typename T2, typename glue_type>
-class Proxy< mtGlue<out_eT, T1, T2, glue_type > >
-  {
-  public:
-  
-  typedef          out_eT                       elem_type;
-  typedef typename get_pod_type<out_eT>::result pod_type;
-  typedef          Mat<out_eT>                  stored_type;
-  typedef          const elem_type*             ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Mat<out_eT> Q;
-  
-  inline explicit Proxy(const mtGlue<out_eT, T1, T2, glue_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows() const { return Q.n_rows; }
-  arma_inline uword get_n_cols() const { return Q.n_cols; }
-  arma_inline uword get_n_elem() const { return Q.n_elem; }
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];          }
-  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row,col); }
-  
-  arma_inline ea_type get_ea() const { return Q.memptr(); }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/ProxyCube.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,376 +0,0 @@
-// Copyright (C) 2010-2012 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2012 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup ProxyCube
-//! @{
-
-
-
-template<typename T1>
-class ProxyCube
-  {
-  public:
-  inline ProxyCube(const T1& A)
-    {
-    arma_type_check(( is_arma_cube_type<T1>::value == false ));
-    }
-  };
-
-
-
-// ea_type is the "element accessor" type,
-// which can provide access to elements via operator[]
-
-template<typename eT>
-class ProxyCube< Cube<eT> >
-  {
-  public:
-  
-  typedef eT                                       elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef Cube<eT>                                 stored_type;
-  typedef const eT*                                ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Cube<eT>& Q;
-  
-  inline explicit ProxyCube(const Cube<eT>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows()       const { return Q.n_rows;       }
-  arma_inline uword get_n_cols()       const { return Q.n_cols;       }
-  arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
-  arma_inline uword get_n_slices()     const { return Q.n_slices;     }
-  arma_inline uword get_n_elem()       const { return Q.n_elem;       }
-  
-  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
-  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
-  
-  arma_inline ea_type get_ea() const { return Q.memptr(); }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Cube<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
-  };
-
-
-
-template<typename eT, typename gen_type>
-class ProxyCube< GenCube<eT, gen_type > >
-  {
-  public:
-  
-  typedef          eT                              elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef GenCube<eT, gen_type>                    stored_type;
-  typedef const GenCube<eT, gen_type>&             ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const GenCube<eT, gen_type>& Q;
-  
-  inline explicit ProxyCube(const GenCube<eT, gen_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows()       const { return Q.n_rows;                     }
-  arma_inline uword get_n_cols()       const { return Q.n_cols;                     }
-  arma_inline uword get_n_elem_slice() const { return Q.n_rows*Q.n_cols;            }
-  arma_inline uword get_n_slices()     const { return Q.n_slices;                   }
-  arma_inline uword get_n_elem()       const { return Q.n_rows*Q.n_cols*Q.n_slices; }
-  
-  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
-  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
-  
-  arma_inline ea_type get_ea() const { return Q; }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Cube<eT2>&) const { return false; }
-  };
-
-
-
-template<typename T1, typename op_type>
-class ProxyCube< OpCube<T1, op_type> >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef Cube<elem_type>                          stored_type;
-  typedef const elem_type*                         ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Cube<elem_type> Q;
-  
-  inline explicit ProxyCube(const OpCube<T1, op_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows()       const { return Q.n_rows;       }
-  arma_inline uword get_n_cols()       const { return Q.n_cols;       }
-  arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
-  arma_inline uword get_n_slices()     const { return Q.n_slices;     }
-  arma_inline uword get_n_elem()       const { return Q.n_elem;       }
-  
-  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
-  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
-  
-  arma_inline ea_type get_ea() const { return Q.memptr(); }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Cube<eT2>&) const { return false; }
-  };
-
-
-
-template<typename T1, typename T2, typename glue_type>
-class ProxyCube< GlueCube<T1, T2, glue_type> >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef Cube<elem_type>                          stored_type;
-  typedef const elem_type*                         ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Cube<elem_type> Q;
-  
-  inline explicit ProxyCube(const GlueCube<T1, T2, glue_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-
-  arma_inline uword get_n_rows()       const { return Q.n_rows;       }
-  arma_inline uword get_n_cols()       const { return Q.n_cols;       }
-  arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
-  arma_inline uword get_n_slices()     const { return Q.n_slices;     }
-  arma_inline uword get_n_elem()       const { return Q.n_elem;       }
-  
-  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
-  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
-  
-  arma_inline ea_type get_ea() const { return Q.memptr(); }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Cube<eT2>&) const { return false; }
-  };
-
-
-
-template<typename eT>
-class ProxyCube< subview_cube<eT> >
-  {
-  public:
-  
-  typedef eT                                       elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef subview_cube<eT>                         stored_type;
-  typedef const subview_cube<eT>&                  ea_type;
-  
-  static const bool prefer_at_accessor = true;
-  static const bool has_subview        = true;
-  
-  arma_aligned const subview_cube<eT>& Q;
-  
-  inline explicit ProxyCube(const subview_cube<eT>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows()       const { return Q.n_rows;       }
-  arma_inline uword get_n_cols()       const { return Q.n_cols;       }
-  arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
-  arma_inline uword get_n_slices()     const { return Q.n_slices;     }
-  arma_inline uword get_n_elem()       const { return Q.n_elem;       }
-  
-  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
-  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
-  
-  arma_inline ea_type get_ea() const { return Q; }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Cube<eT2>& X) const { return (void_ptr(&(Q.m)) == void_ptr(&X)); }
-  };
-
-
-
-template<typename T1, typename eop_type>
-class ProxyCube< eOpCube<T1, eop_type > >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef eOpCube<T1, eop_type>                    stored_type;
-  typedef const eOpCube<T1, eop_type>&             ea_type;
-  
-  static const bool prefer_at_accessor = eOpCube<T1, eop_type>::prefer_at_accessor;
-  static const bool has_subview        = eOpCube<T1, eop_type>::has_subview;
-  
-  arma_aligned const eOpCube<T1, eop_type>& Q;
-  
-  inline explicit ProxyCube(const eOpCube<T1, eop_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows()       const { return Q.get_n_rows();       }
-  arma_inline uword get_n_cols()       const { return Q.get_n_cols();       }
-  arma_inline uword get_n_elem_slice() const { return Q.get_n_elem_slice(); }
-  arma_inline uword get_n_slices()     const { return Q.get_n_slices();     }
-  arma_inline uword get_n_elem()       const { return Q.get_n_elem();       }
-  
-  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
-  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
-  
-  arma_inline ea_type get_ea() const { return Q; }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Cube<eT2>& X) const { return Q.P.is_alias(X); }
-  };
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-class ProxyCube< eGlueCube<T1, T2, eglue_type > >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef eGlueCube<T1, T2, eglue_type>            stored_type;
-  typedef const eGlueCube<T1, T2, eglue_type>&     ea_type;
-  
-  static const bool prefer_at_accessor = eGlueCube<T1, T2, eglue_type>::prefer_at_accessor;
-  static const bool has_subview        = eGlueCube<T1, T2, eglue_type>::has_subview;
-  
-  arma_aligned const eGlueCube<T1, T2, eglue_type>& Q;
-  
-  inline explicit ProxyCube(const eGlueCube<T1, T2, eglue_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows()       const { return Q.get_n_rows();       }
-  arma_inline uword get_n_cols()       const { return Q.get_n_cols();       }
-  arma_inline uword get_n_elem_slice() const { return Q.get_n_elem_slice(); }
-  arma_inline uword get_n_slices()     const { return Q.get_n_slices();     }
-  arma_inline uword get_n_elem()       const { return Q.get_n_elem();       }
-  
-  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
-  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
-  
-  arma_inline ea_type get_ea() const { return Q; }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Cube<eT2>& X) const { return (Q.P1.is_alias(X) || Q.P2.is_alias(X)); }
-  };
-
-
-
-template<typename out_eT, typename T1, typename op_type>
-class ProxyCube< mtOpCube<out_eT, T1, op_type> >
-  {
-  public:
-  
-  typedef          out_eT                       elem_type;
-  typedef typename get_pod_type<out_eT>::result pod_type;
-  typedef          Cube<out_eT>                 stored_type;
-  typedef          const elem_type*             ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Cube<out_eT> Q;
-  
-  inline explicit ProxyCube(const mtOpCube<out_eT, T1, op_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows()       const { return Q.n_rows;       }
-  arma_inline uword get_n_cols()       const { return Q.n_cols;       }
-  arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
-  arma_inline uword get_n_slices()     const { return Q.n_slices;     }
-  arma_inline uword get_n_elem()       const { return Q.n_elem;       }
-  
-  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
-  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
-  
-  arma_inline ea_type get_ea() const { return Q.memptr(); }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Cube<eT2>&) const { return false; }
-  };
-
-
-
-template<typename out_eT, typename T1, typename T2, typename glue_type>
-class ProxyCube< mtGlueCube<out_eT, T1, T2, glue_type > >
-  {
-  public:
-  
-  typedef          out_eT                       elem_type;
-  typedef typename get_pod_type<out_eT>::result pod_type;
-  typedef          Cube<out_eT>                 stored_type;
-  typedef          const elem_type*             ea_type;
-  
-  static const bool prefer_at_accessor = false;
-  static const bool has_subview        = false;
-  
-  arma_aligned const Cube<out_eT> Q;
-  
-  inline explicit ProxyCube(const mtGlueCube<out_eT, T1, T2, glue_type>& A)
-    : Q(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  arma_inline uword get_n_rows()       const { return Q.n_rows;       }
-  arma_inline uword get_n_cols()       const { return Q.n_cols;       }
-  arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
-  arma_inline uword get_n_slices()     const { return Q.n_slices;     }
-  arma_inline uword get_n_elem()       const { return Q.n_elem;       }
-  
-  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
-  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
-  
-  arma_inline ea_type get_ea() const { return Q.memptr(); }
-  
-  template<typename eT2>
-  arma_inline bool is_alias(const Cube<eT2>&) const { return false; }
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Row_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Row
-//! @{
-
-//! Class for row vectors (matrices with only one row)
-
-template<typename eT>
-class Row : public Mat<eT>
-  {
-  public:
-  
-  typedef eT                                elem_type;
-  typedef typename get_pod_type<eT>::result pod_type;
-  
-  
-  inline          Row();
-  inline          Row(const Row<eT>& X);
-  inline explicit Row(const uword N);
-  inline          Row(const uword in_rows, const uword in_cols);
-  
-  inline                  Row(const char*        text);
-  inline const Row& operator=(const char*        text);
-  
-  inline                  Row(const std::string& text);
-  inline const Row& operator=(const std::string& text);
-  
-  #if defined(ARMA_USE_CXX11)
-  inline                  Row(const std::initializer_list<eT>& list);
-  inline const Row& operator=(const std::initializer_list<eT>& list);
-  #endif
-  
-  inline const Row& operator=(const eT val);
-
-  template<typename T1> inline                   Row(const Base<eT,T1>& X);
-  template<typename T1> inline const Row&  operator=(const Base<eT,T1>& X);
-  
-  inline Row(      eT* aux_mem, const uword aux_length, const bool copy_aux_mem = true, const bool strict = true);
-  inline Row(const eT* aux_mem, const uword aux_length);
-  
-  template<typename T1, typename T2>
-  inline explicit Row(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
-  
-  template<typename T1> inline                  Row(const BaseCube<eT,T1>& X);
-  template<typename T1> inline const Row& operator=(const BaseCube<eT,T1>& X);
-  
-  inline                  Row(const subview_cube<eT>& X);
-  inline const Row& operator=(const subview_cube<eT>& X);
-  
-  inline mat_injector<Row> operator<<(const eT val);
-  
-  arma_inline eT& col(const uword col_num);
-  arma_inline eT  col(const uword col_num) const;
-  
-  arma_inline       subview_row<eT> cols(const uword in_col1, const uword in_col2);
-  arma_inline const subview_row<eT> cols(const uword in_col1, const uword in_col2) const;
-  
-  arma_inline       subview_row<eT> subvec(const uword in_col1, const uword in_col2);
-  arma_inline const subview_row<eT> subvec(const uword in_col1, const uword in_col2) const;
-  
-  arma_inline       subview_row<eT> subvec(const span& col_span);
-  arma_inline const subview_row<eT> subvec(const span& col_span) const;
-  
-  // arma_inline       subview_row<eT> operator()(const span& col_span);
-  // arma_inline const subview_row<eT> operator()(const span& col_span) const;
-  
-  
-  inline void shed_col (const uword col_num);
-  inline void shed_cols(const uword in_col1, const uword in_col2);
-  
-                        inline void insert_cols(const uword col_num, const uword N, const bool set_to_zero = true);
-  template<typename T1> inline void insert_cols(const uword col_num, const Base<eT,T1>& X);
-  
-  
-  typedef       eT*       row_iterator;
-  typedef const eT* const_row_iterator;
-  
-  inline       row_iterator begin_row(const uword row_num);
-  inline const_row_iterator begin_row(const uword row_num) const;
-  
-  inline       row_iterator end_row  (const uword row_num);
-  inline const_row_iterator end_row  (const uword row_num) const;
-  
-  
-  template<uword fixed_n_elem>
-  class fixed : public Row<eT>
-    {
-    private:
-    
-    static const bool use_extra = (fixed_n_elem > arma_config::mat_prealloc);
-    
-    arma_aligned eT mem_local_extra[ (use_extra) ? fixed_n_elem : 1 ];
-    
-    arma_inline void mem_setup();
-    
-    
-    public:
-    
-    static const uword n_rows = 1;
-    static const uword n_cols = fixed_n_elem;
-    static const uword n_elem = fixed_n_elem;
-    
-    arma_inline fixed();
-    arma_inline fixed(const fixed<fixed_n_elem>& X);
-         inline fixed(const subview_cube<eT>& X);
-    
-    template<typename T1>              inline fixed(const Base<eT,T1>& A);
-    template<typename T1, typename T2> inline fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
-    
-    inline fixed(      eT* aux_mem, const bool copy_aux_mem = true);
-    inline fixed(const eT* aux_mem);
-    
-    inline fixed(const char*        text);
-    inline fixed(const std::string& text);
-    
-    template<typename T1> inline const Row& operator=(const Base<eT,T1>& A);
-    
-    inline const Row& operator=(const eT val);
-    inline const Row& operator=(const char*        text);
-    inline const Row& operator=(const std::string& text);
-    inline const Row& operator=(const subview_cube<eT>& X);
-    
-    inline       subview_row<eT> operator()(const uword   row_num,  const span& col_span);
-    inline const subview_row<eT> operator()(const uword   row_num,  const span& col_span) const;
-    
-    inline       subview_col<eT> operator()(const span& row_span, const uword   col_num );
-    inline const subview_col<eT> operator()(const span& row_span, const uword   col_num ) const;
-    
-    inline       subview<eT>     operator()(const span& row_span, const span& col_span);
-    inline const subview<eT>     operator()(const span& row_span, const span& col_span) const;
-    
-    arma_inline arma_warn_unused eT& operator[] (const uword i);
-    arma_inline arma_warn_unused eT  operator[] (const uword i) const;
-    arma_inline arma_warn_unused eT& at         (const uword i);
-    arma_inline arma_warn_unused eT  at         (const uword i) const;
-    arma_inline arma_warn_unused eT& operator() (const uword i);
-    arma_inline arma_warn_unused eT  operator() (const uword i) const;
-    
-    arma_inline arma_warn_unused eT& at         (const uword in_row, const uword in_col);
-    arma_inline arma_warn_unused eT  at         (const uword in_row, const uword in_col) const;
-    arma_inline arma_warn_unused eT& operator() (const uword in_row, const uword in_col);
-    arma_inline arma_warn_unused eT  operator() (const uword in_row, const uword in_col) const;
-    
-    arma_hot inline const Row<eT>& fill(const eT val);
-    arma_hot inline const Row<eT>& zeros();
-    arma_hot inline const Row<eT>& ones();
-    };
-  
-  
-  #ifdef ARMA_EXTRA_ROW_PROTO
-    #include ARMA_INCFILE_WRAP(ARMA_EXTRA_ROW_PROTO)
-  #endif
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/Row_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1125 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup Row
-//! @{
-
-
-//! construct an empty row vector
-template<typename eT>
-inline
-Row<eT>::Row()
-  : Mat<eT>(1, 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  }
-
-
-
-template<typename eT>
-inline
-Row<eT>::Row(const Row<eT>& X)
-  : Mat<eT>(1, X.n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  arrayops::copy((*this).memptr(), X.memptr(), X.n_elem);
-  }
-
-
-
-//! construct a row vector with the specified number of n_elem
-template<typename eT>
-inline
-Row<eT>::Row(const uword in_n_elem)
-  : Mat<eT>(1, in_n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  }
-
-
-
-template<typename eT>
-inline
-Row<eT>::Row(const uword in_n_rows, const uword in_n_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::init_warm(in_n_rows, in_n_cols);
-  }
-
-
-
-template<typename eT>
-inline
-Row<eT>::Row(const char* text)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::operator=(text);
-  }
-  
-
-
-template<typename eT>
-inline
-const Row<eT>&
-Row<eT>::operator=(const char* text)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(text);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-Row<eT>::Row(const std::string& text)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::operator=(text);
-  }
-
-
-
-template<typename eT>
-inline
-const Row<eT>&
-Row<eT>::operator=(const std::string& text)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(text);
-  
-  return *this;
-  }
-
-
-
-#if defined(ARMA_USE_CXX11)
-
-template<typename eT>
-inline
-Row<eT>::Row(const std::initializer_list<eT>& list)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::operator=(list);
-  }
-
-
-
-template<typename eT>
-inline
-const Row<eT>&
-Row<eT>::operator=(const std::initializer_list<eT>& list)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(list);
-  
-  return *this;
-  }
-
-#endif
-
-
-
-template<typename eT>
-inline
-const Row<eT>&
-Row<eT>::operator=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(val);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-Row<eT>::Row(const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::operator=(X.get_ref());
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Row<eT>&
-Row<eT>::operator=(const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(X.get_ref());
-  
-  return *this;
-  }
-
-
-
-//! construct a row vector from a given auxiliary array
-template<typename eT>
-inline
-Row<eT>::Row(eT* aux_mem, const uword aux_length, const bool copy_aux_mem, const bool strict)
-  : Mat<eT>(aux_mem, 1, aux_length, copy_aux_mem, strict)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  }
-
-
-
-//! construct a row vector from a given auxiliary array
-template<typename eT>
-inline
-Row<eT>::Row(const eT* aux_mem, const uword aux_length)
-  : Mat<eT>(aux_mem, 1, aux_length)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  }
-
-
-
-template<typename eT>
-template<typename T1, typename T2>
-inline
-Row<eT>::Row
-  (
-  const Base<typename Row<eT>::pod_type, T1>& A,
-  const Base<typename Row<eT>::pod_type, T2>& B
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::init(A,B);
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-Row<eT>::Row(const BaseCube<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::operator=(X);
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-const Row<eT>&
-Row<eT>::operator=(const BaseCube<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-Row<eT>::Row(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::vec_state) = 2;
-  
-  Mat<eT>::operator=(X);
-  }
-
-
-
-template<typename eT>
-inline
-const Row<eT>&
-Row<eT>::operator=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::operator=(X);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-mat_injector< Row<eT> >
-Row<eT>::operator<<(const eT val)
-  {
-  return mat_injector< Row<eT> >(*this, val);
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT&
-Row<eT>::col(const uword col_num)
-  {
-  arma_debug_check( (col_num >= Mat<eT>::n_cols), "Row::col(): out of bounds" );
-  
-  return access::rw(Mat<eT>::mem[col_num]);
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT
-Row<eT>::col(const uword col_num) const
-  {
-  arma_debug_check( (col_num >= Mat<eT>::n_cols), "Row::col(): out of bounds" );
-  
-  return Mat<eT>::mem[col_num];
-  }
-
-
-
-template<typename eT>
-arma_inline
-subview_row<eT>
-Row<eT>::cols(const uword in_col1, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols) ), "Row::cols(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  return subview_row<eT>(*this, 0, in_col1, subview_n_cols);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const subview_row<eT>
-Row<eT>::cols(const uword in_col1, const uword in_col2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols) ), "Row::cols(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  return subview_row<eT>(*this, 0, in_col1, subview_n_cols);
-  }
-
-
-
-template<typename eT>
-arma_inline
-subview_row<eT>
-Row<eT>::subvec(const uword in_col1, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols) ), "Row::subvec(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  return subview_row<eT>(*this, 0, in_col1, subview_n_cols);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const subview_row<eT>
-Row<eT>::subvec(const uword in_col1, const uword in_col2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols) ), "Row::subvec(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  return subview_row<eT>(*this, 0, in_col1, subview_n_cols);
-  }
-
-
-
-template<typename eT>
-arma_inline
-subview_row<eT>
-Row<eT>::subvec(const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool col_all = col_span.whole;
-
-  const uword local_n_cols = Mat<eT>::n_cols;
-  
-  const uword in_col1       = col_all ? 0            : col_span.a;
-  const uword in_col2       =                          col_span.b;
-  const uword subvec_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
-
-  arma_debug_check( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ), "Row::subvec(): indices out of bounds or incorrectly used");
-  
-  return subview_row<eT>(*this, 0, in_col1, subvec_n_cols);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const subview_row<eT>
-Row<eT>::subvec(const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool col_all = col_span.whole;
-
-  const uword local_n_cols = Mat<eT>::n_cols;
-  
-  const uword in_col1       = col_all ? 0            : col_span.a;
-  const uword in_col2       =                          col_span.b;
-  const uword subvec_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
-
-  arma_debug_check( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ), "Row::subvec(): indices out of bounds or incorrectly used");
-  
-  return subview_row<eT>(*this, 0, in_col1, subvec_n_cols);
-  }
-
-
-
-// template<typename eT>
-// arma_inline
-// subview_row<eT>
-// Row<eT>::operator()(const span& col_span)
-//   {
-//   arma_extra_debug_sigprint();
-//   
-//   return subvec(col_span);
-//   }
-// 
-// 
-// 
-// template<typename eT>
-// arma_inline
-// const subview_row<eT>
-// Row<eT>::operator()(const span& col_span) const
-//   {
-//   arma_extra_debug_sigprint();
-//   
-//   return subvec(col_span);
-//   }
-
-
-
-//! remove specified columns
-template<typename eT>
-inline
-void
-Row<eT>::shed_col(const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( col_num >= Mat<eT>::n_cols, "Row::shed_col(): out of bounds");
-  
-  shed_cols(col_num, col_num);
-  }
-
-
-
-//! remove specified columns
-template<typename eT>
-inline
-void
-Row<eT>::shed_cols(const uword in_col1, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols),
-    "Row::shed_cols(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword n_keep_front = in_col1;
-  const uword n_keep_back  = Mat<eT>::n_cols - (in_col2 + 1);
-  
-  Row<eT> X(n_keep_front + n_keep_back);
-  
-        eT* X_mem = X.memptr();
-  const eT* t_mem = (*this).memptr();
-  
-  if(n_keep_front > 0)
-    {
-    arrayops::copy( X_mem, t_mem, n_keep_front );
-    }
-  
-  if(n_keep_back > 0)
-    {
-    arrayops::copy( &(X_mem[n_keep_front]), &(t_mem[in_col2+1]), n_keep_back);
-    }
-  
-  Mat<eT>::steal_mem(X);
-  }
-
-
-
-//! insert N cols at the specified col position,
-//! optionally setting the elements of the inserted cols to zero
-template<typename eT>
-inline
-void
-Row<eT>::insert_cols(const uword col_num, const uword N, const bool set_to_zero)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword t_n_cols = Mat<eT>::n_cols;
-  
-  const uword A_n_cols = col_num;
-  const uword B_n_cols = t_n_cols - col_num;
-  
-  // insertion at col_num == n_cols is in effect an append operation
-  arma_debug_check( (col_num > t_n_cols), "Row::insert_cols(): out of bounds");
-  
-  if(N > 0)
-    {
-    Row<eT> out(t_n_cols + N);
-    
-          eT* out_mem = out.memptr();
-    const eT*   t_mem = (*this).memptr();
-    
-    if(A_n_cols > 0)
-      {
-      arrayops::copy( out_mem, t_mem, A_n_cols );
-      }
-    
-    if(B_n_cols > 0)
-      {
-      arrayops::copy( &(out_mem[col_num + N]), &(t_mem[col_num]), B_n_cols );
-      }
-    
-    if(set_to_zero == true)
-      {
-      arrayops::inplace_set( &(out_mem[col_num]), eT(0), N );
-      }
-    
-    Mat<eT>::steal_mem(out);
-    }
-  }
-
-
-
-//! insert the given object at the specified col position; 
-//! the given object must have one row
-template<typename eT>
-template<typename T1>
-inline
-void
-Row<eT>::insert_cols(const uword col_num, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>::insert_cols(col_num, X);
-  }
-
-
-
-template<typename eT>
-inline
-typename Row<eT>::row_iterator
-Row<eT>::begin_row(const uword row_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= Mat<eT>::n_rows), "begin_row(): index out of bounds");
-  
-  return Mat<eT>::memptr();
-  }
-
-
-
-template<typename eT>
-inline
-typename Row<eT>::const_row_iterator
-Row<eT>::begin_row(const uword row_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= Mat<eT>::n_rows), "begin_row(): index out of bounds");
-  
-  return Mat<eT>::memptr();
-  }
-
-
-
-template<typename eT>
-inline
-typename Row<eT>::row_iterator
-Row<eT>::end_row(const uword row_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= Mat<eT>::n_rows), "end_row(): index out of bounds");
-  
-  return Mat<eT>::memptr() + Mat<eT>::n_cols;
-  }
-
-
-
-template<typename eT>
-inline
-typename Row<eT>::const_row_iterator
-Row<eT>::end_row(const uword row_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= Mat<eT>::n_rows), "end_row(): index out of bounds");
-  
-  return Mat<eT>::memptr() + Mat<eT>::n_cols;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-void
-Row<eT>::fixed<fixed_n_elem>::mem_setup()
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(Mat<eT>::n_rows)    = 1;
-  access::rw(Mat<eT>::n_cols)    = fixed_n_elem;
-  access::rw(Mat<eT>::n_elem)    = fixed_n_elem;
-  access::rw(Mat<eT>::vec_state) = 2;
-  access::rw(Mat<eT>::mem_state) = 3;
-  access::rw(Mat<eT>::mem)       = (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-Row<eT>::fixed<fixed_n_elem>::fixed()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-Row<eT>::fixed<fixed_n_elem>::fixed(const fixed<fixed_n_elem>& X)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  eT* dest = (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
-  
-  arrayops::copy( dest, X.mem, fixed_n_elem );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-Row<eT>::fixed<fixed_n_elem>::fixed(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  Row<eT>::operator=(X);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-template<typename T1>
-arma_inline
-Row<eT>::fixed<fixed_n_elem>::fixed(const Base<eT,T1>& A)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  Row<eT>::operator=(A.get_ref());
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-template<typename T1, typename T2>
-arma_inline
-Row<eT>::fixed<fixed_n_elem>::fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  Row<eT>::init(A,B);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-Row<eT>::fixed<fixed_n_elem>::fixed(eT* aux_mem, const bool copy_aux_mem)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  access::rw(Mat<eT>::n_rows)    = 1;
-  access::rw(Mat<eT>::n_cols)    = fixed_n_elem;
-  access::rw(Mat<eT>::n_elem)    = fixed_n_elem;
-  access::rw(Mat<eT>::vec_state) = 2;
-  access::rw(Mat<eT>::mem_state) = 3;
-  
-  if(copy_aux_mem == true)
-    {
-    eT* dest = (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
-  
-    access::rw(Mat<eT>::mem) = dest;
-    
-    arrayops::copy( dest, aux_mem, fixed_n_elem );
-    }
-  else
-    {
-    access::rw(Mat<eT>::mem) = aux_mem;
-    }
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-Row<eT>::fixed<fixed_n_elem>::fixed(const eT* aux_mem)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  arrayops::copy( const_cast<eT*>(Mat<eT>::mem), aux_mem, fixed_n_elem );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-Row<eT>::fixed<fixed_n_elem>::fixed(const char* text)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  Row<eT>::operator=(text);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-Row<eT>::fixed<fixed_n_elem>::fixed(const std::string& text)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  mem_setup();
-  
-  Row<eT>::operator=(text);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-subview_row<eT>
-Row<eT>::fixed<fixed_n_elem>::operator()(const uword row_num, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_num, col_span);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-template<typename T1>
-const Row<eT>&
-Row<eT>::fixed<fixed_n_elem>::operator=(const Base<eT,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  Row<eT>::operator=(A.get_ref());
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-const Row<eT>&
-Row<eT>::fixed<fixed_n_elem>::operator=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  Row<eT>::operator=(val);
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-const Row<eT>&
-Row<eT>::fixed<fixed_n_elem>::operator=(const char* text)
-  {
-  arma_extra_debug_sigprint();
-  
-  Row<eT>::operator=(text);
-  
-  return *this; 
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-const Row<eT>&
-Row<eT>::fixed<fixed_n_elem>::operator=(const std::string& text)
-  {
-  arma_extra_debug_sigprint();
-  
-  Row<eT>::operator=(text);
-  
-  return *this; 
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-const Row<eT>&
-Row<eT>::fixed<fixed_n_elem>::operator=(const subview_cube<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  Row<eT>::operator=(X);
-  
-  return *this; 
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-const subview_row<eT>
-Row<eT>::fixed<fixed_n_elem>::operator()(const uword row_num, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_num, col_span);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-subview_col<eT>
-Row<eT>::fixed<fixed_n_elem>::operator()(const span& row_span, const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_span, col_num);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-const subview_col<eT>
-Row<eT>::fixed<fixed_n_elem>::operator()(const span& row_span, const uword col_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_span, col_num);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-subview<eT>
-Row<eT>::fixed<fixed_n_elem>::operator()(const span& row_span, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_span, col_span);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-inline
-const subview<eT>
-Row<eT>::fixed<fixed_n_elem>::operator()(const span& row_span, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return Mat<eT>::operator()(row_span, col_span);
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT&
-Row<eT>::fixed<fixed_n_elem>::operator[] (const uword i)
-  {
-  return access::rw( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT
-Row<eT>::fixed<fixed_n_elem>::operator[] (const uword i) const
-  {
-  return ( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT&
-Row<eT>::fixed<fixed_n_elem>::at(const uword i)
-  {
-  return access::rw( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT
-Row<eT>::fixed<fixed_n_elem>::at(const uword i) const
-  {
-  return ( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT&
-Row<eT>::fixed<fixed_n_elem>::operator() (const uword i)
-  {
-  arma_debug_check( (i >= fixed_n_elem), "Row::fixed::operator(): out of bounds");
-  
-  return access::rw( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT
-Row<eT>::fixed<fixed_n_elem>::operator() (const uword i) const
-  {
-  arma_debug_check( (i >= fixed_n_elem), "Row::fixed::operator(): out of bounds");
-  
-  return ( Mat<eT>::mem[i] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT&
-Row<eT>::fixed<fixed_n_elem>::at(const uword in_row, const uword in_col)
-  {
-  return access::rw( Mat<eT>::mem[in_col] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT
-Row<eT>::fixed<fixed_n_elem>::at(const uword in_row, const uword in_col) const
-  {
-  return ( Mat<eT>::mem[in_col] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT&
-Row<eT>::fixed<fixed_n_elem>::operator() (const uword in_row, const uword in_col)
-  {
-  arma_debug_check( ((in_row >= 1) || (in_col >= fixed_n_elem)), "Row::fixed::operator(): out of bounds" );
-  
-  return access::rw( Mat<eT>::mem[in_col] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_inline
-arma_warn_unused
-eT
-Row<eT>::fixed<fixed_n_elem>::operator() (const uword in_row, const uword in_col) const
-  {
-  arma_debug_check( ((in_row >= 1) || (in_col >= fixed_n_elem)), "Row::fixed::operator(): out of bounds" );
-  
-  return ( Mat<eT>::mem[in_col] );
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_hot
-inline
-const Row<eT>&
-Row<eT>::fixed<fixed_n_elem>::fill(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_set( const_cast<eT*>(Mat<eT>::mem), val, fixed_n_elem );
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_hot
-inline
-const Row<eT>&
-Row<eT>::fixed<fixed_n_elem>::zeros()
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_set( const_cast<eT*>(Mat<eT>::mem), eT(0), fixed_n_elem );
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-template<uword fixed_n_elem>
-arma_hot
-inline
-const Row<eT>&
-Row<eT>::fixed<fixed_n_elem>::ones()
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_set( const_cast<eT*>(Mat<eT>::mem), eT(1), fixed_n_elem );
-  
-  return *this;
-  }
-
-
-
-#ifdef ARMA_EXTRA_ROW_MEAT
-  #include ARMA_INCFILE_WRAP(ARMA_EXTRA_ROW_MEAT)
-#endif
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/access.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup access
-//! @{
-
-
-class access
-  {
-  public:
-  
-  //! internal function to allow modification of data declared as read-only
-  template<typename T1> arma_inline static T1& rw(const T1& x) { return const_cast<T1&>(x); }
-
-  //! internal function to obtain the real part of either a plain number or a complex number
-  template<typename eT> arma_inline static const eT& tmp_real(const eT&              X) { return X;        }
-  template<typename  T> arma_inline static const   T tmp_real(const std::complex<T>& X) { return X.real(); }
-  };
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/arma_config.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup arma_config
-//! @{
-
-
-
-struct arma_config
-  {
-  #if defined(ARMA_MAT_PREALLOC)
-    static const uword mat_prealloc = (sword(ARMA_MAT_PREALLOC) > 0) ? uword(ARMA_MAT_PREALLOC) : 1;
-  #else
-    static const uword mat_prealloc = 16;
-  #endif
-  
-  #if defined(ARMA_USE_ATLAS)
-    static const bool atlas = true;
-  #else
-    static const bool atlas = false;
-  #endif
-  
-  
-  #if defined(ARMA_USE_LAPACK)
-    static const bool lapack = true;
-  #else
-    static const bool lapack = false;
-  #endif
-  
-  
-  #if defined(ARMA_USE_BLAS)
-    static const bool blas = true;
-  #else
-    static const bool blas = false;
-  #endif
-
-
-  #if defined(ARMA_USE_BOOST)
-    static const bool boost = true;
-  #else
-    static const bool boost = false;
-  #endif
-  
-
-  #if defined(ARMA_USE_BOOST_DATE)
-    static const bool boost_date = true;
-  #else
-    static const bool boost_date = false;
-  #endif
-
-
-  #if !defined(ARMA_NO_DEBUG) && !defined(NDEBUG)
-    static const bool debug = true;
-  #else
-    static const bool debug = false;
-  #endif
-  
-  
-  #if defined(ARMA_EXTRA_DEBUG)
-    static const bool extra_debug = true;
-  #else
-    static const bool extra_debug = false;
-  #endif
-  
-  
-  #if defined(ARMA_GOOD_COMPILER)
-    static const bool good_comp = true;
-  #else
-    static const bool good_comp = false;
-  #endif
-  
-  
-  #if (  \
-         defined(ARMA_EXTRA_MAT_PROTO)   || defined(ARMA_EXTRA_MAT_MEAT)   \
-      || defined(ARMA_EXTRA_COL_PROTO)   || defined(ARMA_EXTRA_COL_MEAT)   \
-      || defined(ARMA_EXTRA_ROW_PROTO)   || defined(ARMA_EXTRA_ROW_MEAT)   \
-      || defined(ARMA_EXTRA_CUBE_PROTO)  || defined(ARMA_EXTRA_CUBE_MEAT)  \
-      || defined(ARMA_EXTRA_FIELD_PROTO) || defined(ARMA_EXTRA_FIELD_MEAT) \
-      )
-    static const bool extra_code = true;
-  #else
-    static const bool extra_code = false;
-  #endif
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/arma_ostream_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup arma_ostream
-//! @{
-
-
-
-class arma_ostream_state
-  {
-  private:
-
-  const ios::fmtflags   orig_flags;
-  const std::streamsize orig_precision;
-  const std::streamsize orig_width;
-  const char            orig_fill;
-
-
-  public:
-
-  inline arma_ostream_state(const std::ostream& o);
-  
-  inline void restore(std::ostream& o) const;
-  };
-
-
-
-class arma_ostream
-  {
-  public:
-  
-  template<typename eT> inline static std::streamsize modify_stream(std::ostream& o, const eT*              data, const uword n_elem);
-  template<typename  T> inline static std::streamsize modify_stream(std::ostream& o, const std::complex<T>* data, const uword n_elem);
-  
-  template<typename eT> inline static void print_elem_zero(std::ostream& o);
-  
-  template<typename eT> arma_inline static void print_elem(std::ostream& o, const eT&              x);
-  template<typename  T>      inline static void print_elem(std::ostream& o, const std::complex<T>& x);
-
-  template<typename eT> inline static void print(std::ostream& o, const  Mat<eT>& m, const bool modify);
-  template<typename eT> inline static void print(std::ostream& o, const Cube<eT>& m, const bool modify);
-  
-  template<typename oT> inline static void print(std::ostream& o, const field<oT>&         m);
-  template<typename oT> inline static void print(std::ostream& o, const subview_field<oT>& m);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/arma_ostream_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,374 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup arma_ostream
-//! @{
-
-
-
-inline
-arma_ostream_state::arma_ostream_state(const std::ostream& o)
-  : orig_flags    (o.flags())
-  , orig_precision(o.precision())
-  , orig_width    (o.width())
-  , orig_fill     (o.fill())
-  {
-  }
-
-
-
-inline
-void
-arma_ostream_state::restore(std::ostream& o) const
-  {
-  o.flags    (orig_flags);
-  o.precision(orig_precision);
-  o.width    (orig_width);
-  o.fill     (orig_fill);
-  }
-
-
-
-//
-//
-
-
-
-template<typename eT>
-inline
-std::streamsize
-arma_ostream::modify_stream(std::ostream& o, const eT* data, const uword n_elem)
-  {
-  o.unsetf(ios::showbase);
-  o.unsetf(ios::uppercase);
-  o.unsetf(ios::showpos);
-  
-  o.fill(' ');
-  
-  std::streamsize cell_width;
-  
-  bool use_layout_B = false;
-  bool use_layout_C = false;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    const eT val = data[i];
-    
-    if(
-      val >= eT(+100) ||
-      ( (is_signed<eT>::value == true) && (val <= eT(-100)) ) ||
-      ( (is_non_integral<eT>::value == true) && (val > eT(0)) && (val <= eT(+1e-4)) ) ||
-      ( (is_non_integral<eT>::value == true) && (is_signed<eT>::value == true) && (val < eT(0)) && (val >= eT(-1e-4)) ) 
-      )
-      {
-      use_layout_C = true;
-      break;
-      }
-      
-    if(
-      (val >= eT(+10)) || ( (is_signed<eT>::value == true) && (val <= eT(-10)) )
-      )
-      {
-      use_layout_B = true;
-      }
-    }
-  
-  if(use_layout_C == true)
-    {
-    o.setf(ios::scientific);
-    o.setf(ios::right);
-    o.unsetf(ios::fixed);
-    o.precision(4);
-    cell_width = 13;
-    }
-  else
-  if(use_layout_B == true)
-    {
-    o.unsetf(ios::scientific);
-    o.setf(ios::right);
-    o.setf(ios::fixed);
-    o.precision(4);
-    cell_width = 10;
-    }
-  else
-    {
-    o.unsetf(ios::scientific);
-    o.setf(ios::right);
-    o.setf(ios::fixed);
-    o.precision(4);
-    cell_width = 9;
-    }
-  
-  return cell_width;
-  }
-
-
-
-//! "better than nothing" settings for complex numbers
-template<typename T>
-inline
-std::streamsize
-arma_ostream::modify_stream(std::ostream& o, const std::complex<T>* data, const uword n_elem)
-  {
-  arma_ignore(data);
-  arma_ignore(n_elem);
-  
-  o.unsetf(ios::showbase);
-  o.unsetf(ios::uppercase);
-  o.fill(' ');
-  
-  o.setf(ios::scientific);
-  o.setf(ios::showpos);
-  o.setf(ios::right);
-  o.unsetf(ios::fixed);
-  
-  std::streamsize cell_width;
-  
-  o.precision(3);
-  cell_width = 2 + 2*(1 + 3 + o.precision() + 5) + 1;
-  
-  return cell_width;
-  }
-
-
-
-template<typename eT>
-inline
-void
-arma_ostream::print_elem_zero(std::ostream& o)
-  {
-  const std::streamsize orig_precision = o.precision();
-  
-  o.precision(0);
-  
-  o << eT(0);
-  
-  o.precision(orig_precision);
-  }
-
-
-
-//! Print an element to the specified stream
-template<typename eT>
-arma_inline
-void
-arma_ostream::print_elem(std::ostream& o, const eT& x)
-  {
-  if(x != eT(0))
-    {
-    o << x;
-    }
-  else
-    {
-    arma_ostream::print_elem_zero<eT>(o);
-    }
-  }
-
-
-
-//! Print a complex element to the specified stream
-template<typename T>
-inline
-void
-arma_ostream::print_elem(std::ostream& o, const std::complex<T>& x)
-  {
-  if( (x.real() != T(0)) || (x.imag() != T(0)) )
-    {
-    std::ostringstream ss;
-    ss.flags(o.flags());
-    //ss.imbue(o.getloc());
-    ss.precision(o.precision());
-  
-    ss << '(' << x.real() << ',' << x.imag() << ')';
-    o << ss.str();
-    }
-  else
-    {
-    o << "(0,0)";
-    }
-  }
-
-
-
-//! Print a matrix to the specified stream
-template<typename eT>
-inline
-void
-arma_ostream::print(std::ostream& o, const Mat<eT>& m, const bool modify)
-  {
-  arma_extra_debug_sigprint();
-  
-  const arma_ostream_state stream_state(o);
-  
-  const std::streamsize cell_width = modify ? arma_ostream::modify_stream(o, m.memptr(), m.n_elem) : o.width();
-  
-  const uword m_n_rows = m.n_rows;
-  const uword m_n_cols = m.n_cols;
-  
-  if(m.is_empty() == false)
-    {
-    if(m_n_cols > 0)
-      {
-      if(cell_width > 0)
-        {
-        for(uword row=0; row < m_n_rows; ++row)
-          {
-          for(uword col=0; col < m_n_cols; ++col)
-            {
-            // the cell width appears to be reset after each element is printed,
-            // hence we need to restore it
-            o.width(cell_width);
-            arma_ostream::print_elem(o, m.at(row,col));
-            }
-        
-          o << '\n';
-          }
-        }
-      else
-        {
-        for(uword row=0; row < m_n_rows; ++row)
-          {
-          for(uword col=0; col < m_n_cols-1; ++col)
-            {
-            arma_ostream::print_elem(o, m.at(row,col));
-            o << ' ';
-            }
-        
-          arma_ostream::print_elem(o, m.at(row, m_n_cols-1));
-          o << '\n';
-          }
-        }
-      }
-    }
-  else
-    {
-    o << "[matrix size: " << m_n_rows << 'x' << m_n_cols << "]\n";
-    }
-  
-  o.flush();
-  stream_state.restore(o);
-  }
-
-
-
-//! Print a cube to the specified stream
-template<typename eT>
-inline
-void
-arma_ostream::print(std::ostream& o, const Cube<eT>& x, const bool modify)
-  {
-  arma_extra_debug_sigprint();
-  
-  const arma_ostream_state stream_state(o);
-  
-  const std::streamsize cell_width = modify ? arma_ostream::modify_stream(o, x.memptr(), x.n_elem) : o.width();
-  
-  if(x.is_empty() == false)
-    {
-    for(uword slice=0; slice < x.n_slices; ++slice)
-      {
-      o << "[cube slice " << slice << ']' << '\n';
-      o.width(cell_width);
-      arma_ostream::print(o, x.slice(slice), false);
-      o << '\n';
-      }
-    }
-  else
-    {
-    o << "[cube size: " << x.n_rows << 'x' << x.n_cols << 'x' << x.n_slices <<  "]\n";
-    }
-
-  stream_state.restore(o);
-  }
-
-
-
-
-//! Print a field to the specified stream
-//! Assumes type oT can be printed, i.e. oT has std::ostream& operator<< (std::ostream&, const oT&) 
-template<typename oT>
-inline
-void
-arma_ostream::print(std::ostream& o, const field<oT>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  const arma_ostream_state stream_state(o);
-  
-  const std::streamsize cell_width = o.width();
-  
-  const uword x_n_rows = x.n_rows;
-  const uword x_n_cols = x.n_cols;
-  
-  if(x.is_empty() == false)
-    {
-    for(uword col=0; col<x_n_cols; ++col)
-      {
-      o << "[field column " << col << ']' << '\n'; 
-      
-      for(uword row=0; row<x_n_rows; ++row)
-        {
-        o.width(cell_width);
-        o << x.at(row,col) << '\n';
-        }
-      
-      o << '\n';
-      }
-    }
-  else
-    {
-    o << "[field size: " << x_n_rows << 'x' << x_n_cols <<  "]\n";
-    }
-  
-  o.flush();
-  stream_state.restore(o);
-  }
-
-
-
-//! Print a subfield to the specified stream
-//! Assumes type oT can be printed, i.e. oT has std::ostream& operator<< (std::ostream&, const oT&) 
-template<typename oT>
-inline
-void
-arma_ostream::print(std::ostream& o, const subview_field<oT>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  const arma_ostream_state stream_state(o);
-  
-  const std::streamsize cell_width = o.width();
-  
-  const uword x_n_rows = x.n_rows;
-  const uword x_n_cols = x.n_cols;
-  
-  for(uword col=0; col<x_n_cols; ++col)
-    {
-    o << "[field column " << col << ']' << '\n'; 
-    for(uword row=0; row<x_n_rows; ++row)
-      {
-      o.width(cell_width);
-      o << x.at(row,col) << '\n';
-      }
-    
-    o << '\n';
-    }
-  
-  o.flush();
-  stream_state.restore(o);
-  }
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/arma_static_check.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup arma_static_check
-//! @{
-
-
-
-template<bool ERROR___INCORRECT_OR_UNSUPPORTED_TYPE>
-struct arma_type_check_cxx1998
-  {
-  arma_inline
-  static
-  void
-  apply()
-    {
-    static const char
-    junk[ ERROR___INCORRECT_OR_UNSUPPORTED_TYPE ? -1 : +1 ];
-    }
-  };
-
-
-
-template<>
-struct arma_type_check_cxx1998<false>
-  {
-  arma_inline
-  static
-  void
-  apply()
-    {
-    }
-  };
-
-
-
-#if !defined(ARMA_USE_CXX11)
-
-  #define arma_static_check(condition, message)  static const char message[ (condition) ? -1 : +1 ]
-  
-  #define arma_type_check(condition)  arma_type_check_cxx1998<condition>::apply()
-
-#else
-
-  #define arma_static_check(condition, message)  static_assert( !(condition), #message )
-  
-  #define arma_type_check(condition)  static_assert( !(condition), "error: incorrect or unsupported type" )
-
-#endif
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/arma_version.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup arma_version
-//! @{
-
-
-
-#define ARMA_VERSION_MAJOR 2
-#define ARMA_VERSION_MINOR 4
-#define ARMA_VERSION_PATCH 4
-#define ARMA_VERSION_NAME  "Loco Lounge Lizard"
-
-
-
-struct arma_version
-  {
-  static const unsigned int major = ARMA_VERSION_MAJOR;
-  static const unsigned int minor = ARMA_VERSION_MINOR;
-  static const unsigned int patch = ARMA_VERSION_PATCH;
-  
-  static
-  inline
-  std::string
-  as_string()
-    {
-    const char* nickname = ARMA_VERSION_NAME;
-    
-    std::stringstream ss;
-    ss << arma_version::major
-       << '.'
-       << arma_version::minor
-       << '.'
-       << arma_version::patch
-       << " ("
-       << nickname
-       << ')';
-    
-    return ss.str();
-    }
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/arrayops_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup arrayops
-//! @{
-
-
-class arrayops
-  {
-  public:
-  
-  template<typename eT>
-  arma_hot arma_inline static void
-  copy(eT* dest, const eT* src, const uword n_elem);
-  
-  
-  template<typename eT>
-  static inline void
-  copy_big(eT* dest, const eT* src, const uword n_elem);
-  
-  
-  // 
-  // array = convert(array)
-  
-  template<typename out_eT, typename in_eT>
-  arma_hot arma_inline static void
-  convert_cx_scalar(out_eT& out, const in_eT&  in, const typename arma_not_cx<out_eT>::result* junk1 = 0, const typename arma_not_cx< in_eT>::result* junk2 = 0);
-  
-  template<typename out_eT, typename in_T>
-  arma_hot arma_inline static void
-  convert_cx_scalar(out_eT& out, const std::complex<in_T>& in, const typename arma_not_cx<out_eT>::result* junk = 0);
-  
-  template<typename out_T, typename in_T>
-  arma_hot arma_inline static void
-  convert_cx_scalar(std::complex<out_T>& out, const std::complex< in_T>& in);
-  
-  template<typename out_eT, typename in_eT>
-  arma_hot inline static void
-  convert(out_eT* dest, const in_eT* src, const uword n_elem);
-  
-  template<typename out_eT, typename in_eT>
-  arma_hot inline static void
-  convert_cx(out_eT* dest, const in_eT* src, const uword n_elem);
-  
-  
-  // 
-  // array op= array
-  
-  template<typename eT>
-  arma_hot inline static
-  void
-  inplace_plus(eT* dest, const eT* src, const uword n_elem);
-  
-  template<typename eT>
-  arma_hot inline static
-  void
-  inplace_minus(eT* dest, const eT* src, const uword n_elem);
-  
-  template<typename eT>
-  arma_hot inline static
-  void
-  inplace_mul(eT* dest, const eT* src, const uword n_elem);
-   
-  template<typename eT>
-  arma_hot inline static
-  void
-  inplace_div(eT* dest, const eT* src, const uword n_elem);
-  
-  
-  // 
-  // array op= scalar
-  
-  template<typename eT>
-  arma_hot inline static
-  void
-  inplace_set(eT* dest, const eT val, const uword n_elem);
-  
-  template<typename eT>
-  arma_hot inline static
-  void
-  inplace_plus(eT* dest, const eT val, const uword n_elem);
-  
-  template<typename eT>
-  arma_hot inline static
-  void
-  inplace_minus(eT* dest, const eT val, const uword n_elem);
-  
-  template<typename eT>
-  arma_hot inline static void
-  inplace_mul(eT* dest, const eT val, const uword n_elem);
-  
-  template<typename eT>
-  arma_hot inline static
-  void
-  inplace_div(eT* dest, const eT val, const uword n_elem);
-  
-  
-  // 
-  // scalar = op(array)
-  
-  template<typename eT>
-  arma_hot arma_pure inline static
-  eT
-  accumulate(const eT* src, const uword n_elem);
-  
-  template<typename eT>
-  arma_hot arma_pure inline static
-  eT
-  product(const eT* src, const uword n_elem);
-  
-  template<typename eT>
-  arma_hot arma_pure inline static
-  bool
-  is_finite(const eT* src, const uword n_elem);
-  
-  template<typename eT>
-  arma_hot arma_pure inline static
-  typename get_pod_type<eT>::result
-  norm_1(const eT* src, const uword n_elem);
-  
-  template<typename eT>
-  arma_hot arma_pure inline static
-  eT
-  norm_2(const eT* src, const uword n_elem, const typename arma_not_cx<eT>::result* junk = 0);
-  
-  template<typename T>
-  arma_hot arma_pure inline static
-  T
-  norm_2(const std::complex<T>* src, const uword n_elem);
-  
-  template<typename eT>
-  arma_hot arma_pure inline static
-  typename get_pod_type<eT>::result
-  norm_k(const eT* src, const uword n_elem, const int k);
-  
-  template<typename eT>
-  arma_hot arma_pure inline static
-  typename get_pod_type<eT>::result
-  norm_max(const eT* src, const uword n_elem);
-  
-  template<typename eT>
-  arma_hot arma_pure inline static
-  typename get_pod_type<eT>::result
-  norm_min(const eT* src, const uword n_elem);
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/arrayops_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,714 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup arrayops
-//! @{
-
-
-
-template<typename eT>
-arma_hot
-arma_inline
-void
-arrayops::copy(eT* dest, const eT* src, const uword n_elem)
-  {
-  switch(n_elem)
-    {
-    default:
-      arrayops::copy_big(dest, src, n_elem);
-      break;
-    case 8:
-      dest[7] = src[7];
-    case 7:
-      dest[6] = src[6];
-    case 6:
-      dest[5] = src[5];
-    case 5:
-      dest[4] = src[4];
-    case 4:
-      dest[3] = src[3];
-    case 3:
-      dest[2] = src[2];
-    case 2:
-      dest[1] = src[1];
-    case 1:
-      dest[0] = src[0];
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-arrayops::copy_big(eT* dest, const eT* src, const uword n_elem)
-  {
-  switch(n_elem)
-    {
-    default:
-      std::memcpy(dest, src, n_elem*sizeof(eT));
-      break;
-    case 32:
-      dest[31] = src[31];
-    case 31:
-      dest[30] = src[30];
-    case 30:
-      dest[29] = src[29];
-    case 29:
-      dest[28] = src[28];
-    case 28:
-      dest[27] = src[27];
-    case 27:
-      dest[26] = src[26];
-    case 26:
-      dest[25] = src[25];
-    case 25:
-      dest[24] = src[24];
-    case 24:
-      dest[23] = src[23];
-    case 23:
-      dest[22] = src[22];
-    case 22:
-      dest[21] = src[21];
-    case 21:
-      dest[20] = src[20];
-    case 20:
-      dest[19] = src[19];
-    case 19:
-      dest[18] = src[18];
-    case 18:
-      dest[17] = src[17];
-    case 17:
-      dest[16] = src[16];
-    case 16:
-      dest[15] = src[15];
-    case 15:
-      dest[14] = src[14];
-    case 14:
-      dest[13] = src[13];
-    case 13:
-      dest[12] = src[12];
-    case 12:
-      dest[11] = src[11];
-    case 11:
-      dest[10] = src[10];
-    case 10:
-      dest[9] = src[9];
-    case 9:
-      dest[8] = src[8];
-    case 8:
-      dest[7] = src[7];
-    case 7:
-      dest[6] = src[6];
-    case 6:
-      dest[5] = src[5];
-    case 5:
-      dest[4] = src[4];
-    case 4:
-      dest[3] = src[3];
-    case 3:
-      dest[2] = src[2];
-    case 2:
-      dest[1] = src[1];
-    case 1:
-      dest[0] = src[0];
-    }
-  }
-
-
-
-template<typename out_eT, typename in_eT>
-arma_hot
-arma_inline
-void
-arrayops::convert_cx_scalar
-  (
-        out_eT& out,
-  const in_eT&  in,
-  const typename arma_not_cx<out_eT>::result* junk1,
-  const typename arma_not_cx< in_eT>::result* junk2
-  )
-  {
-  arma_ignore(junk1);
-  arma_ignore(junk2);
-  
-  out = out_eT(in);
-  }
-
-
-
-template<typename out_eT, typename in_T>
-arma_hot
-arma_inline
-void
-arrayops::convert_cx_scalar
-  (
-        out_eT&             out,
-  const std::complex<in_T>& in,
-  const typename arma_not_cx<out_eT>::result* junk
-  )
-  {
-  arma_ignore(junk);
-  
-  out = out_eT( in.real() );
-  }
-
-
-
-template<typename out_T, typename in_T>
-arma_hot
-arma_inline
-void
-arrayops::convert_cx_scalar
-  (
-        std::complex<out_T>& out,
-  const std::complex< in_T>& in
-  )
-  {
-  typedef std::complex<out_T> out_eT;
-  
-  out = out_eT(in);
-  }
-
-
-
-template<typename out_eT, typename in_eT>
-arma_hot
-inline
-void
-arrayops::convert(out_eT* dest, const in_eT* src, const uword n_elem)
-  {
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    dest[i] = out_eT( src[i] );
-    dest[j] = out_eT( src[j] );
-    }
-  
-  if(i < n_elem)
-    {
-    dest[i] = out_eT( src[i] );
-    }
-  }
-
-
-
-template<typename out_eT, typename in_eT>
-arma_hot
-inline
-void
-arrayops::convert_cx(out_eT* dest, const in_eT* src, const uword n_elem)
-  {
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    arrayops::convert_cx_scalar( dest[i], src[i] );
-    arrayops::convert_cx_scalar( dest[j], src[j] );
-    }
-  
-  if(i < n_elem)
-    {
-    arrayops::convert_cx_scalar( dest[i], src[i] );
-    }
-  }
-
-
-
-template<typename eT>
-arma_hot
-inline
-void
-arrayops::inplace_plus(eT* dest, const eT* src, const uword n_elem)
-  {
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    dest[i] += src[i];
-    dest[j] += src[j];
-    }
-  
-  if(i < n_elem)
-    {
-    dest[i] += src[i];
-    }
-  }
-
-
-
-template<typename eT>
-arma_hot
-inline
-void
-arrayops::inplace_minus(eT* dest, const eT* src, const uword n_elem)
-  {
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    dest[i] -= src[i];
-    dest[j] -= src[j];
-    }
-  
-  if(i < n_elem)
-    {
-    dest[i] -= src[i];
-    }
-  }
-
-
-
-template<typename eT>
-arma_hot
-inline
-void
-arrayops::inplace_mul(eT* dest, const eT* src, const uword n_elem)
-  {
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    dest[i] *= src[i];
-    dest[j] *= src[j];
-    }
-  
-  if(i < n_elem)
-    {
-    dest[i] *= src[i];
-    }
-  }
-
-
-
-template<typename eT>
-arma_hot
-inline
-void
-arrayops::inplace_div(eT* dest, const eT* src, const uword n_elem)
-  {
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    dest[i] /= src[i];
-    dest[j] /= src[j];
-    }
-  
-  if(i < n_elem)
-    {
-    dest[i] /= src[i];
-    }
-  }
-
-
-
-template<typename eT>
-arma_hot
-inline
-void
-arrayops::inplace_set(eT* dest, const eT val, const uword n_elem)
-  {
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    dest[i] = val;
-    dest[j] = val;
-    }
-  
-  if(i < n_elem)
-    {
-    dest[i] = val;
-    }
-  }
-
-
-
-template<typename eT>
-arma_hot
-inline
-void
-arrayops::inplace_plus(eT* dest, const eT val, const uword n_elem)
-  {
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    dest[i] += val;
-    dest[j] += val;
-    }
-  
-  if(i < n_elem)
-    {
-    dest[i] += val;
-    }
-  }
-
-
-
-template<typename eT>
-arma_hot
-inline
-void
-arrayops::inplace_minus(eT* dest, const eT val, const uword n_elem)
-  {
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    dest[i] -= val;
-    dest[j] -= val;
-    }
-  
-  if(i < n_elem)
-    {
-    dest[i] -= val;
-    }
-  }
-
-
-
-template<typename eT>
-arma_hot
-inline
-void
-arrayops::inplace_mul(eT* dest, const eT val, const uword n_elem)
-  {
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    dest[i] *= val;
-    dest[j] *= val;
-    }
-  
-  if(i < n_elem)
-    {
-    dest[i] *= val;
-    }
-  }
-
-
-
-template<typename eT>
-arma_hot
-inline
-void
-arrayops::inplace_div(eT* dest, const eT val, const uword n_elem)
-  {
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    dest[i] /= val;
-    dest[j] /= val;
-    }
-  
-  if(i < n_elem)
-    {
-    dest[i] /= val;
-    }
-  }
-
-
-
-template<typename eT>
-arma_hot
-arma_pure
-inline
-eT
-arrayops::accumulate(const eT* src, const uword n_elem)
-  {
-  uword i,j;
-  
-  eT acc1 = eT(0);
-  eT acc2 = eT(0);
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    acc1 += src[i];
-    acc2 += src[j];
-    }
-  
-  if(i < n_elem)
-    {
-    acc1 += src[i];
-    }
-  
-  return acc1 + acc2;
-  }
-
-
-
-template<typename eT>
-arma_hot
-arma_pure
-inline
-eT
-arrayops::product(const eT* src, const uword n_elem)
-  {
-  eT val1 = eT(1);
-  eT val2 = eT(1);
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    val1 *= src[i];
-    val2 *= src[j];
-    }
-  
-  if(i < n_elem)
-    {
-    val1 *= src[i];
-    }
-  
-  return val1 * val2;
-  }
-
-
-
-template<typename eT>
-arma_hot
-arma_pure
-inline
-bool
-arrayops::is_finite(const eT* src, const uword n_elem)
-  {
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    const eT val_i = src[i];
-    const eT val_j = src[j];
-    
-    if( (arma_isfinite(val_i) == false) || (arma_isfinite(val_j) == false) )
-      {
-      return false;
-      }
-    }
-  
-  if(i < n_elem)
-    {
-    if(arma_isfinite(src[i]) == false)
-      {
-      return false;
-      }
-    }
-  
-  return true;
-  }
-
-
-
-// TODO: this function is currently not used
-template<typename eT>
-arma_hot
-arma_pure
-inline
-typename get_pod_type<eT>::result
-arrayops::norm_1(const eT* src, const uword n_elem)
-  {
-  typedef typename get_pod_type<eT>::result T;
-  
-  T acc = T(0);
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    acc += std::abs(src[i]);
-    acc += std::abs(src[j]);
-    }
-  
-  if(i < n_elem)
-    {
-    acc += std::abs(src[i]);
-    }
-  
-  return acc;
-  }
-
-
-
-// TODO: this function is currently not used
-template<typename eT>
-arma_hot
-arma_pure
-inline
-eT
-arrayops::norm_2(const eT* src, const uword n_elem, const typename arma_not_cx<eT>::result* junk)
-  {
-  arma_ignore(junk);
-  
-  eT acc = eT(0);
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = src[i];
-    const eT tmp_j = src[j];
-    
-    acc += tmp_i * tmp_i;
-    acc += tmp_j * tmp_j;
-    }
-  
-  if(i < n_elem)
-    {
-    const eT tmp_i = src[i];
-    
-    acc += tmp_i * tmp_i;
-    }
-  
-  return std::sqrt(acc);
-  }
-
-
-
-// TODO: this function is currently not used
-template<typename T>
-arma_hot
-arma_pure
-inline
-T
-arrayops::norm_2(const std::complex<T>* src, const uword n_elem)
-  {
-  T acc = T(0);
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    const T tmp_i = std::abs(src[i]);
-    const T tmp_j = std::abs(src[j]);
-    
-    acc += tmp_i * tmp_i;
-    acc += tmp_j * tmp_j;
-    }
-  
-  if(i < n_elem)
-    {
-    const T tmp_i = std::abs(src[i]);
-    
-    acc += tmp_i * tmp_i;
-    }
-  
-  return std::sqrt(acc);
-  }
-
-
-
-// TODO: this function is currently not used
-template<typename eT>
-arma_hot
-arma_pure
-inline
-typename get_pod_type<eT>::result
-arrayops::norm_k(const eT* src, const uword n_elem, const int k)
-  {
-  typedef typename get_pod_type<eT>::result T;
-  
-  T acc = T(0);
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    acc += std::pow(std::abs(src[i]), k);
-    acc += std::pow(std::abs(src[j]), k);
-    }
-  
-  if(i < n_elem)
-    {
-    acc += std::pow(std::abs(src[i]), k);
-    }
-  
-  return std::pow(acc, T(1)/T(k));
-  }
-
-
-
-// TODO: this function is currently not used
-template<typename eT>
-arma_hot
-arma_pure
-inline
-typename get_pod_type<eT>::result
-arrayops::norm_max(const eT* src, const uword n_elem)
-  {
-  typedef typename get_pod_type<eT>::result T;
-  
-  T max_val = std::abs(src[0]);
-  
-  uword i,j;
-  
-  for(i=1, j=2; j<n_elem; i+=2, j+=2)
-    {
-    const T tmp_i = std::abs(src[i]);
-    const T tmp_j = std::abs(src[j]);
-    
-    if(max_val < tmp_i) { max_val = tmp_i; }
-    if(max_val < tmp_j) { max_val = tmp_j; }
-    }
-  
-  if(i < n_elem)
-    {
-    const T tmp_i = std::abs(src[i]);
-    
-    if(max_val < tmp_i) { max_val = tmp_i; }
-    }
-  
-  return max_val;
-  }
-
-
-
-// TODO: this function is currently not used
-template<typename eT>
-arma_hot
-arma_pure
-inline
-typename get_pod_type<eT>::result
-arrayops::norm_min(const eT* src, const uword n_elem)
-  {
-  typedef typename get_pod_type<eT>::result T;
-  
-  T min_val = std::abs(src[0]);
-  
-  uword i,j;
-  
-  for(i=1, j=2; j<n_elem; i+=2, j+=2)
-    {
-    const T tmp_i = std::abs(src[i]);
-    const T tmp_j = std::abs(src[j]);
-    
-    if(min_val > tmp_i) { min_val = tmp_i; }
-    if(min_val > tmp_j) { min_val = tmp_j; }
-    }
-  
-  if(i < n_elem)
-    {
-    const T tmp_i = std::abs(src[i]);
-    
-    if(min_val > tmp_i) { min_val = tmp_i; }
-    }
-  
-  return min_val;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/atlas_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-#ifdef ARMA_USE_ATLAS
-
-
-//! \namespace atlas namespace for ATLAS functions (imported from the global namespace)
-namespace atlas
-  {
-  
-  using ::CblasColMajor;
-  using ::CblasNoTrans;
-  using ::CblasTrans;
-  using ::CblasConjTrans;
-  
-  #if defined(ARMA_USE_WRAPPER)
-  extern "C"
-    {
-    
-    float  wrapper_cblas_sdot(const int N, const float  *X, const int incX, const float  *Y, const int incY);
-    double wrapper_cblas_ddot(const int N, const double *X, const int incX, const double *Y, const int incY);
-    
-    void wrapper_cblas_cdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu);
-    void wrapper_cblas_zdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu);
-    
-    
-    void wrapper_cblas_sgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const float alpha,
-                             const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY);
-    
-    void wrapper_cblas_dgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const double alpha,
-                             const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY);
-    
-    void wrapper_cblas_cgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha,
-                             const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY);
-    
-    void wrapper_cblas_zgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha,
-                             const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY);
-    
-    
-    
-    void wrapper_cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
-                             const int M, const int N, const int K, const float alpha,
-                             const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc);
-    
-    void wrapper_cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
-                             const int M, const int N, const int K, const double alpha,
-                             const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc);
-    
-    void wrapper_cblas_cgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
-                             const int M, const int N, const int K, const void *alpha,
-                             const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc);
-    
-    void wrapper_cblas_zgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
-                             const int M, const int N, const int K, const void *alpha,
-                             const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc);
-    
-    
-    int wrapper_clapack_sgetrf(const enum CBLAS_ORDER Order, const int M, const int N, float  *A, const int lda, int *ipiv);
-    int wrapper_clapack_dgetrf(const enum CBLAS_ORDER Order, const int M, const int N, double *A, const int lda, int *ipiv);
-    int wrapper_clapack_cgetrf(const enum CBLAS_ORDER Order, const int M, const int N, void   *A, const int lda, int *ipiv);
-    int wrapper_clapack_zgetrf(const enum CBLAS_ORDER Order, const int M, const int N, void   *A, const int lda, int *ipiv);
-    
-    int wrapper_clapack_sgetri(const enum CBLAS_ORDER Order, const int N, float  *A, const int lda, const int *ipiv);
-    int wrapper_clapack_dgetri(const enum CBLAS_ORDER Order, const int N, double *A, const int lda, const int *ipiv);
-    int wrapper_clapack_cgetri(const enum CBLAS_ORDER Order, const int N, void   *A, const int lda, const int *ipiv);
-    int wrapper_clapack_zgetri(const enum CBLAS_ORDER Order, const int N, void   *A, const int lda, const int *ipiv);
-
-    int wrapper_clapack_sgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, float  *A, const int lda, int *ipiv, float  *B, const int ldb);
-    int wrapper_clapack_dgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, double *A, const int lda, int *ipiv, double *B, const int ldb);
-    int wrapper_clapack_cgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, void   *A, const int lda, int *ipiv, void   *B, const int ldb);
-    int wrapper_clapack_zgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, void   *A, const int lda, int *ipiv, void   *B, const int ldb);
-    
-    }
-  #endif
-  
-  }
-
-
-#endif
--- a/armadillo-2.4.4/include/armadillo_bits/atlas_wrapper.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,303 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-#ifdef ARMA_USE_ATLAS
-
-
-//! \namespace atlas namespace for ATLAS functions (imported from the global namespace)
-namespace atlas
-  {
-  
-  template<typename eT>
-  inline static const eT& tmp_real(const eT& X)              { return X; }
-  
-  template<typename T>
-  inline static const T&  tmp_real(const std::complex<T>& X) { return X.real(); }
-  
-  
-  
-  template<typename eT>
-  arma_inline
-  eT
-  cblas_dot(const int N, const eT* X, const eT* Y)
-    {
-    arma_type_check((is_supported_blas_type<eT>::value == false));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      return eT( arma_atlas(cblas_sdot)(N, (const T*)X, 1, (const T*)Y, 1) );
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      return eT( arma_atlas(cblas_ddot)(N, (const T*)X, 1, (const T*)Y, 1) );
-      }
-    else
-      {
-      return eT(0);
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  arma_inline
-  eT
-  cx_cblas_dot(const int N, const eT* X, const eT* Y)
-    {
-    arma_type_check((is_supported_blas_type<eT>::value == false));
-    
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef typename std::complex<float> T;
-      
-      T out;    
-      arma_atlas(cblas_cdotu_sub)(N, (const T*)X, 1, (const T*)Y, 1, &out);
-      
-      return eT(out);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef typename std::complex<double> T;
-      
-      T out;
-      arma_atlas(cblas_zdotu_sub)(N, (const T*)X, 1, (const T*)Y, 1, &out);
-      
-      return eT(out);
-      }
-    else
-      {
-      return eT(0);
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  cblas_gemv
-    (
-    const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
-    const int M, const int N,
-    const eT alpha,
-    const eT *A, const int lda,
-    const eT *X, const int incX,
-    const eT beta,
-    eT *Y, const int incY
-    )
-    {
-    arma_type_check((is_supported_blas_type<eT>::value == false));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_atlas(cblas_sgemv)(Order, TransA, M, N, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)X, incX, (const T)tmp_real(beta), (T*)Y, incY);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_atlas(cblas_dgemv)(Order, TransA, M, N, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)X, incX, (const T)tmp_real(beta), (T*)Y, incY);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_atlas(cblas_cgemv)(Order, TransA, M, N, (const T*)&alpha, (const T*)A, lda, (const T*)X, incX, (const T*)&beta, (T*)Y, incY);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_atlas(cblas_zgemv)(Order, TransA, M, N, (const T*)&alpha, (const T*)A, lda, (const T*)X, incX, (const T*)&beta, (T*)Y, incY);
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  cblas_gemm
-    (
-    const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
-    const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
-    const int K, const eT alpha, const eT *A,
-    const int lda, const eT *B, const int ldb,
-    const eT beta, eT *C, const int ldc
-    )
-    {
-    arma_type_check((is_supported_blas_type<eT>::value == false));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_atlas(cblas_sgemm)(Order, TransA, TransB, M, N, K, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)B, ldb, (const T)tmp_real(beta), (T*)C, ldc);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_atlas(cblas_dgemm)(Order, TransA, TransB, M, N, K, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)B, ldb, (const T)tmp_real(beta), (T*)C, ldc);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_atlas(cblas_cgemm)(Order, TransA, TransB, M, N, K, (const T*)&alpha, (const T*)A, lda, (const T*)B, ldb, (const T*)&beta, (T*)C, ldc);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_atlas(cblas_zgemm)(Order, TransA, TransB, M, N, K, (const T*)&alpha, (const T*)A, lda, (const T*)B, ldb, (const T*)&beta, (T*)C, ldc);
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  int
-  clapack_getrf
-    (
-    const enum CBLAS_ORDER Order, const int M, const int N,
-    eT *A, const int lda, int *ipiv
-    )
-    {
-    arma_type_check((is_supported_blas_type<eT>::value == false));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      return arma_atlas(clapack_sgetrf)(Order, M, N, (T*)A, lda, ipiv);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      return arma_atlas(clapack_dgetrf)(Order, M, N, (T*)A, lda, ipiv);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      return arma_atlas(clapack_cgetrf)(Order, M, N, (T*)A, lda, ipiv);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      return arma_atlas(clapack_zgetrf)(Order, M, N, (T*)A, lda, ipiv);
-      }
-    else
-      {
-      return -1;
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  int
-  clapack_getri
-    (
-    const enum CBLAS_ORDER Order, const int N, eT *A,
-    const int lda, const int *ipiv
-    )
-    {
-    arma_type_check((is_supported_blas_type<eT>::value == false));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      return arma_atlas(clapack_sgetri)(Order, N, (T*)A, lda, ipiv);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      return arma_atlas(clapack_dgetri)(Order, N, (T*)A, lda, ipiv);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      return arma_atlas(clapack_cgetri)(Order, N, (T*)A, lda, ipiv);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      return arma_atlas(clapack_zgetri)(Order, N, (T*)A, lda, ipiv);
-      }
-    else
-      {
-      return -1;
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  int
-  clapack_gesv
-    (
-    const enum CBLAS_ORDER Order,
-    const int N, const int NRHS,
-    eT* A, const int lda, int* ipiv,
-    eT* B, const int ldb
-    )
-    {
-    arma_type_check((is_supported_blas_type<eT>::value == false));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      return arma_atlas(clapack_sgesv)(Order, N, NRHS, (T*)A, lda, ipiv, (T*)B, ldb);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      return arma_atlas(clapack_dgesv)(Order, N, NRHS, (T*)A, lda, ipiv, (T*)B, ldb);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      return arma_atlas(clapack_cgesv)(Order, N, NRHS, (T*)A, lda, ipiv, (T*)B, ldb);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      return arma_atlas(clapack_zgesv)(Order, N, NRHS, (T*)A, lda, ipiv, (T*)B, ldb);
-      }
-    else
-      {
-      return -1;
-      }
-    }
-
-
-
-  }
-
-#endif
--- a/armadillo-2.4.4/include/armadillo_bits/auxlib_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,224 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// Copyright (C)      2009 Edmund Highcock
-// Copyright (C)      2011 James Sanders
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup auxlib
-//! @{
-
-
-//! wrapper for accessing external functions defined in ATLAS, LAPACK or BLAS libraries
-class auxlib
-  {
-  public:
-  
-  
-  template<const uword row, const uword col>
-  struct pos
-    {
-    static const uword n2 = row + col*2;
-    static const uword n3 = row + col*3;
-    static const uword n4 = row + col*4;
-    };
-  
-  
-  //
-  // inv
-  
-  template<typename eT, typename T1>
-  inline static bool inv(Mat<eT>& out, const Base<eT,T1>& X, const bool slow = false);
-  
-  template<typename eT>
-  inline static bool inv(Mat<eT>& out, const Mat<eT>& A, const bool slow = false);
-  
-  template<typename eT>
-  inline static bool inv_noalias_tinymat(Mat<eT>& out, const Mat<eT>& X, const uword N);
-  
-  template<typename eT>
-  inline static bool inv_inplace_tinymat(Mat<eT>& out, const uword N);
-  
-  template<typename eT>
-  inline static bool inv_inplace_lapack(Mat<eT>& out);
-  
-  
-  //
-  // inv_tr
-  
-  template<typename eT, typename T1>
-  inline static bool inv_tr(Mat<eT>& out, const Base<eT,T1>& X, const uword layout);
-  
-  
-  //
-  // inv_sym
-  
-  template<typename eT, typename T1>
-  inline static bool inv_sym(Mat<eT>& out, const Base<eT,T1>& X, const uword layout);
-  
-  
-  //
-  // inv_sympd
-  
-  template<typename eT, typename T1>
-  inline static bool inv_sympd(Mat<eT>& out, const Base<eT,T1>& X, const uword layout);
-  
-  
-  //
-  // det
-  
-  template<typename eT, typename T1>
-  inline static eT det(const Base<eT,T1>& X, const bool slow = false);
-  
-  template<typename eT>
-  inline static eT det_tinymat(const Mat<eT>& X, const uword N);
-  
-  template<typename eT>
-  inline static eT det_lapack(const Mat<eT>& X, const bool make_copy);
-  
-  
-  //
-  // log_det
-  
-  template<typename eT, typename T1>
-  inline static bool log_det(eT& out_val, typename get_pod_type<eT>::result& out_sign, const Base<eT,T1>& X);
-  
-  
-  //
-  // lu
-  
-  template<typename eT, typename T1>
-  inline static bool lu(Mat<eT>& L, Mat<eT>& U, podarray<blas_int>& ipiv, const Base<eT,T1>& X);
-  
-  template<typename eT, typename T1>
-  inline static bool lu(Mat<eT>& L, Mat<eT>& U, Mat<eT>& P, const Base<eT,T1>& X);
-  
-  template<typename eT, typename T1>
-  inline static bool lu(Mat<eT>& L, Mat<eT>& U, const Base<eT,T1>& X);
-  
-  
-  //
-  // eig
-  
-  template<typename eT, typename T1> 
-  inline static bool eig_sym(Col<eT>& eigval, const Base<eT,T1>& X);
-  
-  template<typename T, typename T1> 
-  inline static bool eig_sym(Col<T>& eigval, const Base<std::complex<T>,T1>& X);
-  
-  template<typename eT, typename T1>
-  inline static bool eig_sym(Col<eT>& eigval, Mat<eT>& eigvec, const Base<eT,T1>& X);
-  
-  template<typename T, typename T1>
-  inline static bool eig_sym(Col<T>& eigval, Mat< std::complex<T> >& eigvec, const Base<std::complex<T>,T1>& X);
-  
-  template<typename T, typename T1>
-  inline static bool eig_gen(Col< std::complex<T> >& eigval, Mat<T>& l_eigvec, Mat<T>& r_eigvec, const Base<T,T1>& X, const char side);
-  
-  template<typename T, typename T1>
-  inline static bool eig_gen(Col< std::complex<T> >& eigval, Mat< std::complex<T> >& l_eigvec, Mat< std::complex<T> >& r_eigvec, const Base< std::complex<T>, T1 >& X, const char side);
-  
-  
-  //
-  // chol
-  
-  template<typename eT, typename T1>
-  inline static bool chol(Mat<eT>& out, const Base<eT,T1>& X);
-  
-  
-  //
-  // qr
-  
-  template<typename eT, typename T1>
-  inline static bool qr(Mat<eT>& Q, Mat<eT>& R, const Base<eT,T1>& X);
-  
-  
-  //
-  // svd
-  
-  template<typename eT, typename T1>
-  inline static bool svd(Col<eT>& S, const Base<eT,T1>& X, uword& n_rows, uword& n_cols);
-  
-  template<typename T, typename T1>
-  inline static bool svd(Col<T>& S, const Base<std::complex<T>, T1>& X, uword& n_rows, uword& n_cols);
-  
-  template<typename eT, typename T1>
-  inline static bool svd(Col<eT>& S, const Base<eT,T1>& X);
-  
-  template<typename T, typename T1>
-  inline static bool svd(Col<T>& S, const Base<std::complex<T>, T1>& X);
-  
-  template<typename eT, typename T1>
-  inline static bool svd(Mat<eT>& U, Col<eT>& S, Mat<eT>& V, const Base<eT,T1>& X);
-  
-  template<typename T, typename T1>
-  inline static bool svd(Mat< std::complex<T> >& U, Col<T>& S, Mat< std::complex<T> >& V, const Base< std::complex<T>, T1>& X);
-  
-  template<typename eT, typename T1>
-  inline static bool svd_econ(Mat<eT>& U, Col<eT>& S, Mat<eT>& V, const Base<eT,T1>& X, const char mode);
-  
-  template<typename T, typename T1>
-  inline static bool svd_econ(Mat< std::complex<T> >& U, Col<T>& S, Mat< std::complex<T> >& V, const Base< std::complex<T>, T1>& X, const char mode);
-  
-  
-  //
-  // solve
-  
-  template<typename eT>
-  inline static bool solve   (Mat<eT>& out, Mat<eT>& A, const Mat<eT>& B, const bool slow = false);
-  
-  template<typename eT>
-  inline static bool solve_od(Mat<eT>& out, Mat<eT>& A, const Mat<eT>& B);
-  
-  template<typename eT>
-  inline static bool solve_ud(Mat<eT>& out, Mat<eT>& A, const Mat<eT>& B);
-  
-  
-  //
-  // solve_tr
-  
-  template<typename eT>
-  inline static bool solve_tr(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const uword layout);
-
-
-  //
-  // Schur decomposition
-  
-  template<typename eT>
-  inline static bool schur_dec(Mat<eT>& Z, Mat<eT>& T, const Mat<eT>& A);
-  
-  template<typename cT>
-  inline static bool schur_dec(Mat<std::complex<cT> >& Z, Mat<std::complex<cT> >& T, const Mat<std::complex<cT> >& A);
-  
-  
-  //
-  // syl (solution of the Sylvester equation AX + XB = C)
-  
-  template<typename eT>
-  inline static bool syl(Mat<eT>& X, const Mat<eT>& A, const Mat<eT>& B, const Mat<eT>& C);
-  
-  
-  //
-  // lyap (solution of the continuous Lyapunov equation AX + XA^H + Q = 0)
-  
-  template<typename eT>
-  inline static bool lyap(Mat<eT>& X, const Mat<eT>& A, const Mat<eT>& Q);
-  
-  
-  //
-  // dlyap (solution of the discrete Lyapunov equation AXA^H - X + Q = 0)
-  
-  template<typename eT>
-  inline static bool dlyap(Mat<eT>& X, const Mat<eT>& A, const Mat<eT>& Q);
-  };
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/auxlib_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2926 +0,0 @@
-// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2012 Conrad Sanderson
-// Copyright (C) 2009 Edmund Highcock
-// Copyright (C) 2011 James Sanders
-// Copyright (C) 2011 Stanislav Funiak
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup auxlib
-//! @{
-
-
-
-//! immediate matrix inverse
-template<typename eT, typename T1>
-inline
-bool
-auxlib::inv(Mat<eT>& out, const Base<eT,T1>& X, const bool slow)
-  {
-  arma_extra_debug_sigprint();
-  
-  out = X.get_ref();
-  
-  arma_debug_check( (out.is_square() == false), "inv(): given matrix is not square" );
-  
-  bool status = false;
-  
-  const uword N = out.n_rows;
-  
-  if( (N <= 4) && (slow == false) )
-    {
-    status = auxlib::inv_inplace_tinymat(out, N);
-    }
-    
-  if( (N > 4) || (status == false) )
-    {
-    status = auxlib::inv_inplace_lapack(out);
-    }
-  
-  return status;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-auxlib::inv(Mat<eT>& out, const Mat<eT>& X, const bool slow)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (X.is_square() == false), "inv(): given matrix is not square" );
-  
-  bool status = false;
-  
-  const uword N = X.n_rows;
-  
-  if( (N <= 4) && (slow == false) )
-    {
-    status = (&out != &X) ? auxlib::inv_noalias_tinymat(out, X, N) : auxlib::inv_inplace_tinymat(out, N);
-    }
-  
-  if( (N > 4) || (status == false) )
-    {
-    out = X;
-    status = auxlib::inv_inplace_lapack(out);
-    }
-  
-  return status;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-auxlib::inv_noalias_tinymat(Mat<eT>& out, const Mat<eT>& X, const uword N)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool det_ok = true;
-  
-  out.set_size(N,N);
-  
-  switch(N)
-    {
-    case 1:
-      {
-      out[0] = eT(1) / X[0];
-      };
-      break;
-      
-    case 2:
-      {
-      const eT* Xm = X.memptr();
-      
-      const eT a = Xm[pos<0,0>::n2];
-      const eT b = Xm[pos<0,1>::n2];
-      const eT c = Xm[pos<1,0>::n2];
-      const eT d = Xm[pos<1,1>::n2];
-      
-      const eT tmp_det = (a*d - b*c);
-      
-      if(tmp_det != eT(0))
-        {
-        eT* outm = out.memptr();
-        
-        outm[pos<0,0>::n2] =  d / tmp_det;
-        outm[pos<0,1>::n2] = -b / tmp_det;
-        outm[pos<1,0>::n2] = -c / tmp_det;
-        outm[pos<1,1>::n2] =  a / tmp_det;
-        }
-      else
-        {
-        det_ok = false;
-        }
-      };
-      break;
-    
-    case 3:
-      {
-      const eT* X_col0 = X.colptr(0);
-      const eT a11 = X_col0[0];
-      const eT a21 = X_col0[1];
-      const eT a31 = X_col0[2];
-      
-      const eT* X_col1 = X.colptr(1);
-      const eT a12 = X_col1[0];
-      const eT a22 = X_col1[1];
-      const eT a32 = X_col1[2];
-      
-      const eT* X_col2 = X.colptr(2);
-      const eT a13 = X_col2[0];
-      const eT a23 = X_col2[1];
-      const eT a33 = X_col2[2];
-      
-      const eT tmp_det = a11*(a33*a22 - a32*a23) - a21*(a33*a12-a32*a13) + a31*(a23*a12 - a22*a13);
-      
-      if(tmp_det != eT(0))
-        {
-        eT* out_col0 = out.colptr(0);
-        out_col0[0] =  (a33*a22 - a32*a23) / tmp_det;
-        out_col0[1] = -(a33*a21 - a31*a23) / tmp_det;
-        out_col0[2] =  (a32*a21 - a31*a22) / tmp_det;
-        
-        eT* out_col1 = out.colptr(1);
-        out_col1[0] = -(a33*a12 - a32*a13) / tmp_det;
-        out_col1[1] =  (a33*a11 - a31*a13) / tmp_det;
-        out_col1[2] = -(a32*a11 - a31*a12) / tmp_det;
-        
-        eT* out_col2 = out.colptr(2);
-        out_col2[0] =  (a23*a12 - a22*a13) / tmp_det;
-        out_col2[1] = -(a23*a11 - a21*a13) / tmp_det;
-        out_col2[2] =  (a22*a11 - a21*a12) / tmp_det;
-        }
-      else
-        {
-        det_ok = false;
-        }
-      };
-      break;
-      
-    case 4:
-      {
-      const eT tmp_det = det(X);
-      
-      if(tmp_det != eT(0))
-        {
-        const eT* Xm   = X.memptr();
-              eT* outm = out.memptr();
-        
-        outm[pos<0,0>::n4] = ( Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] - Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] - Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] + Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
-        outm[pos<1,0>::n4] = ( Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] + Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] + Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] - Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
-        outm[pos<2,0>::n4] = ( Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] + Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] - Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] + Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
-        outm[pos<3,0>::n4] = ( Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] + Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] - Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] ) / tmp_det;
-        
-        outm[pos<0,1>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] - Xm[pos<0,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
-        outm[pos<1,1>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] + Xm[pos<0,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] + Xm[pos<0,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
-        outm[pos<2,1>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] - Xm[pos<0,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
-        outm[pos<3,1>::n4] = ( Xm[pos<0,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] + Xm[pos<0,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] ) / tmp_det;
-        
-        outm[pos<0,2>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,3>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
-        outm[pos<1,2>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,3>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
-        outm[pos<2,2>::n4] = ( Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,0>::n4] + Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,3>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
-        outm[pos<3,2>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,2>::n4] ) / tmp_det;
-        
-        outm[pos<0,3>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4] + Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4] ) / tmp_det;
-        outm[pos<1,3>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4] + Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4] ) / tmp_det;
-        outm[pos<2,3>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4] ) / tmp_det;
-        outm[pos<3,3>::n4] = ( Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4] + Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4] ) / tmp_det;
-        }
-      else
-        {
-        det_ok = false;
-        }
-      };
-      break;
-    
-    default:
-      ;
-    }
-  
-  return det_ok;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-auxlib::inv_inplace_tinymat(Mat<eT>& X, const uword N)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool det_ok = true;
-  
-  // for more info, see:
-  // http://www.dr-lex.34sp.com/random/matrix_inv.html
-  // http://www.cvl.iis.u-tokyo.ac.jp/~miyazaki/tech/teche23.html
-  // http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
-  // http://www.geometrictools.com//LibFoundation/Mathematics/Wm4Matrix4.inl
-  
-  switch(N)
-    {
-    case 1:
-      {
-      X[0] = eT(1) / X[0];
-      };
-      break;
-      
-    case 2:
-      {
-      const eT a = X[pos<0,0>::n2];
-      const eT b = X[pos<0,1>::n2];
-      const eT c = X[pos<1,0>::n2];
-      const eT d = X[pos<1,1>::n2];
-      
-      const eT tmp_det = (a*d - b*c);
-      
-      if(tmp_det != eT(0))
-        {
-        X[pos<0,0>::n2] =  d / tmp_det;
-        X[pos<0,1>::n2] = -b / tmp_det;
-        X[pos<1,0>::n2] = -c / tmp_det;
-        X[pos<1,1>::n2] =  a / tmp_det;
-        }
-      else
-        {
-        det_ok = false;
-        }
-      };
-      break;
-    
-    case 3:
-      {
-      eT* X_col0 = X.colptr(0);
-      eT* X_col1 = X.colptr(1);
-      eT* X_col2 = X.colptr(2);
-      
-      const eT a11 = X_col0[0];
-      const eT a21 = X_col0[1];
-      const eT a31 = X_col0[2];
-      
-      const eT a12 = X_col1[0];
-      const eT a22 = X_col1[1];
-      const eT a32 = X_col1[2];
-      
-      const eT a13 = X_col2[0];
-      const eT a23 = X_col2[1];
-      const eT a33 = X_col2[2];
-      
-      const eT tmp_det = a11*(a33*a22 - a32*a23) - a21*(a33*a12-a32*a13) + a31*(a23*a12 - a22*a13);
-      
-      if(tmp_det != eT(0))
-        {
-        X_col0[0] =  (a33*a22 - a32*a23) / tmp_det;
-        X_col0[1] = -(a33*a21 - a31*a23) / tmp_det;
-        X_col0[2] =  (a32*a21 - a31*a22) / tmp_det;
-        
-        X_col1[0] = -(a33*a12 - a32*a13) / tmp_det;
-        X_col1[1] =  (a33*a11 - a31*a13) / tmp_det;
-        X_col1[2] = -(a32*a11 - a31*a12) / tmp_det;
-        
-        X_col2[0] =  (a23*a12 - a22*a13) / tmp_det;
-        X_col2[1] = -(a23*a11 - a21*a13) / tmp_det;
-        X_col2[2] =  (a22*a11 - a21*a12) / tmp_det;
-        }
-      else
-        {
-        det_ok = false;
-        }
-      };
-      break;
-      
-    case 4:
-      {
-      const eT tmp_det = det(X);
-      
-      if(tmp_det != eT(0))
-        {
-        const Mat<eT> A(X);
-        
-        const eT* Am = A.memptr();
-              eT* Xm = X.memptr();
-        
-        Xm[pos<0,0>::n4] = ( Am[pos<1,2>::n4]*Am[pos<2,3>::n4]*Am[pos<3,1>::n4] - Am[pos<1,3>::n4]*Am[pos<2,2>::n4]*Am[pos<3,1>::n4] + Am[pos<1,3>::n4]*Am[pos<2,1>::n4]*Am[pos<3,2>::n4] - Am[pos<1,1>::n4]*Am[pos<2,3>::n4]*Am[pos<3,2>::n4] - Am[pos<1,2>::n4]*Am[pos<2,1>::n4]*Am[pos<3,3>::n4] + Am[pos<1,1>::n4]*Am[pos<2,2>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
-        Xm[pos<1,0>::n4] = ( Am[pos<1,3>::n4]*Am[pos<2,2>::n4]*Am[pos<3,0>::n4] - Am[pos<1,2>::n4]*Am[pos<2,3>::n4]*Am[pos<3,0>::n4] - Am[pos<1,3>::n4]*Am[pos<2,0>::n4]*Am[pos<3,2>::n4] + Am[pos<1,0>::n4]*Am[pos<2,3>::n4]*Am[pos<3,2>::n4] + Am[pos<1,2>::n4]*Am[pos<2,0>::n4]*Am[pos<3,3>::n4] - Am[pos<1,0>::n4]*Am[pos<2,2>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
-        Xm[pos<2,0>::n4] = ( Am[pos<1,1>::n4]*Am[pos<2,3>::n4]*Am[pos<3,0>::n4] - Am[pos<1,3>::n4]*Am[pos<2,1>::n4]*Am[pos<3,0>::n4] + Am[pos<1,3>::n4]*Am[pos<2,0>::n4]*Am[pos<3,1>::n4] - Am[pos<1,0>::n4]*Am[pos<2,3>::n4]*Am[pos<3,1>::n4] - Am[pos<1,1>::n4]*Am[pos<2,0>::n4]*Am[pos<3,3>::n4] + Am[pos<1,0>::n4]*Am[pos<2,1>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
-        Xm[pos<3,0>::n4] = ( Am[pos<1,2>::n4]*Am[pos<2,1>::n4]*Am[pos<3,0>::n4] - Am[pos<1,1>::n4]*Am[pos<2,2>::n4]*Am[pos<3,0>::n4] - Am[pos<1,2>::n4]*Am[pos<2,0>::n4]*Am[pos<3,1>::n4] + Am[pos<1,0>::n4]*Am[pos<2,2>::n4]*Am[pos<3,1>::n4] + Am[pos<1,1>::n4]*Am[pos<2,0>::n4]*Am[pos<3,2>::n4] - Am[pos<1,0>::n4]*Am[pos<2,1>::n4]*Am[pos<3,2>::n4] ) / tmp_det;
-        
-        Xm[pos<0,1>::n4] = ( Am[pos<0,3>::n4]*Am[pos<2,2>::n4]*Am[pos<3,1>::n4] - Am[pos<0,2>::n4]*Am[pos<2,3>::n4]*Am[pos<3,1>::n4] - Am[pos<0,3>::n4]*Am[pos<2,1>::n4]*Am[pos<3,2>::n4] + Am[pos<0,1>::n4]*Am[pos<2,3>::n4]*Am[pos<3,2>::n4] + Am[pos<0,2>::n4]*Am[pos<2,1>::n4]*Am[pos<3,3>::n4] - Am[pos<0,1>::n4]*Am[pos<2,2>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
-        Xm[pos<1,1>::n4] = ( Am[pos<0,2>::n4]*Am[pos<2,3>::n4]*Am[pos<3,0>::n4] - Am[pos<0,3>::n4]*Am[pos<2,2>::n4]*Am[pos<3,0>::n4] + Am[pos<0,3>::n4]*Am[pos<2,0>::n4]*Am[pos<3,2>::n4] - Am[pos<0,0>::n4]*Am[pos<2,3>::n4]*Am[pos<3,2>::n4] - Am[pos<0,2>::n4]*Am[pos<2,0>::n4]*Am[pos<3,3>::n4] + Am[pos<0,0>::n4]*Am[pos<2,2>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
-        Xm[pos<2,1>::n4] = ( Am[pos<0,3>::n4]*Am[pos<2,1>::n4]*Am[pos<3,0>::n4] - Am[pos<0,1>::n4]*Am[pos<2,3>::n4]*Am[pos<3,0>::n4] - Am[pos<0,3>::n4]*Am[pos<2,0>::n4]*Am[pos<3,1>::n4] + Am[pos<0,0>::n4]*Am[pos<2,3>::n4]*Am[pos<3,1>::n4] + Am[pos<0,1>::n4]*Am[pos<2,0>::n4]*Am[pos<3,3>::n4] - Am[pos<0,0>::n4]*Am[pos<2,1>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
-        Xm[pos<3,1>::n4] = ( Am[pos<0,1>::n4]*Am[pos<2,2>::n4]*Am[pos<3,0>::n4] - Am[pos<0,2>::n4]*Am[pos<2,1>::n4]*Am[pos<3,0>::n4] + Am[pos<0,2>::n4]*Am[pos<2,0>::n4]*Am[pos<3,1>::n4] - Am[pos<0,0>::n4]*Am[pos<2,2>::n4]*Am[pos<3,1>::n4] - Am[pos<0,1>::n4]*Am[pos<2,0>::n4]*Am[pos<3,2>::n4] + Am[pos<0,0>::n4]*Am[pos<2,1>::n4]*Am[pos<3,2>::n4] ) / tmp_det;
-        
-        Xm[pos<0,2>::n4] = ( Am[pos<0,2>::n4]*Am[pos<1,3>::n4]*Am[pos<3,1>::n4] - Am[pos<0,3>::n4]*Am[pos<1,2>::n4]*Am[pos<3,1>::n4] + Am[pos<0,3>::n4]*Am[pos<1,1>::n4]*Am[pos<3,2>::n4] - Am[pos<0,1>::n4]*Am[pos<1,3>::n4]*Am[pos<3,2>::n4] - Am[pos<0,2>::n4]*Am[pos<1,1>::n4]*Am[pos<3,3>::n4] + Am[pos<0,1>::n4]*Am[pos<1,2>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
-        Xm[pos<1,2>::n4] = ( Am[pos<0,3>::n4]*Am[pos<1,2>::n4]*Am[pos<3,0>::n4] - Am[pos<0,2>::n4]*Am[pos<1,3>::n4]*Am[pos<3,0>::n4] - Am[pos<0,3>::n4]*Am[pos<1,0>::n4]*Am[pos<3,2>::n4] + Am[pos<0,0>::n4]*Am[pos<1,3>::n4]*Am[pos<3,2>::n4] + Am[pos<0,2>::n4]*Am[pos<1,0>::n4]*Am[pos<3,3>::n4] - Am[pos<0,0>::n4]*Am[pos<1,2>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
-        Xm[pos<2,2>::n4] = ( Am[pos<0,1>::n4]*Am[pos<1,3>::n4]*Am[pos<3,0>::n4] - Am[pos<0,3>::n4]*Am[pos<1,1>::n4]*Am[pos<3,0>::n4] + Am[pos<0,3>::n4]*Am[pos<1,0>::n4]*Am[pos<3,1>::n4] - Am[pos<0,0>::n4]*Am[pos<1,3>::n4]*Am[pos<3,1>::n4] - Am[pos<0,1>::n4]*Am[pos<1,0>::n4]*Am[pos<3,3>::n4] + Am[pos<0,0>::n4]*Am[pos<1,1>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
-        Xm[pos<3,2>::n4] = ( Am[pos<0,2>::n4]*Am[pos<1,1>::n4]*Am[pos<3,0>::n4] - Am[pos<0,1>::n4]*Am[pos<1,2>::n4]*Am[pos<3,0>::n4] - Am[pos<0,2>::n4]*Am[pos<1,0>::n4]*Am[pos<3,1>::n4] + Am[pos<0,0>::n4]*Am[pos<1,2>::n4]*Am[pos<3,1>::n4] + Am[pos<0,1>::n4]*Am[pos<1,0>::n4]*Am[pos<3,2>::n4] - Am[pos<0,0>::n4]*Am[pos<1,1>::n4]*Am[pos<3,2>::n4] ) / tmp_det;
-        
-        Xm[pos<0,3>::n4] = ( Am[pos<0,3>::n4]*Am[pos<1,2>::n4]*Am[pos<2,1>::n4] - Am[pos<0,2>::n4]*Am[pos<1,3>::n4]*Am[pos<2,1>::n4] - Am[pos<0,3>::n4]*Am[pos<1,1>::n4]*Am[pos<2,2>::n4] + Am[pos<0,1>::n4]*Am[pos<1,3>::n4]*Am[pos<2,2>::n4] + Am[pos<0,2>::n4]*Am[pos<1,1>::n4]*Am[pos<2,3>::n4] - Am[pos<0,1>::n4]*Am[pos<1,2>::n4]*Am[pos<2,3>::n4] ) / tmp_det;
-        Xm[pos<1,3>::n4] = ( Am[pos<0,2>::n4]*Am[pos<1,3>::n4]*Am[pos<2,0>::n4] - Am[pos<0,3>::n4]*Am[pos<1,2>::n4]*Am[pos<2,0>::n4] + Am[pos<0,3>::n4]*Am[pos<1,0>::n4]*Am[pos<2,2>::n4] - Am[pos<0,0>::n4]*Am[pos<1,3>::n4]*Am[pos<2,2>::n4] - Am[pos<0,2>::n4]*Am[pos<1,0>::n4]*Am[pos<2,3>::n4] + Am[pos<0,0>::n4]*Am[pos<1,2>::n4]*Am[pos<2,3>::n4] ) / tmp_det;
-        Xm[pos<2,3>::n4] = ( Am[pos<0,3>::n4]*Am[pos<1,1>::n4]*Am[pos<2,0>::n4] - Am[pos<0,1>::n4]*Am[pos<1,3>::n4]*Am[pos<2,0>::n4] - Am[pos<0,3>::n4]*Am[pos<1,0>::n4]*Am[pos<2,1>::n4] + Am[pos<0,0>::n4]*Am[pos<1,3>::n4]*Am[pos<2,1>::n4] + Am[pos<0,1>::n4]*Am[pos<1,0>::n4]*Am[pos<2,3>::n4] - Am[pos<0,0>::n4]*Am[pos<1,1>::n4]*Am[pos<2,3>::n4] ) / tmp_det;
-        Xm[pos<3,3>::n4] = ( Am[pos<0,1>::n4]*Am[pos<1,2>::n4]*Am[pos<2,0>::n4] - Am[pos<0,2>::n4]*Am[pos<1,1>::n4]*Am[pos<2,0>::n4] + Am[pos<0,2>::n4]*Am[pos<1,0>::n4]*Am[pos<2,1>::n4] - Am[pos<0,0>::n4]*Am[pos<1,2>::n4]*Am[pos<2,1>::n4] - Am[pos<0,1>::n4]*Am[pos<1,0>::n4]*Am[pos<2,2>::n4] + Am[pos<0,0>::n4]*Am[pos<1,1>::n4]*Am[pos<2,2>::n4] ) / tmp_det;
-        }
-      else
-        {
-        det_ok = false;
-        }
-      };
-      break;
-      
-    default:
-      ;
-    }
-  
-  return det_ok;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-auxlib::inv_inplace_lapack(Mat<eT>& out)
-  {
-  arma_extra_debug_sigprint();
-
-  if(out.is_empty())
-    {
-    return true;
-    }
-  
-  #if defined(ARMA_USE_ATLAS)
-    {
-    podarray<int> ipiv(out.n_rows);
-    
-    int info = atlas::clapack_getrf(atlas::CblasColMajor, out.n_rows, out.n_cols, out.memptr(), out.n_rows, ipiv.memptr());
-    
-    if(info == 0)
-      {
-      info = atlas::clapack_getri(atlas::CblasColMajor, out.n_rows, out.memptr(), out.n_rows, ipiv.memptr());
-      }
-    
-    return (info == 0);
-    }
-  #elif defined(ARMA_USE_LAPACK)
-    {
-    blas_int n_rows = out.n_rows;
-    blas_int n_cols = out.n_cols;
-    blas_int info   = 0;
-    
-    podarray<blas_int> ipiv(out.n_rows);
-    
-    // 84 was empirically found -- it is the maximum value suggested by LAPACK (as provided by ATLAS v3.6)
-    // based on tests with various matrix types on 32-bit and 64-bit machines
-    //
-    // the "work" array is deliberately long so that a secondary (time-consuming)
-    // memory allocation is avoided, if possible
-    
-    blas_int work_len = (std::max)(blas_int(1), n_rows*84);
-    podarray<eT> work( static_cast<uword>(work_len) );
-    
-    lapack::getrf(&n_rows, &n_cols, out.memptr(), &n_rows, ipiv.memptr(), &info);
-    
-    if(info == 0)
-      {
-      // query for optimum size of work_len
-      
-      blas_int work_len_tmp = -1;
-      lapack::getri(&n_rows, out.memptr(), &n_rows, ipiv.memptr(), work.memptr(), &work_len_tmp, &info);
-      
-      if(info == 0)
-        {
-        blas_int proposed_work_len = static_cast<blas_int>(access::tmp_real(work[0]));
-        
-        // if necessary, allocate more memory
-        if(work_len < proposed_work_len)
-          {
-          work_len = proposed_work_len;
-          work.set_size( static_cast<uword>(work_len) );
-          }
-        }
-      
-      lapack::getri(&n_rows, out.memptr(), &n_rows, ipiv.memptr(), work.memptr(), &work_len, &info);
-      }
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(out);
-    arma_stop("inv(): use of ATLAS or LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-bool
-auxlib::inv_tr(Mat<eT>& out, const Base<eT,T1>& X, const uword layout)
-  {
-  arma_extra_debug_sigprint();
-  
-  out = X.get_ref();
-  
-  arma_debug_check( (out.is_square() == false), "inv(): given matrix is not square" );
-  
-  if(out.is_empty())
-    {
-    return true;
-    }
-  
-  bool status;
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    char     uplo = (layout == 0) ? 'U' : 'L';
-    char     diag = 'N';
-    blas_int n    = blas_int(out.n_rows);
-    blas_int info = 0;
-    
-    lapack::trtri(&uplo, &diag, &n, out.memptr(), &n, &info);
-    
-    status = (info == 0);
-    }
-  #else
-    {
-    arma_ignore(layout);
-    arma_stop("inv(): use of LAPACK needs to be enabled");
-    status = false;
-    }
-  #endif
-  
-  
-  if(status == true)
-    {
-    if(layout == 0)
-      {
-      // upper triangular
-      out = trimatu(out);
-      }
-    else
-      {
-      // lower triangular      
-      out = trimatl(out);
-      }
-    }
-  
-  return status;
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-bool
-auxlib::inv_sym(Mat<eT>& out, const Base<eT,T1>& X, const uword layout)
-  {
-  arma_extra_debug_sigprint();
-  
-  out = X.get_ref();
-  
-  arma_debug_check( (out.is_square() == false), "inv(): given matrix is not square" );
-  
-  if(out.is_empty())
-    {
-    return true;
-    }
-  
-  bool status;
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    char     uplo  = (layout == 0) ? 'U' : 'L';
-    blas_int n     = blas_int(out.n_rows);
-    blas_int lwork = n*n; // TODO: use lwork = -1 to determine optimal size
-    blas_int info  = 0;
-    
-    podarray<blas_int> ipiv;
-    ipiv.set_size(out.n_rows);
-    
-    podarray<eT> work;
-    work.set_size( uword(lwork) );
-    
-    lapack::sytrf(&uplo, &n, out.memptr(), &n, ipiv.memptr(), work.memptr(), &lwork, &info);
-    
-    status = (info == 0);
-    
-    if(status == true)
-      {
-      lapack::sytri(&uplo, &n, out.memptr(), &n, ipiv.memptr(), work.memptr(), &info);
-      
-      out = (layout == 0) ? symmatu(out) : symmatl(out);
-      
-      status = (info == 0);
-      }
-    }
-  #else
-    {
-    arma_ignore(layout);
-    arma_stop("inv(): use of LAPACK needs to be enabled");
-    status = false;
-    }
-  #endif
-  
-  return status;
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-bool
-auxlib::inv_sympd(Mat<eT>& out, const Base<eT,T1>& X, const uword layout)
-  {
-  arma_extra_debug_sigprint();
-  
-  out = X.get_ref();
-  
-  arma_debug_check( (out.is_square() == false), "inv(): given matrix is not square" );
-  
-  if(out.is_empty())
-    {
-    return true;
-    }
-  
-  bool status;
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    char     uplo = (layout == 0) ? 'U' : 'L';
-    blas_int n    = blas_int(out.n_rows);
-    blas_int info = 0;
-    
-    lapack::potrf(&uplo, &n, out.memptr(), &n, &info);
-    
-    status = (info == 0);
-    
-    if(status == true)
-      {
-      lapack::potri(&uplo, &n, out.memptr(), &n, &info);
-    
-      out = (layout == 0) ? symmatu(out) : symmatl(out);
-    
-      status = (info == 0);
-      }
-    }
-  #else
-    {
-    arma_ignore(layout);
-    arma_stop("inv(): use of LAPACK needs to be enabled");
-    status = false;
-    }
-  #endif
-  
-  return status;
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-eT
-auxlib::det(const Base<eT,T1>& X, const bool slow)
-  {
-  const unwrap<T1>   tmp(X.get_ref());
-  const Mat<eT>& A = tmp.M;
-  
-  arma_debug_check( (A.is_square() == false), "det(): matrix is not square" );
-  
-  const bool make_copy = (is_Mat<T1>::value == true) ? true : false;
-  
-  if(slow == false)
-    {
-    const uword N = A.n_rows;
-    
-    switch(N)
-      {
-      case 0:
-      case 1:
-      case 2:
-        return auxlib::det_tinymat(A, N);
-        break;
-      
-      case 3:
-      case 4:
-        {
-        const eT tmp_det = auxlib::det_tinymat(A, N);
-        return (tmp_det != eT(0)) ? tmp_det : auxlib::det_lapack(A, make_copy);
-        }
-        break;
-      
-      default:
-        return auxlib::det_lapack(A, make_copy);
-      }
-    }
-  else
-    {
-    return auxlib::det_lapack(A, make_copy);
-    }
-  }
-
-
-
-template<typename eT>
-inline
-eT
-auxlib::det_tinymat(const Mat<eT>& X, const uword N)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(N)
-    {
-    case 0:
-      return eT(1);
-      break;
-    
-    case 1:
-      return X[0];
-      break;
-    
-    case 2:
-      {
-      const eT* Xm = X.memptr();
-      
-      return ( Xm[pos<0,0>::n2]*Xm[pos<1,1>::n2] - Xm[pos<0,1>::n2]*Xm[pos<1,0>::n2] );
-      }
-      break;
-    
-    case 3:
-      {
-      // const double tmp1 = X.at(0,0) * X.at(1,1) * X.at(2,2);
-      // const double tmp2 = X.at(0,1) * X.at(1,2) * X.at(2,0);
-      // const double tmp3 = X.at(0,2) * X.at(1,0) * X.at(2,1);
-      // const double tmp4 = X.at(2,0) * X.at(1,1) * X.at(0,2);
-      // const double tmp5 = X.at(2,1) * X.at(1,2) * X.at(0,0);
-      // const double tmp6 = X.at(2,2) * X.at(1,0) * X.at(0,1);
-      // return (tmp1+tmp2+tmp3) - (tmp4+tmp5+tmp6);
-      
-      const eT* a_col0 = X.colptr(0);
-      const eT  a11    = a_col0[0];
-      const eT  a21    = a_col0[1];
-      const eT  a31    = a_col0[2];
-      
-      const eT* a_col1 = X.colptr(1);
-      const eT  a12    = a_col1[0];
-      const eT  a22    = a_col1[1];
-      const eT  a32    = a_col1[2];
-      
-      const eT* a_col2 = X.colptr(2);
-      const eT  a13    = a_col2[0];
-      const eT  a23    = a_col2[1];
-      const eT  a33    = a_col2[2];
-      
-      return ( a11*(a33*a22 - a32*a23) - a21*(a33*a12-a32*a13) + a31*(a23*a12 - a22*a13) );
-      }
-      break;
-      
-    case 4:
-      {
-      const eT* Xm = X.memptr();
-      
-      const eT val = \
-          Xm[pos<0,3>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,0>::n4] \
-        - Xm[pos<0,2>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,0>::n4] \
-        - Xm[pos<0,3>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,0>::n4] \
-        + Xm[pos<0,1>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,0>::n4] \
-        + Xm[pos<0,2>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,0>::n4] \
-        - Xm[pos<0,1>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,0>::n4] \
-        - Xm[pos<0,3>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,1>::n4] \
-        + Xm[pos<0,2>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,1>::n4] \
-        + Xm[pos<0,3>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,1>::n4] \
-        - Xm[pos<0,0>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,1>::n4] \
-        - Xm[pos<0,2>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,1>::n4] \
-        + Xm[pos<0,0>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,1>::n4] \
-        + Xm[pos<0,3>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,2>::n4] \
-        - Xm[pos<0,1>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,2>::n4] \
-        - Xm[pos<0,3>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,2>::n4] \
-        + Xm[pos<0,0>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,2>::n4] \
-        + Xm[pos<0,1>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,2>::n4] \
-        - Xm[pos<0,0>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,2>::n4] \
-        - Xm[pos<0,2>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,3>::n4] \
-        + Xm[pos<0,1>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,3>::n4] \
-        + Xm[pos<0,2>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,3>::n4] \
-        - Xm[pos<0,0>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,3>::n4] \
-        - Xm[pos<0,1>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,3>::n4] \
-        + Xm[pos<0,0>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,3>::n4] \
-        ;
-      
-      return val;
-      }
-      break;
-    
-    default:
-      return eT(0);
-      ;
-    }
-  }
-
-
-
-//! immediate determinant of a matrix using ATLAS or LAPACK
-template<typename eT>
-inline
-eT
-auxlib::det_lapack(const Mat<eT>& X, const bool make_copy)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT> X_copy;
-  
-  if(make_copy == true)
-    {
-    X_copy = X;
-    }
-  
-  Mat<eT>& tmp = (make_copy == true) ? X_copy : const_cast< Mat<eT>& >(X);
-  
-  if(tmp.is_empty())
-    {
-    return eT(1);
-    }
-  
-  
-  #if defined(ARMA_USE_ATLAS)
-    {
-    podarray<int> ipiv(tmp.n_rows);
-    
-    //const int info =
-    atlas::clapack_getrf(atlas::CblasColMajor, tmp.n_rows, tmp.n_cols, tmp.memptr(), tmp.n_rows, ipiv.memptr());
-    
-    // on output tmp appears to be L+U_alt, where U_alt is U with the main diagonal set to zero
-    eT val = tmp.at(0,0);
-    for(uword i=1; i < tmp.n_rows; ++i)
-      {
-      val *= tmp.at(i,i);
-      }
-    
-    int sign = +1;
-    for(uword i=0; i < tmp.n_rows; ++i)
-      {
-      if( int(i) != ipiv.mem[i] )  // NOTE: no adjustment required, as the clapack version of getrf() assumes counting from 0
-        {
-        sign *= -1;
-        }
-      }
-    
-    return ( (sign < 0) ? -val : val );
-    }
-  #elif defined(ARMA_USE_LAPACK)
-    {
-    podarray<blas_int> ipiv(tmp.n_rows);
-    
-    blas_int info   = 0;
-    blas_int n_rows = blas_int(tmp.n_rows);
-    blas_int n_cols = blas_int(tmp.n_cols);
-    
-    lapack::getrf(&n_rows, &n_cols, tmp.memptr(), &n_rows, ipiv.memptr(), &info);
-    
-    // on output tmp appears to be L+U_alt, where U_alt is U with the main diagonal set to zero
-    eT val = tmp.at(0,0);
-    for(uword i=1; i < tmp.n_rows; ++i)
-      {
-      val *= tmp.at(i,i);
-      }
-    
-    blas_int sign = +1;
-    for(uword i=0; i < tmp.n_rows; ++i)
-      {
-      if( blas_int(i) != (ipiv.mem[i] - 1) )  // NOTE: adjustment of -1 is required as Fortran counts from 1
-        {
-        sign *= -1;
-        }
-      }
-    
-    return ( (sign < 0) ? -val : val );
-    }
-  #else
-    {
-    arma_ignore(X);
-    arma_ignore(make_copy);
-    arma_ignore(tmp);
-    arma_stop("det(): use of ATLAS or LAPACK needs to be enabled");
-    return eT(0);
-    }
-  #endif
-  }
-
-
-
-//! immediate log determinant of a matrix using ATLAS or LAPACK
-template<typename eT, typename T1>
-inline
-bool
-auxlib::log_det(eT& out_val, typename get_pod_type<eT>::result& out_sign, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename get_pod_type<eT>::result T;
-  
-  #if defined(ARMA_USE_ATLAS)
-    {
-    Mat<eT> tmp(X.get_ref());
-    arma_debug_check( (tmp.is_square() == false), "log_det(): given matrix is not square" );
-    
-    if(tmp.is_empty())
-      {
-      out_val  = eT(0);
-      out_sign =  T(1);
-      return true;
-      }
-    
-    podarray<int> ipiv(tmp.n_rows);
-    
-    const int info = atlas::clapack_getrf(atlas::CblasColMajor, tmp.n_rows, tmp.n_cols, tmp.memptr(), tmp.n_rows, ipiv.memptr());
-    
-    // on output tmp appears to be L+U_alt, where U_alt is U with the main diagonal set to zero
-    
-    sword sign = (is_complex<eT>::value == false) ? ( (access::tmp_real( tmp.at(0,0) ) < T(0)) ? -1 : +1 ) : +1;
-    eT   val = (is_complex<eT>::value == false) ? std::log( (access::tmp_real( tmp.at(0,0) ) < T(0)) ? tmp.at(0,0)*T(-1) : tmp.at(0,0) ) : std::log( tmp.at(0,0) );
-    
-    for(uword i=1; i < tmp.n_rows; ++i)
-      {
-      const eT x = tmp.at(i,i);
-      
-      sign *= (is_complex<eT>::value == false) ? ( (access::tmp_real(x) < T(0)) ? -1 : +1 ) : +1;
-      val  += (is_complex<eT>::value == false) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x);
-      }
-    
-    for(uword i=0; i < tmp.n_rows; ++i)
-      {
-      if( int(i) != ipiv.mem[i] )  // NOTE: no adjustment required, as the clapack version of getrf() assumes counting from 0
-        {
-        sign *= -1;
-        }
-      }
-    
-    out_val  = val;
-    out_sign = T(sign);
-    
-    return (info == 0);
-    }
-  #elif defined(ARMA_USE_LAPACK)
-    {
-    Mat<eT> tmp(X.get_ref());
-    arma_debug_check( (tmp.is_square() == false), "log_det(): given matrix is not square" );
-    
-    if(tmp.is_empty())
-      {
-      out_val  = eT(0);
-      out_sign =  T(1);
-      return true;
-      }
-    
-    podarray<blas_int> ipiv(tmp.n_rows);
-    
-    blas_int info   = 0;
-    blas_int n_rows = blas_int(tmp.n_rows);
-    blas_int n_cols = blas_int(tmp.n_cols);
-    
-    lapack::getrf(&n_rows, &n_cols, tmp.memptr(), &n_rows, ipiv.memptr(), &info);
-    
-    // on output tmp appears to be L+U_alt, where U_alt is U with the main diagonal set to zero
-    
-    sword sign = (is_complex<eT>::value == false) ? ( (access::tmp_real( tmp.at(0,0) ) < T(0)) ? -1 : +1 ) : +1;
-    eT   val = (is_complex<eT>::value == false) ? std::log( (access::tmp_real( tmp.at(0,0) ) < T(0)) ? tmp.at(0,0)*T(-1) : tmp.at(0,0) ) : std::log( tmp.at(0,0) );
-    
-    for(uword i=1; i < tmp.n_rows; ++i)
-      {
-      const eT x = tmp.at(i,i);
-      
-      sign *= (is_complex<eT>::value == false) ? ( (access::tmp_real(x) < T(0)) ? -1 : +1 ) : +1;
-      val  += (is_complex<eT>::value == false) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x);
-      }
-    
-    for(uword i=0; i < tmp.n_rows; ++i)
-      {
-      if( blas_int(i) != (ipiv.mem[i] - 1) )  // NOTE: adjustment of -1 is required as Fortran counts from 1
-        {
-        sign *= -1;
-        }
-      }
-    
-    out_val  = val;
-    out_sign = T(sign);
-    
-    return (info == 0);
-    }
-  #else
-    {
-    out_val  = eT(0);
-    out_sign =  T(0);
-    
-    arma_stop("log_det(): use of ATLAS or LAPACK needs to be enabled");
-    
-    return false;
-    }
-  #endif
-  }
-
-
-
-//! immediate LU decomposition of a matrix using ATLAS or LAPACK
-template<typename eT, typename T1>
-inline
-bool
-auxlib::lu(Mat<eT>& L, Mat<eT>& U, podarray<blas_int>& ipiv, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  U = X.get_ref();
-  
-  const uword U_n_rows = U.n_rows;
-  const uword U_n_cols = U.n_cols;
-  
-  if(U.is_empty())
-    {
-    L.set_size(U_n_rows, 0);
-    U.set_size(0, U_n_cols);
-    ipiv.reset();
-    return true;
-    }
-  
-  #if defined(ARMA_USE_ATLAS) || defined(ARMA_USE_LAPACK)
-    {
-    bool status;
-    
-    #if defined(ARMA_USE_ATLAS)
-      {
-      ipiv.set_size( (std::min)(U_n_rows, U_n_cols) );
-      
-      int info = atlas::clapack_getrf(atlas::CblasColMajor, U_n_rows, U_n_cols, U.memptr(), U_n_rows, ipiv.memptr());
-      
-      status = (info == 0);
-      }
-    #elif defined(ARMA_USE_LAPACK)
-      {
-      ipiv.set_size( (std::min)(U_n_rows, U_n_cols) );
-      
-      blas_int info = 0;
-      
-      blas_int n_rows = U_n_rows;
-      blas_int n_cols = U_n_cols;
-      
-      
-      lapack::getrf(&n_rows, &n_cols, U.memptr(), &n_rows, ipiv.memptr(), &info);
-      
-      // take into account that Fortran counts from 1
-      arrayops::inplace_minus(ipiv.memptr(), blas_int(1), ipiv.n_elem);
-      
-      status = (info == 0);
-      }
-    #endif
-    
-    L.copy_size(U);
-    
-    for(uword col=0; col < U_n_cols; ++col)
-      {
-      for(uword row=0; (row < col) && (row < U_n_rows); ++row)
-        {
-        L.at(row,col) = eT(0);
-        }
-      
-      if( L.in_range(col,col) == true )
-        {
-        L.at(col,col) = eT(1);
-        }
-      
-      for(uword row = (col+1); row < U_n_rows; ++row)
-        {
-        L.at(row,col) = U.at(row,col);
-        U.at(row,col) = eT(0);
-        }
-      }
-    
-    return status;
-    }
-  #else
-    {
-    arma_stop("lu(): use of ATLAS or LAPACK needs to be enabled");
-    
-    return false;
-    }
-  #endif
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-bool
-auxlib::lu(Mat<eT>& L, Mat<eT>& U, Mat<eT>& P, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  podarray<blas_int> ipiv1;
-  const bool status = auxlib::lu(L, U, ipiv1, X);
-  
-  if(status == true)
-    {
-    if(U.is_empty())
-      {
-      // L and U have been already set to the correct empty matrices
-      P.eye(L.n_rows, L.n_rows);
-      return true;
-      }
-    
-    const uword n      = ipiv1.n_elem;
-    const uword P_rows = U.n_rows;
-    
-    podarray<blas_int> ipiv2(P_rows);
-    
-    const blas_int* ipiv1_mem = ipiv1.memptr();
-          blas_int* ipiv2_mem = ipiv2.memptr();
-    
-    for(uword i=0; i<P_rows; ++i)
-      {
-      ipiv2_mem[i] = blas_int(i);
-      }
-    
-    for(uword i=0; i<n; ++i)
-      {
-      const uword k = static_cast<uword>(ipiv1_mem[i]);
-      
-      if( ipiv2_mem[i] != ipiv2_mem[k] )
-        {
-        std::swap( ipiv2_mem[i], ipiv2_mem[k] );
-        }
-      }
-    
-    P.zeros(P_rows, P_rows);
-    
-    for(uword row=0; row<P_rows; ++row)
-      {
-      P.at(row, static_cast<uword>(ipiv2_mem[row])) = eT(1);
-      }
-    
-    if(L.n_cols > U.n_rows)
-      {
-      L.shed_cols(U.n_rows, L.n_cols-1);
-      }
-      
-    if(U.n_rows > L.n_cols)
-      {
-      U.shed_rows(L.n_cols, U.n_rows-1);
-      }
-    }
-  
-  return status;
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-bool
-auxlib::lu(Mat<eT>& L, Mat<eT>& U, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  podarray<blas_int> ipiv1;
-  const bool status = auxlib::lu(L, U, ipiv1, X);
-  
-  if(status == true)
-    {
-    if(U.is_empty())
-      {
-      // L and U have been already set to the correct empty matrices
-      return true;
-      }
-    
-    const uword n      = ipiv1.n_elem;
-    const uword P_rows = U.n_rows;
-    
-    podarray<blas_int> ipiv2(P_rows);
-    
-    const blas_int* ipiv1_mem = ipiv1.memptr();
-          blas_int* ipiv2_mem = ipiv2.memptr();
-    
-    for(uword i=0; i<P_rows; ++i)
-      {
-      ipiv2_mem[i] = blas_int(i);
-      }
-    
-    for(uword i=0; i<n; ++i)
-      {
-      const uword k = static_cast<uword>(ipiv1_mem[i]);
-      
-      if( ipiv2_mem[i] != ipiv2_mem[k] )
-        {
-        std::swap( ipiv2_mem[i], ipiv2_mem[k] );
-        L.swap_rows( static_cast<uword>(ipiv2_mem[i]), static_cast<uword>(ipiv2_mem[k]) );
-        }
-      }
-    
-    if(L.n_cols > U.n_rows)
-      {
-      L.shed_cols(U.n_rows, L.n_cols-1);
-      }
-      
-    if(U.n_rows > L.n_cols)
-      {
-      U.shed_rows(L.n_cols, U.n_rows-1);
-      }
-    }
-  
-  return status;
-  }
-
-
-
-//! immediate eigenvalues of a symmetric real matrix using LAPACK
-template<typename eT, typename T1>
-inline
-bool
-auxlib::eig_sym(Col<eT>& eigval, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    Mat<eT> A(X.get_ref());
-    
-    arma_debug_check( (A.is_square() == false), "eig_sym(): given matrix is not square");
-    
-    if(A.is_empty())
-      {
-      eigval.reset();
-      return true;
-      }
-    
-    // rudimentary "better-than-nothing" test for symmetry
-    //arma_debug_check( (A.at(A.n_rows-1, 0) != A.at(0, A.n_cols-1)), "auxlib::eig(): given matrix is not symmetric" );
-    
-    char jobz  = 'N';
-    char uplo  = 'U';
-    
-    blas_int n_rows = A.n_rows;
-    blas_int lwork  = (std::max)(blas_int(1), 3*n_rows-1);
-    
-    eigval.set_size( static_cast<uword>(n_rows) );
-    podarray<eT> work( static_cast<uword>(lwork) );
-    
-    blas_int info;
-    
-    arma_extra_debug_print("lapack::syev()");
-    lapack::syev(&jobz, &uplo, &n_rows, A.memptr(), &n_rows, eigval.memptr(), work.memptr(), &lwork, &info);
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(eigval);
-    arma_ignore(X);
-    arma_stop("eig_sym(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-//! immediate eigenvalues of a hermitian complex matrix using LAPACK
-template<typename T, typename T1>
-inline
-bool
-auxlib::eig_sym(Col<T>& eigval, const Base<std::complex<T>,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T> eT;
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    Mat<eT> A(X.get_ref());
-    arma_debug_check( (A.is_square() == false), "eig_sym(): given matrix is not hermitian");
-    
-    if(A.is_empty())
-      {
-      eigval.reset();
-      return true;
-      }
-    
-    char jobz  = 'N'; 
-    char uplo  = 'U';
-    
-    blas_int n_rows = A.n_rows;
-    blas_int lda    = A.n_rows;
-    blas_int lwork  = (std::max)(blas_int(1), 2*n_rows - 1);  // TODO: automatically find best size of lwork
-    
-    eigval.set_size( static_cast<uword>(n_rows) );
-    
-    podarray<eT> work( static_cast<uword>(lwork) );
-    podarray<T>  rwork( static_cast<uword>((std::max)(blas_int(1), 3*n_rows - 2)) );
-    
-    blas_int info;
-    
-    arma_extra_debug_print("lapack::heev()");
-    lapack::heev(&jobz, &uplo, &n_rows, A.memptr(), &lda, eigval.memptr(), work.memptr(), &lwork, rwork.memptr(), &info);
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(eigval);
-    arma_ignore(X);
-    arma_stop("eig_sym(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-//! immediate eigenvalues and eigenvectors of a symmetric real matrix using LAPACK
-template<typename eT, typename T1>
-inline
-bool
-auxlib::eig_sym(Col<eT>& eigval, Mat<eT>& eigvec, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    eigvec = X.get_ref();
-    
-    arma_debug_check( (eigvec.is_square() == false), "eig_sym(): given matrix is not square" );
-    
-    if(eigvec.is_empty())
-      {
-      eigval.reset();
-      eigvec.reset();
-      return true;
-      }
-    
-    // rudimentary "better-than-nothing" test for symmetry
-    //arma_debug_check( (A.at(A.n_rows-1, 0) != A.at(0, A.n_cols-1)), "auxlib::eig(): given matrix is not symmetric" );
-    
-    char jobz  = 'V';
-    char uplo  = 'U';
-    
-    blas_int n_rows = eigvec.n_rows;
-    blas_int lwork  = (std::max)(blas_int(1), 3*n_rows-1);
-    
-    eigval.set_size( static_cast<uword>(n_rows) );
-    podarray<eT> work( static_cast<uword>(lwork) );
-    
-    blas_int info;
-    
-    arma_extra_debug_print("lapack::syev()");
-    lapack::syev(&jobz, &uplo, &n_rows, eigvec.memptr(), &n_rows, eigval.memptr(), work.memptr(), &lwork, &info);
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(eigval);
-    arma_ignore(eigvec);
-    arma_stop("eig_sym(): use of LAPACK needs to be enabled");
-    
-    return false;
-    }
-  #endif
-  }
-
-
-
-//! immediate eigenvalues and eigenvectors of a hermitian complex matrix using LAPACK
-template<typename T, typename T1>
-inline
-bool
-auxlib::eig_sym(Col<T>& eigval, Mat< std::complex<T> >& eigvec, const Base<std::complex<T>,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T> eT;
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    eigvec = X.get_ref();
-    
-    arma_debug_check( (eigvec.is_square() == false), "eig_sym(): given matrix is not hermitian" );
-    
-    if(eigvec.is_empty())
-      {
-      eigval.reset();
-      eigvec.reset();
-      return true;
-      }
-    
-    char jobz  = 'V';
-    char uplo  = 'U';
-    
-    blas_int n_rows = eigvec.n_rows;
-    blas_int lda    = eigvec.n_rows;
-    blas_int lwork  = (std::max)(blas_int(1), 2*n_rows - 1);  // TODO: automatically find best size of lwork
-    
-    eigval.set_size( static_cast<uword>(n_rows) );
-    
-    podarray<eT> work( static_cast<uword>(lwork) );
-    podarray<T>  rwork( static_cast<uword>((std::max)(blas_int(1), 3*n_rows - 2)) );
-    
-    blas_int info;
-    
-    arma_extra_debug_print("lapack::heev()");
-    lapack::heev(&jobz, &uplo, &n_rows, eigvec.memptr(), &lda, eigval.memptr(), work.memptr(), &lwork, rwork.memptr(), &info);
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(eigval);
-    arma_ignore(eigvec);
-    arma_ignore(X);
-    arma_stop("eig_sym(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-//! Eigenvalues and eigenvectors of a general square real matrix using LAPACK.
-//! The argument 'side' specifies which eigenvectors should be calculated
-//! (see code for mode details).
-template<typename T, typename T1>
-inline
-bool
-auxlib::eig_gen
-  (
-  Col< std::complex<T> >& eigval,
-  Mat<T>& l_eigvec,
-  Mat<T>& r_eigvec,
-  const Base<T,T1>& X,
-  const char side
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    char jobvl;
-    char jobvr;
-    
-    switch(side)
-      {
-      case 'l':  // left
-        jobvl = 'V';
-        jobvr = 'N';
-        break;
-        
-      case 'r':  // right
-        jobvl = 'N';
-        jobvr = 'V';
-        break;
-        
-      case 'b':  // both
-        jobvl = 'V';
-        jobvr = 'V';
-        break;
-        
-      case 'n':  // neither
-        jobvl = 'N';
-        jobvr = 'N';
-        break;
-      
-      default:
-        arma_stop("eig_gen(): parameter 'side' is invalid");
-        return false;
-      }
-    
-    Mat<T> A(X.get_ref());
-    arma_debug_check( (A.is_square() == false), "eig_gen(): given matrix is not square" );
-    
-    if(A.is_empty())
-      {
-      eigval.reset();
-      l_eigvec.reset();
-      r_eigvec.reset();
-      return true;
-      }
-    
-    uword A_n_rows = A.n_rows;
-    
-    blas_int n_rows = A_n_rows;
-    blas_int lda    = A_n_rows;
-    blas_int lwork  = (std::max)(blas_int(1), 4*n_rows);  // TODO: automatically find best size of lwork
-    
-    eigval.set_size(A_n_rows);
-    l_eigvec.set_size(A_n_rows, A_n_rows);
-    r_eigvec.set_size(A_n_rows, A_n_rows);
-    
-    podarray<T> work( static_cast<uword>(lwork) );
-    podarray<T> rwork( static_cast<uword>((std::max)(blas_int(1), 3*n_rows)) );
-    
-    podarray<T> wr(A_n_rows);
-    podarray<T> wi(A_n_rows);
-    
-    Mat<T> A_copy = A;
-    blas_int info;
-    
-    arma_extra_debug_print("lapack::geev()");
-    lapack::geev(&jobvl, &jobvr, &n_rows, A_copy.memptr(), &lda, wr.memptr(), wi.memptr(), l_eigvec.memptr(), &n_rows, r_eigvec.memptr(), &n_rows, work.memptr(), &lwork, &info);
-    
-    
-    eigval.set_size(A_n_rows);
-    for(uword i=0; i<A_n_rows; ++i)
-      {
-      eigval[i] = std::complex<T>(wr[i], wi[i]);
-      }
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(eigval);
-    arma_ignore(l_eigvec);
-    arma_ignore(r_eigvec);
-    arma_ignore(X);
-    arma_ignore(side);
-    arma_stop("eig_gen(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-
-
-//! Eigenvalues and eigenvectors of a general square complex matrix using LAPACK
-//! The argument 'side' specifies which eigenvectors should be calculated
-//! (see code for mode details).
-template<typename T, typename T1>
-inline
-bool
-auxlib::eig_gen
-  (
-  Col< std::complex<T> >& eigval,
-  Mat< std::complex<T> >& l_eigvec, 
-  Mat< std::complex<T> >& r_eigvec, 
-  const Base< std::complex<T>, T1 >& X, 
-  const char side
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T> eT;
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    char jobvl;
-    char jobvr;
-    
-    switch(side)
-      {
-      case 'l':  // left
-        jobvl = 'V';
-        jobvr = 'N';
-        break;
-        
-      case 'r':  // right
-        jobvl = 'N';
-        jobvr = 'V';
-        break;
-        
-      case 'b':  // both
-        jobvl = 'V';
-        jobvr = 'V';
-        break;
-        
-      case 'n':  // neither
-        jobvl = 'N';
-        jobvr = 'N';
-        break;
-      
-      default:
-        arma_stop("eig_gen(): parameter 'side' is invalid");
-        return false;
-      }
-    
-    Mat<eT> A(X.get_ref());
-    arma_debug_check( (A.is_square() == false), "eig_gen(): given matrix is not square" );
-    
-    if(A.is_empty())
-      {
-      eigval.reset();
-      l_eigvec.reset();
-      r_eigvec.reset();
-      return true;
-      }
-    
-    uword A_n_rows = A.n_rows;
-       
-    blas_int n_rows = A_n_rows;
-    blas_int lda    = A_n_rows;
-    blas_int lwork  = (std::max)(blas_int(1), 4*n_rows);  // TODO: automatically find best size of lwork
-    
-    eigval.set_size(A_n_rows);
-    l_eigvec.set_size(A_n_rows, A_n_rows);
-    r_eigvec.set_size(A_n_rows, A_n_rows);
-    
-    podarray<eT> work( static_cast<uword>(lwork) );
-    podarray<T>  rwork( static_cast<uword>((std::max)(blas_int(1), 3*n_rows)) );  // was 2,3
-    
-    blas_int info;
-    
-    arma_extra_debug_print("lapack::cx_geev()");
-    lapack::cx_geev(&jobvl, &jobvr, &n_rows, A.memptr(), &lda, eigval.memptr(), l_eigvec.memptr(), &n_rows, r_eigvec.memptr(), &n_rows, work.memptr(), &lwork, rwork.memptr(), &info);
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(eigval);
-    arma_ignore(l_eigvec);
-    arma_ignore(r_eigvec);
-    arma_ignore(X);
-    arma_ignore(side);
-    arma_stop("eig_gen(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-bool
-auxlib::chol(Mat<eT>& out, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    out = X.get_ref();
-    
-    arma_debug_check( (out.is_square() == false), "chol(): given matrix is not square" );
-    
-    if(out.is_empty())
-      {
-      return true;
-      }
-    
-    const uword out_n_rows = out.n_rows;
-    
-    char      uplo = 'U';
-    blas_int  n    = out_n_rows;
-    blas_int  info;
-    
-    lapack::potrf(&uplo, &n, out.memptr(), &n, &info);
-    
-    for(uword col=0; col<out_n_rows; ++col)
-      {
-      eT* colptr = out.colptr(col);
-      
-      for(uword row=(col+1); row < out_n_rows; ++row)
-        {
-        colptr[row] = eT(0);
-        }
-      }
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(out);
-    arma_stop("chol(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-bool 
-auxlib::qr(Mat<eT>& Q, Mat<eT>& R, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    R = X.get_ref();
-    
-    const uword R_n_rows = R.n_rows;
-    const uword R_n_cols = R.n_cols;
-    
-    if(R.is_empty())
-      {
-      Q.eye(R_n_rows, R_n_rows);
-      return true;
-      }
-    
-    blas_int m            = static_cast<blas_int>(R_n_rows);
-    blas_int n            = static_cast<blas_int>(R_n_cols);
-    blas_int work_len     = (std::max)(blas_int(1),n);
-    blas_int work_len_tmp;
-    blas_int k            = (std::min)(m,n);
-    blas_int info;
-    
-    podarray<eT> tau( static_cast<uword>(k) );
-    podarray<eT> work( static_cast<uword>(work_len) );
-    
-    // query for the optimum value of work_len
-    work_len_tmp = -1;
-    lapack::geqrf(&m, &n, R.memptr(), &m, tau.memptr(), work.memptr(), &work_len_tmp, &info);
-    
-    if(info == 0)
-      {
-      work_len = static_cast<blas_int>(access::tmp_real(work[0]));
-      work.set_size( static_cast<uword>(work_len) );
-      }
-    
-    lapack::geqrf(&m, &n, R.memptr(), &m, tau.memptr(), work.memptr(), &work_len, &info);
-    
-    Q.set_size(R_n_rows, R_n_rows);
-    
-    arrayops::copy( Q.memptr(), R.memptr(), (std::min)(Q.n_elem, R.n_elem) );
-    
-    //
-    // construct R
-    
-    for(uword col=0; col < R_n_cols; ++col)
-      {
-      for(uword row=(col+1); row < R_n_rows; ++row)
-        {
-        R.at(row,col) = eT(0);
-        }
-      }
-    
-    
-    if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
-      {
-      // query for the optimum value of work_len
-      work_len_tmp = -1;
-      lapack::orgqr(&m, &m, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &work_len_tmp, &info);
-      
-      if(info == 0)
-        {
-        work_len = static_cast<blas_int>(access::tmp_real(work[0]));
-        work.set_size( static_cast<uword>(work_len) );
-        }
-      
-      lapack::orgqr(&m, &m, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &work_len, &info);
-      }
-    else
-    if( (is_supported_complex_float<eT>::value == true) || (is_supported_complex_double<eT>::value == true) )
-      {
-      // query for the optimum value of work_len
-      work_len_tmp = -1;
-      lapack::ungqr(&m, &m, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &work_len_tmp, &info);
-      
-      if(info == 0)
-        {
-        work_len = static_cast<blas_int>(access::tmp_real(work[0]));
-        work.set_size( static_cast<uword>(work_len) );
-        }
-      
-      lapack::ungqr(&m, &m, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &work_len, &info);
-      }
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(Q);
-    arma_ignore(R);
-    arma_ignore(X);
-    arma_stop("qr(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-bool
-auxlib::svd(Col<eT>& S, const Base<eT,T1>& X, uword& X_n_rows, uword& X_n_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    Mat<eT> A(X.get_ref());
-    
-    X_n_rows = A.n_rows;
-    X_n_cols = A.n_cols;
-    
-    if(A.is_empty())
-      {
-      S.reset();
-      return true;
-      }
-    
-    Mat<eT> U(1, 1);
-    Mat<eT> V(1, A.n_cols);
-    
-    char jobu  = 'N';
-    char jobvt = 'N';
-    
-    blas_int  m     = A.n_rows;
-    blas_int  n     = A.n_cols;
-    blas_int  lda   = A.n_rows;
-    blas_int  ldu   = U.n_rows;
-    blas_int  ldvt  = V.n_rows;
-    blas_int  lwork = 2 * (std::max)(blas_int(1), (std::max)( (3*(std::min)(m,n) + (std::max)(m,n)), 5*(std::min)(m,n) ) );
-    blas_int  info;
-    
-    S.set_size( static_cast<uword>((std::min)(m, n)) );
-    
-    podarray<eT> work( static_cast<uword>(lwork) );
-  
-  
-    // let gesvd_() calculate the optimum size of the workspace
-    blas_int lwork_tmp = -1;
-    
-    lapack::gesvd<eT>
-      (
-      &jobu, &jobvt,
-      &m,&n,
-      A.memptr(), &lda,
-      S.memptr(),
-      U.memptr(), &ldu,
-      V.memptr(), &ldvt,
-      work.memptr(), &lwork_tmp,
-      &info
-      );
-    
-    if(info == 0)
-      {
-      blas_int proposed_lwork = static_cast<blas_int>(work[0]);
-      
-      if(proposed_lwork > lwork)
-        {
-        lwork = proposed_lwork;
-        work.set_size( static_cast<uword>(lwork) );
-        }
-      
-      lapack::gesvd<eT>
-        (
-        &jobu, &jobvt,
-        &m, &n,
-        A.memptr(), &lda,
-        S.memptr(),
-        U.memptr(), &ldu,
-        V.memptr(), &ldvt,
-        work.memptr(), &lwork,
-        &info
-        );
-      }
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(S);
-    arma_ignore(X);
-    arma_ignore(X_n_rows);
-    arma_ignore(X_n_cols);
-    arma_stop("svd(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-template<typename T, typename T1>
-inline
-bool
-auxlib::svd(Col<T>& S, const Base<std::complex<T>, T1>& X, uword& X_n_rows, uword& X_n_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef std::complex<T> eT;
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    Mat<eT> A(X.get_ref());
-    
-    X_n_rows = A.n_rows;
-    X_n_cols = A.n_cols;
-    
-    if(A.is_empty())
-      {
-      S.reset();
-      return true;
-      }
-    
-    Mat<eT> U(1, 1);
-    Mat<eT> V(1, A.n_cols);
-    
-    char jobu  = 'N';
-    char jobvt = 'N';
-    
-    blas_int  m     = A.n_rows;
-    blas_int  n     = A.n_cols;
-    blas_int  lda   = A.n_rows;
-    blas_int  ldu   = U.n_rows;
-    blas_int  ldvt  = V.n_rows;
-    blas_int  lwork = 2 * (std::max)(blas_int(1), 2*(std::min)(m,n)+(std::max)(m,n) );
-    blas_int  info;
-    
-    S.set_size( static_cast<uword>((std::min)(m,n)) );
-    
-    podarray<eT> work( static_cast<uword>(lwork) );
-    podarray<T>  rwork( static_cast<uword>(5*(std::min)(m,n)) );
-    
-    // let gesvd_() calculate the optimum size of the workspace
-    blas_int lwork_tmp = -1;
-    
-    lapack::cx_gesvd<T>
-      (
-      &jobu, &jobvt,
-      &m, &n,
-      A.memptr(), &lda,
-      S.memptr(),
-      U.memptr(), &ldu,
-      V.memptr(), &ldvt,
-      work.memptr(), &lwork_tmp,
-      rwork.memptr(),
-      &info
-      );
-    
-    if(info == 0)
-      {
-      blas_int proposed_lwork = static_cast<blas_int>(real(work[0]));
-      if(proposed_lwork > lwork)
-        {
-        lwork = proposed_lwork;
-        work.set_size( static_cast<uword>(lwork) );
-        }
-      
-      lapack::cx_gesvd<T>
-        (
-        &jobu, &jobvt,
-        &m, &n,
-        A.memptr(), &lda,
-        S.memptr(),
-        U.memptr(), &ldu,
-        V.memptr(), &ldvt,
-        work.memptr(), &lwork,
-        rwork.memptr(),
-        &info
-        );
-      }
-        
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(S);
-    arma_ignore(X);
-    arma_ignore(X_n_rows);
-    arma_ignore(X_n_cols);
-
-    arma_stop("svd(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-bool
-auxlib::svd(Col<eT>& S, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  uword junk;
-  return auxlib::svd(S, X, junk, junk);
-  }
-
-
-
-template<typename T, typename T1>
-inline
-bool
-auxlib::svd(Col<T>& S, const Base<std::complex<T>, T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  uword junk;
-  return auxlib::svd(S, X, junk, junk);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-bool
-auxlib::svd(Mat<eT>& U, Col<eT>& S, Mat<eT>& V, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    Mat<eT> A(X.get_ref());
-    
-    if(A.is_empty())
-      {
-      U.eye(A.n_rows, A.n_rows);
-      S.reset();
-      V.eye(A.n_cols, A.n_cols);
-      return true;
-      }
-    
-    U.set_size(A.n_rows, A.n_rows);
-    V.set_size(A.n_cols, A.n_cols);
-    
-    char jobu  = 'A';
-    char jobvt = 'A';
-    
-    blas_int  m     = A.n_rows;
-    blas_int  n     = A.n_cols;
-    blas_int  lda   = A.n_rows;
-    blas_int  ldu   = U.n_rows;
-    blas_int  ldvt  = V.n_rows;
-    blas_int  lwork = 2 * (std::max)(blas_int(1), (std::max)( (3*(std::min)(m,n) + (std::max)(m,n)), 5*(std::min)(m,n) ) );
-    blas_int  info;
-    
-    
-    S.set_size( static_cast<uword>((std::min)(m,n)) );
-    podarray<eT> work( static_cast<uword>(lwork) );
-  
-    // let gesvd_() calculate the optimum size of the workspace
-    blas_int lwork_tmp = -1;
-    
-    lapack::gesvd<eT>
-      (
-      &jobu, &jobvt,
-      &m, &n,
-      A.memptr(), &lda,
-      S.memptr(),
-      U.memptr(), &ldu,
-      V.memptr(), &ldvt,
-      work.memptr(), &lwork_tmp,
-      &info
-      );
-    
-    if(info == 0)
-      {
-      blas_int proposed_lwork = static_cast<blas_int>(work[0]);
-      if(proposed_lwork > lwork)
-        {
-        lwork = proposed_lwork;
-        work.set_size( static_cast<uword>(lwork) );
-        }
-      
-      lapack::gesvd<eT>
-        (
-        &jobu, &jobvt,
-        &m, &n,
-        A.memptr(), &lda,
-        S.memptr(),
-        U.memptr(), &ldu,
-        V.memptr(), &ldvt,
-        work.memptr(), &lwork,
-        &info
-        );
-      
-      op_strans::apply(V,V);  // op_strans will work out that an in-place transpose can be done
-      }
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(U);
-    arma_ignore(S);
-    arma_ignore(V);
-    arma_ignore(X);
-    arma_stop("svd(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-template<typename T, typename T1>
-inline
-bool
-auxlib::svd(Mat< std::complex<T> >& U, Col<T>& S, Mat< std::complex<T> >& V, const Base< std::complex<T>, T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef std::complex<T> eT;
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    Mat<eT> A(X.get_ref());
-    
-    if(A.is_empty())
-      {
-      U.eye(A.n_rows, A.n_rows);
-      S.reset();
-      V.eye(A.n_cols, A.n_cols);
-      return true;
-      }
-    
-    U.set_size(A.n_rows, A.n_rows);
-    V.set_size(A.n_cols, A.n_cols);
-    
-    char jobu  = 'A';
-    char jobvt = 'A';
-    
-    blas_int  m     = A.n_rows;
-    blas_int  n     = A.n_cols;
-    blas_int  lda   = A.n_rows;
-    blas_int  ldu   = U.n_rows;
-    blas_int  ldvt  = V.n_rows;
-    blas_int  lwork = 2 * (std::max)(blas_int(1), 2*(std::min)(m,n)+(std::max)(m,n) );
-    blas_int  info;
-    
-    S.set_size( static_cast<uword>((std::min)(m,n)) );
-    
-    podarray<eT> work( static_cast<uword>(lwork) );
-    podarray<T>  rwork( static_cast<uword>(5*(std::min)(m,n)) );
-    
-    // let gesvd_() calculate the optimum size of the workspace
-    blas_int lwork_tmp = -1;
-    lapack::cx_gesvd<T>
-     (
-     &jobu, &jobvt,
-     &m, &n,
-     A.memptr(), &lda,
-     S.memptr(),
-     U.memptr(), &ldu,
-     V.memptr(), &ldvt,
-     work.memptr(), &lwork_tmp,
-     rwork.memptr(),
-     &info
-     );
-    
-    if(info == 0)
-      {
-      blas_int proposed_lwork = static_cast<blas_int>(real(work[0]));
-      if(proposed_lwork > lwork)
-        {
-        lwork = proposed_lwork;
-        work.set_size( static_cast<uword>(lwork) );
-        }
-      
-      lapack::cx_gesvd<T>
-        (
-        &jobu, &jobvt,
-        &m, &n,
-        A.memptr(), &lda,
-        S.memptr(),
-        U.memptr(), &ldu,
-        V.memptr(), &ldvt,
-        work.memptr(), &lwork,
-        rwork.memptr(),
-        &info
-        );
-      
-      op_htrans::apply(V,V);  // op_htrans will work out that an in-place transpose can be done
-      }
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(U);
-    arma_ignore(S);
-    arma_ignore(V);
-    arma_ignore(X);
-    arma_stop("svd(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-bool
-auxlib::svd_econ(Mat<eT>& U, Col<eT>& S, Mat<eT>& V, const Base<eT,T1>& X, const char mode)
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    Mat<eT> A(X.get_ref());
-    
-    blas_int m    = A.n_rows;
-    blas_int n    = A.n_cols;
-    blas_int lda  = A.n_rows;
-    
-    S.set_size( static_cast<uword>((std::min)(m,n)) );
-    
-    blas_int ldu  = 0;
-    blas_int ldvt = 0;
-    
-    char jobu;
-    char jobvt;
-    
-    switch(mode)
-      {
-      case 'l':
-        jobu  = 'S';
-        jobvt = 'N';
-        
-        ldu  = m;
-        ldvt = 1;
-        
-        U.set_size( static_cast<uword>(ldu), static_cast<uword>((std::min)(m,n)) );
-        V.reset();
-        
-        break;
-      
-      
-      case 'r':
-        jobu  = 'N';
-        jobvt = 'S';
-        
-        ldu = 1;
-        ldvt = (std::min)(m,n);
-        
-        U.reset();
-        V.set_size( static_cast<uword>(ldvt), static_cast<uword>(n) );
-        
-        break;
-      
-      
-      case 'b':
-        jobu  = 'S';
-        jobvt = 'S';
-        
-        ldu  = m;
-        ldvt = (std::min)(m,n);
-        
-        U.set_size( static_cast<uword>(ldu),  static_cast<uword>((std::min)(m,n)) );
-        V.set_size( static_cast<uword>(ldvt), static_cast<uword>(n)               );
-        
-        break;
-      
-      
-      default:
-        U.reset();
-        S.reset();
-        V.reset();
-        return false;
-      }
-    
-    
-    if(A.is_empty())
-      {
-      U.eye();
-      S.reset();
-      V.eye();
-      return true;
-      }
-    
-    
-    blas_int lwork = 2 * (std::max)(blas_int(1), (std::max)( (3*(std::min)(m,n) + (std::max)(m,n)), 5*(std::min)(m,n) ) );
-    blas_int info  = 0;
-    
-    
-    podarray<eT> work( static_cast<uword>(lwork) );
-    
-    // let gesvd_() calculate the optimum size of the workspace
-    blas_int lwork_tmp = -1;
-    
-    lapack::gesvd<eT>
-      (
-      &jobu, &jobvt,
-      &m, &n,
-      A.memptr(), &lda,
-      S.memptr(),
-      U.memptr(), &ldu,
-      V.memptr(), &ldvt,
-      work.memptr(), &lwork_tmp,
-      &info
-      );
-    
-    if(info == 0)
-      {
-      blas_int proposed_lwork = static_cast<blas_int>(work[0]);
-      if(proposed_lwork > lwork)
-        {
-        lwork = proposed_lwork;
-        work.set_size( static_cast<uword>(lwork) );
-        }
-      
-      lapack::gesvd<eT>
-        (
-        &jobu, &jobvt,
-        &m, &n,
-        A.memptr(), &lda,
-        S.memptr(),
-        U.memptr(), &ldu,
-        V.memptr(), &ldvt,
-        work.memptr(), &lwork,
-        &info
-        );
-      
-      op_strans::apply(V,V);  // op_strans will work out that an in-place transpose can be done
-      }
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(U);
-    arma_ignore(S);
-    arma_ignore(V);
-    arma_ignore(X);
-    arma_ignore(mode);
-    arma_stop("svd(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-template<typename T, typename T1>
-inline
-bool
-auxlib::svd_econ(Mat< std::complex<T> >& U, Col<T>& S, Mat< std::complex<T> >& V, const Base< std::complex<T>, T1>& X, const char mode)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef std::complex<T> eT;
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    Mat<eT> A(X.get_ref());
-    
-    blas_int m    = A.n_rows;
-    blas_int n    = A.n_cols;
-    blas_int lda  = A.n_rows;
-    
-    S.set_size( static_cast<uword>((std::min)(m,n)) );
-    
-    blas_int ldu  = 0;
-    blas_int ldvt = 0;
-    
-    char jobu;
-    char jobvt;
-    
-    switch(mode)
-      {
-      case 'l':
-        jobu  = 'S';
-        jobvt = 'N';
-        
-        ldu  = m;
-        ldvt = 1;
-        
-        U.set_size( static_cast<uword>(ldu), static_cast<uword>((std::min)(m,n)) );
-        V.reset();
-        
-        break;
-      
-      
-      case 'r':
-        jobu  = 'N';
-        jobvt = 'S';
-        
-        ldu  = 1;
-        ldvt = (std::min)(m,n);
-        
-        U.reset();
-        V.set_size( static_cast<uword>(ldvt), static_cast<uword>(n) );
-        
-        break;
-      
-      
-      case 'b':
-        jobu  = 'S';
-        jobvt = 'S';
-        
-        ldu  = m;
-        ldvt = (std::min)(m,n);
-        
-        U.set_size( static_cast<uword>(ldu),  static_cast<uword>((std::min)(m,n)) );
-        V.set_size( static_cast<uword>(ldvt), static_cast<uword>(n)               );
-        
-        break;
-      
-      
-      default:
-        U.reset();
-        S.reset();
-        V.reset();
-        return false;
-      }
-    
-    
-    if(A.is_empty())
-      {
-      U.eye();
-      S.reset();
-      V.eye();
-      return true;
-      }
-    
-    
-    blas_int lwork = 2 * (std::max)(blas_int(1), (std::max)( (3*(std::min)(m,n) + (std::max)(m,n)), 5*(std::min)(m,n) ) );
-    blas_int info  = 0;
-    
-    
-    podarray<eT>  work( static_cast<uword>(lwork) );
-    podarray<T>  rwork( static_cast<uword>(5*(std::min)(m,n)) );
-    
-    // let gesvd_() calculate the optimum size of the workspace
-    blas_int lwork_tmp = -1;
-    
-    lapack::cx_gesvd<T>
-      (
-      &jobu, &jobvt,
-      &m, &n,
-      A.memptr(), &lda,
-      S.memptr(),
-      U.memptr(), &ldu,
-      V.memptr(), &ldvt,
-      work.memptr(), &lwork_tmp,
-      rwork.memptr(),
-      &info
-      );
-    
-    if(info == 0)
-      {
-      blas_int proposed_lwork = static_cast<blas_int>(real(work[0]));
-      if(proposed_lwork > lwork)
-        {
-        lwork = proposed_lwork;
-        work.set_size( static_cast<uword>(lwork) );
-        }
-      
-      lapack::cx_gesvd<T>
-        (
-        &jobu, &jobvt,
-        &m, &n,
-        A.memptr(), &lda,
-        S.memptr(),
-        U.memptr(), &ldu,
-        V.memptr(), &ldvt,
-        work.memptr(), &lwork,
-        rwork.memptr(),
-        &info
-        );
-      
-      op_htrans::apply(V,V);  // op_strans will work out that an in-place transpose can be done
-      }
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(U);
-    arma_ignore(S);
-    arma_ignore(V);
-    arma_ignore(X);
-    arma_ignore(mode);
-    arma_stop("svd(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-//! Solve a system of linear equations.
-//! Assumes that A.n_rows = A.n_cols and B.n_rows = A.n_rows
-template<typename eT>
-inline
-bool
-auxlib::solve(Mat<eT>& out, Mat<eT>& A, const Mat<eT>& B, const bool slow)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(A.is_empty() || B.is_empty())
-    {
-    out.zeros(A.n_cols, B.n_cols);
-    return true;
-    }
-  else
-    {
-    const uword A_n_rows = A.n_rows;
-    
-    bool status = false;
-    
-    if( (A_n_rows <= 4) && (slow == false) )
-      {
-      Mat<eT> A_inv;
-      
-      status = auxlib::inv_noalias_tinymat(A_inv, A, A_n_rows);
-      
-      if(status == true)
-        {
-        out.set_size(A_n_rows, B.n_cols);
-        
-        gemm_emul<false,false,false,false>::apply(out, A_inv, B);
-        
-        return true;
-        }
-      }
-    
-    if( (A_n_rows > 4) || (status == false) )
-      {
-      #if defined(ARMA_USE_ATLAS)
-        {
-        podarray<int> ipiv(A_n_rows);
-        
-        out = B;
-        
-        int info = atlas::clapack_gesv<eT>(atlas::CblasColMajor, A_n_rows, B.n_cols, A.memptr(), A_n_rows, ipiv.memptr(), out.memptr(), A_n_rows);
-        
-        return (info == 0);
-        }
-      #elif defined(ARMA_USE_LAPACK)
-        {
-        blas_int n    = A_n_rows;
-        blas_int lda  = A_n_rows;
-        blas_int ldb  = A_n_rows;
-        blas_int nrhs = B.n_cols;
-        blas_int info;
-        
-        podarray<blas_int> ipiv(A_n_rows);
-        
-        out = B;
-        
-        lapack::gesv<eT>(&n, &nrhs, A.memptr(), &lda, ipiv.memptr(), out.memptr(), &ldb, &info);
-        
-        return (info == 0);
-        }
-      #else
-        {
-        arma_stop("solve(): use of ATLAS or LAPACK needs to be enabled");
-        return false;
-        }
-      #endif
-      }
-    }
-  
-  return true;
-  }
-
-
-
-//! Solve an over-determined system.
-//! Assumes that A.n_rows > A.n_cols and B.n_rows = A.n_rows
-template<typename eT>
-inline
-bool
-auxlib::solve_od(Mat<eT>& out, Mat<eT>& A, const Mat<eT>& B)
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    if(A.is_empty() || B.is_empty())
-      {
-      out.zeros(A.n_cols, B.n_cols);
-      return true;
-      }
-    
-    char trans = 'N';
-    
-    blas_int  m     = A.n_rows;
-    blas_int  n     = A.n_cols;
-    blas_int  lda   = A.n_rows;
-    blas_int  ldb   = A.n_rows;
-    blas_int  nrhs  = B.n_cols;
-    blas_int  lwork = n + (std::max)(n, nrhs);
-    blas_int  info;
-    
-    Mat<eT> tmp = B;
-    
-    podarray<eT> work( static_cast<uword>(lwork) );
-    
-    arma_extra_debug_print("lapack::gels()");
-    
-    // NOTE: the dgels() function in the lapack library supplied by ATLAS 3.6 seems to have problems
-    
-    lapack::gels<eT>
-      (
-      &trans, &m, &n, &nrhs,
-      A.memptr(), &lda,
-      tmp.memptr(), &ldb,
-      work.memptr(), &lwork,
-      &info
-      );
-    
-    arma_extra_debug_print("lapack::gels() -- finished");
-    
-    out.set_size(A.n_cols, B.n_cols);
-    
-    for(uword col=0; col<B.n_cols; ++col)
-      {
-      arrayops::copy( out.colptr(col), tmp.colptr(col), A.n_cols );
-      }
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(out);
-    arma_ignore(A);
-    arma_ignore(B);
-    arma_stop("solve(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-//! Solve an under-determined system.
-//! Assumes that A.n_rows < A.n_cols and B.n_rows = A.n_rows
-template<typename eT>
-inline
-bool
-auxlib::solve_ud(Mat<eT>& out, Mat<eT>& A, const Mat<eT>& B)
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    if(A.is_empty() || B.is_empty())
-      {
-      out.zeros(A.n_cols, B.n_cols);
-      return true;
-      }
-    
-    char trans = 'N';
-    
-    blas_int  m     = A.n_rows;
-    blas_int  n     = A.n_cols;
-    blas_int  lda   = A.n_rows;
-    blas_int  ldb   = A.n_cols;
-    blas_int  nrhs  = B.n_cols;
-    blas_int  lwork = m + (std::max)(m,nrhs);
-    blas_int  info;
-    
-    
-    Mat<eT> tmp;
-    tmp.zeros(A.n_cols, B.n_cols);
-    
-    for(uword col=0; col<B.n_cols; ++col)
-      {
-      eT* tmp_colmem = tmp.colptr(col);
-      
-      arrayops::copy( tmp_colmem, B.colptr(col), B.n_rows );
-      
-      for(uword row=B.n_rows; row<A.n_cols; ++row)
-        {
-        tmp_colmem[row] = eT(0);
-        }
-      }
-    
-    podarray<eT> work( static_cast<uword>(lwork) );
-    
-    arma_extra_debug_print("lapack::gels()");
-    
-    // NOTE: the dgels() function in the lapack library supplied by ATLAS 3.6 seems to have problems
-    
-    lapack::gels<eT>
-      (
-      &trans, &m, &n, &nrhs,
-      A.memptr(), &lda,
-      tmp.memptr(), &ldb,
-      work.memptr(), &lwork,
-      &info
-      );
-    
-    arma_extra_debug_print("lapack::gels() -- finished");
-    
-    out.set_size(A.n_cols, B.n_cols);
-    
-    for(uword col=0; col<B.n_cols; ++col)
-      {
-      arrayops::copy( out.colptr(col), tmp.colptr(col), A.n_cols );
-      }
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(out);
-    arma_ignore(A);
-    arma_ignore(B);
-    arma_stop("solve(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-//
-// solve_tr
-
-template<typename eT>
-inline
-bool
-auxlib::solve_tr(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const uword layout)
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    if(A.is_empty() || B.is_empty())
-      {
-      out.zeros(A.n_cols, B.n_cols);
-      return true;
-      }
-    
-    out = B;
-    
-    char     uplo  = (layout == 0) ? 'U' : 'L';
-    char     trans = 'N';
-    char     diag  = 'N';
-    blas_int n     = blas_int(A.n_rows);
-    blas_int nrhs  = blas_int(B.n_cols);
-    blas_int info  = 0;
-    
-    lapack::trtrs<eT>(&uplo, &trans, &diag, &n, &nrhs, A.memptr(), &n, out.memptr(), &n, &info);
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(out);
-    arma_ignore(A);
-    arma_ignore(B);
-    arma_ignore(layout);
-    arma_stop("solve(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-//
-// Schur decomposition
-
-template<typename eT>
-inline
-bool
-auxlib::schur_dec(Mat<eT>& Z, Mat<eT>& T, const Mat<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    arma_debug_check( (A.is_square() == false), "schur_dec(): given matrix is not square" );
-    
-    if(A.is_empty())
-      {
-      Z.reset();
-      T.reset();
-      return true;
-      }
-    
-    const uword A_n_rows = A.n_rows;
-    
-    char    jobvs    = 'V';                // get Schur vectors (Z)
-    char     sort    = 'N';                // do not sort eigenvalues/vectors
-    blas_int* select = 0;                  // pointer to sorting function
-    blas_int    n    = blas_int(A_n_rows);
-    blas_int sdim    = 0;                  // output for sorting
-    
-    blas_int lwork = 3 * n;                // workspace must be at least 3 * n (if set to -1, optimal size is output in work(0) and nothing else is done
-    
-    podarray<eT>       work( static_cast<uword>(lwork) );
-    podarray<blas_int> bwork(A_n_rows);
-    
-    blas_int info = 0;
-    
-    Z.set_size(A_n_rows, A_n_rows);
-    T = A;
-    
-    podarray<eT> wr(A_n_rows);             // output for eigenvalues
-    podarray<eT> wi(A_n_rows);             // output for eigenvalues
-    
-    lapack::gees(&jobvs, &sort, select, &n, T.memptr(), &n, &sdim, wr.memptr(), wi.memptr(), Z.memptr(), &n, work.memptr(), &lwork, bwork.memptr(), &info);
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(Z);
-    arma_ignore(T);
-    arma_stop("schur_dec(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-template<typename cT>
-inline
-bool
-auxlib::schur_dec(Mat<std::complex<cT> >& Z, Mat<std::complex<cT> >& T, const Mat<std::complex<cT> >& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    arma_debug_check( (A.is_square() == false), "schur_dec(): matrix A is not square" );
-    
-    if(A.is_empty())
-      {
-      Z.reset();
-      T.reset();
-      return true;
-      }
-    
-    typedef std::complex<cT> eT;
-    
-    const uword A_n_rows = A.n_rows;
-    
-    char        jobvs = 'V';                // get Schur vectors (Z)
-    char         sort = 'N';                // do not sort eigenvalues/vectors
-    blas_int*  select = 0;                  // pointer to sorting function
-    blas_int        n = blas_int(A_n_rows);
-    blas_int     sdim = 0;                  // output for sorting
-    
-    blas_int lwork = 3 * n;                 // workspace must be at least 3 * n (if set to -1, optimal size is output in work(0) and nothing else is done
-    
-    podarray<eT>       work( static_cast<uword>(lwork) );
-    podarray<blas_int> bwork(A_n_rows);
-    
-    blas_int info = 0;
-    
-    Z.set_size(A_n_rows, A_n_rows);
-    T = A;
-    
-    podarray<eT>     w(A_n_rows);           // output for eigenvalues
-    podarray<cT> rwork(A_n_rows);
-    
-    lapack::cx_gees(&jobvs, &sort, select, &n, T.memptr(), &n, &sdim, w.memptr(), Z.memptr(), &n, work.memptr(), &lwork, rwork.memptr(), bwork.memptr(), &info);
-    
-    return (info == 0);
-    }
-  #else
-    {
-    arma_ignore(Z);
-    arma_ignore(T);
-    arma_stop("schur_dec(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-
-
-
-//
-// syl (solution of the Sylvester equation AX + XB = C)
-
-template<typename eT>
-inline
-bool
-auxlib::syl(Mat<eT>& X, const Mat<eT>& A, const Mat<eT>& B, const Mat<eT>& C)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (A.is_square() == false) || (B.is_square() == false),
-    "syl(): given matrix is not square"
-    );
-    
-  arma_debug_check
-    (
-    (C.n_rows != A.n_rows) || (C.n_cols != B.n_cols),
-    "syl(): matrices are not conformant"
-    );
-  
-  if(A.is_empty() || B.is_empty() || C.is_empty())
-    {
-    X.reset();
-    return true;
-    }
-  
-  #if defined(ARMA_USE_LAPACK)
-    {
-    Mat<eT> Z1, Z2, T1, T2;
-    
-    const bool status_sd1 = auxlib::schur_dec(Z1, T1, A);
-    const bool status_sd2 = auxlib::schur_dec(Z2, T2, B);
-    
-    if( (status_sd1 == false) || (status_sd2 == false) )
-      {
-      return false;
-      }
-    
-    char     trana = 'N';
-    char     tranb = 'N';
-    blas_int  isgn = +1;
-    blas_int     m = blas_int(T1.n_rows);
-    blas_int     n = blas_int(T2.n_cols);
-    
-    eT       scale = eT(0);
-    blas_int  info = 0;
-    
-    Mat<eT> Y = trans(Z1) * C * Z2;
-    
-    lapack::trsyl<eT>(&trana, &tranb, &isgn, &m, &n, T1.memptr(), &m, T2.memptr(), &n, Y.memptr(), &m, &scale, &info);
-    
-    //Y /= scale;
-    Y /= (-scale);
-    
-    X = Z1 * Y * trans(Z2);
-    
-    return (info >= 0);
-    }
-  #else
-    {
-    arma_stop("syl(): use of LAPACK needs to be enabled");
-    return false;
-    }
-  #endif
-  }
-  
-  
-  
-//
-// lyap (solution of the continuous Lyapunov equation AX + XA^H + Q = 0)
-
-template<typename eT>
-inline
-bool
-auxlib::lyap(Mat<eT>& X, const Mat<eT>& A, const Mat<eT>& Q)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.is_square() == false), "lyap(): matrix A is not square");
-  arma_debug_check( (Q.is_square() == false), "lyap(): matrix Q is not square");
-  arma_debug_check( (A.n_rows != Q.n_rows),   "lyap(): matrices A and Q have different dimensions");
-  
-  Mat<eT> htransA;
-  op_htrans::apply_noalias(htransA, A);
-  
-  const Mat<eT> mQ = -Q;
-  
-  return auxlib::syl(X, A, htransA, mQ);
-  }
-
-
-
-//
-// dlyap (solution of the discrete Lyapunov equation AXA^H - X + Q = 0)
-
-template<typename eT>
-inline
-bool
-auxlib::dlyap(Mat<eT>& X, const Mat<eT>& A, const Mat<eT>& Q)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.is_square() == false), "dlyap(): matrix A is not square");
-  arma_debug_check( (Q.is_square() == false), "dlyap(): matrix Q is not square");
-  arma_debug_check( (A.n_rows != Q.n_rows),   "dlyap(): matrices A and Q have different dimensions");
-  
-  const Col<eT> vecQ = reshape(Q, Q.n_elem, 1);
-  
-  const Mat<eT> M = eye< Mat<eT> >(Q.n_elem, Q.n_elem) - kron(conj(A), A);
-  
-  Col<eT> vecX;
-  
-  const bool status = solve(vecX, M, vecQ);
-  
-  if(status == true)
-    {
-    X = reshape(vecX, Q.n_rows, Q.n_cols);
-    return true;
-    }
-  else
-    {
-    X.reset();
-    return false;
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/blas_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-#ifdef ARMA_USE_BLAS
-
-
-#if !defined(ARMA_BLAS_CAPITALS)
-  
-  #define arma_sdot  sdot
-  #define arma_ddot  ddot
-  
-  #define arma_sgemv sgemv
-  #define arma_dgemv dgemv
-  #define arma_cgemv cgemv
-  #define arma_zgemv zgemv
-  
-  #define arma_sgemm sgemm
-  #define arma_dgemm dgemm
-  #define arma_cgemm cgemm
-  #define arma_zgemm zgemm
-  
-#else
-  
-  #define arma_sdot  SDOT
-  #define arma_ddot  DDOT
-  
-  #define arma_sgemv SGEMV
-  #define arma_dgemv DGEMV
-  #define arma_cgemv CGEMV
-  #define arma_zgemv ZGEMV
-  
-  #define arma_sgemm SGEMM
-  #define arma_dgemm DGEMM
-  #define arma_cgemm CGEMM
-  #define arma_zgemm ZGEMM
-  
-#endif
-
-
-
-extern "C"
-  {
-  float  arma_fortran(arma_sdot)(blas_int* n, const float*  x, blas_int* incx, const float*  y, blas_int* incy);
-  double arma_fortran(arma_ddot)(blas_int* n, const double* x, blas_int* incx, const double* y, blas_int* incy);
-  
-  void arma_fortran(arma_sgemv)(const char* transA, const blas_int* m, const blas_int* n, const float*  alpha, const float*  A, const blas_int* ldA, const float*  x, const blas_int* incx, const float*  beta, float*  y, const blas_int* incy);
-  void arma_fortran(arma_dgemv)(const char* transA, const blas_int* m, const blas_int* n, const double* alpha, const double* A, const blas_int* ldA, const double* x, const blas_int* incx, const double* beta, double* y, const blas_int* incy);
-  void arma_fortran(arma_cgemv)(const char* transA, const blas_int* m, const blas_int* n, const void*   alpha, const void*   A, const blas_int* ldA, const void*   x, const blas_int* incx, const void*   beta, void*   y, const blas_int* incy);
-  void arma_fortran(arma_zgemv)(const char* transA, const blas_int* m, const blas_int* n, const void*   alpha, const void*   A, const blas_int* ldA, const void*   x, const blas_int* incx, const void*   beta, void*   y, const blas_int* incy);
-  
-  void arma_fortran(arma_sgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const float*  alpha, const float*  A, const blas_int* ldA, const float*  B, const blas_int* ldB, const float*  beta, float*  C, const blas_int* ldC);
-  void arma_fortran(arma_dgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const double* alpha, const double* A, const blas_int* ldA, const double* B, const blas_int* ldB, const double* beta, double* C, const blas_int* ldC);
-  void arma_fortran(arma_cgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const void*   alpha, const void*   A, const blas_int* ldA, const void*   B, const blas_int* ldB, const void*   beta, void*   C, const blas_int* ldC);
-  void arma_fortran(arma_zgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const void*   alpha, const void*   A, const blas_int* ldA, const void*   B, const blas_int* ldB, const void*   beta, void*   C, const blas_int* ldC);
-  
-  // void   arma_fortran(arma_dswap)(const blas_int* n, double* x, const blas_int* incx, double* y, const blas_int* incy);
-  // void   arma_fortran(arma_dscal)(const blas_int* n, const double* alpha, double* x, const blas_int* incx);
-  // void   arma_fortran(arma_dcopy)(const blas_int* n, const double* x, const blas_int* incx, double* y, const blas_int* incy);
-  // void   arma_fortran(arma_daxpy)(const blas_int* n, const double* alpha, const double* x, const blas_int* incx, double* y, const blas_int* incy);
-  // void   arma_fortran(arma_dger )(const blas_int* m, const blas_int* n, const double* alpha, const double* x, const blas_int* incx, const double* y, const blas_int* incy, double* A, const blas_int* ldA);
-  }
-
-
-#endif
--- a/armadillo-2.4.4/include/armadillo_bits/blas_wrapper.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-#ifdef ARMA_USE_BLAS
-
-
-//! \namespace blas namespace for BLAS functions
-namespace blas
-  {
-  
-  
-  template<typename eT>
-  inline
-  eT
-  dot(const uword n_elem, const eT* x, const eT* y)
-    {
-    arma_ignore(n_elem);
-    arma_ignore(x);
-    arma_ignore(y);
-    
-    return eT(0);
-    }
-  
-  
-  
-  template<>
-  inline
-  float
-  dot(const uword n_elem, const float* x, const float* y)
-    {
-    blas_int n   = blas_int(n_elem);
-    blas_int inc = blas_int(1);
-    
-    return arma_fortran(arma_sdot)(&n, x, &inc, y, &inc);
-    }
-  
-  
-  
-  template<>
-  inline
-  double
-  dot(const uword n_elem, const double* x, const double* y)
-    {
-    blas_int n   = blas_int(n_elem);
-    blas_int inc = blas_int(1);
-    
-    return arma_fortran(arma_ddot)(&n, x, &inc, y, &inc);
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  gemv(const char* transA, const blas_int* m, const blas_int* n, const eT* alpha, const eT* A, const blas_int* ldA, const eT* x, const blas_int* incx, const eT* beta, eT* y, const blas_int* incy)
-    {
-    arma_type_check((is_supported_blas_type<eT>::value == false));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_sgemv)(transA, m, n, (const T*)alpha, (const T*)A, ldA, (const T*)x, incx, (const T*)beta, (T*)y, incy);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dgemv)(transA, m, n, (const T*)alpha, (const T*)A, ldA, (const T*)x, incx, (const T*)beta, (T*)y, incy);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_cgemv)(transA, m, n, (const T*)alpha, (const T*)A, ldA, (const T*)x, incx, (const T*)beta, (T*)y, incy);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_zgemv)(transA, m, n, (const T*)alpha, (const T*)A, ldA, (const T*)x, incx, (const T*)beta, (T*)y, incy);
-      }
-    
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  gemm(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const eT* alpha, const eT* A, const blas_int* ldA, const eT* B, const blas_int* ldB, const eT* beta, eT* C, const blas_int* ldC)
-    {
-    arma_type_check((is_supported_blas_type<eT>::value == false));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_sgemm)(transA, transB, m, n, k, (const T*)alpha, (const T*)A, ldA, (const T*)B, ldB, (const T*)beta, (T*)C, ldC);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dgemm)(transA, transB, m, n, k, (const T*)alpha, (const T*)A, ldA, (const T*)B, ldB, (const T*)beta, (T*)C, ldC);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_cgemm)(transA, transB, m, n, k, (const T*)alpha, (const T*)A, ldA, (const T*)B, ldB, (const T*)beta, (T*)C, ldC);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_zgemm)(transA, transB, m, n, k, (const T*)alpha, (const T*)A, ldA, (const T*)B, ldB, (const T*)beta, (T*)C, ldC);
-      }
-    
-    }
-  
-  }
-
-
-#endif
--- a/armadillo-2.4.4/include/armadillo_bits/cmath_wrap.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup cmath_wrap
-//! @{
-
-
-
-//
-// wrappers for isfinite
-//
-
-
-
-template<typename eT>
-arma_inline
-bool
-arma_isfinite(eT val)
-  {
-  arma_ignore(val);
-    
-  return true;
-  }
-
-
-
-template<>
-arma_inline
-bool
-arma_isfinite(float x)
-  {
-  #if defined(ARMA_HAVE_STD_ISFINITE)
-    {
-    return (std::isfinite(x) != 0);
-    }
-  #else
-    {
-    const bool x_is_inf = ( (x == x) && ((x - x) != float(0)) );
-    const bool x_is_nan = (x != x);
-
-    return ( (x_is_inf == false) && (x_is_nan == false) );
-    }
-  #endif
-  }
-
-
-
-template<>
-arma_inline
-bool
-arma_isfinite(double x)
-  {
-  #if defined(ARMA_HAVE_STD_ISFINITE)
-    {
-    return (std::isfinite(x) != 0);
-    }
-  #else
-    {
-    const bool x_is_inf = ( (x == x) && ((x - x) != double(0)) );
-    const bool x_is_nan = (x != x);
-
-    return ( (x_is_inf == false) && (x_is_nan == false) );
-    }
-  #endif
-  }
-
-
-
-template<typename T>
-arma_inline
-bool
-arma_isfinite(const std::complex<T>& x)
-  {
-  if( (arma_isfinite(x.real()) == false) || (arma_isfinite(x.imag()) == false) )
-    {
-    return false;
-    }
-  else
-    {
-    return true;
-    }
-  }
-
-
-
-//
-// wrappers for trigonometric functions
-//
-
-
-
-// Wherever possible, try to use TR1 versions of the functions below,
-// otherwise fall back to Boost Math.
-//
-// complex acos
-// complex asin
-// complex atan
-//
-// real    acosh
-// real    asinh
-// real    atanh
-//
-// complex acosh
-// complex asinh
-// complex atanh
-// 
-// 
-// If TR1 not present and Boost math not present,
-// we have our own rudimentary versions of:
-// 
-// real    acosh
-// real    asinh
-// real    atanh
-
-
-
-#if defined(ARMA_USE_BOOST)
-  #define arma_boost_wrap(trig_fn, val) ( (boost::math::trig_fn)(val) )
-#else
-  #define arma_boost_wrap(trig_fn, val) ( arma_stop( #trig_fn "(): need Boost libraries" ), val )
-#endif
-
-
-template<typename T>
-arma_inline
-std::complex<T>
-arma_acos(const std::complex<T>& x)
-  {
-  #if defined(ARMA_HAVE_STD_TR1)
-    {
-    return std::tr1::acos(x);
-    }
-  #else
-    {
-    return arma_boost_wrap(acos, x);
-    }
-  #endif
-  }
-
-
-
-template<typename T>
-arma_inline
-std::complex<T>
-arma_asin(const std::complex<T>& x)
-  {
-  #if defined(ARMA_HAVE_STD_TR1)
-    {
-    return std::tr1::asin(x);
-    }
-  #else
-    {
-    return arma_boost_wrap(asin, x);
-    }
-  #endif
-  }
-
-
-
-template<typename T>
-arma_inline
-std::complex<T>
-arma_atan(const std::complex<T>& x)
-  {
-  #if defined(ARMA_HAVE_STD_TR1)
-    {
-    return std::tr1::atan(x);
-    }
-  #else
-    {
-    return arma_boost_wrap(atan, x);
-    }
-  #endif
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT
-arma_acosh(const eT x)
-  {
-  #if defined(ARMA_HAVE_STD_TR1)
-    {
-    return std::tr1::acosh(x);
-    }
-  #elif defined(ARMA_USE_BOOST)
-    {
-    return boost::math::acosh(x);
-    }
-  #else
-    {
-    if(x >= eT(1))
-      {
-      // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/02/
-      return std::log( x + std::sqrt(x*x - eT(1)) );
-      }
-    else
-      {
-      if(std::numeric_limits<eT>::has_quiet_NaN == true)
-        {
-        return -(std::numeric_limits<eT>::quiet_NaN());
-        }
-      else
-        {
-        return eT(0);
-        }
-      }
-    }
-  #endif
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT
-arma_asinh(const eT x)
-  {
-  #if defined(ARMA_HAVE_STD_TR1)
-    {
-    return std::tr1::asinh(x);
-    }
-  #elif defined(ARMA_USE_BOOST)
-    {
-    return boost::math::asinh(x);
-    }
-  #else
-    {
-    // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/02/
-    return std::log( x + std::sqrt(x*x + eT(1)) );
-    }
-  #endif
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT
-arma_atanh(const eT x)
-  {
-  #if defined(ARMA_HAVE_STD_TR1)
-    {
-    return std::tr1::atanh(x);
-    }
-  #elif defined(ARMA_USE_BOOST)
-    {
-    return boost::math::atanh(x);
-    }
-  #else
-    {
-    if( (x >= eT(-1)) && (x <= eT(+1)) )
-      {
-      // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/02/
-      return std::log( ( eT(1)+x ) / ( eT(1)-x ) ) / eT(2);
-      }
-    else
-      {
-      if(std::numeric_limits<eT>::has_quiet_NaN == true)
-        {
-        return -(std::numeric_limits<eT>::quiet_NaN());
-        }
-      else
-        {
-        return eT(0);
-        }
-      }
-    }
-  #endif
-  }
-
-
-
-template<typename T>
-arma_inline
-std::complex<T>
-arma_acosh(const std::complex<T>& x)
-  {
-  #if defined(ARMA_HAVE_STD_TR1)
-    {
-    return std::tr1::acosh(x);
-    }
-  #else
-    {
-    return arma_boost_wrap(acosh, x);
-    }
-  #endif
-  }
-
-
-
-template<typename T>
-arma_inline
-std::complex<T>
-arma_asinh(const std::complex<T>& x)
-  {
-  #if defined(ARMA_HAVE_STD_TR1)
-    {
-    return std::tr1::asinh(x);
-    }
-  #else
-    {
-    return arma_boost_wrap(asinh, x);
-    }
-  #endif
-  }
-
-
-
-template<typename T>
-arma_inline
-std::complex<T>
-arma_atanh(const std::complex<T>& x)
-  {
-  #if defined(ARMA_HAVE_STD_TR1)
-    {
-    return std::tr1::atanh(x);
-    }
-  #else
-    {
-    return arma_boost_wrap(atanh, x);
-    }
-  #endif
-  }
-
-
-
-#undef arma_boost_wrap
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/compiler_setup.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-#define arma_hot
-#define arma_cold
-#define arma_pure
-#define arma_const
-#define arma_inline  inline
-#define arma_aligned
-#define arma_warn_unused
-#define arma_deprecated
-#define arma_ignore(variable)  ((void)(variable))
-
-
-#if defined(ARMA_BLAS_UNDERSCORE)
-  #define arma_fortran2_noprefix(function) function##_
-  #define arma_fortran2_prefix(function)   wrapper_##function##_
-#else
-  #define arma_fortran2_prefix(function)   wrapper_##function
-  #define arma_fortran2_noprefix(function) function
-#endif
-
-#if defined(ARMA_USE_WRAPPER)
-  #define arma_fortran(function) arma_fortran2_prefix(function)
-  #define arma_atlas(function)   wrapper_##function
-#else
-  #define arma_fortran(function) arma_fortran2_noprefix(function)
-  #define arma_atlas(function)   function
-#endif
-
-#define arma_fortran_prefix(function)   arma_fortran2_prefix(function)
-#define arma_fortran_noprefix(function) arma_fortran2_noprefix(function)
-
-
-#define ARMA_INCFILE_WRAP(x) <x>
-
-
-#if defined(__INTEL_COMPILER)
-  
-  #if (__INTEL_COMPILER < 1000)
-    #error "*** Need a newer compiler ***"
-  #endif
-  
-  #define ARMA_GOOD_COMPILER
-  #undef  ARMA_HAVE_STD_TR1
-  
-  #if (__INTEL_COMPILER <= 1110)
-    #undef ARMA_HAVE_STD_ISFINITE
-  #endif
-  
-#elif defined(__GNUG__)
-  
-  #if (__GNUC__ < 4)
-    #error "*** Need a newer compiler ***"
-  #endif
-  
-  #define ARMA_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-  
-  #define ARMA_GOOD_COMPILER
-  #undef  ARMA_HAVE_STD_TR1
-  
-  #undef  arma_pure
-  #undef  arma_const
-  #undef  arma_inline
-  #undef  arma_aligned
-  #undef  arma_warn_unused
-  #undef  arma_deprecated
-  
-  #define arma_pure               __attribute__((pure))
-  #define arma_const              __attribute__((const))
-  #define arma_inline      inline __attribute__((always_inline))
-  #define arma_aligned            __attribute__((aligned))
-  #define arma_warn_unused        __attribute__((warn_unused_result))
-  #define arma_deprecated         __attribute__((deprecated))
-  
-  #if (ARMA_GCC_VERSION >= 40200)
-    #if defined(_GLIBCXX_USE_C99_MATH_TR1) && defined(_GLIBCXX_USE_C99_COMPLEX_TR1)
-      #define ARMA_HAVE_STD_TR1
-    #endif
-  #endif
-  
-  #if defined(__GXX_EXPERIMENTAL_CXX0X__)
-    #undef ARMA_HAVE_STD_TR1
-    
-    #if !defined(ARMA_USE_CXX11)
-      #define ARMA_USE_CXX11
-    #endif
-  #endif
-  
-  #if defined(__clang__)
-    #undef ARMA_HAVE_STD_TR1
-  #endif
-  
-  #if (ARMA_GCC_VERSION >= 40300)
-    #undef  arma_hot
-    #undef  arma_cold
-    
-    #define arma_hot  __attribute__((hot))
-    #define arma_cold __attribute__((cold))
-  #endif
-  
-  #undef ARMA_GCC_VERSION
-  
-#endif
-
-
-#if defined(_MSC_VER)
-  
-  #if (_MSC_VER < 1500)
-    #error "*** Need a newer compiler ***"
-  #endif
-  
-  #undef ARMA_GOOD_COMPILER
-  #undef ARMA_HAVE_STD_ISFINITE
-  #undef ARMA_HAVE_STD_SNPRINTF
-  #undef ARMA_HAVE_LOG1P
-  #undef ARMA_HAVE_STD_ISINF
-  #undef ARMA_HAVE_STD_ISNAN
-  #undef ARMA_HAVE_STD_TR1
-  
-  #undef  arma_inline
-  #define arma_inline inline __forceinline
-  
-  // #if (_MSC_VER >= 1400)
-  //   #undef  arma_aligned
-  //   #define arma_aligned __declspec(align(16))
-  // #endif
-  
-#endif
-
-
-#if defined(__CUDACC__)
-  #undef ARMA_HAVE_STD_ISFINITE
-  #undef ARMA_HAVE_STD_SNPRINTF
-  #undef ARMA_HAVE_LOG1P
-  #undef ARMA_HAVE_STD_ISINF
-  #undef ARMA_HAVE_STD_ISNAN
-  #undef ARMA_HAVE_STD_TR1
-#endif
-
-
-#if defined(__SUNPRO_CC)
-  #undef ARMA_HAVE_STD_ISFINITE
-  #undef ARMA_HAVE_STD_SNPRINTF
-  #undef ARMA_HAVE_LOG1P
-  #undef ARMA_HAVE_STD_ISINF
-  #undef ARMA_HAVE_STD_ISNAN
-  #undef ARMA_HAVE_STD_TR1
-#endif
--- a/armadillo-2.4.4/include/armadillo_bits/config.hpp.cmake	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2012 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-// #define ARMA_64BIT_WORD
-//// Uncomment the above line if you require matrices/vectors capable of holding more than 4 billion elements.
-//// Your machine and compiler must have support for 64 bit integers (eg. via "long" or "long long")
-
-// #define ARMA_USE_CXX11
-//// Uncomment the above line if you have a C++ compiler that supports the C++11 standard
-//// This will enable additional features, such as use of initialiser lists
-
-#if !defined(ARMA_USE_LAPACK)
-#cmakedefine ARMA_USE_LAPACK
-//// Uncomment the above line if you have LAPACK or a fast replacement for LAPACK,
-//// such as Intel's MKL, AMD's ACML, or the Accelerate framework.
-//// LAPACK is required for matrix decompositions (eg. SVD) and matrix inverse.
-#endif
-
-#if !defined(ARMA_USE_BLAS)
-#cmakedefine ARMA_USE_BLAS
-//// Uncomment the above line if you have BLAS or a fast replacement for BLAS,
-//// such as GotoBLAS, Intel's MKL, AMD's ACML, or the Accelerate framework.
-//// BLAS is used for matrix multiplication.
-//// Without BLAS, matrix multiplication will still work, but might be slower.
-#endif
-
-// #define ARMA_BLAS_LONG
-//// Uncomment the above line if your BLAS and LAPACK libraries use "long" instead of "int"
-
-// #define ARMA_BLAS_LONG_LONG
-//// Uncomment the above line if your BLAS and LAPACK libraries use "long long" instead of "int"
-
-#define ARMA_BLAS_UNDERSCORE
-//// Uncomment the above line if your BLAS and LAPACK libraries have function names with a trailing underscore.
-//// Conversely, comment it out if the function names don't have a trailing underscore.
-
-// #define ARMA_BLAS_CAPITALS
-//// Uncomment the above line if your BLAS and LAPACK libraries have capitalised function names (eg. ACML on 64-bit Windows)
-
-#if !defined(ARMA_MAT_PREALLOC)
-  #define ARMA_MAT_PREALLOC 16
-#endif
-//// This is the number of preallocated elements used by matrices and vectors;
-//// it must be an integer that is at least 1.
-//// If you mainly use lots of very small vectors (eg. <= 4 elements),
-//// change the number to the size of your vectors.
-
-// #define ARMA_USE_TBB_ALLOC
-//// Uncomment the above line if you want to use Intel TBB scalable_malloc() and scalable_free() instead of standard new[] and delete[]
-
-#cmakedefine ARMA_USE_ATLAS
-#define ARMA_ATLAS_INCLUDE_DIR ${ARMA_ATLAS_INCLUDE_DIR}/
-//// If you're using ATLAS and the compiler can't find cblas.h and/or clapack.h
-//// uncomment the above define and specify the appropriate include directory.
-//// Make sure the directory has a trailing /
-
-#cmakedefine ARMA_USE_BOOST
-#cmakedefine ARMA_USE_BOOST_DATE
-#cmakedefine ARMA_USE_WRAPPER
-
-#if !defined(ARMA_DEFAULT_OSTREAM)
-  #define ARMA_DEFAULT_OSTREAM std::cout
-#endif
-
-#define ARMA_PRINT_LOGIC_ERRORS
-#define ARMA_PRINT_RUNTIME_ERRORS
-
-#cmakedefine ARMA_HAVE_STD_ISFINITE
-#cmakedefine ARMA_HAVE_STD_ISINF
-#cmakedefine ARMA_HAVE_STD_ISNAN
-#cmakedefine ARMA_HAVE_STD_SNPRINTF
-
-#cmakedefine ARMA_HAVE_LOG1P
-#cmakedefine ARMA_HAVE_GETTIMEOFDAY
-
-// #define ARMA_EXTRA_DEBUG
-// #define ARMA_NO_DEBUG
-
-#if defined(ARMA_DONT_USE_ATLAS)
-  #undef ARMA_USE_ATLAS
-  #undef ARMA_ATLAS_INCLUDE_DIR
-#endif
-
-#if defined(ARMA_DONT_USE_LAPACK)
-  #undef ARMA_USE_LAPACK
-#endif
-
-#if defined(ARMA_DONT_USE_BLAS)
-  #undef ARMA_USE_BLAS
-#endif
-
-#if defined(ARMA_DONT_PRINT_LOGIC_ERRORS)
-  #undef ARMA_PRINT_LOGIC_ERRORS
-#endif
-
-#if defined(ARMA_DONT_PRINT_RUNTIME_ERRORS)
-  #undef ARMA_PRINT_RUNTIME_ERRORS
-#endif
--- a/armadillo-2.4.4/include/armadillo_bits/constants.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,332 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup constants
-//! @{
-
-
-namespace priv
-  {
-  class Math_helper
-    {
-    public:
-    
-    template<typename eT>
-    static
-    typename arma_float_only<eT>::result
-    nan(typename arma_float_only<eT>::result* junk = 0)
-      {
-      arma_ignore(junk);
-      
-      if(std::numeric_limits<eT>::has_quiet_NaN == true)
-        {
-        return std::numeric_limits<eT>::quiet_NaN();
-        }
-      else
-        {
-        return eT(0);
-        }
-      }
-    
-    
-    template<typename eT>
-    static
-    typename arma_cx_only<eT>::result
-    nan(typename arma_cx_only<eT>::result* junk = 0)
-      {
-      arma_ignore(junk);
-      
-      typedef typename get_pod_type<eT>::result T;
-      
-      return eT( Math_helper::nan<T>(), Math_helper::nan<T>() );
-      }
-    
-    
-    template<typename eT>
-    static
-    typename arma_integral_only<eT>::result
-    nan(typename arma_integral_only<eT>::result* junk = 0)
-      {
-      arma_ignore(junk);
-      
-      return eT(0);
-      }
-    
-    
-    template<typename eT>
-    static
-    typename arma_float_only<eT>::result
-    inf(typename arma_float_only<eT>::result* junk = 0)
-      {
-      arma_ignore(junk);
-      
-      if(std::numeric_limits<eT>::has_infinity == true)
-        {
-        return std::numeric_limits<eT>::infinity();
-        }
-      else
-        {
-        return std::numeric_limits<eT>::max();
-        }
-      }
-    
-    
-    template<typename eT>
-    static
-    typename arma_cx_only<eT>::result
-    inf(typename arma_cx_only<eT>::result* junk = 0)
-      {
-      arma_ignore(junk);
-      
-      typedef typename get_pod_type<eT>::result T;
-      
-      return eT( Math_helper::inf<T>(), Math_helper::inf<T>() );
-      }
-    
-
-    template<typename eT>
-    static
-    typename arma_integral_only<eT>::result
-    inf(typename arma_integral_only<eT>::result* junk = 0)
-      {
-      arma_ignore(junk);
-      
-      return std::numeric_limits<eT>::max();
-      }
-    
-    };
-  }
-
-
-
-template<typename eT>
-class Math
-  {
-  public:
-  
-  // the long lengths of the constants are for future support of "long double"
-  // and any smart compiler that does high-precision computation at compile-time
-  
-  //! ratio of any circle's circumference to its diameter
-  static eT pi()        { return eT(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679); }
-  
-  //! base of the natural logarithm
-  static eT e()         { return eT(2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274); }
-  
-  //! Euler's constant, aka Euler-Mascheroni constant
-  static eT euler()     { return eT(0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495); }
-  
-  //! golden ratio
-  static eT gratio()    { return eT(1.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374); }
-  
-  //! square root of 2
-  static eT sqrt2()     { return eT(1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727); }
-  
-  //! the difference between 1 and the least value greater than 1 that is representable
-  static eT eps()       { return std::numeric_limits<eT>::epsilon(); }
-  
-  //! log of the minimum representable value
-  static eT log_min()   { static const eT out = std::log(std::numeric_limits<eT>::min()); return out; }
-    
-  //! log of the maximum representable value
-  static eT log_max()   { static const eT out = std::log(std::numeric_limits<eT>::max()); return out; }
-  
-  //! "not a number"
-  static eT nan()       { return priv::Math_helper::nan<eT>(); }
-  
-  //! infinity 
-  static eT inf()       { return priv::Math_helper::inf<eT>(); }
-  };
-
-
-
-//! Physical constants taken from NIST and WolframAlpha on 2009-06-23
-//! http://physics.nist.gov/cuu/Constants
-//! http://www.wolframalpha.com
-//! See also http://en.wikipedia.org/wiki/Physical_constant
-template<typename eT>
-class Phy
-  {
-  public:
-  
-  //! atomic mass constant (in kg)
-  static eT m_u()       {  return eT(1.660538782e-27); }
-  
-  //! Avogadro constant
-  static eT N_A()       {  return eT(6.02214179e23); }
-  
-  //! Boltzmann constant (in joules per kelvin)
-  static eT k()         {  return eT(1.3806504e-23); }
-  
-  //! Boltzmann constant (in eV/K)
-  static eT k_evk()     {  return eT(8.617343e-5); }
-  
-  //! Bohr radius (in meters)
-  static eT a_0()       { return eT(0.52917720859e-10); }
-  
-  //! Bohr magneton
-  static eT mu_B()      { return eT(927.400915e-26); }
-  
-  //! characteristic impedance of vacuum (in ohms)
-  static eT Z_0()       { return eT(3.76730313461771e-2); }
-  
-  //! conductance quantum (in siemens)
-  static eT G_0()       { return eT(7.7480917004e-5); }
-  
-  //! Coulomb's constant (in meters per farad)
-  static eT k_e()       { return eT(8.9875517873681764e9); }
-  
-  //! electric constant (in farads per meter)
-  static eT eps_0()     { return eT(8.85418781762039e-12); }
-  
-  //! electron mass (in kg)
-  static eT m_e()       { return eT(9.10938215e-31); }
-  
-  //! electron volt (in joules)
-  static eT eV()        { return eT(1.602176487e-19); }
-  
-  //! elementary charge (in coulombs)
-  static eT e()         { return eT(1.602176487e-19); }
-  
-  //! Faraday constant (in coulombs)
-  static eT F()         { return eT(96485.3399); }
-  
-  //! fine-structure constant
-  static eT alpha()     { return eT(7.2973525376e-3); }
-  
-  //! inverse fine-structure constant
-  static eT alpha_inv() { return eT(137.035999679); }
-  
-  //! Josephson constant
-  static eT K_J()       { return eT(483597.891e9); }
-  
-  //! magnetic constant (in henries per meter)
-  static eT mu_0()      { return eT(1.25663706143592e-06); }
-  
-  //! magnetic flux quantum (in webers)
-  static eT phi_0()     { return eT(2.067833667e-15); }
-  
-  //! molar gas constant (in joules per mole kelvin)
-  static eT R()         { return eT(8.314472); }
-  
-  //! Newtonian constant of gravitation (in newton square meters per kilogram squared)
-  static eT G()         { return eT(6.67428e-11); }
-  
-  //! Planck constant (in joule seconds)
-  static eT h()         { return eT(6.62606896e-34); }
-  
-  //! Planck constant over 2 pi, aka reduced Planck constant (in joule seconds)
-  static eT h_bar()     { return eT(1.054571628e-34); }
-  
-  //! proton mass (in kg)
-  static eT m_p()       { return eT(1.672621637e-27); }
-  
-  //! Rydberg constant (in reciprocal meters)
-  static eT R_inf()     { return eT(10973731.568527); }
-  
-  //! speed of light in vacuum (in meters per second)
-  static eT c_0()       { return eT(299792458.0); }
-  
-  //! Stefan-Boltzmann constant
-  static eT sigma()     { return eT(5.670400e-8); }
-  
-  //! von Klitzing constant (in ohms)
-  static eT R_k()       { return eT(25812.807557); }
-  
-  //! Wien wavelength displacement law constant
-  static eT b()         { return eT(2.8977685e-3); }
-  };
-
-
-
-typedef Math<float>  fmath;
-typedef Math<double> math;
-
-typedef Phy<float>   fphy;
-typedef Phy<double>  phy;
-
-
-
-namespace priv
-  {
-  
-  template<typename eT>
-  static
-  arma_inline
-  arma_hot
-  typename arma_float_only<eT>::result
-  most_neg(typename arma_float_only<eT>::result* junk = 0)
-    {
-    arma_ignore(junk);
-    
-    if(std::numeric_limits<eT>::has_infinity == true)
-      {
-      return -(std::numeric_limits<eT>::infinity());
-      }
-    else
-      {
-      return -(std::numeric_limits<eT>::max());
-      }
-    }
-  
-  
-  template<typename eT>
-  static
-  arma_inline
-  arma_hot
-  typename arma_integral_only<eT>::result
-  most_neg(typename arma_integral_only<eT>::result* junk = 0)
-    {
-    arma_ignore(junk);
-    
-    return std::numeric_limits<eT>::min();
-    }
-  
-  
-  template<typename eT>
-  static
-  arma_inline
-  arma_hot
-  typename arma_float_only<eT>::result
-  most_pos(typename arma_float_only<eT>::result* junk = 0)
-    {
-    arma_ignore(junk);
-    
-    if(std::numeric_limits<eT>::has_infinity == true)
-      {
-      return std::numeric_limits<eT>::infinity();
-      }
-    else
-      {
-      return std::numeric_limits<eT>::max();
-      }
-    }
-  
-  
-  template<typename eT>
-  static
-  arma_inline
-  arma_hot
-  typename arma_integral_only<eT>::result
-  most_pos(typename arma_integral_only<eT>::result* junk = 0)
-    {
-    arma_ignore(junk);
-    
-    return std::numeric_limits<eT>::max();
-    }
-
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/debug.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1183 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// Copyright (C) 2011 Stanislav Funiak
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup debug
-//! @{
-
-
-
-template<typename T>
-inline
-std::ostream&
-arma_stream_err1(std::ostream* user_stream)
-  {
-  static std::ostream* stream_err1 = &(ARMA_DEFAULT_OSTREAM);
-  
-  if(user_stream != NULL)
-    {
-    stream_err1 = user_stream;
-    }
-  
-  return *stream_err1;
-  }
-
-
-
-template<typename T>
-inline
-std::ostream&
-arma_stream_err2(std::ostream* user_stream)
-  {
-  static std::ostream* stream_err2 = &(ARMA_DEFAULT_OSTREAM);
-  
-  if(user_stream != NULL)
-    {
-    stream_err2 = user_stream;
-    }
-  
-  return *stream_err2;
-  }
-
-
-
-inline
-void
-set_stream_err1(std::ostream& user_stream)
-  {
-  arma_stream_err1<char>(&user_stream);
-  }
-
-
-
-inline
-void
-set_stream_err2(std::ostream& user_stream)
-  {
-  arma_stream_err2<char>(&user_stream);
-  }
-
-
-
-inline
-std::ostream&
-get_stream_err1()
-  {
-  return arma_stream_err1<char>(NULL);
-  }
-
-
-
-inline
-std::ostream&
-get_stream_err2()
-  {
-  return arma_stream_err2<char>(NULL);
-  }
-
-
-
-//
-// arma_stop
-
-//! print a message to get_stream_err1() and/or throw a logic_error exception
-template<typename T1>
-inline
-void
-arma_cold
-arma_stop(const T1& x)
-  {
-  #if defined(ARMA_PRINT_LOGIC_ERRORS)
-    {
-    std::ostream& out = get_stream_err1();
-    
-    out.flush();
-    
-    out << '\n';
-    out << "error: " << x << '\n';
-    out << '\n';
-    out.flush();
-    }
-  #else
-    {
-    arma_ignore(x);
-    }
-  #endif
-  
-  throw std::logic_error("");
-  }
-
-
-
-template<typename T1>
-inline
-void
-arma_cold
-arma_stop_bad_alloc(const T1& x)
-  {
-  std::ostream& out = get_stream_err1();
-  
-  out.flush();
-  
-  out << '\n';
-  out << "error: " << x << '\n';
-  out << '\n';
-  out.flush();
-  
-  throw std::bad_alloc();
-  }
-
-
-
-//
-// arma_bad
-
-//! print a message to get_stream_err2() and/or throw a run-time error exception
-template<typename T1>
-inline
-void
-arma_cold
-arma_bad(const T1& x, const bool hurl = true)
-  {
-  #if defined(ARMA_PRINT_RUNTIME_ERRORS)
-    {
-    std::ostream& out = get_stream_err2();
-    
-    out.flush();
-    
-    out << '\n';
-    out << "error: " << x << '\n';
-    out << '\n';
-    out.flush();
-    }
-  #else
-    {
-    arma_ignore(x);
-    }
-  #endif
-  
-  if(hurl == true)
-    {
-    throw std::runtime_error("");
-    }
-  }
-
-
-
-//
-// arma_print
-
-
-inline
-void
-arma_cold
-arma_print()
-  {
-  get_stream_err1() << std::endl;
-  }
-
-
-template<typename T1>
-inline
-void
-arma_cold
-arma_print(const T1& x)
-  {
-  get_stream_err1() << x << std::endl;
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-arma_cold
-arma_print(const T1& x, const T2& y)
-  {
-  get_stream_err1() << x << y << std::endl;
-  }
-
-
-
-template<typename T1, typename T2, typename T3>
-inline
-void
-arma_cold
-arma_print(const T1& x, const T2& y, const T3& z)
-  {
-  get_stream_err1() << x << y << z << std::endl;
-  }
-
-
-
-
-
-
-//
-// arma_sigprint
-
-//! print a message the the log stream with a preceding @ character.
-//! by default the log stream is cout.
-//! used for printing the signature of a function
-//! (see the arma_extra_debug_sigprint macro) 
-inline
-void
-arma_sigprint(const char* x)
-  {
-  get_stream_err1() << "@ " << x;
-  }
-
-
-
-//
-// arma_bktprint
-
-
-inline
-void
-arma_bktprint()
-  {
-  get_stream_err1() << std::endl;
-  }
-
-
-template<typename T1>
-inline
-void
-arma_bktprint(const T1& x)
-  {
-  get_stream_err1() << " [" << x << ']' << std::endl;
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-arma_bktprint(const T1& x, const T2& y)
-  {
-  get_stream_err1() << " [" << x << y << ']' << std::endl;
-  }
-
-
-
-
-
-
-//
-// arma_thisprint
-
-inline
-void
-arma_thisprint(const void* this_ptr)
-  {
-  get_stream_err1() << " [this = " << this_ptr << ']' << std::endl;
-  }
-
-
-
-//
-// arma_warn
-
-
-//! print a message to the warn stream
-template<typename T1>
-inline
-void
-arma_cold
-arma_warn(const bool state, const T1& x)
-  {
-  if(state==true)
-    {
-    get_stream_err2() << x << std::endl;
-    }
-  }
-
-
-template<typename T1, typename T2>
-inline
-void
-arma_cold
-arma_warn(const bool state, const T1& x, const T2& y)
-  {
-  if(state==true)
-    {
-    get_stream_err2() << x << y << std::endl;
-    }
-  }
-
-
-template<typename T1, typename T2, typename T3>
-inline
-void
-arma_cold
-arma_warn(const bool state, const T1& x, const T2& y, const T3& z)
-  {
-  if(state==true)
-    {
-    get_stream_err2() << x << y << z << std::endl;
-    }
-  }
-
-
-
-//
-// arma_check
-
-//! if state is true, abort program
-template<typename T1>
-inline
-void
-arma_hot
-arma_check(const bool state, const T1& x)
-  {
-  if(state==true)
-    {
-    arma_stop(arma_boost::str_wrapper(x));
-    }
-  }
-
-
-template<typename T1, typename T2>
-inline
-void
-arma_hot
-arma_check(const bool state, const T1& x, const T2& y)
-  {
-  if(state==true)
-    {
-    arma_stop( std::string(x) + std::string(y) );
-    }
-  }
-
-
-template<typename T1>
-inline
-void
-arma_hot
-arma_check_bad_alloc(const bool state, const T1& x)
-  {
-  if(state==true)
-    {
-    arma_stop_bad_alloc(x);
-    }
-  }
-
-
-
-//
-// arma_set_error
-
-
-arma_inline
-void
-arma_hot
-arma_set_error(bool& err_state, char*& err_msg, const bool expression, const char* message)
-  {
-  if(expression == true)
-    {
-    err_state = true;
-    err_msg   = const_cast<char*>(message);
-    }
-  }
-
-
-
-
-//
-// functions for generating strings indicating size errors
-
-inline
-std::string
-arma_cold
-arma_incompat_size_string(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x)
-  {
-  std::stringstream tmp;
-  
-  tmp << x << ": incompatible matrix dimensions: " << A_n_rows << 'x' << A_n_cols << " and " << B_n_rows << 'x' << B_n_cols;
-  
-  return tmp.str();
-  }
-
-
-
-inline
-arma_cold
-std::string
-arma_incompat_size_string(const uword A_n_rows, const uword A_n_cols, const uword A_n_slices, const uword B_n_rows, const uword B_n_cols, const uword B_n_slices, const char* x)
-  {
-  std::stringstream tmp;
-  
-  tmp << x << ": incompatible cube dimensions: " << A_n_rows << 'x' << A_n_cols << 'x' << A_n_slices << " and " << B_n_rows << 'x' << B_n_cols << 'x' << B_n_slices;
-  
-  return tmp.str();
-  }
-
-
-
-template<typename eT>
-inline
-arma_cold
-std::string
-arma_incompat_size_string(const subview_cube<eT>& Q, const Mat<eT>& A, const char* x)
-  {
-  std::stringstream tmp;
-  
-  tmp << x
-      << ": interpreting matrix as cube with dimenensions: "
-      << A.n_rows << 'x' << A.n_cols << 'x' << 1
-      << " or "
-      << A.n_rows << 'x' << 1        << 'x' << A.n_cols
-      << " or "
-      << 1        << 'x' << A.n_rows << 'x' << A.n_cols
-      << " is incompatible with cube dimensions: "
-      << Q.n_rows << 'x' << Q.n_cols << 'x' << Q.n_slices;
-      
-  return tmp.str();
-  }
-
-
-
-//
-// functions for checking whether two matrices have the same dimensions
-
-
-
-inline
-void
-arma_hot
-arma_assert_same_size(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x)
-  {
-  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
-    {
-    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
-    }
-  }
-
-
-
-//! stop if given matrices have different sizes
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const Mat<eT1>& A, const Mat<eT2>& B, const char* x)
-  {
-  const uword A_n_rows = A.n_rows;
-  const uword A_n_cols = A.n_cols;
-  
-  const uword B_n_rows = B.n_rows;
-  const uword B_n_cols = B.n_cols;
-  
-  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
-    {
-    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
-    }
-  }
-
-
-
-//! stop if given proxies have different sizes
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const Proxy<eT1>& A, const Proxy<eT2>& B, const char* x)
-  {
-  const uword A_n_rows = A.get_n_rows();
-  const uword A_n_cols = A.get_n_cols();
-  
-  const uword B_n_rows = B.get_n_rows();
-  const uword B_n_cols = B.get_n_cols();
-  
-  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
-    {
-    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const subview<eT1>& A, const subview<eT2>& B, const char* x)
-  {
-  const uword A_n_rows = A.n_rows;
-  const uword A_n_cols = A.n_cols;
-  
-  const uword B_n_rows = B.n_rows;
-  const uword B_n_cols = B.n_cols;
-  
-  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
-    {
-    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const Mat<eT1>& A, const subview<eT2>& B, const char* x)
-  {
-  const uword A_n_rows = A.n_rows;
-  const uword A_n_cols = A.n_cols;
-  
-  const uword B_n_rows = B.n_rows;
-  const uword B_n_cols = B.n_cols;
-  
-  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
-    {
-    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const subview<eT1>& A, const Mat<eT2>& B, const char* x)
-  {
-  const uword A_n_rows = A.n_rows;
-  const uword A_n_cols = A.n_cols;
-  
-  const uword B_n_rows = B.n_rows;
-  const uword B_n_cols = B.n_cols;
-  
-  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
-    {
-    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const Mat<eT1>& A, const Proxy<eT2>& B, const char* x)
-  {
-  const uword A_n_rows = A.n_rows;
-  const uword A_n_cols = A.n_cols;
-  
-  const uword B_n_rows = B.get_n_rows();
-  const uword B_n_cols = B.get_n_cols();
-  
-  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
-    {
-    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const Proxy<eT1>& A, const Mat<eT2>& B, const char* x)
-  {
-  const uword A_n_rows = A.get_n_rows();
-  const uword A_n_cols = A.get_n_cols();
-  
-  const uword B_n_rows = B.n_rows;
-  const uword B_n_cols = B.n_cols;
-  
-  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
-    {
-    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const Proxy<eT1>& A, const subview<eT2>& B, const char* x)
-  {
-  const uword A_n_rows = A.get_n_rows();
-  const uword A_n_cols = A.get_n_cols();
-  
-  const uword B_n_rows = B.n_rows;
-  const uword B_n_cols = B.n_cols;
-  
-  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
-    {
-    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const subview<eT1>& A, const Proxy<eT2>& B, const char* x)
-  {
-  const uword A_n_rows = A.n_rows;
-  const uword A_n_cols = A.n_cols;
-  
-  const uword B_n_rows = B.get_n_rows();
-  const uword B_n_cols = B.get_n_cols();
-  
-  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
-    {
-    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
-    }
-  }
-
-
-
-//
-// functions for checking whether two cubes have the same dimensions
-
-
-
-inline
-void
-arma_hot
-arma_assert_same_size(const uword A_n_rows, const uword A_n_cols, const uword A_n_slices, const uword B_n_rows, const uword B_n_cols, const uword B_n_slices, const char* x)
-  {
-  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) || (A_n_slices != B_n_slices) )
-    {
-    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, A_n_slices, B_n_rows, B_n_cols, B_n_slices, x) );
-    }
-  }
-
-
-
-//! stop if given cubes have different sizes
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const Cube<eT1>& A, const Cube<eT2>& B, const char* x)
-  {
-  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
-    {
-    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const Cube<eT1>& A, const subview_cube<eT2>& B, const char* x)
-  {
-  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
-    {
-    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const subview_cube<eT1>& A, const Cube<eT2>& B, const char* x)
-  {
-  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
-    {
-    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const subview_cube<eT1>& A, const subview_cube<eT2>& B, const char* x)
-  {
-  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices))
-    {
-    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
-    }
-  }
-
-
-
-//! stop if given cube proxies have different sizes
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const ProxyCube<eT1>& A, const ProxyCube<eT2>& B, const char* x)
-  {
-  const uword A_n_rows   = A.get_n_rows();
-  const uword A_n_cols   = A.get_n_cols();
-  const uword A_n_slices = A.get_n_slices();
-  
-  const uword B_n_rows   = B.get_n_rows();
-  const uword B_n_cols   = B.get_n_cols();
-  const uword B_n_slices = B.get_n_slices();
-  
-  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) || (A_n_slices != B_n_slices))
-    {
-    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, A_n_slices, B_n_rows, B_n_cols, B_n_slices, x) );
-    }
-  }
-
-
-
-//
-// functions for checking whether a cube or subcube can be interpreted as a matrix (i.e. single slice)
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const Cube<eT1>& A, const Mat<eT2>& B, const char* x)
-  {
-  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != 1) )
-    {
-    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, 1, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const Mat<eT1>& A, const Cube<eT2>& B, const char* x)
-  {
-  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (1 != B.n_slices) )
-    {
-    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, 1, B.n_rows, B.n_cols, B.n_slices, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const subview_cube<eT1>& A, const Mat<eT2>& B, const char* x)
-  {
-  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != 1) )
-    {
-    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, 1, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_same_size(const Mat<eT1>& A, const subview_cube<eT2>& B, const char* x)
-  {
-  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (1 != B.n_slices) )
-    {
-    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, 1, B.n_rows, B.n_cols, B.n_slices, x) );
-    }
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-arma_assert_cube_as_mat(const Mat<eT>& M, const T1& Q, const char* x, const bool check_compat_size)
-  {
-  const uword Q_n_rows   = Q.n_rows;
-  const uword Q_n_cols   = Q.n_cols;
-  const uword Q_n_slices = Q.n_slices;
-  
-  const uword M_vec_state = M.vec_state;
-  
-  if(M_vec_state == 0)
-    {
-    if( ( (Q_n_rows == 1) || (Q_n_cols == 1) || (Q_n_slices == 1) ) == false )
-      {
-      std::stringstream tmp;
-        
-      tmp << x
-          << ": can't interpret cube with dimensions "
-          << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices 
-          << " as a matrix; one of the dimensions must be 1";
-      
-      arma_stop( tmp.str() );
-      }
-    }
-  else
-    {
-    if(Q_n_slices == 1)
-      {
-      if( (M_vec_state == 1) && (Q_n_cols != 1) )
-        {
-        std::stringstream tmp;
-        
-        tmp << x
-            << ": can't interpret cube with dimensions "
-            << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
-            << " as a column vector";
-        
-        arma_stop( tmp.str() );
-        }
-      
-      if( (M_vec_state == 2) && (Q_n_rows != 1) )
-        {
-        std::stringstream tmp;
-        
-        tmp << x
-            << ": can't interpret cube with dimensions "
-            << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
-            << " as a row vector";
-        
-        arma_stop( tmp.str() );
-        }
-      }
-    else
-      {
-      if( (Q_n_cols != 1) && (Q_n_rows != 1) )
-        {
-        std::stringstream tmp;
-        
-        tmp << x
-            << ": can't interpret cube with dimensions "
-            << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
-            << " as a vector";
-        
-        arma_stop( tmp.str() );
-        }
-      }
-    }
-  
-  
-  if(check_compat_size == true)
-    {
-    const uword M_n_rows = M.n_rows;
-    const uword M_n_cols = M.n_cols;
-    
-    if(M_vec_state == 0)
-      {
-      if(
-          (
-          ( (Q_n_rows == M_n_rows) && (Q_n_cols   == M_n_cols) )
-          ||
-          ( (Q_n_rows == M_n_rows) && (Q_n_slices == M_n_cols) )
-          ||
-          ( (Q_n_cols == M_n_rows) && (Q_n_slices == M_n_cols) )
-          )
-          == false
-        )
-        {
-        std::stringstream tmp;
-        
-        tmp << x
-            << ": can't interpret cube with dimenensions "
-            << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
-            << " as a matrix with dimensions "
-            << M_n_rows << 'x' << M_n_cols;
-        
-        arma_stop( tmp.str() );
-        }
-      }
-    else
-      {
-      if(Q_n_slices == 1)
-        {
-        if( (M_vec_state == 1) && (Q_n_rows != M_n_rows) )
-          {
-          std::stringstream tmp;
-          
-          tmp << x
-              << ": can't interpret cube with dimensions "
-              << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
-              << " as a column vector with dimensions "
-              << M_n_rows << 'x' << M_n_cols;
-          
-          arma_stop( tmp.str() );
-          }
-        
-        if( (M_vec_state == 2) && (Q_n_cols != M_n_cols) )
-          {
-          std::stringstream tmp;
-          
-          tmp << x
-              << ": can't interpret cube with dimensions "
-              << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
-              << " as a row vector with dimensions "
-              << M_n_rows << 'x' << M_n_cols;
-          
-          arma_stop( tmp.str() );
-          }
-        }
-      else
-        {
-        if( ( (M_n_cols == Q_n_slices) || (M_n_rows == Q_n_slices) ) == false )
-          {
-          std::stringstream tmp;
-          
-          tmp << x
-              << ": can't interpret cube with dimensions "
-              << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
-              << " as a vector with dimensions "
-              << M_n_rows << 'x' << M_n_cols;
-          
-          arma_stop( tmp.str() );
-          }
-        }
-      }
-    }
-  }
-
-
-
-//
-// functions for checking whether two matrices have dimensions that are compatible with the matrix multiply operation
-
-
-
-inline
-void
-arma_hot
-arma_assert_mul_size(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x)
-  {
-  if(A_n_cols != B_n_rows)
-    {
-    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
-    }
-  }
-
-
-
-//! stop if given matrices are incompatible for multiplication
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_mul_size(const Mat<eT1>& A, const Mat<eT2>& B, const char* x)
-  {
-  const uword A_n_cols = A.n_cols;
-  const uword B_n_rows = B.n_rows;
-  
-  if(A_n_cols != B_n_rows)
-    {
-    arma_stop( arma_incompat_size_string(A.n_rows, A_n_cols, B_n_rows, B.n_cols, x) );
-    }
-  }
-
-
-
-//! stop if given matrices are incompatible for multiplication
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_mul_size(const Mat<eT1>& A, const Mat<eT2>& B, const bool do_trans_A, const bool do_trans_B, const char* x)
-  {
-  const uword final_A_n_cols = (do_trans_A == false) ? A.n_cols : A.n_rows;
-  const uword final_B_n_rows = (do_trans_B == false) ? B.n_rows : B.n_cols;
-    
-  if(final_A_n_cols != final_B_n_rows)
-    {
-    const uword final_A_n_rows = (do_trans_A == false) ? A.n_rows : A.n_cols;
-    const uword final_B_n_cols = (do_trans_B == false) ? B.n_cols : B.n_rows;
-    
-    arma_stop( arma_incompat_size_string(final_A_n_rows, final_A_n_cols, final_B_n_rows, final_B_n_cols, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_mul_size(const Mat<eT1>& A, const subview<eT2>& B, const char* x)
-  {
-  if(A.n_cols != B.n_rows)
-    {
-    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_mul_size(const subview<eT1>& A, const Mat<eT2>& B, const char* x)
-  {
-  if(A.n_cols != B.n_rows)
-    {
-    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
-    }
-  }
-
-
-
-template<typename eT1, typename eT2>
-inline
-void
-arma_hot
-arma_assert_mul_size(const subview<eT1>& A, const subview<eT2>& B, const char* x)
-  {
-  if(A.n_cols != B.n_rows)
-    {
-    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
-    }
-  }
-
-
-
-//
-// macros
-
-
-#define ARMA_STRING1(x) #x
-#define ARMA_STRING2(x) ARMA_STRING1(x)
-#define ARMA_FILELINE  __FILE__ ": " ARMA_STRING2(__LINE__)
-
-
-#if defined (__GNUG__)
-  #define ARMA_FNSIG  __PRETTY_FUNCTION__
-#elif defined (_MSC_VER)
-  #define ARMA_FNSIG  __FUNCSIG__ 
-#elif defined (ARMA_USE_BOOST)
-  #define ARMA_FNSIG  BOOST_CURRENT_FUNCTION  
-#else 
-  #define ARMA_FNSIG  "(unknown)"
-#endif
-
-
-
-#if !defined(ARMA_NO_DEBUG) && !defined(NDEBUG)
-  
-  #define arma_debug_print              arma_print
-  #define arma_debug_warn               arma_warn
-  #define arma_debug_check              arma_check
-  #define arma_debug_set_error          arma_set_error
-  #define arma_debug_assert_same_size   arma_assert_same_size
-  #define arma_debug_assert_mul_size    arma_assert_mul_size
-  #define arma_debug_assert_cube_as_mat arma_assert_cube_as_mat
-  
-#else
-  
-  #undef ARMA_EXTRA_DEBUG
-  
-  #define arma_debug_print              true ? (void)0 : arma_print
-  #define arma_debug_warn               true ? (void)0 : arma_warn
-  #define arma_debug_check              true ? (void)0 : arma_check
-  #define arma_debug_set_error          true ? (void)0 : arma_set_error
-  #define arma_debug_assert_same_size   true ? (void)0 : arma_assert_same_size
-  #define arma_debug_assert_mul_size    true ? (void)0 : arma_assert_mul_size
-  #define arma_debug_assert_cube_as_mat true ? (void)0 : arma_debug_assert_cube_as_mat
-
-#endif
-
-
-
-#if defined(ARMA_EXTRA_DEBUG)
-  
-  #define arma_extra_debug_sigprint       arma_sigprint(ARMA_FNSIG); arma_bktprint
-  #define arma_extra_debug_sigprint_this  arma_sigprint(ARMA_FNSIG); arma_thisprint
-  #define arma_extra_debug_print          arma_print
-  #define arma_extra_debug_warn           arma_warn
-  #define arma_extra_debug_check          arma_check
-
-#else
-  
-  #define arma_extra_debug_sigprint        true ? (void)0 : arma_bktprint
-  #define arma_extra_debug_sigprint_this   true ? (void)0 : arma_thisprint
-  #define arma_extra_debug_print           true ? (void)0 : arma_print
-  #define arma_extra_debug_warn            true ? (void)0 : arma_warn
-  #define arma_extra_debug_check           true ? (void)0 : arma_check
- 
-#endif
-
-
-
-
-#if defined(ARMA_EXTRA_DEBUG)
-
-  namespace junk
-    {
-    class arma_first_extra_debug_message
-      {
-      public:
-      
-      inline
-      arma_cold
-      arma_first_extra_debug_message()
-        {
-        union
-          {
-          unsigned short a;
-          unsigned char  b[sizeof(unsigned short)];
-          } endian_test;
-          
-        endian_test.a = 1;
-        
-        const bool  little_endian = (endian_test.b[0] == 1);
-        const char* nickname      = ARMA_VERSION_NAME;
-        
-        std::ostream& out = get_stream_err1();
-        
-        out << "@ ---" << '\n';
-        out << "@ Armadillo "
-            << arma_version::major << '.' << arma_version::minor << '.' << arma_version::patch
-            << " (" << nickname << ")\n";
-        
-        out << "@ arma_config::mat_prealloc   = " << arma_config::mat_prealloc   << " element(s)\n";
-        out << "@ arma_config::atlas          = " << arma_config::atlas          << '\n';
-        out << "@ arma_config::lapack         = " << arma_config::lapack         << '\n';
-        out << "@ arma_config::blas           = " << arma_config::blas           << '\n';
-        out << "@ arma_config::boost          = " << arma_config::boost          << '\n';
-        out << "@ arma_config::boost_date     = " << arma_config::boost_date     << '\n';
-        out << "@ arma_config::good_comp      = " << arma_config::good_comp      << '\n';
-        out << "@ arma_config::extra_code     = " << arma_config::extra_code     << '\n';
-        out << "@ sizeof(void*)    = " << sizeof(void*)    << '\n';
-        out << "@ sizeof(uword)    = " << sizeof(uword)    << '\n';
-        out << "@ sizeof(int)      = " << sizeof(int)      << '\n';
-        out << "@ sizeof(long)     = " << sizeof(long)     << '\n';
-        out << "@ sizeof(blas_int) = " << sizeof(blas_int) << '\n';
-        out << "@ little_endian    = " << little_endian    << '\n';
-        out << "@ ---" << std::endl;
-        }
-      
-      };
-    
-    static arma_first_extra_debug_message arma_first_extra_debug_message_run;
-    }
-
-#endif
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/diagmat_proxy.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,339 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup diagmat_proxy
-//! @{
-
-
-
-template<typename T1>
-class diagmat_proxy
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  inline diagmat_proxy(const Base<typename T1::elem_type,T1>& X)
-    : P       ( X.get_ref() )
-    , P_is_vec( (P.get_n_rows() == 1) || (P.get_n_cols() == 1) )
-    , n_elem  ( P_is_vec ? P.get_n_elem() : (std::min)(P.get_n_elem(), P.get_n_rows()) )
-    {
-    arma_extra_debug_sigprint();
-    
-    arma_debug_check
-      (
-      (P_is_vec == false) && (P.get_n_rows() != P.get_n_cols()),
-      "diagmat(): only vectors and square matrices are accepted"
-      );
-    }
-  
-  
-  arma_inline
-  elem_type
-  operator[](const uword i) const
-    {
-    if( (Proxy<T1>::prefer_at_accessor == true) || (P_is_vec == false) )
-      {
-      return P.at(i,i);
-      }
-    else
-      {
-      return P[i];
-      }
-    }
-  
-  
-  arma_inline
-  elem_type
-  at(const uword row, const uword col) const
-    {
-    if(row == col)
-      {
-      if( (Proxy<T1>::prefer_at_accessor == true) || (P_is_vec == false) )
-        {
-        return P.at(row,row);
-        }
-      else
-        {
-        return P[row];
-        }
-      }
-    else
-      {
-      return elem_type(0);
-      }
-    }
-  
-  
-  const Proxy<T1> P;
-  const bool      P_is_vec;
-  const uword     n_elem;
-  };
-
-
-
-template<typename eT>
-class diagmat_proxy< Mat<eT> >
-  {
-  public:
-  
-  typedef          eT                              elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  
-  inline diagmat_proxy(const Mat<eT>& X)
-    : P(X)
-    , P_is_vec( (P.n_rows == 1) || (P.n_cols == 1) )
-    , n_elem( P_is_vec ? P.n_elem : (std::min)(P.n_elem, P.n_rows) )
-    {
-    arma_extra_debug_sigprint();
-    
-    arma_debug_check
-      (
-      (P_is_vec == false) && (P.n_rows != P.n_cols),
-      "diagmat(): only vectors and square matrices are accepted"
-      );
-    }
-  
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return P_is_vec ? P[i] : P.at(i,i);                                         }
-  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? ( P_is_vec ? P[row] : P.at(row,row) ) : elem_type(0); }
-
-  const Mat<eT>& P;
-  const bool     P_is_vec;
-  const uword    n_elem;
-  };
-
-
-
-template<typename eT>
-class diagmat_proxy< Row<eT> >
-  {
-  public:
-  
-  typedef          eT                              elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  
-  inline diagmat_proxy(const Row<eT>& X)
-    : P(X)
-    , P_is_vec(true)
-    , n_elem(P.n_elem)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return P[i];                                                                }
-  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); }
-
-
-  const Row<eT>& P;
-  const bool     P_is_vec;
-  const uword    n_elem;
-  };
-
-
-
-template<typename eT>
-class diagmat_proxy< Col<eT> >
-  {
-  public:
-  
-  typedef          eT                              elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  
-  inline diagmat_proxy(const Col<eT>& X)
-    : P(X)
-    , P_is_vec(true)
-    , n_elem(P.n_elem)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return P[i];                                 }
-  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); }
-  
-
-  const Col<eT>& P;
-  const bool     P_is_vec;
-  const uword    n_elem;
-  };
-
-
-
-template<typename T1>
-class diagmat_proxy_check
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  inline diagmat_proxy_check(const Base<typename T1::elem_type,T1>& X, const Mat<typename T1::elem_type>& out)
-    : P(X.get_ref())
-    , P_is_vec( (P.n_rows == 1) || (P.n_cols == 1) )
-    , n_elem( P_is_vec ? P.n_elem : (std::min)(P.n_elem, P.n_rows) )
-    {
-    arma_extra_debug_sigprint();
-    arma_ignore(out);
-    
-    arma_debug_check
-      (
-      (P_is_vec == false) && (P.n_rows != P.n_cols),
-      "diagmat(): only vectors and square matrices are accepted"
-      );
-    }
-  
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return P_is_vec ? P[i] : P.at(i,i);                                         }
-  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? ( P_is_vec ? P[row] : P.at(row,row) ) : elem_type(0); }
-  
-
-  const Mat<elem_type> P;
-  const bool           P_is_vec;
-  const uword          n_elem;
-  };
-
-
-
-template<typename eT>
-class diagmat_proxy_check< Mat<eT> >
-  {
-  public:
-  
-  typedef          eT                              elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  
-  inline diagmat_proxy_check(const Mat<eT>& X, const Mat<eT>& out)
-    : P_local ( (&X == &out) ? new Mat<eT>(X) : 0  )
-    , P       ( (&X == &out) ? (*P_local)     : X  )
-    , P_is_vec( (P.n_rows == 1) || (P.n_cols == 1) )
-    , n_elem  ( P_is_vec ? P.n_elem : (std::min)(P.n_elem, P.n_rows) )
-    {
-    arma_extra_debug_sigprint();
-    
-    arma_debug_check
-      (
-      (P_is_vec == false) && (P.n_rows != P.n_cols),
-      "diagmat(): only vectors and square matrices are accepted"
-      );
-    }
-  
-  inline ~diagmat_proxy_check()
-    {
-    if(P_local)
-      {
-      delete P_local;
-      }
-    }
-  
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return P_is_vec ? P[i] : P.at(i,i);                                         }
-  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? ( P_is_vec ? P[row] : P.at(row,row) ) : elem_type(0); }
-  
-
-  const Mat<eT>* P_local;
-  const Mat<eT>& P;
-  const bool     P_is_vec;
-  const uword    n_elem;
-  };
-
-
-
-template<typename eT>
-class diagmat_proxy_check< Row<eT> >
-  {
-  public:
-  
-  typedef          eT                              elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  inline diagmat_proxy_check(const Row<eT>& X, const Mat<eT>& out)
-    : P_local ( (&X == reinterpret_cast<const Row<eT>*>(&out)) ? new Row<eT>(X) : 0 )
-    , P       ( (&X == reinterpret_cast<const Row<eT>*>(&out)) ? (*P_local)     : X )
-    , P_is_vec(true)
-    , n_elem  (P.n_elem)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline ~diagmat_proxy_check()
-    {
-    if(P_local)
-      {
-      delete P_local;
-      }
-    }
-  
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return P[i];                                 }
-  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); }
-  
-  
-  const Row<eT>* P_local;
-  const Row<eT>& P;
-  const bool     P_is_vec;
-  const uword    n_elem;
-  };
-
-
-
-
-
-
-template<typename eT>
-class diagmat_proxy_check< Col<eT> >
-  {
-  public:
-  
-  typedef          eT                              elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  inline diagmat_proxy_check(const Col<eT>& X, const Mat<eT>& out)
-    : P_local ( (&X == reinterpret_cast<const Col<eT>*>(&out)) ? new Col<eT>(X) : 0 )
-    , P       ( (&X == reinterpret_cast<const Col<eT>*>(&out)) ? (*P_local)     : X )
-    , P_is_vec(true)
-    , n_elem  (P.n_elem)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline ~diagmat_proxy_check()
-    {
-    if(P_local)
-      {
-      delete P_local;
-      }
-    }
-  
-  
-  arma_inline elem_type operator[] (const uword i)                    const { return P[i];                                 }
-  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); }
-  
-  
-  const Col<eT>* P_local;
-  const Col<eT>& P;
-  const bool     P_is_vec;
-  const uword    n_elem;
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/diagview_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup diagview
-//! @{
-
-
-//! Class for storing data required to extract and set the diagonals of a matrix
-template<typename eT>
-class diagview : public Base<eT, diagview<eT> >
-  {
-  public:    arma_aligned const Mat<eT>& m;
-  protected: arma_aligned       Mat<eT>* m_ptr;
-  
-  public:
-  
-  typedef eT                                elem_type;
-  typedef typename get_pod_type<eT>::result pod_type;
-  
-  const uword row_offset;
-  const uword col_offset;
-  
-  const uword n_rows;     // equal to n_elem
-  const uword n_elem;
-  
-  static const uword n_cols = 1;
-  
-  
-  protected:
-  
-  arma_inline diagview(const Mat<eT>& in_m, const uword in_row_offset, const uword in_col_offset, const uword len);
-  arma_inline diagview(      Mat<eT>& in_m, const uword in_row_offset, const uword in_col_offset, const uword len);
-  
-  
-  public:
-  
-  inline ~diagview();
-  
-  inline void operator=(const diagview& x);
-  
-  inline void operator+=(const eT val);
-  inline void operator-=(const eT val);
-  inline void operator*=(const eT val);
-  inline void operator/=(const eT val);
-  
-  template<typename T1> inline void operator= (const Base<eT,T1>& x);
-  template<typename T1> inline void operator+=(const Base<eT,T1>& x);
-  template<typename T1> inline void operator-=(const Base<eT,T1>& x);
-  template<typename T1> inline void operator%=(const Base<eT,T1>& x);
-  template<typename T1> inline void operator/=(const Base<eT,T1>& x);
-  
-  
-  arma_inline eT& operator[](const uword i);
-  arma_inline eT  operator[](const uword i) const;
-  
-  arma_inline eT&         at(const uword i);
-  arma_inline eT          at(const uword i) const;
-  
-  arma_inline eT& operator()(const uword i);
-  arma_inline eT  operator()(const uword i) const;
-  
-  arma_inline eT&         at(const uword in_n_row, const uword in_n_col);
-  arma_inline eT          at(const uword in_n_row, const uword in_n_col) const;
-   
-  arma_inline eT& operator()(const uword in_n_row, const uword in_n_col);
-  arma_inline eT  operator()(const uword in_n_row, const uword in_n_col) const;
-  
-  
-  inline void fill(const eT val);
-  inline void zeros();
-  inline void ones();
-  
-  inline static void extract(Mat<eT>& out, const diagview& in);
-  
-  inline static void  plus_inplace(Mat<eT>& out, const diagview& in);
-  inline static void minus_inplace(Mat<eT>& out, const diagview& in);
-  inline static void schur_inplace(Mat<eT>& out, const diagview& in);
-  inline static void   div_inplace(Mat<eT>& out, const diagview& in);
-  
-  
-  private:
-  
-  friend class Mat<eT>;
-  friend class subview<eT>;
-  
-  diagview();
-  //diagview(const diagview&);  // making this private causes an error under gcc 4.1/4.2, but not 4.3
-  };
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/diagview_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,745 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup diagview
-//! @{
-
-
-template<typename eT>
-inline
-diagview<eT>::~diagview()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-template<typename eT>
-arma_inline
-diagview<eT>::diagview(const Mat<eT>& in_m, const uword in_row_offset, const uword in_col_offset, const uword in_len)
-  : m(in_m)
-  , m_ptr(0)
-  , row_offset(in_row_offset)
-  , col_offset(in_col_offset)
-  , n_rows(in_len)
-  , n_elem(in_len)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-arma_inline
-diagview<eT>::diagview(Mat<eT>& in_m, const uword in_row_offset, const uword in_col_offset, const uword in_len)
-  : m(in_m)
-  , m_ptr(&in_m)
-  , row_offset(in_row_offset)
-  , col_offset(in_col_offset)
-  , n_rows(in_len)
-  , n_elem(in_len)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-//! set a diagonal of our matrix using a diagonal from a foreign matrix
-template<typename eT>
-inline
-void
-diagview<eT>::operator= (const diagview<eT>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  diagview<eT>& t = *this;
-  
-  arma_debug_check( (t.n_elem != x.n_elem), "diagview: diagonals have incompatible lengths");
-  
-        Mat<eT>& t_m = *(t.m_ptr);
-  const Mat<eT>& x_m = x.m;
-  
-  if(&t_m != &x_m)
-    {
-    const uword t_n_elem     = t.n_elem;
-    const uword t_row_offset = t.row_offset;
-    const uword t_col_offset = t.col_offset;
-    
-    const uword x_row_offset = x.row_offset;
-    const uword x_col_offset = x.col_offset;
-    
-    uword i,j;
-    for(i=0, j=1; j < t_n_elem; i+=2, j+=2)
-      {
-      const eT tmp_i = x_m.at(i + x_row_offset, i + x_col_offset);
-      const eT tmp_j = x_m.at(j + x_row_offset, j + x_col_offset);
-      
-      t_m.at(i + t_row_offset, i + t_col_offset) = tmp_i;
-      t_m.at(j + t_row_offset, j + t_col_offset) = tmp_j;
-      }
-    
-    if(i < t_n_elem)
-      {
-      t_m.at(i + t_row_offset, i + t_col_offset) = x_m.at(i + x_row_offset, i + x_col_offset);
-      }
-    }
-  else
-    {
-    const Mat<eT> tmp = x;
-    
-    (*this).operator=(tmp);
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-diagview<eT>::operator+=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>& t_m = (*m_ptr);
-  
-  const uword t_n_elem     = n_elem;
-  const uword t_row_offset = row_offset;
-  const uword t_col_offset = col_offset;
-  
-  for(uword i=0; i<t_n_elem; ++i)
-    {
-    t_m.at( i + t_row_offset,  i + t_col_offset) += val;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-diagview<eT>::operator-=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>& t_m = (*m_ptr);
-  
-  const uword t_n_elem     = n_elem;
-  const uword t_row_offset = row_offset;
-  const uword t_col_offset = col_offset;
-  
-  for(uword i=0; i<t_n_elem; ++i)
-    {
-    t_m.at( i + t_row_offset,  i + t_col_offset) -= val;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-diagview<eT>::operator*=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>& t_m = (*m_ptr);
-  
-  const uword t_n_elem     = n_elem;
-  const uword t_row_offset = row_offset;
-  const uword t_col_offset = col_offset;
-  
-  for(uword i=0; i<t_n_elem; ++i)
-    {
-    t_m.at( i + t_row_offset,  i + t_col_offset) *= val;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-diagview<eT>::operator/=(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>& t_m = (*m_ptr);
-  
-  const uword t_n_elem     = n_elem;
-  const uword t_row_offset = row_offset;
-  const uword t_col_offset = col_offset;
-  
-  for(uword i=0; i<t_n_elem; ++i)
-    {
-    t_m.at( i + t_row_offset,  i + t_col_offset) /= val;
-    }
-  }
-
-
-
-//! set a diagonal of our matrix using data from a foreign object
-template<typename eT>
-template<typename T1>
-inline
-void
-diagview<eT>::operator= (const Base<eT,T1>& o)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1> tmp(o.get_ref());
-  const Mat<eT>& x = tmp.M;
-  
-  diagview<eT>& t = *this;
-  
-  arma_debug_check
-    (
-    ( (t.n_elem != x.n_elem) || (x.is_vec() == false) ),
-    "diagview: given object has incompatible size"
-    );
-  
-  Mat<eT>& t_m = *(t.m_ptr);
-  
-  const uword t_n_elem     = t.n_elem;
-  const uword t_row_offset = t.row_offset;
-  const uword t_col_offset = t.col_offset;
-  
-  const eT* x_mem = x.memptr();
-  
-  uword i,j;
-  for(i=0, j=1; j < t_n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = x_mem[i];
-    const eT tmp_j = x_mem[j];
-    
-    t_m.at( i + t_row_offset,  i + t_col_offset) = tmp_i;
-    t_m.at( j + t_row_offset,  j + t_col_offset) = tmp_j;
-    }
-  
-  if(i < t_n_elem)
-    {
-    t_m.at( i + t_row_offset,  i + t_col_offset) = x_mem[i];
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-diagview<eT>::operator+=(const Base<eT,T1>& o)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1> tmp(o.get_ref());
-  const Mat<eT>& x = tmp.M;
-  
-  diagview<eT>& t = *this;
-  
-  arma_debug_check
-    (
-    ( (t.n_elem != x.n_elem) || (x.is_vec() == false) ),
-    "diagview: given object has incompatible size"
-    );
-  
-  Mat<eT>& t_m = *(t.m_ptr);
-  
-  const uword t_n_elem     = t.n_elem;
-  const uword t_row_offset = t.row_offset;
-  const uword t_col_offset = t.col_offset;
-  
-  const eT* x_mem = x.memptr();
-  
-  uword i,j;
-  for(i=0, j=1; j < t_n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = x_mem[i];
-    const eT tmp_j = x_mem[j];
-    
-    t_m.at( i + t_row_offset,  i + t_col_offset) += tmp_i;
-    t_m.at( j + t_row_offset,  j + t_col_offset) += tmp_j;
-    }
-  
-  if(i < t_n_elem)
-    {
-    t_m.at( i + t_row_offset,  i + t_col_offset) += x_mem[i];
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-diagview<eT>::operator-=(const Base<eT,T1>& o)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1> tmp(o.get_ref());
-  const Mat<eT>& x = tmp.M;
-  
-  diagview<eT>& t = *this;
-  
-  arma_debug_check
-    (
-    ( (t.n_elem != x.n_elem) || (x.is_vec() == false) ),
-    "diagview: given object has incompatible size"
-    );
-  
-  Mat<eT>& t_m = *(t.m_ptr);
-  
-  const uword t_n_elem     = t.n_elem;
-  const uword t_row_offset = t.row_offset;
-  const uword t_col_offset = t.col_offset;
-  
-  const eT* x_mem = x.memptr();
-  
-  uword i,j;
-  for(i=0, j=1; j < t_n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = x_mem[i];
-    const eT tmp_j = x_mem[j];
-    
-    t_m.at( i + t_row_offset,  i + t_col_offset) -= tmp_i;
-    t_m.at( j + t_row_offset,  j + t_col_offset) -= tmp_j;
-    }
-  
-  if(i < t_n_elem)
-    {
-    t_m.at( i + t_row_offset,  i + t_col_offset) -= x_mem[i];
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-diagview<eT>::operator%=(const Base<eT,T1>& o)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1> tmp(o.get_ref());
-  const Mat<eT>& x = tmp.M;
-  
-  diagview<eT>& t = *this;
-  
-  arma_debug_check
-    (
-    ( (t.n_elem != x.n_elem) || (x.is_vec() == false) ),
-    "diagview: given object has incompatible size"
-    );
-  
-  Mat<eT>& t_m = *(t.m_ptr);
-  
-  const uword t_n_elem     = t.n_elem;
-  const uword t_row_offset = t.row_offset;
-  const uword t_col_offset = t.col_offset;
-  
-  const eT* x_mem = x.memptr();
-  
-  uword i,j;
-  for(i=0, j=1; j < t_n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = x_mem[i];
-    const eT tmp_j = x_mem[j];
-    
-    t_m.at( i + t_row_offset,  i + t_col_offset) *= tmp_i;
-    t_m.at( j + t_row_offset,  j + t_col_offset) *= tmp_j;
-    }
-  
-  if(i < t_n_elem)
-    {
-    t_m.at( i + t_row_offset,  i + t_col_offset) *= x_mem[i];
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-diagview<eT>::operator/=(const Base<eT,T1>& o)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1> tmp(o.get_ref());
-  const Mat<eT>& x = tmp.M;
-  
-  diagview<eT>& t = *this;
-  
-  arma_debug_check
-    (
-    ( (t.n_elem != x.n_elem) || (x.is_vec() == false) ),
-    "diagview: given object has incompatible size"
-    );
-  
-  Mat<eT>& t_m = *(t.m_ptr);
-  
-  const uword t_n_elem     = t.n_elem;
-  const uword t_row_offset = t.row_offset;
-  const uword t_col_offset = t.col_offset;
-  
-  const eT* x_mem = x.memptr();
-  
-  uword i,j;
-  for(i=0, j=1; j < t_n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = x_mem[i];
-    const eT tmp_j = x_mem[j];
-    
-    t_m.at( i + t_row_offset,  i + t_col_offset) /= tmp_i;
-    t_m.at( j + t_row_offset,  j + t_col_offset) /= tmp_j;
-    }
-  
-  if(i < t_n_elem)
-    {
-    t_m.at( i + t_row_offset,  i + t_col_offset) /= x_mem[i];
-    }
-  }
-
-
-
-//! extract a diagonal and store it as a column vector
-template<typename eT>
-inline
-void
-diagview<eT>::extract(Mat<eT>& out, const diagview<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing;
-  // size setting and alias checking is done by either the Mat contructor or operator=()
-  
-  const Mat<eT>& in_m = in.m;
-  
-  const uword in_n_elem     = in.n_elem;
-  const uword in_row_offset = in.row_offset;
-  const uword in_col_offset = in.col_offset;
-  
-  eT* out_mem = out.memptr();
-  
-  uword i,j;
-  for(i=0, j=1; j < in_n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset );
-    const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset );
-    
-    out_mem[i] = tmp_i;
-    out_mem[j] = tmp_j;
-    }
-  
-  if(i < in_n_elem)
-    {
-    out_mem[i] = in_m.at( i + in_row_offset, i + in_col_offset );
-    }
-  }
-
-
-
-//! X += Y.diag()
-template<typename eT>
-inline
-void
-diagview<eT>::plus_inplace(Mat<eT>& out, const diagview<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, in.n_rows, in.n_cols, "addition");
-  
-  const Mat<eT>& in_m = in.m;
-  
-  const uword in_n_elem     = in.n_elem;
-  const uword in_row_offset = in.row_offset;
-  const uword in_col_offset = in.col_offset;
-  
-  eT* out_mem = out.memptr();
-  
-  uword i,j;
-  for(i=0, j=1; j < in_n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset );
-    const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset );
-    
-    out_mem[i] += tmp_i;
-    out_mem[j] += tmp_j;
-    }
-  
-  if(i < in_n_elem)
-    {
-    out_mem[i] += in_m.at( i + in_row_offset, i + in_col_offset );
-    }
-  }
-
-
-
-//! X -= Y.diag()
-template<typename eT>
-inline
-void
-diagview<eT>::minus_inplace(Mat<eT>& out, const diagview<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, in.n_rows, in.n_cols, "subtraction");
-  
-  const Mat<eT>& in_m = in.m;
-  
-  const uword in_n_elem     = in.n_elem;
-  const uword in_row_offset = in.row_offset;
-  const uword in_col_offset = in.col_offset;
-  
-  eT* out_mem = out.memptr();
-  
-  uword i,j;
-  for(i=0, j=1; j < in_n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset );
-    const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset );
-    
-    out_mem[i] -= tmp_i;
-    out_mem[j] -= tmp_j;
-    }
-  
-  if(i < in_n_elem)
-    {
-    out_mem[i] -= in_m.at( i + in_row_offset, i + in_col_offset );
-    }
-  }
-
-
-
-//! X %= Y.diag()
-template<typename eT>
-inline
-void
-diagview<eT>::schur_inplace(Mat<eT>& out, const diagview<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, in.n_rows, in.n_cols, "element-wise multiplication");
-  
-  const Mat<eT>& in_m = in.m;
-  
-  const uword in_n_elem     = in.n_elem;
-  const uword in_row_offset = in.row_offset;
-  const uword in_col_offset = in.col_offset;
-  
-  eT* out_mem = out.memptr();
-  
-  uword i,j;
-  for(i=0, j=1; j < in_n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset );
-    const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset );
-    
-    out_mem[i] *= tmp_i;
-    out_mem[j] *= tmp_j;
-    }
-  
-  if(i < in_n_elem)
-    {
-    out_mem[i] *= in_m.at( i + in_row_offset, i + in_col_offset );
-    }
-  }
-
-
-
-//! X /= Y.diag()
-template<typename eT>
-inline
-void
-diagview<eT>::div_inplace(Mat<eT>& out, const diagview<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, in.n_rows, in.n_cols, "element-wise division");
-  
-  const Mat<eT>& in_m = in.m;
-  
-  const uword in_n_elem     = in.n_elem;
-  const uword in_row_offset = in.row_offset;
-  const uword in_col_offset = in.col_offset;
-  
-  eT* out_mem = out.memptr();
-  
-  uword i,j;
-  for(i=0, j=1; j < in_n_elem; i+=2, j+=2)
-    {
-    const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset );
-    const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset );
-    
-    out_mem[i] /= tmp_i;
-    out_mem[j] /= tmp_j;
-    }
-  
-  if(i < in_n_elem)
-    {
-    out_mem[i] /= in_m.at( i + in_row_offset, i + in_col_offset );
-    }
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT&
-diagview<eT>::operator[](const uword i)
-  {
-  return (*m_ptr).at(i+row_offset, i+col_offset);
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT
-diagview<eT>::operator[](const uword i) const
-  {
-  return m.at(i+row_offset, i+col_offset);
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT&
-diagview<eT>::at(const uword i)
-  {
-  return (*m_ptr).at(i+row_offset, i+col_offset);
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT
-diagview<eT>::at(const uword i) const
-  {
-  return m.at(i+row_offset, i+col_offset);
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT&
-diagview<eT>::operator()(const uword i)
-  {
-  arma_debug_check( (i >= n_elem), "diagview::operator(): out of bounds" );
-  
-  return (*m_ptr).at(i+row_offset, i+col_offset);
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT
-diagview<eT>::operator()(const uword i) const
-  {
-  arma_debug_check( (i >= n_elem), "diagview::operator(): out of bounds" );
-  
-  return m.at(i+row_offset, i+col_offset);
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT&
-diagview<eT>::at(const uword row, const uword col)
-  {
-  return (*m_ptr).at(row+row_offset, row+col_offset);
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT
-diagview<eT>::at(const uword row, const uword col) const
-  {
-  return m.at(row+row_offset, row+col_offset);
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT&
-diagview<eT>::operator()(const uword row, const uword col)
-  {
-  arma_debug_check( ((row >= n_elem) || (col > 0)), "diagview::operator(): out of bounds" );
-  
-  return (*m_ptr).at(row+row_offset, row+col_offset);
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT
-diagview<eT>::operator()(const uword row, const uword col) const
-  {
-  arma_debug_check( ((row >= n_elem) || (col > 0)), "diagview::operator(): out of bounds" );
-  
-  return m.at(row+row_offset, row+col_offset);
-  }
-
-
-
-template<typename eT>
-inline
-void
-diagview<eT>::fill(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>& x = (*m_ptr);
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    x.at(i+row_offset, i+col_offset) = val;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-diagview<eT>::zeros()
-  {
-  arma_extra_debug_sigprint();
-  
-  (*this).fill(eT(0));
-  }
-
-
-
-template<typename eT>
-inline
-void
-diagview<eT>::ones()
-  {
-  arma_extra_debug_sigprint();
-  
-  (*this).fill(eT(1));
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/diskio_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Ian Cullinan
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup diskio
-//! @{
-
-
-//! class for saving and loading matrices and fields
-class diskio
-  {
-  public:
-  
-  template<typename eT> inline static std::string gen_txt_header(const Mat<eT>& x);
-  template<typename eT> inline static std::string gen_bin_header(const Mat<eT>& x);
-  
-  template<typename eT> inline static std::string gen_txt_header(const Cube<eT>& x);
-  template<typename eT> inline static std::string gen_bin_header(const Cube<eT>& x);
-  
-  inline static file_type guess_file_type(std::istream& f);
-  
-  inline static char conv_to_hex_char(const u8 x);
-  inline static void conv_to_hex(char* out, const u8 x);
-  
-  inline static std::string gen_tmp_name(const std::string& x);
-  
-  inline static bool safe_rename(const std::string& old_name, const std::string& new_name);
-  
-  
-  //
-  // matrix saving
-  
-  template<typename eT> inline static bool save_raw_ascii  (const Mat<eT>&                x, const std::string& final_name);
-  template<typename eT> inline static bool save_raw_binary (const Mat<eT>&                x, const std::string& final_name);
-  template<typename eT> inline static bool save_arma_ascii (const Mat<eT>&                x, const std::string& final_name);
-  template<typename eT> inline static bool save_csv_ascii  (const Mat<eT>&                x, const std::string& final_name);
-  template<typename eT> inline static bool save_arma_binary(const Mat<eT>&                x, const std::string& final_name);
-  template<typename eT> inline static bool save_pgm_binary (const Mat<eT>&                x, const std::string& final_name);
-  template<typename  T> inline static bool save_pgm_binary (const Mat< std::complex<T> >& x, const std::string& final_name);
-  
-  template<typename eT> inline static bool save_raw_ascii  (const Mat<eT>&                x, std::ostream& f);
-  template<typename eT> inline static bool save_raw_binary (const Mat<eT>&                x, std::ostream& f);
-  template<typename eT> inline static bool save_arma_ascii (const Mat<eT>&                x, std::ostream& f);
-  template<typename eT> inline static bool save_csv_ascii  (const Mat<eT>&                x, std::ostream& f);
-  template<typename eT> inline static bool save_arma_binary(const Mat<eT>&                x, std::ostream& f);
-  template<typename eT> inline static bool save_pgm_binary (const Mat<eT>&                x, std::ostream& f);
-  template<typename  T> inline static bool save_pgm_binary (const Mat< std::complex<T> >& x, std::ostream& f);
-  
-  
-  //
-  // matrix loading
-  
-  template<typename eT> inline static bool load_raw_ascii  (Mat<eT>&                x, const std::string& name, std::string& err_msg);
-  template<typename eT> inline static bool load_raw_binary (Mat<eT>&                x, const std::string& name, std::string& err_msg);
-  template<typename eT> inline static bool load_arma_ascii (Mat<eT>&                x, const std::string& name, std::string& err_msg);
-  template<typename eT> inline static bool load_csv_ascii  (Mat<eT>&                x, const std::string& name, std::string& err_msg);
-  template<typename eT> inline static bool load_arma_binary(Mat<eT>&                x, const std::string& name, std::string& err_msg);
-  template<typename eT> inline static bool load_pgm_binary (Mat<eT>&                x, const std::string& name, std::string& err_msg);
-  template<typename  T> inline static bool load_pgm_binary (Mat< std::complex<T> >& x, const std::string& name, std::string& err_msg);
-  template<typename eT> inline static bool load_auto_detect(Mat<eT>&                x, const std::string& name, std::string& err_msg);
-  
-  template<typename eT> inline static bool load_raw_ascii  (Mat<eT>&                x, std::istream& f,  std::string& err_msg);
-  template<typename eT> inline static bool load_raw_binary (Mat<eT>&                x, std::istream& f,  std::string& err_msg);
-  template<typename eT> inline static bool load_arma_ascii (Mat<eT>&                x, std::istream& f,  std::string& err_msg);
-  template<typename eT> inline static bool load_csv_ascii  (Mat<eT>&                x, std::istream& f,  std::string& err_msg);
-  template<typename eT> inline static bool load_arma_binary(Mat<eT>&                x, std::istream& f,  std::string& err_msg);
-  template<typename eT> inline static bool load_pgm_binary (Mat<eT>&                x, std::istream& is, std::string& err_msg);
-  template<typename  T> inline static bool load_pgm_binary (Mat< std::complex<T> >& x, std::istream& is, std::string& err_msg);
-  template<typename eT> inline static bool load_auto_detect(Mat<eT>&                x, std::istream& f,  std::string& err_msg);
-  
-  inline static void pnm_skip_comments(std::istream& f);
-  
-  
-  //
-  // cube saving
-  
-  template<typename eT> inline static bool save_raw_ascii  (const Cube<eT>& x, const std::string& name);
-  template<typename eT> inline static bool save_raw_binary (const Cube<eT>& x, const std::string& name);
-  template<typename eT> inline static bool save_arma_ascii (const Cube<eT>& x, const std::string& name);
-  template<typename eT> inline static bool save_arma_binary(const Cube<eT>& x, const std::string& name);
-  
-  template<typename eT> inline static bool save_raw_ascii  (const Cube<eT>& x, std::ostream& f);
-  template<typename eT> inline static bool save_raw_binary (const Cube<eT>& x, std::ostream& f);
-  template<typename eT> inline static bool save_arma_ascii (const Cube<eT>& x, std::ostream& f);
-  template<typename eT> inline static bool save_arma_binary(const Cube<eT>& x, std::ostream& f);
-  
-  
-  //
-  // cube loading
-  
-  template<typename eT> inline static bool load_raw_ascii  (Cube<eT>& x, const std::string& name, std::string& err_msg);
-  template<typename eT> inline static bool load_raw_binary (Cube<eT>& x, const std::string& name, std::string& err_msg);
-  template<typename eT> inline static bool load_arma_ascii (Cube<eT>& x, const std::string& name, std::string& err_msg);
-  template<typename eT> inline static bool load_arma_binary(Cube<eT>& x, const std::string& name, std::string& err_msg);
-  template<typename eT> inline static bool load_auto_detect(Cube<eT>& x, const std::string& name, std::string& err_msg);
-  
-  template<typename eT> inline static bool load_raw_ascii  (Cube<eT>& x, std::istream& f, std::string& err_msg);
-  template<typename eT> inline static bool load_raw_binary (Cube<eT>& x, std::istream& f, std::string& err_msg);
-  template<typename eT> inline static bool load_arma_ascii (Cube<eT>& x, std::istream& f, std::string& err_msg);
-  template<typename eT> inline static bool load_arma_binary(Cube<eT>& x, std::istream& f, std::string& err_msg);
-  template<typename eT> inline static bool load_auto_detect(Cube<eT>& x, std::istream& f, std::string& err_msg);
-  
-  
-  //
-  // field saving and loading
-  
-  template<typename T1> inline static bool save_arma_binary(const field<T1>& x, const std::string&  name);
-  template<typename T1> inline static bool save_arma_binary(const field<T1>& x,       std::ostream& f);
-  
-  template<typename T1> inline static bool load_arma_binary(      field<T1>& x, const std::string&  name, std::string& err_msg);
-  template<typename T1> inline static bool load_arma_binary(      field<T1>& x,       std::istream& f,    std::string& err_msg);
-  
-  template<typename T1> inline static bool load_auto_detect(      field<T1>& x, const std::string&  name, std::string& err_msg);
-  template<typename T1> inline static bool load_auto_detect(      field<T1>& x,       std::istream& f,    std::string& err_msg);
-  
-  inline static bool save_std_string(const field<std::string>& x, const std::string&  name);
-  inline static bool save_std_string(const field<std::string>& x,       std::ostream& f);
-  
-  inline static bool load_std_string(      field<std::string>& x, const std::string&  name, std::string& err_msg);
-  inline static bool load_std_string(      field<std::string>& x,       std::istream& f,    std::string& err_msg);
-  
-
-
-  //
-  // handling of PPM images by cubes
-
-  template<typename T1> inline static bool save_ppm_binary(const Cube<T1>& x, const std::string&  final_name);
-  template<typename T1> inline static bool save_ppm_binary(const Cube<T1>& x,       std::ostream& f);
-  
-  template<typename T1> inline static bool load_ppm_binary(      Cube<T1>& x, const std::string&  final_name, std::string& err_msg);
-  template<typename T1> inline static bool load_ppm_binary(      Cube<T1>& x,       std::istream& f,          std::string& err_msg);
-
-
-  //
-  // handling of PPM images by fields
-
-  template<typename T1> inline static bool save_ppm_binary(const field<T1>& x, const std::string&  final_name);
-  template<typename T1> inline static bool save_ppm_binary(const field<T1>& x,       std::ostream& f);
-  
-  template<typename T1> inline static bool load_ppm_binary(      field<T1>& x, const std::string&  final_name, std::string& err_msg);
-  template<typename T1> inline static bool load_ppm_binary(      field<T1>& x,       std::istream& f,          std::string& err_msg);
-  
-
-
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/diskio_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3118 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Ian Cullinan
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup diskio
-//! @{
-
-
-//! Generate the first line of the header used for saving matrices in text format.
-//! Format: "ARMA_MAT_TXT_ABXYZ".
-//! A is one of: I (for integral types) or F (for floating point types).
-//! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
-//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
-template<typename eT>
-inline
-std::string
-diskio::gen_txt_header(const Mat<eT>& x)
-  {
-  arma_type_check(( is_supported_elem_type<eT>::value == false ));
-
-  arma_ignore(x);
-  
-  if(is_u8<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_TXT_IU001");
-    }
-  else
-  if(is_s8<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_TXT_IS001");
-    }
-  else
-  if(is_u16<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_TXT_IU002");
-    }
-  else
-  if(is_s16<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_TXT_IS002");
-    }
-  else
-  if(is_u32<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_TXT_IU004");
-    }
-  else
-  if(is_s32<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_TXT_IS004");
-    }
-#if defined(ARMA_64BIT_WORD)
-  else
-  if(is_u64<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_TXT_IU008");
-    }
-  else
-  if(is_s64<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_TXT_IS008");
-    }
-#endif
-  else
-  if(is_float<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_TXT_FN004");
-    }
-  else
-  if(is_double<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_TXT_FN008");
-    }
-  else
-  if(is_complex_float<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_TXT_FC008");
-    }
-  else
-  if(is_complex_double<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_TXT_FC016");
-    }
-  else
-    {
-    return std::string();
-    }
-  
-  }
-
-
-
-//! Generate the first line of the header used for saving matrices in binary format.
-//! Format: "ARMA_MAT_BIN_ABXYZ".
-//! A is one of: I (for integral types) or F (for floating point types).
-//! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
-//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
-template<typename eT>
-inline
-std::string
-diskio::gen_bin_header(const Mat<eT>& x)
-  {
-  arma_type_check(( is_supported_elem_type<eT>::value == false ));
-  
-  arma_ignore(x);
-  
-  if(is_u8<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_BIN_IU001");
-    }
-  else
-  if(is_s8<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_BIN_IS001");
-    }
-  else
-  if(is_u16<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_BIN_IU002");
-    }
-  else
-  if(is_s16<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_BIN_IS002");
-    }
-  else
-  if(is_u32<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_BIN_IU004");
-    }
-  else
-  if(is_s32<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_BIN_IS004");
-    }
-#if defined(ARMA_64BIT_WORD)
-  else
-  if(is_u64<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_BIN_IU008");
-    }
-  else
-  if(is_s64<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_BIN_IS008");
-    }
-#endif
-  else
-  if(is_float<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_BIN_FN004");
-    }
-  else
-  if(is_double<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_BIN_FN008");
-    }
-  else
-  if(is_complex_float<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_BIN_FC008");
-    }
-  else
-  if(is_complex_double<eT>::value == true)
-    {
-    return std::string("ARMA_MAT_BIN_FC016");
-    }
-  else
-    {
-    return std::string();
-    }
-  
-  }
-
-
-
-//! Generate the first line of the header used for saving cubes in text format.
-//! Format: "ARMA_CUB_TXT_ABXYZ".
-//! A is one of: I (for integral types) or F (for floating point types).
-//! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
-//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
-template<typename eT>
-inline
-std::string
-diskio::gen_txt_header(const Cube<eT>& x)
-  {
-  arma_type_check(( is_supported_elem_type<eT>::value == false ));
-  
-  arma_ignore(x);
-
-  if(is_u8<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_TXT_IU001");
-    }
-  else
-  if(is_s8<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_TXT_IS001");
-    }
-  else
-  if(is_u16<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_TXT_IU002");
-    }
-  else
-  if(is_s16<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_TXT_IS002");
-    }
-  else
-  if(is_u32<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_TXT_IU004");
-    }
-  else
-  if(is_s32<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_TXT_IS004");
-    }
-#if defined(ARMA_64BIT_WORD)
-  else
-  if(is_u64<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_TXT_IU008");
-    }
-  else
-  if(is_s64<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_TXT_IS008");
-    }
-#endif
-  else
-  if(is_float<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_TXT_FN004");
-    }
-  else
-  if(is_double<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_TXT_FN008");
-    }
-  else
-  if(is_complex_float<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_TXT_FC008");
-    }
-  else
-  if(is_complex_double<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_TXT_FC016");
-    }
-  else
-    {
-    return std::string();
-    }
-  
-  }
-
-
-
-//! Generate the first line of the header used for saving cubes in binary format.
-//! Format: "ARMA_CUB_BIN_ABXYZ".
-//! A is one of: I (for integral types) or F (for floating point types).
-//! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
-//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
-template<typename eT>
-inline
-std::string
-diskio::gen_bin_header(const Cube<eT>& x)
-  {
-  arma_type_check(( is_supported_elem_type<eT>::value == false ));
-  
-  arma_ignore(x);
-  
-  if(is_u8<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_BIN_IU001");
-    }
-  else
-  if(is_s8<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_BIN_IS001");
-    }
-  else
-  if(is_u16<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_BIN_IU002");
-    }
-  else
-  if(is_s16<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_BIN_IS002");
-    }
-  else
-  if(is_u32<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_BIN_IU004");
-    }
-  else
-  if(is_s32<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_BIN_IS004");
-    }
-#if defined(ARMA_64BIT_WORD)
-  else
-  if(is_u64<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_BIN_IU008");
-    }
-  else
-  if(is_s64<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_BIN_IS008");
-    }
-#endif
-  else
-  if(is_float<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_BIN_FN004");
-    }
-  else
-  if(is_double<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_BIN_FN008");
-    }
-  else
-  if(is_complex_float<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_BIN_FC008");
-    }
-  else
-  if(is_complex_double<eT>::value == true)
-    {
-    return std::string("ARMA_CUB_BIN_FC016");
-    }
-  else
-    {
-    return std::string();
-    }
-  
-  }
-
-
-
-inline
-file_type
-diskio::guess_file_type(std::istream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  f.clear();
-  const std::fstream::pos_type pos1 = f.tellg();
-  
-  f.clear();
-  f.seekg(0, ios::end);
-  
-  f.clear();
-  const std::fstream::pos_type pos2 = f.tellg();
-  
-  const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
-  
-  f.clear();
-  f.seekg(pos1);
-  
-  podarray<unsigned char> data(N);
-  
-  unsigned char* ptr = data.memptr();
-  
-  f.clear();
-  f.read( reinterpret_cast<char*>(ptr), std::streamsize(N) );
-  
-  const bool load_okay = f.good();
-  
-  f.clear();
-  f.seekg(pos1);
-  
-  bool has_binary = false;
-  bool has_comma  = false;
-  
-  if(load_okay == true)
-    {
-    uword i = 0;
-    uword j = (N >= 2) ? 1 : 0;
-    
-    for(; j<N; i+=2, j+=2)
-      {
-      const unsigned char val_i = ptr[i];
-      const unsigned char val_j = ptr[j];
-      
-      // the range checking can be made more elaborate
-      if( ((val_i <= 8) || (val_i >= 123)) || ((val_j <= 8) || (val_j >= 123)) )
-        {
-        has_binary = true;
-        break;
-        }
-      
-      if( (val_i == ',') || (val_j == ',') )
-        {
-        has_comma = true;
-        break;
-        }
-      }
-    }
-  else
-    {
-    return file_type_unknown;
-    }
-  
-  if(has_binary)
-    {
-    return raw_binary;
-    }
-  
-  if(has_comma)
-    {
-    return csv_ascii;
-    }
-  
-  return raw_ascii;
-  }
-
-
-
-inline
-char
-diskio::conv_to_hex_char(const u8 x)
-  {
-  char out;
-
-  switch(x)
-    {
-    case  0: out = '0'; break;
-    case  1: out = '1'; break;
-    case  2: out = '2'; break;
-    case  3: out = '3'; break;
-    case  4: out = '4'; break;
-    case  5: out = '5'; break;
-    case  6: out = '6'; break;
-    case  7: out = '7'; break;
-    case  8: out = '8'; break;
-    case  9: out = '9'; break;
-    case 10: out = 'a'; break;
-    case 11: out = 'b'; break;
-    case 12: out = 'c'; break;
-    case 13: out = 'd'; break;
-    case 14: out = 'e'; break;
-    case 15: out = 'f'; break;
-    default: out = '-'; break;
-    }
-
-  return out;  
-  }
-
-
-
-inline
-void
-diskio::conv_to_hex(char* out, const u8 x)
-  {
-  const u8 a = x / 16;
-  const u8 b = x - 16*a;
-
-  out[0] = conv_to_hex_char(a);
-  out[1] = conv_to_hex_char(b);
-  }
-
-
-
-//! Append a quasi-random string to the given filename.
-//! The rand() function is deliberately not used,
-//! as rand() has an internal state that changes
-//! from call to call. Such states should not be
-//! modified in scientific applications, where the
-//! results should be reproducable and not affected 
-//! by saving data.
-inline
-std::string
-diskio::gen_tmp_name(const std::string& x)
-  {
-  const std::string* ptr_x     = &x;
-  const u8*          ptr_ptr_x = reinterpret_cast<const u8*>(&ptr_x);
-  
-  const char* extra      = ".tmp_";
-  const uword extra_size = 5;
-  
-  const uword tmp_size   = 2*sizeof(u8*) + 2*2;
-        char  tmp[tmp_size];
-  
-  uword char_count = 0;
-  
-  for(uword i=0; i<sizeof(u8*); ++i)
-    {
-    conv_to_hex(&tmp[char_count], ptr_ptr_x[i]);
-    char_count += 2;
-    }
-  
-  const uword x_size = static_cast<uword>(x.size());
-  u8 sum = 0;
-  
-  for(uword i=0; i<x_size; ++i)
-    {
-    sum += u8(x[i]);
-    }
-  
-  conv_to_hex(&tmp[char_count], sum);
-  char_count += 2;
-  
-  conv_to_hex(&tmp[char_count], u8(x_size));
-  
-  
-  std::string out;
-  out.resize(x_size + extra_size + tmp_size);
-  
-  
-  for(uword i=0; i<x_size; ++i)
-    {
-    out[i] = x[i];
-    }
-  
-  for(uword i=0; i<extra_size; ++i)
-    {
-    out[x_size + i] = extra[i];
-    }
-  
-  for(uword i=0; i<tmp_size; ++i)
-    {
-    out[x_size + extra_size + i] = tmp[i];
-    }
-  
-  return out;
-  }
-
-
-
-//! Safely rename a file.
-//! Before renaming, test if we can write to the final file.
-//! This should prevent:
-//! (i)  overwriting files that are write protected,
-//! (ii) overwriting directories.
-inline
-bool
-diskio::safe_rename(const std::string& old_name, const std::string& new_name)
-  {
-  std::fstream f(new_name.c_str(), std::fstream::out | std::fstream::app);
-  f.put(' ');
-  
-  bool save_okay = f.good();
-  f.close();
-  
-  if(save_okay == true)
-    {
-    std::remove(new_name.c_str());
-    
-    const int mv_result = std::rename(old_name.c_str(), new_name.c_str());
-    
-    save_okay = (mv_result == 0);
-    }
-  
-  return save_okay;
-  }
-
-
-
-//! Save a matrix as raw text (no header, human readable).
-//! Matrices can be loaded in Matlab and Octave, as long as they don't have complex elements.
-template<typename eT>
-inline
-bool
-diskio::save_raw_ascii(const Mat<eT>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  
-  std::fstream f(tmp_name.c_str(), std::fstream::out);
-  
-  bool save_okay = f.is_open();
-  
-  if(save_okay == true)
-    {
-    save_okay = diskio::save_raw_ascii(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-//! Save a matrix as raw text (no header, human readable).
-//! Matrices can be loaded in Matlab and Octave, as long as they don't have complex elements.
-template<typename eT>
-inline
-bool
-diskio::save_raw_ascii(const Mat<eT>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  uword cell_width;
-  
-  // TODO: need sane values for complex numbers
-  
-  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
-    {
-    f.setf(ios::scientific);
-    f.precision(10);
-    cell_width = 18;
-    }
-  
-  for(uword row=0; row < x.n_rows; ++row)
-    {
-    for(uword col=0; col < x.n_cols; ++col)
-      {
-      f.put(' ');
-      
-      if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
-        {
-        f.width(cell_width);
-        }
-      
-      f << x.at(row,col);
-      }
-      
-    f.put('\n');
-    }
-  
-  return f.good();
-  }
-
-
-
-//! Save a matrix as raw binary (no header)
-template<typename eT>
-inline
-bool
-diskio::save_raw_binary(const Mat<eT>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  
-  std::ofstream f(tmp_name.c_str(), std::fstream::binary);
-  
-  bool save_okay = f.is_open();
-  
-  if(save_okay == true)
-    {
-    save_okay = diskio::save_raw_binary(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-diskio::save_raw_binary(const Mat<eT>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
-  
-  return f.good();
-  }
-
-
-
-//! Save a matrix in text format (human readable),
-//! with a header that indicates the matrix type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::save_arma_ascii(const Mat<eT>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  
-  std::ofstream f(tmp_name.c_str());
-  
-  bool save_okay = f.is_open();
-
-  if(save_okay == true)  
-    {
-    save_okay = diskio::save_arma_ascii(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-//! Save a matrix in text format (human readable),
-//! with a header that indicates the matrix type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::save_arma_ascii(const Mat<eT>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  const ios::fmtflags orig_flags = f.flags();
-  
-  f << diskio::gen_txt_header(x) << '\n';
-  f << x.n_rows << ' ' << x.n_cols << '\n';
-  
-  uword cell_width;
-  
-  // TODO: need sane values for complex numbers
-  
-  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
-    {
-    f.setf(ios::scientific);
-    f.precision(10);
-    cell_width = 18;
-    }
-    
-  for(uword row=0; row < x.n_rows; ++row)
-    {
-    for(uword col=0; col < x.n_cols; ++col)
-      {
-      f.put(' ');
-      
-      if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )        
-        {
-        f.width(cell_width);
-        }
-      
-      f << x.at(row,col);
-      }
-    
-    f.put('\n');
-    }
-  
-  const bool save_okay = f.good();
-  
-  f.flags(orig_flags);
-  
-  return save_okay;
-  }
-
-
-
-//! Save a matrix in CSV text format (human readable)
-template<typename eT>
-inline
-bool
-diskio::save_csv_ascii(const Mat<eT>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  
-  std::ofstream f(tmp_name.c_str());
-  
-  bool save_okay = f.is_open();
-  
-  if(save_okay == true)  
-    {
-    save_okay = diskio::save_csv_ascii(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-//! Save a matrix in CSV text format (human readable)
-template<typename eT>
-inline
-bool
-diskio::save_csv_ascii(const Mat<eT>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  const ios::fmtflags orig_flags = f.flags();
-  
-  // TODO: need sane values for complex numbers
-  
-  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
-    {
-    f.setf(ios::scientific);
-    f.precision(10);
-    }
-  
-  uword x_n_rows = x.n_rows;
-  uword x_n_cols = x.n_cols;
-  
-  for(uword row=0; row < x_n_rows; ++row)
-    {
-    for(uword col=0; col < x_n_cols; ++col)
-      {
-      f << x.at(row,col);
-      
-      if( col < (x_n_cols-1) )
-        {
-        f.put(',');
-        }
-      }
-    
-    f.put('\n');
-    }
-  
-  const bool save_okay = f.good();
-  
-  f.flags(orig_flags);
-  
-  return save_okay;
-  }
-
-
-
-//! Save a matrix in binary format,
-//! with a header that stores the matrix type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::save_arma_binary(const Mat<eT>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  
-  std::ofstream f(tmp_name.c_str(), std::fstream::binary);
-  
-  bool save_okay = f.is_open();
-  
-  if(save_okay == true)
-    {
-    save_okay = diskio::save_arma_binary(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-//! Save a matrix in binary format,
-//! with a header that stores the matrix type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::save_arma_binary(const Mat<eT>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-
-  f << diskio::gen_bin_header(x) << '\n';
-  f << x.n_rows << ' ' << x.n_cols << '\n';
-  
-  f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
-  
-  return f.good();
-  }
-
-
-
-//! Save a matrix as a PGM greyscale image
-template<typename eT>
-inline
-bool
-diskio::save_pgm_binary(const Mat<eT>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  
-  std::fstream f(tmp_name.c_str(), std::fstream::out | std::fstream::binary);
-  
-  bool save_okay = f.is_open();
-  
-  if(save_okay == true)
-    {
-    save_okay = diskio::save_pgm_binary(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-//
-// TODO:
-// add functionality to save the image in a normalised format,
-// i.e. scaled so that every value falls in the [0,255] range.
-
-//! Save a matrix as a PGM greyscale image
-template<typename eT>
-inline
-bool
-diskio::save_pgm_binary(const Mat<eT>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  f << "P5" << '\n';
-  f << x.n_cols << ' ' << x.n_rows << '\n';
-  f << 255 << '\n';
-  
-  const uword n_elem = x.n_rows * x.n_cols;
-  podarray<u8> tmp(n_elem);
-  
-  uword i = 0;
-  
-  for(uword row=0; row < x.n_rows; ++row)
-    {
-    for(uword col=0; col < x.n_cols; ++col)
-      {
-      tmp[i] = u8( x.at(row,col) );  // TODO: add round() ?
-      ++i;
-      }
-    }
-  
-  f.write(reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
-  
-  return f.good();
-  }
-
-
-
-//! Save a matrix as a PGM greyscale image
-template<typename T>
-inline
-bool
-diskio::save_pgm_binary(const Mat< std::complex<T> >& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uchar_mat tmp = conv_to<uchar_mat>::from(x);
-  
-  return diskio::save_pgm_binary(tmp, final_name);
-  }
-
-
-
-//! Save a matrix as a PGM greyscale image
-template<typename T>
-inline
-bool
-diskio::save_pgm_binary(const Mat< std::complex<T> >& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uchar_mat tmp = conv_to<uchar_mat>::from(x);
-  
-  return diskio::save_pgm_binary(tmp, f);
-  }
-
-
-
-//! Load a matrix as raw text (no header, human readable).
-//! Can read matrices saved as text in Matlab and Octave.
-//! NOTE: this is much slower than reading a file with a header.
-template<typename eT>
-inline
-bool
-diskio::load_raw_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-
-  std::fstream f;
-  f.open(name.c_str(), std::fstream::in);
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_raw_ascii(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Load a matrix as raw text (no header, human readable).
-//! Can read matrices saved as text in Matlab and Octave.
-//! NOTE: this is much slower than reading a file with a header.
-template<typename eT>
-inline
-bool
-diskio::load_raw_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool load_okay = f.good();
-  
-  f.clear();
-  const std::fstream::pos_type pos1 = f.tellg();
-  
-  //
-  // work out the size
-  
-  uword f_n_rows = 0;
-  uword f_n_cols = 0;
-  
-  bool f_n_cols_found = false;
-  
-  std::string line_string;
-  std::string token;
-  
-  while( (f.good() == true) && (load_okay == true) )
-    {
-    std::getline(f, line_string);
-    
-    if(line_string.size() == 0)
-      {
-      break;
-      }
-    
-    std::stringstream line_stream(line_string);
-    
-    uword line_n_cols = 0;
-    
-    while (line_stream >> token)
-      {
-      ++line_n_cols;
-      }
-    
-    if(f_n_cols_found == false)
-      {
-      f_n_cols = line_n_cols;
-      f_n_cols_found = true;
-      }
-    else
-      {
-      if(line_n_cols != f_n_cols)
-        {
-        err_msg = "inconsistent number of columns in ";
-        load_okay = false;
-        }
-      }
-    
-    ++f_n_rows;
-    }
-    
-  if(load_okay == true)
-    {
-    f.clear();
-    f.seekg(pos1);
-    
-    x.set_size(f_n_rows, f_n_cols);
-    
-    eT val;
-    
-    for(uword row=0; (row < x.n_rows) && (load_okay == true); ++row)
-      {
-      for(uword col=0; (col < x.n_cols) && (load_okay == true); ++col)
-        {
-        f >> val;
-        
-        if(f.fail() == false)
-          {
-          x.at(row,col) = val;
-          }
-        else
-          {
-          load_okay = false;
-          err_msg = "couldn't interpret data in ";
-          //break;
-          }
-        }
-      }
-    }
-  
-  
-  // an empty file indicates an empty matrix
-  if( (f_n_cols_found == false) && (load_okay == true) )
-    {
-    x.reset();
-    }
-  
-  
-  return load_okay;
-  }
-
-
-
-//! Load a matrix in binary format (no header);
-//! the matrix is assumed to have one column
-template<typename eT>
-inline
-bool
-diskio::load_raw_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::ifstream f;
-  f.open(name.c_str(), std::fstream::binary);
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_raw_binary(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-diskio::load_raw_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(err_msg);
-  
-  f.clear();
-  const std::streampos pos1 = f.tellg();
-  
-  f.clear();
-  f.seekg(0, ios::end);
-
-  f.clear();
-  const std::streampos pos2 = f.tellg();
-  
-  const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
-  
-  f.clear();
-  //f.seekg(0, ios::beg);
-  f.seekg(pos1);
-  
-  x.set_size(N / sizeof(eT), 1);
-  
-  f.clear();
-  f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(N) );
-  
-  return f.good();
-  }
-
-
-
-//! Load a matrix in text format (human readable),
-//! with a header that indicates the matrix type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::load_arma_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::ifstream f(name.c_str());
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_arma_ascii(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Load a matrix in text format (human readable),
-//! with a header that indicates the matrix type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::load_arma_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool load_okay = true;
-  
-  std::string f_header;
-  uword f_n_rows;
-  uword f_n_cols;
-  
-  f >> f_header;
-  f >> f_n_rows;
-  f >> f_n_cols;
-  
-  if(f_header == diskio::gen_txt_header(x))
-    {
-    x.set_size(f_n_rows, f_n_cols);
-    
-    for(uword row=0; row < x.n_rows; ++row)
-      {
-      for(uword col=0; col < x.n_cols; ++col)
-        {
-        f >> x.at(row,col);
-        }
-      }
-    
-    load_okay = f.good();
-    }
-  else
-    {
-    load_okay = false;
-    err_msg = "incorrect header in ";
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Load a matrix in CSV text format (human readable)
-template<typename eT>
-inline
-bool
-diskio::load_csv_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::fstream f;
-  f.open(name.c_str(), std::fstream::in);
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_csv_ascii(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Load a matrix in CSV text format (human readable)
-template<typename eT>
-inline
-bool
-diskio::load_csv_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool load_okay = f.good();
-  
-  f.clear();
-  const std::fstream::pos_type pos1 = f.tellg();
-  
-  //
-  // work out the size
-  
-  uword f_n_rows = 0;
-  uword f_n_cols = 0;
-  
-  std::string line_string;
-  std::string token;
-  
-  while( (f.good() == true) && (load_okay == true) )
-    {
-    std::getline(f, line_string);
-    
-    if(line_string.size() == 0)
-      {
-      break;
-      }
-    
-    std::stringstream line_stream(line_string);
-    
-    uword line_n_cols = 0;
-    
-    while(line_stream.good() == true)
-      {
-      getline(line_stream, token, ',');
-      ++line_n_cols;
-      }
-    
-    if(f_n_cols < line_n_cols)
-      {
-      f_n_cols = line_n_cols;
-      }
-    
-    ++f_n_rows;
-    }
-  
-  f.clear();
-  f.seekg(pos1);
-  
-  x.zeros(f_n_rows, f_n_cols);
-  
-  uword row = 0;
-  
-  while(f.good() == true)
-    {
-    std::getline(f, line_string);
-    
-    if(line_string.size() == 0)
-      {
-      break;
-      }
-    
-    std::stringstream line_stream(line_string);
-    
-    uword col = 0;
-    
-    while(line_stream.good() == true)
-      {
-      getline(line_stream, token, ',');
-      
-      eT val;
-      
-      std::stringstream ss(token);
-      
-      ss >> val;
-      
-      if(ss.fail() == false)
-        {
-        x.at(row,col) = val;
-        }
-      
-      ++col;
-      }
-    
-    ++row;
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Load a matrix in binary format,
-//! with a header that indicates the matrix type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::load_arma_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::ifstream f;
-  f.open(name.c_str(), std::fstream::binary);
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_arma_binary(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-diskio::load_arma_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool load_okay = true;
-  
-  std::string f_header;
-  uword f_n_rows;
-  uword f_n_cols;
-  
-  f >> f_header;
-  f >> f_n_rows;
-  f >> f_n_cols;
-  
-  if(f_header == diskio::gen_bin_header(x))
-    {
-    //f.seekg(1, ios::cur);  // NOTE: this may not be portable, as on a Windows machine a newline could be two characters
-    f.get();
-    
-    x.set_size(f_n_rows,f_n_cols);
-    f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(x.n_elem*sizeof(eT)) );
-    
-    load_okay = f.good();
-    }
-  else
-    {
-    load_okay = false;
-    err_msg = "incorrect header in ";
-    }
-  
-  return load_okay;
-  }
-
-
-
-inline
-void
-diskio::pnm_skip_comments(std::istream& f)
-  {
-  while( isspace(f.peek()) )
-    {
-    while( isspace(f.peek()) )
-      {
-      f.get();
-      }
-  
-    if(f.peek() == '#')
-      {
-      while( (f.peek() != '\r') && (f.peek()!='\n') )
-        {
-        f.get();
-        }
-      }
-    }
-  }
-
-
-
-//! Load a PGM greyscale image as a matrix
-template<typename eT>
-inline
-bool
-diskio::load_pgm_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::fstream f;
-  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_pgm_binary(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Load a PGM greyscale image as a matrix
-template<typename eT>
-inline
-bool
-diskio::load_pgm_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
-  {
-  bool load_okay = true;
-  
-  std::string f_header;
-  f >> f_header;
-  
-  if(f_header == "P5")
-    {
-    uword f_n_rows = 0;
-    uword f_n_cols = 0;
-    int f_maxval = 0;
-  
-    diskio::pnm_skip_comments(f);
-  
-    f >> f_n_cols;
-    diskio::pnm_skip_comments(f);
-  
-    f >> f_n_rows;
-    diskio::pnm_skip_comments(f);
-  
-    f >> f_maxval;
-    f.get();
-    
-    if( (f_maxval > 0) || (f_maxval <= 65535) )
-      {
-      x.set_size(f_n_rows,f_n_cols);
-      
-      if(f_maxval <= 255)
-        {
-        const uword n_elem = f_n_cols*f_n_rows;
-        podarray<u8> tmp(n_elem);
-        
-        f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
-        
-        uword i = 0;
-        
-        //cout << "f_n_cols = " << f_n_cols << endl;
-        //cout << "f_n_rows = " << f_n_rows << endl;
-        
-        
-        for(uword row=0; row < f_n_rows; ++row)
-          {
-          for(uword col=0; col < f_n_cols; ++col)
-            {
-            x.at(row,col) = eT(tmp[i]);
-            ++i;
-            }
-          }
-          
-        }
-      else
-        {
-        const uword n_elem = f_n_cols*f_n_rows;
-        podarray<u16> tmp(n_elem);
-        
-        f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(n_elem*2) );
-        
-        uword i = 0;
-        
-        for(uword row=0; row < f_n_rows; ++row)
-          {
-          for(uword col=0; col < f_n_cols; ++col)
-            {
-            x.at(row,col) = eT(tmp[i]);
-            ++i;
-            }
-          }
-        
-        }
-      
-      }
-    else
-      {
-      load_okay = false;
-      err_msg = "currently no code available to handle loading ";
-      }
-    
-    if(f.good() == false)
-      {
-      load_okay = false;
-      }
-    }
-  else
-    {
-    load_okay = false;
-    err_msg = "unsupported header in ";
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Load a PGM greyscale image as a matrix
-template<typename T>
-inline
-bool
-diskio::load_pgm_binary(Mat< std::complex<T> >& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  uchar_mat tmp;
-  const bool load_okay = diskio::load_pgm_binary(tmp, name, err_msg);
-  
-  x = conv_to< Mat< std::complex<T> > >::from(tmp);
-  
-  return load_okay;
-  }
-
-
-
-//! Load a PGM greyscale image as a matrix
-template<typename T>
-inline
-bool
-diskio::load_pgm_binary(Mat< std::complex<T> >& x, std::istream& is, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  uchar_mat tmp;
-  const bool load_okay = diskio::load_pgm_binary(tmp, is, err_msg);
-  
-  x = conv_to< Mat< std::complex<T> > >::from(tmp);
-  
-  return load_okay;
-  }
-
-
-
-//! Try to load a matrix by automatically determining its type
-template<typename eT>
-inline
-bool
-diskio::load_auto_detect(Mat<eT>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::fstream f;
-  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_auto_detect(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Try to load a matrix by automatically determining its type
-template<typename eT>
-inline
-bool
-diskio::load_auto_detect(Mat<eT>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  static const std::string ARMA_MAT_TXT = "ARMA_MAT_TXT";
-  static const std::string ARMA_MAT_BIN = "ARMA_MAT_BIN";
-  static const std::string           P5 = "P5";
-  
-  podarray<char> raw_header(ARMA_MAT_TXT.length() + 1);
-  
-  std::streampos pos = f.tellg();
-    
-  f.read( raw_header.memptr(), std::streamsize(ARMA_MAT_TXT.length()) );
-  raw_header[ARMA_MAT_TXT.length()] = '\0';
-  
-  f.clear();
-  f.seekg(pos);
-  
-  const std::string header = raw_header.mem;
-  
-  if(ARMA_MAT_TXT == header.substr(0,ARMA_MAT_TXT.length()))
-    {
-    return load_arma_ascii(x, f, err_msg);
-    }
-  else
-  if(ARMA_MAT_BIN == header.substr(0,ARMA_MAT_BIN.length()))
-    {
-    return load_arma_binary(x, f, err_msg);
-    }
-  else
-  if(P5 == header.substr(0,P5.length()))
-    {
-    return load_pgm_binary(x, f, err_msg);
-    }
-  else
-    {
-    const file_type ft = guess_file_type(f);
-    
-    switch(ft)
-      {
-      case csv_ascii:
-        return load_csv_ascii(x, f, err_msg);
-        break;
-      
-      case raw_binary:
-        return load_raw_binary(x, f, err_msg);
-        break;
-        
-      case raw_ascii:
-        return load_raw_ascii(x, f, err_msg);
-        break;
-      
-      default:
-        err_msg = "unknown data in ";
-        return false;
-      }
-    }
-  
-  return false;
-  }
-
-
-
-// cubes
-
-
-
-//! Save a cube as raw text (no header, human readable).
-template<typename eT>
-inline
-bool
-diskio::save_raw_ascii(const Cube<eT>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  
-  std::fstream f(tmp_name.c_str(), std::fstream::out);
-  
-  bool save_okay = f.is_open();
-  
-  if(save_okay == true)
-    {
-    save_okay = save_raw_ascii(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-//! Save a cube as raw text (no header, human readable).
-template<typename eT>
-inline
-bool
-diskio::save_raw_ascii(const Cube<eT>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  uword cell_width;
-  
-  // TODO: need sane values for complex numbers
-  
-  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
-    {
-    f.setf(ios::scientific);
-    f.precision(10);
-    cell_width = 18;
-    }
-  
-  for(uword slice=0; slice < x.n_slices; ++slice)
-    {
-    for(uword row=0; row < x.n_rows; ++row)
-      {
-      for(uword col=0; col < x.n_cols; ++col)
-        {
-        f.put(' ');
-        
-        if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
-          {
-          f.width(cell_width);
-          }
-        
-        f << x.at(row,col,slice);
-        }
-        
-      f.put('\n');
-      }
-    }
-  
-  return f.good();
-  }
-
-
-
-//! Save a cube as raw binary (no header)
-template<typename eT>
-inline
-bool
-diskio::save_raw_binary(const Cube<eT>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  
-  std::ofstream f(tmp_name.c_str(), std::fstream::binary);
-  
-  bool save_okay = f.is_open();
-  
-  if(save_okay == true)
-    {
-    save_okay = diskio::save_raw_binary(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-diskio::save_raw_binary(const Cube<eT>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
-  
-  return f.good();
-  }
-
-
-
-//! Save a cube in text format (human readable),
-//! with a header that indicates the cube type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::save_arma_ascii(const Cube<eT>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  
-  std::ofstream f(tmp_name.c_str());
-  
-  bool save_okay = f.is_open();
-  
-  if(save_okay == true)
-    {
-    save_okay = diskio::save_arma_ascii(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-//! Save a cube in text format (human readable),
-//! with a header that indicates the cube type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::save_arma_ascii(const Cube<eT>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  const ios::fmtflags orig_flags = f.flags();
-  
-  f << diskio::gen_txt_header(x) << '\n';
-  f << x.n_rows << ' ' << x.n_cols << ' ' << x.n_slices << '\n';
-  
-  uword cell_width;
-  
-  // TODO: need sane values for complex numbers
-  
-  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
-    {
-    f.setf(ios::scientific);
-    f.precision(10);
-    cell_width = 18;
-    }
-    
-  for(uword slice=0; slice < x.n_slices; ++slice)
-    {
-    for(uword row=0; row < x.n_rows; ++row)
-      {
-      for(uword col=0; col < x.n_cols; ++col)
-        {
-        f.put(' ');
-        
-        if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )        
-          {
-          f.width(cell_width);
-          }
-        
-        f << x.at(row,col,slice);
-        }
-      
-      f.put('\n');
-      }
-    }
-  
-  const bool save_okay = f.good();
-  
-  f.flags(orig_flags);
-  
-  return save_okay;
-  }
-
-
-
-//! Save a cube in binary format,
-//! with a header that stores the cube type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::save_arma_binary(const Cube<eT>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  
-  std::ofstream f(tmp_name.c_str(), std::fstream::binary);
-  
-  bool save_okay = f.is_open();
-  
-  if(save_okay == true)
-    {
-    save_okay = diskio::save_arma_binary(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-//! Save a cube in binary format,
-//! with a header that stores the cube type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::save_arma_binary(const Cube<eT>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  f << diskio::gen_bin_header(x) << '\n';
-  f << x.n_rows << ' ' << x.n_cols << ' ' << x.n_slices << '\n';
-  
-  f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
-  
-  return f.good();
-  }
-
-
-
-//! Load a cube as raw text (no header, human readable).
-//! NOTE: this is much slower than reading a file with a header.
-template<typename eT>
-inline
-bool
-diskio::load_raw_ascii(Cube<eT>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT> tmp;
-  const bool load_okay = diskio::load_raw_ascii(tmp, name, err_msg);
-  
-  if(load_okay == true)
-    {
-    if(tmp.is_empty() == false)
-      {
-      x.set_size(tmp.n_rows, tmp.n_cols, 1);
-      
-      x.slice(0) = tmp;
-      }
-    else
-      {
-      x.reset();
-      }
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Load a cube as raw text (no header, human readable).
-//! NOTE: this is much slower than reading a file with a header.
-template<typename eT>
-inline
-bool
-diskio::load_raw_ascii(Cube<eT>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT> tmp;
-  const bool load_okay = diskio::load_raw_ascii(tmp, f, err_msg);
-  
-  if(load_okay == true)
-    {
-    if(tmp.is_empty() == false)
-      {
-      x.set_size(tmp.n_rows, tmp.n_cols, 1);
-      
-      x.slice(0) = tmp;
-      }
-    else
-      {
-      x.reset();
-      }
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Load a cube in binary format (no header);
-//! the cube is assumed to have one slice with one column
-template<typename eT>
-inline
-bool
-diskio::load_raw_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::ifstream f;
-  f.open(name.c_str(), std::fstream::binary);
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_raw_binary(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-diskio::load_raw_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(err_msg);
-  
-  f.clear();
-  const std::streampos pos1 = f.tellg();
-  
-  f.clear();
-  f.seekg(0, ios::end);
-  
-  f.clear();
-  const std::streampos pos2 = f.tellg();
-  
-  const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
-  
-  f.clear();
-  //f.seekg(0, ios::beg);
-  f.seekg(pos1);
-  
-  x.set_size(N / sizeof(eT), 1, 1);
-  
-  f.clear();
-  f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(N) );
-  
-  return f.good();
-  }
-
-
-
-//! Load a cube in text format (human readable),
-//! with a header that indicates the cube type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::load_arma_ascii(Cube<eT>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::ifstream f(name.c_str());
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_arma_ascii(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-  
-
-
-//! Load a cube in text format (human readable),
-//! with a header that indicates the cube type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::load_arma_ascii(Cube<eT>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool load_okay = true;
-  
-  std::string f_header;
-  uword f_n_rows;
-  uword f_n_cols;
-  uword f_n_slices;
-  
-  f >> f_header;
-  f >> f_n_rows;
-  f >> f_n_cols;
-  f >> f_n_slices;
-  
-  if(f_header == diskio::gen_txt_header(x))
-    {
-    x.set_size(f_n_rows, f_n_cols, f_n_slices);
-
-    for(uword slice=0; slice < x.n_slices; ++slice)
-      {
-      for(uword row=0; row < x.n_rows; ++row)
-        {
-        for(uword col=0; col < x.n_cols; ++col)
-          {
-          f >> x.at(row,col,slice);
-          }
-        }
-      }
-    
-    load_okay = f.good();
-    }
-  else
-    {
-    load_okay = false;
-    err_msg = "incorrect header in ";
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Load a cube in binary format,
-//! with a header that indicates the cube type as well as its dimensions
-template<typename eT>
-inline
-bool
-diskio::load_arma_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::ifstream f;
-  f.open(name.c_str(), std::fstream::binary);
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_arma_binary(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-diskio::load_arma_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool load_okay = true;
-  
-  std::string f_header;
-  uword f_n_rows;
-  uword f_n_cols;
-  uword f_n_slices;
-  
-  f >> f_header;
-  f >> f_n_rows;
-  f >> f_n_cols;
-  f >> f_n_slices;
-  
-  if(f_header == diskio::gen_bin_header(x))
-    {
-    //f.seekg(1, ios::cur);  // NOTE: this may not be portable, as on a Windows machine a newline could be two characters
-    f.get();
-    
-    x.set_size(f_n_rows, f_n_cols, f_n_slices);
-    f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(x.n_elem*sizeof(eT)) );
-    
-    load_okay = f.good();
-    }
-  else
-    {
-    load_okay = false;
-    err_msg = "incorrect header in ";
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Try to load a cube by automatically determining its type
-template<typename eT>
-inline
-bool
-diskio::load_auto_detect(Cube<eT>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::fstream f;
-  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_auto_detect(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Try to load a cube by automatically determining its type
-template<typename eT>
-inline
-bool
-diskio::load_auto_detect(Cube<eT>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  static const std::string ARMA_CUB_TXT = "ARMA_CUB_TXT";
-  static const std::string ARMA_CUB_BIN = "ARMA_CUB_BIN";
-  static const std::string           P6 = "P6";
-  
-  podarray<char> raw_header(ARMA_CUB_TXT.length() + 1);
-  
-  std::streampos pos = f.tellg();
-  
-  f.read( raw_header.memptr(), std::streamsize(ARMA_CUB_TXT.length()) );
-  raw_header[ARMA_CUB_TXT.length()] = '\0';
-  
-  f.clear();
-  f.seekg(pos);
-  
-  const std::string header = raw_header.mem;
-  
-  if(ARMA_CUB_TXT == header.substr(0, ARMA_CUB_TXT.length()))
-    {
-    return load_arma_ascii(x, f, err_msg);
-    }
-  else
-  if(ARMA_CUB_BIN == header.substr(0, ARMA_CUB_BIN.length()))
-    {
-    return load_arma_binary(x, f, err_msg);
-    }
-  else
-  if(P6 == header.substr(0, P6.length()))
-    {
-    return load_ppm_binary(x, f, err_msg);
-    }
-  else
-    {
-    const file_type ft = guess_file_type(f);
-    
-    switch(ft)
-      {
-      // case csv_ascii:
-      //   return load_csv_ascii(x, f, err_msg);
-      //   break;
-      
-      case raw_binary:
-        return load_raw_binary(x, f, err_msg);
-        break;
-        
-      case raw_ascii:
-        return load_raw_ascii(x, f, err_msg);
-        break;
-        
-      default:
-        err_msg = "unknown data in ";
-        return false;
-      }
-    }
-  
-  return false;
-  }
-
-
-
-
-
-// fields
-
-
-
-template<typename T1>
-inline
-bool
-diskio::save_arma_binary(const field<T1>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  
-  std::ofstream f( tmp_name.c_str(), std::fstream::binary );
-  
-  bool save_okay = f.is_open();
-  
-  if(save_okay == true)
-    {
-    save_okay = diskio::save_arma_binary(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-template<typename T1>
-inline
-bool
-diskio::save_arma_binary(const field<T1>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( (is_Mat<T1>::value == false) && (is_Cube<T1>::value == false) ));
-  
-  f << "ARMA_FLD_BIN" << '\n';
-  f << x.n_rows << '\n';
-  f << x.n_cols << '\n';
-  
-  bool save_okay = true;
-  
-  for(uword i=0; i<x.n_elem; ++i)
-    {
-    save_okay = diskio::save_arma_binary(x[i], f);
-    
-    if(save_okay == false)
-      {
-      break;
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-template<typename T1>
-inline
-bool
-diskio::load_arma_binary(field<T1>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::ifstream f( name.c_str(), std::fstream::binary );
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_arma_binary(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-template<typename T1>
-inline
-bool
-diskio::load_arma_binary(field<T1>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( (is_Mat<T1>::value == false) && (is_Cube<T1>::value == false) ));
-  
-  bool load_okay = true;
-  
-  std::string f_type;
-  f >> f_type;
-  
-  if(f_type != "ARMA_FLD_BIN")
-    {
-    load_okay = false;
-    err_msg = "unsupported field type in ";
-    }
-  else
-    {
-    uword f_n_rows;
-    uword f_n_cols;
-  
-    f >> f_n_rows;
-    f >> f_n_cols;
-    
-    x.set_size(f_n_rows, f_n_cols);
-    
-    f.get();      
-    
-    for(uword i=0; i<x.n_elem; ++i)
-      {
-      load_okay = diskio::load_arma_binary(x[i], f, err_msg);
-      
-      if(load_okay == false)
-        {
-        break;
-        }
-      }
-    }
-  
-  return load_okay;
-  }
-
-
-
-inline
-bool
-diskio::save_std_string(const field<std::string>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  
-  std::ofstream f( tmp_name.c_str(), std::fstream::binary );
-  
-  bool save_okay = f.is_open();
-  
-  if(save_okay == true)
-    {
-    save_okay = diskio::save_std_string(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-inline
-bool
-diskio::save_std_string(const field<std::string>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  for(uword row=0; row<x.n_rows; ++row)
-  for(uword col=0; col<x.n_cols; ++col)
-    {
-    f << x.at(row,col);
-    
-    if(col < x.n_cols-1)
-      {
-      f << ' ';
-      }
-    else
-      {
-      f << '\n';
-      }
-    }
-  
-  return f.good();
-  }
-
-
-
-inline
-bool
-diskio::load_std_string(field<std::string>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::ifstream f( name.c_str() );
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_std_string(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-inline
-bool
-diskio::load_std_string(field<std::string>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool load_okay = true;
-  
-  //
-  // work out the size
-  
-  uword f_n_rows = 0;
-  uword f_n_cols = 0;
-  
-  bool f_n_cols_found = false;
-  
-  std::string line_string;
-  std::string token;
-  
-  while( (f.good() == true) && (load_okay == true) )
-    {
-    std::getline(f, line_string);
-    if(line_string.size() == 0)
-      break;
-    
-    std::stringstream line_stream(line_string);
-    
-    uword line_n_cols = 0;
-    while (line_stream >> token)
-      line_n_cols++;
-    
-    if(f_n_cols_found == false)
-      {
-      f_n_cols = line_n_cols;
-      f_n_cols_found = true;
-      }
-    else
-      {
-      if(line_n_cols != f_n_cols)
-        {
-        load_okay = false;
-        err_msg = "inconsistent number of columns in ";
-        }
-      }
-    
-    ++f_n_rows;
-    }
-    
-  if(load_okay == true)
-    {
-    f.clear();
-    f.seekg(0, ios::beg);
-    //f.seekg(start);
-    
-    x.set_size(f_n_rows, f_n_cols);
-  
-    for(uword row=0; row < x.n_rows; ++row)
-      {
-      for(uword col=0; col < x.n_cols; ++col)
-        {
-        f >> x.at(row,col);
-        }
-      }
-    }
-  
-  if(f.good() == false)
-    {
-    load_okay = false; 
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Try to load a field by automatically determining its type
-template<typename T1>
-inline
-bool
-diskio::load_auto_detect(field<T1>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::fstream f;
-  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_auto_detect(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-//! Try to load a field by automatically determining its type
-template<typename T1>
-inline
-bool
-diskio::load_auto_detect(field<T1>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_Mat<T1>::value == false ));
-  
-  static const std::string ARMA_FLD_BIN = "ARMA_FLD_BIN";
-  static const std::string           P6 = "P6";
-  
-  podarray<char> raw_header(ARMA_FLD_BIN.length() + 1);
-  
-  std::streampos pos = f.tellg();
-  
-  f.read( raw_header.memptr(), std::streamsize(ARMA_FLD_BIN.length()) );
-  
-  f.clear();
-  f.seekg(pos);
-  
-  raw_header[ARMA_FLD_BIN.length()] = '\0';
-  
-  const std::string header = raw_header.mem;
-  
-  if(ARMA_FLD_BIN == header.substr(0, ARMA_FLD_BIN.length()))
-    {
-    return load_arma_binary(x, f, err_msg);
-    }
-  else
-  if(P6 == header.substr(0, P6.length()))
-    {
-    return load_ppm_binary(x, f, err_msg);
-    }
-  else
-    {
-    err_msg = "unsupported header in ";
-    return false;
-    }
-  }
-
-
-
-//
-// handling of PPM images by cubes
-
-
-template<typename eT>
-inline
-bool
-diskio::load_ppm_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::fstream f;
-  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_ppm_binary(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-diskio::load_ppm_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  bool load_okay = true;
-  
-  std::string f_header;
-  f >> f_header;
-  
-  if(f_header == "P6")
-    {
-    uword f_n_rows = 0;
-    uword f_n_cols = 0;
-    int f_maxval = 0;
-  
-    diskio::pnm_skip_comments(f);
-  
-    f >> f_n_cols;
-    diskio::pnm_skip_comments(f);
-  
-    f >> f_n_rows;
-    diskio::pnm_skip_comments(f);
-  
-    f >> f_maxval;
-    f.get();
-    
-    if( (f_maxval > 0) || (f_maxval <= 65535) )
-      {
-      x.set_size(f_n_rows, f_n_cols, 3);
-      
-      if(f_maxval <= 255)
-        {
-        const uword n_elem = 3*f_n_cols*f_n_rows;
-        podarray<u8> tmp(n_elem);
-        
-        f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
-        
-        uword i = 0;
-        
-        //cout << "f_n_cols = " << f_n_cols << endl;
-        //cout << "f_n_rows = " << f_n_rows << endl;
-        
-        
-        for(uword row=0; row < f_n_rows; ++row)
-          {
-          for(uword col=0; col < f_n_cols; ++col)
-            {
-            x.at(row,col,0) = eT(tmp[i+0]);
-            x.at(row,col,1) = eT(tmp[i+1]);
-            x.at(row,col,2) = eT(tmp[i+2]);
-            i+=3;
-            }
-          
-          }
-        }
-      else
-        {
-        const uword n_elem = 3*f_n_cols*f_n_rows;
-        podarray<u16> tmp(n_elem);
-        
-        f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(2*n_elem) );
-        
-        uword i = 0;
-        
-        for(uword row=0; row < f_n_rows; ++row)
-          {
-          for(uword col=0; col < f_n_cols; ++col)
-            {
-            x.at(row,col,0) = eT(tmp[i+0]);
-            x.at(row,col,1) = eT(tmp[i+1]);
-            x.at(row,col,2) = eT(tmp[i+2]);
-            i+=3;
-            }
-          
-          }
-        
-        }
-      
-      }
-    else
-      {
-      load_okay = false;
-      err_msg = "currently no code available to handle loading ";
-      }
-      
-    if(f.good() == false)
-      {
-      load_okay = false;
-      }
-    
-    }
-  else
-    {
-    load_okay = false;
-    err_msg = "unsupported header in ";
-    }
-  
-  return load_okay;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-diskio::save_ppm_binary(const Cube<eT>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  
-  std::ofstream f( tmp_name.c_str(), std::fstream::binary );
-  
-  bool save_okay = f.is_open();
-  
-  if(save_okay == true)
-    {
-    save_okay = diskio::save_ppm_binary(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-diskio::save_ppm_binary(const Cube<eT>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (x.n_slices != 3), "diskio::save_ppm_binary(): given cube must have exactly 3 slices" );
-  
-  const uword n_elem = 3 * x.n_rows * x.n_cols;
-  podarray<u8> tmp(n_elem);
-  
-  uword i = 0;
-  for(uword row=0; row < x.n_rows; ++row)
-    {
-    for(uword col=0; col < x.n_cols; ++col)
-      {
-      tmp[i+0] = u8( access::tmp_real( x.at(row,col,0) ) );
-      tmp[i+1] = u8( access::tmp_real( x.at(row,col,1) ) );
-      tmp[i+2] = u8( access::tmp_real( x.at(row,col,2) ) );
-      
-      i+=3;
-      }
-    }
-  
-  f << "P6" << '\n';
-  f << x.n_cols << '\n';
-  f << x.n_rows << '\n';
-  f << 255 << '\n';
-  
-  f.write( reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
-  
-  return f.good();
-  }
-
-
-
-//
-// handling of PPM images by fields
-
-
-
-template<typename T1>
-inline
-bool
-diskio::load_ppm_binary(field<T1>& x, const std::string& name, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::fstream f;
-  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
-  
-  bool load_okay = f.is_open();
-  
-  if(load_okay == true)
-    {
-    load_okay = diskio::load_ppm_binary(x, f, err_msg);
-    f.close();
-    }
-  
-  return load_okay;
-  }
-
-
-
-template<typename T1>
-inline
-bool
-diskio::load_ppm_binary(field<T1>& x, std::istream& f, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_Mat<T1>::value == false ));
-  typedef typename T1::elem_type eT;
-  
-  bool load_okay = true;
-  
-  std::string f_header;
-  f >> f_header;
-  
-  if(f_header == "P6")
-    {
-    uword f_n_rows = 0;
-    uword f_n_cols = 0;
-    int f_maxval = 0;
-  
-    diskio::pnm_skip_comments(f);
-  
-    f >> f_n_cols;
-    diskio::pnm_skip_comments(f);
-  
-    f >> f_n_rows;
-    diskio::pnm_skip_comments(f);
-  
-    f >> f_maxval;
-    f.get();
-    
-    if( (f_maxval > 0) || (f_maxval <= 65535) )
-      {
-      x.set_size(3);
-      Mat<eT>& R = x(0);
-      Mat<eT>& G = x(1);
-      Mat<eT>& B = x(2);
-      
-      R.set_size(f_n_rows,f_n_cols);
-      G.set_size(f_n_rows,f_n_cols);
-      B.set_size(f_n_rows,f_n_cols);
-      
-      if(f_maxval <= 255)
-        {
-        const uword n_elem = 3*f_n_cols*f_n_rows;
-        podarray<u8> tmp(n_elem);
-        
-        f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
-        
-        uword i = 0;
-        
-        //cout << "f_n_cols = " << f_n_cols << endl;
-        //cout << "f_n_rows = " << f_n_rows << endl;
-        
-        
-        for(uword row=0; row < f_n_rows; ++row)
-          {
-          for(uword col=0; col < f_n_cols; ++col)
-            {
-            R.at(row,col) = eT(tmp[i+0]);
-            G.at(row,col) = eT(tmp[i+1]);
-            B.at(row,col) = eT(tmp[i+2]);
-            i+=3;
-            }
-          
-          }
-        }
-      else
-        {
-        const uword n_elem = 3*f_n_cols*f_n_rows;
-        podarray<u16> tmp(n_elem);
-        
-        f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(2*n_elem) );
-        
-        uword i = 0;
-        
-        for(uword row=0; row < f_n_rows; ++row)
-          {
-          for(uword col=0; col < f_n_cols; ++col)
-            {
-            R.at(row,col) = eT(tmp[i+0]);
-            G.at(row,col) = eT(tmp[i+1]);
-            B.at(row,col) = eT(tmp[i+2]);
-            i+=3;
-            }
-          
-          }
-        
-        }
-      
-      }
-    else
-      {
-      load_okay = false;
-      err_msg = "currently no code available to handle loading ";
-      }
-    
-    if(f.good() == false)
-      {
-      load_okay = false;
-      }
-    
-    }
-  else
-    {
-    load_okay = false;
-    err_msg = "unsupported header in ";
-    }
-  
-  return load_okay;
-  }
-
-
-
-template<typename T1>
-inline
-bool
-diskio::save_ppm_binary(const field<T1>& x, const std::string& final_name)
-  {
-  arma_extra_debug_sigprint();
-  
-  const std::string tmp_name = diskio::gen_tmp_name(final_name);
-  std::ofstream f( tmp_name.c_str(), std::fstream::binary );
-  
-  bool save_okay = f.is_open();
-  
-  if(save_okay == true)
-    {
-    save_okay = diskio::save_ppm_binary(x, f);
-    
-    f.flush();
-    f.close();
-    
-    if(save_okay == true)
-      {
-      save_okay = diskio::safe_rename(tmp_name, final_name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-template<typename T1>
-inline
-bool
-diskio::save_ppm_binary(const field<T1>& x, std::ostream& f)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_Mat<T1>::value == false ));
-  
-  typedef typename T1::elem_type eT;
-  
-  arma_debug_check( (x.n_elem != 3), "diskio::save_ppm_binary(): given field must have exactly 3 matrices of equal size" );
-  
-  bool same_size = true;
-  for(uword i=1; i<3; ++i)
-    {
-    if( (x(0).n_rows != x(i).n_rows) || (x(0).n_cols != x(i).n_cols) )
-      {
-      same_size = false;
-      break;
-      }
-    }
-  
-  arma_debug_check( (same_size != true), "diskio::save_ppm_binary(): given field must have exactly 3 matrices of equal size" );
-  
-  const Mat<eT>& R = x(0);
-  const Mat<eT>& G = x(1);
-  const Mat<eT>& B = x(2);
-  
-  f << "P6" << '\n';
-  f << R.n_cols << '\n';
-  f << R.n_rows << '\n';
-  f << 255 << '\n';
-
-  const uword n_elem = 3 * R.n_rows * R.n_cols;
-  podarray<u8> tmp(n_elem);
-
-  uword i = 0;
-  for(uword row=0; row < R.n_rows; ++row)
-    {
-    for(uword col=0; col < R.n_cols; ++col)
-      {
-      tmp[i+0] = u8( access::tmp_real( R.at(row,col) ) );
-      tmp[i+1] = u8( access::tmp_real( G.at(row,col) ) );
-      tmp[i+2] = u8( access::tmp_real( B.at(row,col) ) );
-      
-      i+=3;
-      }
-    }
-  
-  f.write( reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
-  
-  return f.good();
-  }
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/eGlueCube_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup eGlueCube
-//! @{
-
-
-template<typename T1, typename T2, typename eglue_type>
-class eGlueCube : public BaseCube<typename T1::elem_type, eGlueCube<T1, T2, eglue_type> >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  static const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
-  static const bool has_subview        = (ProxyCube<T1>::has_subview        || ProxyCube<T2>::has_subview       );
-  
-  arma_aligned const ProxyCube<T1> P1;
-  arma_aligned const ProxyCube<T2> P2;
-  
-  arma_inline ~eGlueCube();
-  arma_inline  eGlueCube(const T1& in_A, const T2& in_B);
-  
-  arma_inline uword get_n_rows()       const;
-  arma_inline uword get_n_cols()       const;
-  arma_inline uword get_n_elem_slice() const;
-  arma_inline uword get_n_slices()     const;
-  arma_inline uword get_n_elem()       const;
-  
-  arma_inline elem_type operator[] (const uword i)                                   const;
-  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const;
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/eGlueCube_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup eGlueCube
-//! @{
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-eGlueCube<T1,T2,eglue_type>::~eGlueCube()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-eGlueCube<T1,T2,eglue_type>::eGlueCube(const T1& in_A, const T2& in_B)
-  : P1(in_A)
-  , P2(in_B)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_assert_same_size
-    (
-    P1.get_n_rows(), P1.get_n_cols(), P1.get_n_slices(),
-    P2.get_n_rows(), P2.get_n_cols(), P2.get_n_slices(), 
-    eglue_type::text()
-    );
-  }
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-uword
-eGlueCube<T1,T2,eglue_type>::get_n_rows() const
-  {
-  return P1.get_n_rows();
-  }
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-uword
-eGlueCube<T1,T2,eglue_type>::get_n_cols() const
-  {
-  return P1.get_n_cols();
-  }
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-uword
-eGlueCube<T1,T2,eglue_type>::get_n_slices() const
-  {
-  return P1.get_n_slices();
-  }
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-uword
-eGlueCube<T1,T2,eglue_type>::get_n_elem_slice() const
-  {
-  return P1.get_n_elem_slice();
-  }
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-uword
-eGlueCube<T1,T2,eglue_type>::get_n_elem() const
-  {
-  return P1.get_n_elem();
-  }
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-typename T1::elem_type
-eGlueCube<T1,T2,eglue_type>::operator[] (const uword i) const
-  {
-  typedef typename T1::elem_type eT;
-  
-  // the optimiser will keep only one return statement
-  
-       if(is_same_type<eglue_type, eglue_plus >::value == true) { return P1[i] + P2[i]; }
-  else if(is_same_type<eglue_type, eglue_minus>::value == true) { return P1[i] - P2[i]; }
-  else if(is_same_type<eglue_type, eglue_div  >::value == true) { return P1[i] / P2[i]; }
-  else if(is_same_type<eglue_type, eglue_schur>::value == true) { return P1[i] * P2[i]; }
-  }
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-typename T1::elem_type
-eGlueCube<T1,T2,eglue_type>::at(const uword row, const uword col, const uword slice) const
-  {
-  typedef typename T1::elem_type eT;
-  
-  // the optimiser will keep only one return statement
-  
-       if(is_same_type<eglue_type, eglue_plus >::value == true) { return P1.at(row,col,slice) + P2.at(row,col,slice); }
-  else if(is_same_type<eglue_type, eglue_minus>::value == true) { return P1.at(row,col,slice) - P2.at(row,col,slice); }
-  else if(is_same_type<eglue_type, eglue_div  >::value == true) { return P1.at(row,col,slice) / P2.at(row,col,slice); }
-  else if(is_same_type<eglue_type, eglue_schur>::value == true) { return P1.at(row,col,slice) * P2.at(row,col,slice); }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/eGlue_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup eGlue
-//! @{
-
-
-template<typename T1, typename T2, typename eglue_type>
-class eGlue : public Base<typename T1::elem_type, eGlue<T1, T2, eglue_type> >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  static const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
-  static const bool has_subview        = (Proxy<T1>::has_subview        || Proxy<T2>::has_subview       );
-  
-  arma_aligned const Proxy<T1> P1;
-  arma_aligned const Proxy<T2> P2;
-  
-  arma_inline ~eGlue();
-  arma_inline  eGlue(const T1& in_A, const T2& in_B);
-  
-  arma_inline uword get_n_rows() const;
-  arma_inline uword get_n_cols() const;
-  arma_inline uword get_n_elem() const;
-  
-  arma_inline elem_type operator[] (const uword i)                  const;
-  arma_inline elem_type at         (const uword row, const uword col) const;
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/eGlue_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup eGlue
-//! @{
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-eGlue<T1,T2,eglue_type>::~eGlue()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-eGlue<T1,T2,eglue_type>::eGlue(const T1& in_A, const T2& in_B)
-  : P1(in_A)
-  , P2(in_B)
-  {
-  arma_extra_debug_sigprint();
-  
-  // arma_debug_assert_same_size( P1, P2, eglue_type::text() );
-  arma_debug_assert_same_size
-    (
-    P1.get_n_rows(), P1.get_n_cols(),
-    P2.get_n_rows(), P2.get_n_cols(),
-    eglue_type::text()
-    );
-  }
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-uword
-eGlue<T1,T2,eglue_type>::get_n_rows() const
-  {
-  return P1.get_n_rows();
-  }
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-uword
-eGlue<T1,T2,eglue_type>::get_n_cols() const
-  {
-  return P1.get_n_cols();
-  }
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-uword
-eGlue<T1,T2,eglue_type>::get_n_elem() const
-  {
-  return P1.get_n_elem();
-  }
-
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-typename T1::elem_type
-eGlue<T1,T2,eglue_type>::operator[] (const uword i) const
-  {
-  typedef typename T1::elem_type eT;
-  
-  // the optimiser will keep only one return statement
-  
-       if(is_same_type<eglue_type, eglue_plus >::value == true) { return P1[i] + P2[i]; }
-  else if(is_same_type<eglue_type, eglue_minus>::value == true) { return P1[i] - P2[i]; }
-  else if(is_same_type<eglue_type, eglue_div  >::value == true) { return P1[i] / P2[i]; }
-  else if(is_same_type<eglue_type, eglue_schur>::value == true) { return P1[i] * P2[i]; }
-  }
-
-
-template<typename T1, typename T2, typename eglue_type>
-arma_inline
-typename T1::elem_type
-eGlue<T1,T2,eglue_type>::at(const uword row, const uword col) const
-  {
-  typedef typename T1::elem_type eT;
-  
-  // the optimiser will keep only one return statement
-  
-       if(is_same_type<eglue_type, eglue_plus >::value == true) { return P1.at(row,col) + P2.at(row,col); }
-  else if(is_same_type<eglue_type, eglue_minus>::value == true) { return P1.at(row,col) - P2.at(row,col); }
-  else if(is_same_type<eglue_type, eglue_div  >::value == true) { return P1.at(row,col) / P2.at(row,col); }
-  else if(is_same_type<eglue_type, eglue_schur>::value == true) { return P1.at(row,col) * P2.at(row,col); }
-  }
-
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/eOpCube_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup eOpCube
-//! @{
-
-
-
-template<typename T1, typename eop_type>
-class eOpCube : public BaseCube<typename T1::elem_type, eOpCube<T1, eop_type> >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  static const bool prefer_at_accessor = ProxyCube<T1>::prefer_at_accessor;
-  static const bool has_subview        = ProxyCube<T1>::has_subview;
-  
-  arma_aligned const ProxyCube<T1> P;
-  arma_aligned       elem_type     aux;          //!< storage of auxiliary data, user defined format
-  arma_aligned       uword         aux_uword_a;  //!< storage of auxiliary data, uword format
-  arma_aligned       uword         aux_uword_b;  //!< storage of auxiliary data, uword format
-  arma_aligned       uword         aux_uword_c;  //!< storage of auxiliary data, uword format
-  
-  inline         ~eOpCube();
-  inline explicit eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m);
-  inline          eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const elem_type in_aux);
-  inline          eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
-  inline          eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
-  inline          eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
-  
-  arma_inline uword get_n_rows()       const;
-  arma_inline uword get_n_cols()       const;
-  arma_inline uword get_n_elem_slice() const;
-  arma_inline uword get_n_slices()     const;
-  arma_inline uword get_n_elem()       const;
-  
-  arma_inline elem_type operator[] (const uword i)                                       const;
-  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const;
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/eOpCube_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup eOpCube
-//! @{
-
-
-
-template<typename T1, typename eop_type>
-eOpCube<T1, eop_type>::eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m)
-  : P (in_m.get_ref())
-  {
-  arma_extra_debug_sigprint();
-  }
-  
-
-
-template<typename T1, typename eop_type>
-eOpCube<T1, eop_type>::eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const typename T1::elem_type in_aux)
-  : P   (in_m.get_ref())
-  , aux (in_aux)
-  {
-  arma_extra_debug_sigprint();
-  }
-  
-
-
-template<typename T1, typename eop_type>
-eOpCube<T1, eop_type>::eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b)
-  : P           (in_m.get_ref())
-  , aux_uword_a (in_aux_uword_a)
-  , aux_uword_b (in_aux_uword_b)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename eop_type>
-eOpCube<T1, eop_type>::eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c)
-  : P           (in_m.get_ref())
-  , aux_uword_a (in_aux_uword_a)
-  , aux_uword_b (in_aux_uword_b)
-  , aux_uword_c (in_aux_uword_c)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename eop_type>
-eOpCube<T1, eop_type>::eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const typename T1::elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c)
-  : P           (in_m.get_ref())
-  , aux         (in_aux)
-  , aux_uword_a (in_aux_uword_a)
-  , aux_uword_b (in_aux_uword_b)
-  , aux_uword_c (in_aux_uword_c)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename eop_type>
-eOpCube<T1, eop_type>::~eOpCube()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename eop_type>
-arma_inline
-uword
-eOpCube<T1, eop_type>::get_n_rows() const
-  {
-  return P.get_n_rows();
-  }
-  
-
-
-template<typename T1, typename eop_type>
-arma_inline
-uword
-eOpCube<T1, eop_type>::get_n_cols() const
-  {
-  return P.get_n_cols();
-  }
-
-
-
-template<typename T1, typename eop_type>
-arma_inline
-uword
-eOpCube<T1, eop_type>::get_n_elem_slice() const
-  {
-  return P.get_n_elem_slice();
-  }
-
-
-
-template<typename T1, typename eop_type>
-arma_inline
-uword
-eOpCube<T1, eop_type>::get_n_slices() const
-  {
-  return P.get_n_slices();
-  }
-
-
-
-template<typename T1, typename eop_type>
-arma_inline
-uword
-eOpCube<T1, eop_type>::get_n_elem() const
-  {
-  return P.get_n_elem();
-  }
-
-
-
-template<typename T1, typename eop_type>
-arma_inline
-typename T1::elem_type
-eOpCube<T1, eop_type>::operator[] (const uword i) const
-  {
-  return eop_core<eop_type>::process(P[i], aux);
-  }
-
-
-
-template<typename T1, typename eop_type>
-arma_inline
-typename T1::elem_type
-eOpCube<T1, eop_type>::at(const uword row, const uword col, const uword slice) const
-  {
-  typedef typename T1::elem_type eT;
-  
-  return eop_core<eop_type>::process(P.at(row, col, slice), aux);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/eOp_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup eOp
-//! @{
-
-
-
-template<typename T1, typename eop_type>
-class eOp : public Base<typename T1::elem_type, eOp<T1, eop_type> >
-  {
-  public:
-  
-  typedef typename T1::elem_type                   elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  typedef          Proxy<T1>                       proxy_type;
-  
-  static const bool prefer_at_accessor = Proxy<T1>::prefer_at_accessor;
-  static const bool has_subview        = Proxy<T1>::has_subview;
-  
-  arma_aligned const Proxy<T1> P;
-  arma_aligned       elem_type aux;          //!< storage of auxiliary data, user defined format
-  arma_aligned       uword     aux_uword_a;  //!< storage of auxiliary data, uword format
-  arma_aligned       uword     aux_uword_b;  //!< storage of auxiliary data, uword format
-  
-  inline         ~eOp();
-  inline explicit eOp(const Base<typename T1::elem_type, T1>& in_m);
-  inline          eOp(const Base<typename T1::elem_type, T1>& in_m, const elem_type in_aux);
-  inline          eOp(const Base<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
-  inline          eOp(const Base<typename T1::elem_type, T1>& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b);
-  
-  arma_inline uword get_n_rows() const;
-  arma_inline uword get_n_cols() const;
-  arma_inline uword get_n_elem() const;
-  
-  arma_inline elem_type operator[] (const uword i)                    const;
-  arma_inline elem_type at         (const uword row, const uword col) const;
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/eOp_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup eOp
-//! @{
-
-
-
-template<typename T1, typename eop_type>
-eOp<T1, eop_type>::eOp(const Base<typename T1::elem_type, T1>& in_m)
-  : P(in_m.get_ref())
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename eop_type>
-eOp<T1, eop_type>::eOp(const Base<typename T1::elem_type, T1>& in_m, const typename T1::elem_type in_aux)
-  : P(in_m.get_ref())
-  , aux(in_aux)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename eop_type>
-eOp<T1, eop_type>::eOp(const Base<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b)
-  : P(in_m.get_ref())
-  , aux_uword_a(in_aux_uword_a)
-  , aux_uword_b(in_aux_uword_b)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename eop_type>
-eOp<T1, eop_type>::eOp(const Base<typename T1::elem_type, T1>& in_m, const typename T1::elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b)
-  : P(in_m.get_ref())
-  , aux(in_aux)
-  , aux_uword_a(in_aux_uword_a)
-  , aux_uword_b(in_aux_uword_b)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename T1, typename eop_type>
-eOp<T1, eop_type>::~eOp()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-  
-
-template<typename T1, typename eop_type>
-arma_inline
-uword
-eOp<T1, eop_type>::get_n_rows() const
-  {
-  return P.get_n_rows();
-  }
-  
-
-
-template<typename T1, typename eop_type>
-arma_inline
-uword
-eOp<T1, eop_type>::get_n_cols() const
-  {
-  return P.get_n_cols();
-  }
-
-
-
-template<typename T1, typename eop_type>
-arma_inline
-uword
-eOp<T1, eop_type>::get_n_elem() const
-  {
-  return P.get_n_elem();
-  }
-
-
-
-template<typename T1, typename eop_type>
-arma_inline
-typename T1::elem_type
-eOp<T1, eop_type>::operator[] (const uword i) const
-  {
-  return eop_core<eop_type>::process(P[i], aux);
-  }
-
-
-
-template<typename T1, typename eop_type>
-arma_inline
-typename T1::elem_type
-eOp<T1, eop_type>::at(const uword row, const uword col) const
-  {
-  return eop_core<eop_type>::process(P.at(row, col), aux);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/eglue_core_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup eglue_core
-//! @{
-
-
-
-template<typename eglue_type>
-struct eglue_core
-  {
-  
-  // matrices
-  
-  template<typename T1, typename T2> arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x);
-  
-  template<typename T1, typename T2> arma_hot inline static void apply_inplace_plus (Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x);
-  template<typename T1, typename T2> arma_hot inline static void apply_inplace_minus(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x);
-  template<typename T1, typename T2> arma_hot inline static void apply_inplace_schur(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x);
-  template<typename T1, typename T2> arma_hot inline static void apply_inplace_div  (Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x);
-  
-  
-  // cubes
-  
-  template<typename T1, typename T2> arma_hot inline static void apply(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x);
-  
-  template<typename T1, typename T2> arma_hot inline static void apply_inplace_plus (Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x);
-  template<typename T1, typename T2> arma_hot inline static void apply_inplace_minus(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x);
-  template<typename T1, typename T2> arma_hot inline static void apply_inplace_schur(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x);
-  template<typename T1, typename T2> arma_hot inline static void apply_inplace_div  (Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x);
-  };
-
-
-
-class eglue_plus;
-class eglue_minus;
-class eglue_div;
-class eglue_schur;
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/eglue_core_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,632 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup eglue_core
-//! @{
-
-
-
-class eglue_plus : public eglue_core<eglue_plus>
-  {
-  public:
-  
-  inline static const char* text() { return "addition"; }
-  };
-
-
-
-class eglue_minus : public eglue_core<eglue_minus>
-  {
-  public:
-  
-  inline static const char* text() { return "subtraction"; }
-  };
-
-
-
-class eglue_div : public eglue_core<eglue_div>
-  {
-  public:
-  
-  inline static const char* text() { return "element-wise division"; }
-  };
-
-
-
-class eglue_schur : public eglue_core<eglue_schur>
-  {
-  public:
-  
-  inline static const char* text() { return "element-wise multiplication"; }
-  };
-
-
-
-#undef arma_applier_1
-#undef arma_applier_2
-#undef arma_applier_3
-#undef operatorA
-#undef operatorB
-
-#define arma_applier_1(operatorA, operatorB) \
-  {\
-  uword i,j;\
-  \
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)\
-    {\
-    eT tmp_i = P1[i];\
-    eT tmp_j = P1[j];\
-    \
-    tmp_i operatorB##= P2[i];\
-    tmp_j operatorB##= P2[j];\
-    \
-    out_mem[i] operatorA tmp_i;\
-    out_mem[j] operatorA tmp_j;\
-    }\
-  \
-  if(i < n_elem)\
-    {\
-    out_mem[i] operatorA P1[i] operatorB P2[i];\
-    }\
-  }
-  
-
-
-#define arma_applier_2(operatorA, operatorB) \
-  {\
-  uword count = 0;\
-  \
-  for(uword col=0; col<n_cols; ++col)\
-    {\
-    uword i,j;\
-    \
-    for(i=0, j=1; j<n_rows; i+=2, j+=2, count+=2)\
-      {\
-      eT tmp_i = P1.at(i,col);\
-      eT tmp_j = P1.at(j,col);\
-      \
-      tmp_i operatorB##= P2.at(i,col);\
-      tmp_j operatorB##= P2.at(j,col);\
-      \
-      out_mem[count  ] operatorA tmp_i;\
-      out_mem[count+1] operatorA tmp_j;\
-      }\
-    \
-    if(i < n_rows)\
-      {\
-      out_mem[count] operatorA P1.at(i,col) operatorB P2.at(i,col);\
-      ++count;\
-      }\
-    }\
-  }
-
-
-
-#define arma_applier_3(operatorA, operatorB) \
-  {\
-  uword count = 0;\
-  \
-  for(uword slice=0; slice<n_slices; ++slice)\
-    {\
-    for(uword col=0; col<n_cols; ++col)\
-      {\
-      uword i,j;\
-      \
-      for(i=0, j=1; j<n_rows; i+=2, j+=2, count+=2)\
-        {\
-        eT tmp_i = P1.at(i,col,slice);\
-        eT tmp_j = P1.at(j,col,slice);\
-        \
-        tmp_i operatorB##= P2.at(i,col,slice);\
-        tmp_j operatorB##= P2.at(j,col,slice);\
-        \
-        out_mem[count  ] operatorA tmp_i;\
-        out_mem[count+1] operatorA tmp_j;\
-        }\
-      \
-      if(i < n_rows)\
-        {\
-        out_mem[count] operatorA P1.at(i,col,slice) operatorB P2.at(i,col,slice);\
-        ++count;\
-        }\
-      }\
-    }\
-  }
-
-
-
-//
-// matrices
-
-
-
-template<typename eglue_type>
-template<typename T1, typename T2>
-arma_hot
-inline
-void
-eglue_core<eglue_type>::apply(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
-  
-  // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing;
-  // size setting and alias checking is done by either the Mat contructor or operator=()
-  
-  eT* out_mem = out.memptr();
-  
-  if(prefer_at_accessor == false)
-    {
-    const uword n_elem = out.n_elem;
-    
-    typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
-    typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
-  
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1(=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1(=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1(=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1(=, *); }
-    }
-  else
-    {
-    const uword n_rows = out.n_rows;
-    const uword n_cols = out.n_cols;
-  
-    const Proxy<T1>& P1 = x.P1;
-    const Proxy<T2>& P2 = x.P2;
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_2(=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_2(=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_2(=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_2(=, *); }
-    }
-  }
-
-
-
-template<typename eglue_type>
-template<typename T1, typename T2>
-arma_hot
-inline
-void
-eglue_core<eglue_type>::apply_inplace_plus(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out, x.P1, "addition");
-  
-  typedef typename T1::elem_type eT;
-  
-  eT* out_mem = out.memptr();
-  
-  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
-  
-  if(prefer_at_accessor == false)
-    {
-    const uword n_elem = out.n_elem;
-    
-    typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
-    typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1(+=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1(+=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1(+=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1(+=, *); }
-    }
-  else
-    {
-    const uword n_rows = out.n_rows;
-    const uword n_cols = out.n_cols;
-    
-    const Proxy<T1>& P1 = x.P1;
-    const Proxy<T2>& P2 = x.P2;
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_2(+=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_2(+=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_2(+=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_2(+=, *); }
-    }
-  }
-
-
-
-template<typename eglue_type>
-template<typename T1, typename T2>
-arma_hot
-inline
-void
-eglue_core<eglue_type>::apply_inplace_minus(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out, x.P1, "subtraction");
-  
-  typedef typename T1::elem_type eT;
-  
-  eT* out_mem = out.memptr();
-  
-  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
-  
-  if(prefer_at_accessor == false)
-    {
-    const uword n_elem = out.n_elem;
-    
-    typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
-    typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1(-=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1(-=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1(-=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1(-=, *); }
-    }
-  else
-    {
-    const uword n_rows = out.n_rows;
-    const uword n_cols = out.n_cols;
-    
-    const Proxy<T1>& P1 = x.P1;
-    const Proxy<T2>& P2 = x.P2;
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_2(-=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_2(-=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_2(-=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_2(-=, *); }
-    }
-  }
-
-
-
-template<typename eglue_type>
-template<typename T1, typename T2>
-arma_hot
-inline
-void
-eglue_core<eglue_type>::apply_inplace_schur(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out, x.P1, "element-wise multiplication");
-  
-  typedef typename T1::elem_type eT;
-  
-  eT* out_mem = out.memptr();
-  
-  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
-  
-  if(prefer_at_accessor == false)
-    {
-    const uword n_elem = out.n_elem;
-    
-    typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
-    typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1(*=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1(*=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1(*=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1(*=, *); }
-    }
-  else
-    {
-    const uword n_rows = out.n_rows;
-    const uword n_cols = out.n_cols;
-    
-    const Proxy<T1>& P1 = x.P1;
-    const Proxy<T2>& P2 = x.P2;
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_2(*=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_2(*=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_2(*=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_2(*=, *); }
-    }
-  }
-
-
-
-template<typename eglue_type>
-template<typename T1, typename T2>
-arma_hot
-inline
-void
-eglue_core<eglue_type>::apply_inplace_div(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out, x.P1, "element-wise division");
-  
-  typedef typename T1::elem_type eT;
-  
-  eT* out_mem = out.memptr();
-  
-  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
-  
-  if(prefer_at_accessor == false)
-    {
-    const uword n_elem = out.n_elem;
-    
-    typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
-    typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
-  
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1(/=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1(/=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1(/=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1(/=, *); }
-    }
-  else
-    {
-    const uword n_rows = out.n_rows;
-    const uword n_cols = out.n_cols;
-    
-    const Proxy<T1>& P1 = x.P1;
-    const Proxy<T2>& P2 = x.P2;
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_2(*=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_2(*=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_2(*=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_2(*=, *); }
-    }
-  }
-
-
-
-//
-// cubes
-
-
-
-template<typename eglue_type>
-template<typename T1, typename T2>
-arma_hot
-inline
-void
-eglue_core<eglue_type>::apply(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
-  
-  // NOTE: we're assuming that the cube has already been set to the correct size and there is no aliasing;
-  // size setting and alias checking is done by either the Cube contructor or operator=()
-  
-  
-  eT* out_mem = out.memptr();
-  
-  if(prefer_at_accessor == false)
-    {
-    const uword n_elem = out.n_elem;
-    
-    typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
-    typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
-  
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1(=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1(=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1(=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1(=, *); }
-    }
-  else
-    {
-    const uword n_rows   = x.get_n_rows();
-    const uword n_cols   = x.get_n_cols();
-    const uword n_slices = x.get_n_slices();
-  
-    const ProxyCube<T1>& P1 = x.P1;
-    const ProxyCube<T2>& P2 = x.P2;
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_3(=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_3(=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_3(=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_3(=, *); }
-    }
-  }
-
-
-
-template<typename eglue_type>
-template<typename T1, typename T2>
-arma_hot
-inline
-void
-eglue_core<eglue_type>::apply_inplace_plus(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword n_rows   = x.get_n_rows();
-  const uword n_cols   = x.get_n_cols();
-  const uword n_slices = x.get_n_slices();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "addition");
-  
-  typedef typename T1::elem_type eT;
-  
-  eT* out_mem = out.memptr();
-  
-  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
-  
-  if(prefer_at_accessor == false)
-    {
-    const uword n_elem  = out.n_elem;
-    
-    typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
-    typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1(+=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1(+=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1(+=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1(+=, *); }
-    }
-  else
-    {
-    const ProxyCube<T1>& P1 = x.P1;
-    const ProxyCube<T2>& P2 = x.P2;
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_3(+=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_3(+=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_3(+=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_3(+=, *); }
-    }
-  }
-
-
-
-template<typename eglue_type>
-template<typename T1, typename T2>
-arma_hot
-inline
-void
-eglue_core<eglue_type>::apply_inplace_minus(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword n_rows   = x.get_n_rows();
-  const uword n_cols   = x.get_n_cols();
-  const uword n_slices = x.get_n_slices();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "subtraction");
-  
-  typedef typename T1::elem_type eT;
-  
-  eT* out_mem = out.memptr();
-  
-  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
-  
-  if(prefer_at_accessor == false)
-    {
-    const uword n_elem  = out.n_elem;
-    
-    typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
-    typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1(-=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1(-=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1(-=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1(-=, *); }
-    }
-  else
-    {
-    const ProxyCube<T1>& P1 = x.P1;
-    const ProxyCube<T2>& P2 = x.P2;
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_3(-=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_3(-=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_3(-=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_3(-=, *); }
-    }
-  }
-
-
-
-template<typename eglue_type>
-template<typename T1, typename T2>
-arma_hot
-inline
-void
-eglue_core<eglue_type>::apply_inplace_schur(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword n_rows   = x.get_n_rows();
-  const uword n_cols   = x.get_n_cols();
-  const uword n_slices = x.get_n_slices();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise multiplication");
-  
-  typedef typename T1::elem_type eT;
-  
-  eT* out_mem = out.memptr();
-  
-  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
-  
-  if(prefer_at_accessor == false)
-    {
-    const uword n_elem  = out.n_elem;
-    
-    typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
-    typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1(*=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1(*=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1(*=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1(*=, *); }
-    }
-  else
-    {
-    const ProxyCube<T1>& P1 = x.P1;
-    const ProxyCube<T2>& P2 = x.P2;
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_3(*=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_3(*=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_3(*=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_3(*=, *); }
-    }
-  }
-
-
-
-template<typename eglue_type>
-template<typename T1, typename T2>
-arma_hot
-inline
-void
-eglue_core<eglue_type>::apply_inplace_div(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword n_rows   = x.get_n_rows();
-  const uword n_cols   = x.get_n_cols();
-  const uword n_slices = x.get_n_slices();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise division");
-  
-  typedef typename T1::elem_type eT;
-  
-  eT* out_mem = out.memptr();
-  
-  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
-  
-  if(prefer_at_accessor == false)
-    {
-    const uword n_elem  = out.n_elem;
-    
-    typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
-    typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1(/=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1(/=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1(/=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1(/=, *); }
-    }
-  else
-    {
-    const ProxyCube<T1>& P1 = x.P1;
-    const ProxyCube<T2>& P2 = x.P2;
-    
-         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_3(/=, +); }
-    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_3(/=, -); }
-    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_3(/=, /); }
-    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_3(/=, *); }
-    }
-  }
-
-
-
-#undef arma_applier_1
-#undef arma_applier_2
-#undef arma_applier_3
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/eop_aux.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,335 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup eop_aux
-//! @{
-
-
-
-template<typename eT>
-struct eop_aux_randu
-  {
-  arma_inline
-  operator eT ()
-    {
-    return eT(std::rand()) / eT(RAND_MAX);
-    }
-  };
-
-
-  
-template<typename T>
-struct eop_aux_randu< std::complex<T> >
-  {
-  arma_inline
-  operator std::complex<T> ()
-    {
-    return std::complex<T>( T(eop_aux_randu<T>()), T(eop_aux_randu<T>()) );
-    }
-  };
-
-
-
-template<typename eT>
-struct eop_aux_randn
-  {
-  // // rudimentary method, based on the central limit theorem
-  // // http://en.wikipedia.org/wiki/Central_limit_theorem
-  // inline
-  // operator eT () const
-  //   {
-  //   const uword N  = 12;  // N must be >= 12 and an even number
-  //   const uword N2 = N/2;
-  //   
-  //   eT acc = eT(0);
-  //   
-  //   for(uword i=0; i<N2; ++i)
-  //     {
-  //     const eT tmp1 = eT(std::rand()) / eT(RAND_MAX);
-  //     const eT tmp2 = eT(std::rand()) / eT(RAND_MAX);
-  //     acc += tmp1+tmp2;
-  //     }
-  //   
-  //   return acc - eT(N2);
-  //   }
-  
-  
-  // polar form of the Box-Muller transformation
-  // http://en.wikipedia.org/wiki/Box-Muller_transformation
-  // http://en.wikipedia.org/wiki/Marsaglia_polar_method
-  inline
-  operator eT () const
-    {
-    // make sure we are internally using at least floats
-    typedef typename promote_type<eT,float>::result eTp;
-    
-    eTp tmp1;
-    eTp tmp2;
-    eTp w;
-    
-    do
-      {
-      tmp1 = eTp(2) * eTp(std::rand()) / eTp(RAND_MAX) - eTp(1);
-      tmp2 = eTp(2) * eTp(std::rand()) / eTp(RAND_MAX) - eTp(1);
-      w = tmp1*tmp1 + tmp2*tmp2;
-      }
-    while ( w >= eTp(1) );
-    
-    return eT( tmp1 * std::sqrt( (eTp(-2) * std::log(w)) / w) );
-    }
-  
-  
-  // other methods:
-  // http://en.wikipedia.org/wiki/Ziggurat_algorithm
-  //
-  // Marsaglia and Tsang Ziggurat technique to transform from a uniform to a normal distribution.
-  // G. Marsaglia, W.W. Tsang.
-  // "Ziggurat method for generating random variables",
-  // J. Statistical Software, vol 5, 2000.
-  // http://www.jstatsoft.org/v05/i08/
-  };
-
-
-
-template<typename T>
-struct eop_aux_randn< std::complex<T> >
-  {
-  arma_inline
-  operator std::complex<T> () const
-    {
-    return std::complex<T>( T(eop_aux_randn<T>()), T(eop_aux_randn<T>()) );
-    }
-
-  };
-
-
-//! use of the SFINAE approach to work around compiler limitations
-//! http://en.wikipedia.org/wiki/SFINAE
-
-class eop_aux
-  {
-  public:
-  
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result    acos  (const eT x) { return eT( std::acos(double(x)) ); }
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result    asin  (const eT x) { return eT( std::asin(double(x)) ); }
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result    atan  (const eT x) { return eT( std::atan(double(x)) ); }
-  
-  template<typename eT> arma_inline static typename arma_float_only<eT>::result       acos  (const eT x) { return std::acos(x); }
-  template<typename eT> arma_inline static typename arma_float_only<eT>::result       asin  (const eT x) { return std::asin(x); }
-  template<typename eT> arma_inline static typename arma_float_only<eT>::result       atan  (const eT x) { return std::atan(x); }
-  
-  template<typename eT> arma_inline static typename arma_cx_only<eT>::result          acos  (const eT x) { return arma_acos(x); }
-  template<typename eT> arma_inline static typename arma_cx_only<eT>::result          asin  (const eT x) { return arma_asin(x); }
-  template<typename eT> arma_inline static typename arma_cx_only<eT>::result          atan  (const eT x) { return arma_atan(x); }
-  
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result    acosh (const eT x) { return eT( arma_acosh(double(x)) ); }
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result    asinh (const eT x) { return eT( arma_asinh(double(x)) ); }
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result    atanh (const eT x) { return eT( arma_atanh(double(x)) ); }
-  
-  template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result acosh (const eT x) { return arma_acosh(x); }
-  template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result asinh (const eT x) { return arma_asinh(x); }
-  template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result atanh (const eT x) { return arma_atanh(x); }
-  
-  template<typename eT> arma_inline static typename arma_not_cx<eT>::result conj(const eT               x) { return x;            }
-  template<typename  T> arma_inline static          std::complex<T>         conj(const std::complex<T>& x) { return std::conj(x); }
-  
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result sqrt  (const eT x) { return eT( std::sqrt (double(x)) ); }
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result log10 (const eT x) { return eT( std::log10(double(x)) ); }
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result log   (const eT x) { return eT( std::log  (double(x)) ); }
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result exp   (const eT x) { return eT( std::exp  (double(x)) ); }
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result cos   (const eT x) { return eT( std::cos  (double(x)) ); }
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result sin   (const eT x) { return eT( std::sin  (double(x)) ); }
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result tan   (const eT x) { return eT( std::tan  (double(x)) ); }
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result cosh  (const eT x) { return eT( std::cosh (double(x)) ); }
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result sinh  (const eT x) { return eT( std::sinh (double(x)) ); }
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result tanh  (const eT x) { return eT( std::tanh (double(x)) ); }
-  
-  template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result sqrt  (const eT x) { return std::sqrt (x); }
-  template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result log10 (const eT x) { return std::log10(x); }
-  template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result log   (const eT x) { return std::log  (x); }
-  template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result exp   (const eT x) { return std::exp  (x); }
-  template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result cos   (const eT x) { return std::cos  (x); }
-  template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result sin   (const eT x) { return std::sin  (x); }
-  template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result tan   (const eT x) { return std::tan  (x); }
-  template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result cosh  (const eT x) { return std::cosh (x); }
-  template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result sinh  (const eT x) { return std::sinh (x); }
-  template<typename eT> arma_inline static typename arma_float_or_cx_only<eT>::result tanh  (const eT x) { return std::tanh (x); }
-  
-  template<typename eT> arma_inline static typename arma_unsigned_integral_only<eT>::result neg (const eT x) { return  x; }
-  template<typename eT> arma_inline static typename arma_signed_only<eT>::result            neg (const eT x) { return -x; }
-  
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result floor(const eT  x) { return x;                                                }
-  template<typename eT> arma_inline static typename arma_float_only<eT>::result    floor(const eT  x) { return std::floor(x);                                    }
-  template<typename eT> arma_inline static typename arma_cx_only<eT>::result       floor(const eT& x) { return eT( std::floor(x.real()), std::floor(x.imag()) ); }
-  
-  template<typename eT> arma_inline static typename arma_integral_only<eT>::result  ceil(const eT  x) { return x;                                                }
-  template<typename eT> arma_inline static typename arma_float_only<eT>::result     ceil(const eT  x) { return std::ceil(x);                                     }
-  template<typename eT> arma_inline static typename arma_cx_only<eT>::result        ceil(const eT& x) { return eT( std::ceil(x.real()), std::ceil(x.imag()) );   }
-  
-  template<typename eT>
-  arma_inline
-  static
-  typename arma_integral_only<eT>::result
-  log2 (const eT x)
-    {
-    return eT( std::log(double(x))/ double(0.69314718055994530942) );
-    }
-  
-  
-  template<typename eT>
-  arma_inline
-  static
-  typename arma_float_or_cx_only<eT>::result
-  log2 (const eT x)
-    {
-    typedef typename get_pod_type<eT>::result T;
-    return std::log(x) / T(0.69314718055994530942);
-    }
-  
-  
-  template<typename eT>
-  arma_inline
-  static
-  typename arma_integral_only<eT>::result
-  exp10 (const eT x)
-    {
-    return eT( std::pow(double(10), double(x)) );
-    }
-  
-  
-  template<typename eT>
-  arma_inline
-  static
-  typename
-  arma_float_or_cx_only<eT>::result
-  exp10 (const eT x)
-    {
-    typedef typename get_pod_type<eT>::result T;
-    return std::pow( T(10), x);
-    }
-  
-  
-  template<typename eT>
-  arma_inline
-  static
-  typename arma_integral_only<eT>::result
-  exp2 (const eT x)
-    {
-    return eT( std::pow(double(2), double(x)) );
-    }
-  
-  
-  template<typename eT>
-  arma_inline
-  static
-  typename arma_float_or_cx_only<eT>::result
-  exp2 (const eT x)
-    {
-    typedef typename get_pod_type<eT>::result T;
-    return std::pow( T(2), x);
-    }
-  
-  
-  template<typename T1, typename T2>
-  arma_inline
-  static
-  typename arma_float_or_cx_only<T1>::result
-  pow(const T1 base, const T2 exponent)
-    {
-    return std::pow(base, exponent);
-    }
-  
-  
-  
-  template<typename T1, typename T2>
-  arma_inline
-  static
-  typename arma_integral_only<T1>::result
-  pow(const T1 base, const T2 exponent)
-    {
-    return T1( std::pow( double(base), double(exponent) ) );
-    }
-  
-  
-  
-  template<typename eT>
-  arma_inline
-  static
-  typename arma_integral_only<eT>::result
-  direct_eps(const eT)
-    {
-    return eT(0);
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  static
-  typename arma_float_only<eT>::result
-  direct_eps(const eT x)
-    {
-    //arma_extra_debug_sigprint();
-    
-    // acording to IEEE Standard for Floating-Point Arithmetic (IEEE 754)
-    // the mantissa length for double is 53 bits = std::numeric_limits<double>::digits
-    // the mantissa length for float  is 24 bits = std::numeric_limits<float >::digits
-    
-    //return std::pow( std::numeric_limits<eT>::radix, (std::floor(std::log10(std::abs(x))/std::log10(std::numeric_limits<eT>::radix))-(std::numeric_limits<eT>::digits-1)) );
-    
-    const eT radix_eT     = eT(std::numeric_limits<eT>::radix);
-    const eT digits_m1_eT = eT(std::numeric_limits<eT>::digits - 1);
-    
-    // return std::pow( radix_eT, eT(std::floor(std::log10(std::abs(x))/std::log10(radix_eT)) - digits_m1_eT) );
-    return eop_aux::pow( radix_eT, eT(std::floor(std::log10(std::abs(x))/std::log10(radix_eT)) - digits_m1_eT) );
-    }
-  
-  
-  
-  template<typename T>
-  inline
-  static
-  typename arma_float_only<T>::result
-  direct_eps(const std::complex<T> x)
-    {
-    //arma_extra_debug_sigprint();
-    
-    //return std::pow( std::numeric_limits<T>::radix, (std::floor(std::log10(std::abs(x))/std::log10(std::numeric_limits<T>::radix))-(std::numeric_limits<T>::digits-1)) );
-    
-    const T radix_T     = T(std::numeric_limits<T>::radix);
-    const T digits_m1_T = T(std::numeric_limits<T>::digits - 1);
-    
-    return std::pow( radix_T, T(std::floor(std::log10(std::abs(x))/std::log10(radix_T)) - digits_m1_T) );
-    }
-  
-  
-  
-  //! work around a bug in GCC 4.4
-  template<typename eT> arma_inline static
-  typename arma_unsigned_integral_only<eT>::result arma_abs(const eT x)              { return x;           }
-  
-  template<typename eT> arma_inline static
-  typename arma_signed_integral_only<eT>::result   arma_abs(const eT x)              { return std::abs(x); }
-  
-  template<typename eT> arma_inline static
-  typename arma_float_only<eT>::result             arma_abs(const eT x)              { return std::abs(x); }
-  
-  template<typename T> arma_inline static
-  typename arma_float_only<T>::result              arma_abs(const std::complex<T> x) { return std::abs(x); }
-  
-  };
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/eop_core_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup eop_core
-//! @{
-
-
-
-template<typename eop_type>
-class eop_core
-  {
-  public:
-  
-  // matrices
-  
-  template<typename T1> arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x);
-  
-  template<typename T1> arma_hot inline static void apply_inplace_plus (Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x);
-  template<typename T1> arma_hot inline static void apply_inplace_minus(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x);
-  template<typename T1> arma_hot inline static void apply_inplace_schur(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x);
-  template<typename T1> arma_hot inline static void apply_inplace_div  (Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x);
-  
-  
-  // cubes
-  
-  template<typename T1> arma_hot inline static void apply(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x);
-  
-  template<typename T1> arma_hot inline static void apply_inplace_plus (Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x);
-  template<typename T1> arma_hot inline static void apply_inplace_minus(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x);
-  template<typename T1> arma_hot inline static void apply_inplace_schur(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x);
-  template<typename T1> arma_hot inline static void apply_inplace_div  (Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x);
-  
-  
-  // common
-  
-  template<typename eT> arma_hot arma_pure arma_inline static eT process(const eT val, const eT k);
-  };
-
-
-
-class eop_neg               : public eop_core<eop_neg>               {};
-class eop_scalar_plus       : public eop_core<eop_scalar_plus>       {};
-class eop_scalar_minus_pre  : public eop_core<eop_scalar_minus_pre>  {};
-class eop_scalar_minus_post : public eop_core<eop_scalar_minus_post> {};
-class eop_scalar_times      : public eop_core<eop_scalar_times>      {};
-class eop_scalar_div_pre    : public eop_core<eop_scalar_div_pre>    {};
-class eop_scalar_div_post   : public eop_core<eop_scalar_div_post>   {};
-class eop_square            : public eop_core<eop_square>            {};
-class eop_sqrt              : public eop_core<eop_sqrt>              {};
-class eop_log               : public eop_core<eop_log>               {};
-class eop_log2              : public eop_core<eop_log2>              {};
-class eop_log10             : public eop_core<eop_log10>             {};
-class eop_trunc_log         : public eop_core<eop_trunc_log>         {};
-class eop_exp               : public eop_core<eop_exp>               {};
-class eop_exp2              : public eop_core<eop_exp2>              {};
-class eop_exp10             : public eop_core<eop_exp10>             {};
-class eop_trunc_exp         : public eop_core<eop_trunc_exp>         {};
-class eop_cos               : public eop_core<eop_cos>               {};
-class eop_sin               : public eop_core<eop_sin>               {};
-class eop_tan               : public eop_core<eop_tan>               {};
-class eop_acos              : public eop_core<eop_acos>              {};
-class eop_asin              : public eop_core<eop_asin>              {};
-class eop_atan              : public eop_core<eop_atan>              {};
-class eop_cosh              : public eop_core<eop_cosh>              {};
-class eop_sinh              : public eop_core<eop_sinh>              {};
-class eop_tanh              : public eop_core<eop_tanh>              {};
-class eop_acosh             : public eop_core<eop_acosh>             {};
-class eop_asinh             : public eop_core<eop_asinh>             {};
-class eop_atanh             : public eop_core<eop_atanh>             {};
-class eop_eps               : public eop_core<eop_eps>               {};
-class eop_abs               : public eop_core<eop_abs>               {};
-class eop_conj              : public eop_core<eop_conj>              {};
-class eop_pow               : public eop_core<eop_pow>               {};
-class eop_floor             : public eop_core<eop_floor>             {};
-class eop_ceil              : public eop_core<eop_ceil>              {};
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/eop_core_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,629 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup eop_core
-//! @{
-
-
-#undef arma_applier_1
-#undef arma_applier_2
-#undef arma_applier_3
-#undef operatorA
-
-#define arma_applier_1(operatorA) \
-  {\
-  uword i,j;\
-  \
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)\
-    {\
-    eT tmp_i = P[i];\
-    eT tmp_j = P[j];\
-    \
-    tmp_i = eop_core<eop_type>::process(tmp_i, k);\
-    tmp_j = eop_core<eop_type>::process(tmp_j, k);\
-    \
-    out_mem[i] operatorA tmp_i;\
-    out_mem[j] operatorA tmp_j;\
-    }\
-  \
-  if(i < n_elem)\
-    {\
-    out_mem[i] operatorA eop_core<eop_type>::process(P[i], k);\
-    }\
-  }
-
-
-#define arma_applier_2(operatorA) \
-  {\
-  uword count = 0;\
-  \
-  for(uword col=0; col<n_cols; ++col)\
-    {\
-    uword i,j;\
-    \
-    for(i=0, j=1; j<n_rows; i+=2, j+=2, count+=2)\
-      {\
-      eT tmp_i = P.at(i,col);\
-      eT tmp_j = P.at(j,col);\
-      \
-      tmp_i = eop_core<eop_type>::process(tmp_i, k);\
-      tmp_j = eop_core<eop_type>::process(tmp_j, k);\
-      \
-      out_mem[count  ] operatorA tmp_i;\
-      out_mem[count+1] operatorA tmp_j;\
-      }\
-    \
-    if(i < n_rows)\
-      {\
-      out_mem[count] operatorA eop_core<eop_type>::process(P.at(i,col), k);\
-      ++count;\
-      }\
-    }\
-  }
-
-
-
-#define arma_applier_3(operatorA) \
-  {\
-  uword count = 0;\
-  \
-  for(uword slice=0; slice<n_slices; ++slice)\
-    {\
-    for(uword col=0; col<n_cols; ++col)\
-      {\
-      uword i,j;\
-      \
-      for(i=0, j=1; j<n_rows; i+=2, j+=2, count+=2)\
-        {\
-        eT tmp_i = P.at(i,col,slice);\
-        eT tmp_j = P.at(j,col,slice);\
-        \
-        tmp_i = eop_core<eop_type>::process(tmp_i, k);\
-        tmp_j = eop_core<eop_type>::process(tmp_j, k);\
-        \
-        out_mem[count  ] operatorA tmp_i;\
-        out_mem[count+1] operatorA tmp_j;\
-        }\
-      \
-      if(i < n_rows)\
-        {\
-        out_mem[count] operatorA eop_core<eop_type>::process(P.at(i,col,slice), k);\
-        ++count;\
-        }\
-      }\
-    }\
-  }
-
-
-
-//
-// matrices
-
-
-
-template<typename eop_type>
-template<typename T1>
-arma_hot
-inline
-void
-eop_core<eop_type>::apply(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const uword n_rows = out.n_rows;
-  const uword n_cols = out.n_cols;
-  const uword n_elem = out.n_elem;
-  
-  // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing;
-  // size setting and alias checking is done by either the Mat contructor or operator=()
-  
-  const eT  k       = x.aux;
-        eT* out_mem = out.memptr();
-  
-  if(Proxy<T1>::prefer_at_accessor == false)
-    {
-    typename Proxy<T1>::ea_type P = x.P.get_ea();
-    
-    arma_applier_1(=);
-    }
-  else
-    {
-    const Proxy<T1>& P = x.P;
-    
-    arma_applier_2(=);
-    }
-  }
-
-
-
-template<typename eop_type>
-template<typename T1>
-arma_hot
-inline
-void
-eop_core<eop_type>::apply_inplace_plus(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const uword n_rows = x.get_n_rows();
-  const uword n_cols = x.get_n_cols();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "addition");
-  
-        eT*   out_mem = out.memptr();
-  const uword n_elem  = out.n_elem;
-  
-  const eT k = x.aux;
-  
-  if(Proxy<T1>::prefer_at_accessor == false)
-    {
-    typename Proxy<T1>::ea_type P = x.P.get_ea();
-    
-    arma_applier_1(+=);
-    }
-  else
-    {
-    const Proxy<T1>& P = x.P;
-    
-    arma_applier_2(+=);
-    }
-  }
-
-
-
-template<typename eop_type>
-template<typename T1>
-arma_hot
-inline
-void
-eop_core<eop_type>::apply_inplace_minus(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const uword n_rows = x.get_n_rows();
-  const uword n_cols = x.get_n_cols();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "subtraction");
-  
-        eT*   out_mem = out.memptr();
-  const uword n_elem  = out.n_elem;
-  
-  const eT k = x.aux;
-  
-  if(Proxy<T1>::prefer_at_accessor == false)
-    {
-    typename Proxy<T1>::ea_type P = x.P.get_ea();
-    
-    arma_applier_1(-=);
-    }
-  else
-    {
-    const Proxy<T1>& P = x.P;
-    
-    arma_applier_2(-=);
-    }
-  }
-
-
-
-template<typename eop_type>
-template<typename T1>
-arma_hot
-inline
-void
-eop_core<eop_type>::apply_inplace_schur(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const uword n_rows = x.get_n_rows();
-  const uword n_cols = x.get_n_cols();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise multiplication");
-  
-        eT*   out_mem = out.memptr();
-  const uword n_elem  = out.n_elem;
-  
-  const eT k = x.aux;
-  
-  if(Proxy<T1>::prefer_at_accessor == false)
-    {
-    typename Proxy<T1>::ea_type P = x.P.get_ea();
-    
-    arma_applier_1(*=);
-    }
-  else
-    {
-    const Proxy<T1>& P = x.P;
-    
-    arma_applier_2(*=);
-    }
-  }
-
-
-
-template<typename eop_type>
-template<typename T1>
-arma_hot
-inline
-void
-eop_core<eop_type>::apply_inplace_div(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const uword n_rows = x.get_n_rows();
-  const uword n_cols = x.get_n_cols();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise division");
-  
-        eT* out_mem = out.memptr();
-  const uword n_elem  = out.n_elem;
-  
-  const eT k = x.aux;
-  
-  if(Proxy<T1>::prefer_at_accessor == false)
-    {
-    typename Proxy<T1>::ea_type P = x.P.get_ea();
-    
-    arma_applier_1(/=);
-    }
-  else
-    {
-    const Proxy<T1>& P = x.P;
-    
-    arma_applier_2(/=);
-    }
-  }
-
-
-
-//
-// cubes
-
-
-
-template<typename eop_type>
-template<typename T1>
-arma_hot
-inline
-void
-eop_core<eop_type>::apply(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const uword n_rows   = out.n_rows;
-  const uword n_cols   = out.n_cols;
-  const uword n_slices = out.n_slices;
-  const uword n_elem   = out.n_elem;
-  
-  // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing;
-  // size setting and alias checking is done by either the Mat contructor or operator=()
-  
-  const eT  k       = x.aux;
-        eT* out_mem = out.memptr();
-  
-  if(ProxyCube<T1>::prefer_at_accessor == false)
-    {
-    typename ProxyCube<T1>::ea_type P = x.P.get_ea();
-    
-    arma_applier_1(=);
-    }
-  else
-    {
-    const ProxyCube<T1>& P = x.P;
-    
-    arma_applier_3(=);
-    }
-  }
-
-
-
-template<typename eop_type>
-template<typename T1>
-arma_hot
-inline
-void
-eop_core<eop_type>::apply_inplace_plus(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const uword n_rows   = x.get_n_rows();
-  const uword n_cols   = x.get_n_cols();
-  const uword n_slices = x.get_n_slices();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "addition");
-  
-        eT*   out_mem = out.memptr();
-  const uword n_elem  = out.n_elem;
-  
-  const eT k = x.aux;
-  
-  if(ProxyCube<T1>::prefer_at_accessor == false)
-    {
-    typename ProxyCube<T1>::ea_type P = x.P.get_ea();
-  
-    arma_applier_1(+=);
-    }
-  else
-    {
-    const ProxyCube<T1>& P = x.P;
-    
-    arma_applier_3(+=);
-    }
-  }
-
-
-
-template<typename eop_type>
-template<typename T1>
-arma_hot
-inline
-void
-eop_core<eop_type>::apply_inplace_minus(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const uword n_rows   = x.get_n_rows();
-  const uword n_cols   = x.get_n_cols();
-  const uword n_slices = x.get_n_slices();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "subtraction");
-  
-        eT*   out_mem = out.memptr();
-  const uword n_elem  = out.n_elem;
-  
-  const eT k = x.aux;
-  
-  if(ProxyCube<T1>::prefer_at_accessor == false)
-    {
-    typename ProxyCube<T1>::ea_type P = x.P.get_ea();
-  
-    arma_applier_1(-=);
-    }
-  else
-    {
-    const ProxyCube<T1>& P = x.P;
-    
-    arma_applier_3(-=);
-    }
-  }
-
-
-
-template<typename eop_type>
-template<typename T1>
-arma_hot
-inline
-void
-eop_core<eop_type>::apply_inplace_schur(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const uword n_rows   = x.get_n_rows();
-  const uword n_cols   = x.get_n_cols();
-  const uword n_slices = x.get_n_slices();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise multiplication");
-  
-        eT*   out_mem = out.memptr();
-  const uword n_elem  = out.n_elem;
-  
-  const eT k = x.aux;
-  
-  if(ProxyCube<T1>::prefer_at_accessor == false)
-    {
-    typename ProxyCube<T1>::ea_type P = x.P.get_ea();
-  
-    arma_applier_1(*=);
-    }
-  else
-    {
-    const ProxyCube<T1>& P = x.P;
-    
-    arma_applier_3(*=);
-    }
-  }
-
-
-
-template<typename eop_type>
-template<typename T1>
-arma_hot
-inline
-void
-eop_core<eop_type>::apply_inplace_div(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const uword n_rows   = x.get_n_rows();
-  const uword n_cols   = x.get_n_cols();
-  const uword n_slices = x.get_n_slices();
-  
-  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise division");
-  
-        eT* out_mem = out.memptr();
-  const uword n_elem  = out.n_elem;
-    
-  const eT k = x.aux;
-  
-  if(ProxyCube<T1>::prefer_at_accessor == false)
-    {
-    typename ProxyCube<T1>::ea_type P = x.P.get_ea();
-  
-    arma_applier_1(/=);
-    }
-  else
-    {
-    const ProxyCube<T1>& P = x.P;
-    
-    arma_applier_3(/=);
-    }
-  }
-
-
-
-//
-// common
-
-
-
-template<typename eop_type>
-template<typename eT>
-arma_hot
-arma_pure
-arma_inline
-eT
-eop_core<eop_type>::process(const eT val, const eT k)
-  {
-  arma_ignore(val);
-  arma_ignore(k);
-  
-  arma_stop("eop_core::process(): unhandled eop_type");
-  return eT(0);
-  }
-
-
-
-template<> template<typename eT> arma_hot arma_const arma_inline eT
-eop_core<eop_scalar_plus      >::process(const eT val, const eT k) { return val + k;                  }
-
-template<> template<typename eT> arma_hot arma_const arma_inline eT
-eop_core<eop_scalar_minus_pre >::process(const eT val, const eT k) { return k - val;                  }
-
-template<> template<typename eT> arma_hot arma_const arma_inline eT
-eop_core<eop_scalar_minus_post>::process(const eT val, const eT k) { return val - k;                  }
-
-template<> template<typename eT> arma_hot arma_const arma_inline eT
-eop_core<eop_scalar_times     >::process(const eT val, const eT k) { return val * k;                  }
-
-template<> template<typename eT> arma_hot arma_const arma_inline eT
-eop_core<eop_scalar_div_pre   >::process(const eT val, const eT k) { return k / val;                  }
-
-template<> template<typename eT> arma_hot arma_const arma_inline eT
-eop_core<eop_scalar_div_post  >::process(const eT val, const eT k) { return val / k;                  }
-
-template<> template<typename eT> arma_hot arma_const arma_inline eT
-eop_core<eop_square           >::process(const eT val, const eT  ) { return val*val;                  }
-
-template<> template<typename eT> arma_hot arma_const arma_inline eT
-eop_core<eop_neg              >::process(const eT val, const eT  ) { return eop_aux::neg(val);        }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_sqrt             >::process(const eT val, const eT  ) { return eop_aux::sqrt(val);       }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_log              >::process(const eT val, const eT  ) { return eop_aux::log(val);        }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_log2             >::process(const eT val, const eT  ) { return eop_aux::log2(val);       }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_log10            >::process(const eT val, const eT  ) { return eop_aux::log10(val);      }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_trunc_log        >::process(const eT val, const eT  ) { return    arma::trunc_log(val);  }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_exp              >::process(const eT val, const eT  ) { return eop_aux::exp(val);        }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_exp2             >::process(const eT val, const eT  ) { return eop_aux::exp2(val);       }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_exp10            >::process(const eT val, const eT  ) { return eop_aux::exp10(val);      }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_trunc_exp        >::process(const eT val, const eT  ) { return    arma::trunc_exp(val);  }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_cos              >::process(const eT val, const eT  ) { return eop_aux::cos(val);        }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_sin              >::process(const eT val, const eT  ) { return eop_aux::sin(val);        }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_tan              >::process(const eT val, const eT  ) { return eop_aux::tan(val);        }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_acos             >::process(const eT val, const eT  ) { return eop_aux::acos(val);       }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_asin             >::process(const eT val, const eT  ) { return eop_aux::asin(val);       }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_atan             >::process(const eT val, const eT  ) { return eop_aux::atan(val);       }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_cosh             >::process(const eT val, const eT  ) { return eop_aux::cosh(val);       }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_sinh             >::process(const eT val, const eT  ) { return eop_aux::sinh(val);       }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_tanh             >::process(const eT val, const eT  ) { return eop_aux::tanh(val);       }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_acosh            >::process(const eT val, const eT  ) { return eop_aux::acosh(val);      }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_asinh            >::process(const eT val, const eT  ) { return eop_aux::asinh(val);      }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_atanh            >::process(const eT val, const eT  ) { return eop_aux::atanh(val);      }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_eps              >::process(const eT val, const eT  ) { return eop_aux::direct_eps(val); }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_abs              >::process(const eT val, const eT  ) { return eop_aux::arma_abs(val);   }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_conj             >::process(const eT val, const eT  ) { return eop_aux::conj(val);       }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_pow              >::process(const eT val, const eT k) { return eop_aux::pow(val, k);     }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_floor            >::process(const eT val, const eT  ) { return eop_aux::floor(val);      }
-
-template<> template<typename eT> arma_hot arma_pure arma_inline eT
-eop_core<eop_ceil             >::process(const eT val, const eT  ) { return eop_aux::ceil(val);       }
-
-
-
-#undef arma_applier_1
-#undef arma_applier_2
-#undef arma_applier_3
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/field_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,261 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Ian Cullinan
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup field
-//! @{
-
-
-
-struct field_prealloc_n_elem
-  {
-  static const uword val = 16;
-  };
-
-
-
-//! A lightweight 2D container for abitrary objects
-//! (the objects must have a copy constructor)
-
-template<typename oT>
-class field
-  {
-  public:
-  
-  typedef oT object_type;
-  
-  const uword n_rows;     //!< number of rows in the field (read-only)
-  const uword n_cols;     //!< number of columns in the field (read-only)
-  const uword n_elem;     //!< number of elements in the field (read-only)
-  
-  
-  private:
-  
-  arma_aligned oT** mem;             //!< pointer to memory used by the object
-  arma_aligned oT*  mem_local[ field_prealloc_n_elem::val ];
-  //!< Internal memory, to avoid calling the 'new' operator for small amounts of memory
-  
-  
-  public:
-  
-  inline ~field();
-  inline  field();
-  
-  inline                  field(const field& x);
-  inline const field& operator=(const field& x);
-  
-  inline                  field(const subview_field<oT>& x);
-  inline const field& operator=(const subview_field<oT>& x);
-  
-  inline explicit field(const uword n_elem_in);
-  inline          field(const uword n_rows_in, const uword n_cols_in);
-  
-  inline void  set_size(const uword n_obj_in);
-  inline void  set_size(const uword n_rows_in, const uword n_cols_in);
-  
-  template<typename oT2>
-  inline void copy_size(const field<oT2>& x);
-  
-  arma_inline       oT& operator[](const uword i);
-  arma_inline const oT& operator[](const uword i) const;
-  
-  arma_inline       oT&         at(const uword i);
-  arma_inline const oT&         at(const uword i) const;
-  
-  arma_inline       oT& operator()(const uword i);
-  arma_inline const oT& operator()(const uword i) const;
-  
-  arma_inline       oT&         at(const uword row, const uword col);
-  arma_inline const oT&         at(const uword row, const uword col) const;
-  
-  arma_inline       oT& operator()(const uword row, const uword col);
-  arma_inline const oT& operator()(const uword row, const uword col) const;
-  
-  inline field_injector<field> operator<<(const oT& val);
-  inline field_injector<field> operator<<(const injector_end_of_row& x);
-  
-  
-  inline       subview_field<oT> row(const uword row_num);
-  inline const subview_field<oT> row(const uword row_num) const;
-  
-  inline       subview_field<oT> col(const uword col_num);
-  inline const subview_field<oT> col(const uword col_num) const;
-  
-  inline       subview_field<oT> rows(const uword in_row1, const uword in_row2);
-  inline const subview_field<oT> rows(const uword in_row1, const uword in_row2) const;
-  
-  inline       subview_field<oT> cols(const uword in_col1, const uword in_col2);
-  inline const subview_field<oT> cols(const uword in_col1, const uword in_col2) const;
-  
-  inline       subview_field<oT> subfield(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2);
-  inline const subview_field<oT> subfield(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const;
-  
-  inline       subview_field<oT> subfield  (const span& row_span, const span& col_span);
-  inline const subview_field<oT> subfield  (const span& row_span, const span& col_span) const;
-  
-  inline       subview_field<oT> operator()(const span& row_span, const span& col_span);
-  inline const subview_field<oT> operator()(const span& row_span, const span& col_span) const;
-  
-  
-  inline void print(const std::string extra_text = "") const;
-  inline void print(std::ostream& user_stream, const std::string extra_text = "") const;
-  
-  inline void fill(const oT& x);
-  
-  inline void reset();
-  inline void reset_objects();
-  
-  arma_inline bool is_empty() const;
-  
-  arma_inline arma_warn_unused bool in_range(const uword   i) const;
-  arma_inline arma_warn_unused bool in_range(const span& x) const;
-  
-  arma_inline arma_warn_unused bool in_range(const uword   in_row,   const uword   in_col  ) const;
-  arma_inline arma_warn_unused bool in_range(const span& row_span, const uword   in_col  ) const;
-  arma_inline arma_warn_unused bool in_range(const uword   in_row,   const span& col_span) const;
-  arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span) const;
-  
-  inline bool save(const std::string   name, const file_type type = arma_binary, const bool print_status = true) const;
-  inline bool save(      std::ostream& os,   const file_type type = arma_binary, const bool print_status = true) const;
-  
-  inline bool load(const std::string   name, const file_type type = auto_detect, const bool print_status = true);
-  inline bool load(      std::istream& is,   const file_type type = auto_detect, const bool print_status = true);
-  
-  
-  inline bool quiet_save(const std::string   name, const file_type type = arma_binary) const;
-  inline bool quiet_save(      std::ostream& os,   const file_type type = arma_binary) const;
-  
-  inline bool quiet_load(const std::string   name, const file_type type = auto_detect);
-  inline bool quiet_load(      std::istream& is,   const file_type type = auto_detect);
-  
-  
-  // iterators
-  
-  class iterator
-    {
-    public:
-    
-    inline iterator(field<oT>& in_M, const bool at_end = false);
-    
-    inline oT& operator* ();
-    
-    inline iterator& operator++();
-    inline void      operator++(int);
-    
-    inline iterator& operator--();
-    inline void      operator--(int);
-    
-    inline bool operator!=(const iterator& X) const;
-    inline bool operator==(const iterator& X) const;
-    
-    arma_aligned field<oT>& M;
-    arma_aligned uword        i;
-    };
-  
-  
-  class const_iterator
-    {
-    public:
-    
-    const_iterator(const field<oT>& in_M, const bool at_end = false);
-    const_iterator(const iterator& X);
-    
-    inline const oT& operator*() const;
-    
-    inline const_iterator& operator++();
-    inline void            operator++(int);
-    
-    inline const_iterator& operator--();
-    inline void            operator--(int);
-    
-    inline bool operator!=(const const_iterator& X) const;
-    inline bool operator==(const const_iterator& X) const;
-    
-    arma_aligned const field<oT>& M;
-    arma_aligned       uword        i;
-    };
-  
-  inline       iterator begin();
-  inline const_iterator begin() const;
-  
-  inline       iterator end();
-  inline const_iterator end()   const;
-  
-  
-  private:
-  
-  inline void init(const field<oT>& x);
-  inline void init(const uword n_rows_in, const uword n_cols_in);
-  
-  inline void delete_objects();
-  inline void create_objects();
-  
-  friend class field_aux;
-  friend class subview_field<oT>;
-  
-  
-  public:
-  
-  #ifdef ARMA_EXTRA_FIELD_PROTO
-    #include ARMA_INCFILE_WRAP(ARMA_EXTRA_FIELD_PROTO)
-  #endif
-  };
-
-
-
-class field_aux
-  {
-  public:
-  
-  template<typename oT> inline static void reset_objects(field< oT >& x);
-  template<typename eT> inline static void reset_objects(field< Mat<eT> >& x);
-  template<typename eT> inline static void reset_objects(field< Col<eT> >& x);
-  template<typename eT> inline static void reset_objects(field< Row<eT> >& x);
-  template<typename eT> inline static void reset_objects(field< Cube<eT> >& x);
-                        inline static void reset_objects(field< std::string >& x);
-  
-  
-  template<typename oT> inline static bool save(const field< oT >& x,       const std::string& name, const file_type type, std::string& err_msg);
-  template<typename oT> inline static bool save(const field< oT >& x,       std::ostream& os,        const file_type type, std::string& err_msg);
-  template<typename oT> inline static bool load(      field< oT >& x,       const std::string& name, const file_type type, std::string& err_msg);
-  template<typename oT> inline static bool load(      field< oT >& x,       std::istream& is,        const file_type type, std::string& err_msg);
-
-  template<typename eT> inline static bool save(const field< Mat<eT> >& x,  const std::string& name, const file_type type, std::string& err_msg);
-  template<typename eT> inline static bool save(const field< Mat<eT> >& x,  std::ostream& os,        const file_type type, std::string& err_msg);
-  template<typename eT> inline static bool load(      field< Mat<eT> >& x,  const std::string& name, const file_type type, std::string& err_msg);
-  template<typename eT> inline static bool load(      field< Mat<eT> >& x,  std::istream& is,        const file_type type, std::string& err_msg);
-  
-  template<typename eT> inline static bool save(const field< Col<eT> >& x,  const std::string& name, const file_type type, std::string& err_msg);
-  template<typename eT> inline static bool save(const field< Col<eT> >& x,  std::ostream& os,        const file_type type, std::string& err_msg);
-  template<typename eT> inline static bool load(      field< Col<eT> >& x,  const std::string& name, const file_type type, std::string& err_msg);
-  template<typename eT> inline static bool load(      field< Col<eT> >& x,  std::istream& is,        const file_type type, std::string& err_msg);
-  
-  template<typename eT> inline static bool save(const field< Row<eT> >& x,  const std::string& name, const file_type type, std::string& err_msg);
-  template<typename eT> inline static bool save(const field< Row<eT> >& x,  std::ostream& os,        const file_type type, std::string& err_msg);
-  template<typename eT> inline static bool load(      field< Row<eT> >& x,  const std::string& name, const file_type type, std::string& err_msg);
-  template<typename eT> inline static bool load(      field< Row<eT> >& x,  std::istream& is,        const file_type type, std::string& err_msg);
-
-  template<typename eT> inline static bool save(const field< Cube<eT> >& x, const std::string& name, const file_type type, std::string& err_msg);
-  template<typename eT> inline static bool save(const field< Cube<eT> >& x, std::ostream& os,        const file_type type, std::string& err_msg);
-  template<typename eT> inline static bool load(      field< Cube<eT> >& x, const std::string& name, const file_type type, std::string& err_msg);
-  template<typename eT> inline static bool load(      field< Cube<eT> >& x, std::istream& is,        const file_type type, std::string& err_msg);
-  
-  inline static bool save(const field< std::string >& x, const std::string& name, const file_type type, std::string& err_msg);
-  inline static bool save(const field< std::string >& x, std::ostream& os,        const file_type type, std::string& err_msg);
-  inline static bool load(      field< std::string >& x, const std::string& name, const file_type type, std::string& err_msg);
-  inline static bool load(      field< std::string >& x, std::istream& is,        const file_type type, std::string& err_msg);
-  
-  };
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/field_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2008 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Ian Cullinan
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup field
-//! @{
-
-
-template<typename oT>
-inline
-field<oT>::~field()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  delete_objects();
-  
-  if(n_elem > sizeof(mem_local)/sizeof(oT*) )
-    {
-    delete [] mem;
-    }
-  
-  if(arma_config::debug == true)
-    {
-    // try to expose buggy user code that accesses deleted objects
-    access::rw(n_rows) = 0;
-    access::rw(n_cols) = 0;
-    access::rw(n_elem) = 0;
-    mem = 0;
-    }
-  }
-
-
-
-template<typename oT>
-inline
-field<oT>::field()
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , mem(0)
-  {
-  arma_extra_debug_sigprint_this(this);
-  }
-
-
-
-//! construct a field from a given field
-template<typename oT>
-inline
-field<oT>::field(const field& x)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , mem(0)
-  {
-  arma_extra_debug_sigprint(arma_boost::format("this = %x   x = %x") % this % &x);
-  
-  init(x);
-  }
-
-
-
-//! construct a field from a given field
-template<typename oT>
-inline
-const field<oT>&
-field<oT>::operator=(const field& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  init(x);
-  return *this;
-  }
-
-
-
-//! construct a field from subview_field (e.g. construct a field from a delayed subfield operation)
-template<typename oT>
-inline
-field<oT>::field(const subview_field<oT>& X)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , mem(0)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  this->operator=(X);
-  }
-
-
-
-//! construct a field from subview_field (e.g. construct a field from a delayed subfield operation)
-template<typename oT>
-inline
-const field<oT>&
-field<oT>::operator=(const subview_field<oT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_field<oT>::extract(*this, X);
-  return *this;
-  }
-
-
-
-//! construct the field with the specified number of elements,
-//! assuming a column-major layout
-template<typename oT>
-inline
-field<oT>::field(const uword n_elem_in)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , mem(0)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init(n_elem_in, 1);
-  }
-
-
-
-//! construct the field with the specified dimensions
-template<typename oT>
-inline
-field<oT>::field(const uword n_rows_in, const uword n_cols_in)
-  : n_rows(0)
-  , n_cols(0)
-  , n_elem(0)
-  , mem(0)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init(n_rows_in, n_cols_in);
-  }
-
-
-
-//! change the field to have the specified number of elements,
-//! assuming a column-major layout (data is not preserved)
-template<typename oT>
-inline
-void
-field<oT>::set_size(const uword n_elem_in)
-  {
-  arma_extra_debug_sigprint(arma_boost::format("n_elem_in = %d") % n_elem_in);
-  
-  init(n_elem_in, 1);
-  }
-
-
-
-//! change the field to have the specified dimensions (data is not preserved)
-template<typename oT>
-inline
-void
-field<oT>::set_size(const uword n_rows_in, const uword n_cols_in)
-  {
-  arma_extra_debug_sigprint(arma_boost::format("n_rows_in = %d, n_cols_in = %d") % n_rows_in % n_cols_in);
-  
-  init(n_rows_in, n_cols_in);
-  }
-
-
-
-//! change the field to have the specified dimensions (data is not preserved)
-template<typename oT>
-template<typename oT2>
-inline
-void
-field<oT>::copy_size(const field<oT2>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  init(x.n_rows, x.n_cols);
-  }
-
-
-
-//! linear element accessor (treats the field as a vector); no bounds check
-template<typename oT>
-arma_inline
-oT&
-field<oT>::operator[] (const uword i)
-  {
-  return (*mem[i]);
-  }
-  
-  
-  
-//! linear element accessor (treats the field as a vector); no bounds check
-template<typename oT>
-arma_inline
-const oT&
-field<oT>::operator[] (const uword i) const
-  {
-  return (*mem[i]);
-  }
-
-
-
-//! linear element accessor (treats the field as a vector); no bounds check
-template<typename oT>
-arma_inline
-oT&
-field<oT>::at(const uword i)
-  {
-  return (*mem[i]);
-  }
-  
-  
-  
-//! linear element accessor (treats the field as a vector); no bounds check
-template<typename oT>
-arma_inline
-const oT&
-field<oT>::at(const uword i) const
-  {
-  return (*mem[i]);
-  }
-
-
-
-//! linear element accessor (treats the field as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
-template<typename oT>
-arma_inline
-oT&
-field<oT>::operator() (const uword i)
-  {
-  arma_debug_check( (i >= n_elem), "field::operator(): index out of bounds");
-  return (*mem[i]);
-  }
-  
-  
-  
-//! linear element accessor (treats the field as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
-template<typename oT>
-arma_inline
-const oT&
-field<oT>::operator() (const uword i) const
-  {
-  arma_debug_check( (i >= n_elem), "field::operator(): index out of bounds");
-  return (*mem[i]);
-  }
-
-
-
-//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
-template<typename oT>
-arma_inline
-oT&
-field<oT>::operator() (const uword in_row, const uword in_col)
-  {
-  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "field::operator(): index out of bounds");
-  return (*mem[in_row + in_col*n_rows]);
-  }
-
-
-
-//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
-template<typename oT>
-arma_inline
-const oT&
-field<oT>::operator() (const uword in_row, const uword in_col) const
-  {
-  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "field::operator(): index out of bounds");
-  return (*mem[in_row + in_col*n_rows]);
-  }
-
-
-
-//! element accessor; no bounds check
-template<typename oT>
-arma_inline
-oT&
-field<oT>::at(const uword in_row, const uword in_col)
-  {
-  return (*mem[in_row + in_col*n_rows]);
-  }
-
-
-
-//! element accessor; no bounds check
-template<typename oT>
-arma_inline
-const oT&
-field<oT>::at(const uword in_row, const uword in_col) const
-  {
-  return (*mem[in_row + in_col*n_rows]);
-  }
-
-
-
-template<typename oT>
-inline
-field_injector< field<oT> >
-field<oT>::operator<<(const oT& val)
-  {
-  return field_injector< field<oT> >(*this, val);
-  }
-
-
-
-template<typename oT>
-inline
-field_injector< field<oT> >
-field<oT>::operator<<(const injector_end_of_row& x)
-  {
-  return field_injector< field<oT> >(*this, x);
-  }
-
-
-
-//! creation of subview_field (row of a field)
-template<typename oT>
-inline
-subview_field<oT>
-field<oT>::row(const uword row_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= n_rows), "field::row(): row out of bounds" );
-  
-  return subview_field<oT>(*this, row_num, 0, 1, n_cols);
-  }
-
-
-
-//! creation of subview_field (row of a field)
-template<typename oT>
-inline
-const subview_field<oT>
-field<oT>::row(const uword row_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (row_num >= n_rows), "field::row(): row out of bounds" );
-  
-  return subview_field<oT>(*this, row_num, 0, 1, n_cols);
-  }
-
-
-
-//! creation of subview_field (column of a field)
-template<typename oT>
-inline
-subview_field<oT>
-field<oT>::col(const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (col_num >= n_cols), "field::col(): out of bounds");
-  
-  return subview_field<oT>(*this, 0, col_num, n_rows, 1);
-  }
-
-
-
-//! creation of subview_field (column of a field)
-template<typename oT>
-inline
-const subview_field<oT>
-field<oT>::col(const uword col_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (col_num >= n_cols), "field::col(): out of bounds");
-  
-  return subview_field<oT>(*this, 0, col_num, n_rows, 1);
-  }
-
-
-
-//! creation of subview_field (subfield comprised of specified rows)
-template<typename oT>
-inline
-subview_field<oT>
-field<oT>::rows(const uword in_row1, const uword in_row2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    ( (in_row1 > in_row2) || (in_row2 >= n_rows) ),
-    "field::rows(): indicies out of bounds or incorrectly used"
-    );
-  
-  const uword sub_n_rows = in_row2 - in_row1 + 1;
-  
-  return subview_field<oT>(*this, in_row1, 0, sub_n_rows, n_cols);
-  }
-
-
-
-//! creation of subview_field (subfield comprised of specified rows)
-template<typename oT>
-inline
-const subview_field<oT>
-field<oT>::rows(const uword in_row1, const uword in_row2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    ( (in_row1 > in_row2) || (in_row2 >= n_rows) ),
-    "field::rows(): indicies out of bounds or incorrectly used"
-    );
-  
-  const uword sub_n_rows = in_row2 - in_row1 + 1;
-  
-  return subview_field<oT>(*this, in_row1, 0, sub_n_rows, n_cols);
-  }
-
-
-
-//! creation of subview_field (subfield comprised of specified columns)
-template<typename oT>
-inline
-subview_field<oT>
-field<oT>::cols(const uword in_col1, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    ( (in_col1 > in_col2) || (in_col2 >= n_cols) ),
-    "field::cols(): indicies out of bounds or incorrectly used"
-    );
-  
-  const uword sub_n_cols = in_col2 - in_col1 + 1;
-  
-  return subview_field<oT>(*this, 0, in_col1, n_rows, sub_n_cols);
-  }
-
-
-
-//! creation of subview_field (subfield comprised of specified columns)
-template<typename oT>
-inline
-const subview_field<oT>
-field<oT>::cols(const uword in_col1, const uword in_col2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    ( (in_col1 > in_col2) || (in_col2 >= n_cols) ),
-    "field::cols(): indicies out of bounds or incorrectly used"
-    );
-  
-  const uword sub_n_cols = in_col2 - in_col1 + 1;
-  
-  return subview_field<oT>(*this, 0, in_col1, n_rows, sub_n_cols);
-  }
-
-
-
-//! creation of subview_field (subfield with arbitrary dimensions)
-template<typename oT>
-inline
-subview_field<oT>
-field<oT>::subfield(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
-    "field::subfield(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword sub_n_rows = in_row2 - in_row1 + 1;
-  const uword sub_n_cols = in_col2 - in_col1 + 1;
-  
-  return subview_field<oT>(*this, in_row1, in_col1, sub_n_rows, sub_n_cols);
-  }
-
-
-
-//! creation of subview_field (subfield with arbitrary dimensions)
-template<typename oT>
-inline
-const subview_field<oT>
-field<oT>::subfield(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
-    "field::subfield(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword sub_n_rows = in_row2 - in_row1 + 1;
-  const uword sub_n_cols = in_col2 - in_col1 + 1;
-  
-  return subview_field<oT>(*this, in_row1, in_col1, sub_n_rows, sub_n_cols);
-  }
-
-
-
-//! creation of subview_field (subfield with arbitrary dimensions)
-template<typename oT>
-inline
-subview_field<oT>
-field<oT>::subfield(const span& row_span, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all = row_span.whole;
-  const bool col_all = col_span.whole;
-  
-  const uword local_n_rows = n_rows;
-  const uword local_n_cols = n_cols;
-  
-  const uword in_row1    = row_all ? 0            : row_span.a;
-  const uword in_row2    =                          row_span.b;
-  const uword sub_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
-  
-  const uword in_col1    = col_all ? 0            : col_span.a;
-  const uword in_col2    =                          col_span.b;
-  const uword sub_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
-  
-  arma_debug_check
-    (
-    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
-    ||
-    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
-    ,
-    "field::subfield(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview_field<oT>(*this, in_row1, in_col1, sub_n_rows, sub_n_cols);
-  }
-
-
-
-//! creation of subview_field (subfield with arbitrary dimensions)
-template<typename oT>
-inline
-const subview_field<oT>
-field<oT>::subfield(const span& row_span, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all = row_span.whole;
-  const bool col_all = col_span.whole;
-  
-  const uword local_n_rows = n_rows;
-  const uword local_n_cols = n_cols;
-  
-  const uword in_row1    = row_all ? 0            : row_span.a;
-  const uword in_row2    =                          row_span.b;
-  const uword sub_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
-  
-  const uword in_col1    = col_all ? 0            : col_span.a;
-  const uword in_col2    =                          col_span.b;
-  const uword sub_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
-  
-  arma_debug_check
-    (
-    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
-    ||
-    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
-    ,
-    "field::subfield(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview_field<oT>(*this, in_row1, in_col1, sub_n_rows, sub_n_cols);
-  }
-
-
-
-template<typename oT>
-inline
-subview_field<oT>
-field<oT>::operator()(const span& row_span, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).subfield(row_span, col_span);
-  }
-
-
-
-template<typename oT>
-inline
-const subview_field<oT>
-field<oT>::operator()(const span& row_span, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).subfield(row_span, col_span);
-  }
-
-
-
-//! print contents of the field (to the cout stream),
-//! optionally preceding with a user specified line of text.
-//! the field class preserves the stream's flags
-//! but the associated operator<< function for type oT 
-//! may still modify the stream's parameters.
-//! NOTE: this function assumes that type oT can be printed,
-//! i.e. the function "std::ostream& operator<< (std::ostream&, const oT&)"
-//! has been defined.
-
-template<typename oT>
-inline
-void
-field<oT>::print(const std::string extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(extra_text.length() != 0)
-    {
-    const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width();
-    
-    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
-  
-    ARMA_DEFAULT_OSTREAM.width(orig_width);
-    }
-  
-  arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this);
-  }
-
-
-
-//! print contents of the field to a user specified stream,
-//! optionally preceding with a user specified line of text.
-//! the field class preserves the stream's flags
-//! but the associated operator<< function for type oT 
-//! may still modify the stream's parameters.
-//! NOTE: this function assumes that type oT can be printed,
-//! i.e. the function "std::ostream& operator<< (std::ostream&, const oT&)"
-//! has been defined.
-
-template<typename oT>
-inline
-void
-field<oT>::print(std::ostream& user_stream, const std::string extra_text) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(extra_text.length() != 0)
-    {
-    const std::streamsize orig_width = user_stream.width();
-    
-    user_stream << extra_text << '\n';
-  
-    user_stream.width(orig_width);
-    }
-  
-  arma_ostream::print(user_stream, *this);
-  }
-
-
-
-//! fill the field with an object
-template<typename oT>
-inline
-void
-field<oT>::fill(const oT& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  field<oT>& t = *this;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    t[i] = x;
-    }
-  }
-
-
-
-//! reset the field to an empty state (i.e. the field will have no objects)
-template<typename oT>
-inline
-void
-field<oT>::reset()
-  {
-  arma_extra_debug_sigprint();
-  
-  init(0,0);
-  }
-
-
-
-//! reset each object
-template<typename oT>
-inline
-void
-field<oT>::reset_objects()
-  {
-  arma_extra_debug_sigprint();
-  
-  field_aux::reset_objects(*this);
-  }
-
-
-
-//! returns true if the field has no objects
-template<typename oT>
-arma_inline
-bool
-field<oT>::is_empty() const
-  {
-  return (n_elem == 0);
-  }
-
-
-
-//! returns true if the given index is currently in range
-template<typename oT>
-arma_inline
-arma_warn_unused
-bool
-field<oT>::in_range(const uword i) const
-  {
-  return (i < n_elem);
-  }
-
-
-
-//! returns true if the given start and end indices are currently in range
-template<typename oT>
-arma_inline
-arma_warn_unused
-bool
-field<oT>::in_range(const span& x) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(x.whole == true)
-    {
-    return true;
-    }
-  else
-    {
-    const uword a = x.a;
-    const uword b = x.b;
-    
-    return ( (a <= b) && (b < n_elem) );
-    }
-  }
-
-
-
-//! returns true if the given location is currently in range
-template<typename oT>
-arma_inline
-arma_warn_unused
-bool
-field<oT>::in_range(const uword in_row, const uword in_col) const
-  {
-  return ( (in_row < n_rows) && (in_col < n_cols) );
-  }
-
-
-
-template<typename oT>
-arma_inline
-arma_warn_unused
-bool
-field<oT>::in_range(const span& row_span, const uword in_col) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(row_span.whole == true)
-    {
-    return (in_col < n_cols);
-    }
-  else
-    {
-    const uword in_row1 = row_span.a;
-    const uword in_row2 = row_span.b;
-    
-    return ( (in_row1 <= in_row2) && (in_row2 < n_rows) && (in_col < n_cols) );
-    }
-  }
-
-
-
-template<typename oT>
-arma_inline
-arma_warn_unused
-bool
-field<oT>::in_range(const uword in_row, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(col_span.whole == true)
-    {
-    return (in_row < n_rows);
-    }
-  else
-    {
-    const uword in_col1 = col_span.a;
-    const uword in_col2 = col_span.b;
-  
-    return ( (in_row < n_rows) && (in_col1 <= in_col2) && (in_col2 < n_cols) );
-    }
-  }
-
-
-
-template<typename oT>
-arma_inline
-arma_warn_unused
-bool
-field<oT>::in_range(const span& row_span, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword in_row1 = row_span.a;
-  const uword in_row2 = row_span.b;
-  
-  const uword in_col1 = col_span.a;
-  const uword in_col2 = col_span.b;
-  
-  const bool rows_ok = row_span.whole ? true : ( (in_row1 <= in_row2) && (in_row2 < n_rows) );
-  const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2) && (in_col2 < n_cols) );
-  
-  return ( (rows_ok == true) && (cols_ok == true) );
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field<oT>::save(const std::string name, const file_type type, const bool print_status) const
-  {
-  arma_extra_debug_sigprint();
-  
-  std::string err_msg;
-  const bool save_okay = field_aux::save(*this, name, type, err_msg);
-  
-  if( (print_status == true) && (save_okay == false) )
-    {
-    if(err_msg.length() > 0)
-      {
-      arma_warn(true, "field::save(): ", err_msg, name);
-      }
-    else
-      {
-      arma_warn(true, "field::save(): couldn't write to ", name);
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field<oT>::save(std::ostream& os, const file_type type, const bool print_status) const
-  {
-  arma_extra_debug_sigprint();
-  
-  std::string err_msg;
-  const bool save_okay = field_aux::save(*this, os, type, err_msg);
-  
-  if( (print_status == true) && (save_okay == false) )
-    {
-    if(err_msg.length() > 0)
-      {
-      arma_warn(true, "field::save(): ", err_msg, "[ostream]");
-      }
-    else
-      {
-      arma_warn(true, "field::save(): couldn't write to [ostream]");
-      }
-    }
-  
-  return save_okay;
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field<oT>::load(const std::string name, const file_type type, const bool print_status)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::string err_msg;
-  const bool load_okay = field_aux::load(*this, name, type, err_msg);
-  
-  if( (print_status == true) && (load_okay == false) )
-    {
-    if(err_msg.length() > 0)
-      {
-      arma_warn(true, "field::load(): ", err_msg, name);
-      }
-    else
-      {
-      arma_warn(true, "field::load(): couldn't read from ", name);
-      }
-    }
-  
-  if(load_okay == false)
-    {
-    (*this).reset();
-    }
-  
-  return load_okay;
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field<oT>::load(std::istream& is, const file_type type, const bool print_status)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::string err_msg;
-  const bool load_okay = field_aux::load(*this, is, type, err_msg);
-  
-  if( (print_status == true) && (load_okay == false) )
-    {
-    if(err_msg.length() > 0)
-      {
-      arma_warn(true, "field::load(): ", err_msg, "[istream]");
-      }
-    else
-      {
-      arma_warn(true, "field::load(): couldn't read from [istream]");
-      }
-    }
-  
-  if(load_okay == false)
-    {
-    (*this).reset();
-    }
-  
-  return load_okay;
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field<oT>::quiet_save(const std::string name, const file_type type) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).save(name, type, false);
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field<oT>::quiet_save(std::ostream& os, const file_type type) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).save(os, type, false);
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field<oT>::quiet_load(const std::string name, const file_type type)
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).load(name, type, false);
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field<oT>::quiet_load(std::istream& is, const file_type type)
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).load(is, type, false);
-  }
-
-
-
-//! construct a field from a given field
-template<typename oT>
-inline
-void
-field<oT>::init(const field<oT>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(this != &x)
-    {
-    init(x.n_rows, x.n_cols);
-    
-    field& t = *this;
-    
-    for(uword col=0; col<x.n_cols; ++col)
-    for(uword row=0; row<x.n_rows; ++row)
-      {
-      t.at(row,col) = x.at(row,col);
-      }
-    }
-  
-  }
-
-
-
-//! internal field construction; if the requested size is small enough, memory from the stack is used. otherwise memory is allocated via 'new'
-template<typename oT>
-inline
-void
-field<oT>::init(const uword n_rows_in, const uword n_cols_in)
-  {
-  arma_extra_debug_sigprint( arma_boost::format("n_rows_in = %d, n_cols_in = %d") % n_rows_in % n_cols_in );
-  
-  const uword n_elem_new = n_rows_in * n_cols_in;
-
-  if(n_elem == n_elem_new)
-    {
-    // delete_objects();
-    // create_objects();
-    access::rw(n_rows) = n_rows_in;
-    access::rw(n_cols) = n_cols_in;
-    }
-  else
-    {
-    delete_objects();
-    
-    if(n_elem > sizeof(mem_local)/sizeof(oT*) )
-      {
-      delete [] mem;
-      }
-    
-    if(n_elem_new <= sizeof(mem_local)/sizeof(oT*) )
-      {
-      mem = mem_local;
-      }
-    else
-      {
-      mem = new(std::nothrow) oT* [n_elem_new];
-      arma_check_bad_alloc( (mem == 0), "field::init(): out of memory" );
-      }
-    
-    access::rw(n_elem) = n_elem_new;
-    
-    if(n_elem_new == 0)
-      {
-      access::rw(n_rows) = 0;
-      access::rw(n_cols) = 0;
-      }
-    else
-      {
-      access::rw(n_rows) = n_rows_in;
-      access::rw(n_cols) = n_cols_in;
-      }
-    
-    create_objects();
-    
-    }
-  
-  }
-
-
-
-template<typename oT>
-inline
-void
-field<oT>::delete_objects()
-  {
-  arma_extra_debug_sigprint( arma_boost::format("n_elem = %d") % n_elem );
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    if(mem[i] != 0)
-      {
-      delete mem[i];
-      mem[i] = 0;
-      }
-    }
-  
-  }
-
-
-
-template<typename oT>
-inline
-void
-field<oT>::create_objects()
-  {
-  arma_extra_debug_sigprint( arma_boost::format("n_elem = %d") % n_elem );
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    mem[i] = new oT;
-    }
-  
-  }
-
-
-
-template<typename oT>
-inline
-field<oT>::iterator::iterator(field<oT>& in_M, const bool at_end)
-  : M(in_M)
-  , i( (at_end == false) ? 0 : in_M.n_elem )
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename oT>
-inline
-oT&
-field<oT>::iterator::operator*()
-  {
-  return M[i];
-  }
-
-
-
-template<typename oT>
-inline
-typename field<oT>::iterator&
-field<oT>::iterator::operator++()
-  {
-  ++i;
-  
-  return *this;
-  }
-
-
-
-template<typename oT>
-inline
-void
-field<oT>::iterator::operator++(int)
-  {
-  operator++();
-  }
-
-
-
-template<typename oT>
-inline
-typename field<oT>::iterator&
-field<oT>::iterator::operator--()
-  {
-  if(i > 0)
-    {
-    --i;
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename oT>
-inline
-void
-field<oT>::iterator::operator--(int)
-  {
-  operator--();
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field<oT>::iterator::operator!=(const typename field<oT>::iterator& X) const
-  {
-  return (i != X.i);
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field<oT>::iterator::operator==(const typename field<oT>::iterator& X) const
-  {
-  return (i == X.i);
-  }
-
-
-
-template<typename oT>
-inline
-field<oT>::const_iterator::const_iterator(const field<oT>& in_M, const bool at_end)
-  : M(in_M)
-  , i( (at_end == false) ? 0 : in_M.n_elem )
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename oT>
-inline
-field<oT>::const_iterator::const_iterator(const typename field<oT>::iterator& X)
-  : M(X.M)
-  , i(X.i)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename oT>
-inline
-const oT&
-field<oT>::const_iterator::operator*() const
-  {
-  return M[i];
-  }
-
-
-
-template<typename oT>
-inline
-typename field<oT>::const_iterator&
-field<oT>::const_iterator::operator++()
-  {
-  ++i;
-  
-  return *this;
-  }
-
-
-
-template<typename oT>
-inline
-void
-field<oT>::const_iterator::operator++(int)
-  {
-  operator++();
-  }
-
-
-
-template<typename oT>
-inline
-typename field<oT>::const_iterator&
-field<oT>::const_iterator::operator--()
-  {
-  if(i > 0)
-    {
-    --i;
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename oT>
-inline
-void
-field<oT>::const_iterator::operator--(int)
-  {
-  operator--();
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field<oT>::const_iterator::operator!=(const typename field<oT>::const_iterator& X) const
-  {
-  return (i != X.i);
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field<oT>::const_iterator::operator==(const typename field<oT>::const_iterator& X) const
-  {
-  return (i == X.i);
-  }
-
-
-
-template<typename oT>
-inline
-typename field<oT>::iterator
-field<oT>::begin()
-  {
-  arma_extra_debug_sigprint();
-  
-  return field<oT>::iterator(*this);
-  }
-
-
-
-template<typename oT>
-inline
-typename field<oT>::const_iterator
-field<oT>::begin() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return field<oT>::const_iterator(*this);
-  }
-
-
-
-template<typename oT>
-inline
-typename field<oT>::iterator
-field<oT>::end()
-  {
-  arma_extra_debug_sigprint();
-  
-  return field<oT>::iterator(*this, true);
-  }
-
-
-
-template<typename oT>
-inline
-typename field<oT>::const_iterator
-field<oT>::end() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return field<oT>::const_iterator(*this, true);
-  }
-  
-
-
-//
-//
-//
-
-
-
-template<typename oT>
-inline
-void
-field_aux::reset_objects(field<oT>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  x.delete_objects();
-  x.create_objects();
-  }
-
-
-
-template<typename eT>
-inline
-void
-field_aux::reset_objects(field< Mat<eT> >& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  for(uword i=0; i<x.n_elem; ++i)
-    {
-    (*(x.mem[i])).reset();
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-field_aux::reset_objects(field< Col<eT> >& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  for(uword i=0; i<x.n_elem; ++i)
-    {
-    (*(x.mem[i])).reset();
-    }
-  }
-  
-  
-  
-template<typename eT>
-inline
-void
-field_aux::reset_objects(field< Row<eT> >& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  for(uword i=0; i<x.n_elem; ++i)
-    {
-    (*(x.mem[i])).reset();
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-field_aux::reset_objects(field< Cube<eT> >& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  for(uword i=0; i<x.n_elem; ++i)
-    {
-    (*(x.mem[i])).reset();
-    }
-  }
-
-
-
-inline
-void
-field_aux::reset_objects(field< std::string >& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  for(uword i=0; i<x.n_elem; ++i)
-    {
-    (*(x.mem[i])).clear();
-    }
-  }
-
-
-
-//
-//
-//
-
-
-
-template<typename oT>
-inline
-bool
-field_aux::save(const field<oT>& x, const std::string& name, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  err_msg = " [sorry, saving/loading this type of field is currently not supported] filename = ";
-  
-  return false;
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field_aux::save(const field<oT>& x, std::ostream& os, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  err_msg = " [sorry, saving/loading this type of field is currently not supported] filename = ";
-  
-  return false;
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field_aux::load(field<oT>& x, const std::string& name, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  err_msg = " [sorry, saving/loading this type of field is currently not supported] filename = ";
-  
-  return false;
-  }
-
-
-
-template<typename oT>
-inline
-bool
-field_aux::load(field<oT>& x, std::istream& is, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  err_msg = " [sorry, saving/loading this type of field is currently not supported] filename = ";
-  
-  return false;
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::save(const field< Mat<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case arma_binary:
-      return diskio::save_arma_binary(x, name);
-      break;
-      
-    case ppm_binary:
-      return diskio::save_ppm_binary(x, name);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::save(const field< Mat<eT> >& x, std::ostream& os, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case arma_binary:
-      return diskio::save_arma_binary(x, os);
-      break;
-      
-    case ppm_binary:
-      return diskio::save_ppm_binary(x, os);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::load(field< Mat<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case auto_detect:
-      return diskio::load_auto_detect(x, name, err_msg);
-      break;
-    
-    case arma_binary:
-      return diskio::load_arma_binary(x, name, err_msg);
-      break;
-      
-    case ppm_binary:
-      return diskio::load_ppm_binary(x, name, err_msg);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::load(field< Mat<eT> >& x, std::istream& is, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case auto_detect:
-      return diskio::load_auto_detect(x, is, err_msg);
-      break;
-    
-    case arma_binary:
-      return diskio::load_arma_binary(x, is, err_msg);
-      break;
-      
-    case ppm_binary:
-      return diskio::load_ppm_binary(x, is, err_msg);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::save(const field< Col<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case arma_binary:
-      return diskio::save_arma_binary(x, name);
-      break;
-      
-    case ppm_binary:
-      return diskio::save_ppm_binary(x, name);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::save(const field< Col<eT> >& x, std::ostream& os, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case arma_binary:
-      return diskio::save_arma_binary(x, os);
-      break;
-      
-    case ppm_binary:
-      return diskio::save_ppm_binary(x, os);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::load(field< Col<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case auto_detect:
-      return diskio::load_auto_detect(x, name, err_msg);
-      break;
-    
-    case arma_binary:
-      return diskio::load_arma_binary(x, name, err_msg);
-      break;
-      
-    case ppm_binary:
-      return diskio::load_ppm_binary(x, name, err_msg);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::load(field< Col<eT> >& x, std::istream& is, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case auto_detect:
-      return diskio::load_auto_detect(x, is, err_msg);
-      break;
-    
-    case arma_binary:
-      return diskio::load_arma_binary(x, is, err_msg);
-      break;
-      
-    case ppm_binary:
-      return diskio::load_ppm_binary(x, is, err_msg);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::save(const field< Row<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case arma_binary:
-      return diskio::save_arma_binary(x, name, err_msg);
-      break;
-      
-    case ppm_binary:
-      return diskio::save_ppm_binary(x, name, err_msg);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::save(const field< Row<eT> >& x, std::ostream& os, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case arma_binary:
-      return diskio::save_arma_binary(x, os, err_msg);
-      break;
-      
-    case ppm_binary:
-      return diskio::save_ppm_binary(x, os, err_msg);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::load(field< Row<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case auto_detect:
-      return diskio::load_auto_detect(x, name, err_msg);
-      break;
-    
-    case arma_binary:
-      return diskio::load_arma_binary(x, name, err_msg);
-      break;
-      
-    case ppm_binary:
-      return diskio::load_ppm_binary(x, name, err_msg);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::load(field< Row<eT> >& x, std::istream& is, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case auto_detect:
-      return diskio::load_auto_detect(x, is, err_msg);
-      break;
-    
-    case arma_binary:
-      return diskio::load_arma_binary(x, is, err_msg);
-      break;
-      
-    case ppm_binary:
-      return diskio::load_ppm_binary(x, is, err_msg);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::save(const field< Cube<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case arma_binary:
-      return diskio::save_arma_binary(x, name, err_msg);
-      break;
-      
-    case ppm_binary:
-      return diskio::save_ppm_binary(x, name, err_msg);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::save(const field< Cube<eT> >& x, std::ostream& os, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case arma_binary:
-      return diskio::save_arma_binary(x, os, err_msg);
-      break;
-      
-    case ppm_binary:
-      return diskio::save_ppm_binary(x, os, err_msg);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::load(field< Cube<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case auto_detect:
-      return diskio::load_auto_detect(x, name, err_msg);
-      break;
-    
-    case arma_binary:
-      return diskio::load_arma_binary(x, name, err_msg);
-      break;
-      
-    case ppm_binary:
-      return diskio::load_ppm_binary(x, name, err_msg);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-field_aux::load(field< Cube<eT> >& x, std::istream& is, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  switch(type)
-    {
-    case auto_detect:
-      return diskio::load_auto_detect(x, is, err_msg);
-      break;
-    
-    case arma_binary:
-      return diskio::load_arma_binary(x, is, err_msg);
-      break;
-      
-    case ppm_binary:
-      return diskio::load_ppm_binary(x, is, err_msg);
-      break;
-    
-    default:
-      err_msg = " [unsupported type] filename = ";
-      return false;
-    }
-  }
-
-
-
-inline
-bool
-field_aux::save(const field< std::string >& x, const std::string& name, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(type);
-  
-  err_msg.clear();
-  
-  return diskio::save_std_string(x, name);
-  }
-
-
-
-inline
-bool
-field_aux::save(const field< std::string >& x, std::ostream& os, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(type);
-  
-  err_msg.clear();
-  
-  return diskio::save_std_string(x, os);
-  }
-
-
-
-inline
-bool
-field_aux::load(field< std::string >& x, const std::string& name, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(type);
-  
-  return diskio::load_std_string(x, name, err_msg);
-  }
-
-
-
-inline
-bool
-field_aux::load(field< std::string >& x, std::istream& is, const file_type type, std::string& err_msg)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(type);
-  
-  return diskio::load_std_string(x, is, err_msg);
-  }
-
-
-
-#ifdef ARMA_EXTRA_FIELD_MEAT
-  #include ARMA_INCFILE_WRAP(ARMA_EXTRA_FIELD_MEAT)
-#endif
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_accu.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,279 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_accu
-//! @{
-
-
-
-//! accumulate the elements of a matrix
-template<typename T1>
-arma_hot
-inline
-typename T1::elem_type
-accu(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type      eT;
-  typedef typename Proxy<T1>::ea_type ea_type;
-  
-  const Proxy<T1> A(X.get_ref());
-  
-  if(Proxy<T1>::prefer_at_accessor == false)
-    {
-          ea_type P      = A.get_ea();
-    const uword   n_elem = A.get_n_elem();
-    
-    eT val1 = eT(0);
-    eT val2 = eT(0);
-    
-    uword i,j;
-    
-    for(i=0, j=1; j<n_elem; i+=2, j+=2)
-      {
-      val1 += P[i];
-      val2 += P[j];
-      }
-    
-    if(i < n_elem)
-      {
-      val1 += P[i];
-      }
-    
-    return val1 + val2;
-    }
-  else
-    {
-    const uword n_rows = A.get_n_rows();
-    const uword n_cols = A.get_n_cols();
-    
-    eT val = eT(0);
-    
-    for(uword col=0; col<n_cols; ++col)
-      {
-      for(uword row=0; row<n_rows; ++row)
-        {
-        val += A.at(row,col);
-        }
-      }
-    
-    return val;
-    }
-  }
-
-
-
-//! explicit handling of Hamming norm (also known as zero norm)
-template<typename T1>
-arma_inline
-arma_warn_unused
-uword
-accu(const mtOp<uword,T1,op_rel_noteq>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const Proxy<T1> A(X.m);
-  
-  const uword n_elem = A.get_n_elem();
-  const eT    val    = X.aux;
-  
-  uword n_nonzero = 0;
-  for(uword i=0; i<n_elem; ++i)
-    {
-    if(A[i] != val)
-      {
-      ++n_nonzero;
-      }
-    }
-  
-  return n_nonzero;
-  }
-
-
-
-//! accumulate the elements of a cube
-template<typename T1>
-arma_hot
-arma_warn_unused
-inline
-typename T1::elem_type
-accu(const BaseCube<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type          eT;
-  typedef typename ProxyCube<T1>::ea_type ea_type;
-  
-  const ProxyCube<T1> A(X.get_ref());
-  
-  if(ProxyCube<T1>::prefer_at_accessor == false)
-    {
-    
-          ea_type P      = A.get_ea();
-    const uword   n_elem = A.get_n_elem();
-    
-    eT val1 = eT(0);
-    eT val2 = eT(0);
-    
-    uword i,j;
-    
-    for(i=0, j=1; j<n_elem; i+=2, j+=2)
-      {
-      val1 += P[i];
-      val2 += P[j];
-      }
-    
-    if(i < n_elem)
-      {
-      val1 += P[i];
-      }
-    
-    return val1 + val2;
-    }
-  else
-    {
-    const uword n_rows   = A.get_n_rows();
-    const uword n_cols   = A.get_n_cols();
-    const uword n_slices = A.get_n_slices();
-    
-    eT val = eT(0);
-    
-    for(uword slice=0; slice<n_slices; ++slice)
-      {
-      for(uword col=0; col<n_cols; ++col)
-        {
-        for(uword row=0; row<n_rows; ++row)
-          {
-          val += A.at(row,col,slice);
-          }
-        }
-      }
-    
-    return val;
-    }
-  }
-
-
-
-//! accumulate the elements of a diagview
-template<typename eT>
-arma_pure
-arma_warn_unused
-inline
-eT
-accu(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();  
-  
-  const uword n_elem = X.n_elem;
-  
-  eT val = eT(0);
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    val += X[i];
-    }
-  
-  return val;
-  }
-
-
-
-//! accumulate the elements of a subview (submatrix)
-template<typename eT>
-arma_pure
-arma_warn_unused
-inline
-eT
-accu(const subview<eT>& S)
-  {
-  arma_extra_debug_sigprint();  
-  
-  const uword S_n_rows = S.n_rows;
-  const uword S_n_cols = S.n_cols;
-  const uword S_n_elem = S.n_elem;
-  
-  eT val = eT(0);
-  
-  if(S_n_elem > 0)
-    {
-    for(uword col=0; col<S_n_cols; ++col)
-      {
-      val += arrayops::accumulate( S.colptr(col), S_n_rows );
-      }
-    }
-  
-  return val;
-  }
-
-
-
-//! accumulate the elements of a subview_row
-template<typename eT>
-arma_pure
-arma_warn_unused
-inline
-eT
-accu(const subview_row<eT>& S)
-  {
-  arma_extra_debug_sigprint();  
-  
-  const Mat<eT>& X = S.m;
-  
-  const uword n_elem     = S.n_elem;
-  const uword row        = S.aux_row1;
-  const uword start_col  = S.aux_col1;
-  const uword end_col_p1 = start_col + S.n_cols;
-  
-  eT val = eT(0);
-    
-  if(n_elem > 0)
-    {
-    uword i,j;
-    
-    for(i=start_col, j=start_col+1; j < end_col_p1; i+=2, j+=2)
-      {
-      val += X.at(row,i);
-      val += X.at(row,j);
-      }
-    
-    if(i < end_col_p1)
-      {
-      val += X.at(row,i);
-      }
-    }
-  
-  return val;
-  }
-
-
-
-//! accumulate the elements of a subview_col
-template<typename eT>
-arma_pure
-arma_warn_unused
-inline
-eT
-accu(const subview_col<eT>& S)
-  {
-  arma_extra_debug_sigprint();
-  
-  return (S.n_elem > 0) ? arrayops::accumulate( S.colptr(0), S.n_rows ) : eT(0);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_as_scalar.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,357 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_as_scalar
-//! @{
-
-
-
-template<uword N>
-struct as_scalar_redirect
-  {
-  template<typename T1>
-  inline static typename T1::elem_type apply(const T1& X);
-  };
-
-
-
-template<>
-struct as_scalar_redirect<2>
-  {
-  template<typename T1, typename T2>
-  inline static typename T1::elem_type apply(const Glue<T1,T2,glue_times>& X);
-  };
-
-
-template<>
-struct as_scalar_redirect<3>
-  {
-  template<typename T1, typename T2, typename T3>
-  inline static typename T1::elem_type apply(const Glue< Glue<T1, T2, glue_times>, T3, glue_times>& X);
-  };
-
-
-
-template<uword N>
-template<typename T1>
-inline
-typename T1::elem_type
-as_scalar_redirect<N>::apply(const T1& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(X);
-  const Mat<eT>& A = tmp.M;
-  
-  arma_debug_check( (A.n_elem != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
-  
-  return A.mem[0];
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-typename T1::elem_type
-as_scalar_redirect<2>::apply(const Glue<T1, T2, glue_times>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  // T1 must result in a matrix with one row
-  // T2 must result in a matrix with one column
-  
-  const partial_unwrap<T1> tmp1(X.A);
-  const partial_unwrap<T2> tmp2(X.B);
-  
-  const Mat<eT>& A = tmp1.M;
-  const Mat<eT>& B = tmp2.M;
-  
-  const uword A_n_rows = (tmp1.do_trans == false) ? A.n_rows : A.n_cols;
-  const uword A_n_cols = (tmp1.do_trans == false) ? A.n_cols : A.n_rows;
-  
-  const uword B_n_rows = (tmp2.do_trans == false) ? B.n_rows : B.n_cols;
-  const uword B_n_cols = (tmp2.do_trans == false) ? B.n_cols : B.n_rows;
-  
-  const eT val = tmp1.get_val() * tmp2.get_val();
-  
-  arma_debug_check( (A_n_rows != 1) || (B_n_cols != 1) || (A_n_cols != B_n_rows), "as_scalar(): incompatible dimensions" );
-  
-  return val * op_dot::direct_dot(A.n_elem, A.mem, B.mem);
-  }
-
-
-
-template<typename T1, typename T2, typename T3>
-inline
-typename T1::elem_type
-as_scalar_redirect<3>::apply(const Glue< Glue<T1, T2, glue_times>, T3, glue_times >& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  // T1 * T2 must result in a matrix with one row
-  // T3 must result in a matrix with one column
-  
-  typedef typename strip_inv    <T2           >::stored_type T2_stripped_1;
-  typedef typename strip_diagmat<T2_stripped_1>::stored_type T2_stripped_2;
-  
-  const strip_inv    <T2>            strip1(X.A.B);
-  const strip_diagmat<T2_stripped_1> strip2(strip1.M);
-  
-  const bool tmp2_do_inv     = strip1.do_inv;
-  const bool tmp2_do_diagmat = strip2.do_diagmat;
-  
-  if(tmp2_do_diagmat == false)
-    {
-    const Mat<eT> tmp(X);
-    
-    arma_debug_check( (tmp.n_elem != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
-    
-    return tmp[0];
-    }
-  else
-    {
-    const partial_unwrap<T1>            tmp1(X.A.A);
-    const partial_unwrap<T2_stripped_2> tmp2(strip2.M);
-    const partial_unwrap<T3>            tmp3(X.B);
-    
-    const Mat<eT>& A = tmp1.M;
-    const Mat<eT>& B = tmp2.M;
-    const Mat<eT>& C = tmp3.M;
-    
-    const uword A_n_rows = (tmp1.do_trans == false) ? A.n_rows : A.n_cols;
-    const uword A_n_cols = (tmp1.do_trans == false) ? A.n_cols : A.n_rows;
-    
-    const bool B_is_vec = B.is_vec();
-    
-    const uword B_n_rows = (B_is_vec == true) ? B.n_elem : ( (tmp2.do_trans == false) ? B.n_rows : B.n_cols );
-    const uword B_n_cols = (B_is_vec == true) ? B.n_elem : ( (tmp2.do_trans == false) ? B.n_cols : B.n_rows );
-    
-    const uword C_n_rows = (tmp3.do_trans == false) ? C.n_rows : C.n_cols;
-    const uword C_n_cols = (tmp3.do_trans == false) ? C.n_cols : C.n_rows;
-    
-    const eT val = tmp1.get_val() * tmp2.get_val() * tmp3.get_val();
-    
-    arma_debug_check
-      (
-      (A_n_rows != 1)        ||
-      (C_n_cols != 1)        ||
-      (A_n_cols != B_n_rows) ||
-      (B_n_cols != C_n_rows)
-      ,
-      "as_scalar(): incompatible dimensions"
-      );
-    
-    
-    if(B_is_vec == true)
-      {
-      if(tmp2_do_inv == true)
-        {
-        return val * op_dotext::direct_rowvec_invdiagvec_colvec(A.mem, B, C.mem);
-        }
-      else
-        {
-        return val * op_dot::direct_dot(A.n_elem, A.mem, B.mem, C.mem);
-        }
-      }
-    else
-      {
-      if(tmp2_do_inv == true)
-        {
-        return val * op_dotext::direct_rowvec_invdiagmat_colvec(A.mem, B, C.mem);
-        }
-      else
-        {
-        return val * op_dotext::direct_rowvec_diagmat_colvec(A.mem, B, C.mem);
-        }
-      }
-    }
-  }
-
-
-
-template<typename T1>
-inline
-typename T1::elem_type
-as_scalar_diag(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(X.get_ref());
-  const Mat<eT>& A = tmp.M;
-  
-  arma_debug_check( (A.n_elem != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
-  
-  return A.mem[0];
-  }
-
-
-
-template<typename T1, typename T2, typename T3>
-inline
-typename T1::elem_type
-as_scalar_diag(const Glue< Glue<T1, T2, glue_times_diag>, T3, glue_times >& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  // T1 * T2 must result in a matrix with one row
-  // T3 must result in a matrix with one column
-  
-  typedef typename strip_diagmat<T2>::stored_type T2_stripped;
-  
-  const strip_diagmat<T2> strip(X.A.B);
-  
-  const partial_unwrap<T1>          tmp1(X.A.A);
-  const partial_unwrap<T2_stripped> tmp2(strip.M);
-  const partial_unwrap<T3>          tmp3(X.B);
-  
-  const Mat<eT>& A = tmp1.M;
-  const Mat<eT>& B = tmp2.M;
-  const Mat<eT>& C = tmp3.M;
-  
-  
-  const uword A_n_rows = (tmp1.do_trans == false) ? A.n_rows : A.n_cols;
-  const uword A_n_cols = (tmp1.do_trans == false) ? A.n_cols : A.n_rows;
-  
-  const bool B_is_vec = B.is_vec();
-  
-  const uword B_n_rows = (B_is_vec == true) ? B.n_elem : ( (tmp2.do_trans == false) ? B.n_rows : B.n_cols );
-  const uword B_n_cols = (B_is_vec == true) ? B.n_elem : ( (tmp2.do_trans == false) ? B.n_cols : B.n_rows );
-  
-  const uword C_n_rows = (tmp3.do_trans == false) ? C.n_rows : C.n_cols;
-  const uword C_n_cols = (tmp3.do_trans == false) ? C.n_cols : C.n_rows;
-  
-  const eT val = tmp1.get_val() * tmp2.get_val() * tmp3.get_val();
-  
-  arma_debug_check
-    (
-    (A_n_rows != 1)        ||
-    (C_n_cols != 1)        ||
-    (A_n_cols != B_n_rows) ||
-    (B_n_cols != C_n_rows)
-    ,
-    "as_scalar(): incompatible dimensions"
-    );
-  
-  
-  if(B_is_vec == true)
-    {
-    return val * op_dot::direct_dot(A.n_elem, A.mem, B.mem, C.mem);
-    }
-  else
-    {
-    return val * op_dotext::direct_rowvec_diagmat_colvec(A.mem, B, C.mem);
-    }
-  }
-
-
-
-template<typename T1, typename T2>
-arma_inline
-arma_warn_unused
-typename T1::elem_type
-as_scalar(const Glue<T1, T2, glue_times>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  if(is_glue_times_diag<T1>::value == false)
-    {
-    const sword N_mat = 1 + depth_lhs< glue_times, Glue<T1,T2,glue_times> >::num;
-    
-    arma_extra_debug_print(arma_boost::format("N_mat = %d") % N_mat);
-    
-    return as_scalar_redirect<N_mat>::apply(X);
-    }
-  else
-    {
-    return as_scalar_diag(X);
-    }
-  }
-
-
-
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::elem_type
-as_scalar(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(X.get_ref());
-  const Mat<eT>& A = tmp.M;
-  
-  arma_debug_check( (A.n_elem != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
-  
-  return A.mem[0];
-  }
-
-
-
-template<typename T1>
-arma_inline
-arma_warn_unused
-typename T1::elem_type
-as_scalar(const eOp<T1, eop_neg>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return -(as_scalar(X.P.Q));
-  }
-
-
-
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::elem_type
-as_scalar(const BaseCube<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_cube<T1> tmp(X.get_ref());
-  const Cube<eT>& A   = tmp.M;
-  
-  arma_debug_check( (A.n_elem != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
-  
-  return A.mem[0];
-  }
-
-
-
-template<typename T>
-arma_inline
-arma_warn_unused
-const typename arma_scalar_only<T>::result &
-as_scalar(const T& x)
-  {
-  return x;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_chol.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_chol
-//! @{
-
-
-
-template<typename T1>
-inline
-const Op<T1, op_chol>
-chol
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return Op<T1, op_chol>(X.get_ref());
-  }
-
-
-
-template<typename T1>
-inline
-bool
-chol
-  (
-         Mat<typename T1::elem_type>&    out,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  try
-    {
-    out = chol(X);
-    }
-  catch(std::runtime_error&)
-    {
-    return false;
-    }
-  
-  return true;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_conv.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_conv
-//! @{
-
-
-
-//! Convolution, which is also equivalent to polynomial multiplication and FIR digital filtering.
-
-template<typename T1, typename T2>
-inline
-const Glue<T1, T2, glue_conv>
-conv(const Base<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Glue<T1, T2, glue_conv>(A.get_ref(), B.get_ref());
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_conv_to.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1102 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_conv_to
-//! @{
-
-
-
-//! conversion from Armadillo Base and BaseCube objects to scalars
-//! (kept only for compatibility with old code; use as_scalar() instead for Base objects like Mat)
-template<typename out_eT>
-class conv_to
-  {
-  public:
-  
-  template<typename in_eT, typename T1>
-  inline static out_eT from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-
-  template<typename in_eT, typename T1>
-  inline static out_eT from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  
-  template<typename in_eT, typename T1>
-  inline static out_eT from(const BaseCube<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT, typename T1>
-  inline static out_eT from(const BaseCube<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  };
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-out_eT
-conv_to<out_eT>::from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  arma_type_check(( is_supported_elem_type<out_eT>::value == false ));
-  
-  const unwrap<T1>      tmp(in.get_ref());
-  const Mat<in_eT>& X = tmp.M;
-  
-  arma_debug_check( (X.n_elem != 1), "conv_to(): given object doesn't have exactly one element" );
-  
-  return out_eT(X.mem[0]);
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-out_eT
-conv_to<out_eT>::from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  arma_type_check(( is_supported_elem_type<out_eT>::value == false ));
-  
-  const unwrap<T1>      tmp(in.get_ref());
-  const Mat<in_eT>& X = tmp.M;
-  
-  arma_debug_check( (X.n_elem != 1), "conv_to(): given object doesn't have exactly one element" );
-  
-  out_eT out;
-  
-  arrayops::convert_cx_scalar(out, X.mem[0]);
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-out_eT
-conv_to<out_eT>::from(const BaseCube<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  arma_type_check(( is_supported_elem_type<out_eT>::value == false ));
-  
-  const unwrap_cube<T1>  tmp(in.get_ref());
-  const Cube<in_eT>& X = tmp.M;
-  
-  arma_debug_check( (X.n_elem != 1), "conv_to(): given object doesn't have exactly one element" );
-  
-  return out_eT(X.mem[0]);
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-out_eT
-conv_to<out_eT>::from(const BaseCube<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  arma_type_check(( is_supported_elem_type<out_eT>::value == false ));
-  
-  const unwrap_cube<T1>  tmp(in.get_ref());
-  const Cube<in_eT>& X = tmp.M;
-  
-  arma_debug_check( (X.n_elem != 1), "conv_to(): given object doesn't have exactly one element" );
-  
-  out_eT out;
-  
-  arrayops::convert_cx_scalar(out, X.mem[0]);
-  
-  return out;
-  }
-
-
-
-//! conversion to Armadillo matrices from Armadillo Base objects,
-//! as well as from std::vector, itpp::Mat and itpp::Vec
-template<typename out_eT>
-class conv_to< Mat<out_eT> >
-  {
-  public:
-  
-  template<typename in_eT, typename T1>
-  inline static Mat<out_eT> from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT, typename T1>
-  inline static Mat<out_eT> from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  
-  
-  
-  template<typename in_eT>
-  inline static Mat<out_eT> from(const std::vector<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT>
-  inline static Mat<out_eT> from(const std::vector<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  
-  
-  
-  template<typename in_eT>
-  inline static Mat<out_eT> from(const itpp::Mat<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT>
-  inline static Mat<out_eT> from(const itpp::Mat<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  
-  
-  
-  template<typename in_eT>
-  inline static Mat<out_eT> from(const itpp::Vec<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT>
-  inline static Mat<out_eT> from(const itpp::Vec<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  };
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-Mat<out_eT>
-conv_to< Mat<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap<T1>      tmp(in.get_ref());
-  const Mat<in_eT>& X = tmp.M;
-  
-  Mat<out_eT> out(X.n_rows, X.n_cols);
-  
-  arrayops::convert( out.memptr(), X.memptr(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-Mat<out_eT>
-conv_to< Mat<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap<T1>      tmp(in.get_ref());
-  const Mat<in_eT>& X = tmp.M;
-  
-  Mat<out_eT> out(X.n_rows, X.n_cols);
-  
-  arrayops::convert_cx( out.memptr(), X.memptr(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Mat<out_eT>
-conv_to< Mat<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Mat<out_eT> out(in.size(), 1);
-  
-  typename std::vector<in_eT>::const_iterator in_begin = in.begin();
-  typename std::vector<in_eT>::const_iterator in_end   = in.end();
-  
-  typename Mat<out_eT>::iterator out_begin = out.begin();
-  typename Mat<out_eT>::iterator out_end   = out.end();
-  
-  typename std::vector<in_eT>::const_iterator in_it;
-  typename Mat<out_eT>::iterator              out_it;
-  
-  for(in_it = in_begin, out_it = out_begin; (in_it != in_end) && (out_it != out_end); ++in_it, ++out_it)
-    {
-    (*out_it) = out_eT(*in_it);
-    }
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Mat<out_eT>
-conv_to< Mat<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Mat<out_eT> out(in.size(), 1);
-  
-  typename std::vector<in_eT>::const_iterator in_begin = in.begin();
-  typename std::vector<in_eT>::const_iterator in_end   = in.end();
-  
-  typename Mat<out_eT>::iterator out_begin = out.begin();
-  typename Mat<out_eT>::iterator out_end   = out.end();
-  
-  typename std::vector<in_eT>::const_iterator in_it;
-  typename Mat<out_eT>::iterator              out_it;
-  
-  for(in_it = in_begin, out_it = out_begin; (in_it != in_end) && (out_it != out_end); ++in_it, ++out_it)
-    {
-          out_eT& out_elem = (*out_it);
-    const in_eT&  in_elem  = (*in_it);
-    
-    arrayops::convert_cx_scalar(out_elem, in_elem);
-    }
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Mat<out_eT>
-conv_to< Mat<out_eT> >::from(const itpp::Mat<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Mat<out_eT> out(in.rows(), in.cols());
-  
-  arrayops::convert( out.memptr(), in._data(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Mat<out_eT>
-conv_to< Mat<out_eT> >::from(const itpp::Mat<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Mat<out_eT> out(in.rows(), in.cols());
-  
-  arrayops::convert_cx( out.memptr(), in._data(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Mat<out_eT>
-conv_to< Mat<out_eT> >::from(const itpp::Vec<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Mat<out_eT> out(in.length(), 1);
-  
-  arrayops::convert( out.memptr(), in._data(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Mat<out_eT>
-conv_to< Mat<out_eT> >::from(const itpp::Vec<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Mat<out_eT> out(in.length(), 1);
-  
-  arrayops::convert_cx( out.memptr(), in._data(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-//! conversion to Armadillo row vectors from Armadillo Base objects,
-//! as well as from std::vector, itpp::Mat and itpp::Vec
-template<typename out_eT>
-class conv_to< Row<out_eT> >
-  {
-  public:
-  
-  template<typename in_eT, typename T1>
-  inline static Row<out_eT> from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT, typename T1>
-  inline static Row<out_eT> from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  
-  
-  
-  template<typename in_eT>
-  inline static Row<out_eT> from(const std::vector<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT>
-  inline static Row<out_eT> from(const std::vector<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  
-  
-  
-  template<typename in_eT>
-  inline static Row<out_eT> from(const itpp::Mat<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT>
-  inline static Row<out_eT> from(const itpp::Mat<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  
-  
-  
-  template<typename in_eT>
-  inline static Row<out_eT> from(const itpp::Vec<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT>
-  inline static Row<out_eT> from(const itpp::Vec<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  };
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-Row<out_eT>
-conv_to< Row<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap<T1>      tmp(in.get_ref());
-  const Mat<in_eT>& X = tmp.M;
-  
-  arma_debug_check( (X.is_vec() == false), "conv_to(): given object can't be interpreted as a vector" );
-  
-  Row<out_eT> out(X.n_elem);
-  
-  arrayops::convert( out.memptr(), X.memptr(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-Row<out_eT>
-conv_to< Row<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap<T1>      tmp(in.get_ref());
-  const Mat<in_eT>& X = tmp.M;
-  
-  arma_debug_check( (X.is_vec() == false), "conv_to(): given object can't be interpreted as a vector" );
-  
-  Row<out_eT> out(X.n_rows, X.n_cols);
-  
-  arrayops::convert_cx( out.memptr(), X.memptr(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Row<out_eT>
-conv_to< Row<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Row<out_eT> out( in.size() );
-  
-  typename std::vector<in_eT>::const_iterator in_begin = in.begin();
-  typename std::vector<in_eT>::const_iterator in_end   = in.end();
-  
-  typename Row<out_eT>::iterator out_begin = out.begin();
-  typename Row<out_eT>::iterator out_end   = out.end();
-  
-  typename std::vector<in_eT>::const_iterator in_it;
-  typename Row<out_eT>::iterator              out_it;
-  
-  for(in_it = in_begin, out_it = out_begin; (in_it != in_end) && (out_it != out_end); ++in_it, ++out_it)
-    {
-    (*out_it) = out_eT(*in_it);
-    }
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Row<out_eT>
-conv_to< Row<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Row<out_eT> out( in.size() );
-  
-  typename std::vector<in_eT>::const_iterator in_begin = in.begin();
-  typename std::vector<in_eT>::const_iterator in_end   = in.end();
-  
-  typename Row<out_eT>::iterator out_begin = out.begin();
-  typename Row<out_eT>::iterator out_end   = out.end();
-  
-  typename std::vector<in_eT>::const_iterator in_it;
-  typename Row<out_eT>::iterator              out_it;
-  
-  for(in_it = in_begin, out_it = out_begin; (in_it != in_end) && (out_it != out_end); ++in_it, ++out_it)
-    {
-          out_eT& out_elem = (*out_it);
-    const in_eT&  in_elem  = (*in_it);
-    
-    arrayops::convert_cx_scalar(out_elem, in_elem);
-    }
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Row<out_eT>
-conv_to< Row<out_eT> >::from(const itpp::Mat<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const bool is_vec = ( (in.rows() == 1) || (in.cols() == 1) );
-  
-  arma_debug_check( (is_vec == false), "conv_to(): given object can't be interpreted as a vector" );
-  
-  Row<out_eT> out(in.rows() * in.cols());
-  
-  arrayops::convert( out.memptr(), in._data(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Row<out_eT>
-conv_to< Row<out_eT> >::from(const itpp::Mat<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  //const bool is_vec = ( (in.rows() == 1) || (in.cols() == 1) );
-  
-  Row<out_eT> out(in.rows() * in.cols());
-  
-  arrayops::convert_cx( out.memptr(), in._data(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Row<out_eT>
-conv_to< Row<out_eT> >::from(const itpp::Vec<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Row<out_eT> out(in.length());
-  
-  arrayops::convert( out.memptr(), in._data(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Row<out_eT>
-conv_to< Row<out_eT> >::from(const itpp::Vec<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Row<out_eT> out(in.length());
-  
-  arrayops::convert_cx( out.memptr(), in._data(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-//! conversion to Armadillo column vectors from Armadillo Base objects,
-//! as well as from std::vector, itpp::Mat and itpp::Vec
-template<typename out_eT>
-class conv_to< Col<out_eT> >
-  {
-  public:
-  
-  template<typename in_eT, typename T1>
-  inline static Col<out_eT> from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT, typename T1>
-  inline static Col<out_eT> from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  
-  
-  
-  template<typename in_eT>
-  inline static Col<out_eT> from(const std::vector<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT>
-  inline static Col<out_eT> from(const std::vector<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  
-  
-  
-  template<typename in_eT>
-  inline static Col<out_eT> from(const itpp::Mat<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT>
-  inline static Col<out_eT> from(const itpp::Mat<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  
-  
-  
-  template<typename in_eT>
-  inline static Col<out_eT> from(const itpp::Vec<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT>
-  inline static Col<out_eT> from(const itpp::Vec<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  };
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-Col<out_eT>
-conv_to< Col<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap<T1>      tmp(in.get_ref());
-  const Mat<in_eT>& X = tmp.M;
-  
-  arma_debug_check( (X.is_vec() == false), "conv_to(): given object can't be interpreted as a vector" );
-  
-  Col<out_eT> out(X.n_elem);
-  
-  arrayops::convert( out.memptr(), X.memptr(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-Col<out_eT>
-conv_to< Col<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap<T1>      tmp(in.get_ref());
-  const Mat<in_eT>& X = tmp.M;
-  
-  arma_debug_check( (X.is_vec() == false), "conv_to(): given object can't be interpreted as a vector" );
-  
-  Col<out_eT> out(X.n_rows, X.n_cols);
-  
-  arrayops::convert_cx( out.memptr(), X.memptr(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Col<out_eT>
-conv_to< Col<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Col<out_eT> out( in.size() );
-  
-  typename std::vector<in_eT>::const_iterator in_begin = in.begin();
-  typename std::vector<in_eT>::const_iterator in_end   = in.end();
-  
-  typename Col<out_eT>::iterator out_begin = out.begin();
-  typename Col<out_eT>::iterator out_end   = out.end();
-  
-  typename std::vector<in_eT>::const_iterator in_it;
-  typename Col<out_eT>::iterator              out_it;
-  
-  for(in_it = in_begin, out_it = out_begin; (in_it != in_end) && (out_it != out_end); ++in_it, ++out_it)
-    {
-    (*out_it) = out_eT(*in_it);
-    }
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Col<out_eT>
-conv_to< Col<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Col<out_eT> out( in.size() );
-  
-  typename std::vector<in_eT>::const_iterator in_begin = in.begin();
-  typename std::vector<in_eT>::const_iterator in_end   = in.end();
-  
-  typename Col<out_eT>::iterator out_begin = out.begin();
-  typename Col<out_eT>::iterator out_end   = out.end();
-  
-  typename std::vector<in_eT>::const_iterator in_it;
-  typename Col<out_eT>::iterator              out_it;
-  
-  for(in_it = in_begin, out_it = out_begin; (in_it != in_end) && (out_it != out_end); ++in_it, ++out_it)
-    {
-          out_eT& out_elem = (*out_it);
-    const in_eT&  in_elem  = (*in_it);
-    
-    arrayops::convert_cx_scalar(out_elem, in_elem);
-    }
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Col<out_eT>
-conv_to< Col<out_eT> >::from(const itpp::Mat<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const bool is_vec = ( (in.rows() == 1) || (in.cols() == 1) );
-  
-  arma_debug_check( (is_vec == false), "conv_to(): given object can't be interpreted as a vector" );
-  
-  Col<out_eT> out(in.rows() * in.cols());
-  
-  arrayops::convert( out.memptr(), in._data(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Col<out_eT>
-conv_to< Col<out_eT> >::from(const itpp::Mat<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  //const bool is_vec = ( (in.rows() == 1) || (in.cols() == 1) );
-  
-  Col<out_eT> out(in.rows() * in.cols());
-  
-  arrayops::convert_cx( out.memptr(), in._data(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Col<out_eT>
-conv_to< Col<out_eT> >::from(const itpp::Vec<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Col<out_eT> out( in.length() );
-  
-  arrayops::convert( out.memptr(), in._data(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT>
-inline
-Col<out_eT>
-conv_to< Col<out_eT> >::from(const itpp::Vec<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  Col<out_eT> out( in.length() );
-  
-  arrayops::convert_cx( out.memptr(), in._data(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-//! conversion to Armadillo cubes from Armadillo BaseCube objects
-template<typename out_eT>
-class conv_to< Cube<out_eT> >
-  {
-  public:
-  
-  template<typename in_eT, typename T1>
-  inline static Cube<out_eT> from(const BaseCube<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT, typename T1>
-  inline static Cube<out_eT> from(const BaseCube<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  };
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-Cube<out_eT>
-conv_to< Cube<out_eT> >::from(const BaseCube<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap_cube<T1>  tmp( in.get_ref() );
-  const Cube<in_eT>& X = tmp.M;
-  
-  Cube<out_eT> out(X.n_rows, X.n_cols, X.n_slices);
-  
-  arrayops::convert( out.memptr(), X.memptr(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-Cube<out_eT>
-conv_to< Cube<out_eT> >::from(const BaseCube<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap_cube<T1>  tmp( in.get_ref() );
-  const Cube<in_eT>& X = tmp.M;
-  
-  Cube<out_eT> out(X.n_rows, X.n_cols, X.n_slices);
-  
-  arrayops::convert_cx( out.memptr(), X.memptr(), out.n_elem );
-  
-  return out;
-  }
-
-
-
-//! conversion to std::vector from Armadillo Base objects
-template<typename out_eT>
-class conv_to< std::vector<out_eT> >
-  {
-  public:
-  
-  template<typename in_eT, typename T1>
-  inline static std::vector<out_eT> from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT, typename T1>
-  inline static std::vector<out_eT> from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  };
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-std::vector<out_eT>
-conv_to< std::vector<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap<T1>      tmp(in.get_ref());
-  const Mat<in_eT>& X = tmp.M;
-  
-  arma_debug_check( (X.is_vec() == false), "conv_to(): given object can't be interpreted as a vector" );
-  
-  std::vector<out_eT> out(X.n_elem);
-  
-  typename Mat<in_eT>::const_iterator X_begin = X.begin();
-  typename Mat<in_eT>::const_iterator X_end   = X.end();
-
-  typename std::vector<out_eT>::iterator out_begin = out.begin();
-  typename std::vector<out_eT>::iterator out_end   = out.end();
-  
-  typename Mat<in_eT>::const_iterator    X_it;
-  typename std::vector<out_eT>::iterator out_it;
-  
-  for(X_it = X_begin, out_it = out_begin; (X_it != X_end) && (out_it != out_end); ++X_it, ++out_it)
-    {
-    (*out_it) = out_eT(*X_it);
-    }
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-std::vector<out_eT>
-conv_to< std::vector<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap<T1>      tmp(in.get_ref());
-  const Mat<in_eT>& X = tmp.M;
-  
-  arma_debug_check( (X.is_vec() == false), "conv_to(): given object can't be interpreted as a vector" );
-  
-  std::vector<out_eT> out(X.n_elem);
-  
-  typename Mat<in_eT>::const_iterator X_begin = X.begin();
-  typename Mat<in_eT>::const_iterator X_end   = X.end();
-
-  typename std::vector<out_eT>::iterator out_begin = out.begin();
-  typename std::vector<out_eT>::iterator out_end   = out.end();
-  
-  typename Mat<in_eT>::const_iterator    X_it;
-  typename std::vector<out_eT>::iterator out_it;
-  
-  for(X_it = X_begin, out_it = out_begin; (X_it != X_end) && (out_it != out_end); ++X_it, ++out_it)
-    {
-          out_eT& out_elem = (*out_it);
-    const in_eT&  X_elem   = (*X_it);
-    
-    arrayops::convert_cx_scalar(out_elem, X_elem);
-    }
-  
-  return out;
-  }
-
-
-
-//! conversion to itpp::Mat from Armadillo Base objects
-template<typename out_eT>
-class conv_to< itpp::Mat<out_eT> >
-  {
-  public:
-  
-  template<typename in_eT, typename T1>
-  inline static itpp::Mat<out_eT> from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT, typename T1>
-  inline static itpp::Mat<out_eT> from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  };
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-itpp::Mat<out_eT>
-conv_to< itpp::Mat<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap<T1>      tmp( in.get_ref() );
-  const Mat<in_eT>& X = tmp.M;
-  
-  itpp::Mat<out_eT> out(X.n_rows, X.n_cols);
-  
-  arrayops::convert( out._data(), X.memptr(), X.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-itpp::Mat<out_eT>
-conv_to< itpp::Mat<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap<T1>      tmp( in.get_ref() );
-  const Mat<in_eT>& X = tmp.M;
-  
-  itpp::Mat<out_eT> out(X.n_rows, X.n_cols);
-  
-  arrayops::convert_cx( out._data(), X.memptr(), X.n_elem );
-  
-  return out;
-  }
-
-
-
-
-//! conversion to itpp::Vec from Armadillo Base objects
-template<typename out_eT>
-class conv_to< itpp::Vec<out_eT> >
-  {
-  public:
-  
-  template<typename in_eT, typename T1>
-  inline static itpp::Vec<out_eT> from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
-  
-  template<typename in_eT, typename T1>
-  inline static itpp::Vec<out_eT> from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
-  };
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-itpp::Vec<out_eT>
-conv_to< itpp::Vec<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap<T1>      tmp( in.get_ref() );
-  const Mat<in_eT>& X = tmp.M;
-  
-  arma_debug_check( (X.is_vec() == false), "conv_to(): given object can't be interpreted as a vector" );
-  
-  itpp::Vec<out_eT> out(X.n_elem);
-  
-  arrayops::convert( out._data(), X.memptr(), X.n_elem );
-  
-  return out;
-  }
-
-
-
-template<typename out_eT>
-template<typename in_eT, typename T1>
-inline
-itpp::Vec<out_eT>
-conv_to< itpp::Vec<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  const unwrap<T1>      tmp( in.get_ref() );
-  const Mat<in_eT>& X = tmp.M;
-  
-  itpp::Vec<out_eT> out(X.n_elem);
-  
-  arrayops::convert_cx( out._data(), X.memptr(), X.n_elem );
-  
-  return out;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_cor.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_cor
-//! @{
-
-
-
-template<typename T1>
-inline
-const Op<T1, op_cor>
-cor(const Base<typename T1::elem_type,T1>& X, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (norm_type > 1), "cor(): norm_type must be 0 or 1");
-  
-  return Op<T1, op_cor>(X.get_ref(), norm_type, 0);
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const Glue<T1,T2,glue_cor>
-cor(const Base<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (norm_type > 1), "cor(): norm_type must be 0 or 1");
-  
-  return Glue<T1, T2, glue_cor>(A.get_ref(), B.get_ref(), norm_type);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_cov.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_cov
-//! @{
-
-
-
-template<typename T1>
-inline
-const Op<T1, op_cov>
-cov(const Base<typename T1::elem_type,T1>& X, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (norm_type > 1), "cov(): norm_type must be 0 or 1");
-
-  return Op<T1, op_cov>(X.get_ref(), norm_type, 0);
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const Glue<T1,T2,glue_cov>
-cov(const Base<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (norm_type > 1), "cov(): norm_type must be 0 or 1");
-  
-  return Glue<T1, T2, glue_cov>(A.get_ref(), B.get_ref(), norm_type);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_cross.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_cross
-//! @{
-
-
-
-//! cross product (only valid for 3 dimensional vectors)
-template<typename T1, typename T2>
-inline
-const Glue<T1, T2, glue_cross>
-cross(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Glue<T1, T2, glue_cross>(X.get_ref(), Y.get_ref());
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_cumsum.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_cumsum
-//! @{
-
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_cumsum_mat>
-cumsum(const Base<typename T1::elem_type,T1>& X, const uword dim = 0)
-  {
-  arma_extra_debug_sigprint();
-
-  return Op<T1, op_cumsum_mat>(X.get_ref(), dim, 0);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const Op<Row<eT>, op_cumsum_vec>
-cumsum(const Row<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<Row<eT>, op_cumsum_vec>(A);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const Op<Col<eT>, op_cumsum_vec>
-cumsum(const Col<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<Col<eT>, op_cumsum_vec>(A);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const Op<subview_row<eT>, op_cumsum_vec>
-cumsum(const subview_row<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<subview_row<eT>, op_cumsum_vec>(A);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const Op<subview_col<eT>, op_cumsum_vec>
-cumsum(const subview_col<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<subview_col<eT>, op_cumsum_vec>(A);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const Op<diagview<eT>, op_cumsum_vec>
-cumsum(const diagview<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<diagview<eT>, op_cumsum_vec>(A);
-  }
-
-
-
-template<typename eT, typename T1>
-arma_inline
-const Op<subview_elem1<eT,T1>, op_cumsum_vec>
-cumsum(const subview_elem1<eT,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<subview_elem1<eT,T1>, op_cumsum_vec>(A);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_det.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_det
-//! @{
-
-
-
-//! determinant of mat
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::elem_type
-det
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const bool slow = false,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  return auxlib::det(X, slow);
-  }
-
-
-
-//! determinant of diagmat
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::elem_type
-det
-  (
-  const Op<T1, op_diagmat>& X,
-  const bool slow = false
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(slow);
-  
-  typedef typename T1::elem_type eT;
-  
-  const diagmat_proxy<T1> A(X.m);
-  
-  const uword A_n_elem = A.n_elem;
-  
-  eT val = eT(1);
-  
-  for(uword i=0; i<A_n_elem; ++i)
-    {
-    val *= A[i];
-    }
-  
-  return val;
-  }
-
-
-
-//! determinant of inv(A), without doing the inverse operation
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::elem_type
-det
-  (
-  const Op<T1,op_inv>& in,
-  const bool slow = false,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename T1::elem_type eT;
-  
-  eT tmp = det(in.m, slow);
-  arma_warn( (tmp == eT(0)), "det(): warning: denominator is zero" );
-  
-  return eT(1) / tmp;
-  }
-
-
-
-//! determinant of trans(A)
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::elem_type
-det
-  (
-  const Op<T1,op_htrans>& in,
-  const bool slow = false,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk1 = 0,
-  const typename         arma_not_cx<typename T1::elem_type>::result* junk2 = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk1);
-  arma_ignore(junk2);
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(in.m);
-  const Mat<eT>& X = tmp.M;
-  
-  return det(X, slow);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_diagmat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_diagmat
-//! @{
-
-
-//! interpret a matrix or a vector as a diagonal matrix (i.e. off-diagonal entries are zero)
-template<typename T1>
-arma_inline
-const Op<T1, op_diagmat>
-diagmat(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_diagmat>(X.get_ref());
-  }
-
-
-
-// TODO:
-// create "op_diagmat2", to allow placement of vector onto a sub- or super- diagonal.
-// op_diagmat2 is required, as other code assumes that op_diagmat indicates only the main diagonal)
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_diagvec.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_diagvec
-//! @{
-
-
-//! extract a diagonal from a matrix
-template<typename T1>
-arma_inline
-const Op<T1, op_diagvec>
-diagvec(const Base<typename T1::elem_type,T1>& X, const sword diag_id = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_diagvec>(X.get_ref(), ((diag_id < 0) ? -diag_id : diag_id), ((diag_id < 0) ? 1 : 0) );
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_dot.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_dot
-//! @{
-
-
-template<typename T1, typename T2>
-arma_inline
-arma_warn_unused
-typename T1::elem_type
-dot
-  (
-  const Base<typename T1::elem_type,T1>& A,
-  const Base<typename T1::elem_type,T2>& B
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return op_dot::apply(A,B);
-  }
-
-
-
-template<typename T1, typename T2>
-arma_inline
-arma_warn_unused
-typename T1::elem_type
-norm_dot
-  (
-  const Base<typename T1::elem_type,T1>& A, 
-  const Base<typename T1::elem_type,T2>& B,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return op_norm_dot::apply(A,B);
-  }
-
-
-
-//
-// cdot
-
-
-
-template<typename T1, typename T2>
-arma_inline
-arma_warn_unused
-typename T1::elem_type
-cdot
-  (
-  const Base<typename T1::elem_type,T1>& A,
-  const Base<typename T1::elem_type,T2>& B,
-  const typename arma_cx_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return op_cdot::apply(A,B);
-  }
-
-
-
-template<typename T1, typename T2>
-arma_inline
-arma_warn_unused
-typename T1::elem_type
-cdot
-  (
-  const Base<typename T1::elem_type,T1>& A,
-  const Base<typename T1::elem_type,T2>& B,
-  const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return op_dot::apply(A,B);
-  }
-
-
-
-
-// convert dot(htrans(x), y) to cdot(x,y)
-
-template<typename T1, typename T2>
-arma_inline
-arma_warn_unused
-typename T1::elem_type
-dot
-  (
-  const Op<T1, op_htrans>& A,
-  const Base<typename T1::elem_type,T2>& B,
-  const typename arma_cx_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return cdot(A.m, B);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_eig.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// Copyright (C) 2009 Edmund Highcock
-// Copyright (C) 2011 Stanislav Funiak
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_eig
-//! @{
-
-
-//
-// symmetric/hermitian matrices
-//
-
-
-//! Eigenvalues of real/complex symmetric/hermitian matrix X
-template<typename T1>
-inline
-bool
-eig_sym
-  (
-         Col<typename T1::pod_type>&     eigval,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  // unwrap_check not used as T1::elem_type and T1::pod_type may not be the same.
-  // furthermore, it doesn't matter if X is an alias of eigval, as auxlib::eig_sym() makes a copy of X
-  
-  const bool status = auxlib::eig_sym(eigval, X);
-  
-  if(status == false)
-    {
-    eigval.reset();
-    arma_bad("eig_sym(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-//! Eigenvalues of real/complex symmetric/hermitian matrix X
-template<typename T1>
-inline
-Col<typename T1::pod_type>
-eig_sym
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  Col<typename T1::pod_type> out;
-  const bool status = auxlib::eig_sym(out, X);
-
-  if(status == false)
-    {
-    out.reset();
-    arma_bad("eig_sym(): failed to converge");
-    }
-  
-  return out;
-  }
-
-
-
-//! Eigenvalues and eigenvectors of real/complex symmetric/hermitian matrix X
-template<typename T1> 
-inline
-bool
-eig_sym
-  (
-         Col<typename T1::pod_type>&     eigval,
-         Mat<typename T1::elem_type>&    eigvec,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  arma_debug_check( ( ((void*)(&eigval)) == ((void*)(&eigvec)) ), "eig_sym(): eigval is an alias of eigvec" );
-  
-  const bool status = auxlib::eig_sym(eigval, eigvec, X);
-  
-  if(status == false)
-    {
-    eigval.reset();
-    eigvec.reset();
-    arma_bad("eig_sym(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-//
-// general matrices
-//
-
-
-
-//! Eigenvalues and eigenvectors (both left and right) of general real/complex square matrix X
-template<typename T1>
-inline
-bool
-eig_gen
-  (
-         Col< std::complex<typename T1::pod_type> >& eigval, 
-         Mat<typename T1::elem_type>&                l_eigvec,
-         Mat<typename T1::elem_type>&                r_eigvec,
-  const Base<typename T1::elem_type,T1>&             X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  arma_debug_check
-    (
-    ((&l_eigvec) == (&r_eigvec)),
-    "eig_gen(): l_eigvec is an alias of r_eigvec"
-    );
-  
-  arma_debug_check
-    (
-      (
-      (((void*)(&eigval)) == ((void*)(&l_eigvec)))
-      ||
-      (((void*)(&eigval)) == ((void*)(&r_eigvec)))
-      ),
-    "eig_gen(): eigval is an alias of l_eigvec or r_eigvec"
-    );
-  
-  const bool status = auxlib::eig_gen(eigval, l_eigvec, r_eigvec, X, 'b');
-  
-  if(status == false)
-    {
-    eigval.reset();
-    l_eigvec.reset();
-    r_eigvec.reset();
-    arma_bad("eig_gen(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-//! Eigenvalues and eigenvectors of general real square matrix X.
-//! Optional argument 'side' specifies which eigenvectors should be computed:
-//! 'r' for right (default) and 'l' for left.
-template<typename eT, typename T1>
-inline
-bool
-eig_gen
-  (
-        Col< std::complex<eT> >& eigval, 
-        Mat< std::complex<eT> >& eigvec,
-  const Base<eT, T1>&            X, 
-  const char                     side = 'r',
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  //std::cout << "real" << std::endl;
-  
-  arma_debug_check( ( ((void*)(&eigval)) == ((void*)(&eigvec)) ), "eig_gen(): eigval is an alias of eigvec" );
-  
-  Mat<eT> dummy_eigvec;
-  Mat<eT> tmp_eigvec;
-  
-  bool status;
-  
-  switch(side)
-    {
-    case 'r':
-      status = auxlib::eig_gen(eigval, dummy_eigvec, tmp_eigvec, X, side);
-      break;
-    
-    case 'l':
-      status = auxlib::eig_gen(eigval, tmp_eigvec, dummy_eigvec, X, side);
-      break;
-      
-    default:
-      arma_stop("eig_gen(): parameter 'side' is invalid");
-      status = false;
-    }
-  
-  if(status == false)
-    {
-    eigval.reset();
-    eigvec.reset();
-    arma_bad("eig_gen(): failed to converge", false);
-    }
-  else
-    {
-    const uword n = eigval.n_elem;
-    
-    if(n > 0)
-      {
-      eigvec.set_size(n,n);
-      
-      for(uword j=0; j<n; ++j)
-        {
-        if( (j < n-1) && (eigval[j] == std::conj(eigval[j+1])) )
-          {
-          // eigvec.col(j)   = Mat< std::complex<eT> >( tmp_eigvec.col(j),  tmp_eigvec.col(j+1) );
-          // eigvec.col(j+1) = Mat< std::complex<eT> >( tmp_eigvec.col(j), -tmp_eigvec.col(j+1) );
-          
-          for(uword i=0; i<n; ++i)
-            {
-            eigvec.at(i,j)   = std::complex<eT>( tmp_eigvec.at(i,j),  tmp_eigvec.at(i,j+1) );
-            eigvec.at(i,j+1) = std::complex<eT>( tmp_eigvec.at(i,j), -tmp_eigvec.at(i,j+1) );
-            }
-          
-          ++j;
-          }
-        else
-          {
-          // eigvec.col(i) = tmp_eigvec.col(i);
-          
-          for(uword i=0; i<n; ++i)
-            {
-            eigvec.at(i,j) = std::complex<eT>(tmp_eigvec.at(i,j), eT(0));
-            }
-          
-          }
-        }
-      }
-    }
-  
-  return status;
-  }
-
-
-
-//! Eigenvalues and eigenvectors of general complex square matrix X
-//! Optional argument 'side' specifies which eigenvectors should be computed:
-//! 'r' for right (default) and 'l' for left.
-template<typename T, typename T1>
-inline
-bool
-eig_gen
-  (
-         Col<std::complex<T> >&    eigval, 
-         Mat<std::complex<T> >&    eigvec,
-  const Base<std::complex<T>, T1>& X, 
-  const char                       side = 'r',
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  //std::cout << "complex" << std::endl;
-  
-  arma_debug_check( ( ((void*)(&eigval)) == ((void*)(&eigvec)) ), "eig_gen(): eigval is an alias of eigvec" );
-  
-  Mat< std::complex<T> > dummy_eigvec;
-  
-  bool status;
-  
-  switch(side)
-    {
-    case 'r':
-      status = auxlib::eig_gen(eigval, dummy_eigvec, eigvec, X, side);
-      break;
-    
-    case 'l':
-      status = auxlib::eig_gen(eigval, eigvec, dummy_eigvec, X, side);
-      break;
-      
-    default:
-      arma_stop("eig_gen(): parameter 'side' is invalid");
-      status = false;
-    }
-  
-  if(status == false)
-    {
-    eigval.reset();
-    eigvec.reset();
-    arma_bad("eig_gen(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/fn_elem.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,625 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_elem
-//! @{
-
-
-
-//
-// find
-
-template<typename eT, typename T1>
-inline
-const mtOp<uword, T1, op_find>
-find(const Base<eT,T1>& X, const uword k = 0, const char* direction = "first")
-  {
-  arma_extra_debug_sigprint();
-  
-  const char sig = direction[0];
-  
-  arma_debug_check
-    (
-    (sig != 'f' && sig != 'F' && sig != 'l' && sig != 'L'),
-    "find(): 3rd input argument must be \"first\" or \"last\""
-    );
-  
-  const uword type = (sig == 'f' || sig == 'F') ? 0 : 1;
-  
-  return mtOp<uword, T1, op_find>(X.get_ref(), k, type);
-  }
-
-
-
-//
-// real
-
-template<typename T1>
-arma_inline
-const T1&
-real(const Base<typename T1::pod_type, T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return X.get_ref();
-  }
-
-
-
-template<typename T1>
-arma_inline
-const T1&
-real(const BaseCube<typename T1::pod_type, T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return X.get_ref();
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<typename T1::pod_type, T1, op_real>
-real(const Base<std::complex<typename T1::pod_type>, T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<typename T1::pod_type, T1, op_real>( X.get_ref() );
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<typename T1::pod_type, T1, op_real>
-real(const BaseCube<std::complex<typename T1::pod_type>, T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<typename T1::pod_type, T1, op_real>( X.get_ref() );
-  }
-
-
-
-//
-// imag
-
-template<typename T1>
-inline
-const Gen<typename T1::pod_type, gen_zeros>
-imag(const Base<typename T1::pod_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Proxy<T1> A(X.get_ref());
-  
-  return Gen<typename T1::pod_type, gen_zeros>(A.get_n_rows(), A.get_n_cols());
-  }
-
-
-
-template<typename T1>
-inline
-const GenCube<typename T1::pod_type, gen_zeros>
-imag(const BaseCube<typename T1::pod_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const ProxyCube<T1> A(X.get_ref());
-  
-  return GenCube<typename T1::pod_type, gen_zeros>(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<typename T1::pod_type, T1, op_imag>
-imag(const Base<std::complex<typename T1::pod_type>, T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<typename T1::pod_type, T1, op_imag>( X.get_ref() );
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<typename T1::pod_type, T1, op_imag>
-imag(const BaseCube<std::complex<typename T1::pod_type>,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<typename T1::pod_type, T1, op_imag>( X.get_ref() );
-  }
-
-
-
-//
-// log
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_log>
-log(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_log>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_log>
-log(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_log>(A.get_ref());
-  }
-
-
-
-//
-// log2
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_log2>
-log2(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_log2>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_log2>
-log2(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_log2>(A.get_ref());
-  }
-
-
-
-//
-// log10
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_log10>
-log10(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_log10>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_log10>
-log10(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_log10>(A.get_ref());
-  }
-
-
-
-//
-// exp
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_exp>
-exp(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_exp>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_exp>
-exp(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_exp>(A.get_ref());
-  }
-
-
-
-// exp2
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_exp2>
-exp2(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_exp2>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_exp2>
-exp2(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_exp2>(A.get_ref());
-  }
-
-
-
-// exp10
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_exp10>
-exp10(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_exp10>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_exp10>
-exp10(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_exp10>(A.get_ref());
-  }
-
-
-
-//
-// abs
-
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_abs>
-abs(const Base<typename T1::elem_type,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  return eOp<T1, eop_abs>(X.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_abs>
-abs(const BaseCube<typename T1::elem_type,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  return eOpCube<T1, eop_abs>(X.get_ref());
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<typename T1::pod_type, T1, op_abs>
-abs(const Base<std::complex<typename T1::pod_type>, T1>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  return mtOp<typename T1::pod_type, T1, op_abs>( X.get_ref() );
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<typename T1::pod_type, T1, op_abs>
-abs(const BaseCube< std::complex<typename T1::pod_type>,T1>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  return mtOpCube<typename T1::pod_type, T1, op_abs>( X.get_ref() );
-  }
-
-
-
-//
-// square
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_square>
-square(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_square>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_square>
-square(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_square>(A.get_ref());
-  }
-
-
-
-//
-// sqrt
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_sqrt>
-sqrt(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_sqrt>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_sqrt>
-sqrt(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_sqrt>(A.get_ref());
-  }
-
-
-
-//
-// conj
-
-template<typename T1>
-arma_inline
-const T1&
-conj(const Base<typename T1::pod_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-
-  return A.get_ref();
-  }
-
-
-
-template<typename T1>
-arma_inline
-const T1&
-conj(const BaseCube<typename T1::pod_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-
-  return A.get_ref();
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_conj>
-conj(const Base<std::complex<typename T1::pod_type>,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-
-  return eOp<T1, eop_conj>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_conj>
-conj(const BaseCube<std::complex<typename T1::pod_type>,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-
-  return eOpCube<T1, eop_conj>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const T1&
-conj(const eOp<T1, eop_conj>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return A.m;
-  }
-
-
-
-template<typename T1>
-arma_inline
-const T1&
-conj(const eOpCube<T1, eop_conj>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return A.m;
-  }
-
-
-
-// TODO: this needs a more elaborate template restriction mechanism to work properly,
-//       i.e. an overloaded version of thus function should do nothing if the input type is non-complex
-// 
-// //! the conjugate of the transpose of a complex matrix is the same as the hermitian transpose
-// template<typename T1>
-// arma_inline
-// const Op<T1, op_htrans>
-// conj(const Op<T1, op_strans>& A)
-//   {
-//   arma_extra_debug_sigprint();
-//   
-//   return Op<T1, op_htrans>(A.m);
-//   }
-
-
-
-// pow
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_pow>
-pow(const Base<typename T1::elem_type,T1>& A, const typename T1::elem_type exponent)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_pow>(A.get_ref(), exponent);
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_pow>
-pow(const BaseCube<typename T1::elem_type,T1>& A, const typename T1::elem_type exponent)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_pow>(A.get_ref(), exponent);
-  }
-
-
-
-// pow, specialised handling (non-complex exponent for complex matrices)
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_pow>
-pow(const Base<typename T1::elem_type,T1>& A, const typename T1::elem_type::value_type exponent)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  return eOp<T1, eop_pow>(A.get_ref(), eT(exponent));
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_pow>
-pow(const BaseCube<typename T1::elem_type,T1>& A, const typename T1::elem_type::value_type exponent)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  return eOpCube<T1, eop_pow>(A.get_ref(), eT(exponent));
-  }
-
-
-
-//
-// floor
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_floor>
-floor(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_floor>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_floor>
-floor(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_floor>(A.get_ref());
-  }
-
-
-
-//
-// ceil
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_ceil>
-ceil(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_ceil>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_ceil>
-ceil(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_ceil>(A.get_ref());
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_eps.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup fn_eps
-//! @{
-
-
-
-//! \brief
-//! eps version for non-complex matrices and vectors
-template<typename T1>
-inline
-const eOp<T1, eop_eps>
-eps(const Base<typename T1::elem_type, T1>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  typedef typename T1::elem_type eT;
-  
-  return eOp<T1, eop_eps>(X.get_ref());
-  }
-
-
-
-//! \brief
-//! eps version for complex matrices and vectors
-template<typename T1>
-inline
-Mat< typename T1::pod_type >
-eps(const Base< std::complex<typename T1::pod_type>, T1>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  typedef typename T1::pod_type   T;
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(X.get_ref());
-  const Mat<eT>& A = tmp.M;
-  
-  Mat<T> out(A.n_rows, A.n_cols);
-  
-         T* out_mem = out.memptr();
-  const eT* A_mem   = A.memptr();
-  const uword n_elem  = A.n_elem;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = eop_aux::direct_eps( A_mem[i] );
-    }
-  
-  
-  return out;
-  }
-
-
-
-template<typename eT>
-arma_inline
-arma_warn_unused
-typename arma_integral_only<eT>::result
-eps(const eT& x)
-  {
-  arma_ignore(x);
-  
-  return eT(0);
-  }
-
-
-
-template<typename eT>
-arma_inline
-arma_warn_unused
-typename arma_float_only<eT>::result
-eps(const eT& x)
-  {
-  return eop_aux::direct_eps(x);
-  }
-
-
-
-template<typename T>
-arma_inline
-arma_warn_unused
-typename arma_float_only<T>::result
-eps(const std::complex<T>& x)
-  {
-  return eop_aux::direct_eps(x);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_eye.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_eye
-//! @{
-
-
-
-arma_inline
-const Gen<mat::elem_type, gen_ones_diag>
-eye(const uword n_rows, const uword n_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Gen<mat::elem_type, gen_ones_diag>(n_rows, n_cols);
-  }
-
-
-
-template<typename mat_type>
-arma_inline
-const Gen<typename mat_type::elem_type, gen_ones_diag>
-eye(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only<mat_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return Gen<typename mat_type::elem_type, gen_ones_diag>(n_rows, n_cols);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_flip.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_flip
-//! @{
-
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_flipud>
-flipud(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_flipud>(X.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_fliplr>
-fliplr(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_fliplr>(X.get_ref());
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_inv.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_inv
-//! @{
-
-
-
-//! delayed matrix inverse (general matrices)
-template<typename T1>
-arma_inline
-const Op<T1, op_inv>
-inv
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const bool slow = false,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return Op<T1, op_inv>(X.get_ref(), ((slow == false) ? 0 : 1), 0);
-  }
-
-
-
-//! remove the inverse operation if applied twice consecutively
-template<typename T1>
-arma_inline
-const T1&
-inv(const Op<T1, op_inv>& X, const bool slow = false)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(slow);
-  
-  return X.m;
-  }
-
-
-
-//! delayed matrix inverse (triangular matrices)
-template<typename T1>
-arma_inline
-const Op<T1, op_inv_tr>
-inv
-  (
-  const Op<T1, op_trimat>& X,
-  const bool slow = false,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(slow);
-  arma_ignore(junk);
-  
-  return Op<T1, op_inv_tr>(X.m, X.aux_uword_a, 0);
-  }
-
-
-
-//! delayed matrix inverse (symmetric positive definite matrices)
-template<typename T1>
-arma_inline
-const Op<T1, op_inv_sympd>
-inv
-  (
-  const Op<T1, op_sympd>& X,
-  const bool slow = false,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(slow);
-  arma_ignore(junk);
-  
-  return Op<T1, op_inv_sympd>(X.m, 0, 0);
-  }
-
-
-
-template<typename T1>
-inline
-bool
-inv
-  (
-         Mat<typename T1::elem_type>&    out,
-  const Base<typename T1::elem_type,T1>& X,
-  const bool slow = false,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  try
-    {
-    out = inv(X,slow);
-    }
-  catch(std::runtime_error&)
-    {
-    return false;
-    }
-  
-  return true;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_join.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_join
-//! @{
-
-
-
-template<typename T1, typename T2>
-inline
-const Glue<T1, T2, glue_join>
-join_cols(const Base<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Glue<T1, T2, glue_join>(A.get_ref(), B.get_ref(), 0);
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const Glue<T1, T2, glue_join>
-join_rows(const Base<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Glue<T1, T2, glue_join>(A.get_ref(), B.get_ref(), 1);
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const GlueCube<T1, T2, glue_join>
-join_slices(const BaseCube<typename T1::elem_type,T1>& A, const BaseCube<typename T1::elem_type,T2>& B)
-  {
-  arma_extra_debug_sigprint();
-  
-  return GlueCube<T1, T2, glue_join>(A.get_ref(), B.get_ref());
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_kron.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_kron
-//! @{
-
-
-
-//! \brief
-//! kronecker product of two matrices,
-//! with the matrices having the same element type
-template<typename T1, typename T2>
-arma_inline
-const Glue<T1,T2,glue_kron>
-kron(const Base<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B)
-  {
-  arma_extra_debug_sigprint();
-
-  return Glue<T1, T2, glue_kron>(A.get_ref(), B.get_ref());
-  }
-
-
-
-//! \brief
-//! kronecker product of two matrices,
-//! with the matrices having different element types
-template<typename T, typename T1, typename T2>
-inline
-Mat<typename eT_promoter<T1,T2>::eT>
-kron(const Base<std::complex<T>,T1>& X, const Base<T,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-
-  typedef typename std::complex<T> eT1;
-
-  promote_type<eT1,T>::check();
-  
-  const unwrap<T1> tmp1(X.get_ref());
-  const unwrap<T2> tmp2(Y.get_ref());
-  
-  const Mat<eT1>& A = tmp1.M;
-  const Mat<T  >& B = tmp2.M;
-
-  Mat<eT1> out;
-  
-  glue_kron::direct_kron(out, A, B);
-  
-  return out;
-  }
-
-
-
-//! \brief
-//! kronecker product of two matrices,
-//! with the matrices having different element types
-template<typename T, typename T1, typename T2>
-inline
-Mat<typename eT_promoter<T1,T2>::eT>
-kron(const Base<T,T1>& X, const Base<std::complex<T>,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-
-  typedef typename std::complex<T> eT2;  
-
-  promote_type<T,eT2>::check();
-  
-  const unwrap<T1> tmp1(X.get_ref());
-  const unwrap<T2> tmp2(Y.get_ref());
-  
-  const Mat<T  >& A = tmp1.M;
-  const Mat<eT2>& B = tmp2.M;
-
-  Mat<eT2> out;
-  
-  glue_kron::direct_kron(out, A, B);
-  
-  return out;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_log_det.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_log_det
-//! @{
-
-
-
-//! log determinant of mat
-template<typename T1>
-inline
-bool
-log_det
-  (
-        typename T1::elem_type&          out_val,
-        typename T1::pod_type&           out_sign,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return auxlib::log_det(out_val, out_sign, X);
-  }
-
-
-
-template<typename T1>
-inline
-void
-log_det
-  (
-        typename T1::elem_type& out_val,
-        typename T1::pod_type&  out_sign,
-  const Op<T1,op_diagmat>&      X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename T1::elem_type eT;
-  typedef typename T1::pod_type   T;
-  
-  const diagmat_proxy<T1> A(X.m);
-  
-  const uword N = A.n_elem;
-  
-  if(N == 0)
-    {
-    out_val  = eT(0);
-    out_sign =  T(1);
-    
-    return;
-    }
-  
-  const eT x = A[0];
-  
-  T  sign = (is_complex<eT>::value == false) ? ( (access::tmp_real(x) < T(0)) ? -1 : +1 ) : +1;
-  eT val  = (is_complex<eT>::value == false) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x);
-  
-  for(uword i=1; i<N; ++i)
-    {
-    const eT x = A[i];
-    
-    sign *= (is_complex<eT>::value == false) ? ( (access::tmp_real(x) < T(0)) ? -1 : +1 ) : +1;
-    val  += (is_complex<eT>::value == false) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x);
-    }
-  
-  out_val  = val;
-  out_sign = sign;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_lu.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_lu
-//! @{
-
-
-
-//! immediate lower upper decomposition, permutation info is embedded into L (similar to Matlab/Octave)
-template<typename T1>
-inline
-bool
-lu
-  (
-         Mat<typename T1::elem_type>&    L,
-         Mat<typename T1::elem_type>&    U,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  arma_debug_check( (&L == &U), "lu(): L and U are the same object");
-  
-  const bool status = auxlib::lu(L, U, X);
-  
-  if(status == false)
-    {
-    L.reset();
-    U.reset();
-    arma_bad("lu(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-//! immediate lower upper decomposition, also providing the permutation matrix
-template<typename T1>
-inline
-bool
-lu
-  (
-         Mat<typename T1::elem_type>&    L,
-         Mat<typename T1::elem_type>&    U, 
-         Mat<typename T1::elem_type>&    P,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  arma_debug_check( ( (&L == &U) || (&L == &P) || (&U == &P) ), "lu(): two or more output objects are the same object");
-  
-  const bool status = auxlib::lu(L, U, P, X);
-  
-  if(status == false)
-    {
-    L.reset();
-    U.reset();
-    P.reset();
-    arma_bad("lu(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_max.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_max
-//! @{
-
-
-//! \brief
-//! Delayed 'maximum values' operation.
-//! The dimension, along which the maxima are found, is set via 'dim'.
-//! For dim = 0, the maximum value of each column is found (i.e. searches by traversing across rows).
-//! For dim = 1, the maximum value of each row is found (i.e. searches by traversing across columns).
-//! The default is dim = 0.
-
-template<typename T1>
-arma_inline
-const Op<T1, op_max>
-max(const Base<typename T1::elem_type,T1>& X, const uword dim = 0)
-  {
-  arma_extra_debug_sigprint();
-
-  return Op<T1, op_max>(X.get_ref(), dim, 0);
-  }
-
-
-//! Immediate 'find the maximum value in a row vector' operation
-template<typename eT>
-inline
-arma_warn_unused
-eT
-max(const Row<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "max(): given object has no elements" );
-  
-  return op_max::direct_max(A.mem, A_n_elem);
-  }
-
-
-
-//! Immediate 'find the maximum value in a column vector' operation
-template<typename eT>
-inline
-arma_warn_unused
-eT
-max(const Col<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "max(): given object has no elements" );
-  
-  return op_max::direct_max(A.mem, A_n_elem);
-  }
-
-
-
-//! \brief
-//! Immediate 'find maximum value' operation,
-//! invoked, for example, by: max(max(A))
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::elem_type
-max(const Op<T1, op_max>& in)
-  {
-  arma_extra_debug_sigprint();
-  arma_extra_debug_print("max(): two consecutive max() calls detected");
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1> tmp1(in.m);
-  const Mat<eT>& X = tmp1.M;
-  
-  const uword X_n_elem = X.n_elem;
-  
-  arma_debug_check( (X_n_elem == 0), "max(): given object has no elements" );
-  
-  return op_max::direct_max(X.mem, X_n_elem);
-  }
-
-
-
-template<typename T1>
-arma_inline
-const Op< Op<T1, op_max>, op_max>
-max(const Op<T1, op_max>& in, const uword dim)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op< Op<T1, op_max>, op_max>(in, dim, 0);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-max(const subview_row<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "max(): given object has no elements" );
-  
-  return op_max::direct_max(A);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-max(const subview_col<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "max(): given object has no elements" );
-  
-  return op_max::direct_max(A.colptr(0), A.n_rows);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-max(const Op<subview<eT>, op_max>& in)
-  {
-  arma_extra_debug_sigprint();
-  arma_extra_debug_print("max(): two consecutive max() calls detected");
-  
-  const subview<eT>& X = in.m;
-  
-  arma_debug_check( (X.n_elem == 0), "max(): given object has no elements" );
-  
-  return op_max::direct_max(X);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-max(const diagview<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "max(): given object has no elements" );
-  
-  return op_max::direct_max(A);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-arma_warn_unused
-eT
-max(const subview_elem1<eT,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> X(A);
-  
-  const uword X_n_elem = X.n_elem;
-  
-  arma_debug_check( (X_n_elem == 0), "max(): given object has no elements" );
-  
-  return op_max::direct_max(X.mem, X_n_elem);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_mean.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_mean
-//! @{
-
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_mean>
-mean(const Base<typename T1::elem_type,T1>& X, const uword dim = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_mean>(X.get_ref(), dim, 0);
-  }
-
-
-
-//! Immediate 'find the mean value of a row vector' operation
-template<typename eT>
-inline
-arma_warn_unused
-eT
-mean(const Row<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "mean(): given object has no elements" );
-  
-  return op_mean::direct_mean(A.mem, A_n_elem);
-  }
-
-
-
-//! Immediate 'find the mean value of a column vector' operation
-template<typename eT>
-inline
-arma_warn_unused
-eT
-mean(const Col<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "mean(): given object has no elements" );
-  
-  return op_mean::direct_mean(A.mem, A_n_elem);
-  }
-
-
-
-//! \brief
-//! Immediate 'find mean value' operation,
-//! invoked, for example, by: mean(mean(A))
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::elem_type
-mean(const Op<T1, op_mean>& in)
-  {
-  arma_extra_debug_sigprint();
-  arma_extra_debug_print("mean(): two consecutive mean() calls detected");
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1> tmp1(in.m);
-  const Mat<eT>& X = tmp1.M;
-  
-  const uword X_n_elem = X.n_elem;
-  
-  arma_debug_check( (X_n_elem == 0), "mean(): given object has no elements" );
-  
-  return op_mean::direct_mean(X.mem, X_n_elem);
-  }
-
-
-
-template<typename T1>
-arma_inline
-const Op< Op<T1, op_mean>, op_mean>
-mean(const Op<T1, op_mean>& in, const uword dim)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op< Op<T1, op_mean>, op_mean>(in, dim, 0);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-mean(const subview_row<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "mean(): given object has no elements" );
-  
-  const eT mu = accu(A) / eT(A.n_cols);
-  
-  return is_finite(mu) ? mu : op_mean::direct_mean_robust(A);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-mean(const subview_col<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "mean(): given object has no elements" );
-  
-  return op_mean::direct_mean(A.colptr(0), A.n_rows);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-mean(const Op<subview<eT>, op_mean>& in)
-  {
-  arma_extra_debug_sigprint();
-  arma_extra_debug_print("mean(): two consecutive mean() calls detected");
-  
-  const subview<eT>& X = in.m;
-  
-  arma_debug_check( (X.n_elem == 0), "mean(): given object has no elements" );
-  
-  return op_mean::direct_mean(X);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-mean(const diagview<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "mean(): given object has no elements" );
-  
-  return op_mean::direct_mean(A);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-arma_warn_unused
-eT
-mean(const subview_elem1<eT,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> X(A);
-  
-  const uword X_n_elem = X.n_elem;
-  
-  arma_debug_check( (X_n_elem == 0), "mean(): given object has no elements" );
-  
-  return op_mean::direct_mean(X.mem, X_n_elem);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_median.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,231 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_median
-//! @{
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_median>
-median(const Base<typename T1::elem_type,T1>& X, const uword dim = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_median>(X.get_ref(), dim, 0);
-  }
-
-
-
-//! Immediate 'find the median value of a row vector' operation
-template<typename eT>
-inline
-arma_warn_unused
-eT
-median(const Row<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "median(): given object has no elements" );
-  
-  return op_median::direct_median(A.mem, A_n_elem);
-  }
-
-
-
-//! Immediate 'find the median value of a column vector' operation
-template<typename eT>
-inline
-arma_warn_unused
-eT
-median(const Col<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "median(): given object has no elements" );
-  
-  return op_median::direct_median(A.mem, A_n_elem);
-  }
-
-
-
-//! Immediate 'find the median value of a row vector' operation (complex number version)
-template<typename T>
-inline
-arma_warn_unused
-std::complex<T>
-median(const Row< std::complex<T> >& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "median(): given object has no elements" );
-  
-  uword index1;
-  uword index2;
-  op_median::direct_cx_median_index(index1, index2, A.mem, A_n_elem);
-  
-  return (index1 == index2) ? A.mem[index1] : op_median::robust_mean( A.mem[index1], A.mem[index2] );
-  }
-
-
-
-//! Immediate 'find the median value of a column vector' operation (complex number version)
-template<typename T>
-inline
-arma_warn_unused
-std::complex<T>
-median(const Col< std::complex<T> >& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "median(): given object has no elements" );
-  
-  uword index1;
-  uword index2;
-  op_median::direct_cx_median_index(index1, index2, A.mem, A_n_elem);
-  
-  return (index1 == index2) ? A.mem[index1] : op_median::robust_mean( A.mem[index1], A.mem[index2] );
-  }
-
-
-
-//! find the median value of a subview_row
-template<typename eT>
-inline
-arma_warn_unused
-eT
-median(const subview_row<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "median(): given object has no elements" );
-  
-  return op_median::direct_median(A);
-  }
-
-
-
-//! find the median value of a subview_col
-template<typename eT>
-inline
-arma_warn_unused
-eT
-median(const subview_col<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "median(): given object has no elements" );
-  
-  return op_median::direct_median(A.colptr(0), A.n_rows);
-  }
-
-
-
-//! find the median value of a subview_row (complex number version)
-template<typename T>
-inline
-arma_warn_unused
-std::complex<T>
-median(const subview_row< std::complex<T> >& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "median(): given object has no elements" );
-  
-  uword index1;
-  uword index2;
-  op_median::direct_cx_median_index(index1, index2, A);
-  
-  return (index1 == index2) ? A[index1] : op_median::robust_mean(A[index1], A[index2]);
-  }
-
-
-
-//! find the median value of a subview_col (complex number version)
-template<typename T>
-inline
-arma_warn_unused
-std::complex<T>
-median(const subview_col< std::complex<T> >& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "median(): given object has no elements" );
-  
-  uword index1;
-  uword index2;
-  op_median::direct_cx_median_index(index1, index2, A);
-  
-  return (index1 == index2) ? A[index1] : op_median::robust_mean(A[index1], A[index2]);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-median(const diagview<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "median(): given object has no elements" );
-  
-  return op_median::direct_median(A);
-  }
-
-
-
-template<typename T>
-inline
-arma_warn_unused
-std::complex<T>
-median(const diagview< std::complex<T> >& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "median(): given object has no elements" );
-  
-  uword index1;
-  uword index2;
-  op_median::direct_cx_median_index(index1, index2, A);
-  
-  return (index1 == index2) ? A[index1] : op_median::robust_mean(A[index1], A[index2]);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-arma_warn_unused
-eT
-median(const subview_elem1<eT,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Col<eT> X(A);
-  
-  return median(X);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_min.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_min
-//! @{
-
-//! \brief
-//! Delayed 'minimum values' operation.
-//! The dimension, along which the minima are found, is set via 'dim'.
-//! For dim = 0, the minimum value of each column is found (i.e. searches by traversing across rows).
-//! For dim = 1, the minimum value of each row is found (i.e. searches by traversing across columns).
-//! The default is dim = 0.
-
-template<typename T1>
-arma_inline
-const Op<T1, op_min>
-min(const Base<typename T1::elem_type,T1>& X, const uword dim = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_min>(X.get_ref(), dim, 0);
-  }
-
-
-//! Immediate 'find the minimum value in a row vector' operation
-template<typename eT>
-inline
-arma_warn_unused
-eT
-min(const Row<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "min(): given object has no elements" );
-  
-  return op_min::direct_min(A.mem, A_n_elem);
-  }
-
-
-
-//! Immediate 'find the minimum value in a column vector'
-template<typename eT>
-inline
-arma_warn_unused
-eT
-min(const Col<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "min(): given object has no elements" );
-  
-  return op_min::direct_min(A.mem, A_n_elem);
-  }
-
-
-
-//! \brief
-//! Immediate 'find minimum value' operation,
-//! invoked, for example, by: min(min(A))
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::elem_type
-min(const Op<T1, op_min>& in)
-  {
-  arma_extra_debug_sigprint();
-  arma_extra_debug_print("min(): two consecutive min() calls detected");
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1> tmp1(in.m);
-  const Mat<eT>& X = tmp1.M;
-  
-  const uword X_n_elem = X.n_elem;
-  
-  arma_debug_check( (X_n_elem == 0), "min(): given object has no elements" );
-  
-  return op_min::direct_min(X.mem, X_n_elem);
-  }
-
-
-
-template<typename T1>
-inline
-const Op< Op<T1, op_min>, op_min>
-min(const Op<T1, op_min>& in, const uword dim)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op< Op<T1, op_min>, op_min>(in, dim, 0);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-min(const subview_row<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "min(): given object has no elements" );
-  
-  return op_min::direct_min(A);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-min(const subview_col<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "min(): given object has no elements" );
-  
-  return op_min::direct_min(A.colptr(0), A.n_rows);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-min(const diagview<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "min(): given object has no elements" );
-  
-  return op_min::direct_min(A);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-eT
-min(const Op<subview<eT>, op_min>& in)
-  {
-  arma_extra_debug_sigprint();
-  arma_extra_debug_print("min(): two consecutive min() calls detected");
-  
-  const subview<eT>& X = in.m;
-  
-  arma_debug_check( (X.n_elem == 0), "min(): given object has no elements" );
-  
-  return op_min::direct_min(X);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-arma_warn_unused
-eT
-min(const subview_elem1<eT,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT> X(A);
-  
-  const uword X_n_elem = X.n_elem;
-  
-  arma_debug_check( (X_n_elem == 0), "min(): given object has no elements" );
-  
-  return op_min::direct_min(X.mem, X_n_elem);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_misc.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_misc
-//! @{
-
-
-
-//! \brief
-//! Generate a vector with 'num' elements.
-//! The values of the elements linearly increase from 'start' upto (and including) 'end'.
-
-template<typename vec_type>
-inline
-vec_type
-linspace
-  (
-  const typename vec_type::pod_type start,
-  const typename vec_type::pod_type end,
-  const uword num = 100u,
-  const typename arma_Mat_Col_Row_only<vec_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename vec_type::elem_type eT;
-  typedef typename vec_type::pod_type   T;
-  
-  vec_type x;
-    
-  if(num >= 2)
-    {
-    x.set_size(num);
-    
-    eT* x_mem = x.memptr();
-    
-    const uword num_m1 = num - 1;
-    
-    if(is_non_integral<T>::value == true)
-      {
-      const T delta = (end-start)/T(num_m1);
-      
-      for(uword i=0; i<num_m1; ++i)
-        {
-        x_mem[i] = eT(start + i*delta);
-        }
-      
-      x_mem[num_m1] = eT(end);
-      }
-    else
-      {
-      const double delta = (end >= start) ? double(end-start)/double(num_m1) : -double(start-end)/double(num_m1);
-      
-      for(uword i=0; i<num_m1; ++i)
-        {
-        x_mem[i] = eT(double(start) + i*delta);
-        }
-      
-      x_mem[num_m1] = eT(end);
-      }
-    
-    return x;
-    }
-  else
-    {
-    x.set_size(1);
-    
-    x[0] = eT(end);
-    }
-  
-  return x;
-  }
-
-
-
-inline
-mat
-linspace(const double start, const double end, const uword num = 100u)
-  {
-  arma_extra_debug_sigprint();
-  return linspace<mat>(start, end, num);
-  }
-
-
-
-//
-// log_add
-
-template<typename eT>
-inline
-typename arma_float_only<eT>::result
-log_add(eT log_a, eT log_b)
-  {
-  if(log_a < log_b)
-    {
-    std::swap(log_a, log_b);
-    }
-  
-  const eT negdelta = log_b - log_a;
-  
-  if( (negdelta < Math<eT>::log_min()) || (arma_isfinite(negdelta) == false) )
-    {
-    return log_a;
-    }
-  else
-    {
-    #if defined(ARMA_HAVE_LOG1P)
-      return (log_a + log1p(std::exp(negdelta)));
-    #else
-      return (log_a + std::log(1.0 + std::exp(negdelta)));
-    #endif
-    }
-  }
-
-
-
-template<typename eT>
-arma_inline
-arma_warn_unused
-bool
-is_finite(const eT x, const typename arma_scalar_only<eT>::result* junk = 0)
-  {
-  arma_ignore(junk);
-  
-  return arma_isfinite(x);
-  }
-
-
-
-template<typename T1>
-inline
-arma_warn_unused
-bool
-is_finite(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(X.get_ref());
-  const Mat<eT>& A = tmp.M;
-  
-  return A.is_finite();
-  }
-
-
-
-template<typename T1>
-inline
-arma_warn_unused
-bool
-is_finite(const BaseCube<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_cube<T1> tmp(X.get_ref());
-  const Cube<eT>& A =   tmp.M;
-  
-  return A.is_finite();
-  }
-
-
-
-template<typename T1>
-arma_inline
-Op<T1, op_sympd>
-sympd(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_sympd>(X.get_ref());
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_norm.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,510 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_norm
-//! @{
-
-
-
-template<typename T1>
-arma_hot
-inline
-typename T1::pod_type
-arma_vec_norm_1(const Proxy<T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::pod_type T;
-
-  T acc = T(0);
-    
-  if(Proxy<T1>::prefer_at_accessor == false)
-    {
-    typename Proxy<T1>::ea_type P = A.get_ea();
-    
-    const uword N = A.get_n_elem();
-    
-    uword i,j;
-    
-    for(i=0, j=1; j<N; i+=2, j+=2)
-      {
-      acc += std::abs(P[i]);
-      acc += std::abs(P[j]);
-      }
-    
-    if(i < N)
-      {
-      acc += std::abs(P[i]);
-      }
-    }
-  else
-    {
-    const uword n_rows = A.get_n_rows();
-    const uword n_cols = A.get_n_cols();
-    
-    for(uword col=0; col<n_cols; ++col)
-      {
-      uword i,j;
-      
-      for(i=0, j=1; j<n_rows; i+=2, j+=2)
-        {
-        acc += std::abs(A.at(i,col));
-        acc += std::abs(A.at(j,col));
-        }
-      
-      if(i < n_rows)
-        {
-        acc += std::abs(A.at(i,col));
-        }
-      }
-    }
-    
-  return acc;
-  }
-
-
-
-template<typename T1>
-arma_hot
-inline
-typename T1::pod_type
-arma_vec_norm_2(const Proxy<T1>& A, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename T1::pod_type T;
-  
-  T acc = T(0);
-  
-  if(Proxy<T1>::prefer_at_accessor == false)
-    {
-    typename Proxy<T1>::ea_type P = A.get_ea();
-    
-    const uword N = A.get_n_elem();
-    
-    uword i,j;
-    
-    for(i=0, j=1; j<N; i+=2, j+=2)
-      {
-      const T tmp_i = P[i];
-      const T tmp_j = P[j];
-      
-      acc += tmp_i * tmp_i;
-      acc += tmp_j * tmp_j;
-      }
-    
-    if(i < N)
-      {
-      const T tmp_i = P[i];
-      
-      acc += tmp_i * tmp_i;
-      }
-    }
-  else
-    {
-    const uword n_rows = A.get_n_rows();
-    const uword n_cols = A.get_n_cols();
-    
-    for(uword col=0; col<n_cols; ++col)
-      {
-      uword i,j;
-      
-      for(i=0, j=1; j<n_rows; i+=2, j+=2)
-        {
-        const T tmp_i = A.at(i,col);
-        const T tmp_j = A.at(j,col);
-        
-        acc += tmp_i * tmp_i;
-        acc += tmp_j * tmp_j;
-        }
-      
-      if(i < n_rows)
-        {
-        const T tmp_i = A.at(i,col);
-        
-        acc += tmp_i * tmp_i;
-        }
-      }
-    }
-  
-  return std::sqrt(acc);
-  }
-
-
-
-template<typename T1>
-arma_hot
-inline
-typename T1::pod_type
-arma_vec_norm_2(const Proxy<T1>& A, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename T1::pod_type T;
-  
-  T acc = T(0);
-  
-  if(Proxy<T1>::prefer_at_accessor == false)
-    {
-    typename Proxy<T1>::ea_type P = A.get_ea();
-    
-    const uword N = A.get_n_elem();
-    
-    for(uword i=0; i<N; ++i)
-      {
-      const T tmp = std::abs(P[i]);
-      acc += tmp*tmp;
-      }
-    }
-  else
-    {
-    const uword n_rows = A.get_n_rows();
-    const uword n_cols = A.get_n_cols();
-    
-    for(uword col=0; col<n_cols; ++col)
-    for(uword row=0; row<n_rows; ++row)
-      {
-      const T tmp = std::abs(A.at(row,col));
-      acc += tmp*tmp;
-      }
-    }
-  
-  return std::sqrt(acc);
-  }
-
-
-
-template<typename T1>
-arma_hot
-inline
-typename T1::pod_type
-arma_vec_norm_k(const Proxy<T1>& A, const int k)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::pod_type T;
-  
-  T acc = T(0);
-  
-  if(Proxy<T1>::prefer_at_accessor == false)
-    {
-    typename Proxy<T1>::ea_type P = A.get_ea();
-    
-    const uword N = A.get_n_elem();
-    
-    uword i,j;
-    
-    for(i=0, j=1; j<N; i+=2, j+=2)
-      {
-      acc += std::pow(std::abs(P[i]), k);
-      acc += std::pow(std::abs(P[j]), k);
-      }
-    
-    if(i < N)
-      {
-      acc += std::pow(std::abs(P[i]), k);
-      }
-    }
-  else
-    {
-    const uword n_rows = A.get_n_rows();
-    const uword n_cols = A.get_n_cols();
-    
-    for(uword col=0; col<n_cols; ++col)
-    for(uword row=0; row<n_rows; ++row)
-      {
-      acc += std::pow(std::abs(A.at(row,col)), k);
-      }
-    }
-  
-  return std::pow(acc, T(1)/T(k));
-  }
-
-
-
-template<typename T1>
-arma_hot
-inline
-typename T1::pod_type
-arma_vec_norm_max(const Proxy<T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::pod_type       T;
-  typedef typename Proxy<T1>::ea_type ea_type;
-  
-        ea_type P = A.get_ea();
-  const uword     N = A.get_n_elem();
-  
-  T max_val = (N != 1) ? priv::most_neg<T>() : std::abs(P[0]);
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<N; i+=2, j+=2)
-    {
-    const T tmp_i = std::abs(P[i]);
-    const T tmp_j = std::abs(P[j]);
-    
-    if(max_val < tmp_i) { max_val = tmp_i; }
-    if(max_val < tmp_j) { max_val = tmp_j; }
-    }
-  
-  if(i < N)
-    {
-    const T tmp_i = std::abs(P[i]);
-    
-    if(max_val < tmp_i) { max_val = tmp_i; }
-    }
-  
-  return max_val;
-  }
-
-
-
-template<typename T1>
-arma_hot
-inline
-typename T1::pod_type
-arma_vec_norm_min(const Proxy<T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::pod_type       T;
-  typedef typename Proxy<T1>::ea_type ea_type;
-  
-        ea_type P = A.get_ea();
-  const uword     N = A.get_n_elem();
-  
-  T min_val = (N != 1) ? priv::most_pos<T>() : std::abs(P[0]);
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<N; i+=2, j+=2)
-    {
-    const T tmp_i = std::abs(P[i]);
-    const T tmp_j = std::abs(P[j]);
-    
-    if(min_val > tmp_i) { min_val = tmp_i; }
-    if(min_val > tmp_j) { min_val = tmp_j; }
-    }
-  
-  if(i < N)
-    {
-    const T tmp_i = std::abs(P[i]);
-    
-    if(min_val > tmp_i) { min_val = tmp_i; }
-    }
-  
-  return min_val;
-  }
-
-
-
-template<typename T1>
-inline
-typename T1::pod_type
-arma_mat_norm_1(const Proxy<T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  typedef typename T1::pod_type   T;
-  
-  const unwrap<typename Proxy<T1>::stored_type> tmp(A.Q);
-  const Mat<eT>& X = tmp.M;
-  
-  // TODO: this can be sped up with a dedicated implementation
-  return as_scalar( max( sum(abs(X)), 1) );
-  }
-
-
-
-template<typename T1>
-inline
-typename T1::pod_type
-arma_mat_norm_2(const Proxy<T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  typedef typename T1::pod_type   T;
-  
-  const unwrap<typename Proxy<T1>::stored_type> tmp(A.Q);
-  const Mat<eT>& X = tmp.M;
-  
-  Col<T> S;
-  svd(S, X);
-  
-  return (S.n_elem > 0) ? max(S) : T(0);
-  }
-
-
-
-template<typename T1>
-inline
-typename T1::pod_type
-arma_mat_norm_inf(const Proxy<T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  typedef typename T1::pod_type   T;
-  
-  const unwrap<typename Proxy<T1>::stored_type> tmp(A.Q);
-  const Mat<eT>& X = tmp.M;
-  
-  // TODO: this can be sped up with a dedicated implementation
-  return as_scalar( max( sum(abs(X),1) ) );
-  }
-
-
-
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::pod_type
-norm
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const uword k,
-  const typename arma_float_or_cx_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename T1::elem_type eT;
-  typedef typename T1::pod_type   T;
-  
-  const Proxy<T1> A(X.get_ref());
-  
-  if(A.get_n_elem() == 0)
-    {
-    return T(0);
-    }
-  
-  const bool is_vec = (A.get_n_rows() == 1) || (A.get_n_cols() == 1);
-  
-  if(is_vec == true)
-    {
-    switch(k)
-      {
-      case 1:
-        return arma_vec_norm_1(A);
-        break;
-      
-      case 2:
-        return arma_vec_norm_2(A);
-        break;
-      
-      default:
-        {
-        arma_debug_check( (k == 0), "norm(): k must be greater than zero"   );
-        return arma_vec_norm_k(A, int(k));
-        }
-      }
-    }
-  else
-    {
-    switch(k)
-      {
-      case 1:
-        return arma_mat_norm_1(A);
-        break;
-      
-      case 2:
-        return arma_mat_norm_2(A);
-        break;
-      
-      default:
-        arma_stop("norm(): unsupported matrix norm type");
-        return T(0);
-      }
-    }
-  }
-
-
-
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::pod_type
-norm
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const char* method,
-  const typename arma_float_or_cx_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename T1::elem_type eT;
-  typedef typename T1::pod_type   T;
-  
-  const Proxy<T1> A(X.get_ref());
-  
-  if(A.get_n_elem() == 0)
-    {
-    return T(0);
-    }
-  
-  const char sig    = method[0];
-  const bool is_vec = (A.get_n_rows() == 1) || (A.get_n_cols() == 1);
-  
-  if(is_vec == true)
-    {
-    if( (sig == 'i') || (sig == 'I') || (sig == '+') )   // max norm
-      {
-      return arma_vec_norm_max(A);
-      }
-    else
-    if(sig == '-')   // min norm
-      {
-      return arma_vec_norm_min(A);
-      }
-    else
-    if( (sig == 'f') || (sig == 'F') )
-      {
-      return arma_vec_norm_2(A);
-      }
-    else
-      {
-      arma_stop("norm(): unsupported vector norm type");
-      return T(0);
-      }
-    }
-  else
-    {
-    if( (sig == 'i') || (sig == 'I') || (sig == '+') )   // inf norm
-      {
-      return arma_mat_norm_inf(A);
-      }
-    else
-    if( (sig == 'f') || (sig == 'F') )
-      {
-      return arma_vec_norm_2(A);
-      }
-    else
-      {
-      arma_stop("norm(): unsupported matrix norm type");
-      return T(0);
-      }
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_ones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_ones
-//! @{
-
-
-
-arma_inline
-const Gen<vec::elem_type, gen_ones_full>
-ones(const uword n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Gen<vec::elem_type, gen_ones_full>(n_elem, 1);
-  }
-
-
-
-template<typename vec_type>
-arma_inline
-const Gen<typename vec_type::elem_type, gen_ones_full>
-ones(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only<vec_type>::result* junk2 = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk1);
-  arma_ignore(junk2);
-  
-  if(is_Row<vec_type>::value == true)
-    {
-    return Gen<typename vec_type::elem_type, gen_ones_full>(1, n_elem);
-    }
-  else
-    {
-    return Gen<typename vec_type::elem_type, gen_ones_full>(n_elem, 1);
-    }
-  }
-
-
-
-arma_inline
-const Gen<mat::elem_type, gen_ones_full>
-ones(const uword n_rows, const uword n_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Gen<mat::elem_type, gen_ones_full>(n_rows, n_cols);
-  }
-
-
-
-template<typename mat_type>
-arma_inline
-const Gen<typename mat_type::elem_type, gen_ones_full>
-ones(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only<mat_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return Gen<typename mat_type::elem_type, gen_ones_full>(n_rows, n_cols);
-  }
-
-
-
-arma_inline
-const GenCube<cube::elem_type, gen_ones_full>
-ones(const uword n_rows, const uword n_cols, const uword n_slices)
-  {
-  arma_extra_debug_sigprint();
-  
-  return GenCube<cube::elem_type, gen_ones_full>(n_rows, n_cols, n_slices);
-  }
-
-
-
-template<typename cube_type>
-arma_inline
-const GenCube<typename cube_type::elem_type, gen_ones_full>
-ones(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only<cube_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return GenCube<typename cube_type::elem_type, gen_ones_full>(n_rows, n_cols, n_slices);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_pinv.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_pinv
-//! @{
-
-
-
-template<typename T1>
-inline
-const Op<T1, op_pinv>
-pinv
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const typename T1::elem_type tol = 0.0,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return Op<T1, op_pinv>(X.get_ref(), tol);
-  }
-
-
-
-template<typename T1>
-inline
-bool
-pinv
-  (
-         Mat<typename T1::elem_type>&    out,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename T1::elem_type tol = 0.0,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  try
-    {
-    out = pinv(X,tol);
-    }
-  catch(std::runtime_error&)
-    {
-    return false;
-    }
-  
-  return true;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_princomp.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// Copyright (C) 2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_princomp
-//! @{
-
-
-
-//! \brief
-//! principal component analysis -- 4 arguments version
-//! coeff_out    -> principal component coefficients
-//! score_out    -> projected samples
-//! latent_out   -> eigenvalues of principal vectors
-//! tsquared_out -> Hotelling's T^2 statistic
-template<typename T1>
-inline
-bool
-princomp
-  (
-         Mat<typename T1::elem_type>&    coeff_out,
-         Mat<typename T1::elem_type>&    score_out,
-         Col<typename T1::pod_type>&     latent_out,
-         Col<typename T1::elem_type>&    tsquared_out,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(X.get_ref());
-  const Mat<eT>& A = tmp.M;
-  
-  const bool status = op_princomp::direct_princomp(coeff_out, score_out, latent_out, tsquared_out, A);
-  
-  if(status == false)
-    {
-    coeff_out.reset();
-    score_out.reset();
-    latent_out.reset();
-    tsquared_out.reset();
-    
-    arma_bad("princomp(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-//! \brief
-//! principal component analysis -- 3 arguments version
-//! coeff_out    -> principal component coefficients
-//! score_out    -> projected samples
-//! latent_out   -> eigenvalues of principal vectors
-template<typename T1>
-inline
-bool
-princomp
-  (
-         Mat<typename T1::elem_type>&    coeff_out,
-         Mat<typename T1::elem_type>&    score_out,
-         Col<typename T1::pod_type>&     latent_out,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(X.get_ref());
-  const Mat<eT>& A = tmp.M;
-  
-  const bool status = op_princomp::direct_princomp(coeff_out, score_out, latent_out, A); 
-  
-  if(status == false)
-    {
-    coeff_out.reset();
-    score_out.reset();
-    latent_out.reset();
-    
-    arma_bad("princomp(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-//! \brief
-//! principal component analysis -- 2 arguments version
-//! coeff_out    -> principal component coefficients
-//! score_out    -> projected samples
-template<typename T1>
-inline
-bool
-princomp
-  (
-         Mat<typename T1::elem_type>&    coeff_out,
-         Mat<typename T1::elem_type>&    score_out,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(X.get_ref());
-  const Mat<eT>& A = tmp.M;
-  
-  const bool status = op_princomp::direct_princomp(coeff_out, score_out, A); 
-  
-  if(status == false)
-    {
-    coeff_out.reset();
-    score_out.reset();
-    
-    arma_bad("princomp(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-//! \brief
-//! principal component analysis -- 1 argument version
-//! coeff_out    -> principal component coefficients
-template<typename T1>
-inline
-bool
-princomp
-  (
-         Mat<typename T1::elem_type>&    coeff_out,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(X.get_ref());
-  const Mat<eT>& A = tmp.M;
-  
-  const bool status = op_princomp::direct_princomp(coeff_out, A);
-  
-  if(status == false)
-    {
-    coeff_out.reset();
-    
-    arma_bad("princomp(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-template<typename T1>
-inline
-const Op<T1, op_princomp>
-princomp
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-
-  return Op<T1, op_princomp>(X.get_ref());
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_prod.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,185 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_prod
-//! @{
-
-
-//! \brief
-//! Delayed product of elements of a matrix along a specified dimension (either rows or columns).
-//! The result is stored in a dense matrix that has either one column or one row.
-//! For dim = 0, find the sum of each column (i.e. traverse across rows)
-//! For dim = 1, find the sum of each row (i.e. traverse across columns)
-//! The default is dim = 0.
-//! NOTE: this function works differently than in Matlab/Octave.
-
-template<typename T1>
-arma_inline
-const Op<T1, op_prod>
-prod(const Base<typename T1::elem_type,T1>& X, const uword dim = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_prod>(X.get_ref(), dim, 0);
-  }
-
-
-
-//! \brief
-//! Immediate 'product of all values' operation for a row vector
-template<typename eT>
-inline
-arma_warn_unused
-eT
-prod(const Row<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return arrayops::product(X.memptr(), X.n_elem);
-  }
-
-
-
-//! \brief
-//! Immediate 'product of all values' operation for a column vector
-template<typename eT>
-inline
-arma_warn_unused
-eT
-prod(const Col<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return arrayops::product(X.memptr(), X.n_elem);
-  }
-
-
-
-//! \brief
-//! Immediate 'product of all values' operation,
-//! invoked, for example, by: prod(prod(A))
-
-template<typename T1>
-inline
-typename T1::elem_type
-prod(const Op<T1, op_prod>& in)
-  {
-  arma_extra_debug_sigprint();
-  arma_extra_debug_print("prod(): two consecutive prod() calls detected");
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(in.m);
-  const Mat<eT>& X = tmp.M;
-  
-  return arrayops::product( X.memptr(), X.n_elem );
-  }
-
-
-
-template<typename T1>
-inline
-const Op<Op<T1, op_prod>, op_prod>
-prod(const Op<T1, op_prod>& in, const uword dim)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<Op<T1, op_prod>, op_prod>(in, dim, 0);
-  }
-
-
-
-//! product of all values of a subview_row
-template<typename eT>
-inline
-arma_warn_unused
-eT
-prod(const subview_row<eT>& S)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat<eT>& X = S.m;
-  
-  const uword n_elem         = S.n_elem;
-  const uword row            = S.aux_row1;
-  const uword start_col      = S.aux_col1;
-  const uword end_col_plus_1 = start_col + S.n_cols;
-  
-  eT val = eT(1);
-  
-  if(n_elem > 0)
-    {
-    for(uword col=start_col; col<end_col_plus_1; ++col)
-      {
-      val *= X.at(row,col);
-      }
-    }
-  
-  return val;
-  }
-
-
-
-//! product of all values of a subview_col
-template<typename eT>
-inline
-arma_warn_unused
-eT
-prod(const subview_col<eT>& S)
-  {
-  arma_extra_debug_sigprint();
-  
-  return (S.n_elem > 0) ? arrayops::product( S.colptr(0), S.n_rows ) : eT(1);
-  }
-
-
-
-//! product of all values of a diagview
-template<typename eT>
-arma_warn_unused
-inline
-eT
-prod(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_elem = X.n_elem;
-  
-  eT val = eT(1);
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    val *= X[i];
-    }
-  
-  return val;
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-arma_warn_unused
-eT
-prod(const subview_elem1<eT,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Col<eT> X(A);
-  
-  return prod(X);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_qr.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2012 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_qr
-//! @{
-
-
-
-//! QR decomposition
-template<typename T1>
-inline
-bool
-qr
-  (
-         Mat<typename T1::elem_type>&    Q,
-         Mat<typename T1::elem_type>&    R,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  arma_debug_check( (&Q == &R), "qr(): Q and R are the same object");
-  
-  const bool status = auxlib::qr(Q, R, X);
-  
-  if(status == false)
-    {
-    Q.reset();
-    R.reset();
-    arma_bad("qr(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_randn.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_randn
-//! @{
-
-
-inline
-double
-randn()
-  {
-  return double(eop_aux_randn<double>());
-  }
-
-
-template<typename eT>
-inline
-typename arma_scalar_only<eT>::result
-randn()
-  {
-  return eT(eop_aux_randn<eT>());
-  }
-
-
-
-//! Generate a vector with all elements set to random values with a gaussian distribution (zero mean, unit variance)
-arma_inline
-const Gen<vec::elem_type, gen_randn>
-randn(const uword n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Gen<vec::elem_type, gen_randn>(n_elem, 1);
-  }
-
-
-
-template<typename vec_type>
-arma_inline
-const Gen<typename vec_type::elem_type, gen_randn>
-randn(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only<vec_type>::result* junk2 = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk1);
-  arma_ignore(junk2);
-  
-  if(is_Row<vec_type>::value == true)
-    {
-    return Gen<typename vec_type::elem_type, gen_randn>(1, n_elem);
-    }
-  else
-    {
-    return Gen<typename vec_type::elem_type, gen_randn>(n_elem, 1);
-    }
-  }
-
-
-
-//! Generate a dense matrix with all elements set to random values with a gaussian distribution (zero mean, unit variance)
-arma_inline
-const Gen<mat::elem_type, gen_randn>
-randn(const uword n_rows, const uword n_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Gen<mat::elem_type, gen_randn>(n_rows, n_cols);
-  }
-
-
-
-template<typename mat_type>
-arma_inline
-const Gen<typename mat_type::elem_type, gen_randn>
-randn(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only<mat_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return Gen<typename mat_type::elem_type, gen_randn>(n_rows, n_cols);
-  }
-
-
-
-arma_inline
-const GenCube<cube::elem_type, gen_randn>
-randn(const uword n_rows, const uword n_cols, const uword n_slices)
-  {
-  arma_extra_debug_sigprint();
-  
-  return GenCube<cube::elem_type, gen_randn>(n_rows, n_cols, n_slices);
-  }
-
-
-
-template<typename cube_type>
-arma_inline
-const GenCube<typename cube_type::elem_type, gen_randn>
-randn(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only<cube_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ignore(junk);
-  
-  return GenCube<typename cube_type::elem_type, gen_randn>(n_rows, n_cols, n_slices);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_randu.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_randu
-//! @{
-
-
-inline
-double
-randu()
-  {
-  return double(eop_aux_randu<double>());
-  }
-
-
-template<typename eT>
-inline
-typename arma_scalar_only<eT>::result
-randu()
-  {
-  return eT(eop_aux_randu<eT>());
-  }
-
-
-
-//! Generate a vector with all elements set to random values in the [0,1] interval (uniform distribution)
-arma_inline
-const Gen<vec::elem_type, gen_randu>
-randu(const uword n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Gen<vec::elem_type, gen_randu>(n_elem, 1);
-  }
-
-
-
-template<typename vec_type>
-arma_inline
-const Gen<typename vec_type::elem_type, gen_randu>
-randu(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only<vec_type>::result* junk2 = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk1);
-  arma_ignore(junk2);
-  
-  if(is_Row<vec_type>::value == true)
-    {
-    return Gen<typename vec_type::elem_type, gen_randu>(1, n_elem);
-    }
-  else
-    {
-    return Gen<typename vec_type::elem_type, gen_randu>(n_elem, 1);
-    }
-  }
-
-
-
-//! Generate a dense matrix with all elements set to random values in the [0,1] interval (uniform distribution)
-arma_inline
-const Gen<mat::elem_type, gen_randu>
-randu(const uword n_rows, const uword n_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Gen<mat::elem_type, gen_randu>(n_rows, n_cols);
-  }
-
-
-
-template<typename mat_type>
-arma_inline
-const Gen<typename mat_type::elem_type, gen_randu>
-randu(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only<mat_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return Gen<typename mat_type::elem_type, gen_randu>(n_rows, n_cols);
-  }
-
-
-
-arma_inline
-const GenCube<cube::elem_type, gen_randu>
-randu(const uword n_rows, const uword n_cols, const uword n_slices)
-  {
-  arma_extra_debug_sigprint();
-  
-  return GenCube<cube::elem_type, gen_randu>(n_rows, n_cols, n_slices);
-  }
-
-
-
-template<typename cube_type>
-arma_inline
-const GenCube<typename cube_type::elem_type, gen_randu>
-randu(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only<cube_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return GenCube<typename cube_type::elem_type, gen_randu>(n_rows, n_cols, n_slices);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_rank.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// Copyright (C) 2011 Stanislav Funiak
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_rank
-//! @{
-
-
-
-template<typename T1>
-inline
-arma_warn_unused
-uword
-rank
-  (
-  const Base<typename T1::elem_type,T1>& X,
-        typename T1::pod_type            tol = 0.0,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename T1::elem_type eT;
-  typedef typename T1::pod_type   T;
-  
-  uword    X_n_rows;
-  uword    X_n_cols;
-  Col<T> s;
-  
-  const bool status = auxlib::svd(s, X, X_n_rows, X_n_cols);
-  const uword  n_elem = s.n_elem;
-  
-  if(status == true)
-    {
-    if( (tol == T(0)) && (n_elem > 0) )
-      {
-      tol = (std::max)(X_n_rows, X_n_cols) * eop_aux::direct_eps(max(s));
-      }
-    
-    // count non zero valued elements in s
-    
-    const T*  s_mem  = s.memptr();
-          uword count  = 0;
-    
-    for(uword i=0; i<n_elem; ++i)
-      {
-      if(s_mem[i] > tol)
-        {
-        ++count;
-        }
-      }
-    
-    return count;
-    }
-  else
-    {
-    arma_bad("rank(): failed to converge");
-    
-    return uword(0);
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_repmat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup fn_repmat
-//! @{
-
-
-//! \brief
-//! delayed 'repeat matrix' construction of a matrix
-template<typename T1>
-arma_inline
-const Op<T1, op_repmat>
-repmat(const Base<typename T1::elem_type,T1>& A, const uword r, const uword c)
-  {
-  arma_extra_debug_sigprint();
-
-  return Op<T1, op_repmat>(A.get_ref(), r, c);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_reshape.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_reshape
-//! @{
-
-
-
-template<typename T1>
-inline
-const Op<T1, op_reshape>
-reshape(const Base<typename T1::elem_type,T1>& X, const uword in_n_rows, const uword in_n_cols, const uword dim = 0)
-  {
-  arma_extra_debug_sigprint();
-
-  arma_debug_check( (dim > 1), "reshape(): dim must be 0 or 1");
-
-  typedef typename T1::elem_type eT;
-  
-  return Op<T1, op_reshape>(X.get_ref(), in_n_rows, in_n_cols, dim, 'j');
-  }
-
-
-
-template<typename T1>
-inline
-const OpCube<T1, op_reshape>
-reshape(const BaseCube<typename T1::elem_type,T1>& X, const uword in_n_rows, const uword in_n_cols, const uword in_n_slices, const uword dim = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (dim > 1), "reshape(): dim must be 0 or 1");
-
-  typedef typename T1::elem_type eT;
-  
-  return OpCube<T1, op_reshape>(X.get_ref(), in_n_rows, in_n_cols, in_n_slices, dim, 'j');
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_resize.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_resize
-//! @{
-
-
-
-template<typename T1>
-inline
-const Op<T1, op_resize>
-resize(const Base<typename T1::elem_type,T1>& X, const uword in_n_rows, const uword in_n_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_resize>(X.get_ref(), in_n_rows, in_n_cols);
-  }
-
-
-
-template<typename T1>
-inline
-const OpCube<T1, op_resize>
-resize(const BaseCube<typename T1::elem_type,T1>& X, const uword in_n_rows, const uword in_n_cols, const uword in_n_slices)
-  {
-  arma_extra_debug_sigprint();
-  
-  return OpCube<T1, op_resize>(X.get_ref(), in_n_rows, in_n_cols, in_n_slices);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_shuffle.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup fn_shuffle
-//! @{
-
-//! \brief
-//! Shuffle the rows or the columns of a matrix or vector in random fashion.
-//! If dim = 0, shuffle the columns (default operation).
-//! If dim = 1, shuffle the rows.
-
-template<typename T1>
-inline
-const Op<T1, op_shuffle>
-shuffle(const Base<typename T1::elem_type,T1>& X, const uword dim = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (dim > 1), "shuffle(): dim must be 0 or 1");
-  
-  return Op<T1, op_shuffle>(X.get_ref(), dim, 0);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_solve.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_solve
-//! @{
-
-
-
-//! Solve a system of linear equations, i.e., A*X = B, where X is unknown.
-//! For a square matrix A, this function is conceptually the same as X = inv(A)*B,
-//! but is done more efficiently.
-//! The number of rows in A and B must be the same.
-//! B can be either a column vector or a matrix.
-//! This function will also try to provide approximate solutions
-//! to under-determined as well as over-determined systems (non-square A matrices).
-
-template<typename T1, typename T2>
-inline
-const Glue<T1, T2, glue_solve>
-solve
-  (
-  const Base<typename T1::elem_type,T1>& A,
-  const Base<typename T1::elem_type,T2>& B,
-  const bool slow = false,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return Glue<T1, T2, glue_solve>(A.get_ref(), B.get_ref(), ((slow == false) ? 0 : 1) );
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const Glue<T1, T2, glue_solve_tr>
-solve
-  (
-  const Op<T1, op_trimat>& A,
-  const Base<typename T1::elem_type,T2>& B,
-  const bool slow = false,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(slow);
-  arma_ignore(junk);
-  
-  return Glue<T1, T2, glue_solve_tr>(A.m, B.get_ref(), A.aux_uword_a);
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-bool
-solve
-  (
-         Mat<typename T1::elem_type>&    out,
-  const Base<typename T1::elem_type,T1>& A,
-  const Base<typename T1::elem_type,T2>& B,
-  const bool slow = false,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  try
-    {
-    out = solve( A.get_ref(), B.get_ref(), slow );
-    }
-  catch(std::runtime_error&)
-    {
-    return false;
-    }
-  
-  return true;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_sort.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_sort
-//! @{
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_sort>
-sort(const Base<typename T1::elem_type,T1>& X, const uword sort_type = 0, const uword dim = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_sort>(X.get_ref(), sort_type, dim);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const Op<Col<eT>, op_sort>
-sort(const Col<eT>& X, const uword sort_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword dim = 0;
-  
-  return Op<Col<eT>, op_sort>(X, sort_type, dim);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const Op<Row<eT>, op_sort>
-sort(const Row<eT>& X, const uword sort_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword dim = 1;
-  
-  return Op<Row<eT>, op_sort>(X, sort_type, dim);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_sort_index.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_sort_index
-//! @{
-
-
-
-
-template<typename T1, typename T2>
-struct arma_sort_index_packet_ascend
-  {
-  T1 val;
-  T2 index;
-  };
-
-
-
-template<typename T1, typename T2>
-struct arma_sort_index_packet_descend
-  {
-  T1 val;
-  T2 index;
-  };
-
-
-
-template<typename T1, typename T2>
-inline
-bool
-operator< (const arma_sort_index_packet_ascend<T1,T2>& A, const arma_sort_index_packet_ascend<T1,T2>& B)
-  {
-  return A.val < B.val;
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-bool
-operator< (const arma_sort_index_packet_descend<T1,T2>& A, const arma_sort_index_packet_descend<T1,T2>& B)
-  {
-  return A.val > B.val;
-  }
-
-
-
-template<typename umat_elem_type, typename packet_type, typename eT>
-void
-inline
-sort_index_helper(umat_elem_type* out_mem, std::vector<packet_type>& packet_vec, const eT* in_mem)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword n_elem = packet_vec.size();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    packet_vec[i].val   = in_mem[i];
-    packet_vec[i].index = i;
-    }
-  
-  std::sort( packet_vec.begin(), packet_vec.end() );
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = packet_vec[i].index;
-    }
-  }
-
-
-
-template<typename T1>
-inline
-umat
-sort_index(const Base<typename T1::elem_type,T1>& X, const uword sort_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  arma_type_check(( is_complex<eT>::value == true ));
-  
-  const unwrap<T1> tmp(X.get_ref());
-  const Mat<eT>& A = tmp.M;
-  
-  if(A.is_empty() == true)
-    {
-    return umat();
-    }
-  
-  arma_debug_check( (A.is_vec() == false), "sort_index(): currently only handles vectors");
-  
-  typedef typename umat::elem_type out_elem_type;
-  
-  umat out(A.n_rows, A.n_cols);
-  
-  if(sort_type == 0)
-    {
-    std::vector< arma_sort_index_packet_ascend<eT,out_elem_type> > packet_vec(A.n_elem);
-    
-    sort_index_helper(out.memptr(), packet_vec, A.mem);
-    }
-  else
-    {
-    std::vector< arma_sort_index_packet_descend<eT,out_elem_type> > packet_vec(A.n_elem);
-    
-    sort_index_helper(out.memptr(), packet_vec, A.mem);
-    }
-  
-  return out;
-  }
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_stddev.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_stddev
-//! @{
-
-
-
-template<typename T1>
-inline
-const mtOp<typename T1::pod_type, T1, op_stddev>
-stddev(const Base<typename T1::elem_type,T1>& X, const uword norm_type = 0, const uword dim = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<typename T1::pod_type, T1, op_stddev>(X.get_ref(), norm_type, dim);
-  }
-
-
-
-//! Immediate 'find the standard deviation of a row vector' operation
-template<typename eT>
-inline
-arma_warn_unused
-typename get_pod_type<eT>::result
-stddev(const Row<eT>& A, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "stddev(): given object has no elements" );
-  
-  return std::sqrt( op_var::direct_var(A.mem, A_n_elem, norm_type) );
-  }
-
-
-
-//! Immediate 'find the standard deviation of a column vector' operation
-template<typename eT>
-inline
-arma_warn_unused
-typename get_pod_type<eT>::result
-stddev(const Col<eT>& A, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "stddev(): given object has no elements" );
-  
-  return std::sqrt( op_var::direct_var(A.mem, A_n_elem, norm_type) );
-  }
-
-
-
-//! find the standard deviation of a subview_row
-template<typename eT>
-inline
-arma_warn_unused
-typename get_pod_type<eT>::result
-stddev(const subview_row<eT>& A, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "stddev(): given object has no elements" );
-  
-  return std::sqrt( op_var::direct_var(A, norm_type) );
-  }
-
-
-
-//! find the standard deviation of a subview_col
-template<typename eT>
-inline
-arma_warn_unused
-typename get_pod_type<eT>::result
-stddev(const subview_col<eT>& A, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "stddev(): given object has no elements" );
-  
-  return std::sqrt( op_var::direct_var(A.colptr(0), A.n_rows, norm_type) );
-  }
-
-
-
-//! find the standard deviation of a diagview
-template<typename eT>
-inline
-arma_warn_unused
-typename get_pod_type<eT>::result
-stddev(const diagview<eT>& A, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "stddev(): given object has no elements" );
-  
-  return std::sqrt( op_var::direct_var(A, norm_type) );
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-arma_warn_unused
-typename get_pod_type<eT>::result
-stddev(const subview_elem1<eT,T1>& A, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Col<eT> X(A);
-  
-  return stddev(X, norm_type);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_strans.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_strans
-//! @{
-
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_strans>
-strans(const Base<typename T1::elem_type,T1>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return Op<T1, op_strans>(X.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_htrans>
-strans(const Base<typename T1::elem_type,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return Op<T1, op_htrans>(X.get_ref());
-  }
-
-
-
-//! two consecutive transpose operations cancel each other
-template<typename T1>
-arma_inline
-const T1&
-strans(const Op<T1, op_strans>& X)
-  {
-  arma_extra_debug_sigprint();
-  arma_extra_debug_print("strans(): removing op_strans");
-  
-  return X.m;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_sum.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,152 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_sum
-//! @{
-
-
-//! \brief
-//! Delayed sum of elements of a matrix along a specified dimension (either rows or columns).
-//! The result is stored in a dense matrix that has either one column or one row.
-//! For dim = 0, find the sum of each column.
-//! For dim = 1, find the sum of each row.
-//! The default is dim = 0.
-//! NOTE: this function works differently than in Matlab/Octave.
-
-template<typename T1>
-arma_inline
-const Op<T1, op_sum>
-sum(const Base<typename T1::elem_type,T1>& X, const uword dim = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_sum>(X.get_ref(), dim, 0);
-  }
-
-
-//! \brief
-//! Immediate 'sum all values' operation for a row vector
-template<typename eT>
-inline
-arma_warn_unused
-eT
-sum(const Row<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return accu(X);
-  }
-
-
-
-//! \brief
-//! Immediate 'sum all values' operation for a column vector
-template<typename eT>
-inline
-arma_warn_unused
-eT
-sum(const Col<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return accu(X);
-  }
-
-
-
-//! \brief
-//! Immediate 'sum all values' operation,
-//! invoked, for example, by: sum(sum(A))
-
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::elem_type
-sum(const Op<T1, op_sum>& in)
-  {
-  arma_extra_debug_sigprint();
-  arma_extra_debug_print("sum(): two consecutive sum() calls detected");
-  
-  return accu(in.m);
-  }
-
-
-
-template<typename T1>
-arma_inline
-const Op<Op<T1, op_sum>, op_sum>
-sum(const Op<T1, op_sum>& in, const uword dim)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<Op<T1, op_sum>, op_sum>(in, dim, 0);
-  }
-
-
-
-//! sum all values of a subview_row
-template<typename eT>
-inline
-arma_warn_unused
-eT
-sum(const subview_row<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return accu(X);
-  }
-
-
-
-//! sum all values of a subview_col
-template<typename eT>
-inline
-arma_warn_unused
-eT
-sum(const subview_col<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return accu(X);
-  }
-
-
-
-//! sum all values of a diagview
-template<typename eT>
-inline
-arma_warn_unused
-eT
-sum(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return accu(X);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-arma_warn_unused
-eT
-sum(const subview_elem1<eT,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return accu(A);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_svd.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_svd
-//! @{
-
-
-
-template<typename T1>
-inline
-bool
-svd
-  (
-         Col<typename T1::pod_type>&     S,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  // it doesn't matter if X is an alias of S, as auxlib::svd() makes a copy of X
-  
-  const bool status = auxlib::svd(S, X);
-  
-  if(status == false)
-    {
-    S.reset();
-    arma_bad("svd(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-template<typename T1>
-inline
-Col<typename T1::pod_type>
-svd
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  Col<typename T1::pod_type> out;
-  
-  const bool status = auxlib::svd(out, X);
-  
-  if(status == false)
-    {
-    out.reset();
-    arma_bad("svd(): failed to converge");
-    }
-  
-  return out;
-  }
-
-
-
-template<typename T1>
-inline
-bool
-svd
-  (
-         Mat<typename T1::elem_type>&    U,
-         Col<typename T1::pod_type >&    S,
-         Mat<typename T1::elem_type>&    V,
-  const Base<typename T1::elem_type,T1>& X,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename T1::elem_type eT;
-  
-  arma_debug_check
-    (
-    ( ((void*)(&U) == (void*)(&S)) || (&U == &V) || ((void*)(&S) == (void*)(&V)) ),
-    "svd(): two or more output objects are the same object"
-    );
-  
-  // auxlib::svd() makes an internal copy of X
-  const bool status = auxlib::svd(U, S, V, X);
-  
-  if(status == false)
-    {
-    U.reset();
-    S.reset();
-    V.reset();
-    arma_bad("svd(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-template<typename T1>
-inline
-bool
-svd_econ
-  (
-         Mat<typename T1::elem_type>&    U,
-         Col<typename T1::pod_type >&    S,
-         Mat<typename T1::elem_type>&    V,
-  const Base<typename T1::elem_type,T1>& X,
-  const char                             mode = 'b',
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename T1::elem_type eT;
-  
-  arma_debug_check
-    (
-    ( ((void*)(&U) == (void*)(&S)) || (&U == &V) || ((void*)(&S) == (void*)(&V)) ),
-    "svd_econ(): two or more output objects are the same object"
-    );
-  
-  arma_debug_check
-    (
-    ( (mode != 'l') && (mode != 'r') && (mode != 'b') ),
-    "svd_econ(): parameter 'mode' is incorrect"
-    );
-  
-  
-  // auxlib::svd_econ() makes an internal copy of X
-  const bool status = auxlib::svd_econ(U, S, V, X, mode);
-  
-  if(status == false)
-    {
-    U.reset();
-    S.reset();
-    V.reset();
-    arma_bad("svd_econ(): failed to converge", false);
-    }
-  
-  return status;
-  }
-
-
-
-template<typename T1>
-arma_deprecated
-inline
-bool
-svd_thin
-  (
-         Mat<typename T1::elem_type>&    U,
-         Col<typename T1::pod_type >&    S,
-         Mat<typename T1::elem_type>&    V,
-  const Base<typename T1::elem_type,T1>& X,
-  const char                             mode = 'b',
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_ignore(junk);
-  
-  return svd_econ(U,S,V,X,mode);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_syl_lyap.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-// Copyright (C) 2011-2012 NICTA (www.nicta.com.au)
-// Copyright (C) 2011-2012 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_syl_lyap
-//! @{
-
-
-//! find the solution of the Sylvester equation AX + XB = C
-template<typename T1, typename T2, typename T3>
-inline
-bool
-syl
-  (
-        Mat <typename T1::elem_type>   & out,
-  const Base<typename T1::elem_type,T1>& in_A,
-  const Base<typename T1::elem_type,T2>& in_B,
-  const Base<typename T1::elem_type,T3>& in_C,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> tmp_A(in_A.get_ref(), out);
-  const unwrap_check<T2> tmp_B(in_B.get_ref(), out);
-  const unwrap_check<T3> tmp_C(in_C.get_ref(), out);
-  
-  const Mat<eT>& A = tmp_A.M;
-  const Mat<eT>& B = tmp_B.M;
-  const Mat<eT>& C = tmp_C.M;
-  
-  const bool status = auxlib::syl(out, A, B, C);
-  
-  if(status == false)
-    {
-    out.reset();
-    arma_bad("syl(): equation appears to be singular", false);
-    }
-  
-  return status;
-  }
-
-
-
-template<typename T1, typename T2, typename T3>
-inline
-Mat<typename T1::elem_type>
-syl
-  (
-  const Base<typename T1::elem_type,T1>& in_A,
-  const Base<typename T1::elem_type,T2>& in_B,
-  const Base<typename T1::elem_type,T3>& in_C,
-  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1> tmp_A( in_A.get_ref() );
-  const unwrap<T2> tmp_B( in_B.get_ref() );
-  const unwrap<T3> tmp_C( in_C.get_ref() );
-  
-  const Mat<eT>& A = tmp_A.M;
-  const Mat<eT>& B = tmp_B.M;
-  const Mat<eT>& C = tmp_C.M;
-  
-  Mat<eT> out;
-  
-  const bool status = auxlib::syl(out, A, B, C);
-  
-  if(status == false)
-    {
-    out.reset();
-    arma_bad("syl(): equation appears to be singular");
-    }
-  
-  return out;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_symmat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_symmat
-//! @{
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_symmat>
-symmatu(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_symmat>(X.get_ref(), 0, 0);
-  }
-
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_symmat>
-symmatl(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_symmat>(X.get_ref(), 1, 0);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_toeplitz.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// Copyright (C) 2011 Alcatel Lucent
-// Copyright (C) 2011 Gerhard Schreiber
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_toeplitz
-//! @{
-
-
-
-template<typename T1>
-inline
-Glue<T1, T1, glue_toeplitz>
-toeplitz(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Glue<T1, T1, glue_toeplitz>( X.get_ref(), X.get_ref() );
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-Glue<T1, T2, glue_toeplitz>
-toeplitz(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Glue<T1, T2, glue_toeplitz>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-template<typename T1>
-inline
-Glue<T1, T1, glue_toeplitz_circ>
-circ_toeplitz(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Glue<T1, T1, glue_toeplitz_circ>( X.get_ref(), X.get_ref() );
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_trace.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_trace
-//! @{
-
-
-//! Immediate trace (sum of diagonal elements) of a square dense matrix
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::elem_type
-trace(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const Proxy<T1> A(X.get_ref());
-
-  arma_debug_check( (A.get_n_rows() != A.get_n_cols()), "trace(): matrix must be square sized" );
-  
-  const uword N   = A.get_n_rows();
-        eT  val = eT(0);
-  
-  for(uword i=0; i<N; ++i)
-    {
-    val += A.at(i,i);
-    }
-  
-  return val;
-  }
-
-
-
-template<typename T1>
-inline
-arma_warn_unused
-typename T1::elem_type
-trace(const Op<T1, op_diagmat>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const diagmat_proxy<T1> A(X.m);
-  
-  const uword N = A.n_elem;
-  
-  eT val = eT(0);
-  
-  for(uword i=0; i<N; ++i)
-    {
-    val += A[i];
-    }
-  
-  return val;
-  }
-
-
-//! speedup for trace(A*B), where the result of A*B is a square sized matrix
-template<typename T1, typename T2>
-inline
-arma_warn_unused
-typename T1::elem_type
-trace(const Glue<T1, T2, glue_times>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1> tmp1(X.A);
-  const unwrap<T2> tmp2(X.B);
-  
-  const Mat<eT>& A = tmp1.M;
-  const Mat<eT>& B = tmp2.M;
-  
-  arma_debug_assert_mul_size(A, B, "matrix multiply");
-  
-  arma_debug_check( (A.n_rows != B.n_cols), "trace(): matrix must be square sized" );
-  
-  const uword N1  = A.n_rows;
-  const uword N2  = A.n_cols;
-        eT  val = eT(0);
-  
-  for(uword i=0; i<N1; ++i)
-    {
-    const eT* B_colmem = B.colptr(i);
-          eT  acc      = eT(0);
-    
-    for(uword j=0; j<N2; ++j)
-      {
-      acc += A.at(i,j) * B_colmem[j];
-      }
-    
-    val += acc;
-    }
-  
-  return val;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_trans.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_trans
-//! @{
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_htrans>
-trans(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_htrans>(X.get_ref());
-  }
-
-
-
-//! two consecutive transpose operations cancel each other
-template<typename T1>
-arma_inline
-const T1&
-trans(const Op<T1, op_htrans>& X)
-  {
-  arma_extra_debug_sigprint();
-  arma_extra_debug_print("trans(): removing op_htrans");
-  
-  return X.m;
-  }
-
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_htrans>
-htrans(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_htrans>(X.get_ref());
-  }
-
-
-
-//! two consecutive hermitian transpose operations cancel each other
-template<typename T1>
-arma_inline
-const T1&
-htrans(const Op<T1, op_htrans>& X)
-  {
-  arma_extra_debug_sigprint();
-  arma_extra_debug_print("htrans(): removing op_htrans");
-  
-  return X.m;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_trig.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,348 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_trig
-//! @{
-
-//
-// trigonometric functions:
-// cos family: cos, acos, cosh, acosh
-// sin family: sin, asin, sinh, asinh
-// tan family: tan, atan, tanh, atanh
-
-
-//
-// cos
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_cos>
-cos(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_cos>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_cos>
-cos(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_cos>(A.get_ref());
-  }
-
-
-
-//
-// acos
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_acos>
-acos(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_acos>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_acos>
-acos(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_acos>(A.get_ref());
-  }
-
-
-
-//
-// cosh
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_cosh>
-cosh(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_cosh>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_cosh>
-cosh(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_cosh>(A.get_ref());
-  }
-
-
-
-//
-// acosh
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_acosh>
-acosh(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_acosh>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_acosh>
-acosh(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_acosh>(A.get_ref());
-  }
-
-
-
-//
-// sin
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_sin>
-sin(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_sin>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_sin>
-sin(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_sin>(A.get_ref());
-  }
-
-
-
-//
-// asin
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_asin>
-asin(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_asin>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_asin>
-asin(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_asin>(A.get_ref());
-  }
-
-
-
-//
-// sinh
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_sinh>
-sinh(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_sinh>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_sinh>
-sinh(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_sinh>(A.get_ref());
-  }
-
-
-
-//
-// asinh
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_asinh>
-asinh(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_asinh>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_asinh>
-asinh(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_asinh>(A.get_ref());
-  }
-
-
-
-//
-// tan
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_tan>
-tan(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_tan>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_tan>
-tan(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_tan>(A.get_ref());
-  }
-
-
-
-//
-// atan
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_atan>
-atan(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_atan>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_atan>
-atan(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_atan>(A.get_ref());
-  }
-
-
-
-//
-// tanh
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_tanh>
-tanh(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_tanh>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_tanh>
-tanh(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_tanh>(A.get_ref());
-  }
-
-
-
-//
-// atanh
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_atanh>
-atanh(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_atanh>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_atanh>
-atanh(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_atanh>(A.get_ref());
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_trimat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_trimat
-//! @{
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_trimat>
-trimatu(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_trimat>(X.get_ref(), 0, 0);
-  }
-
-
-
-template<typename T1>
-arma_inline
-const Op<T1, op_trimat>
-trimatl(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_trimat>(X.get_ref(), 1, 0);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_trunc_exp.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup fn_trunc_exp
-//! @{
-
-
-
-template<typename eT>
-inline
-static
-typename arma_float_only<eT>::result
-trunc_exp(const eT x)
-  {
-  if(std::numeric_limits<eT>::is_iec559 && (x >= Math<eT>::log_max() ))
-    {
-    return std::numeric_limits<eT>::max();
-    }
-  else
-    {
-    return std::exp(x);
-    }
-  }
-
-
-
-template<typename eT>
-inline
-static
-typename arma_integral_only<eT>::result
-trunc_exp(const eT x)
-  {
-  return eT( trunc_exp( double(x) ) );
-  }
-
-
-
-template<typename T>
-arma_inline
-static
-std::complex<T>
-trunc_exp(const std::complex<T>& x)
-  {
-  return std::exp(x);
-  }
-  
-  
-  
-template<typename T1>
-arma_inline
-const eOp<T1, eop_trunc_exp>
-trunc_exp(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_trunc_exp>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_trunc_exp>
-trunc_exp(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_trunc_exp>(A.get_ref());
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_trunc_log.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_trunc_log
-//! @{
-
-
-
-template<typename eT>
-inline 
-static
-typename arma_float_only<eT>::result
-trunc_log(const eT x)
-  {
-  if(std::numeric_limits<eT>::is_iec559)
-    {
-    if(x == std::numeric_limits<eT>::infinity())
-      {
-      return Math<eT>::log_max();
-      }
-    else
-      {
-      return (x <= eT(0)) ? Math<eT>::log_min() : std::log(x);
-      }
-    }
-  else
-    {
-    return std::log(x);
-    }
-  }
-
-
-
-template<typename eT>
-inline 
-static
-typename arma_integral_only<eT>::result
-trunc_log(const eT x)
-  {
-  return eT( trunc_log( double(x) ) );
-  }
-
-
-
-template<typename T>
-inline 
-static
-std::complex<T>
-trunc_log(const std::complex<T>& x)
-  {
-  return std::log(x);
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOp<T1, eop_trunc_log>
-trunc_log(const Base<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_trunc_log>(A.get_ref());
-  }
-
-
-
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_trunc_log>
-trunc_log(const BaseCube<typename T1::elem_type,T1>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_trunc_log>(A.get_ref());
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_var.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_var
-//! @{
-
-
-
-template<typename T1>
-inline
-const mtOp<typename T1::pod_type, T1, op_var>
-var(const Base<typename T1::elem_type,T1>& X, const uword norm_type = 0, const uword dim = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<typename T1::pod_type, T1, op_var>(X.get_ref(), norm_type, dim);
-  }
-
-
-
-//! Immediate 'find the variance of a row vector' operation
-template<typename eT>
-inline
-arma_warn_unused
-typename get_pod_type<eT>::result
-var(const Row<eT>& A, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "var(): given object has no elements" );
-  
-  return op_var::direct_var(A.mem, A_n_elem, norm_type);
-  }
-
-
-
-//! Immediate 'find the variance of a column vector' operation
-template<typename eT>
-inline
-arma_warn_unused
-typename get_pod_type<eT>::result
-var(const Col<eT>& A, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_elem = A.n_elem;
-  
-  arma_debug_check( (A_n_elem == 0), "var(): given object has no elements" );
-  
-  return op_var::direct_var(A.mem, A_n_elem, norm_type);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-typename get_pod_type<eT>::result
-var(const subview_row<eT>& A, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "var(): given object has no elements" );
-  
-  return op_var::direct_var(A, norm_type);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-typename get_pod_type<eT>::result
-var(const subview_col<eT>& A, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "var(): given object has no elements" );
-  
-  return op_var::direct_var(A.colptr(0), A.n_rows, norm_type);
-  }
-
-
-
-template<typename eT>
-inline
-arma_warn_unused
-typename get_pod_type<eT>::result
-var(const diagview<eT>& A, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( (A.n_elem == 0), "var(): given object has no elements" );
-  
-  return op_var::direct_var(A, norm_type);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-arma_warn_unused
-typename get_pod_type<eT>::result
-var(const subview_elem1<eT,T1>& A, const uword norm_type = 0)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Col<eT> X(A);
-  
-  return var(X, norm_type);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/fn_zeros.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup fn_zeros
-//! @{
-
-
-//! Generate a vector with all elements set to zero
-arma_inline
-const Gen<vec::elem_type, gen_zeros>
-zeros(const uword n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Gen<vec::elem_type, gen_zeros>(n_elem, 1);
-  }
-
-
-
-template<typename vec_type>
-arma_inline
-const Gen<typename vec_type::elem_type, gen_zeros>
-zeros(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only<vec_type>::result* junk2 = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk1);
-  arma_ignore(junk2);
-  
-  if(is_Row<vec_type>::value == true)
-    {
-    return Gen<typename vec_type::elem_type, gen_zeros>(1, n_elem);
-    }
-  else
-    {
-    return Gen<typename vec_type::elem_type, gen_zeros>(n_elem, 1);
-    }
-  }
-
-
-
-//! Generate a dense matrix with all elements set to zero
-arma_inline
-const Gen<mat::elem_type, gen_zeros>
-zeros(const uword n_rows, const uword n_cols)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Gen<mat::elem_type, gen_zeros>(n_rows, n_cols);
-  }
-
-
-
-template<typename mat_type>
-arma_inline
-const Gen<typename mat_type::elem_type, gen_zeros>
-zeros(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only<mat_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return Gen<typename mat_type::elem_type, gen_zeros>(n_rows, n_cols);
-  }
-
-
-
-arma_inline
-const GenCube<cube::elem_type, gen_zeros>
-zeros(const uword n_rows, const uword n_cols, const uword n_slices)
-  {
-  arma_extra_debug_sigprint();
-  
-  return GenCube<cube::elem_type, gen_zeros>(n_rows, n_cols, n_slices);
-  }
-
-
-
-template<typename cube_type>
-arma_inline
-const GenCube<typename cube_type::elem_type, gen_zeros>
-zeros(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only<cube_type>::result* junk = 0)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  return GenCube<typename cube_type::elem_type, gen_zeros>(n_rows, n_cols, n_slices);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/format_wrap.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,551 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup format_wrap
-//! @{
-
-
-//! \namespace arma_boost namespace for functions and classes which partially emulate Boost functionality 
-namespace arma_boost
-  {
-  
-  #if defined(ARMA_USE_BOOST_FORMAT)
-
-    using boost::format;
-    using boost::basic_format;
-    using boost::str;
-
-  #else
-  
-    #if defined(ARMA_HAVE_STD_SNPRINTF)
-
-      #define arma_snprintf std::snprintf
-
-    #else
-
-      // better-than-nothing emulation of C99 snprintf(),
-      // with correct return value and null-terminated output string.
-      // note that _snprintf() provided by MS is not a good substitute for snprintf()
-
-      inline
-      int
-      arma_snprintf(char* out, size_t size, const char* fmt, ...)
-        {
-        size_t i;
-        
-        for(i=0; i<size; ++i)
-          {
-          out[i] = fmt[i];
-          if(fmt[i] == char(0))
-            break;
-          }
-        
-        if(size > 0)
-          out[size-1] = char(0);
-        
-        return int(i);
-        }
-
-    #endif
-    
-    class format
-      {
-      public:
-    
-      format(const char* in_fmt)
-        : A(in_fmt)
-        {
-        }
-    
-      format(const std::string& in_fmt)
-        : A(in_fmt)
-        {
-        }
-    
-    
-      const std::string A;
-    
-      private:
-      format();
-      };
-    
-    
-    
-    template<typename T1, typename T2>
-    class basic_format
-      {
-      public:
-    
-      basic_format(const T1& in_A, const T2& in_B)
-        : A(in_A)
-        , B(in_B)
-        {
-        }
-    
-      const T1& A;
-      const T2& B;
-    
-      private:
-      basic_format();
-      };
-    
-    
-    
-    template<typename T2>
-    inline
-    basic_format< format, T2 >
-    operator% (const format& X, const T2& arg)
-      {
-      return basic_format< format, T2 >(X, arg);
-      }
-    
-    
-    
-    template<typename T1, typename T2, typename T3>
-    inline
-    basic_format< basic_format<T1,T2>, T3 >
-    operator% (const basic_format<T1,T2>& X, const T3& arg)
-      {
-      return basic_format< basic_format<T1,T2>, T3 >(X, arg);
-      }
-    
-    
-    
-    template<typename T2>
-    inline
-    std::string
-    str(const basic_format< format, T2>& X)
-      {
-      char  local_buffer[1024];
-      char* buffer = local_buffer;
-      
-      int buffer_size   = 1024;
-      int required_size = buffer_size;
-   
-      bool using_local_buffer = true;
-      
-      std::string out;
-      
-      do
-        {
-        if(using_local_buffer == false)
-          {
-          buffer = new char[buffer_size];
-          }
-        
-        required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.c_str(), X.B);
-        
-        if(required_size < buffer_size)
-          {
-          if(required_size > 0)
-            {
-            out = buffer;
-            }
-          }
-        else
-          {
-          buffer_size *= 2;
-          }
-        
-        if(using_local_buffer == true)
-          {
-          using_local_buffer = false;
-          }
-        else
-          {
-          delete[] buffer;
-          }
-        
-        } while( (required_size >= buffer_size) );
-
-      return out;
-      }
-    
-    
-    
-    template<typename T2, typename T3>
-    inline
-    std::string
-    str(const basic_format< basic_format< format, T2>, T3>& X)
-      {
-      char  local_buffer[1024];
-      char* buffer = local_buffer;
-      
-      int buffer_size   = 1024;
-      int required_size = buffer_size;
-   
-      bool using_local_buffer = true;
-      
-      std::string out;
-      
-      do
-        {
-        if(using_local_buffer == false)
-          {
-          buffer = new char[buffer_size];
-          }
-        
-        required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.c_str(), X.A.B, X.B);
-        
-        if(required_size < buffer_size)
-          {
-          if(required_size > 0)
-            {
-            out = buffer;
-            }
-          }
-        else
-          {
-          buffer_size *= 2;
-          }
-        
-        if(using_local_buffer == true)
-          {
-          using_local_buffer = false;
-          }
-        else
-          {
-          delete[] buffer;
-          }
-        
-        } while( (required_size >= buffer_size) );
-
-      return out;
-      }
-    
-    
-    
-    template<typename T2, typename T3, typename T4>
-    inline
-    std::string
-    str(const basic_format< basic_format< basic_format< format, T2>, T3>, T4>& X)
-      {
-      char  local_buffer[1024];
-      char* buffer = local_buffer;
-      
-      int buffer_size   = 1024;
-      int required_size = buffer_size;
-   
-      bool using_local_buffer = true;
-      
-      std::string out;
-      
-      do
-        {
-        if(using_local_buffer == false)
-          {
-          buffer = new char[buffer_size];
-          }
-        
-        required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.c_str(), X.A.A.B, X.A.B, X.B);
-        
-        if(required_size < buffer_size)
-          {
-          if(required_size > 0)
-            {
-            out = buffer;
-            }
-          }
-        else
-          {
-          buffer_size *= 2;
-          }
-        
-        if(using_local_buffer == true)
-          {
-          using_local_buffer = false;
-          }
-        else
-          {
-          delete[] buffer;
-          }
-        
-        } while( (required_size >= buffer_size) );
-
-      return out;
-      }
-    
-    
-    
-    template<typename T2, typename T3, typename T4, typename T5>
-    inline
-    std::string
-    str(const basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>& X)
-      {
-      char  local_buffer[1024];
-      char* buffer = local_buffer;
-      
-      int buffer_size   = 1024;
-      int required_size = buffer_size;
-   
-      bool using_local_buffer = true;
-      
-      std::string out;
-      
-      do
-        {
-        if(using_local_buffer == false)
-          {
-          buffer = new char[buffer_size];
-          }
-        
-        required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.c_str(), X.A.A.A.B, X.A.A.B, X.A.B, X.B);
-        
-        if(required_size < buffer_size)
-          {
-          if(required_size > 0)
-            {
-            out = buffer;
-            }
-          }
-        else
-          {
-          buffer_size *= 2;
-          }
-        
-        if(using_local_buffer == true)
-          {
-          using_local_buffer = false;
-          }
-        else
-          {
-          delete[] buffer;
-          }
-        
-        } while( (required_size >= buffer_size) );
-
-      return out;
-      }
-    
-    
-    
-    template<typename T2, typename T3, typename T4, typename T5, typename T6>
-    inline
-    std::string
-    str(const basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>& X)
-      {
-      char  local_buffer[1024];
-      char* buffer = local_buffer;
-      
-      int buffer_size   = 1024;
-      int required_size = buffer_size;
-   
-      bool using_local_buffer = true;
-      
-      std::string out;
-      
-      do
-        {
-        if(using_local_buffer == false)
-          {
-          buffer = new char[buffer_size];
-          }
-        
-        required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.c_str(), X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B);
-        
-        if(required_size < buffer_size)
-          {
-          if(required_size > 0)
-            {
-            out = buffer;
-            }
-          }
-        else
-          {
-          buffer_size *= 2;
-          }
-        
-        if(using_local_buffer == true)
-          {
-          using_local_buffer = false;
-          }
-        else
-          {
-          delete[] buffer;
-          }
-        
-        } while( (required_size >= buffer_size) );
-
-      return out;
-      }
-    
-    
-    
-    template<typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
-    inline
-    std::string
-    str(const basic_format< basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>, T7>& X)
-      {
-      char  local_buffer[1024];
-      char* buffer = local_buffer;
-      
-      int buffer_size   = 1024;
-      int required_size = buffer_size;
-   
-      bool using_local_buffer = true;
-      
-      std::string out;
-      
-      do
-        {
-        if(using_local_buffer == false)
-          {
-          buffer = new char[buffer_size];
-          }
-        
-        required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.A.c_str(), X.A.A.A.A.A.B, X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B);
-        
-        if(required_size < buffer_size)
-          {
-          if(required_size > 0)
-            {
-            out = buffer;
-            }
-          }
-        else
-          {
-          buffer_size *= 2;
-          }
-        
-        if(using_local_buffer == true)
-          {
-          using_local_buffer = false;
-          }
-        else
-          {
-          delete[] buffer;
-          }
-        
-        } while( (required_size >= buffer_size) );
-
-      return out;
-      }
-    
-    
-    
-    template<typename T1>
-    struct format_metaprog
-      {
-      static const uword depth = 0;
-    
-      inline
-      static  
-      const std::string&
-      get_fmt(const T1& X)
-        {
-        return X.A;
-        }
-      };
-    
-    
-    
-    //template<>
-    template<typename T1, typename T2>
-    struct format_metaprog< basic_format<T1,T2> >
-      {
-      static const uword depth = 1 + format_metaprog<T1>::depth;
-    
-      inline
-      static
-      const std::string&
-      get_fmt(const T1& X)
-        {
-        return format_metaprog<T1>::get_fmt(X.A);
-        }
-    
-      };
-    
-    
-    
-    template<typename T1, typename T2>
-    inline
-    std::string
-    str(const basic_format<T1,T2>& X)
-      {
-      return format_metaprog< basic_format<T1,T2> >::get_fmt(X.A);
-      }
-    
-    
-    
-    template<typename T1, typename T2>
-    inline
-    std::ostream&
-    operator<< (std::ostream& o, const basic_format<T1,T2>& X)
-      {
-      o << str(X);
-      return o;
-      }
-        
-        
-  #endif
-  
-  
-  template<typename T> struct string_only              { };
-  template<>           struct string_only<std::string> { typedef std::string result; };
-  
-  template<typename T> struct char_only                { };
-  template<>           struct char_only<char         > { typedef char        result; };
-
-  template<typename T>
-  struct basic_format_only { };
-  
-  #if defined(ARMA_USE_BOOST_FORMAT)
-    template<typename T>
-    struct basic_format_only< basic_format<T>      > { typedef basic_format<T>     result; };
-  #else
-    template<typename T1, typename T2>
-    struct basic_format_only< basic_format<T1, T2> > { typedef basic_format<T1,T2> result; };
-  #endif
-
-
-
-  template<typename T1>
-  inline
-  static
-  const T1&
-  str_wrapper(const T1& x, const typename string_only<T1>::result* junk = 0)
-    {
-    arma_ignore(junk);
-    
-    return x;
-    }
-  
-  
-  
-  template<typename T1>
-  inline
-  static
-  const T1*
-  str_wrapper(const T1* x, const typename char_only<T1>::result* junk = 0)
-    {
-    arma_ignore(junk);
-    
-    return x;
-    }
-  
-  
-  
-  template<typename T1>
-  inline
-  static
-  std::string
-  str_wrapper(const T1& x, const typename basic_format_only<T1>::result* junk = 0)
-    {
-    arma_ignore(junk);
-    
-    return str(x);
-    }
-  
-  }
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/forward_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-using std::cout;
-using std::cerr;
-using std::endl;
-using std::ios;
-
-template<typename eT> class Mat;
-template<typename eT> class Col;
-template<typename eT> class Row;
-template<typename eT> class Cube;
-template<typename oT> class field;
-
-template<typename eT> class subview;
-template<typename eT> class subview_col;
-template<typename eT> class subview_row;
-template<typename eT> class subview_cube;
-template<typename oT> class subview_field;
-
-template<typename eT> class diagview;
-
-template<typename eT, typename T1>              class subview_elem1;
-template<typename eT, typename T1, typename T2> class subview_elem2;
-
-
-class arma_empty_class {};
-
-class diskio;
-
-class op_min;
-class op_max;
-
-class op_strans;
-class op_htrans;
-class op_inv;
-class op_sum;
-class op_abs;
-class op_diagmat;
-class op_trimat;
-
-class eop_conj;
-
-class glue_times;
-class glue_times_diag;
-
-class glue_rel_lt;
-class glue_rel_gt;
-class glue_rel_lteq;
-class glue_rel_gteq;
-class glue_rel_eq;
-class glue_rel_noteq;
-
-class op_rel_lt_pre;
-class op_rel_lt_post;
-class op_rel_gt_pre;
-class op_rel_gt_post;
-class op_rel_lteq_pre;
-class op_rel_lteq_post;
-class op_rel_gteq_pre;
-class op_rel_gteq_post;
-class op_rel_eq;
-class op_rel_noteq;
-
-class gen_ones_diag;
-class gen_ones_full;
-class gen_zeros;
-class gen_randu;
-class gen_randn;
-
-
-template<const bool, const bool, const bool, const bool> class gemm;
-template<const bool, const bool, const bool>             class gemv;
-
-
-template<                 typename eT, typename gen_type> class  Gen; 
-
-template<                 typename T1, typename  op_type> class   Op; 
-template<                 typename T1, typename eop_type> class  eOp;
-template<typename out_eT, typename T1, typename  op_type> class mtOp;
-
-template<                 typename T1, typename T2, typename  glue_type> class   Glue;
-template<                 typename T1, typename T2, typename eglue_type> class  eGlue;
-template<typename out_eT, typename T1, typename T2, typename  glue_type> class mtGlue;
-
-
-
-template<                 typename eT, typename gen_type> class  GenCube; 
-
-template<                 typename T1, typename  op_type> class   OpCube; 
-template<                 typename T1, typename eop_type> class  eOpCube; 
-template<typename out_eT, typename T1, typename  op_type> class mtOpCube;
-
-template<                 typename T1, typename T2, typename  glue_type> class   GlueCube;
-template<                 typename T1, typename T2, typename eglue_type> class  eGlueCube;
-template<typename out_eT, typename T1, typename T2, typename  glue_type> class mtGlueCube;
-
-
-template<typename T1> class Proxy;
-template<typename T1> class ProxyCube;
-
-
-
-//! \addtogroup injector
-//! @{
-
-
-struct injector_end_of_row {};
-
-static const injector_end_of_row endr = injector_end_of_row();
-//!< endr indicates "end of row" when using the << operator;
-//!< similar conceptual meaning to std::endl
-
-//! @}
-
-
-
-//! \addtogroup diskio
-//! @{
-
-
-enum file_type
-  {
-  file_type_unknown,
-  auto_detect,  //!< Automatically detect the file type (file must be one of the following types)
-  raw_ascii,    //!< ASCII format (text), without any other information.
-  arma_ascii,   //!< Armadillo ASCII format (text), with information about matrix type and size
-  csv_ascii,    //!< comma separated values (CSV), without any other information
-  raw_binary,   //!< raw binary format, without any other information.
-  arma_binary,  //!< Armadillo binary format, with information about matrix type and size
-  pgm_binary,   //!< Portable Grey Map (greyscale image)
-  ppm_binary    //!< Portable Pixel Map (colour image), used by the field and cube classes
-  };
-
-
-//! @}
-
-
--- a/armadillo-2.4.4/include/armadillo_bits/gemm.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,506 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup gemm
-//! @{
-
-
-
-//! for tiny square matrices, size <= 4x4
-template<const bool do_trans_A=false, const bool use_alpha=false, const bool use_beta=false>
-class gemm_emul_tinysq
-  {
-  public:
-  
-  
-  template<typename eT>
-  arma_hot
-  inline
-  static
-  void
-  apply
-    (
-          Mat<eT>& C,
-    const Mat<eT>& A,
-    const Mat<eT>& B,
-    const eT alpha = eT(1),
-    const eT beta  = eT(0)
-    )
-    {
-    arma_extra_debug_sigprint();
-    
-    switch(A.n_rows)
-      {
-      case 4:
-        gemv_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply( C.colptr(3), A, B.colptr(3), alpha, beta );
-        
-      case 3:
-        gemv_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply( C.colptr(2), A, B.colptr(2), alpha, beta );
-        
-      case 2:
-        gemv_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply( C.colptr(1), A, B.colptr(1), alpha, beta );
-        
-      case 1:
-        gemv_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply( C.colptr(0), A, B.colptr(0), alpha, beta );
-        
-      default:
-        ;
-      }
-    }
-  
-  };
-
-
-
-template<const bool do_trans_A=false, const bool do_trans_B=false, const bool use_alpha=false, const bool use_beta=false>
-class gemm_emul_large
-  {
-  public:
-  
-  template<typename eT>
-  arma_hot
-  inline
-  static
-  void
-  apply
-    (
-          Mat<eT>& C,
-    const Mat<eT>& A,
-    const Mat<eT>& B,
-    const eT alpha = eT(1),
-    const eT beta  = eT(0)
-    )
-    {
-    arma_extra_debug_sigprint();
-
-    const uword A_n_rows = A.n_rows;
-    const uword A_n_cols = A.n_cols;
-    
-    const uword B_n_rows = B.n_rows;
-    const uword B_n_cols = B.n_cols;
-    
-    if( (do_trans_A == false) && (do_trans_B == false) )
-      {
-      arma_aligned podarray<eT> tmp(A_n_cols);
-      eT* A_rowdata = tmp.memptr();
-      
-      for(uword row_A=0; row_A < A_n_rows; ++row_A)
-        {
-        tmp.copy_row(A, row_A);
-        
-        for(uword col_B=0; col_B < B_n_cols; ++col_B)
-          {
-          const eT acc = op_dot::direct_dot_arma(B_n_rows, A_rowdata, B.colptr(col_B));
-          
-          if( (use_alpha == false) && (use_beta == false) )
-            {
-            C.at(row_A,col_B) = acc;
-            }
-          else
-          if( (use_alpha == true) && (use_beta == false) )
-            {
-            C.at(row_A,col_B) = alpha * acc;
-            }
-          else
-          if( (use_alpha == false) && (use_beta == true) )
-            {
-            C.at(row_A,col_B) = acc + beta*C.at(row_A,col_B);
-            }
-          else
-          if( (use_alpha == true) && (use_beta == true) )
-            {
-            C.at(row_A,col_B) = alpha*acc + beta*C.at(row_A,col_B);
-            }
-          
-          }
-        }
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == false) )
-      {
-      for(uword col_A=0; col_A < A_n_cols; ++col_A)
-        {
-        // col_A is interpreted as row_A when storing the results in matrix C
-        
-        const eT* A_coldata = A.colptr(col_A);
-        
-        for(uword col_B=0; col_B < B_n_cols; ++col_B)
-          {
-          const eT acc = op_dot::direct_dot_arma(B_n_rows, A_coldata, B.colptr(col_B));
-          
-          if( (use_alpha == false) && (use_beta == false) )
-            {
-            C.at(col_A,col_B) = acc;
-            }
-          else
-          if( (use_alpha == true) && (use_beta == false) )
-            {
-            C.at(col_A,col_B) = alpha * acc;
-            }
-          else
-          if( (use_alpha == false) && (use_beta == true) )
-            {
-            C.at(col_A,col_B) = acc + beta*C.at(col_A,col_B);
-            }
-          else
-          if( (use_alpha == true) && (use_beta == true) )
-            {
-            C.at(col_A,col_B) = alpha*acc + beta*C.at(col_A,col_B);
-            }
-          
-          }
-        }
-      }
-    else
-    if( (do_trans_A == false) && (do_trans_B == true) )
-      {
-      Mat<eT> BB;
-      op_strans::apply_noalias(BB, B);
-      
-      gemm_emul_large<false, false, use_alpha, use_beta>::apply(C, A, BB, alpha, beta);
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == true) )
-      {
-      // mat B_tmp = trans(B);
-      // dgemm_arma<true, false,  use_alpha, use_beta>::apply(C, A, B_tmp, alpha, beta);
-      
-      
-      // By using the trans(A)*trans(B) = trans(B*A) equivalency,
-      // transpose operations are not needed
-      
-      arma_aligned podarray<eT> tmp(B.n_cols);
-      eT* B_rowdata = tmp.memptr();
-      
-      for(uword row_B=0; row_B < B_n_rows; ++row_B)
-        {
-        tmp.copy_row(B, row_B);
-        
-        for(uword col_A=0; col_A < A_n_cols; ++col_A)
-          {
-          const eT acc = op_dot::direct_dot_arma(A_n_rows, B_rowdata, A.colptr(col_A));
-          
-          if( (use_alpha == false) && (use_beta == false) )
-            {
-            C.at(col_A,row_B) = acc;
-            }
-          else
-          if( (use_alpha == true) && (use_beta == false) )
-            {
-            C.at(col_A,row_B) = alpha * acc;
-            }
-          else
-          if( (use_alpha == false) && (use_beta == true) )
-            {
-            C.at(col_A,row_B) = acc + beta*C.at(col_A,row_B);
-            }
-          else
-          if( (use_alpha == true) && (use_beta == true) )
-            {
-            C.at(col_A,row_B) = alpha*acc + beta*C.at(col_A,row_B);
-            }
-          
-          }
-        }
-      
-      }
-    }
-  
-  };
-    
-  
-  
-template<const bool do_trans_A=false, const bool do_trans_B=false, const bool use_alpha=false, const bool use_beta=false>
-class gemm_emul
-  {
-  public:
-  
-  
-  template<typename eT>
-  arma_hot
-  inline
-  static
-  void
-  apply
-    (
-          Mat<eT>& C,
-    const Mat<eT>& A,
-    const Mat<eT>& B,
-    const eT alpha = eT(1),
-    const eT beta  = eT(0),
-    const typename arma_not_cx<eT>::result* junk = 0
-    )
-    {
-    arma_extra_debug_sigprint();
-    arma_ignore(junk);
-    
-    const uword A_n_rows = A.n_rows;
-    const uword A_n_cols = A.n_cols;
-    
-    const uword B_n_rows = B.n_rows;
-    const uword B_n_cols = B.n_cols;
-    
-    if( (A_n_rows <= 4) && (A_n_rows == A_n_cols) && (A_n_rows == B_n_rows) && (B_n_rows == B_n_cols) )
-      {
-      if(do_trans_B == false)
-        {
-        gemm_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply(C, A, B, alpha, beta);
-        }
-      else
-        {
-        Mat<eT> BB(A_n_rows, A_n_rows);
-        op_strans::apply_noalias_tinysq(BB, B);
-        
-        gemm_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply(C, A, BB, alpha, beta);
-        }
-      }
-    else
-      {
-      gemm_emul_large<do_trans_A, do_trans_B, use_alpha, use_beta>::apply(C, A, B, alpha, beta);
-      }
-    }
-  
-
-
-  template<typename eT>
-  arma_hot
-  inline
-  static
-  void
-  apply
-    (
-          Mat<eT>& C,
-    const Mat<eT>& A,
-    const Mat<eT>& B,
-    const eT alpha = eT(1),
-    const eT beta  = eT(0),
-    const typename arma_cx_only<eT>::result* junk = 0
-    )
-    {
-    arma_extra_debug_sigprint();
-    arma_ignore(junk);
-    
-    // "better than nothing" handling of hermitian transposes for complex number matrices
-    
-    Mat<eT> tmp_A;
-    Mat<eT> tmp_B;
-    
-    if(do_trans_A)
-      {
-      op_htrans::apply_noalias(tmp_A, A);
-      }
-    
-    if(do_trans_B)
-      {
-      op_htrans::apply_noalias(tmp_B, B);
-      }
-    
-    const Mat<eT>& AA = (do_trans_A == false) ? A : tmp_A;
-    const Mat<eT>& BB = (do_trans_B == false) ? B : tmp_B;
-    
-    const uword A_n_rows = AA.n_rows;
-    const uword A_n_cols = AA.n_cols;
-    
-    const uword B_n_rows = BB.n_rows;
-    const uword B_n_cols = BB.n_cols;
-    
-    if( (A_n_rows <= 4) && (A_n_rows == A_n_cols) && (A_n_rows == B_n_rows) && (B_n_rows == B_n_cols) )
-      {
-      gemm_emul_tinysq<false, use_alpha, use_beta>::apply(C, AA, BB, alpha, beta);
-      }
-    else
-      {
-      gemm_emul_large<false, false, use_alpha, use_beta>::apply(C, AA, BB, alpha, beta);
-      }
-    }
-
-  };
-
-
-
-//! \brief
-//! Wrapper for ATLAS/BLAS dgemm function, using template arguments to control the arguments passed to dgemm.
-//! Matrix 'C' is assumed to have been set to the correct size (i.e. taking into account transposes)
-
-template<const bool do_trans_A=false, const bool do_trans_B=false, const bool use_alpha=false, const bool use_beta=false>
-class gemm
-  {
-  public:
-  
-  template<typename eT>
-  inline
-  static
-  void
-  apply_blas_type( Mat<eT>& C, const Mat<eT>& A, const Mat<eT>& B, const eT alpha = eT(1), const eT beta = eT(0) )
-    {
-    arma_extra_debug_sigprint();
-    
-    if( (A.n_elem <= 48u) && (B.n_elem <= 48u) )
-      {
-      gemm_emul<do_trans_A, do_trans_B, use_alpha, use_beta>::apply(C,A,B,alpha,beta);
-      }
-    else
-      {
-      #if defined(ARMA_USE_ATLAS)
-        {
-        arma_extra_debug_print("atlas::cblas_gemm()");
-        
-        atlas::cblas_gemm<eT>
-          (
-          atlas::CblasColMajor,
-          (do_trans_A) ? ( is_complex<eT>::value ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans,
-          (do_trans_B) ? ( is_complex<eT>::value ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans,
-          C.n_rows,
-          C.n_cols,
-          (do_trans_A) ? A.n_rows : A.n_cols,
-          (use_alpha) ? alpha : eT(1),
-          A.mem,
-          (do_trans_A) ? A.n_rows : C.n_rows,
-          B.mem,
-          (do_trans_B) ? C.n_cols : ( (do_trans_A) ? A.n_rows : A.n_cols ),
-          (use_beta) ? beta : eT(0),
-          C.memptr(),
-          C.n_rows
-          );
-        }
-      #elif defined(ARMA_USE_BLAS)
-        {
-        arma_extra_debug_print("blas::gemm()");
-        
-        const char trans_A = (do_trans_A) ? ( is_complex<eT>::value ? 'C' : 'T' ) : 'N';
-        const char trans_B = (do_trans_B) ? ( is_complex<eT>::value ? 'C' : 'T' ) : 'N';
-        
-        const blas_int m   = C.n_rows;
-        const blas_int n   = C.n_cols;
-        const blas_int k   = (do_trans_A) ? A.n_rows : A.n_cols;
-        
-        const eT local_alpha = (use_alpha) ? alpha : eT(1);
-        
-        const blas_int lda = (do_trans_A) ? k : m;
-        const blas_int ldb = (do_trans_B) ? n : k;
-        
-        const eT local_beta  = (use_beta) ? beta : eT(0);
-        
-        arma_extra_debug_print( arma_boost::format("blas::gemm(): trans_A = %c") % trans_A );
-        arma_extra_debug_print( arma_boost::format("blas::gemm(): trans_B = %c") % trans_B );
-        
-        blas::gemm<eT>
-          (
-          &trans_A,
-          &trans_B,
-          &m,
-          &n,
-          &k,
-          &local_alpha,
-          A.mem,
-          &lda,
-          B.mem,
-          &ldb,
-          &local_beta,
-          C.memptr(),
-          &m
-          );
-        }
-      #else
-        {
-        gemm_emul<do_trans_A, do_trans_B, use_alpha, use_beta>::apply(C,A,B,alpha,beta);
-        }
-      #endif
-      }
-    }
-  
-  
-  
-  //! immediate multiplication of matrices A and B, storing the result in C
-  template<typename eT>
-  inline
-  static
-  void
-  apply( Mat<eT>& C, const Mat<eT>& A, const Mat<eT>& B, const eT alpha = eT(1), const eT beta = eT(0) )
-    {
-    gemm_emul<do_trans_A, do_trans_B, use_alpha, use_beta>::apply(C,A,B,alpha,beta);
-    }
-  
-  
-  
-  arma_inline
-  static
-  void
-  apply
-    (
-          Mat<float>& C,
-    const Mat<float>& A,
-    const Mat<float>& B,
-    const float alpha = float(1),
-    const float beta  = float(0)
-    )
-    {
-    gemm<do_trans_A, do_trans_B, use_alpha, use_beta>::apply_blas_type(C,A,B,alpha,beta);
-    }
-  
-  
-  
-  arma_inline
-  static
-  void
-  apply
-    (
-          Mat<double>& C,
-    const Mat<double>& A,
-    const Mat<double>& B,
-    const double alpha = double(1),
-    const double beta  = double(0)
-    )
-    {
-    gemm<do_trans_A, do_trans_B, use_alpha, use_beta>::apply_blas_type(C,A,B,alpha,beta);
-    }
-  
-  
-  
-  arma_inline
-  static
-  void
-  apply
-    (
-          Mat< std::complex<float> >& C,
-    const Mat< std::complex<float> >& A,
-    const Mat< std::complex<float> >& B,
-    const std::complex<float> alpha = std::complex<float>(1),
-    const std::complex<float> beta  = std::complex<float>(0)
-    )
-    {
-    gemm<do_trans_A, do_trans_B, use_alpha, use_beta>::apply_blas_type(C,A,B,alpha,beta);
-    }
-  
-  
-  
-  arma_inline
-  static
-  void
-  apply
-    (
-          Mat< std::complex<double> >& C,
-    const Mat< std::complex<double> >& A,
-    const Mat< std::complex<double> >& B,
-    const std::complex<double> alpha = std::complex<double>(1),
-    const std::complex<double> beta  = std::complex<double>(0)
-    )
-    {
-    gemm<do_trans_A, do_trans_B, use_alpha, use_beta>::apply_blas_type(C,A,B,alpha,beta);
-    }
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/gemm_mixed.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,453 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup gemm_mixed
-//! @{
-
-
-
-//! \brief
-//! Matrix multplication where the matrices have differing element types.
-//! Uses caching for speedup.
-//! Matrix 'C' is assumed to have been set to the correct size (i.e. taking into account transposes)
-
-template<const bool do_trans_A=false, const bool do_trans_B=false, const bool use_alpha=false, const bool use_beta=false>
-class gemm_mixed_large
-  {
-  public:
-  
-  template<typename out_eT, typename in_eT1, typename in_eT2>
-  arma_hot
-  inline
-  static
-  void
-  apply
-    (
-          Mat<out_eT>& C,
-    const Mat<in_eT1>& A,
-    const Mat<in_eT2>& B,
-    const out_eT alpha = out_eT(1),
-    const out_eT beta  = out_eT(0)
-    )
-    {
-    arma_extra_debug_sigprint();
-    
-    const uword A_n_rows = A.n_rows;
-    const uword A_n_cols = A.n_cols;
-    
-    const uword B_n_rows = B.n_rows;
-    const uword B_n_cols = B.n_cols;
-    
-    if( (do_trans_A == false) && (do_trans_B == false) )
-      {
-      podarray<in_eT1> tmp(A_n_cols);
-      in_eT1* A_rowdata = tmp.memptr();
-      
-      for(uword row_A=0; row_A < A_n_rows; ++row_A)
-        {
-        tmp.copy_row(A, row_A);
-        
-        for(uword col_B=0; col_B < B_n_cols; ++col_B)
-          {
-          const in_eT2* B_coldata = B.colptr(col_B);
-          
-          out_eT acc = out_eT(0);
-          for(uword i=0; i < B_n_rows; ++i)
-            {
-            acc += upgrade_val<in_eT1,in_eT2>::apply(A_rowdata[i]) * upgrade_val<in_eT1,in_eT2>::apply(B_coldata[i]);
-            }
-        
-          if( (use_alpha == false) && (use_beta == false) )
-            {
-            C.at(row_A,col_B) = acc;
-            }
-          else
-          if( (use_alpha == true) && (use_beta == false) )
-            {
-            C.at(row_A,col_B) = alpha * acc;
-            }
-          else
-          if( (use_alpha == false) && (use_beta == true) )
-            {
-            C.at(row_A,col_B) = acc + beta*C.at(row_A,col_B);
-            }
-          else
-          if( (use_alpha == true) && (use_beta == true) )
-            {
-            C.at(row_A,col_B) = alpha*acc + beta*C.at(row_A,col_B);
-            }
-          
-          }
-        }
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == false) )
-      {
-      for(uword col_A=0; col_A < A_n_cols; ++col_A)
-        {
-        // col_A is interpreted as row_A when storing the results in matrix C
-        
-        const in_eT1* A_coldata = A.colptr(col_A);
-        
-        for(uword col_B=0; col_B < B_n_cols; ++col_B)
-          {
-          const in_eT2* B_coldata = B.colptr(col_B);
-          
-          out_eT acc = out_eT(0);
-          for(uword i=0; i < B_n_rows; ++i)
-            {
-            acc += upgrade_val<in_eT1,in_eT2>::apply(A_coldata[i]) * upgrade_val<in_eT1,in_eT2>::apply(B_coldata[i]);
-            }
-        
-          if( (use_alpha == false) && (use_beta == false) )
-            {
-            C.at(col_A,col_B) = acc;
-            }
-          else
-          if( (use_alpha == true) && (use_beta == false) )
-            {
-            C.at(col_A,col_B) = alpha * acc;
-            }
-          else
-          if( (use_alpha == false) && (use_beta == true) )
-            {
-            C.at(col_A,col_B) = acc + beta*C.at(col_A,col_B);
-            }
-          else
-          if( (use_alpha == true) && (use_beta == true) )
-            {
-            C.at(col_A,col_B) = alpha*acc + beta*C.at(col_A,col_B);
-            }
-          
-          }
-        }
-      }
-    else
-    if( (do_trans_A == false) && (do_trans_B == true) )
-      {
-      Mat<in_eT2> B_tmp;
-      
-      op_strans::apply_noalias(B_tmp, B);
-      
-      gemm_mixed_large<false, false, use_alpha, use_beta>::apply(C, A, B_tmp, alpha, beta);
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == true) )
-      {
-      // mat B_tmp = trans(B);
-      // dgemm_arma<true, false,  use_alpha, use_beta>::apply(C, A, B_tmp, alpha, beta);
-      
-      
-      // By using the trans(A)*trans(B) = trans(B*A) equivalency,
-      // transpose operations are not needed
-      
-      podarray<in_eT2> tmp(B_n_cols);
-      in_eT2* B_rowdata = tmp.memptr();
-      
-      for(uword row_B=0; row_B < B_n_rows; ++row_B)
-        {
-        tmp.copy_row(B, row_B);
-        
-        for(uword col_A=0; col_A < A_n_cols; ++col_A)
-          {
-          const in_eT1* A_coldata = A.colptr(col_A);
-          
-          out_eT acc = out_eT(0);
-          for(uword i=0; i < A_n_rows; ++i)
-            {
-            acc += upgrade_val<in_eT1,in_eT2>::apply(B_rowdata[i]) * upgrade_val<in_eT1,in_eT2>::apply(A_coldata[i]);
-            }
-        
-          if( (use_alpha == false) && (use_beta == false) )
-            {
-            C.at(col_A,row_B) = acc;
-            }
-          else
-          if( (use_alpha == true) && (use_beta == false) )
-            {
-            C.at(col_A,row_B) = alpha * acc;
-            }
-          else
-          if( (use_alpha == false) && (use_beta == true) )
-            {
-            C.at(col_A,row_B) = acc + beta*C.at(col_A,row_B);
-            }
-          else
-          if( (use_alpha == true) && (use_beta == true) )
-            {
-            C.at(col_A,row_B) = alpha*acc + beta*C.at(col_A,row_B);
-            }
-          
-          }
-        }
-      
-      }
-    }
-    
-  };
-
-
-
-//! Matrix multplication where the matrices have different element types.
-//! Simple version (no caching).
-//! Matrix 'C' is assumed to have been set to the correct size (i.e. taking into account transposes)
-template<const bool do_trans_A=false, const bool do_trans_B=false, const bool use_alpha=false, const bool use_beta=false>
-class gemm_mixed_small
-  {
-  public:
-  
-  template<typename out_eT, typename in_eT1, typename in_eT2>
-  arma_hot
-  inline
-  static
-  void
-  apply
-    (
-          Mat<out_eT>& C,
-    const Mat<in_eT1>& A,
-    const Mat<in_eT2>& B,
-    const out_eT alpha = out_eT(1),
-    const out_eT beta  = out_eT(0)
-    )
-    {
-    arma_extra_debug_sigprint();
-    
-    const uword A_n_rows = A.n_rows;
-    const uword A_n_cols = A.n_cols;
-    
-    const uword B_n_rows = B.n_rows;
-    const uword B_n_cols = B.n_cols;
-    
-    if( (do_trans_A == false) && (do_trans_B == false) )
-      {
-      for(uword row_A = 0; row_A < A_n_rows; ++row_A)
-        {
-        for(uword col_B = 0; col_B < B_n_cols; ++col_B)
-          {
-          const in_eT2* B_coldata = B.colptr(col_B);
-          
-          out_eT acc = out_eT(0);
-          for(uword i = 0; i < B_n_rows; ++i)
-            {
-            const out_eT val1 = upgrade_val<in_eT1,in_eT2>::apply(A.at(row_A,i));
-            const out_eT val2 = upgrade_val<in_eT1,in_eT2>::apply(B_coldata[i]);
-            acc += val1 * val2;
-            //acc += upgrade_val<in_eT1,in_eT2>::apply(A.at(row_A,i)) * upgrade_val<in_eT1,in_eT2>::apply(B_coldata[i]);
-            }
-          
-          if( (use_alpha == false) && (use_beta == false) )
-            {
-            C.at(row_A,col_B) = acc;
-            }
-          else
-          if( (use_alpha == true) && (use_beta == false) )
-            {
-            C.at(row_A,col_B) = alpha * acc;
-            }
-          else
-          if( (use_alpha == false) && (use_beta == true) )
-            {
-            C.at(row_A,col_B) = acc + beta*C.at(row_A,col_B);
-            }
-          else
-          if( (use_alpha == true) && (use_beta == true) )
-            {
-            C.at(row_A,col_B) = alpha*acc + beta*C.at(row_A,col_B);
-            }
-          }
-        }
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == false) )
-      {
-      for(uword col_A=0; col_A < A_n_cols; ++col_A)
-        {
-        // col_A is interpreted as row_A when storing the results in matrix C
-        
-        const in_eT1* A_coldata = A.colptr(col_A);
-        
-        for(uword col_B=0; col_B < B_n_cols; ++col_B)
-          {
-          const in_eT2* B_coldata = B.colptr(col_B);
-          
-          out_eT acc = out_eT(0);
-          for(uword i=0; i < B_n_rows; ++i)
-            {
-            acc += upgrade_val<in_eT1,in_eT2>::apply(A_coldata[i]) * upgrade_val<in_eT1,in_eT2>::apply(B_coldata[i]);
-            }
-        
-          if( (use_alpha == false) && (use_beta == false) )
-            {
-            C.at(col_A,col_B) = acc;
-            }
-          else
-          if( (use_alpha == true) && (use_beta == false) )
-            {
-            C.at(col_A,col_B) = alpha * acc;
-            }
-          else
-          if( (use_alpha == false) && (use_beta == true) )
-            {
-            C.at(col_A,col_B) = acc + beta*C.at(col_A,col_B);
-            }
-          else
-          if( (use_alpha == true) && (use_beta == true) )
-            {
-            C.at(col_A,col_B) = alpha*acc + beta*C.at(col_A,col_B);
-            }
-          
-          }
-        }
-      }
-    else
-    if( (do_trans_A == false) && (do_trans_B == true) )
-      {
-      for(uword row_A = 0; row_A < A_n_rows; ++row_A)
-        {
-        for(uword row_B = 0; row_B < B_n_rows; ++row_B)
-          {
-          out_eT acc = out_eT(0);
-          for(uword i = 0; i < B_n_cols; ++i)
-            {
-            acc += upgrade_val<in_eT1,in_eT2>::apply(A.at(row_A,i)) * upgrade_val<in_eT1,in_eT2>::apply(B.at(row_B,i));
-            }
-          
-          if( (use_alpha == false) && (use_beta == false) )
-            {
-            C.at(row_A,row_B) = acc;
-            }
-          else
-          if( (use_alpha == true) && (use_beta == false) )
-            {
-            C.at(row_A,row_B) = alpha * acc;
-            }
-          else
-          if( (use_alpha == false) && (use_beta == true) )
-            {
-            C.at(row_A,row_B) = acc + beta*C.at(row_A,row_B);
-            }
-          else
-          if( (use_alpha == true) && (use_beta == true) )
-            {
-            C.at(row_A,row_B) = alpha*acc + beta*C.at(row_A,row_B);
-            }
-          }
-        }
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == true) )
-      {
-      for(uword row_B=0; row_B < B_n_rows; ++row_B)
-        {
-        
-        for(uword col_A=0; col_A < A_n_cols; ++col_A)
-          {
-          const in_eT1* A_coldata = A.colptr(col_A);
-          
-          out_eT acc = out_eT(0);
-          for(uword i=0; i < A_n_rows; ++i)
-            {
-            acc += upgrade_val<in_eT1,in_eT2>::apply(B.at(row_B,i)) * upgrade_val<in_eT1,in_eT2>::apply(A_coldata[i]);
-            }
-        
-          if( (use_alpha == false) && (use_beta == false) )
-            {
-            C.at(col_A,row_B) = acc;
-            }
-          else
-          if( (use_alpha == true) && (use_beta == false) )
-            {
-            C.at(col_A,row_B) = alpha * acc;
-            }
-          else
-          if( (use_alpha == false) && (use_beta == true) )
-            {
-            C.at(col_A,row_B) = acc + beta*C.at(col_A,row_B);
-            }
-          else
-          if( (use_alpha == true) && (use_beta == true) )
-            {
-            C.at(col_A,row_B) = alpha*acc + beta*C.at(col_A,row_B);
-            }
-          
-          }
-        }
-      
-      }
-    }
-    
-  };
-
-
-
-
-
-//! \brief
-//! Matrix multplication where the matrices have differing element types.
-
-template<const bool do_trans_A=false, const bool do_trans_B=false, const bool use_alpha=false, const bool use_beta=false>
-class gemm_mixed
-  {
-  public:
-  
-  //! immediate multiplication of matrices A and B, storing the result in C
-  template<typename out_eT, typename in_eT1, typename in_eT2>
-  inline
-  static
-  void
-  apply
-    (
-          Mat<out_eT>& C,
-    const Mat<in_eT1>& A,
-    const Mat<in_eT2>& B,
-    const out_eT alpha = out_eT(1),
-    const out_eT beta  = out_eT(0)
-    )
-    {
-    arma_extra_debug_sigprint();
-    
-    Mat<in_eT1> tmp_A;
-    Mat<in_eT2> tmp_B;
-    
-    const bool predo_trans_A = ( (do_trans_A == true) && (is_complex<in_eT1>::value == true) );
-    const bool predo_trans_B = ( (do_trans_B == true) && (is_complex<in_eT2>::value == true) );
-    
-    if(do_trans_A)
-      {
-      op_htrans::apply_noalias(tmp_A, A);
-      }
-    
-    if(do_trans_B)
-      {
-      op_htrans::apply_noalias(tmp_B, B);
-      }
-     
-    const Mat<in_eT1>& AA = (predo_trans_A == false) ? A : tmp_A;
-    const Mat<in_eT2>& BB = (predo_trans_B == false) ? B : tmp_B;
-    
-    if( (AA.n_elem <= 64u) && (BB.n_elem <= 64u) )
-      {
-      gemm_mixed_small<((predo_trans_A) ? false : do_trans_A), ((predo_trans_B) ? false : do_trans_B), use_alpha, use_beta>::apply(C, AA, BB, alpha, beta);
-      }
-    else
-      {
-      gemm_mixed_large<((predo_trans_A) ? false : do_trans_A), ((predo_trans_B) ? false : do_trans_B), use_alpha, use_beta>::apply(C, AA, BB, alpha, beta);
-      }
-    }
-  
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/gemv.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,492 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup gemv
-//! @{
-
-
-
-//! for tiny square matrices, size <= 4x4
-template<const bool do_trans_A=false, const bool use_alpha=false, const bool use_beta=false>
-class gemv_emul_tinysq
-  {
-  public:
-  
-  
-  template<const uword row, const uword col>
-  struct pos
-    {
-    static const uword n2 = (do_trans_A == false) ? (row + col*2) : (col + row*2);
-    static const uword n3 = (do_trans_A == false) ? (row + col*3) : (col + row*3);
-    static const uword n4 = (do_trans_A == false) ? (row + col*4) : (col + row*4);
-    };
-  
-  
-  
-  template<typename eT, const uword i>
-  arma_hot
-  arma_inline
-  static
-  void
-  assign(eT* y, const eT acc, const eT alpha, const eT beta)
-    {
-    if(use_beta == false)
-      {
-      y[i] = (use_alpha == false) ? acc : alpha*acc;
-      }
-    else
-      {
-      const eT tmp = y[i];
-      
-      y[i] = beta*tmp + ( (use_alpha == false) ? acc : alpha*acc );
-      }
-    }
-  
-  
-
-  template<typename eT>
-  arma_hot
-  inline
-  static
-  void
-  apply( eT* y, const Mat<eT>& A, const eT* x, const eT alpha = eT(1), const eT beta = eT(0) )
-    {
-    arma_extra_debug_sigprint();
-    
-    const eT*  Am = A.memptr();
-    
-    switch(A.n_rows)
-      {
-      case 1:
-        {
-        const eT acc = Am[0] * x[0];
-        
-        assign<eT, 0>(y, acc, alpha, beta);
-        }
-        break;
-      
-      
-      case 2:
-        {
-        const eT x0 = x[0];
-        const eT x1 = x[1];
-        
-        const eT acc0 = Am[pos<0,0>::n2]*x0 + Am[pos<0,1>::n2]*x1;
-        const eT acc1 = Am[pos<1,0>::n2]*x0 + Am[pos<1,1>::n2]*x1;
-        
-        assign<eT, 0>(y, acc0, alpha, beta);
-        assign<eT, 1>(y, acc1, alpha, beta);
-        }
-        break;
-      
-        
-      case 3:
-        {
-        const eT x0 = x[0];
-        const eT x1 = x[1];
-        const eT x2 = x[2];
-        
-        const eT acc0 = Am[pos<0,0>::n3]*x0 + Am[pos<0,1>::n3]*x1 + Am[pos<0,2>::n3]*x2;
-        const eT acc1 = Am[pos<1,0>::n3]*x0 + Am[pos<1,1>::n3]*x1 + Am[pos<1,2>::n3]*x2;
-        const eT acc2 = Am[pos<2,0>::n3]*x0 + Am[pos<2,1>::n3]*x1 + Am[pos<2,2>::n3]*x2;
-        
-        assign<eT, 0>(y, acc0, alpha, beta);
-        assign<eT, 1>(y, acc1, alpha, beta);
-        assign<eT, 2>(y, acc2, alpha, beta);
-        }
-        break;
-      
-      
-      case 4:
-        {
-        const eT x0 = x[0];
-        const eT x1 = x[1];
-        const eT x2 = x[2];
-        const eT x3 = x[3];
-        
-        const eT acc0 = Am[pos<0,0>::n4]*x0 + Am[pos<0,1>::n4]*x1 + Am[pos<0,2>::n4]*x2 + Am[pos<0,3>::n4]*x3;
-        const eT acc1 = Am[pos<1,0>::n4]*x0 + Am[pos<1,1>::n4]*x1 + Am[pos<1,2>::n4]*x2 + Am[pos<1,3>::n4]*x3;
-        const eT acc2 = Am[pos<2,0>::n4]*x0 + Am[pos<2,1>::n4]*x1 + Am[pos<2,2>::n4]*x2 + Am[pos<2,3>::n4]*x3;
-        const eT acc3 = Am[pos<3,0>::n4]*x0 + Am[pos<3,1>::n4]*x1 + Am[pos<3,2>::n4]*x2 + Am[pos<3,3>::n4]*x3;
-        
-        assign<eT, 0>(y, acc0, alpha, beta);
-        assign<eT, 1>(y, acc1, alpha, beta);
-        assign<eT, 2>(y, acc2, alpha, beta);
-        assign<eT, 3>(y, acc3, alpha, beta);
-        }
-        break;
-      
-      
-      default:
-        ;
-      }
-    }
-    
-  };
-
-
-
-//! \brief
-//! Partial emulation of ATLAS/BLAS gemv().
-//! 'y' is assumed to have been set to the correct size (i.e. taking into account the transpose)
-
-template<const bool do_trans_A=false, const bool use_alpha=false, const bool use_beta=false>
-class gemv_emul_large
-  {
-  public:
-  
-  template<typename eT>
-  arma_hot
-  inline
-  static
-  void
-  apply( eT* y, const Mat<eT>& A, const eT* x, const eT alpha = eT(1), const eT beta = eT(0) )
-    {
-    arma_extra_debug_sigprint();
-    
-    const uword A_n_rows = A.n_rows;
-    const uword A_n_cols = A.n_cols;
-    
-    if(do_trans_A == false)
-      {
-      if(A_n_rows == 1)
-        {
-        const eT acc = op_dot::direct_dot_arma(A_n_cols, A.mem, x);
-        
-        if( (use_alpha == false) && (use_beta == false) )
-          {
-          y[0] = acc;
-          }
-        else
-        if( (use_alpha == true) && (use_beta == false) )
-          {
-          y[0] = alpha * acc;
-          }
-        else
-        if( (use_alpha == false) && (use_beta == true) )
-          {
-          y[0] = acc + beta*y[0];
-          }
-        else
-        if( (use_alpha == true) && (use_beta == true) )
-          {
-          y[0] = alpha*acc + beta*y[0];
-          }
-        }
-      else
-      for(uword row=0; row < A_n_rows; ++row)
-        {
-        eT acc = eT(0);
-        
-        for(uword i=0; i < A_n_cols; ++i)
-          {
-          acc += A.at(row,i) * x[i];
-          }
-        
-        if( (use_alpha == false) && (use_beta == false) )
-          {
-          y[row] = acc;
-          }
-        else
-        if( (use_alpha == true) && (use_beta == false) )
-          {
-          y[row] = alpha * acc;
-          }
-        else
-        if( (use_alpha == false) && (use_beta == true) )
-          {
-          y[row] = acc + beta*y[row];
-          }
-        else
-        if( (use_alpha == true) && (use_beta == true) )
-          {
-          y[row] = alpha*acc + beta*y[row];
-          }
-        }
-      }
-    else
-    if(do_trans_A == true)
-      {
-      for(uword col=0; col < A_n_cols; ++col)
-        {
-        // col is interpreted as row when storing the results in 'y'
-        
-        
-        // const eT* A_coldata = A.colptr(col);
-        // 
-        // eT acc = eT(0);
-        // for(uword row=0; row < A_n_rows; ++row)
-        //   {
-        //   acc += A_coldata[row] * x[row];
-        //   }
-        
-        const eT acc = op_dot::direct_dot_arma(A_n_rows, A.colptr(col), x);
-        
-        if( (use_alpha == false) && (use_beta == false) )
-          {
-          y[col] = acc;
-          }
-        else
-        if( (use_alpha == true) && (use_beta == false) )
-          {
-          y[col] = alpha * acc;
-          }
-        else
-        if( (use_alpha == false) && (use_beta == true) )
-          {
-          y[col] = acc + beta*y[col];
-          }
-        else
-        if( (use_alpha == true) && (use_beta == true) )
-          {
-          y[col] = alpha*acc + beta*y[col];
-          }
-        
-        }
-      }
-    }
-  
-  };
-
-
-
-template<const bool do_trans_A=false, const bool use_alpha=false, const bool use_beta=false>
-class gemv_emul
-  {
-  public:
-  
-  template<typename eT>
-  arma_hot
-  inline
-  static
-  void
-  apply( eT* y, const Mat<eT>& A, const eT* x, const eT alpha = eT(1), const eT beta = eT(0), const typename arma_not_cx<eT>::result* junk = 0 )
-    {
-    arma_extra_debug_sigprint();
-    arma_ignore(junk);
-    
-    const uword A_n_rows = A.n_rows;
-    const uword A_n_cols = A.n_cols;
-    
-    if( (A_n_rows <= 4) && (A_n_rows == A_n_cols) )
-      {
-      gemv_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply(y, A, x, alpha, beta);
-      }
-    else
-      {
-      gemv_emul_large<do_trans_A, use_alpha, use_beta>::apply(y, A, x, alpha, beta);
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  arma_hot
-  inline
-  static
-  void
-  apply( eT* y, const Mat<eT>& A, const eT* x, const eT alpha = eT(1), const eT beta = eT(0), const typename arma_cx_only<eT>::result* junk = 0 )
-    {
-    arma_extra_debug_sigprint();
-    
-    Mat<eT> tmp_A;
-    
-    if(do_trans_A)
-      {
-      op_htrans::apply_noalias(tmp_A, A);
-      }
-    
-    const Mat<eT>& AA = (do_trans_A == false) ? A : tmp_A;
-    
-    const uword AA_n_rows = AA.n_rows;
-    const uword AA_n_cols = AA.n_cols;
-    
-    if( (AA_n_rows <= 4) && (AA_n_rows == AA_n_cols) )
-      {
-      gemv_emul_tinysq<false, use_alpha, use_beta>::apply(y, AA, x, alpha, beta);
-      }
-    else
-      {
-      gemv_emul_large<false, use_alpha, use_beta>::apply(y, AA, x, alpha, beta);
-      }
-    }
-  };
-
-
-
-//! \brief
-//! Wrapper for ATLAS/BLAS gemv function, using template arguments to control the arguments passed to gemv.
-//! 'y' is assumed to have been set to the correct size (i.e. taking into account the transpose)
-
-template<const bool do_trans_A=false, const bool use_alpha=false, const bool use_beta=false>
-class gemv
-  {
-  public:
-  
-  template<typename eT>
-  inline
-  static
-  void
-  apply_blas_type( eT* y, const Mat<eT>& A, const eT* x, const eT alpha = eT(1), const eT beta = eT(0) )
-    {
-    arma_extra_debug_sigprint();
-    
-    if(A.n_elem <= 64u)
-      {
-      gemv_emul<do_trans_A, use_alpha, use_beta>::apply(y,A,x,alpha,beta);
-      }
-    else
-      {
-      #if defined(ARMA_USE_ATLAS)
-        {
-        arma_extra_debug_print("atlas::cblas_gemv()");
-        
-        atlas::cblas_gemv<eT>
-          (
-          atlas::CblasColMajor,
-          (do_trans_A) ? ( is_complex<eT>::value ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans,
-          A.n_rows,
-          A.n_cols,
-          (use_alpha) ? alpha : eT(1),
-          A.mem,
-          A.n_rows,
-          x,
-          1,
-          (use_beta) ? beta : eT(0),
-          y,
-          1
-          );
-        }
-      #elif defined(ARMA_USE_BLAS)
-        {
-        arma_extra_debug_print("blas::gemv()");
-        
-        const char      trans_A     = (do_trans_A) ? ( is_complex<eT>::value ? 'C' : 'T' ) : 'N';
-        const blas_int  m           = A.n_rows;
-        const blas_int  n           = A.n_cols;
-        const eT        local_alpha = (use_alpha) ? alpha : eT(1);
-        //const blas_int  lda         = A.n_rows;
-        const blas_int  inc         = 1;
-        const eT        local_beta  = (use_beta) ? beta : eT(0);
-        
-        arma_extra_debug_print( arma_boost::format("blas::gemv(): trans_A = %c") % trans_A );
-        
-        blas::gemv<eT>
-          (
-          &trans_A,
-          &m,
-          &n,
-          &local_alpha,
-          A.mem,
-          &m,  // lda
-          x,
-          &inc,
-          &local_beta,
-          y,
-          &inc
-          );
-        }
-      #else
-        {
-        gemv_emul<do_trans_A, use_alpha, use_beta>::apply(y,A,x,alpha,beta);
-        }
-      #endif
-      }
-    
-    }
-  
-  
-  
-  template<typename eT>
-  arma_inline
-  static
-  void
-  apply( eT* y, const Mat<eT>& A, const eT* x, const eT alpha = eT(1), const eT beta = eT(0) )
-    {
-    gemv_emul<do_trans_A, use_alpha, use_beta>::apply(y,A,x,alpha,beta);
-    }
-  
-  
-  
-  arma_inline
-  static
-  void
-  apply
-    (
-          float*      y,
-    const Mat<float>& A,
-    const float*      x,
-    const float       alpha = float(1),
-    const float       beta  = float(0)
-    )
-    {
-    gemv<do_trans_A, use_alpha, use_beta>::apply_blas_type(y,A,x,alpha,beta);
-    }
-
-
-  
-  arma_inline
-  static
-  void
-  apply
-    (
-          double*      y,
-    const Mat<double>& A,
-    const double*      x,
-    const double       alpha = double(1),
-    const double       beta  = double(0)
-    )
-    {
-    gemv<do_trans_A, use_alpha, use_beta>::apply_blas_type(y,A,x,alpha,beta);
-    }
-
-
-  
-  arma_inline
-  static
-  void
-  apply
-    (
-          std::complex<float>*         y,
-    const Mat< std::complex<float > >& A,
-    const std::complex<float>*         x,
-    const std::complex<float>          alpha = std::complex<float>(1),
-    const std::complex<float>          beta  = std::complex<float>(0)
-    )
-    {
-    gemv<do_trans_A, use_alpha, use_beta>::apply_blas_type(y,A,x,alpha,beta);
-    }
-
-
-  
-  arma_inline
-  static
-  void
-  apply
-    (
-          std::complex<double>*        y,
-    const Mat< std::complex<double> >& A,
-    const std::complex<double>*        x,
-    const std::complex<double>         alpha = std::complex<double>(1),
-    const std::complex<double>         beta  = std::complex<double>(0)
-    )
-    {
-    gemv<do_trans_A, use_alpha, use_beta>::apply_blas_type(y,A,x,alpha,beta);
-    }
-
-
-  
-  };
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_conv_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup glue_conv
-//! @{
-
-
-
-class glue_conv
-  {
-  public:
-
-  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_conv>& X);
-  };
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/glue_conv_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup glue_conv
-//! @{
-
-
-//! rudimentary implementation of the convolution operation
-
-template<typename T1, typename T2>
-inline
-void
-glue_conv::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_conv>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> A_tmp(X.A, out);
-  const unwrap_check<T2> B_tmp(X.B, out);
-  
-  const Mat<eT>& A = A_tmp.M;
-  const Mat<eT>& B = B_tmp.M;
-  
-  arma_debug_check( ( (A.is_vec() == false) || (B.is_vec() == false) ), "conv(): inputs must be vectors" );
-  
-  
-  const Mat<eT>& h = (A.n_elem <= B.n_elem) ? A : B;
-  const Mat<eT>& x = (A.n_elem <= B.n_elem) ? B : A;
-  
-  
-  const uword   h_n_elem = h.n_elem;
-  const uword   x_n_elem = x.n_elem;
-  const uword out_n_elem = h_n_elem + x_n_elem - 1;
-  
-  
-  if( (h_n_elem == 0) || (x_n_elem == 0) )
-    {
-    out.reset();
-    return;
-    }
-  
-  
-  (A.n_cols == 1) ? out.set_size(out_n_elem, 1) : out.set_size(1, out_n_elem);
-  
-  
-  const eT*   h_mem = h.memptr();
-  const eT*   x_mem = x.memptr();
-        eT* out_mem = out.memptr();
-  
-  
-  for(uword out_i = 0; out_i < (h_n_elem-1); ++out_i)
-    {
-    eT acc = eT(0);
-    
-    uword h_i = out_i;
-    
-    for(uword x_i = 0; x_i <= out_i; ++x_i, --h_i)
-      {
-      acc += h_mem[h_i] * x_mem[x_i];
-      }
-    
-    out_mem[out_i] = acc;
-    }
-  
-  
-  for(uword out_i = h_n_elem-1; out_i < out_n_elem - (h_n_elem-1); ++out_i)
-    {
-    eT acc = eT(0);
-   
-    uword h_i = h_n_elem - 1;
-    
-    for(uword x_i = out_i - h_n_elem + 1; x_i <= out_i; ++x_i, --h_i)
-      {
-      acc += h_mem[h_i] * x_mem[x_i];
-      }
-      
-    out_mem[out_i] = acc;
-    }
-  
-  
-  for(uword out_i = out_n_elem - (h_n_elem-1); out_i < out_n_elem; ++out_i)
-    {
-    eT acc = eT(0);
-    
-    uword h_i = h_n_elem - 1;
-    
-    for(uword x_i = out_i - h_n_elem + 1; x_i < x_n_elem; ++x_i, --h_i)
-      {
-      acc += h_mem[h_i] * x_mem[x_i];
-      }
-    
-    out_mem[out_i] = acc;
-    }
-  
-  
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_cor_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup glue_cor
-//! @{
-
-
-
-class glue_cor
-  {
-  public:
-
-  template<typename eT> inline static void direct_cor(Mat<eT>&                out, const Mat<eT>&                A, const Mat<eT>&                B, const uword norm_type);
-  template<typename T>  inline static void direct_cor(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat< std::complex<T> >& B, const uword norm_type);
-  
-  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cor>& X);
-  };
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/glue_cor_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup glue_cor
-//! @{
-
-
-
-template<typename eT>
-inline
-void
-glue_cor::direct_cor(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(A.is_empty() || B.is_empty() )
-    {
-    out.reset();
-    return;
-    }
-  
-  if(A.is_vec() && B.is_vec())
-    {
-    arma_debug_check( (A.n_elem != B.n_elem), "cor(): the number of elements in the two vectors must match" );
-    
-    const eT* A_ptr = A.memptr();
-    const eT* B_ptr = B.memptr();
-    
-    eT A_acc   = eT(0);
-    eT B_acc   = eT(0);
-    eT out_acc = eT(0);
-    
-    const uword N = A.n_elem;
-    
-    for(uword i=0; i<N; ++i)
-      {
-      const eT A_tmp = A_ptr[i];
-      const eT B_tmp = B_ptr[i];
-      
-      A_acc += A_tmp;
-      B_acc += B_tmp;
-      
-      out_acc += A_tmp * B_tmp;
-      }
-    
-    out_acc -= (A_acc * B_acc)/eT(N);
-    
-    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);    
-    
-    out.set_size(1,1);
-    out[0] = out_acc/norm_val;
-    
-    const Mat<eT> stddev_A = (A.n_rows == 1) ? Mat<eT>(stddev(trans(A))) : Mat<eT>(stddev(A));
-    const Mat<eT> stddev_B = (B.n_rows == 1) ? Mat<eT>(stddev(trans(B))) : Mat<eT>(stddev(B));
-    
-    out /= stddev_A * stddev_B;
-    }
-  else
-    {
-    arma_debug_assert_same_size(A, B, "cor()");
-    
-    const uword N = A.n_rows;
-    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
-    
-    out = trans(A) * B;
-    out -= (trans(sum(A)) * sum(B))/eT(N);
-    out /= norm_val;
-    out /= trans(stddev(A)) * stddev(B);
-    }
-  }
-
-
-
-template<typename T>
-inline
-void
-glue_cor::direct_cor(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat< std::complex<T> >& B, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T> eT;
-  
-  if(A.is_empty() || B.is_empty() )
-    {
-    out.reset();
-    return;
-    }
-  
-  if(A.is_vec() && B.is_vec())
-    {
-    arma_debug_check( (A.n_elem != B.n_elem), "cor(): the number of elements in the two vectors must match" );
-    
-    const eT* A_ptr = A.memptr();
-    const eT* B_ptr = B.memptr();        
-    
-    eT A_acc   = eT(0);
-    eT B_acc   = eT(0);
-    eT out_acc = eT(0);
-    
-    const uword N = A.n_elem;
-    
-    for(uword i=0; i<N; ++i)
-      {
-      const eT A_tmp = A_ptr[i];
-      const eT B_tmp = B_ptr[i];
-      
-      A_acc += A_tmp;
-      B_acc += B_tmp;
-      
-      out_acc += std::conj(A_tmp) * B_tmp;
-      }
-    
-    out_acc -= (std::conj(A_acc) * B_acc)/eT(N);
-    
-    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
-    
-    out.set_size(1,1);
-    out[0] = out_acc/norm_val;
-    
-    const Mat<T> stddev_A = (A.n_rows == 1) ? Mat<T>(stddev(trans(A))) : Mat<T>(stddev(A));
-    const Mat<T> stddev_B = (B.n_rows == 1) ? Mat<T>(stddev(trans(B))) : Mat<T>(stddev(B));
-    
-    out /= conv_to< Mat<eT> >::from( stddev_A * stddev_B );
-    }
-  else
-    {
-    arma_debug_assert_same_size(A, B, "cor()");
-    
-    const uword N = A.n_rows;
-    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
-    
-    out = trans(A) * B;                     // out = strans(conj(A)) * B;
-    out -= (trans(sum(A)) * sum(B))/eT(N);  // out -= (strans(conj(sum(A))) * sum(B))/eT(N);
-    out /= norm_val;
-    out /= conv_to< Mat<eT> >::from( trans(stddev(A)) * stddev(B) );
-    }
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_cor::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cor>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> A_tmp(X.A, out);
-  const unwrap_check<T2> B_tmp(X.B, out);
-  
-  const Mat<eT>& A = A_tmp.M;
-  const Mat<eT>& B = B_tmp.M;
-  
-  const uword norm_type = X.aux_uword;
-  
-  if(&A != &B)
-    {
-    glue_cor::direct_cor(out, A, B, norm_type);
-    }
-  else
-    {
-    op_cor::direct_cor(out, A, norm_type);
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_cov_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup glue_cov
-//! @{
-
-
-
-class glue_cov
-  {
-  public:
-
-  template<typename eT> inline static void direct_cov(Mat<eT>&                out, const Mat<eT>&                A, const Mat<eT>&                B, const uword norm_type);
-  template<typename T>  inline static void direct_cov(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat< std::complex<T> >& B, const uword norm_type);
-  
-  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cov>& X);
-  };
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/glue_cov_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup glue_cov
-//! @{
-
-
-
-template<typename eT>
-inline
-void
-glue_cov::direct_cov(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-
-  if(A.is_vec() && B.is_vec())
-    {
-    arma_debug_check( (A.n_elem != B.n_elem), "cov(): the number of elements in A and B must match" );
-
-    const eT* A_ptr = A.memptr();
-    const eT* B_ptr = B.memptr();
-
-    eT A_acc   = eT(0);
-    eT B_acc   = eT(0);
-    eT out_acc = eT(0);
-
-    const uword N = A.n_elem;
-
-    for(uword i=0; i<N; ++i)
-      {
-      const eT A_tmp = A_ptr[i];
-      const eT B_tmp = B_ptr[i];
-
-      A_acc += A_tmp;
-      B_acc += B_tmp;
-
-      out_acc += A_tmp * B_tmp;
-      }
-
-    out_acc -= (A_acc * B_acc)/eT(N);
-
-    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
-
-    out.set_size(1,1);
-    out[0] = out_acc/norm_val;
-    }
-  else
-    {
-    arma_debug_assert_same_size(A, B, "cov()");
-
-    const uword N = A.n_rows;
-    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
-
-    out = trans(A) * B;
-    out -= (trans(sum(A)) * sum(B))/eT(N);
-    out /= norm_val;
-    }
-  }
-
-
-
-template<typename T>
-inline
-void
-glue_cov::direct_cov(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat< std::complex<T> >& B, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-
-  typedef typename std::complex<T> eT;
-
-  if(A.is_vec() && B.is_vec())
-    { 
-    arma_debug_check( (A.n_elem != B.n_elem), "cov(): the number of elements in A and B must match" );
-
-    const eT* A_ptr = A.memptr();
-    const eT* B_ptr = B.memptr();        
-
-    eT A_acc   = eT(0);
-    eT B_acc   = eT(0);
-    eT out_acc = eT(0);
-
-    const uword N = A.n_elem;
-
-    for(uword i=0; i<N; ++i)
-      {
-      const eT A_tmp = A_ptr[i];
-      const eT B_tmp = B_ptr[i];
-
-      A_acc += A_tmp;
-      B_acc += B_tmp;
-
-      out_acc += std::conj(A_tmp) * B_tmp;
-      }
-
-    out_acc -= (std::conj(A_acc) * B_acc)/eT(N);
-
-    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
-
-    out.set_size(1,1);
-    out[0] = out_acc/norm_val;
-    }
-  else
-    {
-    arma_debug_assert_same_size(A, B, "cov()");
-  
-    const uword N = A.n_rows;
-    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
-    
-    out = trans(A) * B;                     // out = strans(conj(A)) * B;
-    out -= (trans(sum(A)) * sum(B))/eT(N);  // out -= (strans(conj(sum(A))) * sum(B))/eT(N);
-    out /= norm_val;
-    }
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_cov::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cov>& X)
-  {
-  arma_extra_debug_sigprint();
-
-  typedef typename T1::elem_type eT;
-
-  const unwrap_check<T1> A_tmp(X.A, out);
-  const unwrap_check<T2> B_tmp(X.B, out);
-
-  const Mat<eT>& A = A_tmp.M;
-  const Mat<eT>& B = B_tmp.M;
-  
-  const uword norm_type = X.aux_uword;
-
-  if(&A != &B)
-    {
-    glue_cov::direct_cov(out, A, B, norm_type);
-    }
-  else
-    {
-    op_cov::direct_cov(out, A, norm_type);
-    }
-  
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_cross_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup glue_cross
-//! @{
-
-
-
-class glue_cross
-  {
-  public:
-
-  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cross>& X);
-  };
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/glue_cross_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup glue_cross
-//! @{
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_cross::apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_cross>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type      eT;
-  typedef typename Proxy<T1>::ea_type ea_type1;
-  typedef typename Proxy<T2>::ea_type ea_type2;
-  
-  const Proxy<T1> A(X.A);
-  const Proxy<T2> B(X.B);
-  
-  arma_debug_check( ((A.get_n_elem() != 3) || (B.get_n_elem() != 3)), "cross(): input vectors must have 3 elements" );
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-  eT*      out_mem = out.memptr();
-  ea_type1 PA      = A.get_ea();
-  ea_type2 PB      = B.get_ea();
-  
-  const eT ax = PA[0];
-  const eT ay = PA[1];
-  const eT az = PA[2];
-  
-  const eT bx = PB[0];
-  const eT by = PB[1];
-  const eT bz = PB[2];
-  
-  out_mem[0] = ay*bz - az*by;
-  out_mem[1] = az*bx - ax*bz;
-  out_mem[2] = ax*by - ay*bx;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_join_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup glue_join
-//! @{
-
-
-
-class glue_join
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_join>& X);
-  
-  template<typename T1, typename T2>
-  inline static void apply(Cube<typename T1::elem_type>& out, const GlueCube<T1,T2,glue_join>& X);
-  };
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/glue_join_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup glue_join
-//! @{
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_join::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_join>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-
-  const unwrap<T1> A_tmp(X.A);
-  const unwrap<T2> B_tmp(X.B);
-  
-  const Mat<eT>& A = A_tmp.M;
-  const Mat<eT>& B = B_tmp.M;
-  
-  const uword A_n_rows = A.n_rows;
-  const uword A_n_cols = A.n_cols;
-  
-  const uword B_n_rows = B.n_rows;
-  const uword B_n_cols = B.n_cols;
-  
-  const uword join_type = X.aux_uword;
-  
-  if(join_type == 0)
-    {
-    arma_debug_check
-      (
-      ( (A_n_cols != B_n_cols) && ( (A_n_rows > 0) || (A_n_cols > 0) ) && ( (B_n_rows > 0) || (B_n_cols > 0) ) ),
-      "join_cols(): number of columns must be the same"
-      );
-    }
-  else
-    {
-    arma_debug_check
-      (
-      ( (A_n_rows != B.n_rows) && ( (A_n_rows > 0) || (A_n_cols > 0) ) && ( (B_n_rows > 0) || (B_n_cols > 0) ) ),
-      "join_rows(): number of rows must be the same"
-      );
-    }
-  
-  
-  if( (&out != &A) && (&out != &B) )
-    {
-    if(join_type == 0)   // join columns (i.e. result matrix has more rows)
-      {
-      out.set_size( A_n_rows + B_n_rows, (std::max)(A_n_cols, B_n_cols) );
-      
-      if( out.n_elem > 0 )
-        {
-        if(A.is_empty() == false)
-          { 
-          out.submat(0,        0,   A_n_rows-1, out.n_cols-1) = A;
-          }
-          
-        if(B.is_empty() == false)
-          {
-          out.submat(A_n_rows, 0, out.n_rows-1, out.n_cols-1) = B;
-          }
-        }
-      }
-    else   // join rows  (i.e. result matrix has more columns)
-      {
-      out.set_size( (std::max)(A_n_rows, B_n_rows), A_n_cols + B_n_cols );
-      
-      if( out.n_elem > 0 )
-        {
-        if(A.is_empty() == false)
-          {
-          out.submat(0, 0,        out.n_rows-1,   A.n_cols-1) = A;
-          }
-        
-        if(B.is_empty() == false)
-          {
-          out.submat(0, A_n_cols, out.n_rows-1, out.n_cols-1) = B;
-          }
-        }
-      }
-    }
-  else  // we have aliasing
-    {
-    Mat<eT> C;
-    
-    if(join_type == 0)
-      {
-      C.set_size( A_n_rows + B_n_rows, (std::max)(A_n_cols, B_n_cols) );
-      
-      if( C.n_elem > 0 )
-        {
-        if(A.is_empty() == false)
-          {
-          C.submat(0,        0, A_n_rows-1, C.n_cols-1) = A;
-          }
-        
-        if(B.is_empty() == false)
-          {
-          C.submat(A_n_rows, 0, C.n_rows-1, C.n_cols-1) = B;
-          }
-        }
-      }
-    else
-      {
-      C.set_size( (std::max)(A_n_rows, B_n_rows), A_n_cols + B_n_cols );
-      
-      if( C.n_elem > 0 )
-        {
-        if(A.is_empty() == false)
-          {
-          C.submat(0, 0,        C.n_rows-1, A_n_cols-1) = A;
-          }
-        
-        if(B.is_empty() == false)
-          {
-          C.submat(0, A_n_cols, C.n_rows-1, C.n_cols-1) = B;
-          }
-        }
-      }
-    
-    out.steal_mem(C);
-    }
-  
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_join::apply(Cube<typename T1::elem_type>& out, const GlueCube<T1,T2,glue_join>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-
-  const unwrap_cube<T1> A_tmp(X.A);
-  const unwrap_cube<T2> B_tmp(X.B);
-  
-  const Cube<eT>& A = A_tmp.M;
-  const Cube<eT>& B = B_tmp.M;
-  
-  if(A.n_elem == 0)
-    {
-    out = B;
-    return;
-    }
-  
-  if(B.n_elem == 0)
-    {
-    out = A;
-    return;
-    }
-  
-  
-  arma_debug_check( ( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) ), "join_slices(): size of slices must be the same" );
-  
-  
-  if( (&out != &A) && (&out != &B) )
-    {
-    out.set_size(A.n_rows, A.n_cols, A.n_slices + B.n_slices);
-    
-    out.slices(0,          A.n_slices-1  ) = A;
-    out.slices(A.n_slices, out.n_slices-1) = B;
-    }
-  else  // we have aliasing
-    {
-    Cube<eT> C(A.n_rows, A.n_cols, A.n_slices + B.n_slices);
-    
-    C.slices(0,          A.n_slices-1) = A;
-    C.slices(A.n_slices, C.n_slices-1) = B;
-    
-    out.steal_mem(C);
-    }
-  
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_kron_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup glue_kron
-//! @{
-
-
-
-class glue_kron
-  {
-  public:
-
-  template<typename eT> inline static void direct_kron(Mat<eT>&                out, const Mat<eT>&                A, const Mat<eT>&                B);
-  template<typename T>  inline static void direct_kron(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat<T>&                 B);
-  template<typename T>  inline static void direct_kron(Mat< std::complex<T> >& out, const Mat<T>&                 A, const Mat< std::complex<T> >& B);
-  
-  template<typename T1, typename T2>   inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_kron>& X);
-  };
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/glue_kron_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup glue_kron
-//! @{
-
-
-
-//! \brief
-//! both input matrices have the same element type
-template<typename eT>
-inline
-void
-glue_kron::direct_kron(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_rows = A.n_rows;
-  const uword A_cols = A.n_cols;
-  const uword B_rows = B.n_rows;
-  const uword B_cols = B.n_cols;
-  
-  out.set_size(A_rows*B_rows, A_cols*B_cols);
-  
-  for(uword i = 0; i < A_rows; i++)
-    {
-    for(uword j = 0; j < A_cols; j++)
-      {
-      out.submat(i*B_rows, j*B_cols, (i+1)*B_rows-1, (j+1)*B_cols-1) = A(i,j) * B; 
-      }
-    }  
-  }
-
-
-
-//! \brief
-//! different types of input matrices
-//! A -> complex, B -> basic element type
-template<typename T>
-inline
-void
-glue_kron::direct_kron(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat<T>& B)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T> eT;
-  
-  const uword A_rows = A.n_rows;
-  const uword A_cols = A.n_cols;
-  const uword B_rows = B.n_rows;
-  const uword B_cols = B.n_cols;
-  
-  out.set_size(A_rows*B_rows, A_cols*B_cols);
-  
-  Mat<eT> tmp_B = conv_to< Mat<eT> >::from(B);
-  
-  for(uword i = 0; i < A_rows; i++)
-    {
-    for(uword j = 0; j < A_cols; j++)
-      {
-      out.submat(i*B_rows, j*B_cols, (i+1)*B_rows-1, (j+1)*B_cols-1) = A(i,j) * tmp_B; 
-      }
-    }  
-  }
-
-
-
-//! \brief
-//! different types of input matrices
-//! A -> basic element type, B -> complex
-template<typename T>
-inline
-void
-glue_kron::direct_kron(Mat< std::complex<T> >& out, const Mat<T>& A, const Mat< std::complex<T> >& B)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_rows = A.n_rows;
-  const uword A_cols = A.n_cols;
-  const uword B_rows = B.n_rows;
-  const uword B_cols = B.n_cols;
-  
-  out.set_size(A_rows*B_rows, A_cols*B_cols);
-  
-  for(uword i = 0; i < A_rows; i++)
-    {
-    for(uword j = 0; j < A_cols; j++)
-      {
-      out.submat(i*B_rows, j*B_cols, (i+1)*B_rows-1, (j+1)*B_cols-1) = A(i,j) * B; 
-      }
-    }  
-  }
-
-
-
-//! \brief
-//! apply Kronecker product for two objects with same element type
-template<typename T1, typename T2>
-inline
-void
-glue_kron::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_kron>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> A_tmp(X.A, out);
-  const unwrap_check<T2> B_tmp(X.B, out);
-  
-  const Mat<eT>& A = A_tmp.M;
-  const Mat<eT>& B = B_tmp.M;
-  
-  glue_kron::direct_kron(out, A, B); 
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_mixed_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup glue_mixed
-//! @{
-
-
-
-class glue_mixed_times
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  inline static void apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_times>& X);
-  };
-
-
-
-class glue_mixed_plus
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  inline static void apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_plus>& X);
-  
-  template<typename T1, typename T2>
-  inline static void apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_plus>& X);
-  };
-
-
-
-class glue_mixed_minus
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  inline static void apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_minus>& X);
-  
-  template<typename T1, typename T2>
-  inline static void apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_minus>& X);
-  };
-
-
-
-class glue_mixed_div
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  inline static void apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_div>& X);
-  
-  template<typename T1, typename T2>
-  inline static void apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_div>& X);
-  };
-
-
-
-class glue_mixed_schur
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  inline static void apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_schur>& X);
-  
-  template<typename T1, typename T2>
-  inline static void apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_schur>& X);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_mixed_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,336 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup glue_mixed
-//! @{
-
-
-
-//! matrix multiplication with different element types
-template<typename T1, typename T2>
-inline
-void
-glue_mixed_times::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_times>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  // TODO: extend the unwrap_check framework to handle mixed matrix types
-  
-  const unwrap<T1> tmp1(X.A);
-  const unwrap<T2> tmp2(X.B);
-  
-  const Mat<eT1>& A = tmp1.M;
-  const Mat<eT2>& B = tmp2.M;
-  
-  const bool A_is_alias = ( ((void *)&out) == ((void *)&A) );
-  const bool B_is_alias = ( ((void *)&out) == ((void *)&B) );
-  
-  const Mat<eT1>* AA_ptr = A_is_alias ? new Mat<eT1>(A) : 0;
-  const Mat<eT2>* BB_ptr = B_is_alias ? new Mat<eT2>(B) : 0;
-  
-  const Mat<eT1>& AA = A_is_alias ? *AA_ptr : A;
-  const Mat<eT2>& BB = B_is_alias ? *BB_ptr : B;
-  
-  arma_debug_assert_mul_size(AA, BB, "multiplication");
-  
-  out.set_size(AA.n_rows, BB.n_cols);
-  
-  gemm_mixed<>::apply(out, AA, BB);
-  
-  if(A_is_alias == true)
-    {
-    delete AA_ptr;
-    }
-  
-  if(B_is_alias == true)
-    {
-    delete BB_ptr;
-    }
-  }
-
-
-
-//! matrix addition with different element types
-template<typename T1, typename T2>
-inline
-void
-glue_mixed_plus::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_plus>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  const Proxy<T1> A(X.A);
-  const Proxy<T2> B(X.B);
-  
-  arma_debug_assert_same_size(A, B, "addition");
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-        out_eT* out_mem = out.memptr();
-  const uword     n_elem  = out.n_elem;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) + upgrade_val<eT1,eT2>::apply(B[i]);
-    }
-  }
-
-
-
-//! matrix subtraction with different element types
-template<typename T1, typename T2>
-inline
-void
-glue_mixed_minus::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_minus>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  const Proxy<T1> A(X.A);
-  const Proxy<T2> B(X.B);
-  
-  arma_debug_assert_same_size(A, B, "subtraction");
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-        out_eT* out_mem = out.memptr();
-  const uword     n_elem  = out.n_elem;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) - upgrade_val<eT1,eT2>::apply(B[i]);
-    }
-  }
-
-
-
-//! element-wise matrix division with different element types
-template<typename T1, typename T2>
-inline
-void
-glue_mixed_div::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_div>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  const Proxy<T1> A(X.A);
-  const Proxy<T2> B(X.B);
-  
-  arma_debug_assert_same_size(A, B, "element-wise division");
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-        out_eT* out_mem = out.memptr();
-  const uword     n_elem  = out.n_elem;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) / upgrade_val<eT1,eT2>::apply(B[i]);
-    }
-  }
-
-
-
-//! element-wise matrix multiplication with different element types
-template<typename T1, typename T2>
-inline
-void
-glue_mixed_schur::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_schur>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  const Proxy<T1> A(X.A);
-  const Proxy<T2> B(X.B);
-  
-  arma_debug_assert_same_size(A, B, "element-wise multiplication");
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-        out_eT* out_mem = out.memptr();
-  const uword     n_elem  = out.n_elem;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) * upgrade_val<eT1,eT2>::apply(B[i]);
-    }
-  }
-
-
-
-//
-//
-//
-
-
-
-//! cube addition with different element types
-template<typename T1, typename T2>
-inline
-void
-glue_mixed_plus::apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_plus>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  const ProxyCube<T1> A(X.A);
-  const ProxyCube<T2> B(X.B);
-  
-  arma_debug_assert_same_size(A, B, "addition");
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  
-        out_eT* out_mem = out.memptr();
-  const uword     n_elem  = out.n_elem;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) + upgrade_val<eT1,eT2>::apply(B[i]);
-    }
-  }
-
-
-
-//! cube subtraction with different element types
-template<typename T1, typename T2>
-inline
-void
-glue_mixed_minus::apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_minus>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  const ProxyCube<T1> A(X.A);
-  const ProxyCube<T2> B(X.B);
-  
-  arma_debug_assert_same_size(A, B, "subtraction");
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  
-        out_eT* out_mem = out.memptr();
-  const uword     n_elem  = out.n_elem;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) - upgrade_val<eT1,eT2>::apply(B[i]);
-    }
-  }
-
-
-
-//! element-wise cube division with different element types
-template<typename T1, typename T2>
-inline
-void
-glue_mixed_div::apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_div>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  const ProxyCube<T1> A(X.A);
-  const ProxyCube<T2> B(X.B);
-  
-  arma_debug_assert_same_size(A, B, "element-wise division");
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  
-        out_eT* out_mem = out.memptr();
-  const uword     n_elem  = out.n_elem;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) / upgrade_val<eT1,eT2>::apply(B[i]);
-    }
-  }
-
-
-
-//! element-wise cube multiplication with different element types
-template<typename T1, typename T2>
-inline
-void
-glue_mixed_schur::apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_schur>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  const ProxyCube<T1> A(X.A);
-  const ProxyCube<T2> B(X.B);
-  
-  arma_debug_assert_same_size(A, B, "element-wise multiplication");
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  
-        out_eT* out_mem = out.memptr();
-  const uword     n_elem  = out.n_elem;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = upgrade_val<eT1,eT2>::apply(A[i]) * upgrade_val<eT1,eT2>::apply(B[i]);
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_relational_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup glue_relational
-//! @{
-
-
-
-class glue_rel_lt
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  inline static void apply(Mat <uword>& out, const mtGlue<uword, T1, T2, glue_rel_lt>& X);
-  
-  template<typename T1, typename T2>
-  inline static void apply(Cube <uword>& out, const mtGlueCube<uword, T1, T2, glue_rel_lt>& X);
-  };
-
-
-
-class glue_rel_gt
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  inline static void apply(Mat <uword>& out, const mtGlue<uword, T1, T2, glue_rel_gt>& X);
-  
-  template<typename T1, typename T2>
-  inline static void apply(Cube <uword>& out, const mtGlueCube<uword, T1, T2, glue_rel_gt>& X);
-  };
-
-
-
-class glue_rel_lteq
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  inline static void apply(Mat <uword>& out, const mtGlue<uword, T1, T2, glue_rel_lteq>& X);
-  
-  template<typename T1, typename T2>
-  inline static void apply(Cube <uword>& out, const mtGlueCube<uword, T1, T2, glue_rel_lteq>& X);
-  };
-
-
-
-class glue_rel_gteq
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  inline static void apply(Mat <uword>& out, const mtGlue<uword, T1, T2, glue_rel_gteq>& X);
-  
-  template<typename T1, typename T2>
-  inline static void apply(Cube <uword>& out, const mtGlueCube<uword, T1, T2, glue_rel_gteq>& X);
-  };
-
-
-
-class glue_rel_eq
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  inline static void apply(Mat <uword>& out, const mtGlue<uword, T1, T2, glue_rel_eq>& X);
-  
-  template<typename T1, typename T2>
-  inline static void apply(Cube <uword>& out, const mtGlueCube<uword, T1, T2, glue_rel_eq>& X);
-  };
-
-
-
-class glue_rel_noteq
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  inline static void apply(Mat <uword>& out, const mtGlue<uword, T1, T2, glue_rel_noteq>& X);
-  
-  template<typename T1, typename T2>
-  inline static void apply(Cube <uword>& out, const mtGlueCube<uword, T1, T2, glue_rel_noteq>& X);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_relational_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,342 +0,0 @@
-// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2012 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup glue_relational
-//! @{
-
-
-
-#undef operator_rel
-#undef operator_str
-
-#undef arma_applier_mat
-#undef arma_applier_cube
-
-
-#define arma_applier_mat(operator_rel, operator_str) \
-  {\
-  const Proxy<T1> P1(X.A);\
-  const Proxy<T2> P2(X.B);\
-  \
-  arma_debug_assert_same_size(P1, P2, operator_str);\
-  \
-  const bool bad_alias = (Proxy<T1>::has_subview && P1.is_alias(out)) || (Proxy<T2>::has_subview && P2.is_alias(out));\
-  \
-  if(bad_alias == false)\
-    {\
-    \
-    const uword n_rows = P1.get_n_rows();\
-    const uword n_cols = P1.get_n_cols();\
-    \
-    out.set_size(n_rows, n_cols);\
-    \
-    uword* out_mem = out.memptr();\
-    \
-    const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);\
-    \
-    if(prefer_at_accessor == false)\
-      {\
-      typename Proxy<T1>::ea_type A = P1.get_ea();\
-      typename Proxy<T2>::ea_type B = P2.get_ea();\
-      \
-      const uword n_elem = out.n_elem;\
-      \
-      for(uword i=0; i<n_elem; ++i)\
-        {\
-        out_mem[i] = (A[i] operator_rel B[i]) ? uword(1) : uword(0);\
-        }\
-      }\
-    else\
-      {\
-      uword count = 0;\
-      \
-      for(uword col=0; col<n_cols; ++col)\
-      for(uword row=0; row<n_rows; ++row, ++count)\
-        {\
-        out_mem[count] = (P1.at(row,col) operator_rel P2.at(row,col)) ? uword(1) : uword(0);\
-        }\
-      }\
-    }\
-  else\
-    {\
-    const unwrap<typename Proxy<T1>::stored_type> tmp1(P1.Q);\
-    const unwrap<typename Proxy<T2>::stored_type> tmp2(P2.Q);\
-    \
-    out = (tmp1.M) operator_rel (tmp2.M);\
-    }\
-  }
-
-
-
-
-#define arma_applier_cube(operator_rel, operator_str) \
-  {\
-  const ProxyCube<T1> P1(X.A);\
-  const ProxyCube<T2> P2(X.B);\
-  \
-  arma_debug_assert_same_size(P1, P2, operator_str);\
-  \
-  const bool bad_alias = (ProxyCube<T1>::has_subview && P1.is_alias(out)) || (ProxyCube<T2>::has_subview && P2.is_alias(out));\
-  \
-  if(bad_alias == false)\
-    {\
-    \
-    const uword n_rows   = P1.get_n_rows();\
-    const uword n_cols   = P1.get_n_cols();\
-    const uword n_slices = P1.get_n_slices();\
-    \
-    out.set_size(n_rows, n_cols, n_slices);\
-    \
-    uword* out_mem = out.memptr();\
-    \
-    const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);\
-    \
-    if(prefer_at_accessor == false)\
-      {\
-      typename ProxyCube<T1>::ea_type A = P1.get_ea();\
-      typename ProxyCube<T2>::ea_type B = P2.get_ea();\
-      \
-      const uword n_elem = out.n_elem;\
-      \
-      for(uword i=0; i<n_elem; ++i)\
-        {\
-        out_mem[i] = (A[i] operator_rel B[i]) ? uword(1) : uword(0);\
-        }\
-      }\
-    else\
-      {\
-      uword count = 0;\
-      \
-      for(uword slice = 0; slice < n_slices; ++slice)\
-      for(uword col   = 0; col   < n_cols;   ++col)\
-      for(uword row   = 0; row   < n_rows;   ++row, ++count)\
-        {\
-        out_mem[count] = (P1.at(row,col,slice) operator_rel P2.at(row,col,slice)) ? uword(1) : uword(0);\
-        }\
-      }\
-    }\
-  else\
-    {\
-    const unwrap_cube<typename ProxyCube<T1>::stored_type> tmp1(P1.Q);\
-    const unwrap_cube<typename ProxyCube<T2>::stored_type> tmp2(P2.Q);\
-    \
-    out = (tmp1.M) operator_rel (tmp2.M);\
-    }\
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_rel_lt::apply
-  (
-        Mat   <uword>& out,
-  const mtGlue<uword, T1, T2, glue_rel_lt>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat(<, "operator<");
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_rel_gt::apply
-  (
-        Mat   <uword>& out,
-  const mtGlue<uword, T1, T2, glue_rel_gt>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat(>, "operator>");
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_rel_lteq::apply
-  (
-        Mat   <uword>& out,
-  const mtGlue<uword, T1, T2, glue_rel_lteq>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat(<=, "operator<=");
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_rel_gteq::apply
-  (
-        Mat   <uword>& out,
-  const mtGlue<uword, T1, T2, glue_rel_gteq>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat(>=, "operator>=");
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_rel_eq::apply
-  (
-        Mat   <uword>& out,
-  const mtGlue<uword, T1, T2, glue_rel_eq>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat(==, "operator==");
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_rel_noteq::apply
-  (
-        Mat   <uword>& out,
-  const mtGlue<uword, T1, T2, glue_rel_noteq>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat(!=, "operator!=");
-  }
-
-
-
-//
-//
-//
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_rel_lt::apply
-  (
-        Cube      <uword>& out,
-  const mtGlueCube<uword, T1, T2, glue_rel_lt>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube(<, "operator<");
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_rel_gt::apply
-  (
-        Cube      <uword>& out,
-  const mtGlueCube<uword, T1, T2, glue_rel_gt>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube(>, "operator>");
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_rel_lteq::apply
-  (
-        Cube      <uword>& out,
-  const mtGlueCube<uword, T1, T2, glue_rel_lteq>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube(<=, "operator<=");
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_rel_gteq::apply
-  (
-        Cube      <uword>& out,
-  const mtGlueCube<uword, T1, T2, glue_rel_gteq>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube(>=, "operator>=");
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_rel_eq::apply
-  (
-        Cube      <uword>& out,
-  const mtGlueCube<uword, T1, T2, glue_rel_eq>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube(==, "operator==");
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_rel_noteq::apply
-  (
-        Cube      <uword>& out,
-  const mtGlueCube<uword, T1, T2, glue_rel_noteq>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube(!=, "operator!=");
-  }
-
-
-
-#undef arma_applier_mat
-#undef arma_applier_cube
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_solve_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup glue_solve
-//! @{
-
-
-
-class glue_solve
-  {
-  public:
-  
-  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_solve>& X);
-  };
-
-
-
-class glue_solve_tr
-  {
-  public:
-  
-  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_solve_tr>& X);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_solve_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup glue_solve
-//! @{
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_solve::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_solve>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  Mat<eT> A = X.A.get_ref();
-  
-  const unwrap_check<T2> B_tmp(X.B, out);
-  const Mat<eT>& B = B_tmp.M;
-  
-  arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in A and B must be the same" );
-  
-  bool status;
-  
-  if(A.n_rows == A.n_cols)
-    {
-    const uword mode = X.aux_uword;
-    
-    status = (mode == 0) ? auxlib::solve(out, A, B) : auxlib::solve(out, A, B, true);
-    }
-  else
-  if(A.n_rows > A.n_cols)
-    {
-    arma_extra_debug_print("solve(): detected over-determined system");
-    status = auxlib::solve_od(out, A, B);
-    }
-  else
-    {
-    arma_extra_debug_print("solve(): detected under-determined system");
-    status = auxlib::solve_ud(out, A, B);
-    }
-  
-  if(status == false)
-    {
-    out.reset();
-    arma_bad("solve(): solution not found");
-    }
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_solve_tr::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_solve_tr>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> A_tmp(X.A, out);
-  const unwrap_check<T2> B_tmp(X.B, out);
-  
-  const Mat<eT>& A = A_tmp.M;
-  const Mat<eT>& B = B_tmp.M;
-  
-  bool  err_state = false;
-  char* err_msg   = 0;
-  
-  arma_debug_set_error( err_state, err_msg, ((&A) == (&B)),           "solve(): A is an alias of B" );
-  arma_debug_set_error( err_state, err_msg, (A.n_rows != B.n_rows),   "solve(): number of rows in A and B must be the same" );
-  arma_debug_set_error( err_state, err_msg, (A.is_square() == false), "solve(): A is not a square matrix" );
-  
-  arma_debug_check(err_state, err_msg);
-  
-  const bool status = auxlib::solve_tr(out, A, B, X.aux_uword);
-  
-  if(status == false)
-    {
-    out.reset();
-    arma_bad("solve(): solution not found");
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_times_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup glue_times
-//! @{
-
-
-
-//! \brief
-//! Template metaprogram depth_lhs
-//! calculates the number of Glue<Tx,Ty, glue_type> instances on the left hand side argument of Glue<Tx,Ty, glue_type>
-//! i.e. it recursively expands each Tx, until the type of Tx is not "Glue<..,.., glue_type>"  (i.e the "glue_type" changes)
-
-template<typename glue_type, typename T1>
-struct depth_lhs
-  {
-  static const uword num = 0;
-  };
-
-template<typename glue_type, typename T1, typename T2>
-struct depth_lhs< glue_type, Glue<T1,T2,glue_type> >
-  {
-  static const uword num = 1 + depth_lhs<glue_type, T1>::num;
-  };
-
-
-
-template<uword N>
-struct glue_times_redirect
-  {
-  template<typename T1, typename T2>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X);
-  };
-
-
-template<>
-struct glue_times_redirect<3>
-  {
-  template<typename T1, typename T2, typename T3>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>,T3,glue_times>& X);
-  };
-
-
-template<>
-struct glue_times_redirect<4>
-  {
-  template<typename T1, typename T2, typename T3, typename T4>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Glue< Glue< Glue<T1,T2,glue_times>, T3, glue_times>, T4, glue_times>& X);
-  };
-
-
-
-//! Class which implements the immediate multiplication of two or more matrices
-class glue_times
-  {
-  public:
-  
-  
-  template<typename T1, typename T2>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X);
-  
-  
-  template<typename T1>
-  inline static void apply_inplace(Mat<typename T1::elem_type>& out, const T1& X);
-  
-  template<typename T1, typename T2>
-  arma_hot inline static void apply_inplace_plus(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_times>& X, const sword sign);
-  
-  template<typename eT1, typename eT2>
-  inline static void apply_mixed(Mat<typename promote_type<eT1,eT2>::result>& out, const Mat<eT1>& X, const Mat<eT2>& Y);
-  
-  
-  template<typename eT>
-  arma_inline static uword  mul_storage_cost(const Mat<eT>& A, const Mat<eT>& B, const bool do_trans_A, const bool do_trans_B);
-  
-  template<typename eT>
-  arma_hot inline static void apply(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const eT val, const bool do_trans_A, const bool do_trans_B, const bool do_scalar_times);
-  
-  template<typename eT>
-  inline static void apply(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const Mat<eT>& C, const eT val, const bool do_trans_A, const bool do_trans_B, const bool do_trans_C, const bool do_scalar_times);
-  
-  template<typename eT>
-  inline static void apply(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const Mat<eT>& C, const Mat<eT>& D, const eT val, const bool do_trans_A, const bool do_trans_B, const bool do_trans_C, const bool do_trans_D, const bool do_scalar_times);
-
-  };
-
-
-
-class glue_times_diag
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_times_diag>& X);
-  
-  };
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/glue_times_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,694 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup glue_times
-//! @{
-
-
-
-template<uword N>
-template<typename T1, typename T2>
-inline
-void
-glue_times_redirect<N>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const partial_unwrap_check<T1> tmp1(X.A, out);
-  const partial_unwrap_check<T2> tmp2(X.B, out);
-  
-  const Mat<eT>& A = tmp1.M;
-  const Mat<eT>& B = tmp2.M;
-  
-  const bool do_trans_A = tmp1.do_trans;
-  const bool do_trans_B = tmp2.do_trans;
-
-  const bool use_alpha = tmp1.do_times || tmp2.do_times;
-  const eT       alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val()) : eT(0);
-  
-  glue_times::apply(out, A, B, alpha, do_trans_A, do_trans_B, use_alpha);
-  }
-
-
-
-template<typename T1, typename T2, typename T3>
-inline
-void
-glue_times_redirect<3>::apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>, T3, glue_times>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  // there is exactly 3 objects
-  // hence we can safely expand X as X.A.A, X.A.B and X.B
-  
-  const partial_unwrap_check<T1> tmp1(X.A.A, out);
-  const partial_unwrap_check<T2> tmp2(X.A.B, out);
-  const partial_unwrap_check<T3> tmp3(X.B,   out);
-  
-  const Mat<eT>& A = tmp1.M;
-  const Mat<eT>& B = tmp2.M;
-  const Mat<eT>& C = tmp3.M;
-  
-  const bool do_trans_A = tmp1.do_trans;
-  const bool do_trans_B = tmp2.do_trans;
-  const bool do_trans_C = tmp3.do_trans;
-  
-  const bool use_alpha = tmp1.do_times || tmp2.do_times || tmp3.do_times;
-  const eT       alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val() * tmp3.get_val()) : eT(0);
-  
-  glue_times::apply(out, A, B, C, alpha, do_trans_A, do_trans_B, do_trans_C, use_alpha);
-  }
-
-
-
-template<typename T1, typename T2, typename T3, typename T4>
-inline
-void
-glue_times_redirect<4>::apply(Mat<typename T1::elem_type>& out, const Glue< Glue< Glue<T1,T2,glue_times>, T3, glue_times>, T4, glue_times>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  // there is exactly 4 objects
-  // hence we can safely expand X as X.A.A.A, X.A.A.B, X.A.B and X.B
-  
-  const partial_unwrap_check<T1> tmp1(X.A.A.A, out);
-  const partial_unwrap_check<T2> tmp2(X.A.A.B, out);
-  const partial_unwrap_check<T3> tmp3(X.A.B,   out);
-  const partial_unwrap_check<T4> tmp4(X.B,     out);
-  
-  const Mat<eT>& A = tmp1.M;
-  const Mat<eT>& B = tmp2.M;
-  const Mat<eT>& C = tmp3.M;
-  const Mat<eT>& D = tmp4.M;
-  
-  const bool do_trans_A = tmp1.do_trans;
-  const bool do_trans_B = tmp2.do_trans;
-  const bool do_trans_C = tmp3.do_trans;
-  const bool do_trans_D = tmp4.do_trans;
-  
-  const bool use_alpha = tmp1.do_times || tmp2.do_times || tmp3.do_times || tmp4.do_times;
-  const eT       alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val() * tmp3.get_val() * tmp4.get_val()) : eT(0);
-  
-  glue_times::apply(out, A, B, C, D, alpha, do_trans_A, do_trans_B, do_trans_C, do_trans_D, use_alpha);
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_times::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
-  {
-  arma_extra_debug_sigprint();
-
-  typedef typename T1::elem_type eT;
-
-  const sword N_mat = 1 + depth_lhs< glue_times, Glue<T1,T2,glue_times> >::num;
-
-  arma_extra_debug_print(arma_boost::format("N_mat = %d") % N_mat);
-
-  glue_times_redirect<N_mat>::apply(out, X);
-  }
-
-
-
-template<typename T1>
-inline
-void
-glue_times::apply_inplace(Mat<typename T1::elem_type>& out, const T1& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> tmp(X, out);
-  const Mat<eT>& B     = tmp.M;
-  
-  arma_debug_assert_mul_size(out, B, "matrix multiplication");
-  
-  const uword out_n_rows = out.n_rows;
-  const uword out_n_cols = out.n_cols;
-  
-  if(out_n_cols == B.n_cols)
-    {
-    // size of resulting matrix is the same as 'out'
-    
-    podarray<eT> tmp(out_n_cols);
-    
-    eT* tmp_rowdata = tmp.memptr();
-    
-    for(uword row=0; row < out_n_rows; ++row)
-      {
-      tmp.copy_row(out, row);
-      
-      for(uword col=0; col < out_n_cols; ++col)
-        {
-        out.at(row,col) = op_dot::direct_dot( out_n_cols, tmp_rowdata, B.colptr(col) );
-        }
-      }
-    
-    }
-  else
-    {
-    const Mat<eT> tmp(out);
-    glue_times::apply(out, tmp, B, eT(1), false, false, false);
-    }
-  
-  }
-
-
-
-template<typename T1, typename T2>
-arma_hot
-inline
-void
-glue_times::apply_inplace_plus(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_times>& X, const sword sign)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const partial_unwrap_check<T1> tmp1(X.A, out);
-  const partial_unwrap_check<T2> tmp2(X.B, out);
-  
-  const Mat<eT>& A     = tmp1.M;
-  const Mat<eT>& B     = tmp2.M;
-  const eT       alpha = tmp1.get_val() * tmp2.get_val() * ( (sign > sword(0)) ? eT(1) : eT(-1) );
-  
-  const bool do_trans_A = tmp1.do_trans;
-  const bool do_trans_B = tmp2.do_trans;
-  const bool use_alpha  = tmp1.do_times || tmp2.do_times || (sign < sword(0));
-  
-  arma_debug_assert_mul_size(A, B, do_trans_A, do_trans_B, "matrix multiplication");
-  
-  const uword result_n_rows = (do_trans_A == false) ? A.n_rows : A.n_cols;
-  const uword result_n_cols = (do_trans_B == false) ? B.n_cols : B.n_rows;
-  
-  arma_assert_same_size(out.n_rows, out.n_cols, result_n_rows, result_n_cols, "addition");
-  
-  if(out.n_elem > 0)
-    {
-    if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == false) )
-      {
-      if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<true,         false, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
-        }
-      else
-      if(B.n_cols == 1)
-        {
-        gemv<false,        false, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
-        }
-      else
-        {
-        gemm<false, false, false, true>::apply(out, A, B, alpha, eT(1));
-        }
-      }
-    else
-    if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == true) )
-      {
-      if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<true,         true, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
-        }
-      else
-      if(B.n_cols == 1)
-        {
-        gemv<false,        true, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
-        }
-      else
-        {
-        gemm<false, false, true, true>::apply(out, A, B, alpha, eT(1));
-        }
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == false) && (use_alpha == false) )
-      {
-      if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<true,        false, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
-        }
-      else
-      if(B.n_cols == 1)
-        {
-        gemv<true,        false, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
-        }
-      else
-        {
-        gemm<true, false, false, true>::apply(out, A, B, alpha, eT(1));
-        }
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == false) && (use_alpha == true) )
-      {
-      if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<true,        true, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
-        }
-      else
-      if(B.n_cols == 1)
-        {
-        gemv<true,        true, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
-        }
-      else
-        {
-        gemm<true, false, true, true>::apply(out, A, B, alpha, eT(1));
-        }
-      }
-    else
-    if( (do_trans_A == false) && (do_trans_B == true) && (use_alpha == false) )
-      {
-      if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<false,       false, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
-        }
-      else
-      if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<false,       false, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
-        }
-      else
-        {
-        gemm<false, true, false, true>::apply(out, A, B, alpha, eT(1));
-        }
-      }
-    else
-    if( (do_trans_A == false) && (do_trans_B == true) && (use_alpha == true) )
-      {
-      if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<false,       true, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
-        }
-      else
-      if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<false,       true, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
-        }
-      else
-        {
-        gemm<false, true, true, true>::apply(out, A, B, alpha, eT(1));
-        }
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == true) && (use_alpha == false) )
-      {
-      if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<false,      false, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
-        }
-      else
-      if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<true,       false, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
-        }
-      else
-        {
-        gemm<true, true, false, true>::apply(out, A, B, alpha, eT(1));
-        }
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == true) && (use_alpha == true) )
-      {
-      if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<false,      true, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
-        }
-      else
-      if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<true,       true, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
-        }
-      else
-        {
-        gemm<true, true, true, true>::apply(out, A, B, alpha, eT(1));
-        }
-      }
-    }
-  
-  
-  }
-
-
-
-template<typename eT>
-arma_inline
-uword
-glue_times::mul_storage_cost(const Mat<eT>& A, const Mat<eT>& B, const bool do_trans_A, const bool do_trans_B)
-  {
-  const uword final_A_n_rows = (do_trans_A == false) ? A.n_rows : A.n_cols;
-  const uword final_B_n_cols = (do_trans_B == false) ? B.n_cols : B.n_rows;
-  
-  return final_A_n_rows * final_B_n_cols;
-  }
-
-
-
-template<typename eT>
-arma_hot
-inline
-void
-glue_times::apply
-  (
-        Mat<eT>& out,
-  const Mat<eT>& A,
-  const Mat<eT>& B,
-  const eT       alpha,
-  const bool     do_trans_A,
-  const bool     do_trans_B,
-  const bool     use_alpha
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_mul_size(A, B, do_trans_A, do_trans_B, "matrix multiplication");
-  
-  const uword final_n_rows = (do_trans_A == false) ? A.n_rows : A.n_cols;
-  const uword final_n_cols = (do_trans_B == false) ? B.n_cols : B.n_rows;
-  
-  out.set_size(final_n_rows, final_n_cols);
-  
-  if( (A.n_elem > 0) && (B.n_elem > 0) )
-    {
-    if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == false) )
-      {
-      if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<true,         false, false>::apply(out.memptr(), B, A.memptr());
-        }
-      else
-      if(B.n_cols == 1)
-        {
-        gemv<false,        false, false>::apply(out.memptr(), A, B.memptr());
-        }
-      else
-        {
-        gemm<false, false, false, false>::apply(out, A, B);
-        }
-      }
-    else
-    if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == true) )
-      {
-      if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<true,         true, false>::apply(out.memptr(), B, A.memptr(), alpha);
-        }
-      else
-      if(B.n_cols == 1)
-        {
-        gemv<false,        true, false>::apply(out.memptr(), A, B.memptr(), alpha);
-        }
-      else
-        {
-        gemm<false, false, true, false>::apply(out, A, B, alpha);
-        }
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == false) && (use_alpha == false) )
-      {
-      if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<true,        false, false>::apply(out.memptr(), B, A.memptr());
-        }
-      else
-      if(B.n_cols == 1)
-        {
-        gemv<true,        false, false>::apply(out.memptr(), A, B.memptr());
-        }
-      else
-        {
-        gemm<true, false, false, false>::apply(out, A, B);
-        }
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == false) && (use_alpha == true) )
-      {
-      if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<true,        true, false>::apply(out.memptr(), B, A.memptr(), alpha);
-        }
-      else
-      if(B.n_cols == 1)
-        {
-        gemv<true,        true, false>::apply(out.memptr(), A, B.memptr(), alpha);
-        }
-      else
-        {
-        gemm<true, false, true, false>::apply(out, A, B, alpha);
-        }
-      }
-    else
-    if( (do_trans_A == false) && (do_trans_B == true) && (use_alpha == false) )
-      {
-      if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<false,       false, false>::apply(out.memptr(), B, A.memptr());
-        }
-      else
-      if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<false,       false, false>::apply(out.memptr(), A, B.memptr());
-        }
-      else
-        {
-        gemm<false, true, false, false>::apply(out, A, B);
-        }
-      }
-    else
-    if( (do_trans_A == false) && (do_trans_B == true) && (use_alpha == true) )
-      {
-      if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<false,       true, false>::apply(out.memptr(), B, A.memptr(), alpha);
-        }
-      else
-      if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<false,       true, false>::apply(out.memptr(), A, B.memptr(), alpha);
-        }
-      else
-        {
-        gemm<false, true, true, false>::apply(out, A, B, alpha);
-        }
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == true) && (use_alpha == false) )
-      {
-      if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<false,      false, false>::apply(out.memptr(), B, A.memptr());
-        }
-      else
-      if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<true,       false, false>::apply(out.memptr(), A, B.memptr());
-        }
-      else
-        {
-        gemm<true, true, false, false>::apply(out, A, B);
-        }
-      }
-    else
-    if( (do_trans_A == true) && (do_trans_B == true) && (use_alpha == true) )
-      {
-      if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<false,      true, false>::apply(out.memptr(), B, A.memptr(), alpha);
-        }
-      else
-      if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
-        {
-        gemv<true,       true, false>::apply(out.memptr(), A, B.memptr(), alpha);
-        }
-      else
-        {
-        gemm<true, true, true, false>::apply(out, A, B, alpha);
-        }
-      }
-    }
-  else
-    {
-    out.zeros();
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-glue_times::apply
-  (
-        Mat<eT>& out,
-  const Mat<eT>& A,
-  const Mat<eT>& B,
-  const Mat<eT>& C,
-  const eT       alpha,
-  const bool     do_trans_A,
-  const bool     do_trans_B,
-  const bool     do_trans_C,
-  const bool     use_alpha
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT> tmp;
-  
-  if( glue_times::mul_storage_cost(A, B, do_trans_A, do_trans_B) <= glue_times::mul_storage_cost(B, C, do_trans_B, do_trans_C) )
-    {
-    // out = (A*B)*C
-    glue_times::apply(tmp, A,   B, alpha, do_trans_A, do_trans_B, use_alpha);
-    glue_times::apply(out, tmp, C, eT(0), false,      do_trans_C, false    );
-    }
-  else
-    {
-    // out = A*(B*C)
-    glue_times::apply(tmp, B, C,   alpha, do_trans_B, do_trans_C, use_alpha);
-    glue_times::apply(out, A, tmp, eT(0), do_trans_A, false,      false    );
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-glue_times::apply
-  (
-        Mat<eT>& out,
-  const Mat<eT>& A,
-  const Mat<eT>& B,
-  const Mat<eT>& C,
-  const Mat<eT>& D,
-  const eT       alpha,
-  const bool     do_trans_A,
-  const bool     do_trans_B,
-  const bool     do_trans_C,
-  const bool     do_trans_D,
-  const bool     use_alpha
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT> tmp;
-  
-  if( glue_times::mul_storage_cost(A, C, do_trans_A, do_trans_C) <= glue_times::mul_storage_cost(B, D, do_trans_B, do_trans_D) )
-    {
-    // out = (A*B*C)*D
-    glue_times::apply(tmp, A, B, C, alpha, do_trans_A, do_trans_B, do_trans_C, use_alpha);
-    
-    glue_times::apply(out, tmp, D, eT(0), false, do_trans_D, false);
-    }
-  else
-    {
-    // out = A*(B*C*D)
-    glue_times::apply(tmp, B, C, D, alpha, do_trans_B, do_trans_C, do_trans_D, use_alpha);
-    
-    glue_times::apply(out, A, tmp, eT(0), do_trans_A, false, false);
-    }
-  }
-
-
-
-//
-// glue_times_diag
-
-
-template<typename T1, typename T2>
-arma_hot
-inline
-void
-glue_times_diag::apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_times_diag>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const strip_diagmat<T1> S1(X.A);
-  const strip_diagmat<T2> S2(X.B);
-  
-  typedef typename strip_diagmat<T1>::stored_type T1_stripped;
-  typedef typename strip_diagmat<T2>::stored_type T2_stripped;
-  
-  if( (S1.do_diagmat == true) && (S2.do_diagmat == false) )
-    {
-    const diagmat_proxy_check<T1_stripped> A(S1.M, out);
-    
-    const unwrap_check<T2> tmp(X.B, out);
-    const Mat<eT>& B     = tmp.M;
-    
-    arma_debug_assert_mul_size(A.n_elem, A.n_elem, B.n_rows, B.n_cols, "matrix multiplication");
-    
-    out.set_size(A.n_elem, B.n_cols);
-    
-    for(uword col=0; col<B.n_cols; ++col)
-      {
-            eT* out_coldata = out.colptr(col);
-      const eT* B_coldata   = B.colptr(col);
-      
-      for(uword row=0; row<B.n_rows; ++row)
-        {
-        out_coldata[row] = A[row] * B_coldata[row];
-        }
-      }
-    }
-  else
-  if( (S1.do_diagmat == false) && (S2.do_diagmat == true) )
-    {
-    const unwrap_check<T1> tmp(X.A, out);
-    const Mat<eT>& A     = tmp.M;
-    
-    const diagmat_proxy_check<T2_stripped> B(S2.M, out);
-    
-    arma_debug_assert_mul_size(A.n_rows, A.n_cols, B.n_elem, B.n_elem, "matrix multiplication");
-    
-    out.set_size(A.n_rows, B.n_elem);
-    
-    for(uword col=0; col<A.n_cols; ++col)
-      {
-      const eT  val = B[col];
-      
-            eT* out_coldata = out.colptr(col);
-      const eT*   A_coldata =   A.colptr(col);
-    
-      for(uword row=0; row<A.n_rows; ++row)
-        {
-        out_coldata[row] = A_coldata[row] * val;
-        }
-      }
-    }
-  else
-  if( (S1.do_diagmat == true) && (S2.do_diagmat == true) )
-    {
-    const diagmat_proxy_check<T1_stripped> A(S1.M, out);
-    const diagmat_proxy_check<T2_stripped> B(S2.M, out);
-    
-    arma_debug_assert_mul_size(A.n_elem, A.n_elem, B.n_elem, B.n_elem, "matrix multiplication");
-    
-    out.zeros(A.n_elem, A.n_elem);
-    
-    for(uword i=0; i<A.n_elem; ++i)
-      {
-      out.at(i,i) = A[i] * B[i];
-      }
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_toeplitz_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// Copyright (C) 2011 Alcatel Lucent
-// Copyright (C) 2011 Gerhard Schreiber
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup glue_toeplitz
-//! @{
-
-
-
-class glue_toeplitz
-  {
-  public:
-  
-  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_toeplitz>& in);
-  };
-
-
-
-class glue_toeplitz_circ
-  {
-  public:
-  
-  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_toeplitz_circ>& in);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/glue_toeplitz_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// Copyright (C) 2011 Alcatel Lucent
-// Copyright (C) 2011 Gerhard Schreiber
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup glue_toeplitz
-//! @{
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_toeplitz::apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_toeplitz>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  if( ((void*)(&in.A)) == ((void*)(&in.B)) )
-    {
-    arma_extra_debug_print("glue_toeplitz::apply(): one argument version");
-    
-    const unwrap_check<T1>  tmp(in.A, out);
-    const Mat<eT>& A      = tmp.M;
-    
-    arma_debug_check( (A.is_vec() == false), "toeplitz(): input argument must be a vector" );
-    
-    const uword N     = A.n_elem;
-    const eT* A_mem = A.memptr();
-    
-    out.set_size(N,N);
-    
-    for(uword col=0; col<N; ++col)
-      {
-      eT* col_mem = out.colptr(col);
-      
-      uword i;
-      
-      i = col;
-      for(uword row=0; row<col; ++row, --i)
-        {
-        col_mem[row] = A_mem[i];
-        }
-      
-      i = 0;
-      for(uword row=col; row<N; ++row, ++i)
-        {
-        col_mem[row] = A_mem[i];
-        }      
-      }
-    }
-  else
-    {
-    arma_extra_debug_print("glue_toeplitz::apply(): two argument version");
-    
-    const unwrap_check<T1> tmp1(in.A, out);
-    const unwrap_check<T2> tmp2(in.B, out);
-    
-    const Mat<eT>& A = tmp1.M;
-    const Mat<eT>& B = tmp2.M;
-    
-    arma_debug_check( ( (A.is_vec() == false) || (B.is_vec() == false) ), "toeplitz(): input arguments must be vectors" );
-    
-    const uword A_N = A.n_elem;
-    const uword B_N = B.n_elem;
-    
-    const eT* A_mem = A.memptr();
-    const eT* B_mem = B.memptr();
-    
-    out.set_size(A_N, B_N);
-    
-    if( out.is_empty() )
-      {
-      return;
-      }
-    
-    for(uword col=0; col<B_N; ++col)
-      {
-      eT* col_mem = out.colptr(col);
-      
-      uword i = 0;
-      for(uword row=col; row<A_N; ++row, ++i)
-        {
-        col_mem[row] = A_mem[i];
-        }
-      }
-    
-    for(uword row=0; row<A_N; ++row)
-      {
-      uword i = 1;
-      for(uword col=(row+1); col<B_N; ++col, ++i)
-        {
-        out.at(row,col) = B_mem[i];
-        }
-      }
-    
-    }
-  
-  
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-void
-glue_toeplitz_circ::apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_toeplitz_circ>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  if( ((void*)(&in.A)) == ((void*)(&in.B)) )
-    {
-    arma_extra_debug_print("glue_toeplitz_circ::apply(): one argument version");
-    
-    const unwrap_check<T1>  tmp(in.A, out);
-    const Mat<eT>& A      = tmp.M;
-    
-    arma_debug_check( (A.is_vec() == false), "toeplitz(): input argument must be a vector" );
-    
-    const uword N     = A.n_elem;
-    const eT* A_mem = A.memptr();
-    
-    out.set_size(N,N);
-    
-    
-    if(A.is_colvec())
-      {
-      // A is interpreted as colvec
-      
-      for(uword col=0; col<N; ++col)
-        {
-        eT* col_mem = out.colptr(col);
-        
-        
-        uword i = col;
-        
-        for(uword row=0; row<col; ++row, --i)
-          {
-          col_mem[row] = A_mem[N-i];
-          }
-        
-        
-        i = 0;
-        
-        for(uword row=col; row<N; ++row, ++i)
-          {
-          col_mem[row] = A_mem[i];
-          }      
-        }
-      
-      }
-    else
-      {
-      // A is interpreted as rowvec - probably not the computationally most efficient way to do this ;-)
-      
-      for(uword row=0; row<N; ++row)
-        {
-        uword i = row;
-         
-        for(uword col=0; col<row; ++col, --i)
-          {
-          out.at(row,col) = A_mem[N-i];
-          }
-         
-        i = 0;
-         
-        for(uword col=row; col<N; ++col, ++i)
-          {
-          out.at(row,col) = A_mem[i];
-          }
-        }
-      }
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/include_atlas.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-#if defined(ARMA_USE_ATLAS)
-  #if !defined(ARMA_ATLAS_INCLUDE_DIR)
-    extern "C"
-      {
-      #include <cblas.h>
-      #include <clapack.h>
-      }
-  #else
-    #define ARMA_STR1(x) x
-    #define ARMA_STR2(x) ARMA_STR1(x)
-    
-    #define ARMA_CBLAS   ARMA_STR2(ARMA_ATLAS_INCLUDE_DIR)ARMA_STR2(cblas.h)
-    #define ARMA_CLAPACK ARMA_STR2(ARMA_ATLAS_INCLUDE_DIR)ARMA_STR2(clapack.h)
-    
-    extern "C"
-      {
-      #include ARMA_INCFILE_WRAP(ARMA_CBLAS)
-      #include ARMA_INCFILE_WRAP(ARMA_CLAPACK)
-      }
-    
-    #undef ARMA_STR1
-    #undef ARMA_STR2
-    #undef ARMA_CBLAS
-    #undef ARMA_CLAPACK
-  #endif
-#endif
--- a/armadillo-2.4.4/include/armadillo_bits/injector_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup injector
-//! @{
-
-
-
-template<typename eT>
-class mat_injector_row
-  {
-  public:
-  
-  inline      mat_injector_row();
-  
-  inline void insert(const eT val) const;
-  
-  mutable uword        n_cols;
-  mutable podarray<eT> A;
-  mutable podarray<eT> B;
-  };
-
-
-
-template<typename T1>
-class mat_injector
-  {
-  public:
-  
-  typedef typename T1::elem_type elem_type;
-  
-  inline void  insert(const elem_type val) const;
-  inline void  end_of_row()                const;
-  inline      ~mat_injector();
-  
-  
-  private:
-  
-  inline mat_injector(T1& in_X, const elem_type val);
-  inline mat_injector(T1& in_X, const injector_end_of_row& x);
-  
-  T1&           X;
-  mutable uword n_rows;
-  
-  mutable podarray< mat_injector_row<elem_type>* >* AA;
-  mutable podarray< mat_injector_row<elem_type>* >* BB;
-  
-  friend class Mat<elem_type>;
-  friend class Row<elem_type>;
-  friend class Col<elem_type>;
-  };
-
-
-
-//
-
-
-
-template<typename oT>
-class field_injector_row
-  {
-  public:
-  
-  inline      field_injector_row();
-  inline     ~field_injector_row();
-  
-  inline void insert(const oT& val) const;
-  
-  mutable uword      n_cols;
-  mutable field<oT>* AA;
-  mutable field<oT>* BB;
-  };
-
-  
-  
-template<typename T1>
-class field_injector
-  {
-  public:
-  
-  typedef typename T1::object_type object_type;
-  
-  inline void  insert(const object_type& val) const;
-  inline void  end_of_row()                   const;
-  inline      ~field_injector();
-  
-  
-  private:
-  
-  inline field_injector(T1& in_X, const object_type& val);
-  inline field_injector(T1& in_X, const injector_end_of_row& x);
-  
-  T1&           X;
-  mutable uword n_rows;
-  
-  mutable podarray< field_injector_row<object_type>* >* AA;
-  mutable podarray< field_injector_row<object_type>* >* BB;
-  
-  friend class field<object_type>;
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/injector_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,589 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup injector
-//! @{
-
-
-
-template<typename eT>
-inline
-mat_injector_row<eT>::mat_injector_row()
-  : n_cols(0)
-  {
-  arma_extra_debug_sigprint();
-  
-  A.set_size( podarray_prealloc_n_elem::val );
-  }
-
-
-
-template<typename eT>
-inline
-void
-mat_injector_row<eT>::insert(const eT val) const
-  {
-  arma_extra_debug_sigprint();
-  
-  if(n_cols < A.n_elem)
-    {
-    A[n_cols] = val;
-    ++n_cols;
-    }
-  else
-    {
-    B.set_size(2 * A.n_elem);
-    
-    arrayops::copy(B.memptr(), A.memptr(), n_cols);
-    
-    B[n_cols] = val;
-    ++n_cols;
-    
-    std::swap( access::rw(A.mem),    access::rw(B.mem)    );
-    std::swap( access::rw(A.n_elem), access::rw(B.n_elem) );
-    }
-  }
-
-
-
-//
-//
-//
-
-
-
-template<typename T1>
-inline
-mat_injector<T1>::mat_injector(T1& in_X, const typename mat_injector<T1>::elem_type val)
-  : X(in_X)
-  , n_rows(1)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename mat_injector<T1>::elem_type eT;
-  
-  AA = new podarray< mat_injector_row<eT>* >;
-  BB = new podarray< mat_injector_row<eT>* >;
-  
-  podarray< mat_injector_row<eT>* >& A = *AA;
-  
-  A.set_size(n_rows);
-  
-  for(uword row=0; row<n_rows; ++row)
-    {
-    A[row] = new mat_injector_row<eT>;
-    }
-  
-  (*(A[0])).insert(val);
-  }
-
-
-
-template<typename T1>
-inline
-mat_injector<T1>::mat_injector(T1& in_X, const injector_end_of_row& x)
-  : X(in_X)
-  , n_rows(1)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(x);
-  
-  typedef typename mat_injector<T1>::elem_type eT;
-  
-  AA = new podarray< mat_injector_row<eT>* >;
-  BB = new podarray< mat_injector_row<eT>* >;
-  
-  podarray< mat_injector_row<eT>* >& A = *AA;
-  
-  A.set_size(n_rows);
-  
-  for(uword row=0; row<n_rows; ++row)
-    {
-    A[row] = new mat_injector_row<eT>;
-    }
-  
-  (*this).end_of_row();
-  }
-
-
-
-template<typename T1>
-inline
-mat_injector<T1>::~mat_injector()
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename mat_injector<T1>::elem_type eT;
-  
-  podarray< mat_injector_row<eT>* >& A = *AA;
-  
-  if(n_rows > 0)
-    {
-    uword max_n_cols = (*(A[0])).n_cols;
-    
-    for(uword row=1; row<n_rows; ++row)
-      {
-      const uword n_cols = (*(A[row])).n_cols;
-      
-      if(max_n_cols < n_cols)
-        {
-        max_n_cols = n_cols;
-        }
-      }
-    
-    const uword max_n_rows = ((*(A[n_rows-1])).n_cols == 0) ? n_rows-1 : n_rows;
-    
-    if(is_Mat_only<T1>::value == true)
-      {
-      X.set_size(max_n_rows, max_n_cols);
-      
-      for(uword row=0; row<max_n_rows; ++row)
-        {
-        const uword n_cols = (*(A[row])).n_cols;
-        
-        for(uword col=0; col<n_cols; ++col)
-          {
-          X.at(row,col) = (*(A[row])).A[col];
-          }
-        
-        for(uword col=n_cols; col<max_n_cols; ++col)
-          {
-          X.at(row,col) = eT(0);
-          }
-        }
-      }
-    else
-    if(is_Row<T1>::value == true)
-      {
-      arma_debug_check( (max_n_rows > 1), "matrix initialisation: incompatible dimensions" );
-      
-      const uword n_cols = (*(A[0])).n_cols;
-      
-      X.set_size(1, n_cols);
-      
-      arrayops::copy( X.memptr(), (*(A[0])).A.memptr(), n_cols );
-      }
-    else
-    if(is_Col<T1>::value == true)
-      {
-      const bool is_vec = ( (max_n_rows == 1) || (max_n_cols == 1) );
-      
-      arma_debug_check( (is_vec == false), "matrix initialisation: incompatible dimensions" );
-      
-      const uword n_elem = (std::max)(max_n_rows, max_n_cols);
-      
-      X.set_size(n_elem, 1);
-      
-      uword i = 0;
-      for(uword row=0; row<max_n_rows; ++row)
-        {
-        const uword n_cols = (*(A[0])).n_cols;
-        
-        for(uword col=0; col<n_cols; ++col)
-          {
-          X[i] = (*(A[row])).A[col];
-          ++i;
-          }
-        
-        for(uword col=n_cols; col<max_n_cols; ++col)
-          {
-          X[i] = eT(0);
-          ++i;
-          }
-        }
-      }
-    }
-  
-  for(uword row=0; row<n_rows; ++row)
-    {
-    delete A[row];
-    }
-    
-  delete AA;
-  delete BB;
-  }
-
-
-
-template<typename T1>
-inline
-void
-mat_injector<T1>::insert(const typename mat_injector<T1>::elem_type val) const
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename mat_injector<T1>::elem_type eT;
-  
-  podarray< mat_injector_row<eT>* >& A = *AA;
-  
-  (*(A[n_rows-1])).insert(val);
-  }
-
-
-
-
-template<typename T1>
-inline
-void
-mat_injector<T1>::end_of_row() const
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename mat_injector<T1>::elem_type eT;
-  
-  podarray< mat_injector_row<eT>* >& A = *AA;
-  podarray< mat_injector_row<eT>* >& B = *BB;
-  
-  B.set_size( n_rows+1 );
-  
-  arrayops::copy(B.memptr(), A.memptr(), n_rows);
-  
-  for(uword row=n_rows; row<(n_rows+1); ++row)
-    {
-    B[row] = new mat_injector_row<eT>;
-    }
-  
-  std::swap(AA, BB);
-  
-  n_rows += 1;
-  }
-
-
-
-template<typename T1>
-arma_inline
-const mat_injector<T1>&
-operator<<(const mat_injector<T1>& ref, const typename mat_injector<T1>::elem_type val)
-  {
-  arma_extra_debug_sigprint();
-  
-  ref.insert(val);
-  
-  return ref;
-  }
-
-
-
-template<typename T1>
-arma_inline
-const mat_injector<T1>&
-operator<<(const mat_injector<T1>& ref, const injector_end_of_row& x)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(x);
-  
-  ref.end_of_row();
-  
-  return ref;
-  }
-
-
-
-//// using a mixture of operator << and , doesn't work yet
-//// e.g. A << 1, 2, 3 << endr
-//// in the above "3 << endr" requires special handling.
-//// similarly, special handling is necessary for "endr << 3"
-//// 
-// template<typename T1>
-// arma_inline
-// const mat_injector<T1>&
-// operator,(const mat_injector<T1>& ref, const typename mat_injector<T1>::elem_type val)
-//   {
-//   arma_extra_debug_sigprint();
-//   
-//   ref.insert(val);
-//   
-//   return ref;
-//   }
-
-
-
-// template<typename T1>
-// arma_inline
-// const mat_injector<T1>&
-// operator,(const mat_injector<T1>& ref, const injector_end_of_row& x)
-//   {
-//   arma_extra_debug_sigprint();
-//   arma_ignore(x);
-//   
-//   ref.end_of_row();
-//   
-//   return ref;
-//   }
-
-
-
-
-//
-//
-//
-
-
-
-template<typename oT>
-inline
-field_injector_row<oT>::field_injector_row()
-  : n_cols(0)
-  {
-  arma_extra_debug_sigprint();
-  
-  AA = new field<oT>;
-  BB = new field<oT>;
-  
-  field<oT>& A = *AA;
-  
-  A.set_size( field_prealloc_n_elem::val );
-  }
-
-
-
-template<typename oT>
-inline
-field_injector_row<oT>::~field_injector_row()
-  {
-  arma_extra_debug_sigprint();
-  
-  delete AA;
-  delete BB;
-  }
-
-
-
-template<typename oT>
-inline
-void
-field_injector_row<oT>::insert(const oT& val) const
-  {
-  arma_extra_debug_sigprint();
-  
-  field<oT>& A = *AA;
-  field<oT>& B = *BB;
-  
-  if(n_cols < A.n_elem)
-    {
-    A[n_cols] = val;
-    ++n_cols;
-    }
-  else
-    {
-    B.set_size(2 * A.n_elem);
-    
-    for(uword i=0; i<n_cols; ++i)
-      {
-      B[i] = A[i];
-      }
-    
-    B[n_cols] = val;
-    ++n_cols;
-    
-    std::swap(AA, BB);
-    }
-  }
-
-
-
-//
-//
-//
-
-
-template<typename T1>
-inline
-field_injector<T1>::field_injector(T1& in_X, const typename field_injector<T1>::object_type& val)
-  : X(in_X)
-  , n_rows(1)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename field_injector<T1>::object_type oT;
-  
-  AA = new podarray< field_injector_row<oT>* >;
-  BB = new podarray< field_injector_row<oT>* >;
-  
-  podarray< field_injector_row<oT>* >& A = *AA;
-  
-  A.set_size(n_rows);
-  
-  for(uword row=0; row<n_rows; ++row)
-    {
-    A[row] = new field_injector_row<oT>;
-    }
-  
-  (*(A[0])).insert(val);
-  }
-
-
-
-template<typename T1>
-inline
-field_injector<T1>::field_injector(T1& in_X, const injector_end_of_row& x)
-  : X(in_X)
-  , n_rows(1)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(x);
-  
-  typedef typename field_injector<T1>::object_type oT;
-  
-  AA = new podarray< field_injector_row<oT>* >;
-  BB = new podarray< field_injector_row<oT>* >;
-  
-  podarray< field_injector_row<oT>* >& A = *AA;
-  
-  A.set_size(n_rows);
-  
-  for(uword row=0; row<n_rows; ++row)
-    {
-    A[row] = new field_injector_row<oT>;
-    }
-  
-  (*this).end_of_row();
-  }
-
-
-
-template<typename T1>
-inline
-field_injector<T1>::~field_injector()
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename field_injector<T1>::object_type oT;
-  
-  podarray< field_injector_row<oT>* >& A = *AA;
-  
-  if(n_rows > 0)
-    {
-    uword max_n_cols = (*(A[0])).n_cols;
-    
-    for(uword row=1; row<n_rows; ++row)
-      {
-      const uword n_cols = (*(A[row])).n_cols;
-      
-      if(max_n_cols < n_cols)
-        {
-        max_n_cols = n_cols;
-        }
-      }
-      
-    const uword max_n_rows = ((*(A[n_rows-1])).n_cols == 0) ? n_rows-1 : n_rows;
-    
-    X.set_size(max_n_rows, max_n_cols);
-    
-    for(uword row=0; row<max_n_rows; ++row)
-      {
-      const uword n_cols = (*(A[row])).n_cols;
-      
-      for(uword col=0; col<n_cols; ++col)
-        {
-        const field<oT>& tmp = *((*(A[row])).AA);
-        X.at(row,col) = tmp[col];
-        }
-      
-      for(uword col=n_cols; col<max_n_cols; ++col)
-        {
-        X.at(row,col) = oT();
-        }
-      }
-    }
-  
-  
-  for(uword row=0; row<n_rows; ++row)
-    {
-    delete A[row];
-    }
-  
-  delete AA;
-  delete BB;
-  }
-
-
-
-template<typename T1>
-inline
-void
-field_injector<T1>::insert(const typename field_injector<T1>::object_type& val) const
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename field_injector<T1>::object_type oT;
-  
-  podarray< field_injector_row<oT>* >& A = *AA;
-  
-  (*(A[n_rows-1])).insert(val);
-  }
-
-
-
-
-template<typename T1>
-inline
-void
-field_injector<T1>::end_of_row() const
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename field_injector<T1>::object_type oT;
-  
-  podarray< field_injector_row<oT>* >& A = *AA;
-  podarray< field_injector_row<oT>* >& B = *BB;
-  
-  B.set_size( n_rows+1 );
-  
-  for(uword row=0; row<n_rows; ++row)
-    {
-    B[row] = A[row];
-    }
-  
-  for(uword row=n_rows; row<(n_rows+1); ++row)
-    {
-    B[row] = new field_injector_row<oT>;
-    }
-  
-  std::swap(AA, BB);
-  
-  n_rows += 1;
-  }
-
-
-
-template<typename T1>
-arma_inline
-const field_injector<T1>&
-operator<<(const field_injector<T1>& ref, const typename field_injector<T1>::object_type& val)
-  {
-  arma_extra_debug_sigprint();
-  
-  ref.insert(val);
-  
-  return ref;
-  }
-
-
-
-template<typename T1>
-arma_inline
-const field_injector<T1>&
-operator<<(const field_injector<T1>& ref, const injector_end_of_row& x)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(x);
-  
-  ref.end_of_row();
-  
-  return ref;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/itpp_wrap.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup itpp_wrap
-//! @{
-
-
-#ifdef ARMA_USE_ITPP
-
-  #include <itpp/base/mat.h>
-  #include <itpp/base/vec.h>
-
-#else
-
-  namespace itpp
-    {
-    
-    //! dummy itpp::Mat class, to prevent compilation errors
-    template<typename eT>
-    class Mat
-      {
-      public:
-      
-      ~Mat()                      {}
-      Mat()                       {}
-      Mat(int n_rows, int n_cols) {}
-      Mat(const Mat& m)           {}
-      
-      const Mat& operator=(const Mat& m) { return *this; }
-
-            int rows()  const { return 0; }
-            int cols()  const { return 0; }
-            int size()  const { return 0; }      
-      const eT* _data() const { return 0; }
-            eT* _data()       { return 0; }
-     };
-  
-  
-    //! dummy itpp::Vec class, to prevent compilation errors
-    template<typename eT>
-    class Vec
-      {
-      public:
-      
-      ~Vec()            {}
-      Vec()             {}
-      Vec(int length)   {}
-      Vec(const Vec& m) {}
-      
-      const Vec& operator=(const Vec& m) { return *this; }
-      
-            int size()   const { return 0; }      
-            int length() const { return 0; }      
-      const eT* _data()  const { return 0; }
-            eT* _data()        { return 0; }
-      };
-    
-    typedef Mat<short int> smat;
-    typedef Vec<short int> svec;
-    
-    typedef Mat<int> imat;
-    typedef Vec<int> ivec;
-  
-    typedef Mat<double> mat;
-    typedef Vec<double> vec;
-    
-    typedef Mat< std::complex<double> > cmat;
-    typedef Vec< std::complex<double> > cvec;
-    }
-
-#endif
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/lapack_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,324 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// Copyright (C)      2009 Edmund Highcock
-// Copyright (C)      2011 James Sanders
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-#ifdef ARMA_USE_LAPACK
-
-
-#if !defined(ARMA_BLAS_CAPITALS)
-  
-  #define arma_sgetrf sgetrf
-  #define arma_dgetrf dgetrf
-  #define arma_cgetrf cgetrf
-  #define arma_zgetrf zgetrf
-  
-  #define arma_sgetri sgetri
-  #define arma_dgetri dgetri
-  #define arma_cgetri cgetri
-  #define arma_zgetri zgetri
-  
-  #define arma_strtri strtri
-  #define arma_dtrtri dtrtri
-  #define arma_ctrtri ctrtri
-  #define arma_ztrtri ztrtri
-  
-  #define arma_ssyev  ssyev
-  #define arma_dsyev  dsyev
-  
-  #define arma_cheev  cheev
-  #define arma_zheev  zheev
-  
-  #define arma_sgeev  sgeev
-  #define arma_dgeev  dgeev
-  
-  #define arma_cgeev  cgeev
-  #define arma_zgeev  zgeev
-  
-  #define arma_spotrf spotrf
-  #define arma_dpotrf dpotrf
-  #define arma_cpotrf cpotrf
-  #define arma_zpotrf zpotrf
-  
-  #define arma_spotri spotri
-  #define arma_dpotri dpotri
-  #define arma_cpotri cpotri
-  #define arma_zpotri zpotri
-  
-  #define arma_sgeqrf sgeqrf
-  #define arma_dgeqrf dgeqrf
-  #define arma_cgeqrf cgeqrf
-  #define arma_zgeqrf zgeqrf
-  
-  #define arma_sorgqr sorgqr
-  #define arma_dorgqr dorgqr
-  
-  #define arma_cungqr cungqr
-  #define arma_zungqr zungqr
-  
-  #define arma_sgesvd sgesvd
-  #define arma_dgesvd dgesvd
-  
-  #define arma_cgesvd cgesvd
-  #define arma_zgesvd zgesvd
-  
-  #define arma_sgesv  sgesv
-  #define arma_dgesv  dgesv
-  #define arma_cgesv  cgesv
-  #define arma_zgesv  zgesv
-  
-  #define arma_sgels  sgels
-  #define arma_dgels  dgels
-  #define arma_cgels  cgels
-  #define arma_zgels  zgels
-  
-  #define arma_strtrs strtrs
-  #define arma_dtrtrs dtrtrs
-  #define arma_ctrtrs ctrtrs
-  #define arma_ztrtrs ztrtrs
-
-  #define arma_sgees  sgees
-  #define arma_dgees  dgees
-  #define arma_cgees  cgees
-  #define arma_zgees  zgees
-  
-  #define arma_strsyl strsyl
-  #define arma_dtrsyl dtrsyl
-  #define arma_ctrsyl ctrsyl
-  #define arma_ztrsyl ztrsyl
-  
-  #define arma_ssytrf ssytrf
-  #define arma_dsytrf dsytrf
-  #define arma_csytrf csytrf
-  #define arma_zsytrf zsytrf
-  
-  #define arma_ssytri ssytri
-  #define arma_dsytri dsytri
-  #define arma_csytri csytri
-  #define arma_zsytri zsytri
-  
-#else
-  
-  #define arma_sgetrf SGETRF
-  #define arma_dgetrf DGETRF
-  #define arma_cgetrf CGETRF
-  #define arma_zgetrf ZGETRF
-  
-  #define arma_sgetri SGETRI
-  #define arma_dgetri DGETRI
-  #define arma_cgetri CGETRI
-  #define arma_zgetri ZGETRI
-  
-  #define arma_strtri STRTRI
-  #define arma_dtrtri DTRTRI
-  #define arma_ctrtri CTRTRI
-  #define arma_ztrtri ZTRTRI
-  
-  #define arma_ssyev  SSYEV
-  #define arma_dsyev  DSYEV
-  
-  #define arma_cheev  CHEEV
-  #define arma_zheev  ZHEEV
-  
-  #define arma_sgeev  SGEEV
-  #define arma_dgeev  DGEEV
-  
-  #define arma_cgeev  CGEEV
-  #define arma_zgeev  ZGEEV
-  
-  #define arma_spotrf SPOTRF
-  #define arma_dpotrf DPOTRF
-  #define arma_cpotrf CPOTRF
-  #define arma_zpotrf ZPOTRF
-  
-  #define arma_spotri SPOTRI
-  #define arma_dpotri DPOTRI
-  #define arma_cpotri CPOTRI
-  #define arma_zpotri ZPOTRI
-  
-  #define arma_sgeqrf SGEQRF
-  #define arma_dgeqrf DGEQRF
-  #define arma_cgeqrf CGEQRF
-  #define arma_zgeqrf ZGEQRF
-  
-  #define arma_sorgqr SORGQR
-  #define arma_dorgqr DORGQR
-  
-  #define arma_cungqr CUNGQR
-  #define arma_zungqr ZUNGQR
-  
-  #define arma_sgesvd SGESVD
-  #define arma_dgesvd DGESVD
-  
-  #define arma_cgesvd CGESVD
-  #define arma_zgesvd ZGESVD
-  
-  #define arma_sgesv  SGESV
-  #define arma_dgesv  DGESV
-  #define arma_cgesv  CGESV
-  #define arma_zgesv  ZGESV
-  
-  #define arma_sgels  SGELS
-  #define arma_dgels  DGELS
-  #define arma_cgels  CGELS
-  #define arma_zgels  ZGELS
-  
-  #define arma_strtrs STRTRS
-  #define arma_dtrtrs DTRTRS
-  #define arma_ctrtrs CTRTRS
-  #define arma_ztrtrs ZTRTRS
-
-  #define arma_sgees  SGEES
-  #define arma_dgees  DGEES
-  #define arma_cgees  CGEES
-  #define arma_zgees  ZGEES
-
-  #define arma_strsyl STRSYL
-  #define arma_dtrsyl DTRSYL
-  #define arma_ctrsyl CTRSYL
-  #define arma_ztrsyl ZTRSYL
-  
-  #define arma_ssytrf SSYTRF
-  #define arma_dsytrf DSYTRF
-  #define arma_csytrf CSYTRF
-  #define arma_zsytrf ZSYTRF
-  
-  #define arma_ssytri SSYTRI
-  #define arma_dsytri DSYTRI
-  #define arma_csytri CSYTRI
-  #define arma_zsytri ZSYTRI
-  
-#endif
-
-
-
-extern "C"
-  {
-  // LU factorisation
-  void arma_fortran(arma_sgetrf)(blas_int* m, blas_int* n,  float* a, blas_int* lda, blas_int* ipiv, blas_int* info);
-  void arma_fortran(arma_dgetrf)(blas_int* m, blas_int* n, double* a, blas_int* lda, blas_int* ipiv, blas_int* info);
-  void arma_fortran(arma_cgetrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda, blas_int* ipiv, blas_int* info);
-  void arma_fortran(arma_zgetrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda, blas_int* ipiv, blas_int* info);
-  
-  // matrix inversion (using LU factorisation result)
-  void arma_fortran(arma_sgetri)(blas_int* n,  float* a, blas_int* lda, blas_int* ipiv,  float* work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_dgetri)(blas_int* n, double* a, blas_int* lda, blas_int* ipiv, double* work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_cgetri)(blas_int* n,  void*  a, blas_int* lda, blas_int* ipiv,   void* work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_zgetri)(blas_int* n,  void*  a, blas_int* lda, blas_int* ipiv,   void* work, blas_int* lwork, blas_int* info);
-  
-  // matrix inversion (triangular matrices)
-  void arma_fortran(arma_strtri)(char* uplo, char* diag, blas_int* n,  float* a, blas_int* lda, blas_int* info);
-  void arma_fortran(arma_dtrtri)(char* uplo, char* diag, blas_int* n, double* a, blas_int* lda, blas_int* info);
-  void arma_fortran(arma_ctrtri)(char* uplo, char* diag, blas_int* n,   void* a, blas_int* lda, blas_int* info);
-  void arma_fortran(arma_ztrtri)(char* uplo, char* diag, blas_int* n,   void* a, blas_int* lda, blas_int* info);
-  
-  // eigenvector decomposition of symmetric real matrices
-  void arma_fortran(arma_ssyev)(char* jobz, char* uplo, blas_int* n,  float* a, blas_int* lda,  float* w,  float* work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_dsyev)(char* jobz, char* uplo, blas_int* n, double* a, blas_int* lda, double* w, double* work, blas_int* lwork, blas_int* info);
-  
-  // eigenvector decomposition of hermitian matrices (complex)
-  void arma_fortran(arma_cheev)(char* jobz, char* uplo, blas_int* n,   void* a, blas_int* lda,  float* w,   void* work, blas_int* lwork,  float* rwork, blas_int* info);
-  void arma_fortran(arma_zheev)(char* jobz, char* uplo, blas_int* n,   void* a, blas_int* lda, double* w,   void* work, blas_int* lwork, double* rwork, blas_int* info);
-  
-  // eigenvector decomposition of general real matrices
-  void arma_fortran(arma_sgeev)(char* jobvl, char* jobvr, blas_int* n,  float* a, blas_int* lda,  float* wr,  float* wi,  float* vl, blas_int* ldvl,  float* vr, blas_int* ldvr,  float* work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_dgeev)(char* jobvl, char* jobvr, blas_int* n, double* a, blas_int* lda, double* wr, double* wi, double* vl, blas_int* ldvl, double* vr, blas_int* ldvr, double* work, blas_int* lwork, blas_int* info);
-  
-  // eigenvector decomposition of general complex matrices
-  void arma_fortran(arma_cgeev)(char* jobvl, char* jobvr, blas_int* n, void* a, blas_int* lda, void* w, void* vl, blas_int* ldvl, void* vr, blas_int* ldvr, void* work, blas_int* lwork,  float* rwork, blas_int* info);
-  void arma_fortran(arma_zgeev)(char* jobvl, char* jobvr, blas_int* n, void* a, blas_int* lda, void* w, void* vl, blas_int* ldvl, void* vr, blas_int* ldvr, void* work, blas_int* lwork, double* rwork, blas_int* info);
-  
-  // Cholesky decomposition
-  void arma_fortran(arma_spotrf)(char* uplo, blas_int* n,  float* a, blas_int* lda, blas_int* info);
-  void arma_fortran(arma_dpotrf)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* info);
-  void arma_fortran(arma_cpotrf)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info);
-  void arma_fortran(arma_zpotrf)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info);
-  
-  // matrix inversion (using Cholesky decomposition result)
-  void arma_fortran(arma_spotri)(char* uplo, blas_int* n,  float* a, blas_int* lda, blas_int* info);
-  void arma_fortran(arma_dpotri)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* info);
-  void arma_fortran(arma_cpotri)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info);
-  void arma_fortran(arma_zpotri)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info);
-  
-  // QR decomposition
-  void arma_fortran(arma_sgeqrf)(blas_int* m, blas_int* n,  float* a, blas_int* lda,  float* tau,  float* work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_dgeqrf)(blas_int* m, blas_int* n, double* a, blas_int* lda, double* tau, double* work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_cgeqrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_zgeqrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info);
-  
-  // Q matrix calculation from QR decomposition (real matrices)
-  void arma_fortran(arma_sorgqr)(blas_int* m, blas_int* n, blas_int* k,  float* a, blas_int* lda,  float* tau,  float* work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_dorgqr)(blas_int* m, blas_int* n, blas_int* k, double* a, blas_int* lda, double* tau, double* work, blas_int* lwork, blas_int* info);
-  
-  // Q matrix calculation from QR decomposition (complex matrices)
-  void arma_fortran(arma_cungqr)(blas_int* m, blas_int* n, blas_int* k,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_zungqr)(blas_int* m, blas_int* n, blas_int* k,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info);
-  
-  // SVD (real matrices)
-  void arma_fortran(arma_sgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, float*  a, blas_int* lda, float*  s, float*  u, blas_int* ldu, float*  vt, blas_int* ldvt, float*  work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_dgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, double* a, blas_int* lda, double* s, double* u, blas_int* ldu, double* vt, blas_int* ldvt, double* work, blas_int* lwork, blas_int* info);
-  
-  // SVD (complex matrices)
-  void arma_fortran(arma_cgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, void*   a, blas_int* lda, float*  s, void*   u, blas_int* ldu, void*   vt, blas_int* ldvt, void*   work, blas_int* lwork, float*  rwork, blas_int* info);
-  void arma_fortran(arma_zgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, void*   a, blas_int* lda, double* s, void*   u, blas_int* ldu, void*   vt, blas_int* ldvt, void*   work, blas_int* lwork, double* rwork, blas_int* info);
-  
-  // solve system of linear equations, using LU decomposition
-  void arma_fortran(arma_sgesv)(blas_int* n, blas_int* nrhs, float*  a, blas_int* lda, blas_int* ipiv, float*  b, blas_int* ldb, blas_int* info);
-  void arma_fortran(arma_dgesv)(blas_int* n, blas_int* nrhs, double* a, blas_int* lda, blas_int* ipiv, double* b, blas_int* ldb, blas_int* info);
-  void arma_fortran(arma_cgesv)(blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, blas_int* ipiv, void*   b, blas_int* ldb, blas_int* info);
-  void arma_fortran(arma_zgesv)(blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, blas_int* ipiv, void*   b, blas_int* ldb, blas_int* info);
-  
-  // solve over/underdetermined system of linear equations
-  void arma_fortran(arma_sgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, float*  a, blas_int* lda, float*  b, blas_int* ldb, float*  work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_dgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, double* a, blas_int* lda, double* b, blas_int* ldb, double* work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_cgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, void*   b, blas_int* ldb, void*   work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_zgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, void*   b, blas_int* ldb, void*   work, blas_int* lwork, blas_int* info);
-  
-  // solve a triangular system of linear equations
-  void arma_fortran(arma_strtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const float*  a, blas_int* lda, float*  b, blas_int* ldb, blas_int* info);
-  void arma_fortran(arma_dtrtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const double* a, blas_int* lda, double* b, blas_int* ldb, blas_int* info);
-  void arma_fortran(arma_ctrtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const void*   a, blas_int* lda, void*   b, blas_int* ldb, blas_int* info);
-  void arma_fortran(arma_ztrtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const void*   a, blas_int* lda, void*   b, blas_int* ldb, blas_int* info);
-  
-  // Schur decomposition (real matrices)
-  void arma_fortran(arma_sgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, float*  a, blas_int* lda, blas_int* sdim, float*  wr, float*  wi, float*  vs, blas_int* ldvs, float*  work, blas_int* lwork, blas_int* bwork, blas_int* info);
-  void arma_fortran(arma_dgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, double* a, blas_int* lda, blas_int* sdim, double* wr, double* wi, double* vs, blas_int* ldvs, double* work, blas_int* lwork, blas_int* bwork, blas_int* info);
-  
-  // Schur decomposition (complex matrices)
-  void arma_fortran(arma_cgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, void* a, blas_int* lda, blas_int* sdim, void* w, void* vs, blas_int* ldvs, void* work, blas_int* lwork, float*  rwork, blas_int* bwork, blas_int* info);
-  void arma_fortran(arma_zgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, void* a, blas_int* lda, blas_int* sdim, void* w, void* vs, blas_int* ldvs, void* work, blas_int* lwork, double* rwork, blas_int* bwork, blas_int* info);
-  
-  // solve a Sylvester equation ax + xb = c, with a and b assumed to be in Schur form
-  void arma_fortran(arma_strsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const float*  a, blas_int* lda, const float*  b, blas_int* ldb, float*  c, blas_int* ldc, float*  scale, blas_int* info);
-  void arma_fortran(arma_dtrsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const double* a, blas_int* lda, const double* b, blas_int* ldb, double* c, blas_int* ldc, double* scale, blas_int* info);
-  void arma_fortran(arma_ctrsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const void*   a, blas_int* lda, const void*   b, blas_int* ldb, void*   c, blas_int* ldc, float*  scale, blas_int* info);
-  void arma_fortran(arma_ztrsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const void*   a, blas_int* lda, const void*   b, blas_int* ldb, void*   c, blas_int* ldc, double* scale, blas_int* info);
-  
-  void arma_fortran(arma_ssytrf)(char* uplo, blas_int* n, float*  a, blas_int* lda, blas_int* ipiv, float*  work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_dsytrf)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* ipiv, double* work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_csytrf)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* lwork, blas_int* info);
-  void arma_fortran(arma_zsytrf)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* lwork, blas_int* info);
-  
-  void arma_fortran(arma_ssytri)(char* uplo, blas_int* n, float*  a, blas_int* lda, blas_int* ipiv, float*  work, blas_int* info);
-  void arma_fortran(arma_dsytri)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* ipiv, double* work, blas_int* info);
-  void arma_fortran(arma_csytri)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* info);
-  void arma_fortran(arma_zsytri)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* info);
-  
-  // void arma_fortran(arma_dgeqp3)(blas_int* m, blas_int* n, double* a, blas_int* lda, blas_int* jpvt, double* tau, double* work, blas_int* lwork, blas_int* info);
-  // void arma_fortran(arma_dormqr)(char* side, char* trans, blas_int* m, blas_int* n, blas_int* k, double* a, blas_int* lda, double* tau, double* c, blas_int* ldc, double* work, blas_int* lwork, blas_int* info);
-  // void  arma_fortran(arma_dposv)(char* uplo, blas_int* n, blas_int* nrhs, double* a, blas_int* lda, double* b, blas_int* ldb, blas_int* info);
-  }
-
-
-#endif
--- a/armadillo-2.4.4/include/armadillo_bits/lapack_wrapper.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,703 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// Copyright (C)      2009 Edmund Highcock
-// Copyright (C)      2011 James Sanders
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-#ifdef ARMA_USE_LAPACK
-
-
-//! \namespace lapack namespace for LAPACK functions
-namespace lapack
-  {
-  
-  
-  template<typename eT>
-  inline
-  void
-  getrf(blas_int* m, blas_int* n, eT* a, blas_int* lda, blas_int* ipiv, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_sgetrf)(m, n, (T*)a, lda, ipiv, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dgetrf)(m, n, (T*)a, lda, ipiv, info);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_cgetrf)(m, n, (T*)a, lda, ipiv, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_zgetrf)(m, n, (T*)a, lda, ipiv, info);
-      }
-    }
-    
-    
-    
-  template<typename eT>
-  inline
-  void
-  getri(blas_int* n,  eT* a, blas_int* lda, blas_int* ipiv, eT* work, blas_int* lwork, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_sgetri)(n, (T*)a, lda, ipiv, (T*)work, lwork, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dgetri)(n, (T*)a, lda, ipiv, (T*)work, lwork, info);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_cgetri)(n, (T*)a, lda, ipiv, (T*)work, lwork, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_zgetri)(n, (T*)a, lda, ipiv, (T*)work, lwork, info);
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  trtri(char* uplo, char* diag, blas_int* n, eT* a, blas_int* lda, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_strtri)(uplo, diag, n, (T*)a, lda, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dtrtri)(uplo, diag, n, (T*)a, lda, info);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_ctrtri)(uplo, diag, n, (T*)a, lda, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_ztrtri)(uplo, diag, n, (T*)a, lda, info);
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  syev(char* jobz, char* uplo, blas_int* n, eT* a, blas_int* lda, eT* w,  eT* work, blas_int* lwork, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_ssyev)(jobz, uplo, n, (T*)a, lda, (T*)w, (T*)work, lwork, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dsyev)(jobz, uplo, n, (T*)a, lda, (T*)w, (T*)work, lwork, info);
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  heev
-    (
-    char* jobz, char* uplo, blas_int* n,
-    eT* a, blas_int* lda, typename eT::value_type* w,
-    eT* work, blas_int* lwork, typename eT::value_type* rwork,
-    blas_int* info
-    )
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef float T;
-      typedef typename std::complex<T> cx_T;
-      arma_fortran(arma_cheev)(jobz, uplo, n, (cx_T*)a, lda, (T*)w, (cx_T*)work, lwork, (T*)rwork, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef double T;
-      typedef typename std::complex<T> cx_T;
-      arma_fortran(arma_zheev)(jobz, uplo, n, (cx_T*)a, lda, (T*)w, (cx_T*)work, lwork, (T*)rwork, info);
-      }
-    }
-  
-	 
-  template<typename eT>
-  inline
-  void
-  geev
-    (
-    char* jobvl, char* jobvr, blas_int* n, 
-    eT* a, blas_int* lda, eT* wr, eT* wi, eT* vl, 
-    blas_int* ldvl, eT* vr, blas_int* ldvr, 
-    eT* work, blas_int* lwork,
-    blas_int* info
-    )
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_sgeev)(jobvl, jobvr, n,  (T*)a, lda, (T*)wr, (T*)wi, (T*)vl, ldvl, (T*)vr, ldvr, (T*)work, lwork, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dgeev)(jobvl, jobvr, n,  (T*)a, lda, (T*)wr, (T*)wi, (T*)vl, ldvl, (T*)vr, ldvr, (T*)work, lwork, info);
-      }
-    }
-
-
-  template<typename eT>
-  inline
-  void
-  cx_geev
-    (
-    char* jobvl, char* jobvr, blas_int* n, 
-    eT* a, blas_int* lda, eT* w, 
-    eT* vl, blas_int* ldvl, 
-    eT* vr, blas_int* ldvr, 
-    eT* work, blas_int* lwork, typename eT::value_type* rwork, 
-    blas_int* info
-    )
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef float T;
-      typedef typename std::complex<T> cx_T;
-      arma_fortran(arma_cgeev)(jobvl, jobvr, n, (cx_T*)a, lda, (cx_T*)w, (cx_T*)vl, ldvl, (cx_T*)vr, ldvr, (cx_T*)work, lwork, (T*)rwork, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef double T;
-      typedef typename std::complex<T> cx_T;
-      arma_fortran(arma_zgeev)(jobvl, jobvr, n, (cx_T*)a, lda, (cx_T*)w, (cx_T*)vl, ldvl, (cx_T*)vr, ldvr, (cx_T*)work, lwork, (T*)rwork, info);
-      }
-    }
-  
-
-
-  
-  template<typename eT>
-  inline
-  void
-  potrf(char* uplo, blas_int* n, eT* a, blas_int* lda, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_spotrf)(uplo, n, (T*)a, lda, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dpotrf)(uplo, n, (T*)a, lda, info);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_cpotrf)(uplo, n, (T*)a, lda, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_zpotrf)(uplo, n, (T*)a, lda, info);
-      }
-    
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  potri(char* uplo, blas_int* n, eT* a, blas_int* lda, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_spotri)(uplo, n, (T*)a, lda, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dpotri)(uplo, n, (T*)a, lda, info);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_cpotri)(uplo, n, (T*)a, lda, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_zpotri)(uplo, n, (T*)a, lda, info);
-      }
-    
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  geqrf(blas_int* m, blas_int* n, eT* a, blas_int* lda, eT* tau, eT* work, blas_int* lwork, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_sgeqrf)(m, n, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dgeqrf)(m, n, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_cgeqrf)(m, n, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_zgeqrf)(m, n, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
-      }
-    
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  orgqr(blas_int* m, blas_int* n, blas_int* k, eT* a, blas_int* lda, eT* tau, eT* work, blas_int* lwork, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_sorgqr)(m, n, k, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dorgqr)(m, n, k, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
-      }
-    }
-
-
-  
-  template<typename eT>
-  inline
-  void
-  ungqr(blas_int* m, blas_int* n, blas_int* k, eT* a, blas_int* lda, eT* tau, eT* work, blas_int* lwork, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_cungqr)(m, n, k, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_zungqr)(m, n, k, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
-      }
-    }
-  
-  
-  template<typename eT>
-  inline
-  void
-  gesvd
-    (
-    char* jobu, char* jobvt, blas_int* m, blas_int* n, eT* a, blas_int* lda,
-    eT* s, eT* u, blas_int* ldu, eT* vt, blas_int* ldvt,
-    eT* work, blas_int* lwork, blas_int* info
-    )
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_sgesvd)(jobu, jobvt, m, n, (T*)a, lda, (T*)s, (T*)u, ldu, (T*)vt, ldvt, (T*)work, lwork, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dgesvd)(jobu, jobvt, m, n, (T*)a, lda, (T*)s, (T*)u, ldu, (T*)vt, ldvt, (T*)work, lwork, info);
-      }
-    }
-  
-  
-  
-  template<typename T>
-  inline
-  void
-  cx_gesvd
-    (
-    char* jobu, char* jobvt, blas_int* m, blas_int* n, std::complex<T>* a, blas_int* lda,
-    T* s, std::complex<T>* u, blas_int* ldu, std::complex<T>* vt, blas_int* ldvt, 
-    std::complex<T>* work, blas_int* lwork, T* rwork, blas_int* info
-    )
-    {
-    arma_type_check(( is_supported_blas_type<T>::value == false ));
-    arma_type_check(( is_supported_blas_type< std::complex<T> >::value == false ));
-    
-    if(is_float<T>::value == true)
-      {
-      typedef float bT;
-      arma_fortran(arma_cgesvd)
-        (
-        jobu, jobvt, m, n, (std::complex<bT>*)a, lda,
-        (bT*)s, (std::complex<bT>*)u, ldu, (std::complex<bT>*)vt, ldvt,
-        (std::complex<bT>*)work, lwork, (bT*)rwork, info
-        );
-      }
-    else
-    if(is_double<T>::value == true)
-      {
-      typedef double bT;
-      arma_fortran(arma_zgesvd)
-        (
-        jobu, jobvt, m, n, (std::complex<bT>*)a, lda,
-        (bT*)s, (std::complex<bT>*)u, ldu, (std::complex<bT>*)vt, ldvt,
-        (std::complex<bT>*)work, lwork, (bT*)rwork, info
-        );
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  gesv(blas_int* n, blas_int* nrhs, eT* a, blas_int* lda, blas_int* ipiv, eT* b, blas_int* ldb, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_sgesv)(n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dgesv)(n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_cgesv)(n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_zgesv)(n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info);
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  gels(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, eT* a, blas_int* lda, eT* b, blas_int* ldb, eT* work, blas_int* lwork, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_sgels)(trans, m, n, nrhs, (T*)a, lda, (T*)b, ldb, (T*)work, lwork, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dgels)(trans, m, n, nrhs, (T*)a, lda, (T*)b, ldb, (T*)work, lwork, info);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_cgels)(trans, m, n, nrhs, (T*)a, lda, (T*)b, ldb, (T*)work, lwork, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_zgels)(trans, m, n, nrhs, (T*)a, lda, (T*)b, ldb, (T*)work, lwork, info);
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  trtrs(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const eT* a, blas_int* lda, eT* b, blas_int* ldb, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_strtrs)(uplo, trans, diag, n, nrhs, (T*)a, lda, (T*)b, ldb, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dtrtrs)(uplo, trans, diag, n, nrhs, (T*)a, lda, (T*)b, ldb, info);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_ctrtrs)(uplo, trans, diag, n, nrhs, (T*)a, lda, (T*)b, ldb, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_ztrtrs)(uplo, trans, diag, n, nrhs, (T*)a, lda, (T*)b, ldb, info);
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  gees(char* jobvs, char* sort, blas_int* select, blas_int* n, eT* a, blas_int* lda, blas_int* sdim, eT* wr, eT* wi, eT* vs, blas_int* ldvs, eT* work, blas_int* lwork, blas_int* bwork, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_sgees)(jobvs, sort, select, n, (T*)a, lda, sdim, (T*)wr, (T*)wi, (T*)vs, ldvs, (T*)work, lwork, bwork, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dgees)(jobvs, sort, select, n, (T*)a, lda, sdim, (T*)wr, (T*)wi, (T*)vs, ldvs, (T*)work, lwork, bwork, info);
-      }
-    }
-  
-  
-  
-  template<typename T>
-  inline
-  void
-  cx_gees(char* jobvs, char* sort, blas_int* select, blas_int* n, std::complex<T>* a, blas_int* lda, blas_int* sdim, std::complex<T>* w, std::complex<T>* vs, blas_int* ldvs, std::complex<T>* work, blas_int* lwork, T* rwork, blas_int* bwork, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<T>::value == false ));
-    arma_type_check(( is_supported_blas_type< std::complex<T> >::value == false ));
-    
-    if(is_float<T>::value == true)
-      {
-      typedef float bT;
-      typedef std::complex<bT> cT;
-      arma_fortran(arma_cgees)(jobvs, sort, select, n, (cT*)a, lda, sdim, (cT*)w, (cT*)vs, ldvs, (cT*)work, lwork, (bT*)rwork, bwork, info);
-      }
-    else
-    if(is_double<T>::value == true)
-      {
-      typedef double bT;
-      typedef std::complex<bT> cT;
-      arma_fortran(arma_zgees)(jobvs, sort, select, n, (cT*)a, lda, sdim, (cT*)w, (cT*)vs, ldvs, (cT*)work, lwork, (bT*)rwork, bwork, info);
-      }
-    }
-  
-  
-  
-  template<typename eT>
-  inline
-  void
-  trsyl(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const eT* a, blas_int* lda, const eT* b, blas_int* ldb, eT* c, blas_int* ldc, eT* scale, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_strsyl)(transa, transb, isgn, m, n, (T*)a, lda, (T*)b, ldb, (T*)c, ldc, (T*)scale, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dtrsyl)(transa, transb, isgn, m, n, (T*)a, lda, (T*)b, ldb, (T*)c, ldc, (T*)scale, info);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_ctrsyl)(transa, transb, isgn, m, n, (T*)a, lda, (T*)b, ldb, (T*)c, ldc, (float*)scale, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_ztrsyl)(transa, transb, isgn, m, n, (T*)a, lda, (T*)b, ldb, (T*)c, ldc, (double*)scale, info);
-      }
-    }
-  
-  
-  template<typename eT>
-  inline
-  void
-  sytrf(char* uplo, blas_int* n, eT* a, blas_int* lda, blas_int* ipiv, eT* work, blas_int* lwork, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_ssytrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dsytrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_csytrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_zsytrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info);
-      }
-    }
-  
-  
-  template<typename eT>
-  inline
-  void
-  sytri(char* uplo, blas_int* n, eT* a, blas_int* lda, blas_int* ipiv, eT* work, blas_int* info)
-    {
-    arma_type_check(( is_supported_blas_type<eT>::value == false ));
-    
-    if(is_float<eT>::value == true)
-      {
-      typedef float T;
-      arma_fortran(arma_ssytri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info);
-      }
-    else
-    if(is_double<eT>::value == true)
-      {
-      typedef double T;
-      arma_fortran(arma_dsytri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info);
-      }
-    else
-    if(is_supported_complex_float<eT>::value == true)
-      {
-      typedef std::complex<float> T;
-      arma_fortran(arma_csytri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info);
-      }
-    else
-    if(is_supported_complex_double<eT>::value == true)
-      {
-      typedef std::complex<double> T;
-      arma_fortran(arma_zsytri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info);
-      }
-    }
-  
-  
-  }
-
-
-#endif
--- a/armadillo-2.4.4/include/armadillo_bits/mtGlueCube_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup mtGlueCube
-//! @{
-
-
-
-template<typename out_eT, typename T1, typename T2, typename glue_type>
-class mtGlueCube : public BaseCube<out_eT, mtGlueCube<out_eT, T1, T2, glue_type> >
-  {
-  public:
-  
-  typedef          out_eT                       elem_type;
-  typedef typename get_pod_type<out_eT>::result pod_type;
-  
-  arma_inline  mtGlueCube(const T1& in_A, const T2& in_B);
-  arma_inline  mtGlueCube(const T1& in_A, const T2& in_B, const uword in_aux_uword);
-  arma_inline ~mtGlueCube();
-  
-  arma_aligned const T1&   A;         //!< first operand
-  arma_aligned const T2&   B;         //!< second operand
-  arma_aligned       uword aux_uword; //!< storage of auxiliary data, uword format
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/mtGlueCube_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup mtGlueCube
-//! @{
-
-
-
-template<typename out_eT, typename T1, typename T2, typename glue_type>
-inline
-mtGlueCube<out_eT,T1,T2,glue_type>::mtGlueCube(const T1& in_A, const T2& in_B)
-  : A(in_A)
-  , B(in_B)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename out_eT, typename T1, typename T2, typename glue_type>
-inline
-mtGlueCube<out_eT,T1,T2,glue_type>::mtGlueCube(const T1& in_A, const T2& in_B, const uword in_aux_uword)
-  : A(in_A)
-  , B(in_B)
-  , aux_uword(in_aux_uword)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename out_eT, typename T1, typename T2, typename glue_type>
-inline
-mtGlueCube<out_eT,T1,T2,glue_type>::~mtGlueCube()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/mtGlue_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup mtGlue
-//! @{
-
-
-
-template<typename out_eT, typename T1, typename T2, typename glue_type>
-class mtGlue : public Base<out_eT, mtGlue<out_eT, T1, T2, glue_type> >
-  {
-  public:
-  
-  typedef          out_eT                       elem_type;
-  typedef typename get_pod_type<out_eT>::result pod_type;
-  
-  arma_inline  mtGlue(const T1& in_A, const T2& in_B);
-  arma_inline  mtGlue(const T1& in_A, const T2& in_B, const uword in_aux_uword);
-  arma_inline ~mtGlue();
-  
-  arma_aligned const T1&   A;         //!< first operand
-  arma_aligned const T2&   B;         //!< second operand
-  arma_aligned       uword aux_uword; //!< storage of auxiliary data, uword format
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/mtGlue_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup mtGlue
-//! @{
-
-
-
-template<typename out_eT, typename T1, typename T2, typename glue_type>
-inline
-mtGlue<out_eT,T1,T2,glue_type>::mtGlue(const T1& in_A, const T2& in_B)
-  : A(in_A)
-  , B(in_B)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename out_eT, typename T1, typename T2, typename glue_type>
-inline
-mtGlue<out_eT,T1,T2,glue_type>::mtGlue(const T1& in_A, const T2& in_B, const uword in_aux_uword)
-  : A(in_A)
-  , B(in_B)
-  , aux_uword(in_aux_uword)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename out_eT, typename T1, typename T2, typename glue_type>
-inline
-mtGlue<out_eT,T1,T2,glue_type>::~mtGlue()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/mtOpCube_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup mtOpCube
-//! @{
-
-
-
-template<typename out_eT, typename T1, typename op_type>
-class mtOpCube : public BaseCube<out_eT, mtOpCube<out_eT, T1, op_type> >
-  {
-  public:
-  
-  typedef          out_eT                       elem_type;
-  typedef typename get_pod_type<out_eT>::result pod_type;
-
-  typedef typename T1::elem_type                in_eT;
-
-  inline explicit mtOpCube(const T1& in_m);
-  inline          mtOpCube(const T1& in_m, const in_eT in_aux);
-  inline          mtOpCube(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
-  inline          mtOpCube(const T1& in_m, const in_eT in_aux,         const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
-  
-  inline          mtOpCube(const char junk, const T1& in_m, const out_eT in_aux);
-  
-  inline         ~mtOpCube();
-    
-  
-  arma_aligned const T1&    m;            //!< storage of reference to the operand (eg. a matrix)
-  arma_aligned       in_eT  aux;          //!< storage of auxiliary data, using the element type as used by T1
-  arma_aligned       out_eT aux_out_eT;   //!< storage of auxiliary data, using the element type as specified by the out_eT template parameter
-  arma_aligned       uword  aux_uword_a;  //!< storage of auxiliary data, uword format
-  arma_aligned       uword  aux_uword_b;  //!< storage of auxiliary data, uword format
-  arma_aligned       uword  aux_uword_c;  //!< storage of auxiliary data, uword format
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/mtOpCube_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup mtOpCube
-//! @{
-
-
-
-template<typename out_eT, typename T1, typename op_type>
-inline
-mtOpCube<out_eT, T1, op_type>::mtOpCube(const T1& in_m)
-  : m(in_m)
-  {
-  arma_extra_debug_sigprint();
-  }
-  
-
-
-template<typename out_eT, typename T1, typename op_type>
-inline
-mtOpCube<out_eT, T1, op_type>::mtOpCube(const T1& in_m, const typename T1::elem_type in_aux)
-  : m(in_m)
-  , aux(in_aux)
-  {
-  arma_extra_debug_sigprint();
-  }
-  
-
-
-template<typename out_eT, typename T1, typename op_type>
-inline
-mtOpCube<out_eT, T1, op_type>::mtOpCube(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c)
-  : m(in_m)
-  , aux_uword_a(in_aux_uword_a)
-  , aux_uword_b(in_aux_uword_b)
-  , aux_uword_c(in_aux_uword_c)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename out_eT, typename T1, typename op_type>
-inline
-mtOpCube<out_eT, T1, op_type>::mtOpCube(const T1& in_m, const typename T1::elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c)
-  : m(in_m)
-  , aux(in_aux)
-  , aux_uword_a(in_aux_uword_a)
-  , aux_uword_b(in_aux_uword_b)
-  , aux_uword_c(in_aux_uword_c)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename out_eT, typename T1, typename op_type>
-inline
-mtOpCube<out_eT, T1, op_type>::mtOpCube(const char junk, const T1& in_m, const out_eT in_aux)
-  : m(in_m)
-  , aux_out_eT(in_aux)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  }
-
-
-
-template<typename out_eT, typename T1, typename op_type>
-inline
-mtOpCube<out_eT, T1, op_type>::~mtOpCube()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/mtOp_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup mtOp
-//! @{
-
-
-
-template<typename out_eT, typename T1, typename op_type>
-class mtOp : public Base<out_eT, mtOp<out_eT, T1, op_type> >
-  {
-  public:
-  
-  typedef          out_eT                       elem_type;
-  typedef typename get_pod_type<out_eT>::result pod_type;
-
-  typedef typename T1::elem_type                in_eT;
-
-  inline explicit mtOp(const T1& in_m);
-  inline          mtOp(const T1& in_m, const in_eT in_aux);
-  inline          mtOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
-  inline          mtOp(const T1& in_m, const in_eT in_aux,         const uword in_aux_uword_a, const uword in_aux_uword_b);
-  
-  inline          mtOp(const char junk, const T1& in_m, const out_eT in_aux);
-  
-  inline         ~mtOp();
-    
-  
-  arma_aligned const T1&    m;            //!< storage of reference to the operand (eg. a matrix)
-  arma_aligned       in_eT  aux;          //!< storage of auxiliary data, using the element type as used by T1
-  arma_aligned       out_eT aux_out_eT;   //!< storage of auxiliary data, using the element type as specified by the out_eT template parameter
-  arma_aligned       uword  aux_uword_a;  //!< storage of auxiliary data, uword format
-  arma_aligned       uword  aux_uword_b;  //!< storage of auxiliary data, uword format
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/mtOp_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup mtOp
-//! @{
-
-
-
-template<typename out_eT, typename T1, typename op_type>
-inline
-mtOp<out_eT, T1, op_type>::mtOp(const T1& in_m)
-  : m(in_m)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename out_eT, typename T1, typename op_type>
-inline
-mtOp<out_eT, T1, op_type>::mtOp(const T1& in_m, const typename T1::elem_type in_aux)
-  : m(in_m)
-  , aux(in_aux)
-  {
-  arma_extra_debug_sigprint();
-  }
-  
-
-
-template<typename out_eT, typename T1, typename op_type>
-inline
-mtOp<out_eT, T1, op_type>::mtOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b)
-  : m(in_m)
-  , aux_uword_a(in_aux_uword_a)
-  , aux_uword_b(in_aux_uword_b)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename out_eT, typename T1, typename op_type>
-inline
-mtOp<out_eT, T1, op_type>::mtOp(const T1& in_m, const typename T1::elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b)
-  : m(in_m)
-  , aux(in_aux)
-  , aux_uword_a(in_aux_uword_a)
-  , aux_uword_b(in_aux_uword_b)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename out_eT, typename T1, typename op_type>
-inline
-mtOp<out_eT, T1, op_type>::mtOp(const char junk, const T1& in_m, const out_eT in_aux)
-  : m(in_m)
-  , aux_out_eT(in_aux)
-  {
-  arma_ignore(junk);
-  
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename out_eT, typename T1, typename op_type>
-inline
-mtOp<out_eT, T1, op_type>::~mtOp()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_chol_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_chol
-//! @{
-
-
-
-class op_chol
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_chol>& X);
-
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_chol_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_chol
-//! @{
-
-
-
-template<typename T1>
-inline
-void
-op_chol::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_chol>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool status = auxlib::chol(out, X.m);
-  
-  if(status == false)
-    {
-    out.reset();
-    arma_bad("chol(): failed to converge");
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_cor_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_cor
-//! @{
-
-
-
-class op_cor
-  {
-  public:
-  
-  template<typename eT> inline static void direct_cor(Mat<eT>&                out, const Mat<eT>& X,                const uword norm_type);
-  template<typename  T> inline static void direct_cor(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& X, const uword norm_type);
-  
-  template<typename T1> inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cor>& in);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_cor_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_cor
-//! @{
-
-
-
-template<typename eT>
-inline
-void
-op_cor::direct_cor(Mat<eT>& out, const Mat<eT>& A, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(A.is_empty())
-    {
-    out.reset();
-    return;
-    }
-  
-  if(A.is_vec())
-    {
-    out.set_size(1,1);
-    out[0] = eT(1);
-    }
-  else
-    {
-    const uword N = A.n_rows;
-    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
-
-    const Row<eT> acc = sum(A);
-    const Row<eT> sd  = stddev(A);
-
-    out = (trans(A) * A);
-    out -= (trans(acc) * acc)/eT(N);
-    out /= norm_val;
-    out /= trans(sd) * sd;
-    }
-  }
-
-
-
-template<typename T>
-inline
-void
-op_cor::direct_cor(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-
-  typedef typename std::complex<T> eT;
-
-  if(A.is_empty())
-    {
-    out.reset();
-    return;
-    }
-  
-  if(A.is_vec())
-    {
-    out.set_size(1,1);
-    out[0] = eT(1);
-    }
-  else
-    {
-    const uword N = A.n_rows;
-    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
-
-    const Row<eT> acc = sum(A);
-    const Row<T>  sd  = stddev(A);
-
-    out = trans(A) * A;               // out = strans(conj(A)) * A;
-    out -= (trans(acc) * acc)/eT(N);  // out -= (strans(conj(acc)) * acc)/eT(N);
-    out /= norm_val;
-
-    //out = out / (trans(sd) * sd);
-    out /= conv_to< Mat<eT> >::from(trans(sd) * sd);
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_cor::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cor>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> tmp(in.m, out);
-  const Mat<eT>& A     = tmp.M;
-  
-  const uword norm_type = in.aux_uword_a;
-  
-  op_cor::direct_cor(out, A, norm_type);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_cov_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_cov
-//! @{
-
-
-
-class op_cov
-  {
-  public:
-  
-  template<typename eT> inline static void direct_cov(Mat<eT>&                out, const Mat<eT>& X,                const uword norm_type);
-  template<typename  T> inline static void direct_cov(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& X, const uword norm_type);
-  
-  template<typename T1> inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cov>& in);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_cov_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_cov
-//! @{
-
-
-
-template<typename eT>
-inline
-void
-op_cov::direct_cov(Mat<eT>& out, const Mat<eT>& A, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(A.is_vec())
-    {
-    if(A.n_rows == 1)
-      {
-      out = var(trans(A), norm_type);      
-      }
-    else
-      {
-      out = var(A, norm_type);
-      }
-    }
-  else
-    {
-    const uword N = A.n_rows;
-    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
-
-    const Row<eT> acc = sum(A);
-
-    out = trans(A) * A;
-    out -= (trans(acc) * acc)/eT(N);
-    out /= norm_val;
-    }
-  }
-
-
-
-template<typename T>
-inline
-void
-op_cov::direct_cov(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T> eT;
-  
-  if(A.is_vec())
-    {
-    if(A.n_rows == 1)
-      {
-      const Mat<T> tmp_mat = var(trans(A), norm_type);
-      out.set_size(1,1);
-      out[0] = tmp_mat[0];
-      }
-    else
-      {
-      const Mat<T> tmp_mat = var(A, norm_type);
-      out.set_size(1,1);
-      out[0] = tmp_mat[0];
-      }
-    }
-  else
-    {
-    const uword N = A.n_rows;
-    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
-    
-    const Row<eT> acc = sum(A);
-    
-    out = trans(A) * A;               // out = strans(conj(A)) * A;
-    out -= (trans(acc) * acc)/eT(N);  // out -= (strans(conj(acc)) * acc)/eT(N);
-    out /= norm_val;
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_cov::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cov>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> tmp(in.m, out);
-  const Mat<eT>& A     = tmp.M;
-  
-  const uword norm_type = in.aux_uword_a;
-  
-  op_cov::direct_cov(out, A, norm_type);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_cumsum_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_cumsum
-//! @{
-
-
-
-class op_cumsum_mat
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cumsum_mat>& in);
-  };
-
-
-
-class op_cumsum_vec
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cumsum_vec>& in);
-  };
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_cumsum_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_cumsum
-//! @{
-
-
-template<typename T1>
-inline
-void
-op_cumsum_mat::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cumsum_mat>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(in.m);
-  const Mat<eT>& X = tmp.M;
-  
-  const uword dim = in.aux_uword_a;
-  arma_debug_check( (dim > 1), "cumsum(): incorrect usage. dim must be 0 or 1");
-  
-  out.copy_size(X);
-  
-  const uword X_n_rows = X.n_rows;
-  const uword X_n_cols = X.n_cols;
-  
-  if(dim == 0)
-    {
-    arma_extra_debug_print("op_cumsum::apply(), dim = 0");
-    
-    for(uword col=0; col<X_n_cols; ++col)
-      {
-            eT* out_colmem = out.colptr(col);
-      const eT* X_colmem   = X.colptr(col);
-      
-      eT acc = eT(0);
-      
-      for(uword row=0; row<X_n_rows; ++row)
-        {
-        acc += X_colmem[row];
-        
-        out_colmem[row] = acc;
-        }
-      }
-    }
-  else
-  if(dim == 1)
-    {
-    arma_extra_debug_print("op_cumsum::apply(), dim = 1");
-    
-    for(uword row=0; row<X_n_rows; ++row)
-      {
-      eT acc = eT(0);
-      
-      for(uword col=0; col<X_n_cols; ++col)
-        {
-        acc += X.at(row,col);
-        
-        out.at(row,col) = acc;
-        }
-      }
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_cumsum_vec::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cumsum_vec>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(in.m);
-  const Mat<eT>& X = tmp.M;
-  
-  const uword n_elem = X.n_elem;
-  
-  out.copy_size(X);
-  
-        eT* out_mem = out.memptr();
-  const eT* X_mem   = X.memptr();
-  
-  eT acc = eT(0);
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    acc += X_mem[i];
-    
-    out_mem[i] = acc;
-    }
-  }
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/op_cx_scalar_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_cx_scalar
-//! @{
-
-
-
-class op_cx_scalar_times
-  {
-  public:
-  
-  template<typename T1>
-  inline static void
-  apply
-    (
-          Mat< typename std::complex<typename T1::pod_type> >& out,
-    const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>& X
-    );
-  
-  template<typename T1>
-  inline static void
-  apply
-    (
-             Cube< typename std::complex<typename T1::pod_type> >& out,
-    const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>& X
-    );
-
-  };
-
-
-
-class op_cx_scalar_plus
-  {
-  public:
-  
-  template<typename T1>
-  inline static void
-  apply
-    (
-          Mat< typename std::complex<typename T1::pod_type> >& out,
-    const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>& X
-    );
-  
-  template<typename T1>
-  inline static void
-  apply
-    (
-             Cube< typename std::complex<typename T1::pod_type> >& out,
-    const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>& X
-    );
-
-  };
-
-
-
-class op_cx_scalar_minus_pre
-  {
-  public:
-  
-  template<typename T1>
-  inline static void
-  apply
-    (
-          Mat< typename std::complex<typename T1::pod_type> >& out,
-    const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>& X
-    );
-  
-  template<typename T1>
-  inline static void
-  apply
-    (
-             Cube< typename std::complex<typename T1::pod_type> >& out,
-    const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>& X
-    );
-
-  };
-
-
-
-class op_cx_scalar_minus_post
-  {
-  public:
-  
-  template<typename T1>
-  inline static void
-  apply
-    (
-          Mat< typename std::complex<typename T1::pod_type> >& out,
-    const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>& X
-    );
-  
-  template<typename T1>
-  inline static void
-  apply
-    (
-             Cube< typename std::complex<typename T1::pod_type> >& out,
-    const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>& X
-    );
-
-  };
-
-
-
-class op_cx_scalar_div_pre
-  {
-  public:
-  
-  template<typename T1>
-  inline static void
-  apply
-    (
-          Mat< typename std::complex<typename T1::pod_type> >& out,
-    const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>& X
-    );
-  
-  template<typename T1>
-  inline static void
-  apply
-    (
-             Cube< typename std::complex<typename T1::pod_type> >& out,
-    const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>& X
-    );
-
-  };
-
-
-
-class op_cx_scalar_div_post
-  {
-  public:
-  
-  template<typename T1>
-  inline static void
-  apply
-    (
-          Mat< typename std::complex<typename T1::pod_type> >& out,
-    const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>& X
-    );
-  
-  template<typename T1>
-  inline static void
-  apply
-    (
-             Cube< typename std::complex<typename T1::pod_type> >& out,
-    const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>& X
-    );
-
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_cx_scalar_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,385 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_cx_scalar
-//! @{
-
-
-
-template<typename T1>
-inline
-void
-op_cx_scalar_times::apply
-  (
-        Mat< typename std::complex<typename T1::pod_type> >& out,
-  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<typename T1::pod_type> eT;
-  typedef typename T1::pod_type                         T;
-  
-  const Proxy<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-  const eT  k       = X.aux_out_eT;
-  const uword n_elem  = out.n_elem;
-        eT* out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = A[i] * k;
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_cx_scalar_plus::apply
-  (
-        Mat< typename std::complex<typename T1::pod_type> >& out,
-  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<typename T1::pod_type> eT;
-  typedef typename T1::pod_type                         T;
-  
-  const Proxy<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-  const eT  k       = X.aux_out_eT;
-  const uword n_elem  = out.n_elem;
-        eT* out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = A[i] + k;
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_cx_scalar_minus_pre::apply
-  (
-        Mat< typename std::complex<typename T1::pod_type> >& out,
-  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<typename T1::pod_type> eT;
-  typedef typename T1::pod_type                         T;
-  
-  const Proxy<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-  const eT  k       = X.aux_out_eT;
-  const uword n_elem  = out.n_elem;
-        eT* out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = k - A[i];
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_cx_scalar_minus_post::apply
-  (
-        Mat< typename std::complex<typename T1::pod_type> >& out,
-  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<typename T1::pod_type> eT;
-  typedef typename T1::pod_type                         T;
-  
-  const Proxy<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-  const eT  k       = X.aux_out_eT;
-  const uword n_elem  = out.n_elem;
-        eT* out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = A[i] - k;
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_cx_scalar_div_pre::apply
-  (
-        Mat< typename std::complex<typename T1::pod_type> >& out,
-  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<typename T1::pod_type> eT;
-  typedef typename T1::pod_type                         T;
-  
-  const Proxy<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-  const eT  k       = X.aux_out_eT;
-  const uword n_elem  = out.n_elem;
-        eT* out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = k / A[i];
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_cx_scalar_div_post::apply
-  (
-        Mat< typename std::complex<typename T1::pod_type> >& out,
-  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<typename T1::pod_type> eT;
-  typedef typename T1::pod_type                         T;
-  
-  const Proxy<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-  const eT  k       = X.aux_out_eT;
-  const uword n_elem  = out.n_elem;
-        eT* out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = A[i] / k;
-    }
-  }
-
-
-
-//
-//
-//
-
-
-
-template<typename T1>
-inline
-void
-op_cx_scalar_times::apply
-  (
-           Cube< typename std::complex<typename T1::pod_type> >& out,
-  const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<typename T1::pod_type> eT;
-  typedef typename T1::pod_type                         T;
-  
-  const ProxyCube<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  
-  const eT  k       = X.aux_out_eT;
-  const uword n_elem  = out.n_elem;
-        eT* out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = A[i] * k;
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_cx_scalar_plus::apply
-  (
-           Cube< typename std::complex<typename T1::pod_type> >& out,
-  const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<typename T1::pod_type> eT;
-  typedef typename T1::pod_type                         T;
-  
-  const ProxyCube<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  
-  const eT  k       = X.aux_out_eT;
-  const uword n_elem  = out.n_elem;
-        eT* out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = A[i] + k;
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_cx_scalar_minus_pre::apply
-  (
-           Cube< typename std::complex<typename T1::pod_type> >& out,
-  const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<typename T1::pod_type> eT;
-  typedef typename T1::pod_type                         T;
-  
-  const ProxyCube<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  
-  const eT  k       = X.aux_out_eT;
-  const uword n_elem  = out.n_elem;
-        eT* out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = k - A[i];
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_cx_scalar_minus_post::apply
-  (
-           Cube< typename std::complex<typename T1::pod_type> >& out,
-  const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<typename T1::pod_type> eT;
-  typedef typename T1::pod_type                         T;
-  
-  const ProxyCube<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  
-  const eT  k       = X.aux_out_eT;
-  const uword n_elem  = out.n_elem;
-        eT* out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = A[i] - k;
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_cx_scalar_div_pre::apply
-  (
-           Cube< typename std::complex<typename T1::pod_type> >& out,
-  const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<typename T1::pod_type> eT;
-  typedef typename T1::pod_type                         T;
-  
-  const ProxyCube<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  
-  const eT  k       = X.aux_out_eT;
-  const uword n_elem  = out.n_elem;
-        eT* out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = k / A[i];
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_cx_scalar_div_post::apply
-  (
-           Cube< typename std::complex<typename T1::pod_type> >& out,
-  const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<typename T1::pod_type> eT;
-  typedef typename T1::pod_type                         T;
-  
-  const ProxyCube<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  
-  const eT  k       = X.aux_out_eT;
-  const uword n_elem  = out.n_elem;
-        eT* out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = A[i] / k;
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_diagmat_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_diagmat
-//! @{
-
-
-
-class op_diagmat
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_diagmat>& X);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_diagmat_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_diagmat
-//! @{
-
-
-
-template<typename T1>
-inline
-void
-op_diagmat::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagmat>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(X.m);
-  const Mat<eT>& A = tmp.M;
-  
-  if(A.is_vec() == true)
-    {
-    // generate a diagonal matrix out of a vector
-    
-    const uword N     = A.n_elem;
-    const eT* A_mem = A.memptr();
-    
-    if(&out != &A)
-      {
-      // no aliasing
-      out.zeros(N,N);
-      
-      for(uword i=0; i<N; ++i)
-        {
-        out.at(i,i) = A_mem[i];
-        }
-      }
-    else
-      {
-      // aliasing
-      
-      const podarray<eT> tmp(A_mem, N);
-      
-      const eT* tmp_mem = tmp.memptr();
-      
-      out.zeros(N,N);
-      
-      for(uword i=0; i<N; ++i)
-        {
-        out.at(i,i) = tmp_mem[i];
-        }
-      }
-    }
-  else
-    {
-    // generate a diagonal matrix out of a matrix
-    
-    arma_debug_check( (A.is_square() == false), "diagmat(): given matrix is not square" );
-    
-    const uword N = A.n_rows;
-    
-    if(&out != &A)
-      {
-      // no aliasing
-      
-      out.zeros(N,N);
-      
-      for(uword i=0; i<N; ++i)
-        {
-        out.at(i,i) = A.at(i,i);
-        }
-      }
-    else
-      {
-      // aliasing
-      
-      for(uword i=0; i<N; ++i)
-        {
-        eT* colptr = out.colptr(i);
-        
-        // clear above the diagonal
-        arrayops::inplace_set(colptr, eT(0), i);
-        
-        // clear below the diagonal
-        arrayops::inplace_set(colptr+(i+1), eT(0), N-1-i);
-        }
-      }
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_diagvec_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_diagvec
-//! @{
-
-
-
-class op_diagvec
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_diagvec>& X);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_diagvec_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_diagvec
-//! @{
-
-
-
-template<typename T1>
-inline
-void
-op_diagvec::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagvec>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const sword id = (X.aux_uword_b > 0) ? -sword(X.aux_uword_a) : sword(X.aux_uword_a);
-  
-  const unwrap_check<T1> tmp(X.m, out);
-  const Mat<eT>& A     = tmp.M;
-
-  out = A.diag(id);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_dot_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_dot
-//! @{
-
-//! \brief
-//! dot product operation 
-
-class op_dot
-  {
-  public:
-  
-  template<typename eT>
-  arma_hot arma_pure inline static eT direct_dot_arma(const uword n_elem, const eT* const A, const eT* const B);
-  
-  template<typename eT>
-  arma_hot arma_pure inline static typename arma_float_only<eT>::result
-  direct_dot(const uword n_elem, const eT* const A, const eT* const B);
-  
-  template<typename eT>
-  arma_hot arma_pure inline static typename arma_cx_only<eT>::result
-  direct_dot(const uword n_elem, const eT* const A, const eT* const B);
-  
-  template<typename eT>
-  arma_hot arma_pure inline static typename arma_integral_only<eT>::result
-  direct_dot(const uword n_elem, const eT* const A, const eT* const B);
-  
-  
-  template<typename eT>
-  arma_hot arma_pure inline static eT direct_dot(const uword n_elem, const eT* const A, const eT* const B, const eT* C);
-  
-  template<typename T1, typename T2>
-  arma_hot arma_inline static typename T1::elem_type apply(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y);
-  
-  template<typename T1, typename T2>
-  arma_hot inline static typename T1::elem_type apply_unwrap(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y);
-  
-  template<typename T1, typename T2>
-  arma_hot inline static typename T1::elem_type apply_proxy (const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y);
-  };
-
-
-
-//! \brief
-//! normalised dot product operation 
-
-class op_norm_dot
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  arma_hot inline static typename T1::elem_type apply       (const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y);
-  
-  template<typename T1, typename T2>
-  arma_hot inline static typename T1::elem_type apply_unwrap(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y);
-  };
-
-
-
-class op_cdot
-  {
-  public:
-  
-  template<typename T1, typename T2>
-  arma_hot arma_inline static typename T1::elem_type apply(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_dot_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,390 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_dot
-//! @{
-
-
-
-
-//! for two arrays, generic version
-template<typename eT>
-arma_hot
-arma_pure
-inline
-eT
-op_dot::direct_dot_arma(const uword n_elem, const eT* const A, const eT* const B)
-  {
-  arma_extra_debug_sigprint();
-  
-  eT val1 = eT(0);
-  eT val2 = eT(0);
-  
-  uword i, j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    val1 += A[i] * B[i];
-    val2 += A[j] * B[j];
-    }
-  
-  if(i < n_elem)
-    {
-    val1 += A[i] * B[i];
-    }
-  
-  return val1 + val2;
-  }
-
-
-
-//! for two arrays, float and double version
-template<typename eT>
-arma_hot
-arma_pure
-inline
-typename arma_float_only<eT>::result
-op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B)
-  {
-  arma_extra_debug_sigprint();
-  
-  if( n_elem <= (128/sizeof(eT)) )
-    {
-    return op_dot::direct_dot_arma(n_elem, A, B);
-    }
-  else
-    {
-    #if defined(ARMA_USE_ATLAS)
-      {
-      arma_extra_debug_print("atlas::cblas_dot()");
-      
-      return atlas::cblas_dot(n_elem, A, B);
-      }
-    #elif defined(ARMA_USE_BLAS)
-      {
-      arma_extra_debug_print("blas::dot()");
-      
-      return blas::dot(n_elem, A, B);
-      }
-    #else
-      {
-      return op_dot::direct_dot_arma(n_elem, A, B);
-      }
-    #endif
-    }
-  }
-
-
-
-//! for two arrays, complex version
-template<typename eT>
-inline
-arma_hot
-arma_pure
-typename arma_cx_only<eT>::result
-op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B)
-  {
-  #if defined(ARMA_USE_ATLAS)
-    {
-    arma_extra_debug_print("atlas::cx_cblas_dot()");
-    
-    return atlas::cx_cblas_dot(n_elem, A, B);
-    }
-  #elif defined(ARMA_USE_BLAS)
-    {
-    // TODO: work out the mess with zdotu() and zdotu_sub() in BLAS
-    return op_dot::direct_dot_arma(n_elem, A, B);
-    }
-  #else
-    {
-    return op_dot::direct_dot_arma(n_elem, A, B);
-    }
-  #endif
-  }
-
-
-
-//! for two arrays, integral version
-template<typename eT>
-arma_hot
-arma_pure
-inline
-typename arma_integral_only<eT>::result
-op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B)
-  {
-  return op_dot::direct_dot_arma(n_elem, A, B);
-  }
-
-
-
-
-//! for three arrays
-template<typename eT>
-arma_hot
-arma_pure
-inline
-eT
-op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B, const eT* C)
-  {
-  arma_extra_debug_sigprint();
-  
-  eT val = eT(0);
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    val += A[i] * B[i] * C[i];
-    }
-
-  return val;
-  }
-
-
-
-template<typename T1, typename T2>
-arma_hot
-arma_inline
-typename T1::elem_type
-op_dot::apply(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  if( (is_Mat<T1>::value == true) && (is_Mat<T2>::value == true) )
-    {
-    return op_dot::apply_unwrap(X,Y);
-    }
-  else
-    {
-    return op_dot::apply_proxy(X,Y);
-    }
-  }
-
-
-
-template<typename T1, typename T2>
-arma_hot
-arma_inline
-typename T1::elem_type
-op_dot::apply_unwrap(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1> tmp1(X.get_ref());
-  const unwrap<T2> tmp2(Y.get_ref());
-  
-  const Mat<eT>& A = tmp1.M;
-  const Mat<eT>& B = tmp2.M;
-  
-  arma_debug_check( (A.n_elem != B.n_elem), "dot(): objects must have the same number of elements" );
-  
-  return op_dot::direct_dot(A.n_elem, A.mem, B.mem);
-  }
-
-
-
-template<typename T1, typename T2>
-arma_hot
-inline
-typename T1::elem_type
-op_dot::apply_proxy(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type      eT;
-  typedef typename Proxy<T1>::ea_type ea_type1;
-  typedef typename Proxy<T2>::ea_type ea_type2;
-  
-  const Proxy<T1> A(X.get_ref());
-  const Proxy<T2> B(Y.get_ref());
-  
-  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor) && (Proxy<T2>::prefer_at_accessor);
-  
-  if(prefer_at_accessor == false)
-    {
-    arma_debug_check( (A.get_n_elem() != B.get_n_elem()), "dot(): objects must have the same number of elements" );
-  
-    const uword    N  = A.get_n_elem();
-          ea_type1 PA = A.get_ea();
-          ea_type2 PB = B.get_ea();
-    
-    eT val1 = eT(0);
-    eT val2 = eT(0);
-    
-    uword i,j;
-    
-    for(i=0, j=1; j<N; i+=2, j+=2)
-      {
-      val1 += PA[i] * PB[i];
-      val2 += PA[j] * PB[j];
-      }
-    
-    if(i < N)
-      {
-      val1 += PA[i] * PB[i];
-      }
-    
-    return val1 + val2;
-    }
-  else
-    {
-    return op_dot::apply_unwrap(A.Q, B.Q);
-    }
-  }
-
-
-
-//
-// op_norm_dot
-
-
-
-template<typename T1, typename T2>
-arma_hot
-inline
-typename T1::elem_type
-op_norm_dot::apply(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type      eT;
-  typedef typename Proxy<T1>::ea_type ea_type1;
-  typedef typename Proxy<T2>::ea_type ea_type2;
-  
-  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor) && (Proxy<T2>::prefer_at_accessor);
-  
-  if(prefer_at_accessor == false)
-    {
-    const Proxy<T1> A(X.get_ref());
-    const Proxy<T2> B(Y.get_ref());
-    
-    arma_debug_check( (A.get_n_elem() != B.get_n_elem()), "norm_dot(): objects must have the same number of elements" );
-    
-    const uword    N  = A.get_n_elem();
-          ea_type1 PA = A.get_ea();
-          ea_type2 PB = B.get_ea();
-    
-    eT acc1 = eT(0);
-    eT acc2 = eT(0);
-    eT acc3 = eT(0);
-    
-    for(uword i=0; i<N; ++i)
-      {
-      const eT tmpA = PA[i];
-      const eT tmpB = PB[i];
-      
-      acc1 += tmpA * tmpA;
-      acc2 += tmpB * tmpB;
-      acc3 += tmpA * tmpB;
-      }
-      
-    return acc3 / ( std::sqrt(acc1 * acc2) );
-    }
-  else
-    {
-    return op_norm_dot::apply_unwrap(X, Y);
-    }
-  }
-
-
-
-template<typename T1, typename T2>
-arma_hot
-inline
-typename T1::elem_type
-op_norm_dot::apply_unwrap(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1> tmp1(X.get_ref());
-  const unwrap<T2> tmp2(Y.get_ref());
-  
-  const Mat<eT>& A = tmp1.M;
-  const Mat<eT>& B = tmp2.M;
-  
-  
-  arma_debug_check( (A.n_elem != B.n_elem), "norm_dot(): objects must have the same number of elements" );
-  
-  const uword N = A.n_elem;
-  
-  const eT* A_mem = A.memptr();
-  const eT* B_mem = B.memptr();
-  
-  eT acc1 = eT(0);
-  eT acc2 = eT(0);
-  eT acc3 = eT(0);
-  
-  for(uword i=0; i<N; ++i)
-    {
-    const eT tmpA = A_mem[i];
-    const eT tmpB = B_mem[i];
-    
-    acc1 += tmpA * tmpA;
-    acc2 += tmpB * tmpB;
-    acc3 += tmpA * tmpB;
-    }
-    
-  return acc3 / ( std::sqrt(acc1 * acc2) );
-  }
-
-
-
-//
-// op_cdot
-
-
-
-template<typename T1, typename T2>
-arma_hot
-arma_inline
-typename T1::elem_type
-op_cdot::apply(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type      eT;
-  typedef typename Proxy<T1>::ea_type ea_type1;
-  typedef typename Proxy<T2>::ea_type ea_type2;
-  
-  const Proxy<T1> A(X.get_ref());
-  const Proxy<T2> B(Y.get_ref());
-  
-  arma_debug_check( (A.get_n_elem() != B.get_n_elem()), "cdot(): objects must have the same number of elements" );
-  
-  const uword    N  = A.get_n_elem();
-        ea_type1 PA = A.get_ea();
-        ea_type2 PB = B.get_ea();
-  
-  eT val1 = eT(0);
-  eT val2 = eT(0);
-  
-  uword i,j;
-  for(i=0, j=1; j<N; i+=2, j+=2)
-    {
-    val1 += std::conj(PA[i]) * PB[i];
-    val2 += std::conj(PA[j]) * PB[j];
-    }
-  
-  if(i < N)
-    {
-    val1 += std::conj(PA[i]) * PB[i];
-    }
-  
-  return val1 + val2;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_dotext_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_dotext
-//! @{
-
-
-
-class op_dotext
-  {
-  public:
-  
-  
-  template<typename eT>
-  inline static eT direct_rowvec_mat_colvec       (const eT* A_mem, const Mat<eT>& B, const eT* C_mem);
-  
-  template<typename eT>
-  inline static eT direct_rowvec_transmat_colvec  (const eT* A_mem, const Mat<eT>& B, const eT* C_mem);
-  
-  template<typename eT>
-  inline static eT direct_rowvec_diagmat_colvec   (const eT* A_mem, const Mat<eT>& B, const eT* C_mem);
-  
-  template<typename eT>
-  inline static eT direct_rowvec_invdiagmat_colvec(const eT* A_mem, const Mat<eT>& B, const eT* C_mem);
-  
-  template<typename eT>
-  inline static eT direct_rowvec_invdiagvec_colvec(const eT* A_mem, const Mat<eT>& B, const eT* C_mem);
-  
-  };
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/op_dotext_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_dotext
-//! @{
-
-
-
-template<typename eT>
-inline
-eT
-op_dotext::direct_rowvec_mat_colvec
-  (
-  const eT*      A_mem,
-  const Mat<eT>& B,
-  const eT*      C_mem
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword cost_AB = B.n_cols;
-  const uword cost_BC = B.n_rows;
-  
-  if(cost_AB <= cost_BC)
-    {
-    podarray<eT> tmp(B.n_cols);
-    
-    for(uword col=0; col<B.n_cols; ++col)
-      {
-      const eT* B_coldata = B.colptr(col);
-      
-      eT val = eT(0);
-      for(uword i=0; i<B.n_rows; ++i)
-        {
-        val += A_mem[i] * B_coldata[i];
-        }
-        
-      tmp[col] = val;
-      }
-    
-    return op_dot::direct_dot(B.n_cols, tmp.mem, C_mem);
-    }
-  else
-    {
-    podarray<eT> tmp(B.n_rows);
-    
-    for(uword row=0; row<B.n_rows; ++row)
-      {
-      eT val = eT(0);
-      for(uword col=0; col<B.n_cols; ++col)
-        {
-        val += B.at(row,col) * C_mem[col];
-        }
-      
-      tmp[row] = val;
-      }
-    
-    return op_dot::direct_dot(B.n_rows, A_mem, tmp.mem);
-    }
-  
-  
-  }
-
-
-
-template<typename eT>
-inline
-eT
-op_dotext::direct_rowvec_transmat_colvec
-  (
-  const eT*      A_mem,
-  const Mat<eT>& B,
-  const eT*      C_mem
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword cost_AB = B.n_rows;
-  const uword cost_BC = B.n_cols;
-  
-  if(cost_AB <= cost_BC)
-    {
-    podarray<eT> tmp(B.n_rows);
-    
-    for(uword row=0; row<B.n_rows; ++row)
-      {
-      eT val = eT(0);
-      
-      for(uword i=0; i<B.n_cols; ++i)
-        {
-        val += A_mem[i] * B.at(row,i);
-        }
-        
-      tmp[row] = val;
-      }
-    
-    return op_dot::direct_dot(B.n_rows, tmp.mem, C_mem);
-    }
-  else
-    {
-    podarray<eT> tmp(B.n_cols);
-    
-    for(uword col=0; col<B.n_cols; ++col)
-      {
-      const eT* B_coldata = B.colptr(col);
-      
-      eT val = eT(0);
-      
-      for(uword i=0; i<B.n_rows; ++i)
-        {
-        val += B_coldata[i] * C_mem[i];
-        }
-      
-      tmp[col] = val;
-      }
-    
-    return op_dot::direct_dot(B.n_cols, A_mem, tmp.mem);
-    }
-  
-  
-  }
-
-
-
-template<typename eT>
-inline
-eT
-op_dotext::direct_rowvec_diagmat_colvec
-  (
-  const eT*      A_mem,
-  const Mat<eT>& B,
-  const eT*      C_mem
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  eT val = eT(0);
-
-  for(uword i=0; i<B.n_rows; ++i)
-    {
-    val += A_mem[i] * B.at(i,i) * C_mem[i];
-    }
-
-  return val;
-  }
-
-
-
-template<typename eT>
-inline
-eT
-op_dotext::direct_rowvec_invdiagmat_colvec
-  (
-  const eT*      A_mem,
-  const Mat<eT>& B,
-  const eT*      C_mem
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  eT val = eT(0);
-
-  for(uword i=0; i<B.n_rows; ++i)
-    {
-    val += (A_mem[i] * C_mem[i]) / B.at(i,i);
-    }
-
-  return val;
-  }
-
-
-
-template<typename eT>
-inline
-eT
-op_dotext::direct_rowvec_invdiagvec_colvec
-  (
-  const eT*      A_mem,
-  const Mat<eT>& B,
-  const eT*      C_mem
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  const eT* B_mem = B.mem;
-  
-  eT val = eT(0);
-
-  for(uword i=0; i<B.n_elem; ++i)
-    {
-    val += (A_mem[i] * C_mem[i]) / B_mem[i];
-    }
-
-  return val;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_find_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// Copyright (C) 2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_find
-//! @{
-
-
-
-class op_find
-  {
-  public:
-  
-  template<typename T1>
-  inline static uword
-  helper
-    (
-    Mat<uword>& indices,
-    const Base<typename T1::elem_type, T1>& X
-    );
-  
-  template<typename T1, typename op_type>
-  inline static uword
-  helper
-    (
-    Mat<uword>& indices,
-    const mtOp<uword, T1, op_type>& X,
-    const typename arma_op_rel_only<op_type>::result junk1 = 0,
-    const typename arma_not_cx<typename T1::elem_type>::result junk2 = 0
-    );
-  
-  template<typename T1, typename op_type>
-  inline static uword
-  helper
-    (
-    Mat<uword>& indices,
-    const mtOp<uword, T1, op_type>& X,
-    const typename arma_op_rel_only<op_type>::result junk1 = 0,
-    const typename arma_cx_only<typename T1::elem_type>::result junk2 = 0
-    );
-  
-  template<typename T1, typename T2, typename glue_type>
-  inline static uword
-  helper
-    (
-    Mat<uword>& indices,
-    const mtGlue<uword, T1, T2, glue_type>& X,
-    const typename arma_glue_rel_only<glue_type>::result junk1 = 0,
-    const typename arma_not_cx<typename T1::elem_type>::result junk2 = 0,
-    const typename arma_not_cx<typename T2::elem_type>::result junk3 = 0
-    );
-  
-  template<typename T1, typename T2, typename glue_type>
-  inline static uword
-  helper
-    (
-    Mat<uword>& indices,
-    const mtGlue<uword, T1, T2, glue_type>& X,
-    const typename arma_glue_rel_only<glue_type>::result junk1 = 0,
-    const typename arma_cx_only<typename T1::elem_type>::result junk2 = 0,
-    const typename arma_cx_only<typename T2::elem_type>::result junk3 = 0
-    );
-  
-  template<typename T1>
-  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_find>& X);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_find_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,321 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// Copyright (C) 2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_find
-//! @{
-
-
-
-template<typename T1>
-inline
-uword
-op_find::helper
-  (
-  Mat<uword>& indices,
-  const Base<typename T1::elem_type, T1>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type      eT;
-  typedef typename Proxy<T1>::ea_type ea_type;
-  
-  const Proxy<T1> A(X.get_ref());
-  
-  ea_type   PA     = A.get_ea();
-  const uword n_elem = A.get_n_elem();
-  
-  indices.set_size(n_elem, 1);
-  
-  uword* indices_mem = indices.memptr();
-  uword  n_nz        = 0;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    if(PA[i] != eT(0))
-      {
-      indices_mem[n_nz] = i;
-      ++n_nz;
-      }
-    }
-   
-  return n_nz;
-  }
-
-
-
-template<typename T1, typename op_type>
-inline
-uword
-op_find::helper
-  (
-  Mat<uword>& indices,
-  const mtOp<uword, T1, op_type>& X,
-  const typename arma_op_rel_only<op_type>::result           junk1,
-  const typename arma_not_cx<typename T1::elem_type>::result junk2
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk1);
-  arma_ignore(junk2);
-  
-  typedef typename T1::elem_type      eT;
-  typedef typename Proxy<T1>::ea_type ea_type;
-  
-  const eT val = X.aux;
-  
-  const Proxy<T1> A(X.m);
-  
-  ea_type   PA     = A.get_ea();
-  const uword n_elem = A.get_n_elem();
-  
-  indices.set_size(n_elem, 1);
-  
-  uword* indices_mem = indices.memptr();
-  uword  n_nz        = 0;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    const eT tmp = PA[i];
-    
-    bool not_zero;
-    
-         if(is_same_type<op_type, op_rel_lt_pre   >::value == true)  { not_zero = (val <  tmp); }
-    else if(is_same_type<op_type, op_rel_lt_post  >::value == true)  { not_zero = (tmp <  val); }
-    else if(is_same_type<op_type, op_rel_gt_pre   >::value == true)  { not_zero = (val >  tmp); }
-    else if(is_same_type<op_type, op_rel_gt_post  >::value == true)  { not_zero = (tmp >  val); }
-    else if(is_same_type<op_type, op_rel_lteq_pre >::value == true)  { not_zero = (val <= tmp); }
-    else if(is_same_type<op_type, op_rel_lteq_post>::value == true)  { not_zero = (tmp <= val); }
-    else if(is_same_type<op_type, op_rel_gteq_pre >::value == true)  { not_zero = (val >= tmp); }
-    else if(is_same_type<op_type, op_rel_gteq_post>::value == true)  { not_zero = (tmp >= val); }
-    else if(is_same_type<op_type, op_rel_eq       >::value == true)  { not_zero = (tmp == val); }
-    else if(is_same_type<op_type, op_rel_noteq    >::value == true)  { not_zero = (tmp != val); }
-    else not_zero = false;
-    
-    if(not_zero == true)
-      {
-      indices_mem[n_nz] = i;
-      ++n_nz;
-      }
-    }
-  
-  return n_nz;
-  }
-
-
-
-template<typename T1, typename op_type>
-inline
-uword
-op_find::helper
-  (
-  Mat<uword>& indices,
-  const mtOp<uword, T1, op_type>& X,
-  const typename arma_op_rel_only<op_type>::result            junk1,
-  const typename arma_cx_only<typename T1::elem_type>::result junk2
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk1);
-  arma_ignore(junk2);
-  
-  typedef typename T1::elem_type      eT;
-  typedef typename Proxy<T1>::ea_type ea_type;
-  
-  const eT val = X.aux;
-  
-  const Proxy<T1> A(X.m);
-  
-  ea_type   PA     = A.get_ea();
-  const uword n_elem = A.get_n_elem();
-  
-  indices.set_size(n_elem, 1);
-  
-  uword* indices_mem = indices.memptr();
-  uword  n_nz        = 0;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    const eT tmp = PA[i];
-    
-    bool not_zero;
-    
-         if(is_same_type<op_type, op_rel_eq   >::value == true)  { not_zero = (tmp == val); }
-    else if(is_same_type<op_type, op_rel_noteq>::value == true)  { not_zero = (tmp != val); }
-    else not_zero = false;
-    
-    if(not_zero == true)
-      {
-      indices_mem[n_nz] = i;
-      ++n_nz;
-      }
-    }
-  
-  return n_nz;
-  }
-
-
-
-template<typename T1, typename T2, typename glue_type>
-inline
-uword
-op_find::helper
-  (
-  Mat<uword>& indices,
-  const mtGlue<uword, T1, T2, glue_type>& X,
-  const typename arma_glue_rel_only<glue_type>::result       junk1,
-  const typename arma_not_cx<typename T1::elem_type>::result junk2,
-  const typename arma_not_cx<typename T2::elem_type>::result junk3
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk1);
-  arma_ignore(junk2);
-  arma_ignore(junk3);
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename Proxy<T1>::ea_type ea_type1;
-  typedef typename Proxy<T2>::ea_type ea_type2;
-  
-  const Proxy<T1> A(X.A);
-  const Proxy<T2> B(X.B);
-  
-  arma_debug_assert_same_size(A, B, "relational operator");
-  
-  ea_type1  PA     = A.get_ea();
-  ea_type2  PB     = B.get_ea();
-  const uword n_elem = B.get_n_elem();
-  
-  indices.set_size(n_elem, 1);
-  
-  uword* indices_mem = indices.memptr();
-  uword  n_nz        = 0;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    const eT1 tmp1 = PA[i];
-    const eT2 tmp2 = PB[i];
-    
-    bool not_zero;
-    
-         if(is_same_type<glue_type, glue_rel_lt    >::value == true)  { not_zero = (tmp1 <  tmp2); }
-    else if(is_same_type<glue_type, glue_rel_gt    >::value == true)  { not_zero = (tmp1 >  tmp2); }
-    else if(is_same_type<glue_type, glue_rel_lteq  >::value == true)  { not_zero = (tmp1 <= tmp2); }
-    else if(is_same_type<glue_type, glue_rel_gteq  >::value == true)  { not_zero = (tmp1 >= tmp2); }
-    else if(is_same_type<glue_type, glue_rel_eq    >::value == true)  { not_zero = (tmp1 == tmp2); }
-    else if(is_same_type<glue_type, glue_rel_noteq >::value == true)  { not_zero = (tmp1 != tmp2); }
-    else not_zero = false;
-    
-    if(not_zero == true)
-      {
-      indices_mem[n_nz] = i;
-      ++n_nz;
-      }
-    }
-  
-  return n_nz;
-  }
-
-
-
-template<typename T1, typename T2, typename glue_type>
-inline
-uword
-op_find::helper
-  (
-  Mat<uword>& indices,
-  const mtGlue<uword, T1, T2, glue_type>& X,
-  const typename arma_glue_rel_only<glue_type>::result        junk1,
-  const typename arma_cx_only<typename T1::elem_type>::result junk2,
-  const typename arma_cx_only<typename T2::elem_type>::result junk3
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk1);
-  arma_ignore(junk2);
-  arma_ignore(junk3);
-  
-  typedef typename Proxy<T1>::ea_type ea_type1;
-  typedef typename Proxy<T2>::ea_type ea_type2;
-  
-  const Proxy<T1> A(X.A);
-  const Proxy<T2> B(X.B);
-  
-  arma_debug_assert_same_size(A, B, "relational operator");
-  
-  ea_type1  PA     = A.get_ea();
-  ea_type2  PB     = B.get_ea();
-  const uword n_elem = B.get_n_elem();
-  
-  indices.set_size(n_elem, 1);
-  
-  uword* indices_mem = indices.memptr();
-  uword  n_nz        = 0;
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    bool not_zero;
-    
-         if(is_same_type<glue_type, glue_rel_eq    >::value == true)  { not_zero = (PA[i] == PB[i]); }
-    else if(is_same_type<glue_type, glue_rel_noteq >::value == true)  { not_zero = (PA[i] != PB[i]); }
-    else not_zero = false;
-    
-    if(not_zero == true)
-      {
-      indices_mem[n_nz] = i;
-      ++n_nz;
-      }
-    }
-  
-  return n_nz;
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_find::apply(Mat<uword>& out, const mtOp<uword, T1, op_find>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword k    = X.aux_uword_a;
-  const uword type = X.aux_uword_b;
-  
-  Mat<uword> indices;
-  const uword n_nz = op_find::helper(indices, X.m);
-  
-  if(n_nz > 0)
-    {
-    if(type == 0)   // "first"
-      {
-      out = (k > 0 && k <= n_nz) ? indices.rows(0,      k-1   ) : indices.rows(0, n_nz-1);
-      }
-    else   // "last"
-      {
-      out = (k > 0 && k <= n_nz) ? indices.rows(n_nz-k, n_nz-1) : indices.rows(0, n_nz-1);
-      }
-    }
-  else
-    {
-    out.reset();
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_flip_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_flip
-//! @{
-
-
-
-class op_flipud
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_flipud>& in);
-
-  };
-
-
-
-
-class op_fliplr
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_fliplr>& in);
-
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_flip_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_flip
-//! @{
-
-
-
-template<typename T1>
-inline
-void
-op_flipud::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_flipud>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>  tmp(in.m);
-  const Mat<eT> X = tmp.M;
-  
-  if(&out != &X)
-    {
-    out.copy_size(X);
-    
-    for(uword i=0; i<X.n_rows; ++i)
-      {
-      out.row(i) = X.row(X.n_rows-1 - i);
-      }
-    }
-  else
-    {
-    const uword N = X.n_rows / 2;
-    
-    for(uword i=0; i<N; ++i)
-      {
-      out.swap_rows(i, X.n_rows-1 - i);
-      }
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_fliplr::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_fliplr>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>  tmp(in.m);
-  const Mat<eT> X = tmp.M;
-  
-  if(&out != &X)
-    {
-    out.copy_size(X);
-    
-    for(uword i=0; i<X.n_cols; ++i)
-      {
-      out.col(i) = X.col(X.n_cols-1 - i);
-      }
-    }
-  else
-    {
-    const uword N = X.n_cols / 2;
-    
-    for(uword i=0; i<N; ++i)
-      {
-      out.swap_cols(i, X.n_cols-1 - i);
-      }
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_htrans_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_htrans
-//! @{
-
-
-//! 'hermitian transpose' operation
-
-class op_htrans
-  {
-  public:
-  
-  template<typename eT>
-  arma_inline static void apply_noalias(Mat<eT>& out, const Mat<eT>& A, const typename arma_not_cx<eT>::result* junk = 0);
-  
-  template<typename eT>
-  inline static void apply_noalias(Mat<eT>& out, const Mat<eT>& A, const typename arma_cx_only<eT>::result* junk = 0);
-  
-  //
-  
-  template<typename eT>
-  arma_inline static void apply(Mat<eT>& out, const Mat<eT>& A, const typename arma_not_cx<eT>::result* junk = 0);
-  
-  template<typename eT>
-  inline static void apply(Mat<eT>& out, const Mat<eT>& A, const typename arma_cx_only<eT>::result* junk = 0);
-  
-  //
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_htrans>& in);
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op< Op<T1, op_trimat>, op_htrans>& in);
-  };
-
-
-
-class op_htrans2
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_htrans2>& in);
-  };
-
-  
-  
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_htrans_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_htrans
-//! @{
-
-
-
-template<typename eT>
-arma_inline
-void
-op_htrans::apply_noalias(Mat<eT>& out, const Mat<eT>& A, const typename arma_not_cx<eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  op_strans::apply_noalias(out, A);
-  }
-
-
-
-template<typename eT>
-inline
-void
-op_htrans::apply_noalias(Mat<eT>& out, const Mat<eT>& A, const typename arma_cx_only<eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  const uword A_n_rows = A.n_rows;
-  const uword A_n_cols = A.n_cols;
-  
-  out.set_size(A_n_cols, A_n_rows);
-  
-  for(uword in_row = 0; in_row < A_n_rows; ++in_row)
-    {
-    const uword out_col = in_row;
-  
-    for(uword in_col = 0; in_col < A_n_cols; ++in_col)
-      {
-      const uword out_row = in_col;
-      out.at(out_row, out_col) = std::conj( A.at(in_row, in_col) );
-      }
-    }
-  
-  }
-
-
-
-template<typename eT>
-arma_inline
-void
-op_htrans::apply(Mat<eT>& out, const Mat<eT>& A, const typename arma_not_cx<eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  op_strans::apply(out, A);
-  }
-
-
-
-template<typename eT>
-inline
-void
-op_htrans::apply(Mat<eT>& out, const Mat<eT>& A, const typename arma_cx_only<eT>::result* junk)
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  if(&out != &A)
-    {
-    op_htrans::apply_noalias(out, A);
-    }
-  else
-    {
-    if(out.n_rows == out.n_cols)
-      {
-      arma_extra_debug_print("doing in-place hermitian transpose of a square matrix");
-      
-      const uword n_rows = out.n_rows;
-      const uword n_cols = out.n_cols;
-      
-      for(uword col=0; col<n_cols; ++col)
-        {
-        eT* coldata = out.colptr(col);
-        
-        out.at(col,col) = std::conj( out.at(col,col) );
-        
-        for(uword row=(col+1); row<n_rows; ++row)
-          {
-          const eT val1 = std::conj(coldata[row]);
-          const eT val2 = std::conj(out.at(col,row));
-          
-          out.at(col,row) = val1;
-          coldata[row]    = val2;
-          }
-        }
-      }
-    else
-      {
-      Mat<eT> tmp;
-      op_strans::apply_noalias(tmp, A);
-      
-      out.steal_mem(tmp);
-      }
-    }
-  
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_htrans::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_htrans>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1> tmp(in.m);
-  const Mat<eT>& A = tmp.M;
-  
-  op_htrans::apply(out, A);
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_htrans::apply(Mat<typename T1::elem_type>& out, const Op< Op<T1, op_trimat>, op_htrans>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(in.m.m);
-  const Mat<eT>& A = tmp.M;
-  
-  const bool upper = in.m.aux_uword_a;
-  
-  op_trimat::apply_htrans(out, A, upper);
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_htrans2::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_htrans2>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1> tmp(in.m);
-  
-  op_htrans::apply(out, tmp.M);
-  
-  arrayops::inplace_mul( out.memptr(), in.aux, out.n_elem );
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_inv_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_inv
-//! @{
-
-
-
-//! 'invert matrix' operation (general matrices)
-class op_inv
-  {
-  public:
-  
-  template<typename eT>
-  inline static void apply(Mat<eT>& out, const Mat<eT>& A, const bool slow = false);
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv>& in);
-  
-  template<typename T1>
-  inline static void apply_diag(Mat<typename T1::elem_type>& out, const Base<typename T1::elem_type, T1>& X);
-  };
-
-
-
-//! 'invert matrix' operation (triangular matrices)
-class op_inv_tr
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv_tr>& in);
-  };
-
-
-
-//! 'invert matrix' operation (symmetric positive definite matrices)
-class op_inv_sympd
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv_sympd>& in);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_inv_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_inv
-//! @{
-
-
-//! immediate inverse of a matrix, storing the result in a dense matrix
-template<typename eT>
-inline
-void
-op_inv::apply(Mat<eT>& out, const Mat<eT>& A, const bool slow)
-  {
-  arma_extra_debug_sigprint();
-  
-  // no need to check for aliasing, due to:
-  // - auxlib::inv() copies A to out before inversion
-  // - for 2x2 and 3x3 matrices the code is alias safe
-  
-  bool status = auxlib::inv(out, A, slow);
-  
-  if(status == false)
-    {
-    out.reset();
-    arma_bad("inv(): matrix appears to be singular");
-    }
-  }
-
-
-
-//! immediate inverse of T1, storing the result in a dense matrix
-template<typename T1>
-inline
-void
-op_inv::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const strip_diagmat<T1> strip(X.m);
-  
-  if(strip.do_diagmat == true)
-    {
-    op_inv::apply_diag(out, strip.M);
-    }
-  else
-    {
-    const uword mode = X.aux_uword_a;
-    
-    const bool status = (mode == 0) ? auxlib::inv(out, X.m) : auxlib::inv(out, X.m, true);
-    
-    if(status == false)
-      {
-      out.reset();
-      arma_bad("inv(): matrix appears to be singular");
-      }
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_inv::apply_diag(Mat<typename T1::elem_type>& out, const Base<typename T1::elem_type, T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const diagmat_proxy_check<T1> A(X.get_ref(), out);
-  
-  const uword N = A.n_elem;
-  
-  out.set_size(N,N);
-  
-  for(uword col=0; col<N; ++col)
-    {
-    for(uword row=0; row<col; ++row)   { out.at(row,col) = eT(0); }
-    
-    out.at(col,col) = eT(1) / A[col];
-    
-    for(uword row=col+1; row<N; ++row) { out.at(row,col) = eT(0); }
-    }
-  
-  }
-
-
-
-//! inverse of T1 (triangular matrices)
-template<typename T1>
-inline
-void
-op_inv_tr::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv_tr>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool status = auxlib::inv_tr(out, X.m, X.aux_uword_a);
-  
-  if(status == false)
-    {
-    out.reset();
-    arma_bad("inv(): matrix appears to be singular");
-    }
-  }
-
-
-
-//! inverse of T1 (symmetric positive definite matrices)
-template<typename T1>
-inline
-void
-op_inv_sympd::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv_sympd>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool status = auxlib::inv_sympd(out, X.m, X.aux_uword_a);
-  
-  if(status == false)
-    {
-    out.reset();
-    arma_bad("inv(): matrix appears to be singular");
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_max_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_max
-//! @{
-
-
-
-//! Class for finding maximum values in a matrix
-class op_max
-  {
-  public:
-  
-  template<typename eT>
-  inline static eT direct_max(const eT* const X, const uword N);
-  
-  template<typename eT>
-  inline static eT direct_max(const eT* const X, const uword N, uword& index_of_max_val);
-  
-  template<typename eT>
-  inline static eT direct_max(const Mat<eT>& X, const uword row);
-  
-  template<typename eT>
-  inline static eT direct_max(const subview<eT>& X);
-  
-  template<typename eT>
-  inline static eT direct_max(const diagview<eT>& X);
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_max>& in);
-  
-  
-  //
-  // for complex numbers
-  
-  template<typename T>
-  inline static std::complex<T> direct_max(const std::complex<T>* const X, const uword n_elem);
-  
-  template<typename T>
-  inline static std::complex<T> direct_max(const std::complex<T>* const X, const uword n_elem, uword& index_of_max_val);
-  
-  template<typename T>
-  inline static std::complex<T> direct_max(const Mat< std::complex<T> >& X, const uword row);
-  
-  template<typename T>
-  inline static std::complex<T> direct_max(const subview< std::complex<T> >& X);
-  
-  template<typename T>
-  inline static std::complex<T> direct_max(const diagview< std::complex<T> >& X);
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_max_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,386 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_max
-//! @{
-
-
-
-template<typename eT>
-arma_pure
-inline
-eT
-op_max::direct_max(const eT* const X, const uword n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  eT max_val = priv::most_neg<eT>();
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    const eT X_i = X[i];
-    const eT X_j = X[j];
-    
-    if(X_i > max_val)
-      {
-      max_val = X_i;
-      }
-    
-    if(X_j > max_val)
-      {
-      max_val = X_j;
-      }
-    }
-  
-  
-  if(i < n_elem)
-    {
-    const eT X_i = X[i];
-    
-    if(X_i > max_val)
-      {
-      max_val = X_i;
-      }
-    }
-  
-  return max_val;
-  }
-
-
-
-template<typename eT>
-inline
-eT
-op_max::direct_max(const eT* const X, const uword n_elem, uword& index_of_max_val)
-  {
-  arma_extra_debug_sigprint();
-  
-  eT max_val = priv::most_neg<eT>();
-  
-  uword best_index = 0;
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    const eT X_i = X[i];
-    const eT X_j = X[j];
-    
-    if(X_i > max_val)
-      {
-      max_val    = X_i;
-      best_index = i;
-      }
-    
-    if(X_j > max_val)
-      {
-      max_val    = X_j;
-      best_index = j;
-      }
-    }
-  
-  
-  if(i < n_elem)
-    {
-    const eT X_i = X[i];
-    
-    if(X_i > max_val)
-      {
-      max_val    = X_i;
-      best_index = i;
-      }
-    }
-  
-  index_of_max_val = best_index;
-  
-  return max_val;
-  }
-
-
-
-template<typename eT>
-inline
-eT
-op_max::direct_max(const Mat<eT>& X, const uword row)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_cols = X.n_cols;
-  
-  eT max_val = priv::most_neg<eT>();
-  
-  for(uword col=0; col<X_n_cols; ++col)
-    {
-    const eT tmp_val = X.at(row,col);
-    
-    if(tmp_val > max_val)
-      {
-      max_val = tmp_val;
-      }
-    }
-  
-  return max_val;
-  }
-
-
-
-template<typename eT>
-inline
-eT
-op_max::direct_max(const subview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_elem = X.n_elem;
-  
-  eT max_val = priv::most_neg<eT>();
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    eT tmp_val = X[i];
-    
-    if(tmp_val > max_val)
-      {
-      max_val = tmp_val;
-      }
-    }
-  
-  return max_val;
-  }
-
-
-
-template<typename eT>
-inline
-eT
-op_max::direct_max(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_elem = X.n_elem;
-  
-  eT max_val = priv::most_neg<eT>();
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    eT tmp_val = X[i];
-    
-    if(tmp_val > max_val)
-      {
-      max_val = tmp_val;
-      }
-    }
-  
-  return max_val;
-  }
-
-
-
-//! \brief
-//! For each row or for each column, find the maximum value.
-//! The result is stored in a dense matrix that has either one column or one row.
-//! The dimension, for which the maxima are found, is set via the max() function.
-template<typename T1>
-inline
-void
-op_max::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_max>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> tmp(in.m, out);
-  const Mat<eT>& X     = tmp.M;
-  
-  const uword dim = in.aux_uword_a;
-  arma_debug_check( (dim > 1), "max(): incorrect usage. dim must be 0 or 1");
-  
-  const uword X_n_rows = X.n_rows;
-  const uword X_n_cols = X.n_cols;
-  
-  if(dim == 0)
-    {
-    arma_extra_debug_print("op_max::apply(), dim = 0");
-    
-    arma_debug_check( (X_n_rows == 0), "max(): given object has zero rows" );
-
-    out.set_size(1, X_n_cols);
-    
-    eT* out_mem = out.memptr();
-    
-    for(uword col=0; col<X_n_cols; ++col)
-      {
-      out_mem[col] = op_max::direct_max( X.colptr(col), X_n_rows );
-      }
-    }
-  else
-  if(dim == 1)
-    {
-    arma_extra_debug_print("op_max::apply(), dim = 1");
-    
-    arma_debug_check( (X_n_cols == 0), "max(): given object has zero columns" );
-
-    out.set_size(X_n_rows, 1);
-    
-    eT* out_mem = out.memptr();
-    
-    for(uword row=0; row<X_n_rows; ++row)
-      {
-      out_mem[row] = op_max::direct_max( X, row );
-      }
-    }
-  }
-
-
-
-template<typename T>
-inline
-std::complex<T>
-op_max::direct_max(const std::complex<T>* const X, const uword n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  uword index   = 0;
-  T   max_val = priv::most_neg<T>();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    const T tmp_val = std::abs(X[i]);
-    
-    if(tmp_val > max_val)
-      {
-      max_val = tmp_val;
-      index   = i;
-      }
-    }
-  
-  return X[index];
-  }
-
-
-
-template<typename T>
-inline
-std::complex<T>
-op_max::direct_max(const std::complex<T>* const X, const uword n_elem, uword& index_of_max_val)
-  {
-  arma_extra_debug_sigprint();
-  
-  uword index   = 0;
-  T   max_val = priv::most_neg<T>();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    const T tmp_val = std::abs(X[i]);
-    
-    if(tmp_val > max_val)
-      {
-      max_val = tmp_val;
-      index   = i;
-      }
-    }
-  
-  index_of_max_val = index;
-  
-  return X[index];
-  }
-
-
-
-template<typename T>
-inline 
-std::complex<T>
-op_max::direct_max(const Mat< std::complex<T> >& X, const uword row)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_cols = X.n_cols;
-  
-  uword index   = 0;
-  T   max_val = priv::most_neg<T>();
-  
-  for(uword col=0; col<X_n_cols; ++col)
-    {
-    const T tmp_val = std::abs(X.at(row,col));
-    
-    if(tmp_val > max_val)
-      {
-      max_val = tmp_val;
-      index   = col;
-      }
-    }
-  
-  return X.at(row,index);
-  }
-
-
-
-template<typename T>
-inline
-std::complex<T>
-op_max::direct_max(const subview< std::complex<T> >& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_elem = X.n_elem;
-  
-  uword index   = 0;
-  T   max_val = priv::most_neg<T>();
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    const T tmp_val = std::abs(X[i]);
-    
-    if(tmp_val > max_val)
-      {
-      max_val = tmp_val;
-      index   = i;
-      }
-    }
-  
-  return X[index];
-  }
-
-
-
-template<typename T>
-inline 
-std::complex<T>
-op_max::direct_max(const diagview< std::complex<T> >& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_elem = X.n_elem;
-  
-  uword index   = 0;
-  T   max_val = priv::most_neg<T>();
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    const T tmp_val = std::abs(X[i]);
-    
-    if(tmp_val > max_val)
-      {
-      max_val = tmp_val;
-      index   = i;
-      }
-    }
-  
-  return X[index];
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_mean_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_mean
-//! @{
-
-
-//! Class for finding mean values of a matrix
-class op_mean
-  {
-  public:
-  
-  template<typename eT>
-  inline static eT direct_mean(const eT* const X, const uword N);
-  
-  template<typename eT>
-  inline static eT direct_mean(const Mat<eT>& X, const uword row);
-  
-  template<typename eT>
-  inline static eT direct_mean(const subview<eT>& X);
-  
-  template<typename eT>
-  inline static eT direct_mean(const diagview<eT>& X);
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_mean>& in);
-  
-  
-  template<typename eT>
-  inline static eT direct_mean_robust(const eT* const X, const uword N);
-  
-  template<typename eT>
-  inline static eT direct_mean_robust(const Mat<eT>& X, const uword row);
-  
-  template<typename eT>
-  inline static eT direct_mean_robust(const subview<eT>& X);
-  
-  template<typename eT>
-  inline static eT direct_mean_robust(const diagview<eT>& X);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_mean_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,279 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_mean
-//! @{
-
-
-
-template<typename eT>
-arma_pure
-inline
-eT
-op_mean::direct_mean(const eT* const X, const uword n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename get_pod_type<eT>::result T;
-  
-  const eT result = arrayops::accumulate(X, n_elem) / T(n_elem);
-  
-  return arma_isfinite(result) ? result : op_mean::direct_mean_robust(X, n_elem);
-  }
-
-
-
-template<typename eT>
-inline
-eT
-op_mean::direct_mean(const Mat<eT>& X, const uword row)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename get_pod_type<eT>::result T;
-  
-  const uword X_n_cols = X.n_cols;
-  
-  eT val = eT(0);
-  
-  for(uword col=0; col<X_n_cols; ++col)
-    {
-    val += X.at(row,col);
-    }
-  
-  const eT result = val / T(X_n_cols);
-  
-  return arma_isfinite(result) ? result : direct_mean_robust(X, row);
-  }
-
-
-
-template<typename eT>
-inline 
-eT
-op_mean::direct_mean(const subview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename get_pod_type<eT>::result T;
-  
-  const uword X_n_elem = X.n_elem;
-  
-  eT val = eT(0);
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    val += X[i];
-    }
-  
-  const eT result = val / T(X_n_elem);
-  
-  return arma_isfinite(result) ? result : direct_mean_robust(X);
-  }
-
-
-
-template<typename eT>
-inline 
-eT
-op_mean::direct_mean(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename get_pod_type<eT>::result T;
-  
-  const uword X_n_elem = X.n_elem;
-  
-  eT val = eT(0);
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    val += X[i];
-    }
-  
-  const eT result = val / T(X_n_elem);
-  
-  return arma_isfinite(result) ? result : direct_mean_robust(X);
-  }
-
-
-
-//! \brief
-//! For each row or for each column, find the mean value.
-//! The result is stored in a dense matrix that has either one column or one row.
-//! The dimension, for which the means are found, is set via the mean() function.
-template<typename T1>
-inline
-void
-op_mean::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_mean>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type            eT;
-  typedef typename get_pod_type<eT>::result  T;
-  
-  const unwrap_check<T1> tmp(in.m, out);
-  const Mat<eT>& X = tmp.M;
-  
-  const uword dim = in.aux_uword_a;
-  arma_debug_check( (dim > 1), "mean(): incorrect usage. dim must be 0 or 1");
-  
-  const uword X_n_rows = X.n_rows;
-  const uword X_n_cols = X.n_cols;
-  
-  if(dim == 0)
-    {
-    arma_extra_debug_print("op_mean::apply(), dim = 0");
-    
-    out.set_size( (X_n_rows > 0) ? 1 : 0, X_n_cols );
-    
-    if(X_n_rows > 0)
-      {
-      eT* out_mem = out.memptr();
-      
-      for(uword col=0; col<X_n_cols; ++col)
-        {
-        out_mem[col] = op_mean::direct_mean( X.colptr(col), X_n_rows );
-        }
-      }
-    }
-  else
-  if(dim == 1)
-    {
-    arma_extra_debug_print("op_mean::apply(), dim = 1");
-    
-    out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0);
-    
-    if(X_n_cols > 0)
-      {
-      eT* out_mem = out.memptr();
-      
-      for(uword row=0; row<X_n_rows; ++row)
-        {
-        out_mem[row] = op_mean::direct_mean( X, row );
-        }
-      }
-    }
-  }
-
-
-
-template<typename eT>
-arma_pure
-inline
-eT
-op_mean::direct_mean_robust(const eT* const X, const uword n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  // use an adapted form of the mean finding algorithm from the running_stat class
-  
-  typedef typename get_pod_type<eT>::result T;
-  
-  uword i,j;
-  
-  eT r_mean = eT(0);
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    const eT Xi = X[i];
-    const eT Xj = X[j];
-    
-    r_mean = r_mean + (Xi - r_mean)/T(j);    // we need i+1, and j is equivalent to i+1 here
-    r_mean = r_mean + (Xj - r_mean)/T(j+1);
-    }
-  
-  
-  if(i < n_elem)
-    {
-    const eT Xi = X[i];
-    
-    r_mean = r_mean + (Xi - r_mean)/T(i+1);
-    }
-  
-  return r_mean;
-  }
-
-
-
-template<typename eT>
-inline
-eT
-op_mean::direct_mean_robust(const Mat<eT>& X, const uword row)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename get_pod_type<eT>::result T;
-  
-  const uword X_n_cols = X.n_cols;
-  
-  eT r_mean = eT(0);
-  
-  for(uword col=0; col<X_n_cols; ++col)
-    {
-    r_mean = r_mean + (X.at(row,col) - r_mean)/T(col+1);
-    }
-  
-  return r_mean;
-  }
-
-
-
-template<typename eT>
-inline 
-eT
-op_mean::direct_mean_robust(const subview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename get_pod_type<eT>::result T;
-  
-  const uword X_n_elem = X.n_elem;
-  
-  eT r_mean = eT(0);
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    r_mean = r_mean + (X[i] - r_mean)/T(i+1);
-    }
-  
-  return r_mean;
-  }
-
-
-
-template<typename eT>
-inline 
-eT
-op_mean::direct_mean_robust(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename get_pod_type<eT>::result T;
-  
-  const uword X_n_elem = X.n_elem;
-  
-  eT r_mean = eT(0);
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    r_mean = r_mean + (X[i] - r_mean)/T(i+1);
-    }
-  
-  return r_mean;
-  }
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/op_median_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_median
-//! @{
-
-
-template<typename T>
-struct arma_cx_median_packet
-  {
-  T   val;
-  uword index;
-  };
-
-
-
-template<typename T>
-inline
-bool
-operator< (const arma_cx_median_packet<T>& A, const arma_cx_median_packet<T>& B)
-  {
-  return A.val < B.val;
-  }
-
-
-
-//! Class for finding median values of a matrix
-class op_median
-  {
-  public:
-  
-  template<typename eT>
-  arma_inline static eT robust_mean(const eT A, const eT B);
-  
-  template<typename eT>
-  inline static eT direct_median(std::vector<eT>& X);
-  
-  template<typename eT>
-  inline static eT direct_median(const eT* X, const uword n_elem);
-  
-  template<typename eT>
-  inline static eT direct_median(const subview<eT>& X);
-  
-  template<typename eT>
-  inline static eT direct_median(const diagview<eT>& X);
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& in);
-  
-  
-  //
-  // for complex numbers
-  
-  template<typename T>
-  arma_inline static std::complex<T> robust_mean(const std::complex<T>& A, const std::complex<T>& B);
-  
-  template<typename T>
-  inline static void direct_cx_median_index(uword& out_index1, uword& out_index2, std::vector< arma_cx_median_packet<T> >& X);
-  
-  template<typename T>
-  inline static void direct_cx_median_index(uword& out_index1, uword& out_index2, const std::complex<T>* X, const uword n_elem);
-  
-  template<typename T>
-  inline static void direct_cx_median_index(uword& out_index1, uword& out_index2, const subview< std::complex<T> >& X);
-  
-  template<typename T>
-  inline static void direct_cx_median_index(uword& out_index1, uword& out_index2, const diagview< std::complex<T> >& X);
-  
-  template<typename T, typename T1>
-  inline static void apply(Mat< std::complex<T> >& out, const Op<T1,op_median>& in);
-  
-  
-  };
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_median_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,379 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_median
-//! @{
-
-
-
-template<typename eT>
-arma_inline
-eT
-op_median::robust_mean(const eT A, const eT B)
-  {
-  return A + (B - A)/eT(2);
-  }
-
-
-
-//! find the median value of a std::vector (contents is modified)
-template<typename eT>
-inline 
-eT
-op_median::direct_median(std::vector<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword n_elem = X.size();
-  const uword half   = n_elem/2;
-  
-  std::sort(X.begin(), X.end());
-  
-  if((n_elem % 2) == 0)
-    {
-    return op_median::robust_mean(X[half-1], X[half]);
-    }
-  else
-    {
-    return X[half];
-    }
-  }
-
-
-
-template<typename eT>
-inline 
-eT
-op_median::direct_median(const eT* X, const uword n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  std::vector<eT> tmp(X, X+n_elem);
-  
-  return op_median::direct_median(tmp);
-  }
-
-
-
-template<typename eT>
-inline 
-eT
-op_median::direct_median(const subview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_elem = X.n_elem;
-  
-  std::vector<eT> tmp(X_n_elem);
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    tmp[i] = X[i];
-    }
-  
-  return op_median::direct_median(tmp);
-  }
-
-
-
-template<typename eT>
-inline 
-eT
-op_median::direct_median(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_elem = X.n_elem;
-  
-  std::vector<eT> tmp(X_n_elem);
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    tmp[i] = X[i];
-    }
-  
-  return op_median::direct_median(tmp);
-  }
-
-
-
-//! \brief
-//! For each row or for each column, find the median value.
-//! The result is stored in a dense matrix that has either one column or one row.
-//! The dimension, for which the medians are found, is set via the median() function.
-template<typename T1>
-inline
-void
-op_median::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> tmp(in.m, out);
-  const Mat<eT>&     X = tmp.M;
-  
-  const uword X_n_rows = X.n_rows;
-  const uword X_n_cols = X.n_cols;
-  
-  const uword dim = in.aux_uword_a;
-  arma_debug_check( (dim > 1), "median(): incorrect usage. dim must be 0 or 1");
-  
-  if(dim == 0)  // in each column
-    {
-    arma_extra_debug_print("op_median::apply(), dim = 0");
-    
-    arma_debug_check( (X_n_rows == 0), "median(): given object has zero rows" );
-
-    out.set_size(1, X_n_cols);
-    
-    std::vector<eT> tmp_vec(X_n_rows);
-      
-    for(uword col=0; col<X_n_cols; ++col)
-      {
-      const eT* colmem = X.colptr(col);
-      
-      for(uword row=0; row<X_n_rows; ++row)
-        {
-        tmp_vec[row] = colmem[row];
-        }
-      
-      out[col] = op_median::direct_median(tmp_vec);
-      }
-    }
-  else
-  if(dim == 1)  // in each row
-    {
-    arma_extra_debug_print("op_median::apply(), dim = 1");
-    
-    arma_debug_check( (X_n_cols == 0), "median(): given object has zero columns" );
-
-    out.set_size(X_n_rows, 1);
-    
-    std::vector<eT> tmp_vec(X_n_cols);
-      
-    for(uword row=0; row<X_n_rows; ++row)
-      {
-      for(uword col=0; col<X_n_cols; ++col)
-        {
-        tmp_vec[col] = X.at(row,col);
-        }
-      
-      out[row] =  op_median::direct_median(tmp_vec);
-      }
-    }
-  }
-
-
-
-template<typename T>
-arma_inline
-std::complex<T>
-op_median::robust_mean(const std::complex<T>& A, const std::complex<T>& B)
-  {
-  return A + (B - A)/T(2);
-  }
-
-
-
-template<typename T>
-inline 
-void
-op_median::direct_cx_median_index
-  (
-  uword& out_index1, 
-  uword& out_index2, 
-  std::vector< arma_cx_median_packet<T> >& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword n_elem = X.size();
-  const uword half   = n_elem/2;
-  
-  std::sort(X.begin(), X.end());
-  
-  if((n_elem % 2) == 0)
-    {
-    out_index1 = X[half-1].index;
-    out_index2 = X[half  ].index;
-    }
-  else
-    {
-    out_index1 = X[half].index;
-    out_index2 = out_index1;
-    }
-  }
-
-
-
-template<typename T>
-inline 
-void
-op_median::direct_cx_median_index
-  (
-  uword& out_index1, 
-  uword& out_index2, 
-  const std::complex<T>* X, 
-  const uword n_elem
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  std::vector< arma_cx_median_packet<T> > tmp(n_elem);
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    tmp[i].val   = std::abs(X[i]);
-    tmp[i].index = i;
-    }
-  
-  op_median::direct_cx_median_index(out_index1, out_index2, tmp);
-  }
-
-
-
-template<typename T>
-inline 
-void
-op_median::direct_cx_median_index
-  (
-  uword& out_index1, 
-  uword& out_index2, 
-  const subview< std::complex<T> >&X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword n_elem = X.n_elem;
-  
-  std::vector< arma_cx_median_packet<T> > tmp(n_elem);
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    tmp[i].val   = std::abs(X[i]);
-    tmp[i].index = i;
-    }
-  
-  op_median::direct_cx_median_index(out_index1, out_index2, tmp);
-  }
-
-
-
-template<typename T>
-inline 
-void
-op_median::direct_cx_median_index
-  (
-  uword& out_index1, 
-  uword& out_index2, 
-  const diagview< std::complex<T> >&X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword n_elem = X.n_elem;
-  
-  std::vector< arma_cx_median_packet<T> > tmp(n_elem);
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    tmp[i].val   = std::abs(X[i]);
-    tmp[i].index = i;
-    }
-  
-  op_median::direct_cx_median_index(out_index1, out_index2, tmp);
-  }
-
-
-
-//! Implementation for complex numbers
-template<typename T, typename T1>
-inline
-void
-op_median::apply(Mat< std::complex<T> >& out, const Op<T1,op_median>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T> eT;
-  
-  arma_type_check(( is_same_type<eT, typename T1::elem_type>::value == false ));
-  
-  const unwrap_check<T1> tmp(in.m, out);
-  const Mat<eT>&     X = tmp.M;
-  
-  const uword X_n_rows = X.n_rows;
-  const uword X_n_cols = X.n_cols;
-  
-  const uword dim = in.aux_uword_a;
-  arma_debug_check( (dim > 1), "median(): incorrect usage. dim must be 0 or 1");
-  
-  if(dim == 0)  // in each column
-    {
-    arma_extra_debug_print("op_median::apply(), dim = 0");
-    
-    arma_debug_check( (X_n_rows == 0), "median(): given object has zero rows" );
-
-    out.set_size(1, X_n_cols);
-    
-    std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_rows);
-    
-    for(uword col=0; col<X_n_cols; ++col)
-      {
-      const eT* colmem = X.colptr(col);
-      
-      for(uword row=0; row<X_n_rows; ++row)
-        {
-        tmp_vec[row].val   = std::abs(colmem[row]);
-        tmp_vec[row].index = row;
-        }
-      
-      uword index1;
-      uword index2;
-      op_median::direct_cx_median_index(index1, index2, tmp_vec);
-        
-      out[col] = op_median::robust_mean(colmem[index1], colmem[index2]);
-      }
-    }
-  else
-  if(dim == 1)  // in each row
-    {
-    arma_extra_debug_print("op_median::apply(), dim = 1");
-    
-    arma_debug_check( (X_n_cols == 0), "median(): given object has zero columns" );
-
-    out.set_size(X_n_rows, 1);
-    
-    std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_cols);
-    
-    for(uword row=0; row<X_n_rows; ++row)
-      {
-      for(uword col=0; col<X_n_cols; ++col)
-        {
-        tmp_vec[col].val   = std::abs(X.at(row,col));
-        tmp_vec[row].index = col;
-        }
-      
-      uword index1;
-      uword index2;
-      op_median::direct_cx_median_index(index1, index2, tmp_vec);
-      
-      out[row] = op_median::robust_mean( X.at(row,index1), X.at(row,index2) );
-      }
-    }
-  }
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/op_min_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_min
-//! @{
-
-
-//! Class for finding minimum values in a matrix
-class op_min
-  {
-  public:
-  
-  template<typename eT>
-  inline static eT direct_min(const eT* const X, const uword N);
-  
-  template<typename eT>
-  inline static eT direct_min(const eT* const X, const uword N, uword& index_of_min_val);
-  
-  template<typename eT>
-  inline static eT direct_min(const Mat<eT>& X, const uword row);
-  
-  template<typename eT>
-  inline static eT direct_min(const subview<eT>& X);
-  
-  template<typename eT>
-  inline static eT direct_min(const diagview<eT>& X);
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_min>& in);
-  
-  
-  //
-  // for complex numbers
-  
-  template<typename T>
-  inline static std::complex<T> direct_min(const std::complex<T>* const X, const uword n_elem);
-  
-  template<typename T>
-  inline static std::complex<T> direct_min(const std::complex<T>* const X, const uword n_elem, uword& index_of_min_val);
-  
-  template<typename T>
-  inline static std::complex<T> direct_min(const Mat< std::complex<T> >& X, const uword row);
-  
-  template<typename T>
-  inline static std::complex<T> direct_min(const subview< std::complex<T> >&X);
-  
-  template<typename T>
-  inline static std::complex<T> direct_min(const diagview< std::complex<T> >&X);
-  
-  };
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_min_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,382 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_min
-//! @{
-
-
-
-template<typename eT>
-arma_pure
-inline 
-eT
-op_min::direct_min(const eT* const X, const uword n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  eT min_val = priv::most_pos<eT>();
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    const eT X_i = X[i];
-    const eT X_j = X[j];
-    
-    if(X_i < min_val)
-      {
-      min_val = X_i;
-      }
-    
-    if(X_j < min_val)
-      {
-      min_val = X_j;
-      }
-    }
-  
-  
-  if(i < n_elem)
-    {
-    const eT X_i = X[i];
-    
-    if(X_i < min_val)
-      {
-      min_val = X_i;
-      }
-    }
-  
-  return min_val;
-  }
-
-
-
-template<typename eT>
-inline 
-eT
-op_min::direct_min(const eT* const X, const uword n_elem, uword& index_of_min_val)
-  {
-  arma_extra_debug_sigprint();
-  
-  eT min_val = priv::most_pos<eT>();
-  
-  uword best_index = 0;
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<n_elem; i+=2, j+=2)
-    {
-    const eT X_i = X[i];
-    const eT X_j = X[j];
-    
-    if(X_i < min_val)
-      {
-      min_val    = X_i;
-      best_index = i;
-      }
-    
-    if(X_j < min_val)
-      {
-      min_val    = X_j;
-      best_index = j;
-      }
-    }
-  
-  
-  if(i < n_elem)
-    {
-    const eT X_i = X[i];
-    
-    if(X_i < min_val)
-      {
-      min_val    = X_i;
-      best_index = i;
-      }
-    }
-  
-  index_of_min_val = best_index;
-  
-  return min_val;
-  }  
-
-
-
-template<typename eT>
-inline 
-eT
-op_min::direct_min(const Mat<eT>& X, const uword row)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_cols = X.n_cols;
-  
-  eT min_val = priv::most_pos<eT>();
-  
-  for(uword col=0; col<X_n_cols; ++col)
-    {
-    const eT tmp_val = X.at(row,col);
-    
-    if(tmp_val < min_val)
-      {
-      min_val = tmp_val;
-      }
-    }
-  
-  return min_val;
-  }
-
-
-
-template<typename eT>
-inline 
-eT
-op_min::direct_min(const subview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_elem = X.n_elem;
-  
-  eT min_val = priv::most_pos<eT>();
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    eT tmp_val = X[i];
-    
-    if(tmp_val < min_val)
-      {
-      min_val = tmp_val;
-      }
-    }
-  
-  return min_val;
-  }
-
-
-
-template<typename eT>
-inline 
-eT
-op_min::direct_min(const diagview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_elem = X.n_elem;
-  
-  eT min_val = priv::most_pos<eT>();;
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    eT tmp_val = X[i];
-    
-    if(tmp_val < min_val)
-      {
-      min_val = tmp_val;
-      }
-    }
-  
-  return min_val;
-  }
-
-
-
-//! \brief
-//! For each row or for each column, find the minimum value.
-//! The result is stored in a dense matrix that has either one column or one row.
-//! The dimension, for which the minima are found, is set via the min() function.
-template<typename T1>
-inline void op_min::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_min>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> tmp(in.m, out);
-  const Mat<eT>&     X = tmp.M;
-  
-  const uword dim = in.aux_uword_a;
-  arma_debug_check( (dim > 1), "min(): incorrect usage. dim must be 0 or 1");
-  
-  const uword X_n_rows = X.n_rows;
-  const uword X_n_cols = X.n_cols;
-  
-  if(dim == 0)  // min in each column
-    {
-    arma_extra_debug_print("op_min::apply(), dim = 0");
-    
-    arma_debug_check( (X_n_rows == 0), "min(): given object has zero rows" );
-
-    out.set_size(1, X_n_cols);
-    
-    eT* out_mem = out.memptr();
-    
-    for(uword col=0; col<X_n_cols; ++col)
-      {
-      out_mem[col] = op_min::direct_min( X.colptr(col), X_n_rows );
-      }
-    }
-  else
-  if(dim == 1)  // min in each row
-    {
-    arma_extra_debug_print("op_min::apply(), dim = 1");
-    
-    arma_debug_check( (X_n_cols == 0), "min(): given object has zero columns" );
-
-    out.set_size(X_n_rows, 1);
-    
-    eT* out_mem = out.memptr();
-    
-    for(uword row=0; row<X_n_rows; ++row)
-      {
-      out_mem[row] = op_min::direct_min( X, row );
-      }
-    }
-  }
-
-
-
-template<typename T>
-inline 
-std::complex<T>
-op_min::direct_min(const std::complex<T>* const X, const uword n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  uword index   = 0;
-  T   min_val = priv::most_pos<T>();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    const T tmp_val = std::abs(X[i]);
-    
-    if(tmp_val < min_val)
-      {
-      min_val = tmp_val;
-      index   = i;
-      }
-    }
-  
-  return X[index];
-  }
-
-
-
-template<typename T>
-inline 
-std::complex<T>
-op_min::direct_min(const std::complex<T>* const X, const uword n_elem, uword& index_of_min_val)
-  {
-  arma_extra_debug_sigprint();
-  
-  uword index   = 0;
-  T   min_val = priv::most_pos<T>();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    const T tmp_val = std::abs(X[i]);
-    
-    if(tmp_val < min_val)
-      {
-      min_val = tmp_val;
-      index   = i;
-      }
-    }
-  
-  index_of_min_val = index;
-  
-  return X[index];
-  }
-
-
-
-template<typename T>
-inline 
-std::complex<T>
-op_min::direct_min(const Mat< std::complex<T> >& X, const uword row)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_cols = X.n_cols;
-  
-  uword index   = 0;
-  T   min_val = priv::most_pos<T>();
-  
-  for(uword col=0; col<X_n_cols; ++col)
-    {
-    const T tmp_val = std::abs(X.at(row,col));
-    
-    if(tmp_val < min_val)
-      {
-      min_val = tmp_val;
-      index   = col;
-      }
-    }
-  
-  return X.at(row,index);
-  }
-
-
-
-template<typename T>
-inline 
-std::complex<T>
-op_min::direct_min(const subview< std::complex<T> >& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_elem = X.n_elem;
-        uword index    = 0;
-        T   min_val  = priv::most_pos<T>();
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    const T tmp_val = std::abs(X[i]);
-    
-    if(tmp_val < min_val)
-      {
-      min_val = tmp_val;
-      index   = i;
-      }
-    }
-  
-  return X[index];
-  }
-
-
-
-template<typename T>
-inline 
-std::complex<T>
-op_min::direct_min(const diagview< std::complex<T> >& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword X_n_elem = X.n_elem;
-        uword index    = 0;
-        T   min_val  = priv::most_pos<T>();
-  
-  for(uword i=0; i<X_n_elem; ++i)
-    {
-    const T tmp_val = std::abs(X[i]);
-    
-    if(tmp_val < min_val)
-      {
-      min_val = tmp_val;
-      index   = i;
-      }
-    }
-  
-  return X[index];
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_misc_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_misc
-//! @{
-
-
-
-class op_real
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply( Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_real>& X);
-  
-  template<typename T1>
-  inline static void apply( Cube<typename T1::pod_type>& out, const mtOpCube<typename T1::pod_type, T1, op_real>& X);
-  };
-
-
-
-class op_imag
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply( Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_imag>& X);
-  
-  template<typename T1>
-  inline static void apply( Cube<typename T1::pod_type>& out, const mtOpCube<typename T1::pod_type, T1, op_imag>& X);
-  };
-
-
-
-class op_abs
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply( Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_abs>& X);
-  
-  template<typename T1>
-  inline static void apply( Cube<typename T1::pod_type>& out, const mtOpCube<typename T1::pod_type, T1, op_abs>& X);
-  };
-
-
-
-class op_sympd
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply( Mat<typename T1::elem_type>& out, const Op<T1, op_sympd>& X);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_misc_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_misc
-//! @{
-
-
-
-template<typename T1>
-inline
-void
-op_real::apply( Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_real>& X )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::pod_type T;
-  
-  const Proxy<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-  const uword n_elem  = out.n_elem;
-        T*  out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = std::real(A[i]);
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_real::apply( Cube<typename T1::pod_type>& out, const mtOpCube<typename T1::pod_type, T1, op_real>& X )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::pod_type T;
-  
-  const ProxyCube<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  
-  const uword n_elem  = out.n_elem;
-        T*  out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = std::real(A[i]);
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_imag::apply( Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_imag>& X )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::pod_type T;
-  
-  const Proxy<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-  const uword n_elem  = out.n_elem;
-        T*  out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = std::imag(A[i]);
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_imag::apply( Cube<typename T1::pod_type>& out, const mtOpCube<typename T1::pod_type, T1, op_imag>& X )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::pod_type T;
-  
-  const ProxyCube<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  
-  const uword n_elem  = out.n_elem;
-        T*  out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = std::imag(A[i]);
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_abs::apply( Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_abs>& X )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::pod_type T;
-  
-  const Proxy<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols());
-  
-  const uword n_elem  = out.n_elem;
-        T*  out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = std::abs(A[i]);
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_abs::apply( Cube<typename T1::pod_type>& out, const mtOpCube<typename T1::pod_type, T1, op_abs>& X )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::pod_type T;
-  
-  const ProxyCube<T1> A(X.m);
-  
-  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
-  
-  const uword n_elem  = out.n_elem;
-        T*  out_mem = out.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    out_mem[i] = std::abs(A[i]);
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_sympd::apply( Mat<typename T1::elem_type>& out, const Op<T1, op_sympd>& X )
-  {
-  arma_extra_debug_sigprint();
-  
-  out = X.m;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_pinv_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_pinv
-//! @{
-
-
-
-class op_pinv
-  {
-  public:
-  
-  template<typename eT> inline static void direct_pinv(Mat<eT>& out, const Mat<eT>& A, const eT in_tol);
-  
-  template<typename T1> inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_pinv>& in);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_pinv_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// Copyright (C) 2011 Stanislav Funiak
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_pinv
-//! @{
-
-
-
-template<typename eT>
-inline
-void
-op_pinv::direct_pinv(Mat<eT>& out, const Mat<eT>& A, const eT in_tol)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename get_pod_type<eT>::result T;
-  
-  T tol = access::tmp_real(in_tol);
-  
-  arma_debug_check((tol < T(0)), "pinv(): tolerance must be >= 0");
-  
-  const uword n_rows = A.n_rows;
-  const uword n_cols = A.n_cols;
-  
-  // economical SVD decomposition 
-  Mat<eT> U;
-  Col< T> s;
-  Mat<eT> V;
-  
-  const bool status = (n_cols > n_rows) ? auxlib::svd_econ(U,s,V,trans(A),'b') : auxlib::svd_econ(U,s,V,A,'b');
-  
-  if(status == false)
-    {
-    out.reset();
-    arma_bad("pinv(): svd failed");
-    return;
-    }
-  
-  const uword s_n_elem = s.n_elem;
-  const T*    s_mem    = s.memptr();
-  
-  // set tolerance to default if it hasn't been specified as an argument 
-  if( (tol == T(0)) && (s_n_elem > 0) )
-    {
-    tol = (std::max)(n_rows, n_cols) * eop_aux::direct_eps( op_max::direct_max(s_mem, s_n_elem) );
-    }
-  
-  
-  // count non zero valued elements in s
-  
-  uword count = 0;
-  
-  for(uword i = 0; i < s_n_elem; ++i)
-    {
-    if(s_mem[i] > tol)
-      {
-      ++count;
-      }
-    }
-  
-  if(count != 0)
-    {
-    Col<T> s2(count);
-    
-    T* s2_mem = s2.memptr();
-    
-    uword count2 = 0;
-    
-    for(uword i=0; i < s_n_elem; ++i)
-      {
-      const T val = s_mem[i];
-      
-      if(val > tol)
-        {
-        s2_mem[count2] = T(1) / val;
-        ++count2;
-        }
-      }
-    
-    
-    if(n_rows >= n_cols)
-      {
-      out = ( V.n_cols > count ? V.cols(0,count-1) : V ) * diagmat(s2) * trans( U.n_cols > count ? U.cols(0,count-1) : U );
-      }
-    else
-      {
-      out = ( U.n_cols > count ? U.cols(0,count-1) : U ) * diagmat(s2) * trans( V.n_cols > count ? V.cols(0,count-1) : V );
-      }
-    }
-  else
-    {
-    out.zeros(n_cols, n_rows);
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_pinv::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_pinv>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(in.m);
-  const Mat<eT>& A = tmp.M;
-  
-  op_pinv::direct_pinv(out, A, in.aux);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_princomp_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// Copyright (C) 2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_princomp
-//! @{
-
-
-
-class op_princomp
-  {
-  public:
-  
-  // real element versions
-  
-  template<typename eT>
-  inline static bool
-  direct_princomp
-    (      
-          Mat<eT>& coeff_out,                                                     
-    const Mat<eT>& in
-    );
-                                                           
-  template<typename eT>
-  inline static bool
-  direct_princomp
-    (      
-          Mat<eT>& coeff_out, 
-          Mat<eT>& score_out,
-    const Mat<eT>& in
-    );
-                                                           
-  template<typename eT>
-  inline static bool
-  direct_princomp
-    (
-          Mat<eT>& coeff_out, 
-          Mat<eT>& score_out, 
-          Col<eT>& latent_out,                    
-    const Mat<eT>& in
-    );
-    
-  template<typename eT>
-  inline static bool
-  direct_princomp
-    (
-          Mat<eT>& coeff_out, 
-          Mat<eT>& score_out, 
-          Col<eT>& latent_out, 
-          Col<eT>& tsquared_out, 
-    const Mat<eT>& in
-    );  
-  
-  
-  // complex element versions
-  
-  template<typename T>
-  inline static bool
-  direct_princomp
-    (
-          Mat< std::complex<T> >& coeff_out,
-    const Mat< std::complex<T> >& in
-    );
-    
-  template<typename T>
-  inline static bool
-  direct_princomp
-    (
-          Mat< std::complex<T> >& coeff_out, 
-          Mat< std::complex<T> >& score_out,                                                   
-    const Mat< std::complex<T> >& in
-    );
-    
-  template<typename T>
-  inline static bool
-  direct_princomp
-    (
-          Mat< std::complex<T> >& coeff_out, 
-          Mat< std::complex<T> >& score_out, 
-                          Col<T>& latent_out,                                   
-    const Mat< std::complex<T> >& in
-    );
-    
-  template<typename T>
-  inline static bool
-  direct_princomp
-    (
-          Mat< std::complex<T> >& coeff_out, 
-          Mat< std::complex<T> >& score_out, 
-                          Col<T>& latent_out, 
-          Col< std::complex<T> >& tsquared_out, 
-    const Mat< std::complex<T> >& in    
-    );
-  
-  
-  template<typename T1>
-  inline static void
-  apply(Mat<typename T1::elem_type>& out, const Op<T1,op_princomp>& in);
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_princomp_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,604 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// Copyright (C) 2010 Dimitrios Bouzas
-// Copyright (C) 2011 Stanislav Funiak
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_princomp
-//! @{
-
-
-
-//! \brief
-//! principal component analysis -- 4 arguments version
-//! computation is done via singular value decomposition
-//! coeff_out    -> principal component coefficients
-//! score_out    -> projected samples
-//! latent_out   -> eigenvalues of principal vectors
-//! tsquared_out -> Hotelling's T^2 statistic
-template<typename eT>
-inline
-bool
-op_princomp::direct_princomp
-  (
-        Mat<eT>& coeff_out,
-        Mat<eT>& score_out,
-        Col<eT>& latent_out, 
-        Col<eT>& tsquared_out,
-  const Mat<eT>& in
-  )
-  {
-  arma_extra_debug_sigprint();
-
-  const uword n_rows = in.n_rows;
-  const uword n_cols = in.n_cols;
-  
-  if(n_rows > 1) // more than one sample
-    {
-    // subtract the mean - use score_out as temporary matrix
-    score_out = in - repmat(mean(in), n_rows, 1);
- 	  
-    // singular value decomposition
-    Mat<eT> U;
-    Col<eT> s;
-    
-    const bool svd_ok = svd(U,s,coeff_out,score_out);
-    
-    if(svd_ok == false)
-      {
-      return false;
-      }
-    
-    
-    //U.reset();  // TODO: do we need this ?  U will get automatically deleted anyway
-    
-    // normalize the eigenvalues
-    s /= std::sqrt( double(n_rows - 1) );
-    
-    // project the samples to the principals
-    score_out *= coeff_out;
-    
-    if(n_rows <= n_cols) // number of samples is less than their dimensionality
-      {
-      score_out.cols(n_rows-1,n_cols-1).zeros();
-      
-      //Col<eT> s_tmp = zeros< Col<eT> >(n_cols);
-      Col<eT> s_tmp(n_cols);
-      s_tmp.zeros();
-      
-      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
-      s = s_tmp;
-          
-      // compute the Hotelling's T-squared
-      s_tmp.rows(0,n_rows-2) = eT(1) / s_tmp.rows(0,n_rows-2);
-      
-      const Mat<eT> S = score_out * diagmat(Col<eT>(s_tmp));   
-      tsquared_out = sum(S%S,1); 
-      }
-    else
-      {
-      // compute the Hotelling's T-squared   
-      const Mat<eT> S = score_out * diagmat(Col<eT>( eT(1) / s));
-      tsquared_out = sum(S%S,1);
-      }
-            
-    // compute the eigenvalues of the principal vectors
-    latent_out = s%s;
-    }
-  else // 0 or 1 samples
-    {
-    coeff_out.eye(n_cols, n_cols);
-    
-    score_out.copy_size(in);
-    score_out.zeros();
-    
-    latent_out.set_size(n_cols);
-    latent_out.zeros();
-    
-    tsquared_out.set_size(n_rows);
-    tsquared_out.zeros();
-    }
-  
-  return true;
-  }
-
-
-
-//! \brief
-//! principal component analysis -- 3 arguments version
-//! computation is done via singular value decomposition
-//! coeff_out    -> principal component coefficients
-//! score_out    -> projected samples
-//! latent_out   -> eigenvalues of principal vectors
-template<typename eT>
-inline
-bool
-op_princomp::direct_princomp
-  (
-        Mat<eT>& coeff_out,
-        Mat<eT>& score_out,
-        Col<eT>& latent_out,
-  const Mat<eT>& in
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword n_rows = in.n_rows;
-  const uword n_cols = in.n_cols;
-  
-  if(n_rows > 1) // more than one sample
-    {
-    // subtract the mean - use score_out as temporary matrix
-    score_out = in - repmat(mean(in), n_rows, 1);
- 	  
-    // singular value decomposition
-    Mat<eT> U;
-    Col<eT> s;
-    
-    const bool svd_ok = svd(U,s,coeff_out,score_out);
-    
-    if(svd_ok == false)
-      {
-      return false;
-      }
-    
-    
-    // U.reset();
-    
-    // normalize the eigenvalues
-    s /= std::sqrt( double(n_rows - 1) );
-    
-    // project the samples to the principals
-    score_out *= coeff_out;
-    
-    if(n_rows <= n_cols) // number of samples is less than their dimensionality
-      {
-      score_out.cols(n_rows-1,n_cols-1).zeros();
-      
-      Col<eT> s_tmp = zeros< Col<eT> >(n_cols);
-      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
-      s = s_tmp;
-      }
-      
-    // compute the eigenvalues of the principal vectors
-    latent_out = s%s;
-    
-    }
-  else // 0 or 1 samples
-    {
-    coeff_out.eye(n_cols, n_cols);
-    
-    score_out.copy_size(in);
-    score_out.zeros();
-    
-    latent_out.set_size(n_cols);
-    latent_out.zeros(); 
-    }
-  
-  return true;
-  }
-
-
-
-//! \brief
-//! principal component analysis -- 2 arguments version
-//! computation is done via singular value decomposition
-//! coeff_out    -> principal component coefficients
-//! score_out    -> projected samples
-template<typename eT>
-inline
-bool
-op_princomp::direct_princomp
-  (
-        Mat<eT>& coeff_out,
-        Mat<eT>& score_out,
-  const Mat<eT>& in
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword n_rows = in.n_rows;
-  const uword n_cols = in.n_cols;
-  
-  if(n_rows > 1) // more than one sample
-    {
-    // subtract the mean - use score_out as temporary matrix
-    score_out = in - repmat(mean(in), n_rows, 1);
- 	  
-    // singular value decomposition
-    Mat<eT> U;
-    Col<eT> s;
-    
-    const bool svd_ok = svd(U,s,coeff_out,score_out);
-    
-    if(svd_ok == false)
-      {
-      return false;
-      }
-    
-    // U.reset();
-    
-    // normalize the eigenvalues
-    s /= std::sqrt( double(n_rows - 1) );
-    
-    // project the samples to the principals
-    score_out *= coeff_out;
-    
-    if(n_rows <= n_cols) // number of samples is less than their dimensionality
-      {
-      score_out.cols(n_rows-1,n_cols-1).zeros();
-      
-      Col<eT> s_tmp = zeros< Col<eT> >(n_cols);
-      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
-      s = s_tmp;
-      }
-    }
-  else // 0 or 1 samples
-    {
-    coeff_out.eye(n_cols, n_cols);
-    score_out.copy_size(in);
-    score_out.zeros();
-    }
-  
-  return true;
-  }
-
-
-
-//! \brief
-//! principal component analysis -- 1 argument version
-//! computation is done via singular value decomposition
-//! coeff_out    -> principal component coefficients
-template<typename eT>
-inline
-bool
-op_princomp::direct_princomp
-  (
-        Mat<eT>& coeff_out,
-  const Mat<eT>& in
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  if(in.n_elem != 0)
-    {
-    // singular value decomposition
-    Mat<eT> U;
-    Col<eT> s;
-    
-    const Mat<eT> tmp = in - repmat(mean(in), in.n_rows, 1);
-    
-    const bool svd_ok = svd(U,s,coeff_out, tmp);
-    
-    if(svd_ok == false)
-      {
-      return false;
-      }
-    }
-  else
-    {
-    coeff_out.eye(in.n_cols, in.n_cols);
-    }
-  
-  return true;
-  }
-
-
-
-//! \brief
-//! principal component analysis -- 4 arguments complex version
-//! computation is done via singular value decomposition
-//! coeff_out    -> principal component coefficients
-//! score_out    -> projected samples
-//! latent_out   -> eigenvalues of principal vectors
-//! tsquared_out -> Hotelling's T^2 statistic
-template<typename T>
-inline
-bool
-op_princomp::direct_princomp
-  (
-        Mat< std::complex<T> >& coeff_out,
-        Mat< std::complex<T> >& score_out,
-        Col<T>&                 latent_out,
-        Col< std::complex<T> >& tsquared_out,
-  const Mat< std::complex<T> >& in
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef std::complex<T> eT;
-  
-  const uword n_rows = in.n_rows;
-  const uword n_cols = in.n_cols;
-  
-  if(n_rows > 1) // more than one sample
-    {
-    // subtract the mean - use score_out as temporary matrix
-    score_out = in - repmat(mean(in), n_rows, 1);
- 	  
-    // singular value decomposition
-    Mat<eT> U;
-    Col<T> s;
-    
-    const bool svd_ok = svd(U,s,coeff_out,score_out); 
-    
-    if(svd_ok == false)
-      {
-      return false;
-      }
-    
-    
-    //U.reset();
-    
-    // normalize the eigenvalues
-    s /= std::sqrt( double(n_rows - 1) );
-    
-    // project the samples to the principals
-    score_out *= coeff_out;
-    
-    if(n_rows <= n_cols) // number of samples is less than their dimensionality
-      {
-      score_out.cols(n_rows-1,n_cols-1).zeros();
-      
-      Col<T> s_tmp = zeros< Col<T> >(n_cols);
-      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
-      s = s_tmp;
-          
-      // compute the Hotelling's T-squared   
-      s_tmp.rows(0,n_rows-2) = 1.0 / s_tmp.rows(0,n_rows-2);
-      const Mat<eT> S = score_out * diagmat(Col<T>(s_tmp));                     
-      tsquared_out = sum(S%S,1); 
-      }
-    else
-      {
-      // compute the Hotelling's T-squared   
-      const Mat<eT> S = score_out * diagmat(Col<T>(T(1) / s));                     
-      tsquared_out = sum(S%S,1);
-      }
-    
-    // compute the eigenvalues of the principal vectors
-    latent_out = s%s;
-    
-    }
-  else // 0 or 1 samples
-    {
-    coeff_out.eye(n_cols, n_cols);
-    
-    score_out.copy_size(in);
-    score_out.zeros();
-      
-    latent_out.set_size(n_cols);
-    latent_out.zeros();
-      
-    tsquared_out.set_size(n_rows);
-    tsquared_out.zeros();
-    }
-  
-  return true;
-  }
-
-
-
-//! \brief
-//! principal component analysis -- 3 arguments complex version
-//! computation is done via singular value decomposition
-//! coeff_out    -> principal component coefficients
-//! score_out    -> projected samples
-//! latent_out   -> eigenvalues of principal vectors
-template<typename T>
-inline
-bool
-op_princomp::direct_princomp
-  (
-        Mat< std::complex<T> >& coeff_out,
-        Mat< std::complex<T> >& score_out,
-        Col<T>&                 latent_out,
-  const Mat< std::complex<T> >& in
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef std::complex<T> eT;
-  
-  const uword n_rows = in.n_rows;
-  const uword n_cols = in.n_cols;
-  
-  if(n_rows > 1) // more than one sample
-    {
-    // subtract the mean - use score_out as temporary matrix
-    score_out = in - repmat(mean(in), n_rows, 1);
- 	  
-    // singular value decomposition
-    Mat<eT> U;
-    Col< T> s;
-    
-    const bool svd_ok = svd(U,s,coeff_out,score_out);
-    
-    if(svd_ok == false)
-      {
-      return false;
-      }
-    
-    
-    // U.reset();
-    
-    // normalize the eigenvalues
-    s /= std::sqrt( double(n_rows - 1) );
-    
-    // project the samples to the principals
-    score_out *= coeff_out;
-    
-    if(n_rows <= n_cols) // number of samples is less than their dimensionality
-      {
-      score_out.cols(n_rows-1,n_cols-1).zeros();
-      
-      Col<T> s_tmp = zeros< Col<T> >(n_cols);
-      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
-      s = s_tmp;
-      }
-      
-    // compute the eigenvalues of the principal vectors
-    latent_out = s%s;
-
-    }
-  else // 0 or 1 samples
-    {
-    coeff_out.eye(n_cols, n_cols);
-
-    score_out.copy_size(in);
-    score_out.zeros();
-
-    latent_out.set_size(n_cols);
-    latent_out.zeros();
-    }
-  
-  return true;
-  }
-
-
-
-//! \brief
-//! principal component analysis -- 2 arguments complex version
-//! computation is done via singular value decomposition
-//! coeff_out    -> principal component coefficients
-//! score_out    -> projected samples
-template<typename T>
-inline
-bool
-op_princomp::direct_princomp
-  (
-        Mat< std::complex<T> >& coeff_out,
-        Mat< std::complex<T> >& score_out,
-  const Mat< std::complex<T> >& in
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef std::complex<T> eT;
-  
-  const uword n_rows = in.n_rows;
-  const uword n_cols = in.n_cols;
-  
-  if(n_rows > 1) // more than one sample
-    {
-    // subtract the mean - use score_out as temporary matrix
-    score_out = in - repmat(mean(in), n_rows, 1);
- 	  
-    // singular value decomposition
-    Mat<eT> U;
-    Col< T> s;
-    
-    const bool svd_ok = svd(U,s,coeff_out,score_out);
-    
-    if(svd_ok == false)
-      {
-      return false;
-      }
-    
-    // U.reset();
-    
-    // normalize the eigenvalues
-    s /= std::sqrt( double(n_rows - 1) );
-
-    // project the samples to the principals
-    score_out *= coeff_out;
-
-    if(n_rows <= n_cols) // number of samples is less than their dimensionality
-      {
-      score_out.cols(n_rows-1,n_cols-1).zeros();
-      }
-
-    }
-  else // 0 or 1 samples
-    {
-    coeff_out.eye(n_cols, n_cols);
-    
-    score_out.copy_size(in);
-    score_out.zeros();
-    }
-  
-  return true;
-  }
-
-
-
-//! \brief
-//! principal component analysis -- 1 argument complex version
-//! computation is done via singular value decomposition
-//! coeff_out    -> principal component coefficients
-template<typename T>
-inline
-bool
-op_princomp::direct_princomp
-  (
-        Mat< std::complex<T> >& coeff_out,
-  const Mat< std::complex<T> >& in
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T> eT;
-  
-  if(in.n_elem != 0)
-    {
- 	  // singular value decomposition
- 	  Mat<eT> U;
-    Col< T> s;
-    
-    const Mat<eT> tmp = in - repmat(mean(in), in.n_rows, 1);
-    
-    const bool svd_ok = svd(U,s,coeff_out, tmp);
-    
-    if(svd_ok == false)
-      {
-      return false;
-      }
-    }
-  else
-    {
-    coeff_out.eye(in.n_cols, in.n_cols);
-    }
-  
-  return true;
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_princomp::apply
-  (
-        Mat<typename T1::elem_type>& out,
-  const Op<T1,op_princomp>&          in
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> tmp(in.m, out);
-  const Mat<eT>& A     = tmp.M;
-  
-  const bool status = op_princomp::direct_princomp(out, A);
-  
-  if(status == false)
-    {
-    out.reset();
-    
-    arma_bad("princomp(): failed to converge");
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_prod_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_prod
-//! @{
-
-//! Class for finding products of values in a matrix  (e.g. along rows or columns)
-class op_prod
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1, op_prod>& in);
-  };
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_prod_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_prod
-//! @{
-
-//! \brief
-//! Immediate product of elements of a matrix along a specified dimension (either rows or columns).
-//! The result is stored in a dense matrix that has either one column or one row.
-//! See the prod() function for more details.
-template<typename T1>
-inline
-void
-op_prod::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_prod>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const uword dim = in.aux_uword_a;
-  arma_debug_check( (dim > 1), "prod(): incorrect usage. dim must be 0 or 1");
-  
-  const unwrap_check<T1> tmp(in.m, out);
-  const Mat<eT>& X     = tmp.M;
-  
-  const uword X_n_rows = X.n_rows;
-  const uword X_n_cols = X.n_cols;
-    
-  if(dim == 0)  // traverse across rows (i.e. find the product in each column)
-    {
-    out.set_size(1, X_n_cols);
-    
-    eT* out_mem = out.memptr();
-    
-    for(uword col=0; col<X_n_cols; ++col)
-      {
-      out_mem[col] = arrayops::product(X.colptr(col), X_n_rows);
-      }
-    }
-  else  // traverse across columns (i.e. find the product in each row)
-    {
-    out.set_size(X_n_rows, 1);
-    
-    eT* out_mem = out.memptr();
-    
-    for(uword row=0; row<X_n_rows; ++row)
-      {
-      eT val = eT(1);
-      
-      for(uword col=0; col<X_n_cols; ++col)
-        {
-        val *= X.at(row,col);
-        }
-      
-      out_mem[row] = val;
-      }
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_relational_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_relational
-//! @{
-
-
-
-class op_rel_lt_pre
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lt_pre>& X);
-  
-  template<typename T1>
-  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lt_pre>& X);
-  };
-
-
-
-class op_rel_lt_post
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lt_post>& X);
-  
-  template<typename T1>
-  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lt_post>& X);
-  };
-
-
-
-class op_rel_gt_pre
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gt_pre>& X);
-  
-  template<typename T1>
-  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gt_pre>& X);
-  };
-
-
-
-class op_rel_gt_post
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gt_post>& X);
-  
-  template<typename T1>
-  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gt_post>& X);
-  };
-
-
-
-class op_rel_lteq_pre
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lteq_pre>& X);
-  
-  template<typename T1>
-  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lteq_pre>& X);
-  };
-
-
-
-class op_rel_lteq_post
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lteq_post>& X);
-  
-  template<typename T1>
-  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lteq_post>& X);
-  };
-
-
-
-class op_rel_gteq_pre
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gteq_pre>& X);
-  
-  template<typename T1>
-  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gteq_pre>& X);
-  };
-
-
-
-class op_rel_gteq_post
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gteq_post>& X);
-  
-  template<typename T1>
-  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gteq_post>& X);
-  };
-
-
-
-class op_rel_eq
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_eq>& X);
-  
-  template<typename T1>
-  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_eq>& X);
-  };
-
-
-
-class op_rel_noteq
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_noteq>& X);
-  
-  template<typename T1>
-  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_noteq>& X);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_relational_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,489 +0,0 @@
-// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2012 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_relational
-//! @{
-
-
-#undef operator_rel
-
-#undef arma_applier_mat_pre
-#undef arma_applier_mat_post
-
-#undef arma_applier_cube_pre
-#undef arma_applier_cube_post
-
-
-#define arma_applier_mat_pre(operator_rel) \
-  {\
-  typedef typename T1::elem_type      eT;\
-  typedef typename Proxy<T1>::ea_type ea_type;\
-  \
-  const eT val = X.aux;\
-  \
-  const Proxy<T1> P(X.m);\
-  \
-  const uword n_rows = P.get_n_rows();\
-  const uword n_cols = P.get_n_cols();\
-  \
-  const bool bad_alias = ( Proxy<T1>::has_subview && P.is_alias(out) );\
-  \
-  if(bad_alias == false)\
-    {\
-    out.set_size(n_rows, n_cols);\
-    \
-    uword* out_mem = out.memptr();\
-    \
-    if(Proxy<T1>::prefer_at_accessor == false)\
-      {\
-            ea_type PA     = P.get_ea();\
-      const uword   n_elem = out.n_elem;\
-      \
-      for(uword i=0; i<n_elem; ++i)\
-        {\
-        out_mem[i] = (val operator_rel PA[i]) ? uword(1) : uword(0);\
-        }\
-      }\
-    else\
-      {\
-      uword count = 0;\
-      \
-      for(uword col=0; col < n_cols; ++col)\
-      for(uword row=0; row < n_rows; ++row, ++count)\
-        {\
-        out_mem[count] = (val operator_rel P.at(row,col)) ? uword(1) : uword(0);\
-        }\
-      }\
-    }\
-  else\
-    {\
-    const unwrap<typename Proxy<T1>::stored_type> tmp(P.Q);\
-    \
-    out = (val) operator_rel (tmp.M);\
-    }\
-  }
-
-
-
-#define arma_applier_mat_post(operator_rel) \
-  {\
-  typedef typename T1::elem_type      eT;\
-  typedef typename Proxy<T1>::ea_type ea_type;\
-  \
-  const eT val = X.aux;\
-  \
-  const Proxy<T1> P(X.m);\
-  \
-  const uword n_rows = P.get_n_rows();\
-  const uword n_cols = P.get_n_cols();\
-  \
-  const bool bad_alias = ( Proxy<T1>::has_subview && P.is_alias(out) );\
-  \
-  if(bad_alias == false)\
-    {\
-    out.set_size(n_rows, n_cols);\
-    \
-    uword* out_mem = out.memptr();\
-    \
-    if(Proxy<T1>::prefer_at_accessor == false)\
-      {\
-            ea_type PA     = P.get_ea();\
-      const uword   n_elem = out.n_elem;\
-      \
-      for(uword i=0; i<n_elem; ++i)\
-        {\
-        out_mem[i] = (PA[i] operator_rel val) ? uword(1) : uword(0);\
-        }\
-      }\
-    else\
-      {\
-      uword count = 0;\
-      \
-      for(uword col=0; col < n_cols; ++col)\
-      for(uword row=0; row < n_rows; ++row, ++count)\
-        {\
-        out_mem[count] = (P.at(row,col) operator_rel val) ? uword(1) : uword(0);\
-        }\
-      }\
-    }\
-  else\
-    {\
-    const unwrap<typename Proxy<T1>::stored_type> tmp(P.Q);\
-    \
-    out = (tmp.M) operator_rel (val);\
-    }\
-  }
-
-
-
-#define arma_applier_cube_pre(operator_rel) \
-  {\
-  typedef typename T1::elem_type          eT;\
-  typedef typename ProxyCube<T1>::ea_type ea_type;\
-  \
-  const eT val = X.aux;\
-  \
-  const ProxyCube<T1> P(X.m);\
-  \
-  const uword n_rows   = P.get_n_rows();\
-  const uword n_cols   = P.get_n_cols();\
-  const uword n_slices = P.get_n_slices();\
-  \
-  const bool bad_alias = ( ProxyCube<T1>::has_subview && P.is_alias(out) );\
-  \
-  if(bad_alias == false)\
-    {\
-    out.set_size(n_rows, n_cols, n_slices);\
-    \
-    uword* out_mem = out.memptr();\
-    \
-    if(ProxyCube<T1>::prefer_at_accessor == false)\
-      {\
-            ea_type PA     = P.get_ea();\
-      const uword   n_elem = out.n_elem;\
-      \
-      for(uword i=0; i<n_elem; ++i)\
-        {\
-        out_mem[i] = (val operator_rel PA[i]) ? uword(1) : uword(0);\
-        }\
-      }\
-    else\
-      {\
-      uword count = 0;\
-      \
-      for(uword slice=0; slice < n_slices; ++slice)\
-      for(uword col=0;   col   < n_cols;   ++col)\
-      for(uword row=0;   row   < n_rows;   ++row, ++count)\
-        {\
-        out_mem[count] = (val operator_rel P.at(row,col,slice)) ? uword(1) : uword(0);\
-        }\
-      }\
-    }\
-  else\
-    {\
-    const unwrap_cube<typename ProxyCube<T1>::stored_type> tmp(P.Q);\
-    \
-    out = (val) operator_rel (tmp.M);\
-    }\
-  }
-
-
-
-#define arma_applier_cube_post(operator_rel) \
-  {\
-  typedef typename T1::elem_type          eT;\
-  typedef typename ProxyCube<T1>::ea_type ea_type;\
-  \
-  const eT val = X.aux;\
-  \
-  const ProxyCube<T1> P(X.m);\
-  \
-  const uword n_rows   = P.get_n_rows();\
-  const uword n_cols   = P.get_n_cols();\
-  const uword n_slices = P.get_n_slices();\
-  \
-  const bool bad_alias = ( ProxyCube<T1>::has_subview && P.is_alias(out) );\
-  \
-  if(bad_alias == false)\
-    {\
-    out.set_size(n_rows, n_cols, n_slices);\
-    \
-    uword* out_mem = out.memptr();\
-    \
-    if(ProxyCube<T1>::prefer_at_accessor == false)\
-      {\
-            ea_type PA     = P.get_ea();\
-      const uword   n_elem = out.n_elem;\
-      \
-      for(uword i=0; i<n_elem; ++i)\
-        {\
-        out_mem[i] = (PA[i] operator_rel val) ? uword(1) : uword(0);\
-        }\
-      }\
-    else\
-      {\
-      uword count = 0;\
-      \
-      for(uword slice=0; slice < n_slices; ++slice)\
-      for(uword col=0;   col   < n_cols;   ++col)\
-      for(uword row=0;   row   < n_rows;   ++row, ++count)\
-        {\
-        out_mem[count] = (P.at(row,col,slice) operator_rel val) ? uword(1) : uword(0);\
-        }\
-      }\
-    }\
-  else\
-    {\
-    const unwrap_cube<typename ProxyCube<T1>::stored_type> tmp(P.Q);\
-    \
-    out = (tmp.M) operator_rel (val);\
-    }\
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_lt_pre::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lt_pre>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat_pre( < );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_gt_pre::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gt_pre>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat_pre( > );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_lteq_pre::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lteq_pre>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat_pre( <= );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_gteq_pre::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gteq_pre>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat_pre( >= );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_lt_post::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lt_post>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat_post( < );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_gt_post::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gt_post>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat_post( > );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_lteq_post::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lteq_post>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat_post( <= );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_gteq_post::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gteq_post>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat_post( >= );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_eq::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_eq>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat_post( == );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_noteq::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_noteq>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_mat_post( != );
-  }
-
-
-
-//
-//
-//
-
-
-
-template<typename T1>
-inline
-void
-op_rel_lt_pre::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lt_pre>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube_pre( < );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_gt_pre::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gt_pre>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube_pre( > );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_lteq_pre::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lteq_pre>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube_pre( <= );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_gteq_pre::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gteq_pre>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube_pre( >= );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_lt_post::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lt_post>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube_post( < );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_gt_post::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gt_post>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube_post( > );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_lteq_post::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lteq_post>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube_post( <= );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_gteq_post::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gteq_post>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube_post( >= );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_eq::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_eq>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube_post( == );
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_rel_noteq::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_noteq>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_applier_cube_post( != );
-  }
-
-
-
-#undef arma_applier_mat_pre
-#undef arma_applier_mat_post
-
-#undef arma_applier_cube_pre
-#undef arma_applier_cube_post
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_repmat_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_repmat
-//! @{
-
-
-
-class op_repmat
-  {
-  public:
-  template<typename T1> inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_repmat>& in);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_repmat_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_repmat
-//! @{
-
-
-
-//! \brief
-//! implementation of the 'repeat matrix' operation, used for constructing matrices
-template<typename T1>
-inline
-void
-op_repmat::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_repmat>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> tmp(in.m, out);
-  const Mat<eT>& X     = tmp.M;
-  
-  const uword copies_per_row = in.aux_uword_a;
-  const uword copies_per_col = in.aux_uword_b;
-  
-  const uword X_n_rows = X.n_rows;
-  const uword X_n_cols = X.n_cols;
-  
-  out.set_size(X_n_rows * copies_per_row, X_n_cols * copies_per_col);
-  
-  const uword out_n_rows = out.n_rows;
-  const uword out_n_cols = out.n_cols;
-  
-  if( (out_n_rows > 0) && (out_n_cols > 0) )
-    {
-    for(uword col = 0; col < out_n_cols; col += X_n_cols)
-      {
-      for(uword row = 0; row < out_n_rows; row += X_n_rows)
-        {
-        out.submat(row, col, row+X_n_rows-1, col+X_n_cols-1) = X;
-        }
-      }
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_reshape_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_reshape
-//! @{
-
-
-
-class op_reshape
-  {
-  public:
-  
-  template<typename T1> inline static void apply( Mat<typename T1::elem_type>& out, const     Op<T1,op_reshape>& in);
-  template<typename T1> inline static void apply(Cube<typename T1::elem_type>& out, const OpCube<T1,op_reshape>& in);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_reshape_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,267 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_reshape
-//! @{
-
-
-
-template<typename T1>
-inline
-void
-op_reshape::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_reshape>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(in.m);
-  const Mat<eT>& A = tmp.M;
-  
-  const uword in_n_rows = in.aux_uword_a;
-  const uword in_n_cols = in.aux_uword_b;
-  const uword in_dim    = in.aux_uword_c;
-  
-  const uword in_n_elem = in_n_rows * in_n_cols;
-  
-  if(A.n_elem == in_n_elem)
-    {
-    if(in_dim == 0)
-      {
-      if(&out != &A)
-        {
-        out.set_size(in_n_rows, in_n_cols);
-        arrayops::copy( out.memptr(), A.memptr(), out.n_elem );
-        }
-      else  // &out == &A, i.e. inplace resize
-        {
-        const bool same_size = ( (out.n_rows == in_n_rows) && (out.n_cols == in_n_cols) );
-        
-        if(same_size == false)
-          {
-          arma_debug_check
-            (
-            (out.mem_state == 3),
-            "reshape(): size can't be changed as template based size specification is in use"
-            );
-          
-          access::rw(out.n_rows) = in_n_rows;
-          access::rw(out.n_cols) = in_n_cols;
-          }
-        }
-      }
-    else
-      {
-      unwrap_check< Mat<eT> > tmp(A, out);
-      const Mat<eT>& B      = tmp.M;
-      
-      out.set_size(in_n_rows, in_n_cols);
-      
-      eT* out_mem = out.memptr();
-      uword i = 0;
-      
-      const uword B_n_rows = B.n_rows;
-      const uword B_n_cols = B.n_cols;
-      
-      for(uword row=0; row<B_n_rows; ++row)
-        {
-        for(uword col=0; col<B_n_cols; ++col)
-          {
-          out_mem[i] = B.at(row,col);
-          ++i;
-          }
-        }
-        
-      }
-    }
-  else
-    {
-    const unwrap_check< Mat<eT> > tmp(A, out);
-    const Mat<eT>& B            = tmp.M;
-    
-    const uword n_elem_to_copy = (std::min)(B.n_elem, in_n_elem);
-    
-    out.set_size(in_n_rows, in_n_cols);
-    
-    eT* out_mem = out.memptr();
-    
-    if(in_dim == 0)
-      {
-      arrayops::copy( out_mem, B.memptr(), n_elem_to_copy );
-      }
-    else
-      {
-      uword row = 0;
-      uword col = 0;
-      
-      const uword B_n_cols = B.n_cols;
-      
-      for(uword i=0; i<n_elem_to_copy; ++i)
-        {
-        out_mem[i] = B.at(row,col);
-        
-        ++col;
-        
-        if(col >= B_n_cols)
-          {
-          col = 0;
-          ++row;
-          }
-        }
-      }
-    
-    for(uword i=n_elem_to_copy; i<in_n_elem; ++i)
-      {
-      out_mem[i] = eT(0);
-      }
-    
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_reshape::apply(Cube<typename T1::elem_type>& out, const OpCube<T1,op_reshape>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_cube<T1> tmp(in.m);
-  const Cube<eT>& A   = tmp.M;
-  
-  const uword in_n_rows   = in.aux_uword_a;
-  const uword in_n_cols   = in.aux_uword_b;
-  const uword in_n_slices = in.aux_uword_c;
-  const uword in_dim      = in.aux_uword_d;
-  
-  const uword in_n_elem = in_n_rows * in_n_cols * in_n_slices;
-  
-  if(A.n_elem == in_n_elem)
-    {
-    if(in_dim == 0)
-      {
-      if(&out != &A)
-        {
-        out.set_size(in_n_rows, in_n_cols, in_n_slices);
-        arrayops::copy( out.memptr(), A.memptr(), out.n_elem );
-        }
-      else  // &out == &A, i.e. inplace resize
-        {
-        const bool same_size = ( (out.n_rows == in_n_rows) && (out.n_cols == in_n_cols) && (out.n_slices == in_n_slices) );
-        
-        if(same_size == false)
-          {
-          arma_debug_check
-            (
-            (out.mem_state == 3),
-            "reshape(): size can't be changed as template based size specification is in use"
-            );
-          
-          out.delete_mat();
-          
-          access::rw(out.n_rows)       = in_n_rows;
-          access::rw(out.n_cols)       = in_n_cols;
-          access::rw(out.n_elem_slice) = in_n_rows * in_n_cols;
-          access::rw(out.n_slices)     = in_n_slices;
-          
-          out.create_mat();
-          }
-        }
-      }
-    else
-      {
-      unwrap_cube_check< Cube<eT> > tmp(A, out);
-      const Cube<eT>& B           = tmp.M;
-      
-      out.set_size(in_n_rows, in_n_cols, in_n_slices);
-      
-      eT* out_mem = out.memptr();
-      uword i = 0;
-      
-      const uword B_n_rows   = B.n_rows;
-      const uword B_n_cols   = B.n_cols;
-      const uword B_n_slices = B.n_slices;
-      
-      for(uword slice=0; slice<B_n_slices; ++slice)
-        {
-        for(uword row=0; row<B_n_rows; ++row)
-          {
-          for(uword col=0; col<B_n_cols; ++col)
-            {
-            out_mem[i] = B.at(row,col,slice);
-            ++i;
-            }
-          }
-        }
-        
-      }
-    }
-  else
-    {
-    const unwrap_cube_check< Cube<eT> > tmp(A, out);
-    const Cube<eT>& B                 = tmp.M;
-    
-    const uword n_elem_to_copy = (std::min)(B.n_elem, in_n_elem);
-    
-    out.set_size(in_n_rows, in_n_cols, in_n_slices);
-    
-    eT* out_mem = out.memptr();
-    
-    if(in_dim == 0)
-      {
-      arrayops::copy( out_mem, B.memptr(), n_elem_to_copy );
-      }
-    else
-      {
-      uword row   = 0;
-      uword col   = 0;
-      uword slice = 0;
-      
-      const uword B_n_rows = B.n_rows;
-      const uword B_n_cols = B.n_cols;
-      
-      for(uword i=0; i<n_elem_to_copy; ++i)
-        {
-        out_mem[i] = B.at(row,col,slice);
-        
-        ++col;
-        
-        if(col >= B_n_cols)
-          {
-          col = 0;
-          ++row;
-          
-          if(row >= B_n_rows)
-            {
-            row = 0;
-            ++slice;
-            }
-          }
-        }
-      }
-    
-    for(uword i=n_elem_to_copy; i<in_n_elem; ++i)
-      {
-      out_mem[i] = eT(0);
-      }
-    
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_resize_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_resize
-//! @{
-
-
-
-class op_resize
-  {
-  public:
-  
-  template<typename T1> inline static void apply( Mat<typename T1::elem_type>& out, const     Op<T1,op_resize>& in);
-  template<typename T1> inline static void apply(Cube<typename T1::elem_type>& out, const OpCube<T1,op_resize>& in);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_resize_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_resize
-//! @{
-
-
-
-template<typename T1>
-inline
-void
-op_resize::apply(Mat<typename T1::elem_type>& actual_out, const Op<T1,op_resize>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const uword out_n_rows = in.aux_uword_a;
-  const uword out_n_cols = in.aux_uword_b;
-  
-  const unwrap<T1>   tmp(in.m);
-  const Mat<eT>& A = tmp.M;
-  
-  const uword A_n_rows = A.n_rows;
-  const uword A_n_cols = A.n_cols;
-  
-  Mat<eT> B;
-  
-  const bool alias = (&actual_out == &A);
-  
-  Mat<eT>& out = alias ? B : actual_out;
-  
-  out.set_size(out_n_rows, out_n_cols);
-  
-  if( (out_n_rows > A_n_rows) || (out_n_cols > A_n_cols) )
-    {
-    out.zeros();
-    }
-  
-  if( (out.n_elem > 0) && (A.n_elem > 0) )
-    {
-    const uword end_row = (std::min)(out_n_rows, A_n_rows) - 1;
-    const uword end_col = (std::min)(out_n_cols, A_n_cols) - 1;
-    
-    out.submat(0, 0, end_row, end_col) = A.submat(0, 0, end_row, end_col);
-    }
-  
-  if(alias)
-    {
-    actual_out.steal_mem(B);
-    }
-  
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_resize::apply(Cube<typename T1::elem_type>& actual_out, const OpCube<T1,op_resize>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const uword out_n_rows   = in.aux_uword_a;
-  const uword out_n_cols   = in.aux_uword_b;
-  const uword out_n_slices = in.aux_uword_c;
-  
-  const unwrap_cube<T1> tmp(in.m);
-  const Cube<eT>& A   = tmp.M;
-  
-  const uword A_n_rows   = A.n_rows;
-  const uword A_n_cols   = A.n_cols;
-  const uword A_n_slices = A.n_slices;
-  
-  Cube<eT> B;
-  
-  const bool alias = (&actual_out == &A);
-  
-  Cube<eT>& out = alias ? B : actual_out;
-  
-  out.set_size(out_n_rows, out_n_cols, out_n_slices);
-  
-  if( (out_n_rows > A_n_rows) || (out_n_cols > A_n_cols) || (out_n_slices > A_n_slices) )
-    {
-    out.zeros();
-    }
-  
-  if( (out.n_elem > 0) && (A.n_elem > 0) )
-    {
-    const uword end_row   = (std::min)(out_n_rows,   A_n_rows)   - 1;
-    const uword end_col   = (std::min)(out_n_cols,   A_n_cols)   - 1;
-    const uword end_slice = (std::min)(out_n_slices, A_n_slices) - 1;
-    
-    out.subcube(0, 0, 0, end_row, end_col, end_slice) = A.subcube(0, 0, 0, end_row, end_col, end_slice);
-    }
-  
-  if(alias)
-    {
-    actual_out.steal_mem(B);
-    }
-  
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_shuffle_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_shuffle
-//! @{
-
-
-
-class op_shuffle
-  {
-  public:
-  
-  template<typename T1> inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_shuffle>& in);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_shuffle_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// Copyright (C) 2009-2010 Dimitrios Bouzas
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup op_shuffle
-//! @{
-
-
-
-template<typename T1>
-inline
-void
-op_shuffle::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_shuffle>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(in.m);
-  const Mat<eT>& X = tmp.M;
-  
-  if(X.is_empty())
-    {
-    out.copy_size(X);
-    return;
-    }
-  
-  const uword dim = in.aux_uword_a;
-  const uword N   = (dim == 0) ? X.n_rows : X.n_cols;
-  
-  // see "fn_sort_index.hpp" for the definition of "arma_sort_index_packet_ascend"
-  // and the associated "operator<"
-  std::vector< arma_sort_index_packet_ascend<int,uword> > packet_vec(N);
-  
-  for(uword i=0; i<N; ++i)
-    {
-    packet_vec[i].val   = std::rand();
-    packet_vec[i].index = i;
-    }
-  
-  std::sort( packet_vec.begin(), packet_vec.end() );
-  
-  if(X.is_vec() == false)
-    {
-    if(&out != &X)
-      {
-      arma_extra_debug_print("op_shuffle::apply(): matrix");
-      
-      out.copy_size(X);
-      
-      if(dim == 0)
-        {
-        for(uword i=0; i<N; ++i)
-          {
-          out.row(i) = X.row(packet_vec[i].index);
-          }
-        }
-      else
-        {
-        for(uword i=0; i<N; ++i)
-          {
-          out.col(i) = X.col(packet_vec[i].index);
-          }
-        }
-      }
-    else  // in-place shuffle
-      {
-      arma_extra_debug_print("op_shuffle::apply(): in-place matrix");
-      
-      // reuse the val member variable of packet_vec
-      // to indicate whether a particular row or column
-      // has already been shuffled
-      
-      for(uword i=0; i<N; ++i)
-        {
-        packet_vec[i].val = 0;
-        }
-        
-      if(dim == 0)
-        {
-        for(uword i=0; i<N; ++i)
-          {
-          if(packet_vec[i].val == 0)
-            {
-            const uword j = packet_vec[i].index;
-            
-            out.swap_rows(i, j);
-            
-            packet_vec[j].val = 1;
-            }
-          }
-        }
-      else
-        {
-        for(uword i=0; i<N; ++i)
-          {
-          if(packet_vec[i].val == 0)
-            {
-            const uword j = packet_vec[i].index;
-            
-            out.swap_cols(i, j);
-            
-            packet_vec[j].val = 1;
-            }
-          }
-        }
-      }
-    }
-  else  // we're dealing with a vector
-    {
-    if(&out != &X)
-      {
-      arma_extra_debug_print("op_shuffle::apply(): vector");
-      
-      out.copy_size(X);
-      
-      if(dim == 0)
-        {
-        if(X.n_rows > 1)  // i.e. column vector
-          {
-          for(uword i=0; i<N; ++i)
-            {
-            out[i] = X[ packet_vec[i].index ];
-            }
-          }
-        else
-          {
-          out = X;
-          }
-        }
-      else
-        {
-        if(X.n_cols > 1)  // i.e. row vector
-          {
-          for(uword i=0; i<N; ++i)
-            {
-            out[i] = X[ packet_vec[i].index ];
-            }
-          }
-        else
-          {
-          out = X;
-          }
-        }
-      }
-    else  // in-place shuffle
-      {
-      arma_extra_debug_print("op_shuffle::apply(): in-place vector");
-      
-      // reuse the val member variable of packet_vec
-      // to indicate whether a particular row or column
-      // has already been shuffled
-      
-      for(uword i=0; i<N; ++i)
-        {
-        packet_vec[i].val = 0;
-        }
-        
-      if(dim == 0)
-        {
-        if(X.n_rows > 1)  // i.e. column vector
-          {
-          for(uword i=0; i<N; ++i)
-            {
-            if(packet_vec[i].val == 0)
-              {
-              const uword j = packet_vec[i].index;
-              
-              std::swap(out[i], out[j]);
-              
-              packet_vec[j].val = 1;
-              }
-            }
-          }
-        }
-      else
-        {
-        if(X.n_cols > 1)  // i.e. row vector
-          {
-          for(uword i=0; i<N; ++i)
-            {
-            if(packet_vec[i].val == 0)
-              {
-              const uword j = packet_vec[i].index;
-              
-              std::swap(out[i], out[j]);
-              
-              packet_vec[j].val = 1;
-              }
-            }
-          }
-        }
-      }
-    }
-  
-  }
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_sort_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_sort
-//! @{
-
-
-
-class op_sort
-  {
-  public:
-  
-  template<typename eT>
-  inline static void copy_row(eT* X, const Mat<eT>& A, const uword row);
-  
-  template<typename eT>
-  inline static void copy_row(Mat<eT>& A, const eT* X, const uword row);
-  
-  template<typename eT>
-  inline static void direct_sort(eT* X, const uword N, const uword sort_type = 0);
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sort>& in);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_sort_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,227 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_sort
-//! @{
-
-
-
-template<typename eT>
-class arma_ascend_sort_helper
-  {
-  public:
-  
-  arma_inline
-  bool
-  operator() (eT a, eT b) const
-    {
-    return (a < b);
-    }
-  };
-  
-
-
-template<typename eT>
-class arma_descend_sort_helper
-  {
-  public:
-  
-  arma_inline
-  bool
-  operator() (eT a, eT b) const
-    {
-    return (a > b);
-    }
-  };
-  
-
-
-template<typename T>
-class arma_ascend_sort_helper< std::complex<T> >
-  {
-  public:
-  
-  typedef typename std::complex<T> eT;
-  
-  inline
-  bool
-  operator() (const eT& a, const eT& b) const
-    {
-    return (std::abs(a) < std::abs(b));
-    }
-  };
-
-
-
-template<typename T>
-class arma_descend_sort_helper< std::complex<T> >
-  {
-  public:
-  
-  typedef typename std::complex<T> eT;
-  
-  inline
-  bool
-  operator() (const eT& a, const eT& b) const
-    {
-    return (std::abs(a) > std::abs(b));
-    }
-  };
-
-
-
-template<typename eT>
-inline 
-void
-op_sort::direct_sort(eT* X, const uword n_elem, const uword sort_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(sort_type == 0)
-    {
-    arma_ascend_sort_helper<eT> comparator;
-    
-    std::sort(&X[0], &X[n_elem], comparator);
-    }
-  else
-    {
-    arma_descend_sort_helper<eT> comparator;
-    
-    std::sort(&X[0], &X[n_elem], comparator);
-    }
-  }
-
-
-
-template<typename eT>
-inline 
-void
-op_sort::copy_row(eT* X, const Mat<eT>& A, const uword row)
-  {
-  const uword N = A.n_cols;
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<N; i+=2, j+=2)
-    {
-    X[i] = A.at(row,i);
-    X[j] = A.at(row,j);
-    }
-  
-  if(i < N)
-    {
-    X[i] = A.at(row,i);
-    }
-  }
-
-
-
-template<typename eT>
-inline 
-void
-op_sort::copy_row(Mat<eT>& A, const eT* X, const uword row)
-  {
-  const uword N = A.n_cols;
-  
-  uword i,j;
-  
-  for(i=0, j=1; j<N; i+=2, j+=2)
-    {
-    A.at(row,i) = X[i]; 
-    A.at(row,j) = X[j];
-    }
-  
-  if(i < N)
-    {
-    A.at(row,i) = X[i];
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_sort::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sort>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(in.m);
-  const Mat<eT>& X = tmp.M;
-  
-  const uword sort_type = in.aux_uword_a;
-  const uword dim       = in.aux_uword_b;
-  
-  arma_debug_check( (sort_type > 1),          "sort(): incorrect usage. sort_type must be 0 or 1");
-  arma_debug_check( (dim > 1),                "sort(): incorrect usage. dim must be 0 or 1"      );
-  arma_debug_check( (X.is_finite() == false), "sort(): given object has non-finite elements"     );
-  
-  if( (X.n_rows * X.n_cols) <= 1 )
-    {
-    out = X;
-    return;
-    }
-  
-  
-  if(dim == 0)  // sort the contents of each column
-    {
-    arma_extra_debug_print("op_sort::apply(), dim = 0");
-    
-    out = X;
-    
-    const uword n_rows = out.n_rows;
-    const uword n_cols = out.n_cols;
-      
-    for(uword col=0; col < n_cols; ++col)
-      {
-      op_sort::direct_sort( out.colptr(col), n_rows, sort_type );
-      }
-    }
-  else
-  if(dim == 1)  // sort the contents of each row
-    {
-    if(X.n_rows == 1)  // a row vector
-      {
-      arma_extra_debug_print("op_sort::apply(), dim = 1, vector specific");
-      
-      out = X;
-      op_sort::direct_sort(out.memptr(), out.n_elem, sort_type);
-      }
-    else  // not a row vector
-      {
-      arma_extra_debug_print("op_sort::apply(), dim = 1, generic");
-      
-      out.copy_size(X);
-      
-      const uword n_rows = out.n_rows;
-      const uword n_cols = out.n_cols;
-      
-      podarray<eT> tmp_array(n_cols);
-      
-      for(uword row=0; row < n_rows; ++row)
-        {
-        op_sort::copy_row(tmp_array.memptr(), X, row);
-        
-        op_sort::direct_sort( tmp_array.memptr(), n_cols, sort_type );
-        
-        op_sort::copy_row(out, tmp_array.memptr(), row);
-        }
-      }
-    }
-  
-  }
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_stddev_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_stddev
-//! @{
-
-//! Class for finding the standard deviation
-class op_stddev
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_stddev>& in);
-  };
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_stddev_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_stddev
-//! @{
-
-
-//! \brief
-//! For each row or for each column, find the standard deviation.
-//! The result is stored in a dense matrix that has either one column or one row.
-//! The dimension for which the standard deviations are found is set via the stddev() function.
-template<typename T1>
-inline
-void
-op_stddev::apply(Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_stddev>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type  in_eT;
-  typedef typename T1::pod_type  out_eT;
-  
-  const unwrap_check_mixed<T1> tmp(in.m, out);
-  const Mat<in_eT>&        X = tmp.M;
-  
-  const uword norm_type = in.aux_uword_a;
-  const uword dim       = in.aux_uword_b;
-  
-  arma_debug_check( (norm_type > 1), "stddev(): incorrect usage. norm_type must be 0 or 1");
-  arma_debug_check( (dim > 1),       "stddev(): incorrect usage. dim must be 0 or 1"      );
-  
-  const uword X_n_rows = X.n_rows;
-  const uword X_n_cols = X.n_cols;
-  
-  if(dim == 0)
-    {
-    arma_extra_debug_print("op_stddev::apply(), dim = 0");
-
-    arma_debug_check( (X_n_rows == 0), "stddev(): given object has zero rows" );
-    
-    out.set_size(1, X_n_cols);
-    
-    out_eT* out_mem = out.memptr();
-    
-    for(uword col=0; col<X_n_cols; ++col)
-      {
-      out_mem[col] = std::sqrt( op_var::direct_var( X.colptr(col), X_n_rows, norm_type ) );
-      }
-    }
-  else
-  if(dim == 1)
-    {
-    arma_extra_debug_print("op_stddev::apply(), dim = 1");
-    
-    arma_debug_check( (X_n_cols == 0), "stddev(): given object has zero columns" );
-
-    out.set_size(X_n_rows, 1);
-    
-    podarray<in_eT> tmp(X_n_cols);
-    
-    in_eT*  tmp_mem = tmp.memptr();
-    out_eT* out_mem = out.memptr();
-    
-    for(uword row=0; row<X_n_rows; ++row)
-      {
-      tmp.copy_row(X, row);
-      
-      out_mem[row] = std::sqrt( op_var::direct_var( tmp_mem, X_n_cols, norm_type) );
-      }
-    }
-  }
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/op_strans_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_strans
-//! @{
-
-
-//! 'matrix transpose' operation
-
-class op_strans
-  {
-  public:
-  
-  template<const bool do_flip, const uword row, const uword col>
-  struct pos
-    {
-    static const uword n2 = (do_flip == false) ? (row + col*2) : (col + row*2);
-    static const uword n3 = (do_flip == false) ? (row + col*3) : (col + row*3);
-    static const uword n4 = (do_flip == false) ? (row + col*4) : (col + row*4);
-    };
-  
-  template<typename eT>
-  inline static void apply_noalias_tinysq(Mat<eT>& out, const Mat<eT>& A);
-  
-  template<typename eT>
-  inline static void apply_noalias(Mat<eT>& out, const Mat<eT>& A);
-  
-  template<typename eT>
-  inline static void apply(Mat<eT>& out, const Mat<eT>& A);
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_strans>& in);
-  
-  
-  // inline static void apply_inplace(mat &out);
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_strans_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,258 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_strans
-//! @{
-
-
-
-//! for tiny square matrices (size <= 4x4)
-template<typename eT>
-inline
-void
-op_strans::apply_noalias_tinysq(Mat<eT>& out, const Mat<eT>& A)
-  {
-  const eT* Am   = A.memptr();
-        eT* outm = out.memptr();
-  
-  switch(A.n_rows)
-    {
-    case 1:
-      {
-      outm[0] = Am[0];
-      }
-      break;
-      
-    case 2:
-      {
-      outm[pos<false,0,0>::n2] = Am[pos<true,0,0>::n2];
-      outm[pos<false,1,0>::n2] = Am[pos<true,1,0>::n2];
-      
-      outm[pos<false,0,1>::n2] = Am[pos<true,0,1>::n2];
-      outm[pos<false,1,1>::n2] = Am[pos<true,1,1>::n2];
-      }
-      break;
-    
-    case 3:
-      {
-      outm[pos<false,0,0>::n3] = Am[pos<true,0,0>::n3];
-      outm[pos<false,1,0>::n3] = Am[pos<true,1,0>::n3];
-      outm[pos<false,2,0>::n3] = Am[pos<true,2,0>::n3];
-      
-      outm[pos<false,0,1>::n3] = Am[pos<true,0,1>::n3];
-      outm[pos<false,1,1>::n3] = Am[pos<true,1,1>::n3];
-      outm[pos<false,2,1>::n3] = Am[pos<true,2,1>::n3];
-      
-      outm[pos<false,0,2>::n3] = Am[pos<true,0,2>::n3];
-      outm[pos<false,1,2>::n3] = Am[pos<true,1,2>::n3];
-      outm[pos<false,2,2>::n3] = Am[pos<true,2,2>::n3];
-      }
-      break;
-    
-    case 4:
-      {
-      outm[pos<false,0,0>::n4] = Am[pos<true,0,0>::n4];
-      outm[pos<false,1,0>::n4] = Am[pos<true,1,0>::n4];
-      outm[pos<false,2,0>::n4] = Am[pos<true,2,0>::n4];
-      outm[pos<false,3,0>::n4] = Am[pos<true,3,0>::n4];
-      
-      outm[pos<false,0,1>::n4] = Am[pos<true,0,1>::n4];
-      outm[pos<false,1,1>::n4] = Am[pos<true,1,1>::n4];
-      outm[pos<false,2,1>::n4] = Am[pos<true,2,1>::n4];
-      outm[pos<false,3,1>::n4] = Am[pos<true,3,1>::n4];
-      
-      outm[pos<false,0,2>::n4] = Am[pos<true,0,2>::n4];
-      outm[pos<false,1,2>::n4] = Am[pos<true,1,2>::n4];
-      outm[pos<false,2,2>::n4] = Am[pos<true,2,2>::n4];
-      outm[pos<false,3,2>::n4] = Am[pos<true,3,2>::n4];
-      
-      outm[pos<false,0,3>::n4] = Am[pos<true,0,3>::n4];
-      outm[pos<false,1,3>::n4] = Am[pos<true,1,3>::n4];
-      outm[pos<false,2,3>::n4] = Am[pos<true,2,3>::n4];
-      outm[pos<false,3,3>::n4] = Am[pos<true,3,3>::n4];
-      }
-      break;
-    
-    default:
-      ;
-    }
-  
-  }
-
-
-
-//! Immediate transpose of a dense matrix
-template<typename eT>
-inline
-void
-op_strans::apply_noalias(Mat<eT>& out, const Mat<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword A_n_cols = A.n_cols;
-  const uword A_n_rows = A.n_rows;
-  
-  out.set_size(A_n_cols, A_n_rows);
-  
-  if( (A_n_cols == 1) || (A_n_rows == 1) )
-    {
-    arrayops::copy( out.memptr(), A.mem, A.n_elem );
-    }
-  else
-    {
-    if( (A_n_rows <= 4) && (A_n_rows == A_n_cols) )
-      {
-      op_strans::apply_noalias_tinysq(out, A);
-      }
-    else
-      {
-      for(uword k=0; k < A_n_cols; ++k)
-        {
-        uword i, j;
-        
-        const eT* colptr = A.colptr(k);
-        
-        for(i=0, j=1; j < A_n_rows; i+=2, j+=2)
-          {
-          const eT tmp_i = colptr[i];
-          const eT tmp_j = colptr[j];
-          
-          out.at(k, i) = tmp_i;
-          out.at(k, j) = tmp_j;
-          }
-        
-        if(i < A_n_rows)
-          {
-          out.at(k, i) = colptr[i];
-          }
-        }
-      }
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-op_strans::apply(Mat<eT>& out, const Mat<eT>& A)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(&out != &A)
-    {
-    op_strans::apply_noalias(out, A);
-    }
-  else
-    {
-    const uword n_rows = out.n_rows;
-    const uword n_cols = out.n_cols;
-      
-    if(n_rows == n_cols)
-      {
-      arma_extra_debug_print("op_strans::apply(): doing in-place transpose of a square matrix");
-      
-      const uword N = n_rows;
-      
-      for(uword k=0; k < N; ++k)
-        {
-        eT* colptr = out.colptr(k);
-        
-        uword i,j;
-        
-        for(i=(k+1), j=(k+2); j < N; i+=2, j+=2)
-          {
-          std::swap(out.at(k,i), colptr[i]);
-          std::swap(out.at(k,j), colptr[j]);
-          }
-        
-        if(i < N)
-          {
-          std::swap(out.at(k,i), colptr[i]);
-          }
-        }
-      }
-    else
-      {
-      Mat<eT> tmp;
-      op_strans::apply_noalias(tmp, A);
-      
-      out.steal_mem(tmp);
-      }
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_strans::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_strans>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(in.m);
-  const Mat<eT>& A = tmp.M;
-  
-  op_strans::apply(out, A);
-  }
-
-
-
-// inline void op_strans::apply_inplace(mat &X)
-//   {
-//   arma_extra_debug_sigprint();
-//   
-//   if((X.n_rows == 1) || (X.n_cols == 1))
-//     {
-//     const uword old_n_rows = X.n_rows;
-//     access::rw(X.n_rows) = X.n_cols;
-//     access::rw(X.n_cols) = old_n_rows;
-//     }
-//   else
-//   if(X.n_rows == X.n_cols)
-//     {
-//     for(uword col=0; col < X.n_cols; ++col)
-//       {
-//       double* X_coldata = X.colptr(col);
-//       
-//       for(uword row=(col+1); row < X.n_rows; ++row)
-//         {
-//         std::swap( A.at(col,row), A_coldata[row] );
-//         }
-//       }
-//     }
-//   else
-//     {
-//     mat tmp = trans(X);
-//     
-//     if(X.mem != X.mem_local)
-//       {
-//       double* old_mem = X.memptr();
-//       access::rw(X.mem) = tmp.memptr();
-//       access::rw(tmp.mem) = old_mem;
-//       }
-//     else
-//       {
-//       X = tmp;
-//       }
-//     }
-//   
-//   }
-
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_sum_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_sum
-//! @{
-
-//! Class for finding sums of values in a matrix  (e.g. along rows or columns)
-class op_sum
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1, op_sum>& in);
-  };
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_sum_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_sum
-//! @{
-
-//! \brief
-//! Immediate sum of elements of a matrix along a specified dimension (either rows or columns).
-//! The result is stored in a dense matrix that has either one column or one row.
-//! See the sum() function for more details.
-template<typename T1>
-inline
-void
-op_sum::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sum>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword dim = in.aux_uword_a;
-  arma_debug_check( (dim > 1), "sum(): incorrect usage. dim must be 0 or 1");
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap_check<T1> tmp(in.m, out);
-  const Mat<eT>& X     = tmp.M;
-  
-  const uword X_n_rows = X.n_rows;
-  const uword X_n_cols = X.n_cols;
-  
-  if(dim == 0)  // traverse across rows (i.e. find the sum in each column)
-    {
-    out.set_size(1, X_n_cols);
-
-    eT* out_mem = out.memptr();
-    
-    for(uword col=0; col<X_n_cols; ++col)
-      {
-      out_mem[col] = arrayops::accumulate(X.colptr(col), X_n_rows);
-      }
-    }
-  else  // traverse across columns (i.e. find the sum in each row)
-    {
-    out.set_size(X_n_rows, 1);
-    
-    eT* out_mem = out.memptr();
-      
-    for(uword row=0; row<X_n_rows; ++row)
-      {
-      eT val = eT(0);
-        
-      for(uword col=0; col<X_n_cols; ++col)
-        {
-        val += X.at(row,col);
-        }
-      
-      out_mem[row] = val;
-      }
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_symmat_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_symmat
-//! @{
-
-
-
-class op_symmat
-  {
-  public:
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_symmat>& in, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0);
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_symmat>& in, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_symmat_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_symmat
-//! @{
-
-
-
-template<typename T1>
-inline
-void
-op_symmat::apply
-  (
-        Mat<typename T1::elem_type>& out,
-  const Op<T1,op_symmat>&            in,
-  const typename arma_not_cx<typename T1::elem_type>::result* junk
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1> tmp(in.m);
-  const Mat<eT>& A = tmp.M;
-  
-  arma_debug_check( (A.is_square() == false), "symmatu()/symmatl(): given matrix must be square" );
-  
-  const uword  N     = A.n_rows;
-  const bool upper = (in.aux_uword_a == 0);
-  
-  if(&out != &A)
-    {
-    out.copy_size(A);
-    
-    if(upper)
-      {
-      // upper triangular: copy the diagonal and the elements above the diagonal
-      
-      for(uword i=0; i<N; ++i)
-        {
-        const eT* A_data   = A.colptr(i);
-              eT* out_data = out.colptr(i);
-        
-        arrayops::copy( out_data, A_data, i+1 );
-        }
-      }
-    else
-      {
-      // lower triangular: copy the diagonal and the elements below the diagonal
-      
-      for(uword i=0; i<N; ++i)
-        {
-        const eT* A_data   = A.colptr(i);
-              eT* out_data = out.colptr(i);
-        
-        arrayops::copy( &out_data[i], &A_data[i], N-i );
-        }
-      }
-    }
-  
-  
-  if(upper)
-    {
-    // reflect elements across the diagonal from upper triangle to lower triangle
-    
-    for(uword col=1; col < N; ++col)
-      {
-      const eT* coldata = out.colptr(col);
-      
-      for(uword row=0; row < col; ++row)
-        {
-        out.at(col,row) = coldata[row];
-        }
-      }
-    }
-  else
-    {
-    // reflect elements across the diagonal from lower triangle to upper triangle
-    
-    for(uword col=0; col < N; ++col)
-      {
-      const eT* coldata = out.colptr(col);
-      
-      for(uword row=(col+1); row < N; ++row)
-        {
-        out.at(col,row) = coldata[row];
-        }
-      }
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_symmat::apply
-  (
-        Mat<typename T1::elem_type>& out,
-  const Op<T1,op_symmat>&            in,
-  const typename arma_cx_only<typename T1::elem_type>::result* junk
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1> tmp(in.m);
-  const Mat<eT>& A = tmp.M;
-  
-  arma_debug_check( (A.is_square() == false), "symmatu()/symmatl(): given matrix must be square" );
-  
-  const uword  N     = A.n_rows;
-  const bool upper = (in.aux_uword_a == 0);
-  
-  if(&out != &A)
-    {
-    out.copy_size(A);
-    
-    if(upper)
-      {
-      // upper triangular: copy the diagonal and the elements above the diagonal
-      
-      for(uword i=0; i<N; ++i)
-        {
-        const eT* A_data   = A.colptr(i);
-              eT* out_data = out.colptr(i);
-        
-        arrayops::copy( out_data, A_data, i+1 );
-        }
-      }
-    else
-      {
-      // lower triangular: copy the diagonal and the elements below the diagonal
-      
-      for(uword i=0; i<N; ++i)
-        {
-        const eT* A_data   = A.colptr(i);
-              eT* out_data = out.colptr(i);
-        
-        arrayops::copy( &out_data[i], &A_data[i], N-i );
-        }
-      }
-    }
-  
-  
-  if(upper)
-    {
-    // reflect elements across the diagonal from upper triangle to lower triangle
-    
-    for(uword col=1; col < N; ++col)
-      {
-      const eT* coldata = out.colptr(col);
-      
-      for(uword row=0; row < col; ++row)
-        {
-        out.at(col,row) = std::conj(coldata[row]);
-        }
-      }
-    }
-  else
-    {
-    // reflect elements across the diagonal from lower triangle to upper triangle
-    
-    for(uword col=0; col < N; ++col)
-      {
-      const eT* coldata = out.colptr(col);
-      
-      for(uword row=(col+1); row < N; ++row)
-        {
-        out.at(col,row) = std::conj(coldata[row]);
-        }
-      }
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_trimat_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// Copyright (C) 2011 Ryan Curtin
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_trimat
-//! @{
-
-
-
-class op_trimat
-  {
-  public:
-  
-  template<typename eT>
-  inline static void fill_zeros(Mat<eT>& A, const bool upper);
-  
-  //
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_trimat>& in);
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::elem_type>& out, const Op<Op<T1,op_htrans>, op_trimat>& in);
-  
-  //
-  
-  template<typename eT>
-  inline static void apply_htrans(Mat<eT>& out, const Mat<eT>& A, const bool upper, const typename arma_not_cx<eT>::result* junk = 0);
-  
-  template<typename eT>
-  inline static void apply_htrans(Mat<eT>& out, const Mat<eT>& A, const bool upper, const typename arma_cx_only<eT>::result* junk = 0);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_trimat_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,248 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// Copyright (C) 2011      Ryan Curtin
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_trimat
-//! @{
-
-
-
-template<typename eT>
-inline
-void
-op_trimat::fill_zeros(Mat<eT>& out, const bool upper)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword N = out.n_rows;
-  
-  if(upper)
-    {
-    // upper triangular: set all elements below the diagonal to zero
-    
-    for(uword i=0; i<N; ++i)
-      {
-      eT* data = out.colptr(i);
-      
-      arrayops::inplace_set( &data[i+1], eT(0), (N-(i+1)) );
-      }
-    }
-  else
-    {
-    // lower triangular: set all elements above the diagonal to zero
-    
-    for(uword i=1; i<N; ++i)
-      {
-      eT* data = out.colptr(i);
-      
-      arrayops::inplace_set( data, eT(0), i );
-      }
-    }
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_trimat::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_trimat>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1> tmp(in.m);
-  const Mat<eT>& A = tmp.M;
-  
-  arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square" );
-  
-  const uword  N     = A.n_rows;
-  const bool upper = (in.aux_uword_a == 0);
-  
-  if(&out != &A)
-    {
-    out.copy_size(A);
-    
-    if(upper)
-      {
-      // upper triangular: copy the diagonal and the elements above the diagonal
-      for(uword i=0; i<N; ++i)
-        {
-        const eT* A_data   = A.colptr(i);
-              eT* out_data = out.colptr(i);
-        
-        arrayops::copy( out_data, A_data, i+1 );
-        }
-      }
-    else
-      {
-      // lower triangular: copy the diagonal and the elements below the diagonal
-      for(uword i=0; i<N; ++i)
-        {
-        const eT* A_data   = A.colptr(i);
-              eT* out_data = out.colptr(i);
-        
-        arrayops::copy( &out_data[i], &A_data[i], N-i );
-        }
-      }
-    }
-  
-  op_trimat::fill_zeros(out, upper);
-  }
-
-
-
-template<typename T1>
-inline
-void
-op_trimat::apply(Mat<typename T1::elem_type>& out, const Op<Op<T1, op_htrans>, op_trimat>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT;
-  
-  const unwrap<T1>   tmp(in.m.m);
-  const Mat<eT>& A = tmp.M;
-  
-  const bool upper = (in.aux_uword_a == 0);
-  
-  op_trimat::apply_htrans(out, A, upper);
-  }
-
-
-
-template<typename eT>
-inline
-void
-op_trimat::apply_htrans
-  (
-        Mat<eT>& out,
-  const Mat<eT>& A,
-  const bool     upper,
-  const typename arma_not_cx<eT>::result* junk
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  // This specialisation is for trimatl(trans(X)) = trans(trimatu(X)) and also
-  // trimatu(trans(X)) = trans(trimatl(X)).  We want to avoid the creation of an
-  // extra temporary.
-  
-  // It doesn't matter if the input and output matrices are the same; we will
-  // pull data from the upper or lower triangular to the lower or upper
-  // triangular (respectively) and then set the rest to 0, so overwriting issues
-  // aren't present.
-  
-  arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square" );
-  
-  const uword N = A.n_rows;
-  
-  if(&out != &A)
-    {
-    out.copy_size(A);
-    }
-  
-  // We can't really get away with any array copy operations here,
-  // unfortunately...
-  
-  if(upper)
-    {
-    // Upper triangular: but since we're transposing, we're taking the lower
-    // triangular and putting it in the upper half.
-    for(uword row = 0; row < N; ++row)
-      {
-      eT* out_colptr = out.colptr(row);
-      
-      for(uword col = 0; col <= row; ++col)
-        {
-        //out.at(col, row) = A.at(row, col);
-        out_colptr[col] = A.at(row, col);
-        }
-      }
-    }
-  else
-    {
-    // Lower triangular: but since we're transposing, we're taking the upper
-    // triangular and putting it in the lower half.
-    for(uword row = 0; row < N; ++row)
-      {
-      for(uword col = row; col < N; ++col)
-        {
-        out.at(col, row) = A.at(row, col);
-        }
-      }
-    }
-  
-  op_trimat::fill_zeros(out, upper);
-  }
-
-
-
-template<typename eT>
-inline
-void
-op_trimat::apply_htrans
-  (
-        Mat<eT>& out,
-  const Mat<eT>& A,
-  const bool     upper,
-  const typename arma_cx_only<eT>::result* junk
-  )
-  {
-  arma_extra_debug_sigprint();
-  arma_ignore(junk);
-  
-  arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square" );
-  
-  const uword N = A.n_rows;
-  
-  if(&out != &A)
-    {
-    out.copy_size(A);
-    }
-  
-  if(upper)
-    {
-    // Upper triangular: but since we're transposing, we're taking the lower
-    // triangular and putting it in the upper half.
-    for(uword row = 0; row < N; ++row)
-      {
-      eT* out_colptr = out.colptr(row);
-      
-      for(uword col = 0; col <= row; ++col)
-        {
-        //out.at(col, row) = std::conj( A.at(row, col) );
-        out_colptr[col] = std::conj( A.at(row, col) );
-        }
-      }
-    }
-  else
-    {
-    // Lower triangular: but since we're transposing, we're taking the upper
-    // triangular and putting it in the lower half.
-    for(uword row = 0; row < N; ++row)
-      {
-      for(uword col = row; col < N; ++col)
-        {
-        out.at(col, row) = std::conj( A.at(row, col) );
-        }
-      }
-    }
-  
-  op_trimat::fill_zeros(out, upper);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_var_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_var
-//! @{
-
-
-
-//! Class for finding variance values of a matrix
-class op_var
-  {
-  public:
-  
-  template<typename eT>
-  inline static eT direct_var(const eT* const X, const uword N, const uword norm_type = 0);
-  
-  template<typename T>
-  inline static  T direct_var(const std::complex<T>* const X, const uword N, const uword norm_type = 0);
-  
-  
-  template<typename eT>
-  inline static typename get_pod_type<eT>::result direct_var(const subview_row<eT>& X, const uword norm_type = 0);
-  
-  template<typename eT>
-  inline static typename get_pod_type<eT>::result direct_var(const subview_col<eT>& X, const uword norm_type = 0);
-  
-  template<typename eT>
-  inline static typename get_pod_type<eT>::result direct_var(const diagview<eT>& X, const uword norm_type = 0);
-  
-  
-  template<typename T1>
-  inline static void apply(Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_var>& in);
-  
-  
-  template<typename eT>
-  inline static eT direct_var_robust(const eT* const X, const uword N, const uword norm_type = 0);
-  
-  template<typename T>
-  inline static  T direct_var_robust(const std::complex<T>* const X, const uword N, const uword norm_type = 0);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/op_var_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,304 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup op_var
-//! @{
-
-
-//! find the variance of an array
-template<typename eT>
-inline
-eT
-op_var::direct_var(const eT* const X, const uword n_elem, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(n_elem >= 2)
-    {
-    const eT acc1 = op_mean::direct_mean(X, n_elem);
-    
-    eT acc2 = eT(0);
-    eT acc3 = eT(0);
-    
-    uword i,j;
-    
-    for(i=0, j=1; j<n_elem; i+=2, j+=2)
-      {
-      const eT Xi = X[i];
-      const eT Xj = X[j];
-      
-      const eT tmpi = acc1 - Xi;
-      const eT tmpj = acc1 - Xj;
-      
-      acc2 += tmpi*tmpi + tmpj*tmpj;
-      acc3 += tmpi      + tmpj;
-      }
-    
-    if(i < n_elem)
-      {
-      const eT Xi = X[i];
-      
-      const eT tmpi = acc1 - Xi;
-      
-      acc2 += tmpi*tmpi;
-      acc3 += tmpi;
-      }
-    
-    const eT norm_val = (norm_type == 0) ? eT(n_elem-1) : eT(n_elem);
-    const eT var_val  = (acc2 - acc3*acc3/eT(n_elem)) / norm_val;
-    
-    return arma_isfinite(var_val) ? var_val : op_var::direct_var_robust(X, n_elem, norm_type);
-    }
-  else
-    {
-    return eT(0);
-    }
-  }
-
-
-
-//! find the variance of an array (version for complex numbers)
-template<typename T>
-inline
-T
-op_var::direct_var(const std::complex<T>* const X, const uword n_elem, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T> eT;
-  
-  if(n_elem >= 2)
-    {
-    const eT acc1 = op_mean::direct_mean(X, n_elem);
-    
-    T  acc2 =  T(0);
-    eT acc3 = eT(0);
-    
-    for(uword i=0; i<n_elem; ++i)
-      {
-      const eT tmp = acc1 - X[i];
-      
-      acc2 += std::norm(tmp);
-      acc3 += tmp;
-      }
-    
-    const T norm_val = (norm_type == 0) ? T(n_elem-1) : T(n_elem);
-    const T var_val  = (acc2 - std::norm(acc3)/T(n_elem)) / norm_val;
-    
-    return arma_isfinite(var_val) ? var_val : op_var::direct_var_robust(X, n_elem, norm_type);
-    }
-  else
-    {
-    return T(0);
-    }
-  }
-
-
-
-//! find the variance of a subview_row
-template<typename eT>
-inline 
-typename get_pod_type<eT>::result
-op_var::direct_var(const subview_row<eT>& X, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword n_elem = X.n_elem;
-  
-  podarray<eT> tmp(n_elem);
-  
-  eT* tmp_mem = tmp.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    tmp_mem[i] = X[i];
-    }
-  
-  return op_var::direct_var(tmp_mem, n_elem, norm_type);
-  }
-
-
-
-//! find the variance of a subview_col
-template<typename eT>
-inline 
-typename get_pod_type<eT>::result
-op_var::direct_var(const subview_col<eT>& X, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  return op_var::direct_var(X.colptr(0), X.n_elem, norm_type);
-  }
-
-
-
-//! find the variance of a diagview
-template<typename eT>
-inline 
-typename get_pod_type<eT>::result
-op_var::direct_var(const diagview<eT>& X, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword n_elem = X.n_elem;
-  
-  podarray<eT> tmp(n_elem);
-  
-  eT* tmp_mem = tmp.memptr();
-  
-  for(uword i=0; i<n_elem; ++i)
-    {
-    tmp_mem[i] = X[i];
-    }
-  
-  return op_var::direct_var(tmp_mem, n_elem, norm_type);
-  }
-
-
-
-//! \brief
-//! For each row or for each column, find the variance.
-//! The result is stored in a dense matrix that has either one column or one row.
-//! The dimension, for which the variances are found, is set via the var() function.
-template<typename T1>
-inline
-void
-op_var::apply(Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_var>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type  in_eT;
-  typedef typename T1::pod_type  out_eT;
-  
-  const unwrap_check_mixed<T1> tmp(in.m, out);
-  const Mat<in_eT>&        X = tmp.M;
-  
-  const uword norm_type = in.aux_uword_a;
-  const uword dim       = in.aux_uword_b;
-  
-  arma_debug_check( (norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1");
-  arma_debug_check( (dim > 1),       "var(): incorrect usage. dim must be 0 or 1"      );
-  
-  const uword X_n_rows = X.n_rows;
-  const uword X_n_cols = X.n_cols;
-  
-  if(dim == 0)
-    {
-    arma_extra_debug_print("op_var::apply(), dim = 0");
-    
-    arma_debug_check( (X_n_rows == 0), "var(): given object has zero rows" );
-
-    out.set_size(1, X_n_cols);
-    
-    out_eT* out_mem = out.memptr();
-    
-    for(uword col=0; col<X_n_cols; ++col)
-      {
-      out_mem[col] = op_var::direct_var( X.colptr(col), X_n_rows, norm_type );
-      }
-    }
-  else
-  if(dim == 1)
-    {
-    arma_extra_debug_print("op_var::apply(), dim = 1");
-    
-    arma_debug_check( (X_n_cols == 0), "var(): given object has zero columns" );
-
-    out.set_size(X_n_rows, 1);
-    
-    podarray<in_eT> tmp(X_n_cols);
-    
-    in_eT*  tmp_mem = tmp.memptr();
-    out_eT* out_mem = out.memptr();
-    
-    for(uword row=0; row<X_n_rows; ++row)
-      {
-      tmp.copy_row(X, row);
-      
-      out_mem[row] = op_var::direct_var( tmp_mem, X_n_cols, norm_type );
-      }
-    }
-  }
-
-
-
-//! find the variance of an array (robust but slow)
-template<typename eT>
-inline
-eT
-op_var::direct_var_robust(const eT* const X, const uword n_elem, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(n_elem > 1)
-    {
-    eT r_mean = X[0];
-    eT r_var  = eT(0);
-    
-    for(uword i=1; i<n_elem; ++i)
-      {
-      const eT tmp      = X[i] - r_mean;
-      const eT i_plus_1 = eT(i+1);
-      
-      r_var  = eT(i-1)/eT(i) * r_var + (tmp*tmp)/i_plus_1;
-      
-      r_mean = r_mean + tmp/i_plus_1;
-      }
-    
-    return (norm_type == 0) ? r_var : (eT(n_elem-1)/eT(n_elem)) * r_var;
-    }
-  else
-    {
-    return eT(0);
-    }
-  }
-
-
-
-//! find the variance of an array (version for complex numbers) (robust but slow)
-template<typename T>
-inline
-T
-op_var::direct_var_robust(const std::complex<T>* const X, const uword n_elem, const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T> eT;
-  
-  if(n_elem > 1)
-    {
-    eT r_mean = X[0];
-     T r_var  = T(0);
-    
-    for(uword i=1; i<n_elem; ++i)
-      {
-      const eT tmp      = X[i] - r_mean;
-      const  T i_plus_1 = T(i+1);
-      
-      r_var  = T(i-1)/T(i) * r_var + std::norm(tmp)/i_plus_1;
-      
-      r_mean = r_mean + tmp/i_plus_1;
-      }
-    
-    return (norm_type == 0) ? r_var : (T(n_elem-1)/T(n_elem)) * r_var;
-    }
-  else
-    {
-    return T(0);
-    }
-  }
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_bits/operator_cube_div.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup operator_cube_div
-//! @{
-
-  
-
-//! BaseCube / scalar
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_scalar_div_post>
-operator/
-  (
-  const BaseCube<typename T1::elem_type,T1>& X,
-  const typename T1::elem_type               k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_scalar_div_post>(X.get_ref(), k);
-  }
-
-
-
-//! scalar / BaseCube
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_scalar_div_pre>
-operator/
-  (
-  const typename T1::elem_type               k,
-  const BaseCube<typename T1::elem_type,T1>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_scalar_div_pre>(X.get_ref(), k);
-  }
-
-
-
-//! complex scalar / non-complex BaseCube (experimental)
-template<typename T1>
-arma_inline
-const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>
-operator/
-  (
-  const std::complex<typename T1::pod_type>& k,
-  const BaseCube<typename T1::pod_type, T1>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>('j', X.get_ref(), k);
-  }
-
-
-
-//! non-complex BaseCube / complex scalar (experimental)
-template<typename T1>
-arma_inline
-const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>
-operator/
-  (
-  const BaseCube<typename T1::pod_type, T1>& X,
-  const std::complex<typename T1::pod_type>& k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>('j', X.get_ref(), k);
-  }
-
-
-
-//! element-wise division of BaseCube objects with same element type
-template<typename T1, typename T2>
-arma_inline
-const eGlueCube<T1, T2, eglue_div>
-operator/
-  (
-  const BaseCube<typename T1::elem_type,T1>& X,
-  const BaseCube<typename T1::elem_type,T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eGlueCube<T1, T2, eglue_div>(X.get_ref(), Y.get_ref());
-  }
-
-
-
-//! element-wise division of BaseCube objects with different element types
-template<typename T1, typename T2>
-inline
-const mtGlueCube<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_div>
-operator/
-  (
-  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T1_result, T1>& X,
-  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T2_result, T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  return mtGlueCube<out_eT, T1, T2, glue_mixed_div>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/operator_cube_minus.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup operator_cube_minus
-//! @{
-
-
-
-//! unary -
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_neg>
-operator-
-  (
-  const BaseCube<typename T1::elem_type,T1>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_neg>(X.get_ref());
-  }
-
-
-
-//! cancellation of two consecutive negations: -(-T1)
-template<typename T1>
-arma_inline
-const T1&
-operator-
-  (
-  const eOpCube<T1, eop_neg>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return X.m;
-  }
-
-
-
-//! BaseCube - scalar
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_scalar_minus_post>
-operator-
-  (
-  const BaseCube<typename T1::elem_type,T1>& X,
-  const typename T1::elem_type               k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_scalar_minus_post>(X.get_ref(), k);
-  }
-
-
-
-//! scalar - BaseCube
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_scalar_minus_pre>
-operator-
-  (
-  const typename T1::elem_type               k,
-  const BaseCube<typename T1::elem_type,T1>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_scalar_minus_pre>(X.get_ref(), k);
-  }
-
-
-
-//! complex scalar - non-complex BaseCube (experimental)
-template<typename T1>
-arma_inline
-const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>
-operator-
-  (
-  const std::complex<typename T1::pod_type>& k,
-  const BaseCube<typename T1::pod_type, T1>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>('j', X.get_ref(), k);
-  }
-
-
-
-//! non-complex BaseCube - complex scalar (experimental)
-template<typename T1>
-arma_inline
-const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>
-operator-
-  (
-  const BaseCube<typename T1::pod_type, T1>& X,
-  const std::complex<typename T1::pod_type>& k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>('j', X.get_ref(), k);
-  }
-
-
-
-//! subtraction of BaseCube objects with same element type
-template<typename T1, typename T2>
-arma_inline
-const eGlueCube<T1, T2, eglue_minus>
-operator-
-  (
-  const BaseCube<typename T1::elem_type,T1>& X,
-  const BaseCube<typename T1::elem_type,T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eGlueCube<T1, T2, eglue_minus>(X.get_ref(), Y.get_ref());
-  }
-
-
-
-//! subtraction of BaseCube objects with different element types
-template<typename T1, typename T2>
-inline
-const mtGlueCube<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_minus>
-operator-
-  (
-  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T1_result, T1>& X,
-  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T2_result, T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  return mtGlueCube<out_eT, T1, T2, glue_mixed_minus>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/operator_cube_plus.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup operator_cube_plus
-//! @{
-
-
-
-//! unary plus operation (does nothing, but is required for completeness)
-template<typename T1>
-arma_inline
-const BaseCube<typename T1::elem_type,T1>&
-operator+
-  (
-  const BaseCube<typename T1::elem_type,T1>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return X;
-  }
-
-
-
-//! BaseCube + scalar
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_scalar_plus>
-operator+
-  (
-  const BaseCube<typename T1::elem_type,T1>& X,
-  const typename T1::elem_type               k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_scalar_plus>(X.get_ref(), k);
-  }
-
-
-
-//! scalar + BaseCube
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_scalar_plus>
-operator+
-  (
-  const typename T1::elem_type               k,
-  const BaseCube<typename T1::elem_type,T1>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_scalar_plus>(X.get_ref(), k);
-  }
-
-
-
-//! non-complex BaseCube + complex scalar (experimental)
-template<typename T1>
-arma_inline
-const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>
-operator+
-  (
-  const BaseCube<typename T1::pod_type, T1>& X,
-  const std::complex<typename T1::pod_type>& k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>('j', X.get_ref(), k);
-  }
-
-
-
-//! complex scalar + non-complex BaseCube (experimental)
-template<typename T1>
-arma_inline
-const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>
-operator+
-  (
-  const std::complex<typename T1::pod_type>& k,
-  const BaseCube<typename T1::pod_type, T1>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>('j', X.get_ref(), k);  // NOTE: order is swapped
-  }
-
-
-
-//! addition of BaseCube objects with same element type
-template<typename T1, typename T2>
-arma_inline
-const eGlueCube<T1, T2, eglue_plus>
-operator+
-  (
-  const BaseCube<typename T1::elem_type,T1>& X,
-  const BaseCube<typename T1::elem_type,T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eGlueCube<T1, T2, eglue_plus>(X.get_ref(), Y.get_ref());
-  }
-
-
-
-//! addition of BaseCube objects with different element types
-template<typename T1, typename T2>
-inline
-const mtGlueCube<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_plus>
-operator+
-  (
-  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T1_result, T1>& X,
-  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T2_result, T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  return mtGlueCube<out_eT, T1, T2, glue_mixed_plus>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/operator_cube_relational.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,268 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup operator_cube_relational
-//! @{
-
-
-
-// <  : lt
-// >  : gt
-// <= : lteq
-// >= : gteq
-// == : eq
-// != : noteq
-
-
-
-template<typename T1, typename T2>
-inline
-const mtGlueCube<uword, T1, T2, glue_rel_lt>
-operator<
-(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtGlueCube<uword, T1, T2, glue_rel_lt>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const mtGlueCube<uword, T1, T2, glue_rel_gt>
-operator>
-(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtGlueCube<uword, T1, T2, glue_rel_gt>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const mtGlueCube<uword, T1, T2, glue_rel_lteq>
-operator<=
-(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtGlueCube<uword, T1, T2, glue_rel_lteq>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const mtGlueCube<uword, T1, T2, glue_rel_gteq>
-operator>=
-(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtGlueCube<uword, T1, T2, glue_rel_gteq>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const mtGlueCube<uword, T1, T2, glue_rel_eq>
-operator==
-(const BaseCube<typename T1::elem_type,T1>& X, const BaseCube<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtGlueCube<uword, T1, T2, glue_rel_eq>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const mtGlueCube<uword, T1, T2, glue_rel_noteq>
-operator!=
-(const BaseCube<typename T1::elem_type,T1>& X, const BaseCube<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtGlueCube<uword, T1, T2, glue_rel_noteq>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-//
-//
-//
-
-
-
-template<typename T1>
-inline
-const mtOpCube<uword, T1, op_rel_lt_pre>
-operator<
-(const typename arma_not_cx<typename T1::elem_type>::result val, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<uword, T1, op_rel_lt_pre>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<uword, T1, op_rel_lt_post>
-operator<
-(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result val)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<uword, T1, op_rel_lt_post>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<uword, T1, op_rel_gt_pre>
-operator>
-(const typename arma_not_cx<typename T1::elem_type>::result val, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<uword, T1, op_rel_gt_pre>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<uword, T1, op_rel_gt_post>
-operator>
-(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result val)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<uword, T1, op_rel_gt_post>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<uword, T1, op_rel_lteq_pre>
-operator<=
-(const typename arma_not_cx<typename T1::elem_type>::result val, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<uword, T1, op_rel_lteq_pre>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<uword, T1, op_rel_lteq_post>
-operator<=
-(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result val)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<uword, T1, op_rel_lteq_post>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<uword, T1, op_rel_gteq_pre>
-operator>=
-(const typename arma_not_cx<typename T1::elem_type>::result val, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<uword, T1, op_rel_gteq_pre>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<uword, T1, op_rel_gteq_post>
-operator>=
-(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result val)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<uword, T1, op_rel_gteq_post>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<uword, T1, op_rel_eq>
-operator==
-(const typename T1::elem_type val, const BaseCube<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<uword, T1, op_rel_eq>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<uword, T1, op_rel_eq>
-operator==
-(const BaseCube<typename T1::elem_type,T1>& X, const typename T1::elem_type val)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<uword, T1, op_rel_eq>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<uword, T1, op_rel_noteq>
-operator!=
-(const typename T1::elem_type val, const BaseCube<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<uword, T1, op_rel_noteq>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOpCube<uword, T1, op_rel_noteq>
-operator!=
-(const BaseCube<typename T1::elem_type,T1>& X, const typename T1::elem_type val)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<uword, T1, op_rel_noteq>(X.get_ref(), val);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/operator_cube_schur.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup operator_cube_schur
-//! @{
-
-
-// operator %, which we define it to do a schur product (element-wise multiplication)
-
-
-//! element-wise multiplication of BaseCube objects with same element type
-template<typename T1, typename T2>
-arma_inline
-const eGlueCube<T1, T2, eglue_schur>
-operator%
-  (
-  const BaseCube<typename T1::elem_type,T1>& X,
-  const BaseCube<typename T1::elem_type,T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eGlueCube<T1, T2, eglue_schur>(X.get_ref(), Y.get_ref());
-  }
-
-
-
-//! element-wise multiplication of BaseCube objects with different element types
-template<typename T1, typename T2>
-inline
-const mtGlueCube<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_schur>
-operator%
-  (
-  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T1_result, T1>& X,
-  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T2_result, T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  return mtGlueCube<out_eT, T1, T2, glue_mixed_schur>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/operator_cube_times.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-
-//! \addtogroup operator_cube_times
-//! @{
-
-
-
-//! BaseCube * scalar
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_scalar_times>
-operator*
-  (
-  const BaseCube<typename T1::elem_type,T1>& X,
-  const typename T1::elem_type               k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_scalar_times>(X.get_ref(), k);
-  }
-
-
-
-//! scalar * BaseCube
-template<typename T1>
-arma_inline
-const eOpCube<T1, eop_scalar_times>
-operator*
-  (
-  const typename T1::elem_type               k,
-  const BaseCube<typename T1::elem_type,T1>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOpCube<T1, eop_scalar_times>(X.get_ref(), k);
-  }
-
-
-
-//! non-complex BaseCube * complex scalar (experimental)
-template<typename T1>
-arma_inline
-const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>
-operator*
-  (
-  const BaseCube<typename T1::pod_type, T1>& X,
-  const std::complex<typename T1::pod_type>& k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>('j', X.get_ref(), k);
-  }
-
-
-
-//! complex scalar * non-complex BaseCube (experimental)
-template<typename T1>
-arma_inline
-const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>
-operator*
-  (
-  const std::complex<typename T1::pod_type>& k,
-  const BaseCube<typename T1::pod_type, T1>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>('j', X.get_ref(), k);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/operator_div.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup operator_div
-//! @{
-
-
-
-//! Base / scalar
-template<typename T1>
-arma_inline
-const eOp<T1, eop_scalar_div_post>
-operator/
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const typename T1::elem_type           k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_scalar_div_post>(X.get_ref(), k);
-  }
-
-
-
-//! scalar / Base
-template<typename T1>
-arma_inline
-const eOp<T1, eop_scalar_div_pre>
-operator/
-  (
-  const typename T1::elem_type           k,
-  const Base<typename T1::elem_type,T1>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_scalar_div_pre>(X.get_ref(), k);
-  }
-
-
-
-//! complex scalar / non-complex Base (experimental)
-template<typename T1>
-arma_inline
-const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>
-operator/
-  (
-  const std::complex<typename T1::pod_type>& k,
-  const Base<typename T1::pod_type, T1>&     X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>('j', X.get_ref(), k);
-  }
-
-
-
-//! non-complex Base / complex scalar (experimental)
-template<typename T1>
-arma_inline
-const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>
-operator/
-  (
-  const Base<typename T1::pod_type, T1>&     X,
-  const std::complex<typename T1::pod_type>& k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>('j', X.get_ref(), k);
-  }
-
-
-
-//! element-wise division of Base objects with same element type
-template<typename T1, typename T2>
-arma_inline
-const eGlue<T1, T2, eglue_div>
-operator/
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const Base<typename T1::elem_type,T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eGlue<T1, T2, eglue_div>(X.get_ref(), Y.get_ref());
-  }
-
-
-
-//! element-wise division of Base objects with different element types
-template<typename T1, typename T2>
-inline
-const mtGlue<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_div>
-operator/
-  (
-  const Base< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T1_result, T1>& X,
-  const Base< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T2_result, T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  return mtGlue<out_eT, T1, T2, glue_mixed_div>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/operator_minus.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup operator_minus
-//! @{
-
-
-
-//! unary -
-template<typename T1>
-arma_inline
-const eOp<T1, eop_neg>
-operator-
-(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1,eop_neg>(X.get_ref());
-  }
-
-
-
-//! cancellation of two consecutive negations: -(-T1)
-template<typename T1>
-arma_inline
-const T1&
-operator-
-(const eOp<T1, eop_neg>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return X.m;
-  }
-
-
-
-//! Base - scalar
-template<typename T1>
-arma_inline
-const eOp<T1, eop_scalar_minus_post>
-operator-
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const typename T1::elem_type           k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_scalar_minus_post>(X.get_ref(), k);
-  }
-
-
-
-//! scalar - Base
-template<typename T1>
-arma_inline
-const eOp<T1, eop_scalar_minus_pre>
-operator-
-  (
-  const typename T1::elem_type           k,
-  const Base<typename T1::elem_type,T1>& X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_scalar_minus_pre>(X.get_ref(), k);
-  }
-
-
-
-//! complex scalar - non-complex Base (experimental)
-template<typename T1>
-arma_inline
-const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>
-operator-
-  (
-  const std::complex<typename T1::pod_type>& k,
-  const Base<typename T1::pod_type, T1>&     X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>('j', X.get_ref(), k);
-  }
-
-
-
-//! non-complex Base - complex scalar (experimental)
-template<typename T1>
-arma_inline
-const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>
-operator-
-  (
-  const Base<typename T1::pod_type, T1>&     X,
-  const std::complex<typename T1::pod_type>& k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>('j', X.get_ref(), k);
-  }
-
-
-
-//! subtraction of Base objects with same element type
-template<typename T1, typename T2>
-arma_inline
-const eGlue<T1, T2, eglue_minus>
-operator-
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const Base<typename T1::elem_type,T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eGlue<T1, T2, eglue_minus>(X.get_ref(), Y.get_ref());
-  }
-
-
-
-//! subtraction of Base objects with different element types
-template<typename T1, typename T2>
-inline
-const mtGlue<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_minus>
-operator-
-  (
-  const Base< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T1_result, T1>& X,
-  const Base< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T2_result, T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  return mtGlue<out_eT, T1, T2, glue_mixed_minus>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/operator_ostream.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup operator_ostream
-//! @{
-
-
-
-template<typename eT, typename T1>
-inline
-std::ostream&
-operator<< (std::ostream& o, const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1> tmp(X.get_ref());
-  
-  arma_ostream::print(o, tmp.M, true);
-  
-  return o;
-  }
-
-
-
-template<typename T1>
-inline
-std::ostream&
-operator<< (std::ostream& o, const BaseCube<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap_cube<T1> tmp(X.get_ref());
-  
-  arma_ostream::print(o, tmp.M, true);
-  
-  return o;
-  }
-
-
-
-//! Print the contents of a field to the specified stream.
-template<typename T1>
-inline
-std::ostream&
-operator<< (std::ostream& o, const field<T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ostream::print(o, X);
-  
-  return o;
-  }
-
-
-
-//! Print the contents of a subfield to the specified stream
-template<typename T1>
-inline
-std::ostream&
-operator<< (std::ostream& o, const subview_field<T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_ostream::print(o, X);
-
-  return o;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/operator_plus.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup operator_plus
-//! @{
-
-
-
-//! unary plus operation (does nothing, but is required for completeness)
-template<typename T1>
-arma_inline
-const Base<typename T1::elem_type,T1>&
-operator+
-(const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return X;
-  }
-
-
-
-//! Base + scalar
-template<typename T1>
-arma_inline
-const eOp<T1, eop_scalar_plus>
-operator+
-(const Base<typename T1::elem_type,T1>& X, const typename T1::elem_type k)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_scalar_plus>(X.get_ref(), k);
-  }
-
-
-
-//! scalar + Base
-template<typename T1>
-arma_inline
-const eOp<T1, eop_scalar_plus>
-operator+
-(const typename T1::elem_type k, const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_scalar_plus>(X.get_ref(), k);  // NOTE: order is swapped
-  }
-
-
-
-//! non-complex Base + complex scalar (experimental)
-template<typename T1>
-arma_inline
-const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>
-operator+
-  (
-  const Base<typename T1::pod_type, T1>&     X,
-  const std::complex<typename T1::pod_type>& k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>('j', X.get_ref(), k);
-  }
-
-
-
-//! complex scalar + non-complex Base (experimental)
-template<typename T1>
-arma_inline
-const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>
-operator+
-  (
-  const std::complex<typename T1::pod_type>& k,
-  const Base<typename T1::pod_type, T1>&     X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>('j', X.get_ref(), k);  // NOTE: order is swapped
-  }
-
-
-
-//! addition of Base objects with same element type
-template<typename T1, typename T2>
-arma_inline
-const eGlue<T1, T2, eglue_plus>
-operator+
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const Base<typename T1::elem_type,T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eGlue<T1, T2, eglue_plus>(X.get_ref(), Y.get_ref());
-  }
-
-
-
-//! addition of Base objects with different element types
-template<typename T1, typename T2>
-inline
-const mtGlue<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_plus>
-operator+
-  (
-  const Base< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T1_result, T1>& X,
-  const Base< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T2_result, T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  return mtGlue<out_eT, T1, T2, glue_mixed_plus>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/operator_relational.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,267 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup operator_relational
-//! @{
-
-
-// <  : lt
-// >  : gt
-// <= : lteq
-// >= : gteq
-// == : eq
-// != : noteq
-
-
-
-template<typename T1, typename T2>
-inline
-const mtGlue<uword, T1, T2, glue_rel_lt>
-operator<
-(const Base<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const Base<typename arma_not_cx<typename T1::elem_type>::result,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtGlue<uword, T1, T2, glue_rel_lt>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const mtGlue<uword, T1, T2, glue_rel_gt>
-operator>
-(const Base<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const Base<typename arma_not_cx<typename T1::elem_type>::result,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtGlue<uword, T1, T2, glue_rel_gt>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const mtGlue<uword, T1, T2, glue_rel_lteq>
-operator<=
-(const Base<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const Base<typename arma_not_cx<typename T1::elem_type>::result,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtGlue<uword, T1, T2, glue_rel_lteq>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const mtGlue<uword, T1, T2, glue_rel_gteq>
-operator>=
-(const Base<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const Base<typename arma_not_cx<typename T1::elem_type>::result,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtGlue<uword, T1, T2, glue_rel_gteq>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const mtGlue<uword, T1, T2, glue_rel_eq>
-operator==
-(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtGlue<uword, T1, T2, glue_rel_eq>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-template<typename T1, typename T2>
-inline
-const mtGlue<uword, T1, T2, glue_rel_noteq>
-operator!=
-(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtGlue<uword, T1, T2, glue_rel_noteq>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-//
-//
-//
-
-
-
-template<typename T1>
-inline
-const mtOp<uword, T1, op_rel_lt_pre>
-operator<
-(const typename arma_not_cx<typename T1::elem_type>::result val, const Base<typename arma_not_cx<typename T1::elem_type>::result,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<uword, T1, op_rel_lt_pre>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<uword, T1, op_rel_lt_post>
-operator<
-(const Base<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result val)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<uword, T1, op_rel_lt_post>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<uword, T1, op_rel_gt_pre>
-operator>
-(const typename arma_not_cx<typename T1::elem_type>::result val, const Base<typename arma_not_cx<typename T1::elem_type>::result,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<uword, T1, op_rel_gt_pre>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<uword, T1, op_rel_gt_post>
-operator>
-(const Base<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result val)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<uword, T1, op_rel_gt_post>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<uword, T1, op_rel_lteq_pre>
-operator<=
-(const typename arma_not_cx<typename T1::elem_type>::result val, const Base<typename arma_not_cx<typename T1::elem_type>::result,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<uword, T1, op_rel_lteq_pre>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<uword, T1, op_rel_lteq_post>
-operator<=
-(const Base<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result val)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<uword, T1, op_rel_lteq_post>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<uword, T1, op_rel_gteq_pre>
-operator>=
-(const typename arma_not_cx<typename T1::elem_type>::result val, const Base<typename arma_not_cx<typename T1::elem_type>::result,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<uword, T1, op_rel_gteq_pre>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<uword, T1, op_rel_gteq_post>
-operator>=
-(const Base<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result val)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<uword, T1, op_rel_gteq_post>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<uword, T1, op_rel_eq>
-operator==
-(const typename T1::elem_type val, const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<uword, T1, op_rel_eq>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<uword, T1, op_rel_eq>
-operator==
-(const Base<typename T1::elem_type,T1>& X, const typename T1::elem_type val)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<uword, T1, op_rel_eq>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<uword, T1, op_rel_noteq>
-operator!=
-(const typename T1::elem_type val, const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<uword, T1, op_rel_noteq>(X.get_ref(), val);
-  }
-
-
-
-template<typename T1>
-inline
-const mtOp<uword, T1, op_rel_noteq>
-operator!=
-(const Base<typename T1::elem_type,T1>& X, const typename T1::elem_type val)
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<uword, T1, op_rel_noteq>(X.get_ref(), val);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/operator_schur.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup operator_schur
-//! @{
-
-
-// operator %, which we define it to do a schur product (element-wise multiplication)
-
-
-//! element-wise multiplication of Base objects with same element type
-template<typename T1, typename T2>
-arma_inline
-const eGlue<T1, T2, eglue_schur>
-operator%
-  (
-  const Base<typename T1::elem_type,T1>& X,
-  const Base<typename T1::elem_type,T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return eGlue<T1, T2, eglue_schur>(X.get_ref(), Y.get_ref());
-  }
-
-
-
-//! element-wise multiplication of Base objects with different element types
-template<typename T1, typename T2>
-inline
-const mtGlue<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_schur>
-operator%
-  (
-  const Base< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T1_result, T1>& X,
-  const Base< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T2_result, T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  return mtGlue<out_eT, T1, T2, glue_mixed_schur>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/operator_times.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,213 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup operator_times
-//! @{
-
-
-
-//! Base * scalar
-template<typename T1>
-arma_inline
-const eOp<T1, eop_scalar_times>
-operator*
-(const Base<typename T1::elem_type,T1>& X, const typename T1::elem_type k)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_scalar_times>(X.get_ref(),k);
-  }
-
-
-
-//! scalar * Base
-template<typename T1>
-arma_inline
-const eOp<T1, eop_scalar_times>
-operator*
-(const typename T1::elem_type k, const Base<typename T1::elem_type,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return eOp<T1, eop_scalar_times>(X.get_ref(),k);  // NOTE: order is swapped
-  }
-
-
-
-//! non-complex Base * complex scalar (experimental)
-template<typename T1>
-arma_inline
-const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>
-operator*
-  (
-  const Base<typename T1::pod_type, T1>&     X,
-  const std::complex<typename T1::pod_type>& k
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>('j', X.get_ref(), k);
-  }
-
-
-
-//! complex scalar * non-complex Base (experimental)
-template<typename T1>
-arma_inline
-const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>
-operator*
-  (
-  const std::complex<typename T1::pod_type>& k,
-  const Base<typename T1::pod_type, T1>&     X
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>('j', X.get_ref(), k);
-  }
-
-
-
-//! scalar * trans(T1)
-template<typename T1>
-arma_inline
-const Op<T1, op_htrans2>
-operator*
-(const typename T1::elem_type k, const Op<T1, op_htrans>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_htrans2>(X.m, k);
-  }
-
-
-
-//! trans(T1) * scalar
-template<typename T1>
-arma_inline
-const Op<T1, op_htrans2>
-operator*
-(const Op<T1, op_htrans>& X, const typename T1::elem_type k)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Op<T1, op_htrans2>(X.m, k);
-  }
-
-
-
-//! Base * diagmat
-template<typename T1, typename T2>
-arma_inline
-const Glue<T1, Op<T2, op_diagmat>, glue_times_diag>
-operator*
-(const Base<typename T2::elem_type,T1>& X, const Op<T2, op_diagmat>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Glue<T1, Op<T2, op_diagmat>, glue_times_diag>(X.get_ref(), Y);
-  }
-
-
-
-//! diagmat * Base
-template<typename T1, typename T2>
-arma_inline
-const Glue<Op<T1, op_diagmat>, T2, glue_times_diag>
-operator*
-(const Op<T1, op_diagmat>& X, const Base<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Glue<Op<T1, op_diagmat>, T2, glue_times_diag>(X, Y.get_ref());
-  }
-
-
-
-//! diagmat * diagmat
-template<typename T1, typename T2>
-arma_inline
-Mat< typename promote_type<typename T1::elem_type, typename T2::elem_type>::result >
-operator*
-(const Op<T1, op_diagmat>& X, const Op<T2, op_diagmat>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  const diagmat_proxy<T1> A(X.m);
-  const diagmat_proxy<T2> B(Y.m);
-  
-  arma_debug_assert_mul_size(A.n_elem, A.n_elem, B.n_elem, B.n_elem, "matrix multiply");
-  
-  const uword N = A.n_elem;
-  
-  Mat<out_eT> out(N,N);
-  
-  out.zeros();
-  
-  for(uword i=0; i<N; ++i)
-    {
-    out.at(i,i) = upgrade_val<eT1,eT2>::apply( A[i] ) * upgrade_val<eT1,eT2>::apply( B[i] );
-    }
-  
-  return out;
-  }
-
-
-
-//! multiplication of Base objects with same element type
-template<typename T1, typename T2>
-arma_inline
-const Glue<T1, T2, glue_times>
-operator*
-(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y)
-  {
-  arma_extra_debug_sigprint();
-  
-  return Glue<T1, T2, glue_times>(X.get_ref(), Y.get_ref());
-  }
-
-
-
-//! multiplication of Base objects with different element types
-template<typename T1, typename T2>
-inline
-const mtGlue< typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_times >
-operator*
-  (
-  const Base< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T1_result, T1>& X,
-  const Base< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T2_result, T2>& Y
-  )
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename T1::elem_type eT1;
-  typedef typename T2::elem_type eT2;
-  
-  typedef typename promote_type<eT1,eT2>::result out_eT;
-  
-  promote_type<eT1,eT2>::check();
-  
-  return mtGlue<out_eT, T1, T2, glue_mixed_times>( X.get_ref(), Y.get_ref() );
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/podarray_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup podarray
-//! @{
-
-
-
-struct podarray_prealloc_n_elem
-  {
-  static const uword val = 16;
-  };
-
-
-
-//! A lightweight array for POD types. If the amount of memory requested is small, the stack is used.
-
-template<typename eT>
-class podarray
-  {
-  public:
-  
-  arma_aligned const uword       n_elem; //!< number of elements held
-  arma_aligned const eT* const mem;    //!< pointer to memory used by the object
-  
-  
-  protected:
-  //! Internal memory, to avoid calling the 'new' operator for small amounts of memory.
-  arma_aligned eT mem_local[ podarray_prealloc_n_elem::val ];
-  
-  
-  public:
-  
-  inline ~podarray();
-  inline  podarray();
-  
-  inline                 podarray (const podarray& x);
-  inline const podarray& operator=(const podarray& x);
-  
-  arma_inline explicit podarray(const uword new_N);
-  
-  arma_inline explicit podarray(const eT* X, const uword new_N);
-  
-  arma_inline eT& operator[] (const uword i);
-  arma_inline eT  operator[] (const uword i) const;
-  
-  arma_inline eT& operator() (const uword i);
-  arma_inline eT  operator() (const uword i) const;
-  
-  inline void set_size(const uword new_n_elem);
-  inline void reset();
-  
-  inline void fill(const eT val);
-  
-  inline void zeros();
-  inline void zeros(const uword new_n_elem);
-  
-  arma_inline       eT* memptr();
-  arma_inline const eT* memptr() const;
-  
-  arma_hot inline void copy_row(const Mat<eT>& A, const uword row);
-  
-  protected:
-  
-  inline void init(const uword new_n_elem);
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/podarray_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,323 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup podarray
-//! @{
-
-
-template<typename eT>
-inline
-podarray<eT>::~podarray()
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  if(n_elem > sizeof(mem_local)/sizeof(eT) )
-    {
-    delete [] mem;
-    }
-  
-  if(arma_config::debug == true)
-    {
-    access::rw(n_elem) = 0;
-    access::rw(mem)    = 0;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-podarray<eT>::podarray()
-  : n_elem(0)
-  , mem   (0)
-  {
-  arma_extra_debug_sigprint_this(this);
-  }
-  
-  
-
-template<typename eT>
-inline
-podarray<eT>::podarray(const podarray& x)
-  : n_elem(0)
-  , mem   (0)
-  {
-  arma_extra_debug_sigprint();
-  
-  this->operator=(x);
-  }
-  
-  
-  
-template<typename eT>
-inline
-const podarray<eT>&
-podarray<eT>::operator=(const podarray& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(this != &x)
-    {
-    init(x.n_elem);
-    
-    arrayops::copy( memptr(), x.memptr(), n_elem );
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-arma_inline
-podarray<eT>::podarray(const uword new_n_elem)
-  : n_elem(0)
-  , mem   (0)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init(new_n_elem);
-  }
-
-
-
-template<typename eT>
-arma_inline
-podarray<eT>::podarray(const eT* X, const uword new_n_elem)
-  : n_elem(0)
-  , mem   (0)
-  {
-  arma_extra_debug_sigprint_this(this);
-  
-  init(new_n_elem);
-  
-  arrayops::copy( memptr(), X, new_n_elem );
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT
-podarray<eT>::operator[] (const uword i) const
-  {
-  return mem[i];
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT&
-podarray<eT>::operator[] (const uword i)
-  {
-  return access::rw(mem[i]);
-  }
-  
-  
-  
-template<typename eT>
-arma_inline
-eT
-podarray<eT>::operator() (const uword i) const
-  {
-  arma_debug_check( (i >= n_elem), "podarray::operator(): index out of bounds");
-  return mem[i];
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT&
-podarray<eT>::operator() (const uword i)
-  {
-  arma_debug_check( (i >= n_elem), "podarray::operator(): index out of bounds");
-  return access::rw(mem[i]);
-  }
-
-
-
-template<typename eT>
-inline
-void
-podarray<eT>::set_size(const uword new_n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  init(new_n_elem);
-  }
-
-
-
-template<typename eT>
-inline
-void
-podarray<eT>::reset()
-  {
-  arma_extra_debug_sigprint();
-  
-  init(0);
-  }
-
-
-
-template<typename eT>
-inline
-void
-podarray<eT>::fill(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  arrayops::inplace_set(memptr(), val, n_elem);
-  }
-
-
-
-template<typename eT>
-inline
-void
-podarray<eT>::zeros()
-  {
-  arma_extra_debug_sigprint();
-  
-  fill(eT(0));
-  }
-
-
-
-template<typename eT>
-inline
-void
-podarray<eT>::zeros(const uword new_n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  init(new_n_elem);
-  fill(eT(0));
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT*
-podarray<eT>::memptr()
-  {
-  return const_cast<eT*>(mem);
-  }
-  
-  
-
-template<typename eT>
-arma_inline
-const eT*
-podarray<eT>::memptr() const
-  {
-  return mem;
-  }
-
-
-
-template<typename eT>
-arma_hot
-inline
-void
-podarray<eT>::copy_row(const Mat<eT>& A, const uword row)
-  {
-  const uword cols = A.n_cols;
-  
-  // note: this function assumes that the podarray has been set to the correct size beforehand
-  eT* out = memptr();
-  
-  switch(cols)
-    {
-    default:
-      {
-      uword i,j;
-      for(i=0, j=1; j < cols; i+=2, j+=2)
-        {
-        const eT tmp_i = A.at(row, i);
-        const eT tmp_j = A.at(row, j);
-        
-        out[i] = tmp_i;
-        out[j] = tmp_j;
-        }
-      
-      if(i < cols)
-        {
-        out[i] = A.at(row, i);
-        }
-      }
-      break;
-    
-    case 8:
-      out[7] = A.at(row, 7);
-
-    case 7:
-      out[6] = A.at(row, 6);
-
-    case 6:
-      out[5] = A.at(row, 5);
-
-    case 5:
-      out[4] = A.at(row, 4);
-
-    case 4:
-      out[3] = A.at(row, 3);
-
-    case 3:
-      out[2] = A.at(row, 2);
-
-    case 2:
-      out[1] = A.at(row, 1);
-
-    case 1:
-      out[0] = A.at(row, 0);
-    }
-  }
-  
-
-
-template<typename eT>
-inline
-void
-podarray<eT>::init(const uword new_n_elem)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(n_elem == new_n_elem)
-    {
-    return;
-    }
-    
-  if(n_elem > sizeof(mem_local)/sizeof(eT) )
-    {
-    delete [] mem;
-    }
-  
-  if(new_n_elem <= sizeof(mem_local)/sizeof(eT) )
-    {
-    access::rw(mem) = mem_local;
-    }
-  else
-    {
-    access::rw(mem) = new eT[new_n_elem];
-    }
-  
-  access::rw(n_elem) = new_n_elem;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/promote_type.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,217 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup promote_type
-//! @{
-
-
-template<typename T1, typename T2>
-struct is_promotable
-  {
-  static const bool value = false;
-  typedef T1 result;
-  };
-
-
-struct is_promotable_ok
-  {
-  static const bool value = true;
-  };
-
-
-template<typename T> struct is_promotable<T,               T> : public is_promotable_ok { typedef T               result; };
-template<typename T> struct is_promotable<std::complex<T>, T> : public is_promotable_ok { typedef std::complex<T> result; };
-
-template<> struct is_promotable<std::complex<double>, std::complex<float> > : public is_promotable_ok { typedef std::complex<double> result; };
-template<> struct is_promotable<std::complex<double>, float>                : public is_promotable_ok { typedef std::complex<double> result; };
-template<> struct is_promotable<std::complex<float>,  double>               : public is_promotable_ok { typedef std::complex<double> result; };
-
-#if defined(ARMA_64BIT_WORD)
-template<typename t> struct is_promotable<std::complex<t>, u64> : public is_promotable_ok { typedef std::complex<t> result; };
-template<typename t> struct is_promotable<std::complex<t>, s64> : public is_promotable_ok { typedef std::complex<t> result; };
-#endif
-template<typename T> struct is_promotable<std::complex<T>, s32> : public is_promotable_ok { typedef std::complex<T> result; };
-template<typename T> struct is_promotable<std::complex<T>, u32> : public is_promotable_ok { typedef std::complex<T> result; };
-template<typename T> struct is_promotable<std::complex<T>, s16> : public is_promotable_ok { typedef std::complex<T> result; };
-template<typename T> struct is_promotable<std::complex<T>, u16> : public is_promotable_ok { typedef std::complex<T> result; };
-template<typename T> struct is_promotable<std::complex<T>, s8>  : public is_promotable_ok { typedef std::complex<T> result; };
-template<typename T> struct is_promotable<std::complex<T>, u8>  : public is_promotable_ok { typedef std::complex<T> result; };
-
-
-template<> struct is_promotable<double, float> : public is_promotable_ok { typedef double result; };
-#if defined(ARMA_64BIT_WORD)
-template<> struct is_promotable<double, s64  > : public is_promotable_ok { typedef double result; };
-template<> struct is_promotable<double, u64  > : public is_promotable_ok { typedef double result; };
-#endif
-template<> struct is_promotable<double, s32  > : public is_promotable_ok { typedef double result; };
-template<> struct is_promotable<double, u32  > : public is_promotable_ok { typedef double result; };
-template<> struct is_promotable<double, s16  > : public is_promotable_ok { typedef double result; };
-template<> struct is_promotable<double, u16  > : public is_promotable_ok { typedef double result; };
-template<> struct is_promotable<double, s8   > : public is_promotable_ok { typedef double result; };
-template<> struct is_promotable<double, u8   > : public is_promotable_ok { typedef double result; };
-
-#if defined(ARMA_64BIT_WORD)
-template<> struct is_promotable<float, s64> : public is_promotable_ok { typedef float result; };
-template<> struct is_promotable<float, u64> : public is_promotable_ok { typedef float result; };
-#endif
-template<> struct is_promotable<float, s32> : public is_promotable_ok { typedef float result; };
-template<> struct is_promotable<float, u32> : public is_promotable_ok { typedef float result; };
-template<> struct is_promotable<float, s16> : public is_promotable_ok { typedef float result; };
-template<> struct is_promotable<float, u16> : public is_promotable_ok { typedef float result; };
-template<> struct is_promotable<float, s8 > : public is_promotable_ok { typedef float result; };
-template<> struct is_promotable<float, u8 > : public is_promotable_ok { typedef float result; };
-
-#if defined(ARMA_64BIT_WORD)
-template<> struct is_promotable<u64, u32> : public is_promotable_ok { typedef u64 result; };
-template<> struct is_promotable<u64, u16> : public is_promotable_ok { typedef u64 result; };
-template<> struct is_promotable<u64, u8 > : public is_promotable_ok { typedef u64 result; };
-#endif
-
-#if defined(ARMA_64BIT_WORD)
-template<> struct is_promotable<s64, u64> : public is_promotable_ok { typedef s64 result; };  // float ?  
-template<> struct is_promotable<s64, u32> : public is_promotable_ok { typedef s64 result; };
-template<> struct is_promotable<s64, s32> : public is_promotable_ok { typedef s64 result; };
-template<> struct is_promotable<s64, s16> : public is_promotable_ok { typedef s64 result; };
-template<> struct is_promotable<s64, u16> : public is_promotable_ok { typedef s64 result; };
-template<> struct is_promotable<s64, s8 > : public is_promotable_ok { typedef s64 result; };
-template<> struct is_promotable<s64, u8 > : public is_promotable_ok { typedef s64 result; };
-#endif
-
-template<> struct is_promotable<s32, u32> : public is_promotable_ok { typedef s32 result; };  // float ?  
-template<> struct is_promotable<s32, s16> : public is_promotable_ok { typedef s32 result; };
-template<> struct is_promotable<s32, u16> : public is_promotable_ok { typedef s32 result; };
-template<> struct is_promotable<s32, s8 > : public is_promotable_ok { typedef s32 result; };
-template<> struct is_promotable<s32, u8 > : public is_promotable_ok { typedef s32 result; };
-
-template<> struct is_promotable<u32, s16> : public is_promotable_ok { typedef s32 result; };  // float ?
-template<> struct is_promotable<u32, u16> : public is_promotable_ok { typedef u32 result; };
-template<> struct is_promotable<u32, s8 > : public is_promotable_ok { typedef s32 result; };  // float ?
-template<> struct is_promotable<u32, u8 > : public is_promotable_ok { typedef u32 result; };
-
-template<> struct is_promotable<s16, u16> : public is_promotable_ok { typedef s16 result; };  // s32 ?
-template<> struct is_promotable<s16, s8 > : public is_promotable_ok { typedef s16 result; };
-template<> struct is_promotable<s16, u8 > : public is_promotable_ok { typedef s16 result; };
-
-template<> struct is_promotable<u16, s8> : public is_promotable_ok { typedef s16 result; };  // s32 ?
-template<> struct is_promotable<u16, u8> : public is_promotable_ok { typedef u16 result; };
-
-template<> struct is_promotable<s8, u8> : public is_promotable_ok { typedef s8 result; };  // s16 ?
-
-
-
-
-//
-// mirrored versions
-
-template<typename T> struct is_promotable<T, std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
-
-template<> struct is_promotable<std::complex<float>, std::complex<double> > : public is_promotable_ok { typedef std::complex<double> result; };
-template<> struct is_promotable<float,               std::complex<double> > : public is_promotable_ok { typedef std::complex<double> result; };
-template<> struct is_promotable<double,              std::complex<float>  > : public is_promotable_ok { typedef std::complex<double> result; };
-
-#if defined(ARMA_64BIT_WORD)
-template<typename T> struct is_promotable<s64, std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
-template<typename T> struct is_promotable<u64, std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
-#endif
-template<typename T> struct is_promotable<s32, std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
-template<typename T> struct is_promotable<u32, std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
-template<typename T> struct is_promotable<s16, std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
-template<typename T> struct is_promotable<u16, std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
-template<typename T> struct is_promotable<s8,  std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
-template<typename T> struct is_promotable<u8,  std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
-
-
-template<> struct is_promotable<float, double> : public is_promotable_ok { typedef double result; };
-#if defined(ARMA_64BIT_WORD)
-template<> struct is_promotable<s64  , double> : public is_promotable_ok { typedef double result; };
-template<> struct is_promotable<u64  , double> : public is_promotable_ok { typedef double result; };
-#endif
-template<> struct is_promotable<s32  , double> : public is_promotable_ok { typedef double result; };
-template<> struct is_promotable<u32  , double> : public is_promotable_ok { typedef double result; };
-template<> struct is_promotable<s16  , double> : public is_promotable_ok { typedef double result; };
-template<> struct is_promotable<u16  , double> : public is_promotable_ok { typedef double result; };
-template<> struct is_promotable<s8   , double> : public is_promotable_ok { typedef double result; };
-template<> struct is_promotable<u8   , double> : public is_promotable_ok { typedef double result; };
-
-#if defined(ARMA_64BIT_WORD)
-template<> struct is_promotable<s64, float> : public is_promotable_ok { typedef float result; };
-template<> struct is_promotable<u64, float> : public is_promotable_ok { typedef float result; };
-#endif
-template<> struct is_promotable<s32, float> : public is_promotable_ok { typedef float result; };
-template<> struct is_promotable<u32, float> : public is_promotable_ok { typedef float result; };
-template<> struct is_promotable<s16, float> : public is_promotable_ok { typedef float result; };
-template<> struct is_promotable<u16, float> : public is_promotable_ok { typedef float result; };
-template<> struct is_promotable<s8 , float> : public is_promotable_ok { typedef float result; };
-template<> struct is_promotable<u8 , float> : public is_promotable_ok { typedef float result; };
-
-#if defined(ARMA_64BIT_WORD)
-template<> struct is_promotable<u32, u64> : public is_promotable_ok { typedef u64 result; };
-template<> struct is_promotable<u16, u64> : public is_promotable_ok { typedef u64 result; };
-template<> struct is_promotable<u8,  u64> : public is_promotable_ok { typedef u64 result; };
-#endif
-
-#if defined(ARMA_64BIT_WORD)
-template<> struct is_promotable<u64, s64> : public is_promotable_ok { typedef s64 result; };  // float ?  
-template<> struct is_promotable<u32, s64> : public is_promotable_ok { typedef s64 result; };
-template<> struct is_promotable<s16, s64> : public is_promotable_ok { typedef s64 result; };
-template<> struct is_promotable<u16, s64> : public is_promotable_ok { typedef s64 result; };
-template<> struct is_promotable<s8 , s64> : public is_promotable_ok { typedef s64 result; };
-template<> struct is_promotable<u8 , s64> : public is_promotable_ok { typedef s64 result; };
-#endif
-
-template<> struct is_promotable<u32, s32> : public is_promotable_ok { typedef s32 result; };  // float ?  
-template<> struct is_promotable<s16, s32> : public is_promotable_ok { typedef s32 result; };
-template<> struct is_promotable<u16, s32> : public is_promotable_ok { typedef s32 result; };
-template<> struct is_promotable<s8 , s32> : public is_promotable_ok { typedef s32 result; };
-template<> struct is_promotable<u8 , s32> : public is_promotable_ok { typedef s32 result; };
-
-template<> struct is_promotable<s16, u32> : public is_promotable_ok { typedef s32 result; };  // float ?
-template<> struct is_promotable<u16, u32> : public is_promotable_ok { typedef u32 result; };
-template<> struct is_promotable<s8 , u32> : public is_promotable_ok { typedef s32 result; };  // float ?
-template<> struct is_promotable<u8 , u32> : public is_promotable_ok { typedef u32 result; };
-
-template<> struct is_promotable<u16, s16> : public is_promotable_ok { typedef s16 result; };  // s32 ?
-template<> struct is_promotable<s8 , s16> : public is_promotable_ok { typedef s16 result; };
-template<> struct is_promotable<u8 , s16> : public is_promotable_ok { typedef s16 result; };
-
-template<> struct is_promotable<s8, u16> : public is_promotable_ok { typedef s16 result; };  // s32 ?
-template<> struct is_promotable<u8, u16> : public is_promotable_ok { typedef u16 result; };
-
-template<> struct is_promotable<u8, s8> : public is_promotable_ok { typedef s8 result; };  // s16 ?
-
-
-
-
-
-template<typename T1, typename T2>
-struct promote_type
-  {
-  inline static void check()
-    {
-    arma_type_check(( is_promotable<T1,T2>::value == false ));
-    }
-  
-  typedef typename is_promotable<T1,T2>::result result;
-  };
-
-
-
-template<typename T1, typename T2>
-struct eT_promoter
-  {
-  typedef typename promote_type<typename T1::elem_type, typename T2::elem_type>::result eT;
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/restrictors.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,188 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup restrictors
-//! @{
-
-
-
-// structures for template based restrictions of input/output arguments
-// (part of the SFINAE approach)
-// http://en.wikipedia.org/wiki/SFINAE
-
-
-template<typename T> struct arma_scalar_only { };
-
-template<> struct arma_scalar_only<u8>     { typedef u8     result; };
-template<> struct arma_scalar_only<s8>     { typedef s8     result; };
-template<> struct arma_scalar_only<u16>    { typedef u16    result; };
-template<> struct arma_scalar_only<s16>    { typedef s16    result; };
-template<> struct arma_scalar_only<u32>    { typedef u32    result; };
-template<> struct arma_scalar_only<s32>    { typedef s32    result; };
-#if defined(ARMA_64BIT_WORD)
-template<> struct arma_scalar_only<u64>    { typedef u64    result; };
-template<> struct arma_scalar_only<s64>    { typedef s64    result; };
-#endif
-template<> struct arma_scalar_only<float>  { typedef float  result; };
-template<> struct arma_scalar_only<double> { typedef double result; };
-
-
-template<typename T>
-struct arma_scalar_only< std::complex<T> > { typedef std::complex<T> result; };
-
-
-
-template<typename T> struct arma_integral_only { };
-
-template<> struct arma_integral_only<u8>  { typedef u8  result; };
-template<> struct arma_integral_only<s8>  { typedef s8  result; };
-template<> struct arma_integral_only<u16> { typedef u16 result; };
-template<> struct arma_integral_only<s16> { typedef s16 result; };
-template<> struct arma_integral_only<u32> { typedef u32 result; };
-template<> struct arma_integral_only<s32> { typedef s32 result; };
-#if defined(ARMA_64BIT_WORD)
-template<> struct arma_integral_only<u64> { typedef u64 result; };
-template<> struct arma_integral_only<s64> { typedef s64 result; };
-#endif
-
-
-
-template<typename T> struct arma_unsigned_integral_only { };
-
-template<> struct arma_unsigned_integral_only<u8>  { typedef u8  result; };
-template<> struct arma_unsigned_integral_only<u16> { typedef u16 result; };
-template<> struct arma_unsigned_integral_only<u32> { typedef u32 result; };
-#if defined(ARMA_64BIT_WORD)
-template<> struct arma_unsigned_integral_only<u64> { typedef u64 result; };
-#endif
-
-
-
-template<typename T> struct arma_signed_integral_only { };
-
-template<> struct arma_signed_integral_only<s8>   { typedef s8  result; };
-template<> struct arma_signed_integral_only<s16>  { typedef s16 result; };
-template<> struct arma_signed_integral_only<s32>  { typedef s32 result; };
-#if defined(ARMA_64BIT_WORD)
-template<> struct arma_signed_integral_only<s64>  { typedef s64 result; };
-#endif
-
-
-
-template<typename T> struct arma_signed_only { };
-
-template<> struct arma_signed_only<s8>   { typedef s8   result; };
-template<> struct arma_signed_only<s16>  { typedef s16  result; };
-template<> struct arma_signed_only<s32>  { typedef s32  result; };
-#if defined(ARMA_64BIT_WORD)
-template<> struct arma_signed_only<s64>  { typedef s64  result; };
-#endif
-template<> struct arma_signed_only<float>  { typedef float  result; };
-template<> struct arma_signed_only<double> { typedef double result; };
-
-template<typename T> struct arma_signed_only< std::complex<T> > { typedef std::complex<T> result; };
-
-
-
-template<typename T> struct arma_float_only { };
-
-template<> struct arma_float_only<float>  { typedef float  result; };
-template<> struct arma_float_only<double> { typedef double result; };
-
-
-
-template<typename T> struct arma_float_or_cx_only { };
-
-template<> struct arma_float_or_cx_only< float >                { typedef float                result; };
-template<> struct arma_float_or_cx_only< double >               { typedef double               result; };
-template<> struct arma_float_or_cx_only< std::complex<float>  > { typedef std::complex<float>  result; };
-template<> struct arma_float_or_cx_only< std::complex<double> > { typedef std::complex<double> result; };
-
-
-
-template<typename T> struct arma_cx_only { };
-
-template<> struct arma_cx_only< std::complex<float>  > { typedef std::complex<float>  result; };
-template<> struct arma_cx_only< std::complex<double> > { typedef std::complex<double> result; };
-
-
-
-template<typename T> struct arma_not_cx                    { typedef T result; };
-template<typename T> struct arma_not_cx< std::complex<T> > { };
-
-
-
-template<typename T> struct arma_blas_type_only { };
-
-template<> struct arma_blas_type_only< float                > { typedef float                result; };
-template<> struct arma_blas_type_only< double               > { typedef double               result; };
-template<> struct arma_blas_type_only< std::complex<float>  > { typedef std::complex<float>  result; };
-template<> struct arma_blas_type_only< std::complex<double> > { typedef std::complex<double> result; };
-
-
-
-template<typename T> struct arma_op_rel_only { };
-
-template<> struct arma_op_rel_only< op_rel_lt_pre    > { typedef int result; };
-template<> struct arma_op_rel_only< op_rel_lt_post   > { typedef int result; };
-template<> struct arma_op_rel_only< op_rel_gt_pre    > { typedef int result; };
-template<> struct arma_op_rel_only< op_rel_gt_post   > { typedef int result; };
-template<> struct arma_op_rel_only< op_rel_lteq_pre  > { typedef int result; };
-template<> struct arma_op_rel_only< op_rel_lteq_post > { typedef int result; };
-template<> struct arma_op_rel_only< op_rel_gteq_pre  > { typedef int result; };
-template<> struct arma_op_rel_only< op_rel_gteq_post > { typedef int result; };
-template<> struct arma_op_rel_only< op_rel_eq        > { typedef int result; };
-template<> struct arma_op_rel_only< op_rel_noteq     > { typedef int result; };
-
-
-
-template<typename T> struct arma_not_op_rel { typedef int result; };
-
-template<> struct arma_not_op_rel< op_rel_lt_pre    > { };
-template<> struct arma_not_op_rel< op_rel_lt_post   > { };
-template<> struct arma_not_op_rel< op_rel_gt_pre    > { };
-template<> struct arma_not_op_rel< op_rel_gt_post   > { };
-template<> struct arma_not_op_rel< op_rel_lteq_pre  > { };
-template<> struct arma_not_op_rel< op_rel_lteq_post > { };
-template<> struct arma_not_op_rel< op_rel_gteq_pre  > { };
-template<> struct arma_not_op_rel< op_rel_gteq_post > { };
-template<> struct arma_not_op_rel< op_rel_eq        > { };
-template<> struct arma_not_op_rel< op_rel_noteq     > { };
-
-
-
-template<typename T> struct arma_glue_rel_only { };
-
-template<> struct arma_glue_rel_only< glue_rel_lt    > { typedef int result; };
-template<> struct arma_glue_rel_only< glue_rel_gt    > { typedef int result; };
-template<> struct arma_glue_rel_only< glue_rel_lteq  > { typedef int result; };
-template<> struct arma_glue_rel_only< glue_rel_gteq  > { typedef int result; };
-template<> struct arma_glue_rel_only< glue_rel_eq    > { typedef int result; };
-template<> struct arma_glue_rel_only< glue_rel_noteq > { typedef int result; };
-
-
-
-template<typename T> struct arma_Mat_Col_Row_only { };
-
-template<typename eT> struct arma_Mat_Col_Row_only< Mat<eT> > { typedef Mat<eT> result; };
-template<typename eT> struct arma_Mat_Col_Row_only< Col<eT> > { typedef Col<eT> result; };
-template<typename eT> struct arma_Mat_Col_Row_only< Row<eT> > { typedef Row<eT> result; };
-
-
-
-template<typename  T> struct arma_Cube_only             { };
-template<typename eT> struct arma_Cube_only< Cube<eT> > { typedef Cube<eT> result; };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/running_stat_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup running_stat
-//! @{
-
-
-
-template<typename eT>
-class arma_counter
-  {
-  public:
-  
-  inline ~arma_counter();
-  inline  arma_counter();
-  
-  inline const arma_counter& operator++();
-  inline void                operator++(int);
-  
-  inline void reset();
-  inline eT   value()         const;
-  inline eT   value_plus_1()  const;
-  inline eT   value_minus_1() const;
-  
-  
-  private:
-  
-  arma_aligned eT    d_count;
-  arma_aligned uword i_count;
-  };
-
-
-
-//! Class for keeping statistics of a continuously sampled process / signal.
-//! Useful if the storage of individual samples is not necessary or desired.
-//! Also useful if the number of samples is not known beforehand or exceeds 
-//! available memory.
-template<typename eT>
-class running_stat
-  {
-  public:
-  
-  typedef typename get_pod_type<eT>::result T;
-  
-  
-  inline ~running_stat();
-  inline  running_stat();
-  
-  inline void operator() (const T sample);
-  inline void operator() (const std::complex<T>& sample);
-  
-  inline void reset();
-  
-  inline eT mean() const;
-  
-  inline  T var   (const uword norm_type = 0) const;
-  inline  T stddev(const uword norm_type = 0) const;
-  
-  inline eT min()  const;
-  inline eT max()  const;
-  
-  inline T count() const;
-  
-  //
-  //
-  
-  private:
-  
-  arma_aligned arma_counter<T> counter;
-  
-  arma_aligned eT r_mean;
-  arma_aligned  T r_var;
-  
-  arma_aligned eT min_val;
-  arma_aligned eT max_val;
-  
-  arma_aligned  T min_val_norm;
-  arma_aligned  T max_val_norm;
-  
-  
-  friend class running_stat_aux;
-  };
-
-
-
-class running_stat_aux
-  {
-  public:
-  
-  template<typename eT>
-  inline static void update_stats(running_stat<eT>&               x,  const eT               sample);
-  
-  template<typename T>
-  inline static void update_stats(running_stat< std::complex<T> >& x, const T                sample);
-  
-  template<typename T>
-  inline static void update_stats(running_stat< std::complex<T> >& x, const std::complex<T>& sample);
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/running_stat_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,427 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup running_stat
-//! @{
-
-
-
-template<typename eT>
-inline
-arma_counter<eT>::~arma_counter()
-  {
-  arma_extra_debug_sigprint_this(this);
-  }
-
-
-
-template<typename eT>
-inline
-arma_counter<eT>::arma_counter()
-  : d_count( eT(0))
-  , i_count(uword(0))
-  {
-  arma_extra_debug_sigprint_this(this);
-  }
-
-
-
-template<typename eT>
-inline
-const arma_counter<eT>& 
-arma_counter<eT>::operator++()
-  {
-  if(i_count < ARMA_MAX_UWORD)
-    {
-    i_count++;
-    }
-  else
-    {
-    d_count += eT(ARMA_MAX_UWORD);
-    i_count  = 0;
-    }
-  
-  return *this;
-  }
-
-
-
-template<typename eT>
-inline
-void
-arma_counter<eT>::operator++(int)
-  {
-  operator++();
-  }
-
-
-
-template<typename eT>
-inline
-void
-arma_counter<eT>::reset()
-  {
-  d_count =  eT(0);
-  i_count = uword(0);
-  }
-
-
-
-template<typename eT>
-inline
-eT
-arma_counter<eT>::value() const
-  {
-  return d_count + eT(i_count);
-  }
-
-
-
-template<typename eT>
-inline
-eT
-arma_counter<eT>::value_plus_1() const
-  {
-  if(i_count < ARMA_MAX_UWORD)
-    {
-    return d_count + eT(i_count + 1);
-    }
-  else
-    {
-    return d_count + eT(ARMA_MAX_UWORD) + eT(1);
-    }
-  }
-
-
-
-template<typename eT>
-inline
-eT
-arma_counter<eT>::value_minus_1() const
-  {
-  if(i_count > 0)
-    {
-    return d_count + eT(i_count - 1);
-    }
-  else
-    {
-    return d_count - eT(1);
-    }
-  }
-
-
-
-//
-
-
-
-template<typename eT>
-running_stat<eT>::~running_stat()
-  {
-  arma_extra_debug_sigprint_this(this);
-  }
-
-
-
-template<typename eT>
-running_stat<eT>::running_stat()
-  : r_mean      (                          eT(0))
-  , r_var       (typename running_stat<eT>::T(0))
-  , min_val     (                          eT(0))
-  , max_val     (                          eT(0))
-  , min_val_norm(typename running_stat<eT>::T(0))
-  , max_val_norm(typename running_stat<eT>::T(0))
-  {
-  arma_extra_debug_sigprint_this(this);
-  }
-
-
-
-//! update statistics to reflect new sample
-template<typename eT>
-inline
-void
-running_stat<eT>::operator() (const typename running_stat<eT>::T sample)
-  {
-  arma_extra_debug_sigprint();
-  
-  if( arma_isfinite(sample) == false )
-    {
-    arma_warn(true, "running_stat: sample ignored as it is non-finite" );
-    return;
-    }
-  
-  running_stat_aux::update_stats(*this, sample);
-  }
-
-
-
-//! update statistics to reflect new sample (version for complex numbers)
-template<typename eT>
-inline
-void
-running_stat<eT>::operator() (const std::complex< typename running_stat<eT>::T >& sample)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_type_check(( is_same_type<eT, std::complex< typename running_stat<eT>::T > >::value == false ));
-  
-  if( arma_isfinite(sample) == false )
-    {
-    arma_warn(true, "running_stat: sample ignored as it is non-finite" );
-    return;
-    }
-  
-  running_stat_aux::update_stats(*this, sample);
-  }
-
-
-
-//! set all statistics to zero
-template<typename eT>
-inline
-void
-running_stat<eT>::reset()
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename running_stat<eT>::T T;
-  
-  counter.reset();
-  
-  r_mean       = eT(0);
-  r_var        =  T(0);
-  
-  min_val      = eT(0);
-  max_val      = eT(0);
-  
-  min_val_norm =  T(0);
-  max_val_norm =  T(0);
-  }
-
-
-
-//! mean or average value
-template<typename eT>
-inline
-eT
-running_stat<eT>::mean() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return r_mean;
-  }
-
-
-
-//! variance
-template<typename eT>
-inline
-typename running_stat<eT>::T
-running_stat<eT>::var(const uword norm_type) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const T N = counter.value();
-  
-  if(N > T(1))
-    {
-    if(norm_type == 0)
-      {
-      return r_var;
-      }
-    else
-      {
-      const T N_minus_1 = counter.value_minus_1();
-      return (N_minus_1/N) * r_var;
-      }
-    }
-  else
-    {
-    return T(0);
-    }
-  }
-
-
-
-//! standard deviation
-template<typename eT>
-inline
-typename running_stat<eT>::T
-running_stat<eT>::stddev(const uword norm_type) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return std::sqrt( (*this).var(norm_type) );
-  }
-
-
-
-//! minimum value
-template<typename eT>
-inline
-eT
-running_stat<eT>::min() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return min_val;
-  }
-
-
-
-//! maximum value
-template<typename eT>
-inline
-eT
-running_stat<eT>::max() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return max_val;
-  }
-
-
-
-//! number of samples so far
-template<typename eT>
-inline
-typename get_pod_type<eT>::result
-running_stat<eT>::count() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return counter.value();
-  }
-
-
-
-//! update statistics to reflect new sample
-template<typename eT>
-inline
-void
-running_stat_aux::update_stats(running_stat<eT>& x, const eT sample)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename running_stat<eT>::T T;
-  
-  const T N = x.counter.value();
-  
-  if(N > T(0))
-    {
-    if(sample < x.min_val)
-      {
-      x.min_val = sample;
-      }
-    
-    if(sample > x.max_val)
-      {
-      x.max_val = sample;
-      }
-    
-    const T  N_plus_1   = x.counter.value_plus_1();
-    const T  N_minus_1  = x.counter.value_minus_1();
-    
-    // note: variance has to be updated before the mean
-    
-    const eT tmp = sample - x.r_mean;
-    
-    x.r_var  = N_minus_1/N * x.r_var + (tmp*tmp)/N_plus_1;
-    
-    x.r_mean = x.r_mean + (sample - x.r_mean)/N_plus_1;
-    //x.r_mean = (N/N_plus_1)*x.r_mean + sample/N_plus_1;
-    //x.r_mean = (x.r_mean + sample/N) * N/N_plus_1;
-    }
-  else
-    {
-    x.r_mean  = sample;
-    x.min_val = sample;
-    x.max_val = sample;
-    
-    // r_var is initialised to zero
-    // in the constructor and reset()
-    }
-  
-  x.counter++;
-  }
-
-
-
-//! update statistics to reflect new sample (version for complex numbers)
-template<typename T>
-inline
-void
-running_stat_aux::update_stats(running_stat< std::complex<T> >& x, const T sample)
-  {
-  arma_extra_debug_sigprint();
-
-  running_stat_aux::update_stats(x, std::complex<T>(sample));
-  }
-
-
-
-//! alter statistics to reflect new sample (version for complex numbers)
-template<typename T>
-inline
-void
-running_stat_aux::update_stats(running_stat< std::complex<T> >& x, const std::complex<T>& sample)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T> eT;
-  
-  const T sample_norm = std::norm(sample);
-  const T N           = x.counter.value();
-  
-  if(N > T(0))
-    {
-    if(sample_norm < x.min_val_norm)
-      {
-      x.min_val_norm = sample_norm;
-      x.min_val      = sample;
-      }
-    
-    if(sample_norm > x.max_val_norm)
-      {
-      x.max_val_norm = sample_norm;
-      x.max_val      = sample;
-      }
-    
-    const T  N_plus_1   = x.counter.value_plus_1();
-    const T  N_minus_1  = x.counter.value_minus_1();
-    
-    x.r_var = N_minus_1/N * x.r_var + std::norm(sample - x.r_mean)/N_plus_1;
-    
-    x.r_mean = x.r_mean + (sample - x.r_mean)/N_plus_1;
-    //x.r_mean = (N/N_plus_1)*x.r_mean + sample/N_plus_1;
-    //x.r_mean = (x.r_mean + sample/N) * N/N_plus_1;
-    }
-  else
-    {
-    x.r_mean       = sample;
-    x.min_val      = sample;
-    x.max_val      = sample;
-    x.min_val_norm = sample_norm;
-    x.max_val_norm = sample_norm;
-    
-    // r_var is initialised to zero
-    // in the constructor and reset()
-    }
-  
-  x.counter++;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/running_stat_vec_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup running_stat_vec
-//! @{
-
-
-
-//! Class for keeping statistics of a continuously sampled process / signal.
-//! Useful if the storage of individual samples is not necessary or desired.
-//! Also useful if the number of samples is not known beforehand or exceeds 
-//! available memory.
-template<typename eT>
-class running_stat_vec
-  {
-  public:
-  
-  typedef typename get_pod_type<eT>::result T;
-  
-  inline ~running_stat_vec();
-  inline  running_stat_vec(const bool in_calc_cov = false);
-  
-  inline running_stat_vec(const running_stat_vec& in_rsv);
-  
-  inline const running_stat_vec& operator=(const running_stat_vec& in_rsv);
-  
-  template<typename T1> arma_hot inline void operator() (const Base<               T,  T1>& X);
-  template<typename T1> arma_hot inline void operator() (const Base< std::complex<T>,  T1>& X);
-  
-  inline void reset();
-  
-  inline const Mat<eT>&  mean() const;
-  
-  inline const Mat< T>&  var   (const uword norm_type = 0);
-  inline       Mat< T>   stddev(const uword norm_type = 0) const;
-  inline const Mat<eT>&  cov   (const uword norm_type = 0);
-  
-  inline const Mat<eT>& min() const;
-  inline const Mat<eT>& max() const;
-  
-  inline T count() const;
-  
-  //
-  //
-  
-  private:
-  
-  const bool calc_cov;
-  
-  arma_aligned arma_counter<T> counter;
-  
-  arma_aligned Mat<eT> r_mean;
-  arma_aligned Mat< T> r_var;
-  arma_aligned Mat<eT> r_cov;
-  
-  arma_aligned Mat<eT> min_val;
-  arma_aligned Mat<eT> max_val;
-  
-  arma_aligned Mat< T> min_val_norm;
-  arma_aligned Mat< T> max_val_norm;
-  
-  arma_aligned Mat< T> r_var_dummy;
-  arma_aligned Mat<eT> r_cov_dummy;
-  
-  arma_aligned Mat<eT> tmp1;
-  arma_aligned Mat<eT> tmp2;
-  
-  friend class running_stat_vec_aux;
-  };
-
-
-
-class running_stat_vec_aux
-  {
-  public:
-  
-  template<typename eT>
-  inline static void update_stats(running_stat_vec< eT >&              x, const Mat<eT>&                sample);
-  
-  template<typename T>
-  inline static void update_stats(running_stat_vec< std::complex<T> >& x, const Mat< T>&                sample);
-  
-  template<typename T>
-  inline static void update_stats(running_stat_vec< std::complex<T> >& x, const Mat< std::complex<T> >& sample);
-  
-  //
-  
-  template<typename eT>
-  inline static Mat<eT> var(const running_stat_vec< eT >&              x, const uword norm_type = 0);
-  
-  template<typename T>
-  inline static Mat< T> var(const running_stat_vec< std::complex<T> >& x, const uword norm_type = 0);
-  
-  //
-  
-  template<typename eT>
-  inline static Mat<              eT > cov(const running_stat_vec< eT >&              x, const uword norm_type = 0);
-  
-  template<typename T>
-  inline static Mat< std::complex<T> > cov(const running_stat_vec< std::complex<T> >& x, const uword norm_type = 0);
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/running_stat_vec_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,578 +0,0 @@
-// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup running_stat_vec
-//! @{
-
-
-
-template<typename eT>
-running_stat_vec<eT>::~running_stat_vec()
-  {
-  arma_extra_debug_sigprint_this(this);
-  }
-
-
-
-template<typename eT>
-running_stat_vec<eT>::running_stat_vec(const bool in_calc_cov)
-  : calc_cov(in_calc_cov)
-  {
-  arma_extra_debug_sigprint_this(this);
-  }
-
-
-
-template<typename eT>
-running_stat_vec<eT>::running_stat_vec(const running_stat_vec<eT>& in_rsv)
-  : calc_cov    (in_rsv.calc_cov)
-  , counter     (in_rsv.counter)
-  , r_mean      (in_rsv.r_mean)
-  , r_var       (in_rsv.r_var)
-  , r_cov       (in_rsv.r_cov)
-  , min_val     (in_rsv.min_val)
-  , max_val     (in_rsv.max_val)
-  , min_val_norm(in_rsv.min_val_norm)
-  , max_val_norm(in_rsv.max_val_norm)
-  {
-  arma_extra_debug_sigprint_this(this);
-  }
-
-
-
-template<typename eT>
-const running_stat_vec<eT>&
-running_stat_vec<eT>::operator=(const running_stat_vec<eT>& in_rsv)
-  {
-  arma_extra_debug_sigprint();
-  
-  access::rw(calc_cov) = in_rsv.calc_cov;
-  
-  counter      = in_rsv.counter;
-  r_mean       = in_rsv.r_mean;
-  r_var        = in_rsv.r_var;
-  r_cov        = in_rsv.r_cov;
-  min_val      = in_rsv.min_val;
-  max_val      = in_rsv.max_val;
-  min_val_norm = in_rsv.min_val_norm;
-  max_val_norm = in_rsv.max_val_norm;
-  
-  return *this;
-  }
-
-
-
-//! update statistics to reflect new sample
-template<typename eT>
-template<typename T1>
-arma_hot
-inline
-void
-running_stat_vec<eT>::operator() (const Base<typename get_pod_type<eT>::result, T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  //typedef typename get_pod_type<eT>::result T;
-  
-  const unwrap<T1>        tmp(X.get_ref());
-  const Mat<eT>& sample = tmp.M;
-  
-  if( sample.is_empty() )
-    {
-    return;
-    }
-  
-  if( sample.is_finite() == false )
-    {
-    arma_warn(true, "running_stat_vec: sample ignored as it has non-finite elements");
-    return;
-    }
-  
-  running_stat_vec_aux::update_stats(*this, sample);
-  }
-
-
-
-//! update statistics to reflect new sample (version for complex numbers)
-template<typename eT>
-template<typename T1>
-arma_hot
-inline
-void
-running_stat_vec<eT>::operator() (const Base<std::complex<typename get_pod_type<eT>::result>, T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  //typedef typename std::complex<typename get_pod_type<eT>::result> eT;
-  
-  const unwrap<T1>        tmp(X.get_ref());
-  const Mat<eT>& sample = tmp.M;
-  
-  if( sample.is_empty() )
-    {
-    return;
-    }
-  
-  if( sample.is_finite() == false )
-    {
-    arma_warn(true, "running_stat_vec: sample ignored as it has non-finite elements");
-    return;
-    }
-  
-  running_stat_vec_aux::update_stats(*this, sample);
-  }
-
-
-
-//! set all statistics to zero
-template<typename eT>
-inline
-void
-running_stat_vec<eT>::reset()
-  {
-  arma_extra_debug_sigprint();
-  
-  counter.reset();
-  
-  r_mean.reset();
-  r_var.reset();
-  r_cov.reset();
-  
-  min_val.reset();
-  max_val.reset();
-  
-  min_val_norm.reset();
-  max_val_norm.reset();
-  
-  r_var_dummy.reset();
-  r_cov_dummy.reset();
-  
-  tmp1.reset();
-  tmp2.reset();
-  }
-
-
-
-//! mean or average value
-template<typename eT>
-inline
-const Mat<eT>&
-running_stat_vec<eT>::mean() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return r_mean;
-  }
-
-
-
-//! variance
-template<typename eT>
-inline
-const Mat<typename get_pod_type<eT>::result>&
-running_stat_vec<eT>::var(const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  const T N = counter.value();
-  
-  if(N > T(1))
-    {
-    if(norm_type == 0)
-      {
-      return r_var;
-      }
-    else
-      {
-      const T N_minus_1 = counter.value_minus_1();
-      
-      r_var_dummy = (N_minus_1/N) * r_var;
-      
-      return r_var_dummy;
-      }
-    }
-  else
-    {
-    r_var_dummy.zeros(r_mean.n_rows, r_mean.n_cols);
-    
-    return r_var_dummy;
-    }
-  
-  }
-
-
-
-//! standard deviation
-template<typename eT>
-inline
-Mat<typename get_pod_type<eT>::result>
-running_stat_vec<eT>::stddev(const uword norm_type) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const T N = counter.value();
-  
-  if(N > T(1))
-    {
-    if(norm_type == 0)
-      {
-      return sqrt(r_var);
-      }
-    else
-      {
-      const T N_minus_1 = counter.value_minus_1();
-      
-      return sqrt( (N_minus_1/N) * r_var );
-      }
-    }
-  else
-    {
-    return Mat<T>();
-    }
-  }
-
-
-
-//! covariance
-template<typename eT>
-inline
-const Mat<eT>&
-running_stat_vec<eT>::cov(const uword norm_type)
-  {
-  arma_extra_debug_sigprint();
-  
-  if(calc_cov == true)
-    {
-    const T N = counter.value();
-    
-    if(N > T(1))
-      {
-      if(norm_type == 0)
-        {
-        return r_cov;
-        }
-      else
-        {
-        const T N_minus_1 = counter.value_minus_1();
-        
-        r_cov_dummy = (N_minus_1/N) * r_cov;
-        
-        return r_cov_dummy;
-        }
-      }
-    else
-      {
-      r_cov_dummy.zeros(r_mean.n_rows, r_mean.n_cols);
-      
-      return r_cov_dummy;
-      }
-    }
-  else
-    {
-    r_cov_dummy.reset();
-    
-    return r_cov_dummy;
-    }
-  
-  }
-
-
-
-//! vector with minimum values
-template<typename eT>
-inline
-const Mat<eT>&
-running_stat_vec<eT>::min() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return min_val;
-  }
-
-
-
-//! vector with maximum values
-template<typename eT>
-inline
-const Mat<eT>&
-running_stat_vec<eT>::max() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return max_val;
-  }
-
-
-
-//! number of samples so far
-template<typename eT>
-inline
-typename get_pod_type<eT>::result
-running_stat_vec<eT>::count() const
-  {
-  arma_extra_debug_sigprint();
-  
-  return counter.value();
-  }
-
-
-
-//
-
-
-
-//! update statistics to reflect new sample
-template<typename eT>
-inline
-void
-running_stat_vec_aux::update_stats(running_stat_vec<eT>& x, const Mat<eT>& sample)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename running_stat_vec<eT>::T T;
-  
-  const T N = x.counter.value();
-  
-  if(N > T(0))
-    {
-    arma_debug_assert_same_size(x.r_mean, sample, "running_stat_vec(): dimensionality mismatch");
-    
-    const uword n_elem      = sample.n_elem;
-    const eT* sample_mem  = sample.memptr();
-          eT* r_mean_mem  = x.r_mean.memptr();
-           T* r_var_mem   = x.r_var.memptr();
-          eT* min_val_mem = x.min_val.memptr();
-          eT* max_val_mem = x.max_val.memptr();
-    
-    const T  N_plus_1   = x.counter.value_plus_1();
-    const T  N_minus_1  = x.counter.value_minus_1();
-    
-    if(x.calc_cov == true)
-      {
-      Mat<eT>& tmp1 = x.tmp1;
-      Mat<eT>& tmp2 = x.tmp2;
-      
-      tmp1 = sample - x.r_mean;
-      
-      if(sample.n_cols == 1)
-        {
-        tmp2 = tmp1*trans(tmp1);
-        }
-      else
-        {
-        tmp2 = trans(tmp1)*tmp1;
-        }
-      
-      x.r_cov *= (N_minus_1/N);
-      x.r_cov += tmp2 / N_plus_1;
-      }
-    
-    
-    for(uword i=0; i<n_elem; ++i)
-      {
-      const eT val = sample_mem[i];
-      
-      if(val < min_val_mem[i])
-        {
-        min_val_mem[i] = val;
-        }
-      
-      if(val > max_val_mem[i])
-        {
-        max_val_mem[i] = val;
-        }
-        
-      const eT r_mean_val = r_mean_mem[i];
-      const eT tmp        = val - r_mean_val;
-    
-      r_var_mem[i] = N_minus_1/N * r_var_mem[i] + (tmp*tmp)/N_plus_1;
-      
-      r_mean_mem[i] = r_mean_val + (val - r_mean_val)/N_plus_1;
-      }
-    }
-  else
-    {
-    arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector");
-    
-    x.r_mean.set_size(sample.n_rows, sample.n_cols);
-    
-    x.r_var.zeros(sample.n_rows, sample.n_cols);
-    
-    if(x.calc_cov == true)
-      {
-      x.r_cov.zeros(sample.n_elem, sample.n_elem);
-      }
-    
-    x.min_val.set_size(sample.n_rows, sample.n_cols);
-    x.max_val.set_size(sample.n_rows, sample.n_cols);
-    
-    
-    const uword n_elem      = sample.n_elem;
-    const eT* sample_mem  = sample.memptr();
-          eT* r_mean_mem  = x.r_mean.memptr();
-          eT* min_val_mem = x.min_val.memptr();
-          eT* max_val_mem = x.max_val.memptr();
-          
-    
-    for(uword i=0; i<n_elem; ++i)
-      {
-      const eT val = sample_mem[i];
-      
-      r_mean_mem[i]  = val;
-      min_val_mem[i] = val;
-      max_val_mem[i] = val;
-      }
-    }
-  
-  x.counter++;
-  }
-
-
-
-//! update statistics to reflect new sample (version for complex numbers)
-template<typename T>
-inline
-void
-running_stat_vec_aux::update_stats(running_stat_vec< std::complex<T> >& x, const Mat<T>& sample)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Mat< std::complex<T> > tmp = conv_to< Mat< std::complex<T> > >::from(sample);
-  
-  running_stat_vec_aux::update_stats(x, tmp);
-  }
-
-
-
-//! alter statistics to reflect new sample (version for complex numbers)
-template<typename T>
-inline
-void
-running_stat_vec_aux::update_stats(running_stat_vec< std::complex<T> >& x, const Mat< std::complex<T> >& sample)
-  {
-  arma_extra_debug_sigprint();
-  
-  typedef typename std::complex<T> eT;
-  
-  const T N = x.counter.value();
-  
-  if(N > T(0))
-    {
-    arma_debug_assert_same_size(x.r_mean, sample, "running_stat_vec(): dimensionality mismatch");
-    
-    const uword n_elem           = sample.n_elem;
-    const eT* sample_mem       = sample.memptr();
-          eT* r_mean_mem       = x.r_mean.memptr();
-           T* r_var_mem        = x.r_var.memptr();
-          eT* min_val_mem      = x.min_val.memptr();
-          eT* max_val_mem      = x.max_val.memptr();
-           T* min_val_norm_mem = x.min_val_norm.memptr();
-           T* max_val_norm_mem = x.max_val_norm.memptr();
-    
-    const T  N_plus_1   = x.counter.value_plus_1();
-    const T  N_minus_1  = x.counter.value_minus_1();
-    
-    if(x.calc_cov == true)
-      {
-      Mat<eT>& tmp1 = x.tmp1;
-      Mat<eT>& tmp2 = x.tmp2;
-      
-      tmp1 = sample - x.r_mean;
-      
-      if(sample.n_cols == 1)
-        {
-        tmp2 = arma::conj(tmp1)*strans(tmp1);
-        }
-      else
-        {
-        tmp2 = trans(tmp1)*tmp1;  //tmp2 = strans(conj(tmp1))*tmp1;
-        }
-      
-      x.r_cov *= (N_minus_1/N);
-      x.r_cov += tmp2 / N_plus_1;
-      }
-    
-    
-    for(uword i=0; i<n_elem; ++i)
-      {
-      const eT& val      = sample_mem[i];
-      const  T  val_norm = std::norm(val);
-      
-      if(val_norm < min_val_norm_mem[i])
-        {
-        min_val_norm_mem[i] = val_norm;
-        min_val_mem[i]      = val;
-        }
-      
-      if(val_norm > max_val_norm_mem[i])
-        {
-        max_val_norm_mem[i] = val_norm;
-        max_val_mem[i]      = val;
-        }
-      
-      const eT& r_mean_val = r_mean_mem[i];
-      
-      r_var_mem[i] = N_minus_1/N * r_var_mem[i] + std::norm(val - r_mean_val)/N_plus_1;
-      
-      r_mean_mem[i] = r_mean_val + (val - r_mean_val)/N_plus_1;
-      }
-    
-    }
-  else
-    {
-    arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector");
-    
-    x.r_mean.set_size(sample.n_rows, sample.n_cols);
-    
-    x.r_var.zeros(sample.n_rows, sample.n_cols);
-    
-    if(x.calc_cov == true)
-      {
-      x.r_cov.zeros(sample.n_elem, sample.n_elem);
-      }
-    
-    x.min_val.set_size(sample.n_rows, sample.n_cols);
-    x.max_val.set_size(sample.n_rows, sample.n_cols);
-    
-    x.min_val_norm.set_size(sample.n_rows, sample.n_cols);
-    x.max_val_norm.set_size(sample.n_rows, sample.n_cols);
-    
-    
-    const uword n_elem           = sample.n_elem;
-    const eT* sample_mem       = sample.memptr();
-          eT* r_mean_mem       = x.r_mean.memptr();
-          eT* min_val_mem      = x.min_val.memptr();
-          eT* max_val_mem      = x.max_val.memptr();
-           T* min_val_norm_mem = x.min_val_norm.memptr();
-           T* max_val_norm_mem = x.max_val_norm.memptr();
-    
-    for(uword i=0; i<n_elem; ++i)
-      {
-      const eT& val      = sample_mem[i];
-      const  T  val_norm = std::norm(val);
-      
-      r_mean_mem[i]  = val;
-      min_val_mem[i] = val;
-      max_val_mem[i] = val;
-      
-      min_val_norm_mem[i] = val_norm;
-      max_val_norm_mem[i] = val_norm;
-      }
-    }
-  
-  x.counter++;
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/span.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// Copyright (C) 2011 Stanislav Funiak
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-//! \addtogroup span
-//! @{
-
-
-struct span_alt {};
-
-
-template<typename Dummy = int>
-class span_base
-  {
-  public:
-  static const span_alt all;
-  };
-
-
-template<typename Dummy>
-const span_alt span_base<Dummy>::all = span_alt();
-
-
-class span : public span_base<>
-  {
-  public:
-
-  uword a;
-  uword b;
-  bool  whole;
-  
-  inline
-  span()
-    : whole(true)
-    {
-    }
-  
-  
-  inline
-  span(const span_alt&)
-    : whole(true)
-    {
-    }
-  
-  // TODO:
-  // if the "explicit" keyword is removed or commented out,
-  // the compiler will be able to automatically convert integers to an instance of the span class.
-  // this is useful for Cube::operator()(span&, span&, span&),
-  // but it might have unintended consequences or interactions elsewhere.
-  // as such, removal of "explicit" needs thorough testing.
-  inline
-  explicit
-  span(const uword in_a)
-    : a(in_a)
-    , b(in_a)
-    , whole(false)
-    {
-    }
-  
-  inline
-  span(const uword in_a, const uword in_b)
-    : a(in_a)
-    , b(in_b)
-    , whole(false)
-    {
-    }
-
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/strip.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup strip
-//! @{
-
-
-
-template<typename T1>
-struct strip_diagmat
-  {
-  typedef T1 stored_type;
-  
-  inline strip_diagmat(const Base<typename T1::elem_type, T1>& X)
-    : M(X.get_ref())
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  static const bool do_diagmat = false;
-  
-  const T1& M;
-  };
-
-
-
-template<typename T1>
-struct strip_diagmat< Op<T1, op_diagmat> >
-  {
-  typedef T1 stored_type;
-  
-  inline strip_diagmat(const Op<T1, op_diagmat>& X)
-    : M(X.m)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  static const bool do_diagmat = true;
-  
-  const T1& M;
-  };
-
-
-
-template<typename T1>
-struct strip_inv
-  {
-  typedef T1 stored_type;
-  
-  inline strip_inv(const T1& X)
-    : M(X)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  static const bool do_inv = false;
-  
-  const T1& M;
-  };
-
-
-
-template<typename T1>
-struct strip_inv< Op<T1, op_inv> >
-  {
-  typedef T1 stored_type;
-  
-  inline strip_inv(const Op<T1, op_inv>& X)
-    : M(X.m)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  static const bool do_inv = true;
-  
-  const T1& M;
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/subview_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,254 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// Copyright (C)      2011 James Sanders
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup subview
-//! @{
-
-
-//! Class for storing data required to construct or apply operations to a submatrix
-//! (i.e. where the submatrix starts and ends as well as a reference/pointer to the original matrix),
-template<typename eT>
-class subview : public Base<eT, subview<eT> >
-  {
-  public:    arma_aligned const Mat<eT>& m;
-  protected: arma_aligned       Mat<eT>* m_ptr;
-  
-  public:
-  
-  typedef eT                                       elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  const uword aux_row1;
-  const uword aux_col1;
-  
-  const uword n_rows;
-  const uword n_cols;
-  const uword n_elem;
-  
-  
-  protected:
-  
-  arma_inline subview(const Mat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols);
-  arma_inline subview(      Mat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols);
-  
-  
-  public:
-  
-  inline ~subview();
-  
-  inline void operator+= (const eT val);
-  inline void operator-= (const eT val);
-  inline void operator*= (const eT val);
-  inline void operator/= (const eT val);
-  
-  // deliberately returning void
-  template<typename T1> inline void operator=  (const Base<eT,T1>& x);
-  template<typename T1> inline void operator+= (const Base<eT,T1>& x);
-  template<typename T1> inline void operator-= (const Base<eT,T1>& x);
-  template<typename T1> inline void operator%= (const Base<eT,T1>& x);
-  template<typename T1> inline void operator/= (const Base<eT,T1>& x);
-  
-  inline void operator=  (const subview& x);
-  inline void operator+= (const subview& x);
-  inline void operator-= (const subview& x);
-  inline void operator%= (const subview& x);
-  inline void operator/= (const subview& x);
-  
-  inline static void extract(Mat<eT>& out, const subview& in);
-  
-  inline static void  plus_inplace(Mat<eT>& out, const subview& in);
-  inline static void minus_inplace(Mat<eT>& out, const subview& in);
-  inline static void schur_inplace(Mat<eT>& out, const subview& in);
-  inline static void   div_inplace(Mat<eT>& out, const subview& in);
-  
-  inline void fill(const eT val);
-  inline void zeros();
-  inline void ones();
-  inline void eye();
-  
-  inline eT& operator[](const uword i);
-  inline eT  operator[](const uword i) const;
-  
-  inline eT& operator()(const uword i);
-  inline eT  operator()(const uword i) const;
-  
-  inline eT& operator()(const uword in_row, const uword in_col);
-  inline eT  operator()(const uword in_row, const uword in_col) const;
-  
-  inline eT&         at(const uword in_row, const uword in_col);
-  inline eT          at(const uword in_row, const uword in_col) const;
-  
-  arma_inline       eT* colptr(const uword in_col);
-  arma_inline const eT* colptr(const uword in_col) const;
-  
-  inline bool check_overlap(const subview& x) const;
-  
-  inline bool is_vec() const;
-  
-  inline       subview_row<eT> row(const uword row_num);
-  inline const subview_row<eT> row(const uword row_num) const;
-  
-  inline            subview_row<eT> operator()(const uword row_num, const span& col_span);
-  inline      const subview_row<eT> operator()(const uword row_num, const span& col_span) const;
-  
-  inline       subview_col<eT> col(const uword col_num);
-  inline const subview_col<eT> col(const uword col_num) const;
-  
-  inline            subview_col<eT> operator()(const span& row_span, const uword col_num);
-  inline      const subview_col<eT> operator()(const span& row_span, const uword col_num) const;
-  
-  inline            Col<eT>  unsafe_col(const uword col_num);
-  inline      const Col<eT>  unsafe_col(const uword col_num) const;
-  
-  inline       subview<eT> rows(const uword in_row1, const uword in_row2);
-  inline const subview<eT> rows(const uword in_row1, const uword in_row2) const;
-  
-  inline       subview<eT> cols(const uword in_col1, const uword in_col2);
-  inline const subview<eT> cols(const uword in_col1, const uword in_col2) const;
-  
-  inline       subview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2);
-  inline const subview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const;
-  
-  inline            subview<eT> submat    (const span& row_span, const span& col_span);
-  inline      const subview<eT> submat    (const span& row_span, const span& col_span) const;
-  
-  inline            subview<eT> operator()(const span& row_span, const span& col_span);
-  inline      const subview<eT> operator()(const span& row_span, const span& col_span) const;
-  
-  inline       diagview<eT> diag(const sword in_id = 0);
-  inline const diagview<eT> diag(const sword in_id = 0) const;
-  
-  inline void swap_rows(const uword in_row1, const uword in_row2);
-  inline void swap_cols(const uword in_col1, const uword in_col2);
-  
-  
-  // // primitive forward iterator
-  // class iter
-  //   {
-  //   public:
-  //   
-  //   inline iter(const subview<eT>& in_M);
-  //   
-  //   arma_inline eT operator* () const;
-  //   
-  //   inline void operator++();
-  //   inline void operator++(int);
-  //   
-  //   
-  //   private:
-  //   
-  //   arma_aligned const eT* mem;
-  //   
-  //   arma_aligned uword n_rows;
-  //   
-  //   arma_aligned uword row_start;
-  //   arma_aligned uword row_end_p1;
-  //   
-  //   arma_aligned uword row;
-  //   arma_aligned uword col;
-  //   arma_aligned uword i;
-  //   };
-  
-  
-  private:
-  
-  friend class Mat<eT>;
-  subview();
-  };
-
-
-
-template<typename eT>
-class subview_col : public subview<eT>
-  {
-  public:
-  
-  typedef eT                                       elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  inline void operator= (const subview<eT>& x);
-  inline void operator= (const subview_col& x);
-  
-  template<typename T1>
-  inline void operator= (const Base<eT,T1>& x);
-  
-  inline       subview_col<eT> rows(const uword in_row1, const uword in_row2);
-  inline const subview_col<eT> rows(const uword in_row1, const uword in_row2) const;
-  
-  inline       subview_col<eT> subvec(const uword in_row1, const uword in_row2);
-  inline const subview_col<eT> subvec(const uword in_row1, const uword in_row2) const;
-  
-  
-  protected:
-  
-  inline subview_col(const Mat<eT>& in_m, const uword in_col);
-  inline subview_col(      Mat<eT>& in_m, const uword in_col);
-  
-  inline subview_col(const Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows);
-  inline subview_col(      Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows);
-  
-  
-  private:
-  
-  friend class Mat<eT>;
-  friend class Col<eT>;
-  friend class subview<eT>;
-  
-  subview_col();
-  };
-
-
-
-template<typename eT>
-class subview_row : public subview<eT>
-  {
-  public:
-  
-  typedef eT                                       elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  inline void operator= (const subview<eT>& x);
-  inline void operator= (const subview_row& x);
-  
-  template<typename T1>
-  inline void operator= (const Base<eT,T1>& x);
-  
-  inline       subview_row<eT> cols(const uword in_col1, const uword in_col2);
-  inline const subview_row<eT> cols(const uword in_col1, const uword in_col2) const;
-  
-  inline       subview_row<eT> subvec(const uword in_col1, const uword in_col2);
-  inline const subview_row<eT> subvec(const uword in_col1, const uword in_col2) const;
-  
-  
-  protected:
-  
-  inline subview_row(const Mat<eT>& in_m, const uword in_row);
-  inline subview_row(      Mat<eT>& in_m, const uword in_row);
-  
-  inline subview_row(const Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols);
-  inline subview_row(      Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols);
-  
-  
-  private:
-  
-  friend class Mat<eT>;
-  friend class Row<eT>;
-  friend class subview<eT>;
-  
-  subview_row();
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/subview_cube_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup subview_cube
-//! @{
-
-
-//! Class for storing data required to construct or apply operations to a subcube
-//! (i.e. where the subcube starts and ends as well as a reference/pointer to the original cube),
-template<typename eT>
-class subview_cube : public BaseCube<eT, subview_cube<eT> >
-  {
-  public:    arma_aligned const Cube<eT>& m;
-  protected: arma_aligned       Cube<eT>* m_ptr;
-  
-  public:
-  
-  typedef eT                                       elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  const uword aux_row1;
-  const uword aux_col1;
-  const uword aux_slice1;
-  
-  const uword n_rows;
-  const uword n_cols;
-  const uword n_elem_slice;
-  const uword n_slices;
-  const uword n_elem;
-  
-  
-  protected:
-  
-  arma_inline subview_cube(const Cube<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_n_rows, const uword in_n_cols, const uword in_n_slices);
-  arma_inline subview_cube(      Cube<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_n_rows, const uword in_n_cols, const uword in_n_slices);
-  
-  
-  public:
-  
-  inline ~subview_cube();
-  
-  inline void operator+= (const eT val);
-  inline void operator-= (const eT val);
-  inline void operator*= (const eT val);
-  inline void operator/= (const eT val);
-  
-  // deliberately returning void
-  template<typename T1> inline void operator=  (const BaseCube<eT,T1>& x);
-  template<typename T1> inline void operator+= (const BaseCube<eT,T1>& x);
-  template<typename T1> inline void operator-= (const BaseCube<eT,T1>& x);
-  template<typename T1> inline void operator%= (const BaseCube<eT,T1>& x);
-  template<typename T1> inline void operator/= (const BaseCube<eT,T1>& x);
-  
-  inline void operator=  (const subview_cube& x);
-  inline void operator+= (const subview_cube& x);
-  inline void operator-= (const subview_cube& x);
-  inline void operator%= (const subview_cube& x);
-  inline void operator/= (const subview_cube& x);
-  
-  template<typename T1> inline void operator=  (const Base<eT,T1>& x);
-  template<typename T1> inline void operator+= (const Base<eT,T1>& x);
-  template<typename T1> inline void operator-= (const Base<eT,T1>& x);
-  template<typename T1> inline void operator%= (const Base<eT,T1>& x);
-  template<typename T1> inline void operator/= (const Base<eT,T1>& x);
-
-  inline static void       extract(Cube<eT>& out, const subview_cube& in);
-  inline static void  plus_inplace(Cube<eT>& out, const subview_cube& in);
-  inline static void minus_inplace(Cube<eT>& out, const subview_cube& in);
-  inline static void schur_inplace(Cube<eT>& out, const subview_cube& in);
-  inline static void   div_inplace(Cube<eT>& out, const subview_cube& in);
-  
-  inline static void       extract(Mat<eT>& out, const subview_cube& in);
-  inline static void  plus_inplace(Mat<eT>& out, const subview_cube& in);
-  inline static void minus_inplace(Mat<eT>& out, const subview_cube& in);
-  inline static void schur_inplace(Mat<eT>& out, const subview_cube& in);
-  inline static void   div_inplace(Mat<eT>& out, const subview_cube& in);
-
-  inline void fill(const eT val);
-  inline void zeros();
-  inline void ones();
-  
-  inline eT& operator[](const uword i);
-  inline eT  operator[](const uword i) const;
-  
-  inline eT& operator()(const uword i);
-  inline eT  operator()(const uword i) const;
-  
-  arma_inline eT& operator()(const uword in_row, const uword in_col, const uword in_slice);
-  arma_inline eT  operator()(const uword in_row, const uword in_col, const uword in_slice) const;
-  
-  arma_inline eT&         at(const uword in_row, const uword in_col, const uword in_slice);
-  arma_inline eT          at(const uword in_row, const uword in_col, const uword in_slice) const;
-  
-  arma_inline       eT* slice_colptr(const uword in_slice, const uword in_col);
-  arma_inline const eT* slice_colptr(const uword in_slice, const uword in_col) const;
-  
-  inline bool check_overlap(const subview_cube& x) const;
-  inline bool check_overlap(const Mat<eT>&      x) const;
-  
-  
-  private:
-  
-  friend class  Mat<eT>;
-  friend class Cube<eT>;
-  
-  subview_cube();
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/subview_cube_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1745 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup subview_cube
-//! @{
-
-
-template<typename eT>
-inline
-subview_cube<eT>::~subview_cube()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-arma_inline
-subview_cube<eT>::subview_cube
-  (
-  const Cube<eT>& in_m,
-  const uword       in_row1,
-  const uword       in_col1,
-  const uword       in_slice1,
-  const uword       in_n_rows,
-  const uword       in_n_cols,
-  const uword       in_n_slices
-  )
-  : m           (in_m)
-  , m_ptr       (0)
-  , aux_row1    (in_row1)
-  , aux_col1    (in_col1)
-  , aux_slice1  (in_slice1)
-  , n_rows      (in_n_rows)
-  , n_cols      (in_n_cols)
-  , n_elem_slice(in_n_rows * in_n_cols)
-  , n_slices    (in_n_slices)
-  , n_elem      (n_elem_slice * in_n_slices)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-arma_inline
-subview_cube<eT>::subview_cube
-  (
-        Cube<eT>& in_m,
-  const uword       in_row1,
-  const uword       in_col1,
-  const uword       in_slice1,
-  const uword       in_n_rows,
-  const uword       in_n_cols,
-  const uword       in_n_slices
-  )
-  : m           (in_m)
-  , m_ptr       (&in_m)
-  , aux_row1    (in_row1)
-  , aux_col1    (in_col1)
-  , aux_slice1  (in_slice1)
-  , n_rows      (in_n_rows)
-  , n_cols      (in_n_cols)
-  , n_elem_slice(in_n_rows * in_n_cols)
-  , n_slices    (in_n_slices)
-  , n_elem      (n_elem_slice * in_n_slices)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_cube<eT>::operator+= (const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword local_n_rows   = n_rows;
-  const uword local_n_cols   = n_cols;
-  const uword local_n_slices = n_slices;
-  
-  for(uword slice = 0; slice < local_n_slices; ++slice)
-    {
-    for(uword col = 0; col < local_n_cols; ++col)
-      {
-      arrayops::inplace_plus( slice_colptr(slice,col), val, local_n_rows );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_cube<eT>::operator-= (const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword local_n_rows   = n_rows;
-  const uword local_n_cols   = n_cols;
-  const uword local_n_slices = n_slices;
-  
-  for(uword slice = 0; slice < local_n_slices; ++slice)
-    {
-    for(uword col = 0; col < local_n_cols; ++col)
-      {
-      arrayops::inplace_minus( slice_colptr(slice,col), val, local_n_rows );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_cube<eT>::operator*= (const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword local_n_rows   = n_rows;
-  const uword local_n_cols   = n_cols;
-  const uword local_n_slices = n_slices;
-  
-  for(uword slice = 0; slice < local_n_slices; ++slice)
-    {
-    for(uword col = 0; col < local_n_cols; ++col)
-      {
-      arrayops::inplace_mul( slice_colptr(slice,col), val, local_n_rows );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_cube<eT>::operator/= (const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword local_n_rows   = n_rows;
-  const uword local_n_cols   = n_cols;
-  const uword local_n_slices = n_slices;
-  
-  for(uword slice = 0; slice < local_n_slices; ++slice)
-    {
-    for(uword col = 0; col < local_n_cols; ++col)
-      {
-      arrayops::inplace_div( slice_colptr(slice,col), val, local_n_rows );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview_cube<eT>::operator= (const BaseCube<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap_cube<T1> tmp(in.get_ref());
-  
-  const Cube<eT>&         x = tmp.M;
-        subview_cube<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "copy into subcube");
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  for(uword slice = 0; slice < t_n_slices; ++slice)
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::copy( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview_cube<eT>::operator+= (const BaseCube<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap_cube<T1> tmp(in.get_ref());
-  
-  const Cube<eT>&         x = tmp.M;
-        subview_cube<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "addition");
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  for(uword slice = 0; slice < t_n_slices; ++slice)
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::inplace_plus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview_cube<eT>::operator-= (const BaseCube<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap_cube<T1> tmp(in.get_ref());
-  
-  const Cube<eT>&         x = tmp.M;
-        subview_cube<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "subtraction");
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  for(uword slice = 0; slice < t_n_slices; ++slice)
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::inplace_minus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview_cube<eT>::operator%= (const BaseCube<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap_cube<T1> tmp(in.get_ref());
-  
-  const Cube<eT>&         x = tmp.M;
-        subview_cube<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "element-wise multiplication");
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  for(uword slice = 0; slice < t_n_slices; ++slice)
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::inplace_mul( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview_cube<eT>::operator/= (const BaseCube<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap_cube<T1> tmp(in.get_ref());
-  
-  const Cube<eT>&         x = tmp.M;
-        subview_cube<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "element-wise division");
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  for(uword slice = 0; slice < t_n_slices; ++slice)
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
-      }
-    }
-  }
-
-
-
-//! x.subcube(...) = y.subcube(...)
-template<typename eT>
-inline
-void
-subview_cube<eT>::operator= (const subview_cube<eT>& x_in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool overlap = check_overlap(x_in);
-  
-        Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
-  const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
-  const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
-  
-  subview_cube<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "copy into subcube");
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  for(uword slice = 0; slice < t_n_slices; ++slice)
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::copy( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
-      }
-    }
-    
-  if(overlap)
-    {
-    delete tmp_subview_cube;
-    delete tmp_cube;
-    }
-  
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_cube<eT>::operator+= (const subview_cube<eT>& x_in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool overlap = check_overlap(x_in);
-  
-        Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
-  const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
-  const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
-  
-  subview_cube<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "addition");
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  for(uword slice = 0; slice < t_n_slices; ++slice)
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::inplace_plus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
-      }
-    }
-  
-  if(overlap)
-    {
-    delete tmp_subview_cube;
-    delete tmp_cube;
-    }
-  
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_cube<eT>::operator-= (const subview_cube<eT>& x_in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool overlap = check_overlap(x_in);
-  
-        Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
-  const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
-  const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
-  
-  subview_cube<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "subtraction");
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  for(uword slice = 0; slice < t_n_slices; ++slice)
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::inplace_minus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
-      }
-    }
-  
-  if(overlap)
-    {
-    delete tmp_subview_cube;
-    delete tmp_cube;
-    }
-    
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_cube<eT>::operator%= (const subview_cube<eT>& x_in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool overlap = check_overlap(x_in);
-  
-        Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
-  const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
-  const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
-  
-  subview_cube<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "element-wise multiplication");
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  for(uword slice = 0; slice < t_n_slices; ++slice)
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::inplace_mul( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
-      }
-    }
-  
-  if(overlap)
-    {
-    delete tmp_subview_cube;
-    delete tmp_cube;
-    }
-  
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_cube<eT>::operator/= (const subview_cube<eT>& x_in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool overlap = check_overlap(x_in);
-  
-        Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
-  const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
-  const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
-  
-  subview_cube<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "element-wise division");
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  for(uword slice = 0; slice < t_n_slices; ++slice)
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
-      }
-    }
-  
-  if(overlap)
-    {
-    delete tmp_subview_cube;
-    delete tmp_cube;
-    }
-  
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview_cube<eT>::operator= (const Base<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1> tmp(in.get_ref());
-  
-  const Mat<eT>&          x = tmp.M;
-        subview_cube<eT>& t = *this;
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  const uword x_n_rows   = x.n_rows;
-  const uword x_n_cols   = x.n_cols;
-  
-  if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
-    {
-    // interpret the matrix as a cube with one slice
-    
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::copy( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
-      }
-    }
-  else
-  if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
-    {
-    for(uword i=0; i < t_n_slices; ++i)
-      {
-      arrayops::copy( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
-      }
-    }
-  else
-  if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
-    {
-    Cube<eT>& Q = *(t.m_ptr);
-    
-    const uword t_aux_row1   = t.aux_row1;
-    const uword t_aux_col1   = t.aux_col1;
-    const uword t_aux_slice1 = t.aux_slice1;
-    
-    for(uword slice=0; slice < t_n_slices; ++slice)
-      {
-      const uword mod_slice = t_aux_slice1 + slice;
-      
-      const eT* x_colptr = x.colptr(slice);
-      
-      uword i,j;
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        const eT tmp_i = x_colptr[i];
-        const eT tmp_j = x_colptr[j];
-        
-        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) = tmp_i;
-        Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) = tmp_j;
-        }
-      
-      if(i < t_n_cols)
-        {
-        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) = x_colptr[i];
-        }
-      }
-    }
-  else
-    {
-    if(arma_config::debug == true)
-      {
-      arma_stop( arma_incompat_size_string(t, x, "copy into subcube") );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview_cube<eT>::operator+= (const Base<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1> tmp(in.get_ref());
-  
-  const Mat<eT>&          x = tmp.M;
-        subview_cube<eT>& t = *this;
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  const uword x_n_rows   = x.n_rows;
-  const uword x_n_cols   = x.n_cols;
-  
-  if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::inplace_plus( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
-      }
-    }
-  else
-  if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
-    {
-    for(uword i=0; i < t_n_slices; ++i)
-      {
-      arrayops::inplace_plus( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
-      }
-    }
-  else
-  if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
-    {
-    Cube<eT>& Q = *(t.m_ptr);
-    
-    const uword t_aux_row1   = t.aux_row1;
-    const uword t_aux_col1   = t.aux_col1;
-    const uword t_aux_slice1 = t.aux_slice1;
-    
-    for(uword slice=0; slice < t_n_slices; ++slice)
-      {
-      const uword mod_slice = t_aux_slice1 + slice;
-      
-      const eT* x_colptr = x.colptr(slice);
-      
-      uword i,j;
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        const eT tmp_i = x_colptr[i];
-        const eT tmp_j = x_colptr[j];
-        
-        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) += tmp_i;
-        Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) += tmp_j;
-        }
-      
-      if(i < t_n_cols)
-        {
-        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) += x_colptr[i];
-        }
-      }
-    }
-  else
-    {
-    if(arma_config::debug == true)
-      {
-      arma_stop( arma_incompat_size_string(t, x, "addition") );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview_cube<eT>::operator-= (const Base<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1> tmp(in.get_ref());
-  
-  const Mat<eT>&          x = tmp.M;
-        subview_cube<eT>& t = *this;
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  const uword x_n_rows   = x.n_rows;
-  const uword x_n_cols   = x.n_cols;
-  
-  if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::inplace_minus( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
-      }
-    }
-  else
-  if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
-    {
-    for(uword i=0; i < t_n_slices; ++i)
-      {
-      arrayops::inplace_minus( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
-      }
-    }
-  else
-  if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
-    {
-    Cube<eT>& Q = *(t.m_ptr);
-    
-    const uword t_aux_row1   = t.aux_row1;
-    const uword t_aux_col1   = t.aux_col1;
-    const uword t_aux_slice1 = t.aux_slice1;
-    
-    for(uword slice=0; slice < t_n_slices; ++slice)
-      {
-      const uword mod_slice = t_aux_slice1 + slice;
-      
-      const eT* x_colptr = x.colptr(slice);
-      
-      uword i,j;
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        const eT tmp_i = x_colptr[i];
-        const eT tmp_j = x_colptr[j];
-        
-        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) -= tmp_i;
-        Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) -= tmp_j;
-        }
-      
-      if(i < t_n_cols)
-        {
-        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) -= x_colptr[i];
-        }
-      }
-    }
-  else
-    {
-    if(arma_config::debug == true)
-      {
-      arma_stop( arma_incompat_size_string(t, x, "subtraction") );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview_cube<eT>::operator%= (const Base<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1> tmp(in.get_ref());
-  
-  const Mat<eT>&          x = tmp.M;
-        subview_cube<eT>& t = *this;
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  const uword x_n_rows   = x.n_rows;
-  const uword x_n_cols   = x.n_cols;
-  
-  if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::inplace_mul( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
-      }
-    }
-  else
-  if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
-    {
-    for(uword i=0; i < t_n_slices; ++i)
-      {
-      arrayops::inplace_mul( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
-      }
-    }
-  else
-  if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
-    {
-    Cube<eT>& Q = *(t.m_ptr);
-    
-    const uword t_aux_row1   = t.aux_row1;
-    const uword t_aux_col1   = t.aux_col1;
-    const uword t_aux_slice1 = t.aux_slice1;
-    
-    for(uword slice=0; slice < t_n_slices; ++slice)
-      {
-      const uword mod_slice = t_aux_slice1 + slice;
-      
-      const eT* x_colptr = x.colptr(slice);
-      
-      uword i,j;
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        const eT tmp_i = x_colptr[i];
-        const eT tmp_j = x_colptr[j];
-        
-        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) *= tmp_i;
-        Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) *= tmp_j;
-        }
-      
-      if(i < t_n_cols)
-        {
-        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) *= x_colptr[i];
-        }
-      }
-    }
-  else
-    {
-    if(arma_config::debug == true)
-      {
-      arma_stop( arma_incompat_size_string(t, x, "element-wise multiplication") );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview_cube<eT>::operator/= (const Base<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1> tmp(in.get_ref());
-  
-  const Mat<eT>&          x = tmp.M;
-        subview_cube<eT>& t = *this;
-  
-  const uword t_n_rows   = t.n_rows;
-  const uword t_n_cols   = t.n_cols;
-  const uword t_n_slices = t.n_slices;
-  
-  const uword x_n_rows   = x.n_rows;
-  const uword x_n_cols   = x.n_cols;
-  
-  if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
-    {
-    for(uword col = 0; col < t_n_cols; ++col)
-      {
-      arrayops::inplace_div( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
-      }
-    }
-  else
-  if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
-    {
-    for(uword i=0; i < t_n_slices; ++i)
-      {
-      arrayops::inplace_div( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
-      }
-    }
-  else
-  if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
-    {
-    Cube<eT>& Q = *(t.m_ptr);
-    
-    const uword t_aux_row1   = t.aux_row1;
-    const uword t_aux_col1   = t.aux_col1;
-    const uword t_aux_slice1 = t.aux_slice1;
-    
-    for(uword slice=0; slice < t_n_slices; ++slice)
-      {
-      const uword mod_slice = t_aux_slice1 + slice;
-      
-      const eT* x_colptr = x.colptr(slice);
-      
-      uword i,j;
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        const eT tmp_i = x_colptr[i];
-        const eT tmp_j = x_colptr[j];
-        
-        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) /= tmp_i;
-        Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) /= tmp_j;
-        }
-      
-      if(i < t_n_cols)
-        {
-        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) /= x_colptr[i];
-        }
-      }
-    }
-  else
-    {
-    if(arma_config::debug == true)
-      {
-      arma_stop( arma_incompat_size_string(t, x, "element-wise division") );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_cube<eT>::fill(const eT val)
-  {
-  arma_extra_debug_sigprint();
-
-  const uword local_n_rows   = n_rows;
-  const uword local_n_cols   = n_cols;
-  const uword local_n_slices = n_slices;
-  
-  for(uword slice = 0; slice < local_n_slices; ++slice)
-    {
-    for(uword col = 0; col < local_n_cols; ++col)
-      {
-      arrayops::inplace_set( slice_colptr(slice,col), val, local_n_rows );
-      }
-    }
-  
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_cube<eT>::zeros()
-  {
-  arma_extra_debug_sigprint();
-  
-  fill(eT(0));
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_cube<eT>::ones()
-  {
-  arma_extra_debug_sigprint();
-  
-  fill(eT(1));
-  }
-
-
-
-template<typename eT>
-inline
-eT&
-subview_cube<eT>::operator[](const uword i)
-  {
-  const uword in_slice = i / n_elem_slice;
-  const uword offset   = in_slice * n_elem_slice;
-  const uword j        = i - offset;
-  
-  const uword in_col   = j / n_rows;
-  const uword in_row   = j % n_rows;
-
-  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return access::rw( (*m_ptr).mem[index] );
-  }
-
-
-
-template<typename eT>
-inline
-eT
-subview_cube<eT>::operator[](const uword i) const
-  {
-  const uword in_slice = i / n_elem_slice;
-  const uword offset   = in_slice * n_elem_slice;
-  const uword j        = i - offset;
-  
-  const uword in_col   = j / n_rows;
-  const uword in_row   = j % n_rows;
-
-  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return m.mem[index];
-  }
-
-
-
-template<typename eT>
-inline
-eT&
-subview_cube<eT>::operator()(const uword i)
-  {
-  arma_debug_check( (i >= n_elem), "subview_cube::operator(): index out of bounds");
-  
-  const uword in_slice = i / n_elem_slice;
-  const uword offset   = in_slice * n_elem_slice;
-  const uword j        = i - offset;
-  
-  const uword in_col   = j / n_rows;
-  const uword in_row   = j % n_rows;
-
-  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return access::rw( (*m_ptr).mem[index] );
-  }
-
-
-
-template<typename eT>
-inline
-eT
-subview_cube<eT>::operator()(const uword i) const
-  {
-  arma_debug_check( (i >= n_elem), "subview_cube::operator(): index out of bounds");
-  
-  const uword in_slice = i / n_elem_slice;
-  const uword offset   = in_slice * n_elem_slice;
-  const uword j        = i - offset;
-  
-  const uword in_col   = j / n_rows;
-  const uword in_row   = j % n_rows;
-
-  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return m.mem[index];
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT&
-subview_cube<eT>::operator()(const uword in_row, const uword in_col, const uword in_slice)
-  {
-  arma_debug_check( ( (in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices) ), "subview_cube::operator(): location out of bounds");
-  
-  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return access::rw( (*m_ptr).mem[index] );
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT
-subview_cube<eT>::operator()(const uword in_row, const uword in_col, const uword in_slice) const
-  {
-  arma_debug_check( ( (in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices) ), "subview_cube::operator(): location out of bounds");
-  
-  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return m.mem[index];
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT&
-subview_cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice)
-  {
-  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return access::rw( (*m_ptr).mem[index] );
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT
-subview_cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice) const
-  {
-  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return m.mem[index];
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT*
-subview_cube<eT>::slice_colptr(const uword in_slice, const uword in_col)
-  {
-  return & access::rw((*m_ptr).mem[  (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1  ]);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const eT*
-subview_cube<eT>::slice_colptr(const uword in_slice, const uword in_col) const
-  {
-  return & m.mem[ (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 ];
-  }
-
-
-
-template<typename eT>
-inline
-bool
-subview_cube<eT>::check_overlap(const subview_cube<eT>& x) const
-  {
-  const subview_cube<eT>& t = *this;
-  
-  if(&t.m != &x.m)
-    {
-    return false;
-    }
-  else
-    {
-    if( (t.n_elem == 0) || (x.n_elem == 0) )
-      {
-      return false;
-      }
-    else
-      {
-      const uword t_row_start  = t.aux_row1;
-      const uword t_row_end_p1 = t_row_start + t.n_rows;
-      
-      const uword t_col_start  = t.aux_col1;
-      const uword t_col_end_p1 = t_col_start + t.n_cols;
-      
-      const uword t_slice_start  = t.aux_slice1;
-      const uword t_slice_end_p1 = t_slice_start + t.n_slices;
-      
-      
-      const uword x_row_start  = x.aux_row1;
-      const uword x_row_end_p1 = x_row_start + x.n_rows;
-      
-      const uword x_col_start  = x.aux_col1;
-      const uword x_col_end_p1 = x_col_start + x.n_cols;
-      
-      const uword x_slice_start  = x.aux_slice1;
-      const uword x_slice_end_p1 = x_slice_start + x.n_slices;
-      
-      
-      const bool outside_rows   = ( (x_row_start   >= t_row_end_p1  ) || (t_row_start   >= x_row_end_p1  ) );
-      const bool outside_cols   = ( (x_col_start   >= t_col_end_p1  ) || (t_col_start   >= x_col_end_p1  ) );
-      const bool outside_slices = ( (x_slice_start >= t_slice_end_p1) || (t_slice_start >= x_slice_end_p1) );
-      
-      return ( (outside_rows == false) && (outside_cols == false) && (outside_slices == false) );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-subview_cube<eT>::check_overlap(const Mat<eT>& x) const
-  {
-  const subview_cube<eT>& t = *this;
-  
-  const uword t_aux_slice1        = t.aux_slice1;
-  const uword t_aux_slice2_plus_1 = t_aux_slice1 + t.n_slices;
-  
-  for(uword slice = t_aux_slice1; slice < t_aux_slice2_plus_1; ++slice)
-    {
-    const Mat<eT>& y = *(t.m.mat_ptrs[slice]);
-  
-    if( x.memptr() == y.memptr() )
-      {
-      return true;
-      }
-    }
-  
-  return false;
-  }
-
-
-
-//! cube X = Y.subcube(...)
-template<typename eT>
-inline
-void
-subview_cube<eT>::extract(Cube<eT>& out, const subview_cube<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-
-  // NOTE: we're assuming that the cube has already been set to the correct size and there is no aliasing;
-  // size setting and alias checking is done by either the Cube contructor or operator=()
-  
-  const uword n_rows   = in.n_rows;
-  const uword n_cols   = in.n_cols;
-  const uword n_slices = in.n_slices;
-  
-  arma_extra_debug_print(arma_boost::format("out.n_rows = %d   out.n_cols = %d    out.n_slices = %d    in.m.n_rows = %d   in.m.n_cols = %d   in.m.n_slices = %d") % out.n_rows % out.n_cols % out.n_slices % in.m.n_rows % in.m.n_cols % in.m.n_slices);
-  
-  
-  for(uword slice = 0; slice < n_slices; ++slice)
-    {
-    for(uword col = 0; col < n_cols; ++col)
-      {
-      arrayops::copy( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
-      }
-    }
-  }
-
-
-
-//! cube X += Y.subcube(...)
-template<typename eT>
-inline
-void
-subview_cube<eT>::plus_inplace(Cube<eT>& out, const subview_cube<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out, in, "addition");
-  
-  const uword n_rows   = out.n_rows;
-  const uword n_cols   = out.n_cols;
-  const uword n_slices = out.n_slices;
-  
-  for(uword slice = 0; slice<n_slices; ++slice)
-    {
-    for(uword col = 0; col<n_cols; ++col)
-      {
-      arrayops::inplace_plus( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
-      }
-    }
-  }
-
-
-
-//! cube X -= Y.subcube(...)
-template<typename eT>
-inline
-void
-subview_cube<eT>::minus_inplace(Cube<eT>& out, const subview_cube<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out, in, "subtraction");
-  
-  const uword n_rows   = out.n_rows;
-  const uword n_cols   = out.n_cols;
-  const uword n_slices = out.n_slices;
-  
-  for(uword slice = 0; slice<n_slices; ++slice)
-    {
-    for(uword col = 0; col<n_cols; ++col)
-      {
-      arrayops::inplace_minus( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
-      }
-    }
-  }
-
-
-
-//! cube X %= Y.subcube(...)
-template<typename eT>
-inline
-void
-subview_cube<eT>::schur_inplace(Cube<eT>& out, const subview_cube<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out, in, "element-wise multiplication");
-  
-  const uword n_rows   = out.n_rows;
-  const uword n_cols   = out.n_cols;
-  const uword n_slices = out.n_slices;
-  
-  for(uword slice = 0; slice<n_slices; ++slice)
-    {
-    for(uword col = 0; col<n_cols; ++col)
-      {
-      arrayops::inplace_mul( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
-      }
-    }
-  }
-
-
-
-//! cube X /= Y.subcube(...)
-template<typename eT>
-inline
-void
-subview_cube<eT>::div_inplace(Cube<eT>& out, const subview_cube<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out, in, "element-wise division");
-  
-  const uword n_rows   = out.n_rows;
-  const uword n_cols   = out.n_cols;
-  const uword n_slices = out.n_slices;
-  
-  for(uword slice = 0; slice<n_slices; ++slice)
-    {
-    for(uword col = 0; col<n_cols; ++col)
-      {
-      arrayops::inplace_div( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
-      }
-    }
-  }
-
-
-
-//! mat X = Y.subcube(...)
-template<typename eT>
-inline
-void
-subview_cube<eT>::extract(Mat<eT>& out, const subview_cube<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_cube_as_mat(out, in, "copy into matrix", false);
-  
-  const uword in_n_rows   = in.n_rows;
-  const uword in_n_cols   = in.n_cols;
-  const uword in_n_slices = in.n_slices;
-  
-  const uword out_vec_state = out.vec_state;
-  
-  if(in_n_slices == 1)
-    {
-    out.set_size(in_n_rows, in_n_cols);
-    
-    for(uword col=0; col < in_n_cols; ++col)
-      {
-      arrayops::copy( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
-      }
-    }
-  else
-    {
-    if(out_vec_state == 0)
-      {
-      if(in_n_cols == 1)
-        {
-        out.set_size(in_n_rows, in_n_slices);
-        
-        for(uword i=0; i < in_n_slices; ++i)
-          {
-          arrayops::copy( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
-          }
-        }
-      else
-      if(in_n_rows == 1)
-        {
-        const Cube<eT>& Q = in.m;
-        
-        const uword in_aux_row1   = in.aux_row1;
-        const uword in_aux_col1   = in.aux_col1;
-        const uword in_aux_slice1 = in.aux_slice1;
-        
-        out.set_size(in_n_cols, in_n_slices);
-        
-        for(uword slice=0; slice < in_n_slices; ++slice)
-          {
-          const uword mod_slice = in_aux_slice1 + slice;
-          
-          eT* out_colptr = out.colptr(slice);
-          
-          uword i,j;
-          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
-            {
-            const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
-            const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
-            
-            out_colptr[i] = tmp_i;
-            out_colptr[j] = tmp_j;
-            }
-          
-          if(i < in_n_cols)
-            {
-            out_colptr[i] = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
-            }
-          }
-        }
-      }
-    else
-      {
-      out.set_size(in_n_slices);
-      
-      eT* out_mem = out.memptr();
-      
-      const Cube<eT>& Q = in.m;
-      
-      const uword in_aux_row1   = in.aux_row1;
-      const uword in_aux_col1   = in.aux_col1;
-      const uword in_aux_slice1 = in.aux_slice1;
-      
-      for(uword i=0; i<in_n_slices; ++i)
-        {
-        out_mem[i] = Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
-        }
-      }
-    }
-  }
-
-
-
-//! mat X += Y.subcube(...)
-template<typename eT>
-inline
-void
-subview_cube<eT>::plus_inplace(Mat<eT>& out, const subview_cube<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_cube_as_mat(out, in, "addition", true);
-  
-  const uword in_n_rows   = in.n_rows;
-  const uword in_n_cols   = in.n_cols;
-  const uword in_n_slices = in.n_slices;
-  
-  const uword out_n_rows    = out.n_rows;
-  const uword out_n_cols    = out.n_cols;
-  const uword out_vec_state = out.vec_state;
-  
-  if(in_n_slices == 1)
-    {
-    for(uword col=0; col < in_n_cols; ++col)
-      {
-      arrayops::inplace_plus( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
-      }
-    }
-  else
-    {
-    if(out_vec_state == 0)
-      {
-      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
-        {
-        for(uword i=0; i < in_n_slices; ++i)
-          {
-          arrayops::inplace_plus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
-          }
-        }
-      else
-      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
-        {
-        const Cube<eT>& Q = in.m;
-        
-        const uword in_aux_row1   = in.aux_row1;
-        const uword in_aux_col1   = in.aux_col1;
-        const uword in_aux_slice1 = in.aux_slice1;
-        
-        for(uword slice=0; slice < in_n_slices; ++slice)
-          {
-          const uword mod_slice = in_aux_slice1 + slice;
-          
-          eT* out_colptr = out.colptr(slice);
-          
-          uword i,j;
-          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
-            {
-            const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
-            const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
-            
-            out_colptr[i] += tmp_i;
-            out_colptr[j] += tmp_j;
-            }
-          
-          if(i < in_n_cols)
-            {
-            out_colptr[i] += Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
-            }
-          }
-        }
-      }
-    else
-      {
-      eT* out_mem = out.memptr();
-      
-      const Cube<eT>& Q = in.m;
-      
-      const uword in_aux_row1   = in.aux_row1;
-      const uword in_aux_col1   = in.aux_col1;
-      const uword in_aux_slice1 = in.aux_slice1;
-      
-      for(uword i=0; i<in_n_slices; ++i)
-        {
-        out_mem[i] += Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
-        }
-      }
-    }
-  }
-
-
-
-//! mat X -= Y.subcube(...)
-template<typename eT>
-inline
-void
-subview_cube<eT>::minus_inplace(Mat<eT>& out, const subview_cube<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_cube_as_mat(out, in, "subtraction", true);
-  
-  const uword in_n_rows   = in.n_rows;
-  const uword in_n_cols   = in.n_cols;
-  const uword in_n_slices = in.n_slices;
-  
-  const uword out_n_rows    = out.n_rows;
-  const uword out_n_cols    = out.n_cols;
-  const uword out_vec_state = out.vec_state;
-  
-  if(in_n_slices == 1)
-    {
-    for(uword col=0; col < in_n_cols; ++col)
-      {
-      arrayops::inplace_minus( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
-      }
-    }
-  else
-    {
-    if(out_vec_state == 0)
-      {
-      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
-        {
-        for(uword i=0; i < in_n_slices; ++i)
-          {
-          arrayops::inplace_minus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
-          }
-        }
-      else
-      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
-        {
-        const Cube<eT>& Q = in.m;
-        
-        const uword in_aux_row1   = in.aux_row1;
-        const uword in_aux_col1   = in.aux_col1;
-        const uword in_aux_slice1 = in.aux_slice1;
-        
-        for(uword slice=0; slice < in_n_slices; ++slice)
-          {
-          const uword mod_slice = in_aux_slice1 + slice;
-          
-          eT* out_colptr = out.colptr(slice);
-          
-          uword i,j;
-          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
-            {
-            const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
-            const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
-            
-            out_colptr[i] -= tmp_i;
-            out_colptr[j] -= tmp_j;
-            }
-          
-          if(i < in_n_cols)
-            {
-            out_colptr[i] -= Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
-            }
-          }
-        }
-      }
-    else
-      {
-      eT* out_mem = out.memptr();
-      
-      const Cube<eT>& Q = in.m;
-      
-      const uword in_aux_row1   = in.aux_row1;
-      const uword in_aux_col1   = in.aux_col1;
-      const uword in_aux_slice1 = in.aux_slice1;
-      
-      for(uword i=0; i<in_n_slices; ++i)
-        {
-        out_mem[i] -= Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
-        }
-      }
-    }
-  }
-
-
-
-//! mat X %= Y.subcube(...)
-template<typename eT>
-inline
-void
-subview_cube<eT>::schur_inplace(Mat<eT>& out, const subview_cube<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_cube_as_mat(out, in, "element-wise multiplication", true);
-  
-  const uword in_n_rows   = in.n_rows;
-  const uword in_n_cols   = in.n_cols;
-  const uword in_n_slices = in.n_slices;
-  
-  const uword out_n_rows    = out.n_rows;
-  const uword out_n_cols    = out.n_cols;
-  const uword out_vec_state = out.vec_state;
-  
-  if(in_n_slices == 1)
-    {
-    for(uword col=0; col < in_n_cols; ++col)
-      {
-      arrayops::inplace_mul( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
-      }
-    }
-  else
-    {
-    if(out_vec_state == 0)
-      {
-      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
-        {
-        for(uword i=0; i < in_n_slices; ++i)
-          {
-          arrayops::inplace_mul( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
-          }
-        }
-      else
-      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
-        {
-        const Cube<eT>& Q = in.m;
-        
-        const uword in_aux_row1   = in.aux_row1;
-        const uword in_aux_col1   = in.aux_col1;
-        const uword in_aux_slice1 = in.aux_slice1;
-        
-        for(uword slice=0; slice < in_n_slices; ++slice)
-          {
-          const uword mod_slice = in_aux_slice1 + slice;
-          
-          eT* out_colptr = out.colptr(slice);
-          
-          uword i,j;
-          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
-            {
-            const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
-            const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
-            
-            out_colptr[i] *= tmp_i;
-            out_colptr[j] *= tmp_j;
-            }
-          
-          if(i < in_n_cols)
-            {
-            out_colptr[i] *= Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
-            }
-          }
-        }
-      }
-    else
-      {
-      eT* out_mem = out.memptr();
-      
-      const Cube<eT>& Q = in.m;
-      
-      const uword in_aux_row1   = in.aux_row1;
-      const uword in_aux_col1   = in.aux_col1;
-      const uword in_aux_slice1 = in.aux_slice1;
-      
-      for(uword i=0; i<in_n_slices; ++i)
-        {
-        out_mem[i] *= Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
-        }
-      }
-    }
-  }
-
-
-
-//! mat X /= Y.subcube(...)
-template<typename eT>
-inline
-void
-subview_cube<eT>::div_inplace(Mat<eT>& out, const subview_cube<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_cube_as_mat(out, in, "element-wise division", true);
-  
-  const uword in_n_rows   = in.n_rows;
-  const uword in_n_cols   = in.n_cols;
-  const uword in_n_slices = in.n_slices;
-  
-  const uword out_n_rows    = out.n_rows;
-  const uword out_n_cols    = out.n_cols;
-  const uword out_vec_state = out.vec_state;
-  
-  if(in_n_slices == 1)
-    {
-    for(uword col=0; col < in_n_cols; ++col)
-      {
-      arrayops::inplace_div( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
-      }
-    }
-  else
-    {
-    if(out_vec_state == 0)
-      {
-      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
-        {
-        for(uword i=0; i < in_n_slices; ++i)
-          {
-          arrayops::inplace_div( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
-          }
-        }
-      else
-      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
-        {
-        const Cube<eT>& Q = in.m;
-        
-        const uword in_aux_row1   = in.aux_row1;
-        const uword in_aux_col1   = in.aux_col1;
-        const uword in_aux_slice1 = in.aux_slice1;
-        
-        for(uword slice=0; slice < in_n_slices; ++slice)
-          {
-          const uword mod_slice = in_aux_slice1 + slice;
-          
-          eT* out_colptr = out.colptr(slice);
-          
-          uword i,j;
-          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
-            {
-            const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
-            const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
-            
-            out_colptr[i] /= tmp_i;
-            out_colptr[j] /= tmp_j;
-            }
-          
-          if(i < in_n_cols)
-            {
-            out_colptr[i] /= Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
-            }
-          }
-        }
-      }
-    else
-      {
-      eT* out_mem = out.memptr();
-      
-      const Cube<eT>& Q = in.m;
-      
-      const uword in_aux_row1   = in.aux_row1;
-      const uword in_aux_col1   = in.aux_col1;
-      const uword in_aux_slice1 = in.aux_slice1;
-      
-      for(uword i=0; i<in_n_slices; ++i)
-        {
-        out_mem[i] /= Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
-        }
-      }
-    }
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/subview_elem1_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup subview_elem1
-//! @{
-
-
-
-template<typename eT, typename T1>
-class subview_elem1 : public Base<eT, subview_elem1<eT,T1> >
-  {
-  public:    arma_aligned const Mat<eT>& m;
-  protected: arma_aligned       Mat<eT>* m_ptr;
-  
-  public:
-  
-  typedef eT                                       elem_type;
-  typedef typename get_pod_type<elem_type>::result pod_type;
-  
-  arma_aligned const Base<uword,T1>& a;
-  
-  
-  protected:
-  
-  arma_inline subview_elem1(const Mat<eT>& in_m, const Base<uword,T1>& in_a);
-  arma_inline subview_elem1(      Mat<eT>& in_m, const Base<uword,T1>& in_a);
-  
-  
-  public:
-  
-  inline ~subview_elem1();
-  
-  template<typename op_type>              inline void inplace_op(const eT                    val);
-  template<typename op_type, typename T2> inline void inplace_op(const subview_elem1<eT,T2>& x  );
-  template<typename op_type, typename T2> inline void inplace_op(const Base<eT,T2>&          x  );
-  
-  inline void fill(const eT val);
-  inline void zeros();
-  inline void ones();
-  
-  inline void operator+= (const eT val);
-  inline void operator-= (const eT val);
-  inline void operator*= (const eT val);
-  inline void operator/= (const eT val);
-  
-  
-  // deliberately returning void
-  template<typename T2> inline void operator_equ(const subview_elem1<eT,T2>& x);
-  template<typename T2> inline void operator=   (const subview_elem1<eT,T2>& x);
-                        inline void operator=   (const subview_elem1<eT,T1>& x);
-  template<typename T2> inline void operator+=  (const subview_elem1<eT,T2>& x);
-  template<typename T2> inline void operator-=  (const subview_elem1<eT,T2>& x);
-  template<typename T2> inline void operator%=  (const subview_elem1<eT,T2>& x);
-  template<typename T2> inline void operator/=  (const subview_elem1<eT,T2>& x);
-  
-  template<typename T2> inline void operator=  (const Base<eT,T2>& x);
-  template<typename T2> inline void operator+= (const Base<eT,T2>& x);
-  template<typename T2> inline void operator-= (const Base<eT,T2>& x);
-  template<typename T2> inline void operator%= (const Base<eT,T2>& x);
-  template<typename T2> inline void operator/= (const Base<eT,T2>& x);
-  
-  inline static void extract(Mat<eT>& out, const subview_elem1& in);
-  
-  template<typename op_type> inline static void mat_inplace_op(Mat<eT>& out, const subview_elem1& in);
-  
-  inline static void  plus_inplace(Mat<eT>& out, const subview_elem1& in);
-  inline static void minus_inplace(Mat<eT>& out, const subview_elem1& in);
-  inline static void schur_inplace(Mat<eT>& out, const subview_elem1& in);
-  inline static void   div_inplace(Mat<eT>& out, const subview_elem1& in);
-  
-  
-  
-  private:
-  
-  friend class Mat<eT>;
-  subview_elem1();
-  };
-
-
-
-class op_subview_elem_equ;
-class op_subview_elem_inplace_plus;
-class op_subview_elem_inplace_minus;
-class op_subview_elem_inplace_schur;
-class op_subview_elem_inplace_div;
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/subview_elem1_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,729 +0,0 @@
-// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2010-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup subview_elem1
-//! @{
-
-
-template<typename eT, typename T1>
-inline
-subview_elem1<eT,T1>::~subview_elem1()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-template<typename eT, typename T1>
-arma_inline
-subview_elem1<eT,T1>::subview_elem1(const Mat<eT>& in_m, const Base<uword,T1>& in_a)
-  : m(in_m)
-  , m_ptr(0)
-  , a(in_a)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT, typename T1>
-arma_inline
-subview_elem1<eT,T1>::subview_elem1(Mat<eT>& in_m, const Base<uword,T1>& in_a)
-  : m(in_m)
-  , m_ptr(&in_m)
-  , a(in_a)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT, typename T1>
-template<typename op_type>
-inline
-void
-subview_elem1<eT,T1>::inplace_op(const eT val)
-  {
-  Mat<eT>& m_local = *m_ptr;
-  
-        eT*   m_mem    = m_local.memptr();
-  const uword m_n_elem = m_local.n_elem;
-  
-  const unwrap_check_mixed<T1> tmp(a.get_ref(), m_local);
-  const umat& aa = tmp.M;
-  
-  arma_debug_check
-    (
-    ( aa.is_vec() == false ),
-    "Mat::elem(): given object is not a vector"
-    );
-  
-  const uword* aa_mem    = aa.memptr();
-  const uword  aa_n_elem = aa.n_elem;
-  
-  uword i,j;
-  for(i=0, j=1; j<aa_n_elem; i+=2, j+=2)
-    {
-    const uword ii = aa_mem[i];
-    const uword jj = aa_mem[j];
-    
-    arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
-    
-         if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  val; m_mem[jj] =  val; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += val; m_mem[jj] += val; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= val; m_mem[jj] -= val; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= val; m_mem[jj] *= val; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= val; m_mem[jj] /= val; }
-    }
-  
-  if(i < aa_n_elem)
-    {
-    const uword ii = aa_mem[i];
-    
-    arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); 
-    
-         if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  val; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += val; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= val; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= val; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= val; }
-    }
-  }
-
-
-
-template<typename eT, typename T1>
-template<typename op_type, typename T2>
-inline
-void
-subview_elem1<eT,T1>::inplace_op(const subview_elem1<eT,T2>& x)
-  {
-  subview_elem1<eT,T1>& t = *this;
-  
-  if(&(t.m) == &(x.m))
-    {
-    arma_extra_debug_print("subview_elem1::inplace_op(): aliasing detected");
-    
-    const Mat<eT> tmp(x);
-    
-         if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { t.operator= (tmp); }
-    else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { t.operator+=(tmp); }
-    else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { t.operator-=(tmp); }
-    else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { t.operator%=(tmp); }
-    else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { t.operator/=(tmp); }
-    }
-  else
-    {
-          Mat<eT>& t_m_local = *(t.m_ptr);
-    const Mat<eT>& x_m_local = x.m;
-    
-    const unwrap_check_mixed<T1> t_tmp(t.a.get_ref(), t_m_local);
-    const unwrap_check_mixed<T2> x_tmp(x.a.get_ref(), t_m_local);
-    
-    const umat& t_aa = t_tmp.M;
-    const umat& x_aa = x_tmp.M;
-    
-    arma_debug_check
-      (
-      ( (t_aa.is_vec() == false) || (x_aa.is_vec() == false) ),
-      "Mat::elem(): given object is not a vector"
-      );
-    
-    const uword* t_aa_mem = t_aa.memptr();
-    const uword* x_aa_mem = x_aa.memptr();
-    
-    const uword t_aa_n_elem = t_aa.n_elem;
-    
-    arma_debug_check( (t_aa_n_elem != x_aa.n_elem), "Mat::elem(): size mismatch" );
-    
-    
-          eT*   t_m_mem    = t_m_local.memptr();
-    const uword t_m_n_elem = t_m_local.n_elem;
-    
-    const eT*   x_m_mem    = x_m_local.memptr();
-    const uword x_m_n_elem = x_m_local.n_elem;
-    
-    uword i,j;
-    for(i=0, j=1; j<t_aa_n_elem; i+=2, j+=2)
-      {
-      const uword t_ii = t_aa_mem[i];
-      const uword t_jj = t_aa_mem[j];
-      
-      const uword x_ii = x_aa_mem[i];
-      const uword x_jj = x_aa_mem[j];
-      
-      arma_debug_check
-        (
-        (t_ii >= t_m_n_elem) || (t_jj >= t_m_n_elem) || (x_ii >= x_m_n_elem) || (x_jj >= x_m_n_elem),
-        "Mat::elem(): index out of bounds"
-        );
-      
-           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { t_m_mem[t_ii]  = x_m_mem[x_ii]; t_m_mem[t_jj]  = x_m_mem[x_jj]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { t_m_mem[t_ii] += x_m_mem[x_ii]; t_m_mem[t_jj] += x_m_mem[x_jj]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { t_m_mem[t_ii] -= x_m_mem[x_ii]; t_m_mem[t_jj] -= x_m_mem[x_jj]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { t_m_mem[t_ii] *= x_m_mem[x_ii]; t_m_mem[t_jj] *= x_m_mem[x_jj]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { t_m_mem[t_ii] /= x_m_mem[x_ii]; t_m_mem[t_jj] /= x_m_mem[x_jj]; }
-      }
-    
-    if(i < t_aa_n_elem)
-      {
-      const uword t_ii = t_aa_mem[i];
-      const uword x_ii = x_aa_mem[i];
-      
-      arma_debug_check
-        (
-        ( (t_ii >= t_m_n_elem) || (x_ii >= x_m_n_elem) ),
-        "Mat::elem(): index out of bounds"
-        );
-      
-           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { t_m_mem[t_ii]  = x_m_mem[x_ii]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { t_m_mem[t_ii] += x_m_mem[x_ii]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { t_m_mem[t_ii] -= x_m_mem[x_ii]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { t_m_mem[t_ii] *= x_m_mem[x_ii]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { t_m_mem[t_ii] /= x_m_mem[x_ii]; }
-      }
-    }
-  }
-
-
-
-template<typename eT, typename T1>
-template<typename op_type, typename T2>
-inline
-void
-subview_elem1<eT,T1>::inplace_op(const Base<eT,T2>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  Mat<eT>& m_local = *m_ptr;
-  
-        eT*   m_mem    = m_local.memptr();
-  const uword m_n_elem = m_local.n_elem;
-  
-  const unwrap_check_mixed<T1> tmp(a.get_ref(), m_local);
-  const umat& aa = tmp.M;
-  
-  arma_debug_check
-    (
-    ( aa.is_vec() == false ),
-    "Mat::elem(): given object is not a vector"
-    );
-  
-  const uword* aa_mem    = aa.memptr();
-  const uword  aa_n_elem = aa.n_elem;
-  
-  const Proxy<T2> P(x.get_ref());
-  
-  arma_debug_check( (aa_n_elem != P.get_n_elem()), "Mat::elem(): size mismatch" );
-  
-  if( (P.is_alias(m) == false) && (Proxy<T2>::prefer_at_accessor == false) )
-    {
-    typename Proxy<T2>::ea_type X = P.get_ea();
-    
-    uword i,j;
-    for(i=0, j=1; j<aa_n_elem; i+=2, j+=2)
-      {
-      const uword ii = aa_mem[i];
-      const uword jj = aa_mem[j];
-      
-      arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
-      
-           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  X[i]; m_mem[jj]  = X[j]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[i]; m_mem[jj] += X[j]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[i]; m_mem[jj] -= X[j]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[i]; m_mem[jj] *= X[j]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= X[i]; m_mem[jj] /= X[j]; }
-      }
-    
-    if(i < aa_n_elem)
-      {
-      const uword ii = aa_mem[i];
-      
-      arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
-      
-           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  X[i]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[i]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[i]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[i]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= X[i]; }
-      }
-    }
-  else
-    {
-    arma_extra_debug_print("subview_elem1::inplace_op(): aliasing or prefer_at_accessor detected");
-    
-    const unwrap_check<typename Proxy<T2>::stored_type> tmp(P.Q, m_local);
-    const Mat<eT>& M = tmp.M;
-    
-    const eT* X = M.memptr();
-    
-    uword i,j;
-    for(i=0, j=1; j<aa_n_elem; i+=2, j+=2)
-      {
-      const uword ii = aa_mem[i];
-      const uword jj = aa_mem[j];
-      
-      arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
-      
-           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  X[i]; m_mem[jj]  = X[j]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[i]; m_mem[jj] += X[j]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[i]; m_mem[jj] -= X[j]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[i]; m_mem[jj] *= X[j]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= X[i]; m_mem[jj] /= X[j]; }
-      }
-    
-    if(i < aa_n_elem)
-      {
-      const uword ii = aa_mem[i];
-      
-      arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
-      
-           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  X[i]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[i]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[i]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[i]; }
-      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= X[i]; }
-      }
-    }
-  }
-
-
-
-//
-//
-
-
-
-template<typename eT, typename T1>
-inline
-void
-subview_elem1<eT,T1>::fill(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_equ>(val);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-subview_elem1<eT,T1>::zeros()
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_equ>(eT(0));
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-subview_elem1<eT,T1>::ones()
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_equ>(eT(1));
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-subview_elem1<eT,T1>::operator+= (const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_inplace_plus>(val);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-subview_elem1<eT,T1>::operator-= (const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_inplace_minus>(val);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-subview_elem1<eT,T1>::operator*= (const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_inplace_schur>(val);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-subview_elem1<eT,T1>::operator/= (const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_inplace_div>(val);
-  }
-
-
-
-//
-//
-
-
-
-template<typename eT, typename T1>
-template<typename T2>
-inline
-void
-subview_elem1<eT,T1>::operator_equ(const subview_elem1<eT,T2>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_equ>(x);
-  }
-
-
-
-
-template<typename eT, typename T1>
-template<typename T2>
-inline
-void
-subview_elem1<eT,T1>::operator= (const subview_elem1<eT,T2>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  (*this).operator_equ(x);
-  }
-
-
-
-//! work around compiler bugs
-template<typename eT, typename T1>
-inline
-void
-subview_elem1<eT,T1>::operator= (const subview_elem1<eT,T1>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  (*this).operator_equ(x);
-  }
-
-
-
-template<typename eT, typename T1>
-template<typename T2>
-inline
-void
-subview_elem1<eT,T1>::operator+= (const subview_elem1<eT,T2>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_inplace_plus>(x);
-  }
-
-
-
-template<typename eT, typename T1>
-template<typename T2>
-inline
-void
-subview_elem1<eT,T1>::operator-= (const subview_elem1<eT,T2>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_inplace_minus>(x);
-  }
-
-
-
-template<typename eT, typename T1>
-template<typename T2>
-inline
-void
-subview_elem1<eT,T1>::operator%= (const subview_elem1<eT,T2>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_inplace_schur>(x);
-  }
-
-
-
-template<typename eT, typename T1>
-template<typename T2>
-inline
-void
-subview_elem1<eT,T1>::operator/= (const subview_elem1<eT,T2>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_inplace_div>(x);
-  }
-
-
-
-template<typename eT, typename T1>
-template<typename T2>
-inline
-void
-subview_elem1<eT,T1>::operator= (const Base<eT,T2>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_equ>(x);
-  }
-
-
-
-template<typename eT, typename T1>
-template<typename T2>
-inline
-void
-subview_elem1<eT,T1>::operator+= (const Base<eT,T2>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_inplace_plus>(x);
-  }
-
-
-
-template<typename eT, typename T1>
-template<typename T2>
-inline
-void
-subview_elem1<eT,T1>::operator-= (const Base<eT,T2>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_inplace_minus>(x);
-  }
-
-
-
-template<typename eT, typename T1>
-template<typename T2>
-inline
-void
-subview_elem1<eT,T1>::operator%= (const Base<eT,T2>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_inplace_schur>(x);
-  }
-
-
-
-template<typename eT, typename T1>
-template<typename T2>
-inline
-void
-subview_elem1<eT,T1>::operator/= (const Base<eT,T2>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  inplace_op<op_subview_elem_inplace_div>(x);
-  }
-
-
-
-//
-//
-
-
-
-template<typename eT, typename T1>
-inline
-void
-subview_elem1<eT,T1>::extract(Mat<eT>& actual_out, const subview_elem1<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap_check_mixed<T1> tmp1(in.a.get_ref(), actual_out);
-  const umat& aa = tmp1.M;
-  
-  arma_debug_check
-    (
-    ( aa.is_vec() == false ),
-    "Mat::elem(): given object is not a vector"
-    );
-  
-  const uword* aa_mem    = aa.memptr();
-  const uword  aa_n_elem = aa.n_elem;
-  
-  const Mat<eT>& m_local = in.m;
-  
-  const eT*   m_mem    = m_local.memptr();
-  const uword m_n_elem = m_local.n_elem;
-  
-  const bool alias = (&actual_out == &m_local);
-  
-  arma_extra_debug_warn(alias, "subview_elem1::extract(): aliasing detected");
-  
-  Mat<eT>* tmp_out = alias ? new Mat<eT>() : 0;
-  Mat<eT>& out     = alias ? *tmp_out      : actual_out;
-  
-  out.set_size(aa_n_elem, 1);
-  
-  eT* out_mem = out.memptr();
-  
-  uword i,j;
-  for(i=0, j=1; j<aa_n_elem; i+=2, j+=2)
-    {
-    const uword ii = aa_mem[i];
-    const uword jj = aa_mem[j];
-    
-    arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
-    
-    out_mem[i] = m_mem[ii];
-    out_mem[j] = m_mem[jj];
-    }
-  
-  if(i < aa_n_elem)
-    {
-    const uword ii = aa_mem[i];
-    
-    arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
-    
-    out_mem[i] = m_mem[ii];
-    }
-  
-  if(alias == true)
-    {
-    actual_out = out;
-    delete tmp_out;
-    }
-  }
-
-
-
-template<typename eT, typename T1>
-template<typename op_type>
-inline
-void
-subview_elem1<eT,T1>::mat_inplace_op(Mat<eT>& out, const subview_elem1& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const unwrap<T1> tmp1(in.a.get_ref());
-  const umat& aa = tmp1.M;
-  
-  arma_debug_check
-    (
-    ( aa.is_vec() == false ),
-    "Mat::elem(): given object is not a vector"
-    );
-  
-  const uword* aa_mem    = aa.memptr();
-  const uword  aa_n_elem = aa.n_elem;
-  
-  const unwrap_check< Mat<eT> > tmp2(in.m, out);
-  const Mat<eT>& m_local      = tmp2.M;
-  
-  const eT*   m_mem    = m_local.memptr();
-  const uword m_n_elem = m_local.n_elem;
-  
-  arma_debug_check( (out.n_elem != aa_n_elem), "Mat::elem(): size mismatch" );
-  
-  eT* out_mem = out.memptr();
-  
-  uword i,j;
-  for(i=0, j=1; j<aa_n_elem; i+=2, j+=2)
-    {
-    const uword ii = aa_mem[i];
-    const uword jj = aa_mem[j];
-    
-    arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
-    
-         if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { out_mem[i] += m_mem[ii]; out_mem[j] += m_mem[jj]; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { out_mem[i] -= m_mem[ii]; out_mem[j] -= m_mem[jj]; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { out_mem[i] *= m_mem[ii]; out_mem[j] *= m_mem[jj]; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { out_mem[i] /= m_mem[ii]; out_mem[j] /= m_mem[jj]; }
-    }
-  
-  if(i < aa_n_elem)
-    {
-    const uword ii = aa_mem[i];
-    
-    arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
-    
-         if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { out_mem[i] += m_mem[ii]; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { out_mem[i] -= m_mem[ii]; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { out_mem[i] *= m_mem[ii]; }
-    else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { out_mem[i] /= m_mem[ii]; }
-    }
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-subview_elem1<eT,T1>::plus_inplace(Mat<eT>& out, const subview_elem1& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  mat_inplace_op<op_subview_elem_inplace_plus>(out, in);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-subview_elem1<eT,T1>::minus_inplace(Mat<eT>& out, const subview_elem1& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  mat_inplace_op<op_subview_elem_inplace_minus>(out, in);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-subview_elem1<eT,T1>::schur_inplace(Mat<eT>& out, const subview_elem1& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  mat_inplace_op<op_subview_elem_inplace_schur>(out, in);
-  }
-
-
-
-template<typename eT, typename T1>
-inline
-void
-subview_elem1<eT,T1>::div_inplace(Mat<eT>& out, const subview_elem1& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  mat_inplace_op<op_subview_elem_inplace_div>(out, in);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/subview_field_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup subview_field
-//! @{
-
-
-//! Class for storing data required to construct or apply operations to a subfield
-//! (i.e. where the subfield starts and ends as well as a reference/pointer to the original field),
-template<typename oT>
-class subview_field
-  {
-  public:  const field<oT>& f;
-  protected:     field<oT>* f_ptr;
-  
-  public:
-  
-  typedef oT object_type;
-  
-  const uword aux_row1;
-  const uword aux_col1;
-  
-  const uword n_rows;
-  const uword n_cols;
-  const uword n_elem;
-  
-  
-  protected:
-  
-  arma_inline subview_field(const field<oT>& in_f, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols);
-  arma_inline subview_field(      field<oT>& in_f, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols);
-  
-  
-  public:
-  
-  inline ~subview_field();
-  
-  inline void operator= (const field<oT>& x);
-  inline void operator= (const subview_field& x);
-  
-  arma_inline       oT& operator[](const uword i);
-  arma_inline const oT& operator[](const uword i) const;
-  
-  arma_inline       oT& operator()(const uword i);
-  arma_inline const oT& operator()(const uword i) const;
-  
-  arma_inline       oT&         at(const uword row, const uword col);
-  arma_inline const oT&         at(const uword row, const uword col) const;
-  
-  arma_inline       oT& operator()(const uword row, const uword col);
-  arma_inline const oT& operator()(const uword row, const uword col) const;
-  
-  inline bool check_overlap(const subview_field& x) const;
-  
-  inline static void extract(field<oT>& out, const subview_field& in);
-  
-  
-  private:
-  
-  friend class field<oT>;
-  
-  
-  subview_field();
-  //subview_field(const subview_field&);
-  };
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/subview_field_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,341 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup subview_field
-//! @{
-
-
-template<typename oT>
-inline
-subview_field<oT>::~subview_field()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename oT>
-arma_inline
-subview_field<oT>::subview_field
-  (
-  const field<oT>& in_f,
-  const uword        in_row1,
-  const uword        in_col1,
-  const uword        in_n_rows,
-  const uword        in_n_cols
-  )
-  : f(in_f)
-  , f_ptr(0)
-  , aux_row1(in_row1)
-  , aux_col1(in_col1)
-  , n_rows(in_n_rows)
-  , n_cols(in_n_cols)
-  , n_elem(in_n_rows*in_n_cols)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename oT>
-arma_inline
-subview_field<oT>::subview_field
-  (
-        field<oT>& in_f,
-  const uword        in_row1,
-  const uword        in_col1,
-  const uword        in_n_rows,
-  const uword        in_n_cols
-  )
-  : f(in_f)
-  , f_ptr(&in_f)
-  , aux_row1(in_row1)
-  , aux_col1(in_col1)
-  , n_rows(in_n_rows)
-  , n_cols(in_n_cols)
-  , n_elem(in_n_rows*in_n_cols)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename oT>
-inline
-void
-subview_field<oT>::operator= (const field<oT>& x)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview_field<oT>& t = *this;
-  
-  arma_debug_check( (t.n_rows != x.n_rows) || (t.n_cols != x.n_cols), "incompatible field dimensions");
-  
-  for(uword col=0; col<t.n_cols; ++col)
-    {
-    for(uword row=0; row<t.n_rows; ++row)
-      {
-      t.at(row,col) = x.at(row,col);
-      }
-    }
-  }
-
-
-
-//! x.subfield(...) = y.subfield(...)
-template<typename oT>
-inline
-void
-subview_field<oT>::operator= (const subview_field<oT>& x_in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool overlap = check_overlap(x_in);
-        
-        field<oT>*         tmp_field   = overlap ? new field<oT>(x_in.f) : 0;
-  const subview_field<oT>* tmp_subview = overlap ? new subview_field<oT>(*tmp_field, x_in.aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
-  const subview_field<oT>& x           = overlap ? (*tmp_subview) : x_in;
-  
-  subview_field<oT>& t = *this;
-  
-  arma_debug_check( (t.n_rows != x.n_rows) || (t.n_cols != x.n_cols), "incompatible field dimensions");
-  
-  for(uword col=0; col<t.n_cols; ++col)
-    {
-    for(uword row=0; row<t.n_rows; ++row)
-      {
-      t.at(row,col) = x.at(row,col);
-      }
-    }
-    
-  if(overlap)
-    {
-    delete tmp_subview;
-    delete tmp_field;
-    }
-  }
-
-
-
-template<typename oT>
-arma_inline
-oT&
-subview_field<oT>::operator[](const uword i)
-  {
-  arma_check( (f_ptr == 0), "subview_field::operator[]: field is read-only");
-  
-  const uword in_col = i / n_rows;
-  const uword in_row = i % n_rows;
-    
-  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-  
-  return *((*f_ptr).mem[index]);
-  }
-
-
-
-template<typename oT>
-arma_inline
-const oT&
-subview_field<oT>::operator[](const uword i) const
-  {
-  const uword in_col = i / n_rows;
-  const uword in_row = i % n_rows;
-  
-  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-  
-  return *(f.mem[index]);
-  }
-
-
-
-template<typename oT>
-arma_inline
-oT&
-subview_field<oT>::operator()(const uword i)
-  {
-  arma_check( (f_ptr == 0), "subview_field::operator(): field is read-only");
-  arma_debug_check( (i >= n_elem), "subview_field::operator(): index out of bounds");
-    
-  const uword in_col = i / n_rows;
-  const uword in_row = i % n_rows;
-  
-  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-  
-  return *((*f_ptr).mem[index]);
-  }
-
-
-
-template<typename oT>
-arma_inline
-const oT&
-subview_field<oT>::operator()(const uword i) const
-  {
-  arma_debug_check( (i >= n_elem), "subview_field::operator(): index out of bounds");
-  
-  const uword in_col = i / n_rows;
-  const uword in_row = i % n_rows;
-  
-  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-  
-  return *(f.mem[index]);
-  }
-
-
-
-template<typename oT>
-arma_inline
-oT&
-subview_field<oT>::operator()(const uword in_row, const uword in_col)
-  {
-  arma_check( (f_ptr == 0), "subview_field::operator(): field is read-only");
-  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "subview_field::operator(): index out of bounds");
-  
-  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-  
-  return *((*f_ptr).mem[index]);
-  }
-
-
-
-template<typename oT>
-arma_inline
-const oT&
-subview_field<oT>::operator()(const uword in_row, const uword in_col) const
-  {
-  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "subview_field::operator(): index out of bounds");
-  
-  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-  
-  return *(f.mem[index]);
-  }
-
-
-
-template<typename oT>
-arma_inline
-oT&
-subview_field<oT>::at(const uword in_row, const uword in_col)
-  {
-  //arma_extra_debug_sigprint();
-  
-  arma_check( (f_ptr == 0), "subview_field::at(): field is read-only");
-  
-  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-  
-  return *((*f_ptr).mem[index]);
-  }
-
-
-
-template<typename oT>
-arma_inline
-const oT&
-subview_field<oT>::at(const uword in_row, const uword in_col) const
-  {
-  //arma_extra_debug_sigprint();
-  
-  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
-  
-  return *(f.mem[index]);
-  }
-
-
-
-template<typename oT>
-inline
-bool
-subview_field<oT>::check_overlap(const subview_field<oT>& x) const
-  {
-  const subview_field<oT>& t = *this;
-  
-  if(&t.f != &x.f)
-    {
-    return false;
-    }
-  else
-    {
-    if( (t.n_elem == 0) || (x.n_elem == 0) )
-      {
-      return false;
-      }
-    else
-      {
-      const uword t_row_start  = t.aux_row1;
-      const uword t_row_end_p1 = t_row_start + t.n_rows;
-      
-      const uword t_col_start  = t.aux_col1;
-      const uword t_col_end_p1 = t_col_start + t.n_cols;
-      
-      
-      const uword x_row_start  = x.aux_row1;
-      const uword x_row_end_p1 = x_row_start + x.n_rows;
-      
-      const uword x_col_start  = x.aux_col1;
-      const uword x_col_end_p1 = x_col_start + x.n_cols;
-      
-      
-      const bool outside_rows = ( (x_row_start >= t_row_end_p1) || (t_row_start >= x_row_end_p1) );
-      const bool outside_cols = ( (x_col_start >= t_col_end_p1) || (t_col_start >= x_col_end_p1) );
-      
-      return ( (outside_rows == false) && (outside_cols == false) );
-      }
-    }
-  }
-
-
-
-//! X = Y.subfield(...)
-template<typename oT>
-inline
-void
-subview_field<oT>::extract(field<oT>& actual_out, const subview_field<oT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  //
-  const bool alias = (&actual_out == &in.f);
-  
-  field<oT>* tmp = (alias) ? new field<oT> : 0;
-  field<oT>& out = (alias) ? (*tmp)        : actual_out;
-  
-  //
-  
-  const uword n_rows = in.n_rows;
-  const uword n_cols = in.n_cols;
-  
-  out.set_size(n_rows, n_cols);
-  
-  arma_extra_debug_print(arma_boost::format("out.n_rows = %d   out.n_cols = %d    in.m.n_rows = %d  in.m.n_cols = %d") % out.n_rows % out.n_cols % in.f.n_rows % in.f.n_cols );
-  
-  for(uword col = 0; col<n_cols; ++col)
-    {
-    for(uword row = 0; row<n_rows; ++row)
-      {
-      out.at(row,col) = in.at(row,col);
-      }
-    }
-  
-  
-  if(alias)
-    {
-    actual_out = out;
-    delete tmp;
-    }
-  
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/subview_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2574 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// Copyright (C)      2011 James Sanders
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup subview
-//! @{
-
-
-template<typename eT>
-inline
-subview<eT>::~subview()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-template<typename eT>
-inline
-subview<eT>::subview(const Mat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols)
-  : m(in_m)
-  , m_ptr(0)
-  , aux_row1(in_row1)
-  , aux_col1(in_col1)
-  , n_rows(in_n_rows)
-  , n_cols(in_n_cols)
-  , n_elem(in_n_rows*in_n_cols)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-subview<eT>::subview(Mat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols)
-  : m(in_m)
-  , m_ptr(&in_m)
-  , aux_row1(in_row1)
-  , aux_col1(in_col1)
-  , n_rows(in_n_rows)
-  , n_cols(in_n_cols)
-  , n_elem(in_n_rows*in_n_cols)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::operator+= (const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword local_n_cols = n_cols;
-  const uword local_n_rows = n_rows;
-  
-  if(local_n_rows == 1)
-    {
-    Mat<eT>& X = (*m_ptr);
-    
-    const uword row           = aux_row1;
-    const uword start_col     = aux_col1;
-    const uword end_col_plus1 = start_col + local_n_cols;
-    
-    uword i,j;
-    
-    for(i=start_col, j=start_col+1; j < end_col_plus1; i+=2, j+=2)
-      {
-      X.at(row, i) += val;
-      X.at(row, j) += val;
-      }
-    
-    if(i < end_col_plus1)
-      {
-      X.at(row, i) += val;
-      }
-    }
-  else
-    {
-    for(uword col=0; col<local_n_cols; ++col)
-      {
-      arrayops::inplace_plus( colptr(col), val, local_n_rows );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::operator-= (const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword local_n_cols = n_cols;
-  const uword local_n_rows = n_rows;
-  
-  if(local_n_rows == 1)
-    {
-    Mat<eT>& X = (*m_ptr);
-    
-    const uword row           = aux_row1;
-    const uword start_col     = aux_col1;
-    const uword end_col_plus1 = start_col + local_n_cols;
-    
-    uword i,j;
-    
-    for(i=start_col, j=start_col+1; j < end_col_plus1; i+=2, j+=2)
-      {
-      X.at(row, i) -= val;
-      X.at(row, j) -= val;
-      }
-    
-    if(i < end_col_plus1)
-      {
-      X.at(row, i) -= val;
-      }
-    }
-  else
-    {
-    for(uword col=0; col<local_n_cols; ++col)
-      {
-      arrayops::inplace_minus( colptr(col), val, local_n_rows );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::operator*= (const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword local_n_cols = n_cols;
-  const uword local_n_rows = n_rows;
-  
-  if(local_n_rows == 1)
-    {
-    Mat<eT>& X = (*m_ptr);
-    
-    const uword row           = aux_row1;
-    const uword start_col     = aux_col1;
-    const uword end_col_plus1 = start_col + local_n_cols;
-    
-    uword i,j;
-    
-    for(i=start_col, j=start_col+1; j < end_col_plus1; i+=2, j+=2)
-      {
-      X.at(row, i) *= val;
-      X.at(row, j) *= val;
-      }
-    
-    if(i < end_col_plus1)
-      {
-      X.at(row, i) *= val;
-      }
-    }
-  else
-    {
-    for(uword col=0; col<local_n_cols; ++col)
-      {
-      arrayops::inplace_mul( colptr(col), val, local_n_rows );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::operator/= (const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword local_n_cols = n_cols;
-  const uword local_n_rows = n_rows;
-  
-  if(local_n_rows == 1)
-    {
-    Mat<eT>& X = (*m_ptr);
-    
-    const uword row           = aux_row1;
-    const uword start_col     = aux_col1;
-    const uword end_col_plus1 = start_col + local_n_cols;
-    
-    uword i,j;
-    
-    for(i=start_col, j=start_col+1; j < end_col_plus1; i+=2, j+=2)
-      {
-      X.at(row, i) /= val;
-      X.at(row, j) /= val;
-      }
-    
-    if(i < end_col_plus1)
-      {
-      X.at(row, i) /= val;
-      }
-    }
-  else
-    {
-    for(uword col=0; col<local_n_cols; ++col)
-      {
-      arrayops::inplace_div( colptr(col), val, local_n_rows );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview<eT>::operator= (const Base<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Proxy<T1> P(in.get_ref());
-  
-  subview<eT>& t = *this;
-  
-  const uword t_n_rows = t.n_rows;
-  const uword t_n_cols = t.n_cols;
-    
-  arma_debug_assert_same_size(t, P, "insert into submatrix");
-  
-  const bool alias = P.is_alias(t.m);
-  
-  arma_extra_debug_warn(alias, "aliasing detected");
-  
-  if( (alias == true) || (is_Mat<typename Proxy<T1>::stored_type>::value == true) )
-    {
-    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, t.m);
-    const Mat<eT>& x = tmp.M;
-    
-    if(t_n_rows == 1)
-      {
-      const eT* x_mem = x.memptr();
-      
-      Mat<eT>& A = (*m_ptr);
-      
-      const uword row       = aux_row1;
-      const uword start_col = aux_col1;
-      
-      uword i,j;
-      
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        A.at(row, start_col+i) = x_mem[i];
-        A.at(row, start_col+j) = x_mem[j];
-        }
-      
-      if(i < t_n_cols)
-        {
-        A.at(row, start_col+i) = x_mem[i];
-        }
-      }
-    else
-      {
-      for(uword col=0; col<t_n_cols; ++col)
-        {
-        arrayops::copy( t.colptr(col), x.colptr(col), t_n_rows );
-        }
-      }
-    }
-  else
-    {
-    if(t_n_rows == 1)
-      {
-      Mat<eT>& A = (*m_ptr);
-      
-      const uword row       = aux_row1;
-      const uword start_col = aux_col1;
-      
-      uword i,j;
-      
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        const eT tmp1 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,i) : P[i];
-        const eT tmp2 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,j) : P[j];
-        
-        A.at(row, start_col+i) = tmp1;
-        A.at(row, start_col+j) = tmp2;
-        }
-      
-      if(i < t_n_cols)
-        {
-        A.at(row, start_col+i) = (Proxy<T1>::prefer_at_accessor) ? P.at(0,i) : P[i];
-        }
-      }
-    else
-      {
-      for(uword col=0; col<t_n_cols; ++col)
-        {
-        eT* t_col_data = t.colptr(col);
-        
-        uword i,j;
-        for(i=0, j=1; j<t_n_rows; i+=2, j+=2)
-          {
-          const eT tmp1 = P.at(i,col);
-          const eT tmp2 = P.at(j,col);
-          
-          t_col_data[i] = tmp1;
-          t_col_data[j] = tmp2;
-          }
-        
-        if(i < t_n_rows)
-          {
-          t_col_data[i] = P.at(i,col);
-          }
-        }
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview<eT>::operator+= (const Base<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Proxy<T1> P(in.get_ref());
-  
-  subview<eT>& t = *this;
-  
-  const uword t_n_rows = t.n_rows;
-  const uword t_n_cols = t.n_cols;
-  
-  arma_debug_assert_same_size(t, P, "addition");
-  
-  const bool alias = P.is_alias(t.m);
-  
-  arma_extra_debug_warn(alias, "aliasing detected");
-  
-  if( (alias == true) || (is_Mat<typename Proxy<T1>::stored_type>::value == true) )
-    {
-    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, t.m);
-    const Mat<eT>& x = tmp.M;
-    
-    if(t_n_rows == 1)
-      {
-      const eT* x_mem = x.memptr();
-      
-      Mat<eT>& A = (*m_ptr);
-      
-      const uword row       = aux_row1;
-      const uword start_col = aux_col1;
-      
-      uword i,j;
-      
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        A.at(row, start_col+i) += x_mem[i];
-        A.at(row, start_col+j) += x_mem[j];
-        }
-      
-      if(i < t_n_cols)
-        {
-        A.at(row, start_col+i) += x_mem[i];
-        }
-      }
-    else
-      {
-      for(uword col=0; col<t_n_cols; ++col)
-        {
-        arrayops::inplace_plus( t.colptr(col), x.colptr(col), t_n_rows );
-        }
-      }
-    }
-  else
-    {
-    if(t_n_rows == 1)
-      {
-      Mat<eT>& A = (*m_ptr);
-      
-      const uword row       = aux_row1;
-      const uword start_col = aux_col1;
-      
-      uword i,j;
-      
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        const eT tmp1 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,i) : P[i];
-        const eT tmp2 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,j) : P[j];
-        
-        A.at(row, start_col+i) += tmp1;
-        A.at(row, start_col+j) += tmp2;
-        }
-      
-      if(i < t_n_cols)
-        {
-        A.at(row, start_col+i) += (Proxy<T1>::prefer_at_accessor) ? P.at(0,i) : P[i];
-        }
-      }
-    else
-      {
-      for(uword col=0; col<t_n_cols; ++col)
-        {
-        eT* t_col_data = t.colptr(col);
-        
-        uword i,j;
-        for(i=0, j=1; j<t_n_rows; i+=2, j+=2)
-          {
-          const eT val1 = P.at(i,col);
-          const eT val2 = P.at(j,col);
-          
-          t_col_data[i] += val1;
-          t_col_data[j] += val2;
-          }
-        
-        if(i < t_n_rows)
-          {
-          t_col_data[i] += P.at(i,col);
-          }
-        }
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview<eT>::operator-= (const Base<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Proxy<T1> P(in.get_ref());
-  
-  subview<eT>& t = *this;
-  
-  const uword t_n_rows = t.n_rows;
-  const uword t_n_cols = t.n_cols;
-  
-  arma_debug_assert_same_size(t, P, "subtraction");
-  
-  const bool alias = P.is_alias(t.m);
-  
-  if( (alias == true) || (is_Mat<typename Proxy<T1>::stored_type>::value == true) )
-    {
-    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, t.m);
-    const Mat<eT>& x = tmp.M;
-    
-    if(t_n_rows == 1)
-      {
-      const eT* x_mem = x.memptr();
-      
-      Mat<eT>& A = (*m_ptr);
-      
-      const uword row       = aux_row1;
-      const uword start_col = aux_col1;
-      
-      uword i,j;
-      
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        A.at(row, start_col+i) -= x_mem[i];
-        A.at(row, start_col+j) -= x_mem[j];
-        }
-      
-      if(i < t_n_cols)
-        {
-        A.at(row, start_col+i) -= x_mem[i];
-        }
-      }
-    else
-      {
-      for(uword col=0; col<t_n_cols; ++col)
-        {
-        arrayops::inplace_minus( t.colptr(col), x.colptr(col), t_n_rows );
-        }
-      }
-    }
-  else
-    {
-    if(t_n_rows == 1)
-      {
-      Mat<eT>& A = (*m_ptr);
-      
-      const uword row       = aux_row1;
-      const uword start_col = aux_col1;
-      
-      uword i,j;
-      
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        const eT tmp1 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,i) : P[i];
-        const eT tmp2 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,j) : P[j];
-        
-        A.at(row, start_col+i) -= tmp1;
-        A.at(row, start_col+j) -= tmp2;
-        }
-      
-      if(i < t_n_cols)
-        {
-        A.at(row, start_col+i) -= (Proxy<T1>::prefer_at_accessor) ? P.at(0,i) : P[i];
-        }
-      }
-    else
-      {
-      for(uword col=0; col<t_n_cols; ++col)
-        {
-        eT* t_col_data = t.colptr(col);
-        
-        uword i,j;
-        for(i=0, j=1; j<t_n_rows; i+=2, j+=2)
-          {
-          const eT val1 = P.at(i,col);
-          const eT val2 = P.at(j,col);
-          
-          t_col_data[i] -= val1;
-          t_col_data[j] -= val2;
-          }
-        
-        if(i < t_n_rows)
-          {
-          t_col_data[i] -= P.at(i,col);
-          }
-        }
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview<eT>::operator%= (const Base<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Proxy<T1> P(in.get_ref());
-  
-  subview<eT>& t = *this;
-  
-  const uword t_n_rows = t.n_rows;
-  const uword t_n_cols = t.n_cols;
-  
-  arma_debug_assert_same_size(t, P, "element-wise multiplication");
-  
-  const bool alias = P.is_alias(t.m);
-  
-  arma_extra_debug_warn(alias, "aliasing detected");
-  
-  if( (alias == true) || (is_Mat<typename Proxy<T1>::stored_type>::value == true) )
-    {
-    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, t.m);
-    const Mat<eT>& x = tmp.M;
-    
-    if(t_n_rows == 1)
-      {
-      const eT* x_mem = x.memptr();
-      
-      Mat<eT>& A = (*m_ptr);
-      
-      const uword row       = aux_row1;
-      const uword start_col = aux_col1;
-      
-      uword i,j;
-      
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        A.at(row, start_col+i) *= x_mem[i];
-        A.at(row, start_col+j) *= x_mem[j];
-        }
-      
-      if(i < t_n_cols)
-        {
-        A.at(row, start_col+i) *= x_mem[i];
-        }
-      }
-    else
-      {
-      for(uword col=0; col<t_n_cols; ++col)
-        {
-        arrayops::inplace_mul( t.colptr(col), x.colptr(col), t_n_rows );
-        }
-      }
-    }
-  else
-    {
-    if(t_n_rows == 1)
-      {
-      Mat<eT>& A = (*m_ptr);
-      
-      const uword row       = aux_row1;
-      const uword start_col = aux_col1;
-      
-      uword i,j;
-      
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        const eT tmp1 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,i) : P[i];
-        const eT tmp2 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,j) : P[j];
-        
-        A.at(row, start_col+i) *= tmp1;
-        A.at(row, start_col+j) *= tmp2;
-        }
-      
-      if(i < t_n_cols)
-        {
-        A.at(row, start_col+i) *= (Proxy<T1>::prefer_at_accessor) ? P.at(0,i) : P[i];
-        }
-      }
-    else
-      {
-      for(uword col=0; col<t_n_cols; ++col)
-        {
-        eT* t_col_data = t.colptr(col);
-        
-        uword i,j;
-        for(i=0, j=1; j<t_n_rows; i+=2, j+=2)
-          {
-          const eT val1 = P.at(i,col);
-          const eT val2 = P.at(j,col);
-          
-          t_col_data[i] *= val1;
-          t_col_data[j] *= val2;
-          }
-        
-        if(i < t_n_rows)
-          {
-          t_col_data[i] *= P.at(i,col);
-          }
-        }
-      }
-    }
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview<eT>::operator/= (const Base<eT,T1>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const Proxy<T1> P(in.get_ref());
-  
-  subview<eT>& t = *this;
-  
-  const uword t_n_rows = t.n_rows;
-  const uword t_n_cols = t.n_cols;
-  
-  arma_debug_assert_same_size(t, P, "element-wise division");
-  
-  const bool alias = P.is_alias(t.m);
-  
-  arma_extra_debug_warn(alias, "aliasing detected");
-  
-  if( (alias == true) || (is_Mat<typename Proxy<T1>::stored_type>::value == true) )
-    {
-    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, t.m);
-    const Mat<eT>& x = tmp.M;
-    
-    if(t_n_rows == 1)
-      {
-      const eT* x_mem = x.memptr();
-      
-      Mat<eT>& A = (*m_ptr);
-      
-      const uword row       = aux_row1;
-      const uword start_col = aux_col1;
-      
-      uword i,j;
-      
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        A.at(row, start_col+i) /= x_mem[i];
-        A.at(row, start_col+j) /= x_mem[j];
-        }
-      
-      if(i < t_n_cols)
-        {
-        A.at(row, start_col+i) /= x_mem[i];
-        }
-      }
-    else
-      {
-      for(uword col=0; col<t_n_cols; ++col)
-        {
-        arrayops::inplace_div( t.colptr(col), x.colptr(col), t_n_rows );
-        }
-      }
-    }
-  else
-    {
-    if(t_n_rows == 1)
-      {
-      Mat<eT>& A = (*m_ptr);
-      
-      const uword row       = aux_row1;
-      const uword start_col = aux_col1;
-      
-      uword i,j;
-      
-      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-        {
-        const eT tmp1 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,i) : P[i];
-        const eT tmp2 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,j) : P[j];
-        
-        A.at(row, start_col+i) /= tmp1;
-        A.at(row, start_col+j) /= tmp2;
-        }
-      
-      if(i < t_n_cols)
-        {
-        A.at(row, start_col+i) /= (Proxy<T1>::prefer_at_accessor) ? P.at(0,i) : P[i];
-        }
-      }
-    else
-      {
-      for(uword col=0; col<t_n_cols; ++col)
-        {
-        eT* t_col_data = t.colptr(col);
-        
-        uword i,j;
-        for(i=0, j=1; j<t_n_rows; i+=2, j+=2)
-          {
-          const eT val1 = P.at(i,col);
-          const eT val2 = P.at(j,col);
-          
-          t_col_data[i] /= val1;
-          t_col_data[j] /= val2;
-          }
-        
-        if(i < t_n_rows)
-          {
-          t_col_data[i] /= P.at(i,col);
-          }
-        }
-      }
-    }
-  }
-
-
-
-//! x.submat(...) = y.submat(...)
-template<typename eT>
-inline
-void
-subview<eT>::operator= (const subview<eT>& x_in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool overlap = check_overlap(x_in);
-  
-        Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
-  const subview<eT>* tmp_subview = overlap ? new subview<eT>(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
-  const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
-  
-  subview<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "insert into submatrix");
-  
-  const uword t_n_cols = t.n_cols;
-  const uword t_n_rows = t.n_rows;
-  
-  if(t_n_rows == 1)
-    {
-          Mat<eT>& A = *(t.m_ptr);
-    const Mat<eT>& B = x.m;
-    
-    const uword row_A = t.aux_row1;
-    const uword row_B = x.aux_row1;
-    
-    const uword start_col_A = t.aux_col1;
-    const uword start_col_B = x.aux_col1;
-    
-    uword i,j;
-    
-    for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-      {
-      const eT tmp1 = B.at(row_B, start_col_B + i);
-      const eT tmp2 = B.at(row_B, start_col_B + j);
-      
-      A.at(row_A, start_col_A + i) = tmp1;
-      A.at(row_A, start_col_A + j) = tmp2;
-      }
-    
-    if(i < t_n_cols)
-      {
-      A.at(row_A, start_col_A + i) = B.at(row_B, start_col_B + i);
-      }
-    }
-  else
-    {
-    for(uword col=0; col<t_n_cols; ++col)
-      {
-      arrayops::copy( t.colptr(col), x.colptr(col), t_n_rows );
-      }
-    }
-  
-  if(overlap)
-    {
-    delete tmp_subview;
-    delete tmp_mat;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::operator+= (const subview<eT>& x_in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool overlap = check_overlap(x_in);
-  
-        Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
-  const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
-  const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
-  
-  subview<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "addition");
-  
-  const uword t_n_rows = t.n_rows;
-  const uword t_n_cols = t.n_cols;
-  
-  if(t_n_rows == 1)
-    {
-          Mat<eT>& A = *(t.m_ptr);
-    const Mat<eT>& B = x.m;
-    
-    const uword row_A = t.aux_row1;
-    const uword row_B = x.aux_row1;
-    
-    const uword start_col_A = t.aux_col1;
-    const uword start_col_B = x.aux_col1;
-    
-    uword i,j;
-    
-    for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-      {
-      const eT tmp1 = B.at(row_B, start_col_B + i);
-      const eT tmp2 = B.at(row_B, start_col_B + j);
-      
-      A.at(row_A, start_col_A + i) += tmp1;
-      A.at(row_A, start_col_A + j) += tmp2;
-      }
-    
-    if(i < t_n_cols)
-      {
-      A.at(row_A, start_col_A + i) += B.at(row_B, start_col_B + i);
-      }
-    }
-  else
-    {
-    for(uword col=0; col<t_n_cols; ++col)
-      {
-      arrayops::inplace_plus( t.colptr(col), x.colptr(col), t_n_rows );
-      }
-    }
-  
-  if(overlap)
-    {
-    delete tmp_subview;
-    delete tmp_mat;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::operator-= (const subview<eT>& x_in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool overlap = check_overlap(x_in);
-  
-        Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
-  const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
-  const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
-  
-  subview<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "subtraction");
-  
-  const uword t_n_rows = t.n_rows;
-  const uword t_n_cols = t.n_cols;
-  
-  if(t_n_rows == 1)
-    {
-          Mat<eT>& A = *(t.m_ptr);
-    const Mat<eT>& B = x.m;
-    
-    const uword row_A = t.aux_row1;
-    const uword row_B = x.aux_row1;
-    
-    const uword start_col_A = t.aux_col1;
-    const uword start_col_B = x.aux_col1;
-    
-    uword i,j;
-    
-    for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-      {
-      const eT tmp1 = B.at(row_B, start_col_B + i);
-      const eT tmp2 = B.at(row_B, start_col_B + j);
-      
-      A.at(row_A, start_col_A + i) -= tmp1;
-      A.at(row_A, start_col_A + j) -= tmp2;
-      }
-    
-    if(i < t_n_cols)
-      {
-      A.at(row_A, start_col_A + i) -= B.at(row_B, start_col_B + i);
-      }
-    }
-  else
-    {
-    for(uword col=0; col<t_n_cols; ++col)
-      {
-      arrayops::inplace_minus( t.colptr(col), x.colptr(col), t_n_rows );
-      }
-    }
-    
-  if(overlap)
-    {
-    delete tmp_subview;
-    delete tmp_mat;
-    }
-  
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::operator%= (const subview& x_in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool overlap = check_overlap(x_in);
-  
-        Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
-  const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
-  const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
-  
-  subview<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "element-wise multiplication");
-  
-  const uword t_n_rows = t.n_rows;
-  const uword t_n_cols = t.n_cols;
-  
-  if(t_n_rows == 1)
-    {
-          Mat<eT>& A = *(t.m_ptr);
-    const Mat<eT>& B = x.m;
-    
-    const uword row_A = t.aux_row1;
-    const uword row_B = x.aux_row1;
-    
-    const uword start_col_A = t.aux_col1;
-    const uword start_col_B = x.aux_col1;
-    
-    uword i,j;
-    
-    for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-      {
-      const eT tmp1 = B.at(row_B, start_col_B + i);
-      const eT tmp2 = B.at(row_B, start_col_B + j);
-      
-      A.at(row_A, start_col_A + i) *= tmp1;
-      A.at(row_A, start_col_A + j) *= tmp2;
-      }
-    
-    if(i < t_n_cols)
-      {
-      A.at(row_A, start_col_A + i) *= B.at(row_B, start_col_B + i);
-      }
-    }
-  else
-    {
-    for(uword col=0; col<t_n_cols; ++col)
-      {
-      arrayops::inplace_mul( t.colptr(col), x.colptr(col), t_n_rows );
-      }
-    }
-  
-  if(overlap)
-    {
-    delete tmp_subview;
-    delete tmp_mat;
-    }
-  
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::operator/= (const subview& x_in)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool overlap = check_overlap(x_in);
-  
-        Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
-  const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
-  const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
-  
-  subview<eT>& t = *this;
-  
-  arma_debug_assert_same_size(t, x, "element-wise division");
-  
-  const uword t_n_rows = t.n_rows;
-  const uword t_n_cols = t.n_cols;
-  
-  if(t_n_rows == 1)
-    {
-          Mat<eT>& A = *(t.m_ptr);
-    const Mat<eT>& B = x.m;
-    
-    const uword row_A = t.aux_row1;
-    const uword row_B = x.aux_row1;
-    
-    const uword start_col_A = t.aux_col1;
-    const uword start_col_B = x.aux_col1;
-    
-    uword i,j;
-    
-    for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
-      {
-      const eT tmp1 = B.at(row_B, start_col_B + i);
-      const eT tmp2 = B.at(row_B, start_col_B + j);
-      
-      A.at(row_A, start_col_A + i) /= tmp1;
-      A.at(row_A, start_col_A + j) /= tmp2;
-      }
-    
-    if(i < t_n_cols)
-      {
-      A.at(row_A, start_col_A + i) /= B.at(row_B, start_col_B + i);
-      }
-    }
-  else
-    {
-    for(uword col=0; col<t_n_cols; ++col)
-      {
-      arrayops::inplace_div( t.colptr(col), x.colptr(col), t_n_rows );
-      }
-    }
-    
-  if(overlap)
-    {
-    delete tmp_subview;
-    delete tmp_mat;
-    }
-  
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::fill(const eT val)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword local_n_cols = n_cols;
-  const uword local_n_rows = n_rows;
-  
-  if(local_n_rows == 1)
-    {
-    Mat<eT>& X = (*m_ptr);
-    
-    const uword row           = aux_row1;
-    const uword start_col     = aux_col1;
-    const uword end_col_plus1 = start_col + local_n_cols;
-    
-    uword i,j;
-    
-    for(i=start_col, j=start_col+1; j < end_col_plus1; i+=2, j+=2)
-      {
-      X.at(row, i) = val;
-      X.at(row, j) = val;
-      }
-    
-    if(i < end_col_plus1)
-      {
-      X.at(row, i) = val;
-      }
-    }
-  else
-    {
-    for(uword col=0; col<local_n_cols; ++col)
-      {
-      arrayops::inplace_set( colptr(col), val, local_n_rows );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::zeros()
-  {
-  arma_extra_debug_sigprint();
-  
-  (*this).fill(eT(0));
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::ones()
-  {
-  arma_extra_debug_sigprint();
-  
-  (*this).fill(eT(1));
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::eye()
-  {
-  arma_extra_debug_sigprint();
-  
-  fill(eT(0));
-  
-  const uword N = (std::min)(n_rows, n_cols);
-  
-  for(uword i=0; i<N; ++i)
-    {
-    at(i,i) = eT(1);
-    }
-  }
-
-
-
-template<typename eT>
-inline
-eT&
-subview<eT>::operator[](const uword i)
-  {
-  const uword in_col = i / n_rows;
-  const uword in_row = i % n_rows;
-    
-  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return access::rw( (*m_ptr).mem[index] );
-  }
-
-
-
-template<typename eT>
-inline
-eT
-subview<eT>::operator[](const uword i) const
-  {
-  const uword in_col = i / n_rows;
-  const uword in_row = i % n_rows;
-  
-  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return m.mem[index];
-  }
-
-
-
-template<typename eT>
-inline
-eT&
-subview<eT>::operator()(const uword i)
-  {
-  arma_debug_check( (i >= n_elem), "subview::operator(): index out of bounds");
-    
-  const uword in_col = i / n_rows;
-  const uword in_row = i % n_rows;
-  
-  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return access::rw( (*m_ptr).mem[index] );
-  }
-
-
-
-template<typename eT>
-inline
-eT
-subview<eT>::operator()(const uword i) const
-  {
-  arma_debug_check( (i >= n_elem), "subview::operator(): index out of bounds");
-  
-  const uword in_col = i / n_rows;
-  const uword in_row = i % n_rows;
-  
-  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return m.mem[index];
-  }
-
-
-
-template<typename eT>
-inline
-eT&
-subview<eT>::operator()(const uword in_row, const uword in_col)
-  {
-  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "subview::operator(): index out of bounds");
-  
-  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return access::rw( (*m_ptr).mem[index] );
-  }
-
-
-
-template<typename eT>
-inline
-eT
-subview<eT>::operator()(const uword in_row, const uword in_col) const
-  {
-  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "subview::operator(): index out of bounds");
-  
-  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return m.mem[index];
-  }
-
-
-
-template<typename eT>
-inline
-eT&
-subview<eT>::at(const uword in_row, const uword in_col)
-  {
-  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return access::rw( (*m_ptr).mem[index] );
-  }
-
-
-
-template<typename eT>
-inline
-eT
-subview<eT>::at(const uword in_row, const uword in_col) const
-  {
-  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
-  return m.mem[index];
-  }
-
-
-
-template<typename eT>
-arma_inline
-eT*
-subview<eT>::colptr(const uword in_col)
-  {
-  return & access::rw((*m_ptr).mem[ (in_col + aux_col1)*m.n_rows + aux_row1 ]);
-  }
-
-
-
-template<typename eT>
-arma_inline
-const eT*
-subview<eT>::colptr(const uword in_col) const
-  {
-  return & m.mem[ (in_col + aux_col1)*m.n_rows + aux_row1 ];
-  }
-
-
-
-template<typename eT>
-inline
-bool
-subview<eT>::check_overlap(const subview<eT>& x) const
-  {
-  const subview<eT>& t = *this;
-  
-  if(&t.m != &x.m)
-    {
-    return false;
-    }
-  else
-    {
-    if( (t.n_elem == 0) || (x.n_elem == 0) )
-      {
-      return false;
-      }
-    else
-      {
-      const uword t_row_start  = t.aux_row1;
-      const uword t_row_end_p1 = t_row_start + t.n_rows;
-      
-      const uword t_col_start  = t.aux_col1;
-      const uword t_col_end_p1 = t_col_start + t.n_cols;
-      
-      
-      const uword x_row_start  = x.aux_row1;
-      const uword x_row_end_p1 = x_row_start + x.n_rows;
-      
-      const uword x_col_start  = x.aux_col1;
-      const uword x_col_end_p1 = x_col_start + x.n_cols;
-      
-      
-      const bool outside_rows = ( (x_row_start >= t_row_end_p1) || (t_row_start >= x_row_end_p1) );
-      const bool outside_cols = ( (x_col_start >= t_col_end_p1) || (t_col_start >= x_col_end_p1) );
-      
-      return ( (outside_rows == false) && (outside_cols == false) );
-      }
-    }
-  }
-
-
-
-template<typename eT>
-inline
-bool
-subview<eT>::is_vec() const
-  {
-  return ( (n_rows == 1) || (n_cols == 1) );
-  }
-
-
-
-//! X = Y.submat(...)
-template<typename eT>
-inline
-void
-subview<eT>::extract(Mat<eT>& out, const subview<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing;
-  // size setting and alias checking is done by either the Mat contructor or operator=()
-  
-  const uword n_rows = in.n_rows;  // number of rows in the subview
-  const uword n_cols = in.n_cols;  // number of columns in the subview
-  
-  arma_extra_debug_print(arma_boost::format("out.n_rows = %d   out.n_cols = %d    in.m.n_rows = %d  in.m.n_cols = %d") % out.n_rows % out.n_cols % in.m.n_rows % in.m.n_cols );
-  
-  
-  if(in.is_vec() == true)
-    {
-    if(n_cols == 1)   // a column vector
-      {
-      arma_extra_debug_print("subview::extract(): copying col (going across rows)");
-      
-      // in.colptr(0) the first column of the subview, taking into account any row offset
-      arrayops::copy( out.memptr(), in.colptr(0), n_rows );
-      }
-    else   // a row vector (possibly empty)
-      {
-      arma_extra_debug_print("subview::extract(): copying row (going across columns)");
-      
-      const Mat<eT>& X = in.m;
-      
-      eT* out_mem = out.memptr();
-      
-      const uword row       = in.aux_row1;
-      const uword start_col = in.aux_col1;
-      
-      uword i,j;
-      
-      for(i=0, j=1; j < n_cols; i+=2, j+=2)
-        {
-        const eT tmp1 = X.at(row, start_col+i);
-        const eT tmp2 = X.at(row, start_col+j);
-        
-        out_mem[i] = tmp1;
-        out_mem[j] = tmp2;
-        }
-      
-      if(i < n_cols)
-        {
-        out_mem[i] = X.at(row, start_col+i);
-        }
-      }
-    }
-  else   // general submatrix
-    {
-    arma_extra_debug_print("subview::extract(): general submatrix");
-    
-    for(uword col = 0; col<n_cols; ++col)   
-      {
-      arrayops::copy( out.colptr(col), in.colptr(col), n_rows );
-      }
-    }
-  }
-
-
-
-//! X += Y.submat(...)
-template<typename eT>
-inline
-void
-subview<eT>::plus_inplace(Mat<eT>& out, const subview<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out, in, "addition");
-  
-  const uword n_rows = in.n_rows;
-  const uword n_cols = in.n_cols;
-  
-  if(n_rows == 1)
-    {
-    eT* out_mem = out.memptr();
-    
-    const Mat<eT>& X = in.m;
-    
-    const uword row       = in.aux_row1;
-    const uword start_col = in.aux_col1;
-    
-    uword i,j;
-    for(i=0, j=1; j < n_cols; i+=2, j+=2)
-      {
-      const eT tmp1 = X.at(row, start_col+i);
-      const eT tmp2 = X.at(row, start_col+j);
-        
-      out_mem[i] += tmp1;
-      out_mem[j] += tmp2;
-      }
-    
-    if(i < n_cols)
-      {
-      out_mem[i] += X.at(row, start_col+i);
-      }
-    }
-  else
-    {
-    for(uword col=0; col<n_cols; ++col)
-      {
-      arrayops::inplace_plus(out.colptr(col), in.colptr(col), n_rows);
-      }
-    }
-  }
-
-
-
-//! X -= Y.submat(...)
-template<typename eT>
-inline
-void
-subview<eT>::minus_inplace(Mat<eT>& out, const subview<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out, in, "subtraction");
-  
-  const uword n_rows = in.n_rows;
-  const uword n_cols = in.n_cols;
-  
-  if(n_rows == 1)
-    {
-    eT* out_mem = out.memptr();
-    
-    const Mat<eT>& X = in.m;
-    
-    const uword row       = in.aux_row1;
-    const uword start_col = in.aux_col1;
-    
-    uword i,j;
-    for(i=0, j=1; j < n_cols; i+=2, j+=2)
-      {
-      const eT tmp1 = X.at(row, start_col+i);
-      const eT tmp2 = X.at(row, start_col+j);
-        
-      out_mem[i] -= tmp1;
-      out_mem[j] -= tmp2;
-      }
-    
-    if(i < n_cols)
-      {
-      out_mem[i] -= X.at(row, start_col+i);
-      }
-    }
-  else
-    {
-    for(uword col=0; col<n_cols; ++col)
-      {
-      arrayops::inplace_minus(out.colptr(col), in.colptr(col), n_rows);
-      }
-    }
-  }
-
-
-
-//! X %= Y.submat(...)
-template<typename eT>
-inline
-void
-subview<eT>::schur_inplace(Mat<eT>& out, const subview<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out, in, "element-wise multiplication");
-  
-  const uword n_rows = in.n_rows;
-  const uword n_cols = in.n_cols;
-  
-  if(n_rows == 1)
-    {
-    eT* out_mem = out.memptr();
-    
-    const Mat<eT>& X = in.m;
-    
-    const uword row       = in.aux_row1;
-    const uword start_col = in.aux_col1;
-    
-    uword i,j;
-    for(i=0, j=1; j < n_cols; i+=2, j+=2)
-      {
-      const eT tmp1 = X.at(row, start_col+i);
-      const eT tmp2 = X.at(row, start_col+j);
-        
-      out_mem[i] *= tmp1;
-      out_mem[j] *= tmp2;
-      }
-    
-    if(i < n_cols)
-      {
-      out_mem[i] *= X.at(row, start_col+i);
-      }
-    }
-  else
-    {
-    for(uword col=0; col<n_cols; ++col)
-      {
-      arrayops::inplace_mul(out.colptr(col), in.colptr(col), n_rows);
-      }
-    }
-  }
-
-
-
-//! X /= Y.submat(...)
-template<typename eT>
-inline
-void
-subview<eT>::div_inplace(Mat<eT>& out, const subview<eT>& in)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_assert_same_size(out, in, "element-wise division");
-  
-  const uword n_rows = in.n_rows;
-  const uword n_cols = in.n_cols;
-  
-  if(n_rows == 1)
-    {
-    eT* out_mem = out.memptr();
-    
-    const Mat<eT>& X = in.m;
-    
-    const uword row       = in.aux_row1;
-    const uword start_col = in.aux_col1;
-    
-    uword i,j;
-    for(i=0, j=1; j < n_cols; i+=2, j+=2)
-      {
-      const eT tmp1 = X.at(row, start_col+i);
-      const eT tmp2 = X.at(row, start_col+j);
-        
-      out_mem[i] /= tmp1;
-      out_mem[j] /= tmp2;
-      }
-    
-    if(i < n_cols)
-      {
-      out_mem[i] /= X.at(row, start_col+i);
-      }
-    }
-  else
-    {
-    for(uword col=0; col<n_cols; ++col)
-      {
-      arrayops::inplace_div(out.colptr(col), in.colptr(col), n_rows);
-      }
-    }
-  }
-
-
-
-//! creation of subview (row vector)
-template<typename eT>
-inline
-subview_row<eT>
-subview<eT>::row(const uword row_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( row_num >= n_rows, "subview::row(): out of bounds" );
-  
-  const uword base_row = aux_row1 + row_num;
-  
-  return subview_row<eT>(*m_ptr, base_row, aux_col1, n_cols);
-  }
-
-
-
-//! creation of subview (row vector)
-template<typename eT>
-inline
-const subview_row<eT>
-subview<eT>::row(const uword row_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( row_num >= n_rows, "subview::row(): out of bounds" );
-  
-  const uword base_row = aux_row1 + row_num;
-  
-  return subview_row<eT>(m, base_row, aux_col1, n_cols);
-  }
-
-
-
-template<typename eT>
-inline
-subview_row<eT>
-subview<eT>::operator()(const uword row_num, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool col_all = col_span.whole;
-  
-  const uword local_n_cols = n_cols;
-  
-  const uword in_col1       = col_all ? 0            : col_span.a;
-  const uword in_col2       =                          col_span.b;
-  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
-  
-  const uword base_col1     = aux_col1 + in_col1;  
-  const uword base_row      = aux_row1 + row_num;
-  
-  arma_debug_check
-    (
-    (row_num >= n_rows)
-    ||
-    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
-    ,
-    "subview::operator(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview_row<eT>(*m_ptr, base_row, base_col1, submat_n_cols);
-  }
-
-
-
-template<typename eT>
-inline
-const subview_row<eT>
-subview<eT>::operator()(const uword row_num, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool col_all = col_span.whole;
-  
-  const uword local_n_cols = n_cols;
-  
-  const uword in_col1       = col_all ? 0            : col_span.a;
-  const uword in_col2       =                          col_span.b;
-  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
-  
-  const uword base_col1     = aux_col1 + in_col1;
-  const uword base_row      = aux_row1 + row_num;
-  
-  arma_debug_check
-    (
-    (row_num >= n_rows)
-    ||
-    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
-    ,
-    "subview::operator(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview_row<eT>(m, base_row, base_col1, submat_n_cols);
-  }
-
-
-
-//! creation of subview (column vector)
-template<typename eT>
-inline
-subview_col<eT>
-subview<eT>::col(const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( col_num >= n_cols, "subview::col(): out of bounds");
-  
-  const uword base_col = aux_col1 + col_num;
-  
-  return subview_col<eT>(*m_ptr, base_col, aux_row1, n_rows);
-  }
-
-
-
-//! creation of subview (column vector)
-template<typename eT>
-inline
-const subview_col<eT>
-subview<eT>::col(const uword col_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( col_num >= n_cols, "subview::col(): out of bounds");
-  
-  const uword base_col = aux_col1 + col_num;
-  
-  return subview_col<eT>(m, base_col, aux_row1, n_rows);
-  }
-
-
-
-template<typename eT>
-inline
-subview_col<eT>
-subview<eT>::operator()(const span& row_span, const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all = row_span.whole;
-  
-  const uword local_n_rows = n_rows;
-  
-  const uword in_row1       = row_all ? 0            : row_span.a;
-  const uword in_row2       =                          row_span.b;
-  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
-  
-  const uword base_row1       = aux_row1 + in_row1;  
-  const uword base_col        = aux_col1 + col_num;
-  
-  arma_debug_check
-    (
-    (col_num >= n_cols)
-    ||
-    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
-    ,
-    "subview::operator(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview_col<eT>(*m_ptr, base_col, base_row1, submat_n_rows);
-  }
-
-
-
-template<typename eT>
-inline
-const subview_col<eT>
-subview<eT>::operator()(const span& row_span, const uword col_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all = row_span.whole;
-  
-  const uword local_n_rows = n_rows;
-  
-  const uword in_row1       = row_all ? 0            : row_span.a;
-  const uword in_row2       =                          row_span.b;
-  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
-  
-  const uword base_row1       = aux_row1 + in_row1;
-  const uword base_col        = aux_col1 + col_num;
-  
-  arma_debug_check
-    (
-    (col_num >= n_cols)
-    ||
-    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
-    ,
-    "subview::operator(): indices out of bounds or incorrectly used"
-    );
-  
-  return subview_col<eT>(m, base_col, base_row1, submat_n_rows);
-  }
-
-
-
-//! create a Col object which uses memory from an existing matrix object.
-//! this approach is currently not alias safe
-//! and does not take into account that the parent matrix object could be deleted.
-//! if deleted memory is accessed by the created Col object,
-//! it will cause memory corruption and/or a crash
-template<typename eT>
-inline
-Col<eT>
-subview<eT>::unsafe_col(const uword col_num)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( col_num >= n_cols, "subview::unsafe_col(): out of bounds");
-  
-  return Col<eT>(colptr(col_num), n_rows, false, true);
-  }
-
-
-
-//! create a Col object which uses memory from an existing matrix object.
-//! this approach is currently not alias safe
-//! and does not take into account that the parent matrix object could be deleted.
-//! if deleted memory is accessed by the created Col object,
-//! it will cause memory corruption and/or a crash
-template<typename eT>
-inline
-const Col<eT>
-subview<eT>::unsafe_col(const uword col_num) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( col_num >= n_cols, "subview::unsafe_col(): out of bounds");
-  
-  return Col<eT>(const_cast<eT*>(colptr(col_num)), n_rows, false, true);
-  }
-
-
-
-//! creation of subview (submatrix comprised of specified row vectors)
-template<typename eT>
-inline
-subview<eT>
-subview<eT>::rows(const uword in_row1, const uword in_row2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 > in_row2) || (in_row2 >= n_rows),
-    "subview::rows(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  const uword base_row1 = aux_row1 + in_row1;
-  
-  return subview<eT>(*m_ptr, base_row1, aux_col1, subview_n_rows, n_cols );
-  }
-
-
-
-//! creation of subview (submatrix comprised of specified row vectors)
-template<typename eT>
-inline
-const subview<eT>
-subview<eT>::rows(const uword in_row1, const uword in_row2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 > in_row2) || (in_row2 >= n_rows),
-    "subview::rows(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  const uword base_row1 = aux_row1 + in_row1;
-  
-  return subview<eT>(m, base_row1, aux_col1, subview_n_rows, n_cols );
-  }
-
-
-
-//! creation of subview (submatrix comprised of specified column vectors)
-template<typename eT>
-inline
-subview<eT>
-subview<eT>::cols(const uword in_col1, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_col1 > in_col2) || (in_col2 >= n_cols),
-    "subview::cols(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  const uword base_col1 = aux_col1 + in_col1;
-  
-  return subview<eT>(*m_ptr, aux_row1, base_col1, n_rows, subview_n_cols);
-  }
-
-
-
-//! creation of subview (submatrix comprised of specified column vectors)
-template<typename eT>
-inline
-const subview<eT>
-subview<eT>::cols(const uword in_col1, const uword in_col2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_col1 > in_col2) || (in_col2 >= n_cols),
-    "subview::cols(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  const uword base_col1 = aux_col1 + in_col1;
-  
-  return subview<eT>(m, aux_row1, base_col1, n_rows, subview_n_cols);
-  }
-
-
-
-//! creation of subview (submatrix)
-template<typename eT>
-inline
-subview<eT>
-subview<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
-    "subview::submat(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  const uword base_row1 = aux_row1 + in_row1;
-  const uword base_col1 = aux_col1 + in_col1;
-  
-  return subview<eT>(*m_ptr, base_row1, base_col1, subview_n_rows, subview_n_cols);
-  }
-
-
-
-//! creation of subview (generic submatrix)
-template<typename eT>
-inline
-const subview<eT>
-subview<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
-    "subview::submat(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  const uword base_row1 = aux_row1 + in_row1;
-  const uword base_col1 = aux_col1 + in_col1;
-  
-  return subview<eT>(m, base_row1, base_col1, subview_n_rows, subview_n_cols);
-  }
-
-
-
-//! creation of subview (submatrix)
-template<typename eT>
-inline
-subview<eT>
-subview<eT>::submat(const span& row_span, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all = row_span.whole;
-  const bool col_all = col_span.whole;
-  
-  const uword local_n_rows = n_rows;
-  const uword local_n_cols = n_cols;
-  
-  const uword in_row1       = row_all ? 0            : row_span.a;
-  const uword in_row2       =                          row_span.b;
-  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
-  
-  const uword in_col1       = col_all ? 0            : col_span.a;
-  const uword in_col2       =                          col_span.b;
-  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
-  
-  arma_debug_check
-    (
-    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
-    ||
-    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
-    ,
-    "subview::submat(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword base_row1 = aux_row1 + in_row1;
-  const uword base_col1 = aux_col1 + in_col1;
-  
-  return subview<eT>(*m_ptr, base_row1, base_col1, submat_n_rows, submat_n_cols);
-  }
-
-
-
-//! creation of subview (generic submatrix)
-template<typename eT>
-inline
-const subview<eT>
-subview<eT>::submat(const span& row_span, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const bool row_all = row_span.whole;
-  const bool col_all = col_span.whole;
-  
-  const uword local_n_rows = n_rows;
-  const uword local_n_cols = n_cols;
-  
-  const uword in_row1       = row_all ? 0            : row_span.a;
-  const uword in_row2       =                          row_span.b;
-  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
-  
-  const uword in_col1       = col_all ? 0            : col_span.a;
-  const uword in_col2       =                          col_span.b;
-  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
-  
-  arma_debug_check
-    (
-    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
-    ||
-    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
-    ,
-    "subview::submat(): indices out of bounds or incorrectly used"
-    );
-  
-  const uword base_row1 = aux_row1 + in_row1;
-  const uword base_col1 = aux_col1 + in_col1;
-  
-  return subview<eT>(m, base_row1, base_col1, submat_n_rows, submat_n_cols);
-  }
-
-
-
-template<typename eT>
-inline
-subview<eT>
-subview<eT>::operator()(const span& row_span, const span& col_span)
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).submat(row_span, col_span);
-  }
-
-
-
-template<typename eT>
-inline
-const subview<eT>
-subview<eT>::operator()(const span& row_span, const span& col_span) const
-  {
-  arma_extra_debug_sigprint();
-  
-  return (*this).submat(row_span, col_span);
-  }
-
-
-
-//! creation of diagview (diagonal)
-template<typename eT>
-inline
-diagview<eT>
-subview<eT>::diag(const sword in_id)
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword row_offset = (in_id < 0) ? uword(-in_id) : 0;
-  const uword col_offset = (in_id > 0) ? uword( in_id) : 0;
-  
-  arma_debug_check
-    (
-    ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
-    "subview::diag(): requested diagonal out of bounds"
-    );
-  
-  const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
-  
-  const uword base_row_offset = aux_row1 + row_offset;
-  const uword base_col_offset = aux_col1 + col_offset;
-  
-  return diagview<eT>(*m_ptr, base_row_offset, base_col_offset, len);
-  }
-
-
-
-//! creation of diagview (diagonal)
-template<typename eT>
-inline
-const diagview<eT>
-subview<eT>::diag(const sword in_id) const
-  {
-  arma_extra_debug_sigprint();
-  
-  const uword row_offset = (in_id < 0) ? -in_id : 0;
-  const uword col_offset = (in_id > 0) ?  in_id : 0;
-  
-  arma_debug_check
-    (
-    ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
-    "subview::diag(): requested diagonal out of bounds"
-    );
-  
-  const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
-  
-  const uword base_row_offset = aux_row1 + row_offset;
-  const uword base_col_offset = aux_col1 + col_offset;
-  
-  return diagview<eT>(m, base_row_offset, base_col_offset, len);
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::swap_rows(const uword in_row1, const uword in_row2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_row1 >= n_rows) || (in_row2 >= n_rows),
-    "subview::swap_rows(): out of bounds"
-    );
-  
-  eT* mem = (*m_ptr).memptr();
-  
-  for(uword col=0; col<n_cols; ++col)
-    {
-    const uword offset = (aux_col1 + col) * m.n_rows;
-    const uword pos1   = aux_row1 + in_row1 + offset;
-    const uword pos2   = aux_row1 + in_row2 + offset;
-    
-    const eT tmp          = mem[pos1];
-    access::rw(mem[pos1]) = mem[pos2];
-    access::rw(mem[pos2]) = tmp;
-    }
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview<eT>::swap_cols(const uword in_col1, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check
-    (
-    (in_col1 >= n_cols) || (in_col2 >= n_cols),
-    "subview::swap_cols(): out of bounds"
-    );
-  
-  if(n_elem > 0)
-    {
-    eT* ptr1 = colptr(in_col1);
-    eT* ptr2 = colptr(in_col2);
-    
-    for(uword row=0; row<n_rows; ++row)
-      {
-      const eT tmp = ptr1[row];
-      ptr1[row]    = ptr2[row];
-      ptr2[row]    = tmp;
-      }
-    }
-  }
-
-
-
-// template<typename eT>
-// inline
-// subview<eT>::iter::iter(const subview<eT>& S)
-//   : mem       (S.m.mem)
-//   , n_rows    (S.m.n_rows)
-//   , row_start (S.aux_row1)
-//   , row_end_p1(row_start + S.n_rows)
-//   , row       (row_start)
-//   , col       (S.aux_col1)
-//   , i         (row + col*n_rows)
-//   {
-//   arma_extra_debug_sigprint();
-//   }
-// 
-// 
-// 
-// template<typename eT>
-// arma_inline
-// eT
-// subview<eT>::iter::operator*() const
-//   {
-//   return mem[i];
-//   }
-// 
-// 
-// 
-// template<typename eT>
-// inline
-// void
-// subview<eT>::iter::operator++()
-//   {
-//   ++row;
-//   
-//   if(row < row_end_p1)
-//     {
-//     ++i;
-//     }
-//   else
-//     {
-//     row = row_start;
-//     ++col;
-//     
-//     i = row + col*n_rows;
-//     }
-//   }
-// 
-// 
-// 
-// template<typename eT>
-// inline
-// void
-// subview<eT>::iter::operator++(int)
-//   {
-//   operator++();
-//   }
-
-
-
-//
-//
-//
-
-
-
-template<typename eT>
-inline
-subview_col<eT>::subview_col(const Mat<eT>& in_m, const uword in_col)
-  : subview<eT>(in_m, 0, in_col, in_m.n_rows, 1)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-subview_col<eT>::subview_col(Mat<eT>& in_m, const uword in_col)
-  : subview<eT>(in_m, 0, in_col, in_m.n_rows, 1)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-subview_col<eT>::subview_col(const Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows)
-  : subview<eT>(in_m, in_row1, in_col, in_n_rows, 1)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-subview_col<eT>::subview_col(Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows)
-  : subview<eT>(in_m, in_row1, in_col, in_n_rows, 1)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_col<eT>::operator=(const subview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview<eT>::operator=(X);
-  arma_debug_check( (subview<eT>::n_cols > 1), "subview_col(): incompatible dimensions" );
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_col<eT>::operator=(const subview_col<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview<eT>::operator=(X); // interprets 'subview_col' as 'subview'
-  arma_debug_check( (subview<eT>::n_cols > 1), "subview_col(): incompatible dimensions" );
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview_col<eT>::operator=(const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview<eT>::operator=(X);
-  arma_debug_check( (subview<eT>::n_cols > 1), "subview_col(): incompatible dimensions" );
-  }
-
-
-
-template<typename eT>
-inline
-subview_col<eT>
-subview_col<eT>::rows(const uword in_row1, const uword in_row2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= subview<eT>::n_rows) ), "subview_col::rows(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  
-  const uword base_row1 = this->aux_row1 + in_row1;
-  
-  return subview_col<eT>(*(this->m_ptr), this->aux_col1, base_row1, subview_n_rows);
-  }
-
-
-
-template<typename eT>
-inline
-const subview_col<eT>
-subview_col<eT>::rows(const uword in_row1, const uword in_row2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= subview<eT>::n_rows) ), "subview_col::rows(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  
-  const uword base_row1 = this->aux_row1 + in_row1;
-  
-  return subview_col<eT>(this->m, this->aux_col1, base_row1, subview_n_rows);
-  }
-
-
-
-template<typename eT>
-inline
-subview_col<eT>
-subview_col<eT>::subvec(const uword in_row1, const uword in_row2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= subview<eT>::n_rows) ), "subview_col::subvec(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  
-  const uword base_row1 = this->aux_row1 + in_row1;
-  
-  return subview_col<eT>(*(this->m_ptr), this->aux_col1, base_row1, subview_n_rows);
-  }
-
-
-
-template<typename eT>
-inline
-const subview_col<eT>
-subview_col<eT>::subvec(const uword in_row1, const uword in_row2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= subview<eT>::n_rows) ), "subview_col::subvec(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_rows = in_row2 - in_row1 + 1;
-  
-  const uword base_row1 = this->aux_row1 + in_row1;
-  
-  return subview_col<eT>(this->m, this->aux_col1, base_row1, subview_n_rows);
-  }
-
-
-
-//
-//
-//
-
-
-
-template<typename eT>
-inline
-subview_row<eT>::subview_row(const Mat<eT>& in_m, const uword in_row)
-  : subview<eT>(in_m, in_row, 0, 1, in_m.n_cols)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-subview_row<eT>::subview_row(Mat<eT>& in_m, const uword in_row)
-  : subview<eT>(in_m, in_row, 0, 1, in_m.n_cols)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-subview_row<eT>::subview_row(const Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols)
-  : subview<eT>(in_m, in_row, in_col1, 1, in_n_cols)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-subview_row<eT>::subview_row(Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols)
-  : subview<eT>(in_m, in_row, in_col1, 1, in_n_cols)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_row<eT>::operator=(const subview<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview<eT>::operator=(X);
-  arma_debug_check( (subview<eT>::n_rows > 1), "subview_row(): incompatible dimensions" );
-  }
-
-
-
-template<typename eT>
-inline
-void
-subview_row<eT>::operator=(const subview_row<eT>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview<eT>::operator=(X); // interprets 'subview_row' as 'subview'
-  arma_debug_check( (subview<eT>::n_rows > 1), "subview_row(): incompatible dimensions" );
-  }
-
-
-
-template<typename eT>
-template<typename T1>
-inline
-void
-subview_row<eT>::operator=(const Base<eT,T1>& X)
-  {
-  arma_extra_debug_sigprint();
-  
-  subview<eT>::operator=(X);
-  arma_debug_check( (subview<eT>::n_rows > 1), "subview_row(): incompatible dimensions" );
-  }
-
-
-
-template<typename eT>
-inline
-subview_row<eT>
-subview_row<eT>::cols(const uword in_col1, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= subview<eT>::n_cols) ), "subview_row::cols(): indices out of bounds or incorrectly used" );
-  
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  const uword base_col1 = this->aux_col1 + in_col1;
-  
-  return subview_row<eT>(*(this->m_ptr), this->aux_row1, base_col1, subview_n_cols);
-  }
-
-
-
-template<typename eT>
-inline
-const subview_row<eT>
-subview_row<eT>::cols(const uword in_col1, const uword in_col2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= subview<eT>::n_cols) ), "subview_row::cols(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  const uword base_col1 = this->aux_col1 + in_col1;
-  
-  return subview_row<eT>(this->m, this->aux_row1, base_col1, subview_n_cols);
-  }
-
-
-
-template<typename eT>
-inline
-subview_row<eT>
-subview_row<eT>::subvec(const uword in_col1, const uword in_col2)
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= subview<eT>::n_cols) ), "subview_row::subvec(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  const uword base_col1 = this->aux_col1 + in_col1;
-  
-  return subview_row<eT>(*(this->m_ptr), this->aux_row1, base_col1, subview_n_cols);
-  }
-
-
-
-template<typename eT>
-inline
-const subview_row<eT>
-subview_row<eT>::subvec(const uword in_col1, const uword in_col2) const
-  {
-  arma_extra_debug_sigprint();
-  
-  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= subview<eT>::n_cols) ), "subview_row::subvec(): indices out of bounds or incorrectly used");
-  
-  const uword subview_n_cols = in_col2 - in_col1 + 1;
-  
-  const uword base_col1 = this->aux_col1 + in_col1;
-  
-  return subview_row<eT>(this->m, this->aux_row1, base_col1, subview_n_cols);
-  }
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/traits.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,672 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup traits
-//! @{
-
-
-template<typename T1>
-struct get_pod_type
-  { typedef T1 result; };
-
-template<typename T2>
-struct get_pod_type< std::complex<T2> >
-  { typedef T2 result; };
-
-
-
-template<typename T>
-struct is_Mat_only
-  { static const bool value = false; };
-
-template<typename eT>
-struct is_Mat_only< Mat<eT> >
-  { static const bool value = true; };
-
-
-
-template<typename T>
-struct is_Mat
-  { static const bool value = false; };
-
-template<typename eT>
-struct is_Mat< Mat<eT> >
-  { static const bool value = true; };
-
-template<typename eT>
-struct is_Mat< Row<eT> >
-  { static const bool value = true; };
-
-template<typename eT>
-struct is_Mat< Col<eT> >
-  { static const bool value = true; };
-
-
-
-template<typename T>
-struct is_Row
-  { static const bool value = false; };
-
-template<typename eT>
-struct is_Row< Row<eT> >
-  { static const bool value = true; };
-
-
-
-template<typename T>
-struct is_Col
-  { static const bool value = false; };
-
-template<typename eT>
-struct is_Col< Col<eT> >
-  { static const bool value = true; };
-
-
-
-
-
-
-template<typename T>
-struct is_subview
-  { static const bool value = false; };
-
-template<typename eT>
-struct is_subview< subview<eT> >
-  { static const bool value = true; };
-
-
-template<typename T>
-struct is_diagview
-  { static const bool value = false; };
-
-template<typename eT>
-struct is_diagview< diagview<eT> >
-  { static const bool value = true; };
-
-
-//
-//
-//
-
-
-
-template<typename T>
-struct is_Cube
-  { static const bool value = false; };
-
-template<typename eT>
-struct is_Cube< Cube<eT> >
-  { static const bool value = true; };
-
-template<typename T>
-struct is_subview_cube
-  { static const bool value = false; };
-
-template<typename eT>
-struct is_subview_cube< subview_cube<eT> >
-  { static const bool value = true; };
-
-
-
-//
-//
-//
-
-
-template<typename T>
-struct is_Gen
-  { static const bool value = false; };
- 
-template<typename eT, typename gen_type>
-struct is_Gen< Gen<eT,gen_type> >
-  { static const bool value = true; };
- 
-
-template<typename T>
-struct is_Op
-  { static const bool value = false; };
- 
-template<typename T1, typename op_type>
-struct is_Op< Op<T1,op_type> >
-  { static const bool value = true; };
- 
-
-template<typename T>
-struct is_eOp
-  { static const bool value = false; };
- 
-template<typename T1, typename eop_type>
-struct is_eOp< eOp<T1,eop_type> >
-  { static const bool value = true; };
- 
-
-template<typename T>
-struct is_mtOp
-  { static const bool value = false; };
- 
-template<typename eT, typename T1, typename op_type>
-struct is_mtOp< mtOp<eT, T1, op_type> >
-  { static const bool value = true; };
- 
-
-template<typename T>
-struct is_Glue
-  { static const bool value = false; };
- 
-template<typename T1, typename T2, typename glue_type>
-struct is_Glue< Glue<T1,T2,glue_type> >
-  { static const bool value = true; };
-
-
-template<typename T>
-struct is_eGlue
-  { static const bool value = false; };
- 
-template<typename T1, typename T2, typename eglue_type>
-struct is_eGlue< eGlue<T1,T2,eglue_type> >
-  { static const bool value = true; };
-
-
-template<typename T>
-struct is_mtGlue
-  { static const bool value = false; };
- 
-template<typename eT, typename T1, typename T2, typename glue_type>
-struct is_mtGlue< mtGlue<eT, T1, T2, glue_type> >
-  { static const bool value = true; };
-
-
-//
-//
-
-
-template<typename T>
-struct is_glue_times
-  { static const bool value = false; };
-
-template<typename T1, typename T2>
-struct is_glue_times< Glue<T1,T2,glue_times> >
-  { static const bool value = true; };
-
-
-template<typename T>
-struct is_glue_times_diag
-  { static const bool value = false; };
-
-template<typename T1, typename T2>
-struct is_glue_times_diag< Glue<T1,T2,glue_times_diag> >
-  { static const bool value = true; };
-
-
-template<typename T>
-struct is_op_diagmat
-  { static const bool value = false; };
- 
-template<typename T1>
-struct is_op_diagmat< Op<T1,op_diagmat> >
-  { static const bool value = true; };
-
-
-//
-//
-
-
-template<typename T>
-struct is_GenCube
-  { static const bool value = false; };
- 
-template<typename eT, typename gen_type>
-struct is_GenCube< GenCube<eT,gen_type> >
-  { static const bool value = true; };
- 
-
-template<typename T>
-struct is_OpCube
-  { static const bool value = false; };
- 
-template<typename T1, typename op_type>
-struct is_OpCube< OpCube<T1,op_type> >
-  { static const bool value = true; };
-
-
-template<typename T>
-struct is_eOpCube
-  { static const bool value = false; };
- 
-template<typename T1, typename eop_type>
-struct is_eOpCube< eOpCube<T1,eop_type> >
-  { static const bool value = true; };
- 
-
-template<typename T>
-struct is_mtOpCube
-  { static const bool value = false; };
- 
-template<typename eT, typename T1, typename op_type>
-struct is_mtOpCube< mtOpCube<eT, T1, op_type> >
-  { static const bool value = true; };
- 
-
-template<typename T>
-struct is_GlueCube
-  { static const bool value = false; };
- 
-template<typename T1, typename T2, typename glue_type>
-struct is_GlueCube< GlueCube<T1,T2,glue_type> >
-  { static const bool value = true; };
-
-
-template<typename T>
-struct is_eGlueCube
-  { static const bool value = false; };
- 
-template<typename T1, typename T2, typename eglue_type>
-struct is_eGlueCube< eGlueCube<T1,T2,eglue_type> >
-  { static const bool value = true; };
-
-
-template<typename T>
-struct is_mtGlueCube
-  { static const bool value = false; };
- 
-template<typename eT, typename T1, typename T2, typename glue_type>
-struct is_mtGlueCube< mtGlueCube<eT, T1, T2, glue_type> >
-  { static const bool value = true; };
-
-
-//
-//
-//
-
-
-template<typename T>
-struct is_op_rel
-  { static const bool value = false; };
-
-template<typename out_eT, typename T1>
-struct is_op_rel< mtOp<out_eT, T1, op_rel_lt_pre> >
-  { static const bool value = true; };
-
-template<typename out_eT, typename T1>
-struct is_op_rel< mtOp<out_eT, T1, op_rel_lt_post> >
-  { static const bool value = true; };
-
-template<typename out_eT, typename T1>
-struct is_op_rel< mtOp<out_eT, T1, op_rel_gt_pre> >
-  { static const bool value = true; };
-
-template<typename out_eT, typename T1>
-struct is_op_rel< mtOp<out_eT, T1, op_rel_gt_post> >
-  { static const bool value = true; };
-
-template<typename out_eT, typename T1>
-struct is_op_rel< mtOp<out_eT, T1, op_rel_lteq_pre> >
-  { static const bool value = true; };
-
-template<typename out_eT, typename T1>
-struct is_op_rel< mtOp<out_eT, T1, op_rel_lteq_post> >
-  { static const bool value = true; };
-
-template<typename out_eT, typename T1>
-struct is_op_rel< mtOp<out_eT, T1, op_rel_gteq_pre> >
-  { static const bool value = true; };
-
-template<typename out_eT, typename T1>
-struct is_op_rel< mtOp<out_eT, T1, op_rel_gteq_post> >
-  { static const bool value = true; };
-
-template<typename out_eT, typename T1>
-struct is_op_rel< mtOp<out_eT, T1, op_rel_eq> >
-  { static const bool value = true; };
-
-template<typename out_eT, typename T1>
-struct is_op_rel< mtOp<out_eT, T1, op_rel_noteq> >
-  { static const bool value = true; };
-
-
-
-//
-//
-//
-
-
-
-template<typename T1>
-struct is_arma_type
-  {
-  static const bool value
-  =  is_Mat<T1>::value
-  || is_Gen<T1>::value
-  || is_Op<T1>::value
-  || is_eOp<T1>::value
-  || is_mtOp<T1>::value
-  || is_Glue<T1>::value
-  || is_eGlue<T1>::value
-  || is_mtGlue<T1>::value
-  || is_subview<T1>::value
-  || is_diagview<T1>::value
-  ;
-  };
-
-
-
-template<typename T1>
-struct is_arma_cube_type
-  {
-  static const bool value
-  =  is_Cube<T1>::value
-  || is_GenCube<T1>::value
-  || is_OpCube<T1>::value
-  || is_eOpCube<T1>::value
-  || is_mtOpCube<T1>::value
-  || is_GlueCube<T1>::value
-  || is_eGlueCube<T1>::value
-  || is_mtGlueCube<T1>::value
-  || is_subview_cube<T1>::value
-  ;
-  };
-
-
-
-//
-//
-//
-
-
-template<typename T1, typename T2>
-struct is_same_type
-  { static const bool value = false; };
-
-
-template<typename T1>
-struct is_same_type<T1,T1>
-  { static const bool value = true; };
-
-
-
-//
-//
-//
-
-
-template<typename T1>
-struct is_u8
-  { static const bool value = false; };
-
-template<>
-struct is_u8<u8>
-  { static const bool value = true; };
-
-
-
-template<typename T1>
-struct is_s8
-  { static const bool value = false; };
-
-template<>
-struct is_s8<s8>
-  { static const bool value = true; };
-
-
-
-template<typename T1>
-struct is_u16
-  { static const bool value = false; };
-
-template<>
-struct is_u16<u16>
-  { static const bool value = true; };
-
-
-
-template<typename T1>
-struct is_s16
-  { static const bool value = false; };
-
-template<>
-struct is_s16<s16>
-  { static const bool value = true; };
-
-
-
-template<typename T1>
-struct is_u32
-  { static const bool value = false; };
-
-template<>
-struct is_u32<u32>
-  { static const bool value = true; };
-
-
-
-template<typename T1>
-struct is_s32
-  { static const bool value = false; };
-
-template<>
-struct is_s32<s32>
-  { static const bool value = true; };
-
-
-
-#if defined(ARMA_64BIT_WORD)
-  template<typename T1>
-  struct is_u64
-    { static const bool value = false; };
-
-  template<>
-  struct is_u64<u64>
-    { static const bool value = true; };
-  
-  
-  template<typename T1>
-  struct is_s64
-    { static const bool value = false; };
-
-  template<>
-  struct is_s64<s64>
-    { static const bool value = true; };
-#endif
-
-
-
-template<typename T1>
-struct is_uword
-  { static const bool value = false; };
-
-template<>
-struct is_uword<uword>
-  { static const bool value = true; };
-
-
-
-template<typename T1>
-struct is_sword
-  { static const bool value = false; };
-
-template<>
-struct is_sword<sword>
-  { static const bool value = true; };
-
-
-
-template<typename T1>
-struct is_float
-  { static const bool value = false; };
-
-template<>
-struct is_float<float>
-  { static const bool value = true; };
-
-
-
-template<typename T1>
-struct is_double
-  { static const bool value = false; };
-
-template<>
-struct is_double<double>
-  { static const bool value = true; };
-
-
-
-template<typename T1>
-struct is_complex
-  { static const bool value = false; };
-
-// template<>
-template<typename eT>
-struct is_complex< std::complex<eT> >
-  { static const bool value = true; };
-
-
-
-template<typename T1>
-struct is_complex_float
-  { static const bool value = false; };
-
-template<>
-struct is_complex_float< std::complex<float> >
-  { static const bool value = true; };
-
-
-
-template<typename T1>
-struct is_complex_double
-  { static const bool value = false; };
-
-template<>
-struct is_complex_double< std::complex<double> >
-  { static const bool value = true; };
-
-
-
-
-//! check for a weird implementation of the std::complex class
-template<typename T1>
-struct is_supported_complex
-  { static const bool value = false; };
-
-//template<>
-template<typename eT>
-struct is_supported_complex< std::complex<eT> >
-  { static const bool value = ( sizeof(std::complex<eT>) == 2*sizeof(eT) ); };
-
-
-
-template<typename T1>
-struct is_supported_complex_float
-  { static const bool value = false; };
-
-template<>
-struct is_supported_complex_float< std::complex<float> >
-  { static const bool value = ( sizeof(std::complex<float>) == 2*sizeof(float) ); };
-
-
-
-template<typename T1>
-struct is_supported_complex_double
-  { static const bool value = false; };
-
-template<>
-struct is_supported_complex_double< std::complex<double> >
-  { static const bool value = ( sizeof(std::complex<double>) == 2*sizeof(double) ); };
-
-
-
-template<typename T1>
-struct is_supported_elem_type
-  {
-  static const bool value = \
-    is_u8<T1>::value ||
-    is_s8<T1>::value ||
-    is_u16<T1>::value ||
-    is_s16<T1>::value ||
-    is_u32<T1>::value ||
-    is_s32<T1>::value ||
-#if defined(ARMA_64BIT_WORD)
-    is_u64<T1>::value ||
-    is_s64<T1>::value ||
-#endif
-    is_float<T1>::value ||
-    is_double<T1>::value ||
-    is_supported_complex_float<T1>::value ||
-    is_supported_complex_double<T1>::value;
-  };
-
-
-
-template<typename T1>
-struct is_supported_blas_type
-  {
-  static const bool value = \
-    is_float<T1>::value ||
-    is_double<T1>::value ||
-    is_supported_complex_float<T1>::value ||
-    is_supported_complex_double<T1>::value;
-  };
-
-
-
-template<typename T>
-struct is_signed
-  {
-  static const bool value = true;
-  };
-
-
-template<> struct is_signed<u8>  { static const bool value = false; };
-template<> struct is_signed<u16> { static const bool value = false; };
-template<> struct is_signed<u32> { static const bool value = false; };
-#if defined(ARMA_64BIT_WORD)
-template<> struct is_signed<u64> { static const bool value = false; };
-#endif
-
-
-template<typename T>
-struct is_non_integral
-  {
-  static const bool value = false;
-  };
-
-
-template<> struct is_non_integral<              float   > { static const bool value = true; };
-template<> struct is_non_integral<              double  > { static const bool value = true; };
-template<> struct is_non_integral< std::complex<float>  > { static const bool value = true; };
-template<> struct is_non_integral< std::complex<double> > { static const bool value = true; };
-
-
-
-
-//
-
-class arma_junk_class;
-
-template<typename T1, typename T2>
-struct force_different_type
-  {
-  typedef T1 T1_result;
-  typedef T2 T2_result;
-  };
-  
-
-template<typename T1>
-struct force_different_type<T1,T1>
-  {
-  typedef T1              T1_result;
-  typedef arma_junk_class T2_result;
-  };
-  
-  
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/typedef.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup typedef
-//! @{
-
-
-#if UCHAR_MAX >= 0xff
-  //! unsigned 8 bit type
-  typedef unsigned char u8;
-  typedef          char s8;
-#else
-  #error "don't know how to typedef 'u8' on this system"
-#endif
-
-// NOTE:
-// "signed char" is not the same as "char". 
-// http://www.embedded.com/columns/programmingpointers/206107018
-// http://en.wikipedia.org/wiki/C_variable_types_and_declarations
-
-
-#if USHRT_MAX >= 0xffff
-  //! unsigned 16 bit type  
-  typedef unsigned short u16;
-  typedef          short s16;
-#else
-  #error "don't know how to typedef 'u16' on this system"
-#endif
-
-
-#if   UINT_MAX  >= 0xffffffff
-  typedef unsigned int  u32;
-  typedef          int  s32;
-#elif ULONG_MAX >= 0xffffffff
-  typedef unsigned long u32;
-  typedef          long s32;
-#else
-  #error "don't know how to typedef 'u32' on this system"
-#endif
-
-
-#if defined(ARMA_64BIT_WORD)
-  #if    ULONG_MAX >= 0xffffffffffffffff
-    typedef unsigned long      u64;
-    typedef          long      s64;
-  #else
-    #if ULLONG_MAX >= 0xffffffffffffffff
-      typedef unsigned long long u64;
-      typedef          long long s64;
-    #else
-      #error "don't know how to typedef 'u64' on this system"
-    #endif
-  #endif
-#endif
-
-
-
-// // only supported by C++11, via #include <cstdint>, or by C99, via #include <stdint.h>
-// 
-// typedef  uint8_t u8;
-// typedef   int8_t s8;
-// 
-// typedef uint16_t u16;
-// typedef  int16_t s16;
-// 
-// typedef uint32_t u32;
-// typedef  int32_t s32;
-// 
-// typedef uint64_t u64;
-// typedef  int64_t s64;
-
-
-
-#if !defined(ARMA_64BIT_WORD)
-  typedef u32 uword;
-  typedef s32 sword;
-
-  typedef u16 uhword;
-  typedef s16 shword;
-  
-  #define ARMA_MAX_UWORD  0xffffffff
-  #define ARMA_MAX_UHWORD 0xffff
-#else
-  typedef u64 uword;
-  typedef s64 sword;
-  
-  typedef u32 uhword;
-  typedef s32 shword;
-
-  #define ARMA_MAX_UWORD  0xffffffffffffffff
-  #define ARMA_MAX_UHWORD 0xffffffff
-#endif
-
-
-
-typedef std::complex<float>  cx_float;
-typedef std::complex<double> cx_double;
-
-typedef Mat <unsigned char> uchar_mat;
-typedef Col <unsigned char> uchar_vec;
-typedef Col <unsigned char> uchar_colvec;
-typedef Row <unsigned char> uchar_rowvec;
-typedef Cube<unsigned char> uchar_cube;
-
-typedef Mat <u32> u32_mat;
-typedef Col <u32> u32_vec;
-typedef Col <u32> u32_colvec;
-typedef Row <u32> u32_rowvec;
-typedef Cube<u32> u32_cube;
-
-typedef Mat <s32> s32_mat;
-typedef Col <s32> s32_vec;
-typedef Col <s32> s32_colvec;
-typedef Row <s32> s32_rowvec;
-typedef Cube<s32> s32_cube;
-
-typedef Mat <uword> umat;
-typedef Col <uword> uvec;
-typedef Col <uword> ucolvec;
-typedef Row <uword> urowvec;
-typedef Cube<uword> ucube;
-
-typedef Mat <sword> imat;
-typedef Col <sword> ivec;
-typedef Col <sword> icolvec;
-typedef Row <sword> irowvec;
-typedef Cube<sword> icube;
-
-typedef Mat <float> fmat;
-typedef Col <float> fvec;
-typedef Col <float> fcolvec;
-typedef Row <float> frowvec;
-typedef Cube<float> fcube;
-
-typedef Mat <double> mat;
-typedef Col <double> vec;
-typedef Col <double> colvec;
-typedef Row <double> rowvec;
-typedef Cube<double> cube;
-
-typedef Mat <cx_float> cx_fmat;
-typedef Col <cx_float> cx_fvec;
-typedef Col <cx_float> cx_fcolvec;
-typedef Row <cx_float> cx_frowvec;
-typedef Cube<cx_float> cx_fcube;
-
-typedef Mat <cx_double> cx_mat;
-typedef Col <cx_double> cx_vec;
-typedef Col <cx_double> cx_colvec;
-typedef Row <cx_double> cx_rowvec;
-typedef Cube<cx_double> cx_cube;
-
-
-
-typedef void* void_ptr;
-
-
-
-namespace junk
-  {
-  struct arma_elem_size_test
-    {
-    
-    arma_static_check( (sizeof(u8) != 1), ERROR___TYPE_U8_HAS_UNSUPPORTED_SIZE );
-    arma_static_check( (sizeof(s8) != 1), ERROR___TYPE_S8_HAS_UNSUPPORTED_SIZE );
-    
-    arma_static_check( (sizeof(u16) != 2), ERROR___TYPE_U16_HAS_UNSUPPORTED_SIZE );
-    arma_static_check( (sizeof(s16) != 2), ERROR___TYPE_S16_HAS_UNSUPPORTED_SIZE );
-    
-    arma_static_check( (sizeof(u32) != 4), ERROR___TYPE_U32_HAS_UNSUPPORTED_SIZE );
-    arma_static_check( (sizeof(s32) != 4), ERROR___TYPE_S32_HAS_UNSUPPORTED_SIZE );
-    
-    #if defined(ARMA_64BIT_WORD)
-    arma_static_check( (sizeof(u64) != 8), ERROR___TYPE_U64_HAS_UNSUPPORTED_SIZE );
-    arma_static_check( (sizeof(s64) != 8), ERROR___TYPE_S64_HAS_UNSUPPORTED_SIZE );
-    #endif
-    
-    arma_static_check( (sizeof(float)  != 4), ERROR___TYPE_FLOAT_HAS_UNSUPPORTED_SIZE );
-    arma_static_check( (sizeof(double) != 8), ERROR___TYPE_DOUBLE_HAS_UNSUPPORTED_SIZE );
-    
-    arma_static_check( (sizeof(std::complex<float>)  != 8),  ERROR___TYPE_COMPLEX_FLOAT_HAS_UNSUPPORTED_SIZE );
-    arma_static_check( (sizeof(std::complex<double>) != 16), ERROR___TYPE_COMPLEX_DOUBLE_HAS_UNSUPPORTED_SIZE );
-    
-    };
-  }
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/typedef_blas_int.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-// Copyright (C) 2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup typedef
-//! @{
-
-
-#if   defined(ARMA_BLAS_LONG_LONG)
-  typedef long long blas_int;
-#elif defined(ARMA_BLAS_LONG)
-  typedef long      blas_int;
-#else
-  typedef int       blas_int;
-#endif
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/typedef_fixed.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,249 +0,0 @@
-// Copyright (C) 2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup typedef_fixed
-//! @{
-
-
-
-typedef umat::fixed<2,2> umat22;
-typedef umat::fixed<3,3> umat33;
-typedef umat::fixed<4,4> umat44;
-typedef umat::fixed<5,5> umat55;
-typedef umat::fixed<6,6> umat66;
-typedef umat::fixed<7,7> umat77;
-typedef umat::fixed<8,8> umat88;
-typedef umat::fixed<9,9> umat99;
-
-typedef imat::fixed<2,2> imat22;
-typedef imat::fixed<3,3> imat33;
-typedef imat::fixed<4,4> imat44;
-typedef imat::fixed<5,5> imat55;
-typedef imat::fixed<6,6> imat66;
-typedef imat::fixed<7,7> imat77;
-typedef imat::fixed<8,8> imat88;
-typedef imat::fixed<9,9> imat99;
-
-typedef fmat::fixed<2,2> fmat22;
-typedef fmat::fixed<3,3> fmat33;
-typedef fmat::fixed<4,4> fmat44;
-typedef fmat::fixed<5,5> fmat55;
-typedef fmat::fixed<6,6> fmat66;
-typedef fmat::fixed<7,7> fmat77;
-typedef fmat::fixed<8,8> fmat88;
-typedef fmat::fixed<9,9> fmat99;
-
-typedef mat::fixed<2,2> mat22;
-typedef mat::fixed<3,3> mat33;
-typedef mat::fixed<4,4> mat44;
-typedef mat::fixed<5,5> mat55;
-typedef mat::fixed<6,6> mat66;
-typedef mat::fixed<7,7> mat77;
-typedef mat::fixed<8,8> mat88;
-typedef mat::fixed<9,9> mat99;
-
-typedef cx_fmat::fixed<2,2> cx_fmat22;
-typedef cx_fmat::fixed<3,3> cx_fmat33;
-typedef cx_fmat::fixed<4,4> cx_fmat44;
-typedef cx_fmat::fixed<5,5> cx_fmat55;
-typedef cx_fmat::fixed<6,6> cx_fmat66;
-typedef cx_fmat::fixed<7,7> cx_fmat77;
-typedef cx_fmat::fixed<8,8> cx_fmat88;
-typedef cx_fmat::fixed<9,9> cx_fmat99;
-
-typedef cx_mat::fixed<2,2> cx_mat22;
-typedef cx_mat::fixed<3,3> cx_mat33;
-typedef cx_mat::fixed<4,4> cx_mat44;
-typedef cx_mat::fixed<5,5> cx_mat55;
-typedef cx_mat::fixed<6,6> cx_mat66;
-typedef cx_mat::fixed<7,7> cx_mat77;
-typedef cx_mat::fixed<8,8> cx_mat88;
-typedef cx_mat::fixed<9,9> cx_mat99;
-
-
-//
-
-
-typedef uvec::fixed<2> uvec2;
-typedef uvec::fixed<3> uvec3;
-typedef uvec::fixed<4> uvec4;
-typedef uvec::fixed<5> uvec5;
-typedef uvec::fixed<6> uvec6;
-typedef uvec::fixed<7> uvec7;
-typedef uvec::fixed<8> uvec8;
-typedef uvec::fixed<9> uvec9;
-
-typedef ivec::fixed<2> ivec2;
-typedef ivec::fixed<3> ivec3;
-typedef ivec::fixed<4> ivec4;
-typedef ivec::fixed<5> ivec5;
-typedef ivec::fixed<6> ivec6;
-typedef ivec::fixed<7> ivec7;
-typedef ivec::fixed<8> ivec8;
-typedef ivec::fixed<9> ivec9;
-
-typedef fvec::fixed<2> fvec2;
-typedef fvec::fixed<3> fvec3;
-typedef fvec::fixed<4> fvec4;
-typedef fvec::fixed<5> fvec5;
-typedef fvec::fixed<6> fvec6;
-typedef fvec::fixed<7> fvec7;
-typedef fvec::fixed<8> fvec8;
-typedef fvec::fixed<9> fvec9;
-
-typedef vec::fixed<2> vec2;
-typedef vec::fixed<3> vec3;
-typedef vec::fixed<4> vec4;
-typedef vec::fixed<5> vec5;
-typedef vec::fixed<6> vec6;
-typedef vec::fixed<7> vec7;
-typedef vec::fixed<8> vec8;
-typedef vec::fixed<9> vec9;
-
-typedef cx_fvec::fixed<2> cx_fvec2;
-typedef cx_fvec::fixed<3> cx_fvec3;
-typedef cx_fvec::fixed<4> cx_fvec4;
-typedef cx_fvec::fixed<5> cx_fvec5;
-typedef cx_fvec::fixed<6> cx_fvec6;
-typedef cx_fvec::fixed<7> cx_fvec7;
-typedef cx_fvec::fixed<8> cx_fvec8;
-typedef cx_fvec::fixed<9> cx_fvec9;
-
-typedef cx_vec::fixed<2> cx_vec2;
-typedef cx_vec::fixed<3> cx_vec3;
-typedef cx_vec::fixed<4> cx_vec4;
-typedef cx_vec::fixed<5> cx_vec5;
-typedef cx_vec::fixed<6> cx_vec6;
-typedef cx_vec::fixed<7> cx_vec7;
-typedef cx_vec::fixed<8> cx_vec8;
-typedef cx_vec::fixed<9> cx_vec9;
-
-
-//
-
-
-typedef ucolvec::fixed<2> ucolvec2;
-typedef ucolvec::fixed<3> ucolvec3;
-typedef ucolvec::fixed<4> ucolvec4;
-typedef ucolvec::fixed<5> ucolvec5;
-typedef ucolvec::fixed<6> ucolvec6;
-typedef ucolvec::fixed<7> ucolvec7;
-typedef ucolvec::fixed<8> ucolvec8;
-typedef ucolvec::fixed<9> ucolvec9;
-
-typedef icolvec::fixed<2> icolvec2;
-typedef icolvec::fixed<3> icolvec3;
-typedef icolvec::fixed<4> icolvec4;
-typedef icolvec::fixed<5> icolvec5;
-typedef icolvec::fixed<6> icolvec6;
-typedef icolvec::fixed<7> icolvec7;
-typedef icolvec::fixed<8> icolvec8;
-typedef icolvec::fixed<9> icolvec9;
-
-typedef fcolvec::fixed<2> fcolvec2;
-typedef fcolvec::fixed<3> fcolvec3;
-typedef fcolvec::fixed<4> fcolvec4;
-typedef fcolvec::fixed<5> fcolvec5;
-typedef fcolvec::fixed<6> fcolvec6;
-typedef fcolvec::fixed<7> fcolvec7;
-typedef fcolvec::fixed<8> fcolvec8;
-typedef fcolvec::fixed<9> fcolvec9;
-
-typedef colvec::fixed<2> colvec2;
-typedef colvec::fixed<3> colvec3;
-typedef colvec::fixed<4> colvec4;
-typedef colvec::fixed<5> colvec5;
-typedef colvec::fixed<6> colvec6;
-typedef colvec::fixed<7> colvec7;
-typedef colvec::fixed<8> colvec8;
-typedef colvec::fixed<9> colvec9;
-
-typedef cx_fcolvec::fixed<2> cx_fcolvec2;
-typedef cx_fcolvec::fixed<3> cx_fcolvec3;
-typedef cx_fcolvec::fixed<4> cx_fcolvec4;
-typedef cx_fcolvec::fixed<5> cx_fcolvec5;
-typedef cx_fcolvec::fixed<6> cx_fcolvec6;
-typedef cx_fcolvec::fixed<7> cx_fcolvec7;
-typedef cx_fcolvec::fixed<8> cx_fcolvec8;
-typedef cx_fcolvec::fixed<9> cx_fcolvec9;
-
-typedef cx_colvec::fixed<2> cx_colvec2;
-typedef cx_colvec::fixed<3> cx_colvec3;
-typedef cx_colvec::fixed<4> cx_colvec4;
-typedef cx_colvec::fixed<5> cx_colvec5;
-typedef cx_colvec::fixed<6> cx_colvec6;
-typedef cx_colvec::fixed<7> cx_colvec7;
-typedef cx_colvec::fixed<8> cx_colvec8;
-typedef cx_colvec::fixed<9> cx_colvec9;
-
-
-//
-
-
-typedef urowvec::fixed<2> urowvec2;
-typedef urowvec::fixed<3> urowvec3;
-typedef urowvec::fixed<4> urowvec4;
-typedef urowvec::fixed<5> urowvec5;
-typedef urowvec::fixed<6> urowvec6;
-typedef urowvec::fixed<7> urowvec7;
-typedef urowvec::fixed<8> urowvec8;
-typedef urowvec::fixed<9> urowvec9;
-
-typedef irowvec::fixed<2> irowvec2;
-typedef irowvec::fixed<3> irowvec3;
-typedef irowvec::fixed<4> irowvec4;
-typedef irowvec::fixed<5> irowvec5;
-typedef irowvec::fixed<6> irowvec6;
-typedef irowvec::fixed<7> irowvec7;
-typedef irowvec::fixed<8> irowvec8;
-typedef irowvec::fixed<9> irowvec9;
-
-typedef frowvec::fixed<2> frowvec2;
-typedef frowvec::fixed<3> frowvec3;
-typedef frowvec::fixed<4> frowvec4;
-typedef frowvec::fixed<5> frowvec5;
-typedef frowvec::fixed<6> frowvec6;
-typedef frowvec::fixed<7> frowvec7;
-typedef frowvec::fixed<8> frowvec8;
-typedef frowvec::fixed<9> frowvec9;
-
-typedef rowvec::fixed<2> rowvec2;
-typedef rowvec::fixed<3> rowvec3;
-typedef rowvec::fixed<4> rowvec4;
-typedef rowvec::fixed<5> rowvec5;
-typedef rowvec::fixed<6> rowvec6;
-typedef rowvec::fixed<7> rowvec7;
-typedef rowvec::fixed<8> rowvec8;
-typedef rowvec::fixed<9> rowvec9;
-
-typedef cx_frowvec::fixed<2> cx_frowvec2;
-typedef cx_frowvec::fixed<3> cx_frowvec3;
-typedef cx_frowvec::fixed<4> cx_frowvec4;
-typedef cx_frowvec::fixed<5> cx_frowvec5;
-typedef cx_frowvec::fixed<6> cx_frowvec6;
-typedef cx_frowvec::fixed<7> cx_frowvec7;
-typedef cx_frowvec::fixed<8> cx_frowvec8;
-typedef cx_frowvec::fixed<9> cx_frowvec9;
-
-typedef cx_rowvec::fixed<2> cx_rowvec2;
-typedef cx_rowvec::fixed<3> cx_rowvec3;
-typedef cx_rowvec::fixed<4> cx_rowvec4;
-typedef cx_rowvec::fixed<5> cx_rowvec5;
-typedef cx_rowvec::fixed<6> cx_rowvec6;
-typedef cx_rowvec::fixed<7> cx_rowvec7;
-typedef cx_rowvec::fixed<8> cx_rowvec8;
-typedef cx_rowvec::fixed<9> cx_rowvec9;
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/undefine_conflicts.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-
-#if defined(log2)
-  #undef log2
-  
-  #if defined(__GNUG__)
-    #warning         "detected 'log2' macro and undefined it"
-  #elif defined(_MSC_VER)
-    #pragma message ("detected 'log2' macro and undefined it")
-  #endif
-#endif
-
-
-
-// 
-// whoever defined macros with the names "min" and "max" should be permanently removed from the gene pool
-
-#if defined(min)
-  #undef min
-  
-  #if defined(__GNUG__)
-    #warning         "detected 'min' macro and undefined it; you may wish to define NOMINMAX before including any windows header"
-  #elif defined(_MSC_VER)
-    #pragma message ("detected 'min' macro and undefined it; you may wish to define NOMINMAX before including any windows header")
-  #endif
-#endif
-
-#if defined(max)
-  #undef max
-  
-  #if defined(__GNUG__)
-    #warning         "detected 'max' macro and undefined it; you may wish to define NOMINMAX before including any windows header"
-  #elif defined(_MSC_VER)
-    #pragma message ("detected 'max' macro and undefined it; you may wish to define NOMINMAX before including any windows header")
-  #endif
-#endif
-
--- a/armadillo-2.4.4/include/armadillo_bits/unwrap.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1483 +0,0 @@
-// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2011 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup unwrap
-//! @{
-
-
-
-template<typename T1>
-class unwrap
-  {
-  public:
-  
-  typedef typename T1::elem_type eT;
-  
-  inline unwrap(const T1& A)   // TODO: change this to Base ?
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  const Mat<eT> M;
-  };
-
-
-
-template<typename eT>
-class unwrap< Mat<eT> >
-  {
-  public:
-
-  inline unwrap(const Mat<eT>& A)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class unwrap< Row<eT> >
-  {
-  public:
-
-  inline unwrap(const Row<eT>& A)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-
-  const Row<eT>& M;
-  };
-
-
-
-template<typename eT>
-class unwrap< Col<eT> >
-  {
-  public:
-
-  inline unwrap(const Col<eT>& A)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-
-  const Col<eT>& M;
-  };
-
-
-
-template<typename out_eT, typename T1, typename T2, typename glue_type>
-class unwrap< mtGlue<out_eT, T1, T2, glue_type> >
-  {
-  public:
-  
-  inline unwrap(const mtGlue<out_eT, T1, T2, glue_type>& A)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  const Mat<out_eT> M;
-  };
-
-
-template<typename out_eT, typename T1, typename op_type>
-class unwrap< mtOp<out_eT, T1, op_type> >
-  {
-  public:
-  
-  inline unwrap(const mtOp<out_eT, T1, op_type>& A)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  const Mat<out_eT> M;
-  };
-
-
-
-//
-//
-//
-
-
-template<typename T1>
-class unwrap_check
-  {
-  public:
-  
-  typedef typename T1::elem_type eT;
-  
-  inline
-  unwrap_check(const T1& A, const Mat<eT>& B)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    arma_ignore(B);
-    }
-  
-  inline
-  ~unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  const Mat<eT> M;
-  };
-
-
-
-template<typename eT>
-class unwrap_check< Mat<eT> >
-  {
-  public:
-
-  inline
-  unwrap_check(const Mat<eT>& A, const Mat<eT>& B)
-    : M_local( (&A == &B) ? new Mat<eT>(A) : 0 )
-    , M      ( (&A == &B) ? (*M_local)     : A )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  // the order below is important
-  const Mat<eT>* M_local;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class unwrap_check< Row<eT> >
-  {
-  public:
-  
-  inline
-  unwrap_check(const Row<eT>& A, const Mat<eT>& B)
-    : M_local( (&A == reinterpret_cast<const Row<eT>*>(&B)) ? new Row<eT>(A) : 0 )
-    , M      ( (&A == reinterpret_cast<const Row<eT>*>(&B)) ? (*M_local)     : A )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  // the order below is important
-  const Row<eT>* M_local;
-  const Row<eT>& M;
-  };
-
-
-
-template<typename eT>
-class unwrap_check< Col<eT> >
-  {
-  public:
-
-  inline
-  unwrap_check(const Col<eT>& A, const Mat<eT>& B)
-    : M_local( (&A == reinterpret_cast<const Col<eT>*>(&B)) ? new Col<eT>(A) : 0 )
-    , M      ( (&A == reinterpret_cast<const Col<eT>*>(&B)) ? (*M_local)     : A )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  // the order below is important
-  const Col<eT>* M_local;
-  const Col<eT>& M;
-  
-  };
-
-
-
-//
-//
-//
-
-
-
-template<typename T1>
-class unwrap_check_mixed
-  {
-  public:
-  
-  typedef typename T1::elem_type eT1;
-  
-  template<typename eT2>
-  inline
-  unwrap_check_mixed(const T1& A, const Mat<eT2>& B)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    arma_ignore(B);
-    }
-  
-  inline
-  ~unwrap_check_mixed()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  const Mat<eT1> M;
-  };
-
-
-
-template<typename eT1>
-class unwrap_check_mixed< Mat<eT1> >
-  {
-  public:
-  
-  template<typename eT2>
-  inline
-  unwrap_check_mixed(const Mat<eT1>& A, const Mat<eT2>& B)
-    : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Mat<eT1>(A) : 0 )
-    , M      ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local)      : A )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~unwrap_check_mixed()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  // the order below is important
-  const Mat<eT1>* M_local;
-  const Mat<eT1>& M;
-  };
-
-
-
-template<typename eT1>
-class unwrap_check_mixed< Row<eT1> >
-  {
-  public:
-  
-  template<typename eT2>
-  inline
-  unwrap_check_mixed(const Row<eT1>& A, const Mat<eT2>& B)
-    : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Row<eT1>(A) : 0 )
-    , M      ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local)      : A )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~unwrap_check_mixed()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  // the order below is important
-  const Row<eT1>* M_local;
-  const Row<eT1>& M;
-  };
-
-
-
-template<typename eT1>
-class unwrap_check_mixed< Col<eT1> >
-  {
-  public:
-  
-  template<typename eT2>
-  inline
-  unwrap_check_mixed(const Col<eT1>& A, const Mat<eT2>& B)
-    : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Col<eT1>(A) : 0 )
-    , M      ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local)      : A )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~unwrap_check_mixed()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  // the order below is important
-  const Col<eT1>* M_local;
-  const Col<eT1>& M;
-  };
-
-
-
-//
-
-
-
-template<typename T1>
-class partial_unwrap
-  {
-  public:
-  
-  typedef typename T1::elem_type eT;
-  
-  inline partial_unwrap(const T1& A)  // TODO: change this to Base ?
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = false;
-  
-  const Mat<eT> M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap< Mat<eT> >
-  {
-  public:
-  
-  inline
-  partial_unwrap(const Mat<eT>& A)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = false;
-  
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap< Row<eT> >
-  {
-  public:
-  
-  inline
-  partial_unwrap(const Row<eT>& A)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = false;
-  
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap< Col<eT> >
-  {
-  public:
-  
-  inline
-  partial_unwrap(const Col<eT>& A)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = false;
-  
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename T1>
-class partial_unwrap< Op<T1, op_htrans> >
-  {
-  public:
-  
-  typedef typename T1::elem_type eT;
-  
-  inline
-  partial_unwrap(const Op<T1,op_htrans>& A)
-    : M(A.m)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = false;
-  
-  const Mat<eT> M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap< Op< Mat<eT>, op_htrans> >
-  {
-  public:
-  
-  inline
-  partial_unwrap(const Op< Mat<eT>, op_htrans>& A)
-    : M(A.m)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = false;
-  
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap< Op< Row<eT>, op_htrans> >
-  {
-  public:
-  
-  inline
-  partial_unwrap(const Op< Row<eT>, op_htrans>& A)
-    : M(A.m)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = false;
-  
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap< Op< Col<eT>, op_htrans> >
-  {
-  public:
-  
-  inline
-  partial_unwrap(const Op< Col<eT>, op_htrans>& A)
-    : M(A.m)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = false;
-  
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename T1>
-class partial_unwrap< Op<T1, op_htrans2> >
-  {
-  public:
-  
-  typedef typename T1::elem_type eT;
-  
-  inline
-  partial_unwrap(const Op<T1,op_htrans2>& A)
-    : val(A.aux)
-    , M  (A.m)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = true;
-  
-  const eT      val;
-  const Mat<eT> M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap< Op< Mat<eT>, op_htrans2> >
-  {
-  public:
-  
-  inline
-  partial_unwrap(const Op< Mat<eT>, op_htrans2>& A)
-    : val(A.aux)
-    , M  (A.m)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = true;
-  
-  const eT       val;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap< Op< Row<eT>, op_htrans2> >
-  {
-  public:
-  
-  inline
-  partial_unwrap(const Op< Row<eT>, op_htrans2>& A)
-    : val(A.aux)
-    , M  (A.m)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = true;
-  
-  const eT       val;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap< Op< Col<eT>, op_htrans2> >
-  {
-  public:
-  
-  inline
-  partial_unwrap(const Op< Col<eT>, op_htrans2>& A)
-    : val(A.aux)
-    , M  (A.m)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = true;
-  
-  const eT       val;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename T1>
-class partial_unwrap< eOp<T1, eop_scalar_times> >
-  {
-  public:
-  
-  typedef typename T1::elem_type eT;
-  
-  inline
-  partial_unwrap(const eOp<T1,eop_scalar_times>& A)
-    : val(A.aux)
-    , M  (A.P.Q)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = true;
-  
-  const eT      val;
-  const Mat<eT> M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap< eOp<Mat<eT>, eop_scalar_times> >
-  {
-  public:
-  
-  inline
-  partial_unwrap(const eOp<Mat<eT>,eop_scalar_times>& A)
-    : val(A.aux)
-    , M  (A.P.Q)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = true;
-  
-  const eT       val;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap< eOp<Row<eT>, eop_scalar_times> >
-  {
-  public:
-  
-  inline
-  partial_unwrap(const eOp<Row<eT>,eop_scalar_times>& A)
-    : val(A.aux)
-    , M  (A.P.Q)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = true;
-  
-  const eT       val;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap< eOp<Col<eT>, eop_scalar_times> >
-  {
-  public:
-  
-  inline
-  partial_unwrap(const eOp<Col<eT>,eop_scalar_times>& A)
-    : val(A.aux)
-    , M  (A.P.Q)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = true;
-  
-  const eT       val;
-  const Mat<eT>& M;
-  };
-
-
-
-//
-
-
-
-template<typename T1>
-class partial_unwrap_check
-  {
-  public:
-  
-  typedef typename T1::elem_type eT;
-  
-  inline partial_unwrap_check(const T1& A, const Mat<eT>& B)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    arma_ignore(B);
-    }
-  
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = false;
-  
-  const Mat<eT> M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap_check< Mat<eT> >
-  {
-  public:
-  
-  inline
-  partial_unwrap_check(const Mat<eT>& A, const Mat<eT>& B)
-    : M_local ( (&A == &B) ? new Mat<eT>(A) : 0 )
-    , M       ( (&A == &B) ? (*M_local)     : A )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = false;
-  
-  // the order below is important
-  const Mat<eT>* M_local;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap_check< Row<eT> >
-  {
-  public:
-  
-  inline
-  partial_unwrap_check(const Row<eT>& A, const Mat<eT>& B)
-    : M_local ( (&A == &B) ? new Mat<eT>(A) : 0 )
-    , M       ( (&A == &B) ? (*M_local)     : A )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = false;
-  
-  // the order below is important
-  const Mat<eT>* M_local;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap_check< Col<eT> >
-  {
-  public:
-  
-  inline
-  partial_unwrap_check(const Col<eT>& A, const Mat<eT>& B)
-    : M_local ( (&A == &B) ? new Mat<eT>(A) : 0 )
-    , M       ( (&A == &B) ? (*M_local)     : A )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = false;
-  
-  // the order below is important
-  const Mat<eT>* M_local;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename T1>
-class partial_unwrap_check< Op<T1, op_htrans> >
-  {
-  public:
-  
-  typedef typename T1::elem_type eT;
-  
-  inline
-  partial_unwrap_check(const Op<T1,op_htrans>& A, const Mat<eT>& B)
-    : M(A.m)
-    {
-    arma_extra_debug_sigprint();
-    arma_ignore(B);
-    }
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = false;
-  
-  const Mat<eT> M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap_check< Op< Mat<eT>, op_htrans> >
-  {
-  public:
-  
-  inline
-  partial_unwrap_check(const Op< Mat<eT>, op_htrans>& A, const Mat<eT>& B)
-    : M_local ( (&A.m == &B) ? new Mat<eT>(A.m) : 0   )
-    , M       ( (&A.m == &B) ? (*M_local)       : A.m )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = false;
-  
-  // the order below is important
-  const Mat<eT>* M_local;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap_check< Op< Row<eT>, op_htrans> >
-  {
-  public:
-  
-  inline
-  partial_unwrap_check(const Op< Row<eT>, op_htrans>& A, const Mat<eT>& B)
-    : M_local ( (&A.m == &B) ? new Mat<eT>(A.m) : 0   )
-    , M       ( (&A.m == &B) ? (*M_local)       : A.m )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = false;
-  
-  // the order below is important
-  const Mat<eT>* M_local;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap_check< Op< Col<eT>, op_htrans> >
-  {
-  public:
-  
-  inline
-  partial_unwrap_check(const Op< Col<eT>, op_htrans>& A, const Mat<eT>& B)
-    : M_local ( (&A.m == &B) ? new Mat<eT>(A.m) : 0   )
-    , M       ( (&A.m == &B) ? (*M_local)       : A.m )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  inline eT get_val() const { return eT(1); }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = false;
-  
-  // the order below is important
-  const Mat<eT>* M_local;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename T1>
-class partial_unwrap_check< Op<T1, op_htrans2> >
-  {
-  public:
-  
-  typedef typename T1::elem_type eT;
-  
-  inline
-  partial_unwrap_check(const Op<T1,op_htrans2>& A, const Mat<eT>& B)
-    : val(A.aux)
-    , M  (A.m)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = true;
-  
-  const eT      val;
-  const Mat<eT> M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap_check< Op< Mat<eT>, op_htrans2> >
-  {
-  public:
-  
-  inline
-  partial_unwrap_check(const Op< Mat<eT>, op_htrans2>& A, const Mat<eT>& B)
-    : val     (A.aux)
-    , M_local ( (&A.m == &B) ? new Mat<eT>(A.m) : 0   )
-    , M       ( (&A.m == &B) ? (*M_local)       : A.m )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = true;
-  
-  // the order below is important
-  const eT       val;
-  const Mat<eT>* M_local;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap_check< Op< Row<eT>, op_htrans2> >
-  {
-  public:
-  
-  inline
-  partial_unwrap_check(const Op< Row<eT>, op_htrans2>& A, const Mat<eT>& B)
-    : val     (A.aux)
-    , M_local ( (&A.m == &B) ? new Mat<eT>(A.m) : 0   )
-    , M       ( (&A.m == &B) ? (*M_local)       : A.m )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = true;
-  
-  // the order below is important
-  const eT       val;
-  const Mat<eT>* M_local;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap_check< Op< Col<eT>, op_htrans2> >
-  {
-  public:
-  
-  inline
-  partial_unwrap_check(const Op< Mat<eT>, op_htrans2>& A, const Mat<eT>& B)
-    : val     (A.aux)
-    , M_local ( (&A.m == &B) ? new Mat<eT>(A.m) : 0   )
-    , M       ( (&A.m == &B) ? (*M_local)       : A.m )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = true;
-  static const bool do_times = true;
-  
-  // the order below is important
-  const eT       val;
-  const Mat<eT>* M_local;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename T1>
-class partial_unwrap_check< eOp<T1, eop_scalar_times> >
-  {
-  public:
-  
-  typedef typename T1::elem_type eT;
-  
-  inline
-  partial_unwrap_check(const eOp<T1,eop_scalar_times>& A, const Mat<eT>& B)
-    : val(A.aux)
-    , M  (A.P.Q)
-    {
-    arma_extra_debug_sigprint();
-    arma_ignore(B);
-    }
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = true;
-  
-  const eT      val;
-  const Mat<eT> M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap_check< eOp<Mat<eT>, eop_scalar_times> >
-  {
-  public:
-  
-  inline
-  partial_unwrap_check(const eOp<Mat<eT>,eop_scalar_times>& A, const Mat<eT>& B)
-    : val(A.aux)
-    , M  (A.P.Q)
-    {
-    arma_extra_debug_sigprint();
-    arma_ignore(B);
-    }
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = true;
-  
-  const eT       val;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap_check< eOp<Row<eT>, eop_scalar_times> >
-  {
-  public:
-  
-  inline
-  partial_unwrap_check(const eOp<Row<eT>,eop_scalar_times>& A, const Mat<eT>& B)
-    : val(A.aux)
-    , M  (A.P.Q)
-    {
-    arma_extra_debug_sigprint();
-    arma_ignore(B);
-    }
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = true;
-  
-  const eT       val;
-  const Mat<eT>& M;
-  };
-
-
-
-template<typename eT>
-class partial_unwrap_check< eOp<Col<eT>, eop_scalar_times> >
-  {
-  public:
-  
-  inline
-  partial_unwrap_check(const eOp<Col<eT>,eop_scalar_times>& A, const Mat<eT>& B)
-    : val(A.aux)
-    , M  (A.P.Q)
-    {
-    arma_extra_debug_sigprint();
-    arma_ignore(B);
-    }
-  
-  inline
-  ~partial_unwrap_check()
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline eT get_val() const { return val; }
-  
-  
-  static const bool do_trans = false;
-  static const bool do_times = true;
-  
-  const eT       val;
-  const Mat<eT>& M;
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/unwrap_cube.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup unwrap_cube
-//! @{
-
-
-
-template<typename T1>
-class unwrap_cube
-  {
-  public:
-  
-  typedef typename T1::elem_type eT;
-  
-  inline
-  unwrap_cube(const T1& A)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  const Cube<eT> M;
-  };
-
-
-
-template<typename eT>
-class unwrap_cube< Cube<eT> >
-  {
-  public:
-
-  inline
-  unwrap_cube(const Cube<eT>& A)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    }
-
-  const Cube<eT>& M;
-  };
-
-
-
-//
-//
-//
-
-
-
-template<typename T1>
-class unwrap_cube_check
-  {
-  typedef typename T1::elem_type eT;
-  
-  inline
-  unwrap_cube_check(const T1& A, const Cube<eT>& B)
-    : M(A)
-    {
-    arma_extra_debug_sigprint();
-    
-    arma_type_check(( is_arma_cube_type<T1>::value == false ));
-    }
-  
-  const Cube<eT> M;
-  };
-
-
-
-template<typename eT>
-class unwrap_cube_check< Cube<eT> >
-  {
-  public:
-
-  inline
-  unwrap_cube_check(const Cube<eT>& A, const Cube<eT>& B)
-    : M_local( (&A == &B) ? new Cube<eT>(A) : 0 )
-    , M      ( (&A == &B) ? (*M_local)      : A )
-    {
-    arma_extra_debug_sigprint();
-    }
-  
-  
-  inline
-  ~unwrap_cube_check()
-    {
-    arma_extra_debug_sigprint();
-    
-    if(M_local)
-      {
-      delete M_local;
-      }
-    }
-  
-  
-  // the order below is important
-  const Cube<eT>* M_local;
-  const Cube<eT>& M;
-  
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/upgrade_val.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
-// Copyright (C) 2009-2010 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup upgrade_val
-//! @{
-
-
-
-//! upgrade_val is used to ensure an operation such as multiplication is possible between two types.
-//! values are upgraded only where necessary.
-
-template<typename T1, typename T2>
-struct upgrade_val
-  {
-  typedef typename promote_type<T1,T2>::result T1_result;
-  typedef typename promote_type<T1,T2>::result T2_result;
-  
-  arma_inline
-  static
-  typename promote_type<T1,T2>::result
-  apply(const T1 x)
-    {
-    typedef typename promote_type<T1,T2>::result out_type;
-    return out_type(x);
-    }
-  
-  arma_inline
-  static
-  typename promote_type<T1,T2>::result
-  apply(const T2 x)
-    {
-    typedef typename promote_type<T1,T2>::result out_type;
-    return out_type(x);
-    }
-  
-  };
-
-
-// template<>
-template<typename T>
-struct upgrade_val<T,T>
-  {
-  typedef T T1_result;
-  typedef T T2_result;
-  
-  arma_inline static const T& apply(const T& x) { return x; }
-  };
-
-
-//! upgrade a type to allow multiplication with a complex type
-//! e.g. the int in "int * complex<double>" is upgraded to a double
-// template<>
-template<typename T, typename T2>
-struct upgrade_val< std::complex<T>, T2 >
-  {
-  typedef std::complex<T> T1_result;
-  typedef T               T2_result;
-  
-  arma_inline static const std::complex<T>& apply(const std::complex<T>& x) { return x;    }
-  arma_inline static       T                apply(const T2 x)               { return T(x); }
-  };
-
-
-// template<>
-template<typename T1, typename T>
-struct upgrade_val< T1, std::complex<T> >
-  {
-  typedef T               T1_result;
-  typedef std::complex<T> T2_result;
-  
-  arma_inline static       T                apply(const T1 x)               { return T(x); }
-  arma_inline static const std::complex<T>& apply(const std::complex<T>& x) { return x;    }
-  };
-
-
-//! ensure we don't lose precision when multiplying a complex number with a higher precision real number
-template<>
-struct upgrade_val< std::complex<float>, double >
-  {
-  typedef std::complex<double> T1_result;
-  typedef double               T2_result;
-  
-  arma_inline static const std::complex<double> apply(const std::complex<float>& x) { return std::complex<double>(x); }
-  arma_inline static       double               apply(const double x)               { return x; }
-  };
-
-
-template<>
-struct upgrade_val< double, std::complex<float> >
-  {
-  typedef double              T1_result;
-  typedef std::complex<float> T2_result;
-  
-  arma_inline static       double               apply(const double x)               { return x; }
-  arma_inline static const std::complex<double> apply(const std::complex<float>& x) { return std::complex<double>(x); }
-  };
-
-
-//! ensure we don't lose precision when multiplying complex numbers with different underlying types
-template<>
-struct upgrade_val< std::complex<float>, std::complex<double> >
-  {
-  typedef std::complex<double> T1_result;
-  typedef std::complex<double> T2_result;
-  
-  arma_inline static const std::complex<double>  apply(const std::complex<float>&  x) { return std::complex<double>(x); }
-  arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
-  };
-
-
-template<>
-struct upgrade_val< std::complex<double>, std::complex<float> >
-  {
-  typedef std::complex<double> T1_result;
-  typedef std::complex<double> T2_result;
-  
-  arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
-  arma_inline static const std::complex<double>  apply(const std::complex<float>&  x) { return std::complex<double>(x); }
-  };
-
-
-//! work around limitations in the complex class (at least as present in gcc 4.1 & 4.3)
-template<>
-struct upgrade_val< std::complex<double>, float >
-  {
-  typedef std::complex<double> T1_result;
-  typedef double               T2_result;
-  
-  arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
-  arma_inline static       double                apply(const float x)                 { return double(x); }
-  };
-
-
-template<>
-struct upgrade_val< float, std::complex<double> >
-  {
-  typedef double               T1_result;
-  typedef std::complex<double> T2_result;
-  
-  arma_inline static       double                apply(const float x)                 { return double(x); }
-  arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
-  };
-
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/wall_clock_bones.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2012 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup wall_clock
-//! @{
-
-
-//! Class for measuring time intervals
-class wall_clock
-  {
-  public:
-  
-  inline  wall_clock();
-  inline ~wall_clock();
-  
-  inline void   tic();  //!< start the timer
-  inline double toc();  //!< return the number of seconds since the last call to tic()
-  
-  
-  private:
-  
-  bool valid;
-  
-  #if defined(ARMA_USE_BOOST_DATE)
-    boost::posix_time::ptime         boost_time1;
-    boost::posix_time::time_duration boost_duration;
-  #elif defined(ARMA_HAVE_GETTIMEOFDAY)
-    struct timeval posix_time1;
-    struct timeval posix_time2;
-  #else
-    clock_t time1;
-  #endif
-  
-  };
-
-
-//! @}
--- a/armadillo-2.4.4/include/armadillo_bits/wall_clock_meat.hpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
-// Copyright (C) 2008-2012 Conrad Sanderson
-// 
-// This file is part of the Armadillo C++ library.
-// It is provided without any warranty of fitness
-// for any purpose. You can redistribute this file
-// and/or modify it under the terms of the GNU
-// Lesser General Public License (LGPL) as published
-// by the Free Software Foundation, either version 3
-// of the License or (at your option) any later version.
-// (see http://www.opensource.org/licenses for more info)
-
-
-//! \addtogroup wall_clock
-//! @{
-
-
-inline
-wall_clock::wall_clock()
-  : valid(false)
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-inline
-wall_clock::~wall_clock()
-  {
-  arma_extra_debug_sigprint();
-  }
-
-
-
-inline
-void
-wall_clock::tic()
-  {
-  arma_extra_debug_sigprint();
-  
-  #if defined(ARMA_USE_BOOST_DATE)
-    {
-    boost_time1 = boost::posix_time::microsec_clock::local_time();
-    valid = true;
-    }
-  #elif defined(ARMA_HAVE_GETTIMEOFDAY)
-    {
-    gettimeofday(&posix_time1, 0);
-    valid = true;
-    }
-  #else
-    {
-    time1 = clock();
-    valid = true;
-    }
-  #endif
-  }
-
-
-
-inline
-double
-wall_clock::toc()
-  {
-  arma_extra_debug_sigprint();
-  
-  if(valid)
-    {
-    #if defined(ARMA_USE_BOOST_DATE)
-      {
-      boost_duration = boost::posix_time::microsec_clock::local_time() - boost_time1;
-      return boost_duration.total_microseconds() * 1e-6;
-      }
-    #elif defined(ARMA_HAVE_GETTIMEOFDAY)
-      {
-      gettimeofday(&posix_time2, 0);
-      
-      const double tmp_time1 = posix_time1.tv_sec + posix_time1.tv_usec * 1.0e-6;
-      const double tmp_time2 = posix_time2.tv_sec + posix_time2.tv_usec * 1.0e-6;
-      
-      return tmp_time2 - tmp_time1;
-      }
-    #else
-      {
-      clock_t time2 = clock();
-      
-      clock_t diff = time2 - time1;
-      
-      return double(diff) / double(CLOCKS_PER_SEC);
-      }
-    #endif
-    }
-  else
-    {  
-    return 0.0;
-    }
-  }
-
-
-
-//! @}
-
--- a/armadillo-2.4.4/include/armadillo_itpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-//
-// !WARNING!
-//
-// As IT++ 4.0 is licensed under the terms of General Public
-// License (GPL) without any exception, including this file
-// will necessairly cause your work to be covered by the GPL.
-// If you do not wish for this to happen, do not include this
-// file.
-
-
-#define ARMA_USE_ITPP
-
-#include <armadillo>
-  
--- a/armadillo-2.4.4/index.html	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<html>
-<body>
-<ul>
-<li><a href="README.txt">README.txt</a></li>
-<li><a href="LICENSE.txt">LICENSE.txt</a></li>
-<li><a href="docs/armadillo_nicta_2010.pdf">docs/armadillo_nicta_2010.pdf</a></li>
-<li><a href="docs/index.html">docs/index.html</a></li>
-</ul>
-</body>
-</html>
--- a/armadillo-2.4.4/licenses/GPL.txt	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,674 +0,0 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
--- a/armadillo-2.4.4/licenses/LGPL.txt	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-		   GNU LESSER GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
-  This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
-  0. Additional Definitions. 
-
-  As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
-  "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
-  An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
-  A "Combined Work" is a work produced by combining or linking an
-Application with the Library.  The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
-  The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
-  The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
-  1. Exception to Section 3 of the GNU GPL.
-
-  You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
-  2. Conveying Modified Versions.
-
-  If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
-   a) under this License, provided that you make a good faith effort to
-   ensure that, in the event an Application does not supply the
-   function or data, the facility still operates, and performs
-   whatever part of its purpose remains meaningful, or
-
-   b) under the GNU GPL, with none of the additional permissions of
-   this License applicable to that copy.
-
-  3. Object Code Incorporating Material from Library Header Files.
-
-  The object code form of an Application may incorporate material from
-a header file that is part of the Library.  You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
-   a) Give prominent notice with each copy of the object code that the
-   Library is used in it and that the Library and its use are
-   covered by this License.
-
-   b) Accompany the object code with a copy of the GNU GPL and this license
-   document.
-
-  4. Combined Works.
-
-  You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
-   a) Give prominent notice with each copy of the Combined Work that
-   the Library is used in it and that the Library and its use are
-   covered by this License.
-
-   b) Accompany the Combined Work with a copy of the GNU GPL and this license
-   document.
-
-   c) For a Combined Work that displays copyright notices during
-   execution, include the copyright notice for the Library among
-   these notices, as well as a reference directing the user to the
-   copies of the GNU GPL and this license document.
-
-   d) Do one of the following:
-
-       0) Convey the Minimal Corresponding Source under the terms of this
-       License, and the Corresponding Application Code in a form
-       suitable for, and under terms that permit, the user to
-       recombine or relink the Application with a modified version of
-       the Linked Version to produce a modified Combined Work, in the
-       manner specified by section 6 of the GNU GPL for conveying
-       Corresponding Source.
-
-       1) Use a suitable shared library mechanism for linking with the
-       Library.  A suitable mechanism is one that (a) uses at run time
-       a copy of the Library already present on the user's computer
-       system, and (b) will operate properly with a modified version
-       of the Library that is interface-compatible with the Linked
-       Version. 
-
-   e) Provide Installation Information, but only if you would otherwise
-   be required to provide such information under section 6 of the
-   GNU GPL, and only to the extent that such information is
-   necessary to install and execute a modified version of the
-   Combined Work produced by recombining or relinking the
-   Application with a modified version of the Linked Version. (If
-   you use option 4d0, the Installation Information must accompany
-   the Minimal Corresponding Source and Corresponding Application
-   Code. If you use option 4d1, you must provide the Installation
-   Information in the manner specified by section 6 of the GNU GPL
-   for conveying Corresponding Source.)
-
-  5. Combined Libraries.
-
-  You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
-   a) Accompany the combined library with a copy of the same work based
-   on the Library, uncombined with any other library facilities,
-   conveyed under the terms of this License.
-
-   b) Give prominent notice with the combined library that part of it
-   is a work based on the Library, and explaining where to find the
-   accompanying uncombined form of the same work.
-
-  6. Revised Versions of the GNU Lesser General Public License.
-
-  The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
-  Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
-  If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
--- a/armadillo-2.4.4/src/wrap_libs.cpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,623 +0,0 @@
-#include "armadillo_bits/config.hpp"
-#include "armadillo_bits/typedef_blas_int.hpp"
-
-#undef ARMA_USE_WRAPPER
-#include "armadillo_bits/compiler_setup.hpp"
-
-#include "armadillo_bits/undefine_conflicts.hpp"
-#include "armadillo_bits/include_atlas.hpp"
-
-
-namespace arma
-{
-
-#include "armadillo_bits/blas_bones.hpp"
-#include "armadillo_bits/lapack_bones.hpp"
-
-// at this stage we have prototypes for the real blas, lapack and atlas functions
-
-// now we make the wrapper functions
-
-
-extern "C"
-  {
-  #if defined(ARMA_USE_BLAS)
-    
-    float arma_fortran_prefix(arma_sdot)(blas_int* n, const float*  x, blas_int* incx, const float*  y, blas_int* incy)
-      {
-      return arma_fortran_noprefix(arma_sdot)(n, x, incx, y, incy);
-      }
-    
-    double arma_fortran_prefix(arma_ddot)(blas_int* n, const double* x, blas_int* incx, const double* y, blas_int* incy)
-      {
-      return arma_fortran_noprefix(arma_ddot)(n, x, incx, y, incy);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_sgemv)(const char* transA, const blas_int* m, const blas_int* n, const float*  alpha, const float*  A, const blas_int* ldA, const float*  x, const blas_int* incx, const float*  beta, float*  y, const blas_int* incy)
-      {
-      arma_fortran_noprefix(arma_sgemv)(transA, m, n, alpha, A, ldA, x, incx, beta, y, incy);
-      }
-    
-    void arma_fortran_prefix(arma_dgemv)(const char* transA, const blas_int* m, const blas_int* n, const double* alpha, const double* A, const blas_int* ldA, const double* x, const blas_int* incx, const double* beta, double* y, const blas_int* incy)
-      {
-      arma_fortran_noprefix(arma_dgemv)(transA, m, n, alpha, A, ldA, x, incx, beta, y, incy);
-      }
-    
-    void arma_fortran_prefix(arma_cgemv)(const char* transA, const blas_int* m, const blas_int* n, const void*   alpha, const void*   A, const blas_int* ldA, const void*   x, const blas_int* incx, const void*   beta, void*   y, const blas_int* incy)
-      {
-      arma_fortran_noprefix(arma_cgemv)(transA, m, n, alpha, A, ldA, x, incx, beta, y, incy);
-      }
-    
-    void arma_fortran_prefix(arma_zgemv)(const char* transA, const blas_int* m, const blas_int* n, const void*   alpha, const void*   A, const blas_int* ldA, const void*   x, const blas_int* incx, const void*   beta, void*   y, const blas_int* incy)
-      {
-      arma_fortran_noprefix(arma_zgemv)(transA, m, n, alpha, A, ldA, x, incx, beta, y, incy);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_sgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const float*  alpha, const float*  A, const blas_int* ldA, const float*  B, const blas_int* ldB, const float*  beta, float*  C, const blas_int* ldC)
-      {
-      arma_fortran_noprefix(arma_sgemm)(transA, transB, m, n, k, alpha, A, ldA, B, ldB, beta, C, ldC);
-      }
-    
-    void arma_fortran_prefix(arma_dgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const double* alpha, const double* A, const blas_int* ldA, const double* B, const blas_int* ldB, const double* beta, double* C, const blas_int* ldC)
-      {
-      arma_fortran_noprefix(arma_dgemm)(transA, transB, m, n, k, alpha, A, ldA, B, ldB, beta, C, ldC);
-      }
-    
-    void arma_fortran_prefix(arma_cgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const void*   alpha, const void*   A, const blas_int* ldA, const void*   B, const blas_int* ldB, const void*   beta, void*   C, const blas_int* ldC)
-      {
-      arma_fortran_noprefix(arma_cgemm)(transA, transB, m, n, k, alpha, A, ldA, B, ldB, beta, C, ldC);
-      }
-    
-    void arma_fortran_prefix(arma_zgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const void*   alpha, const void*   A, const blas_int* ldA, const void*   B, const blas_int* ldB, const void*   beta, void*   C, const blas_int* ldC)
-      {
-      arma_fortran_noprefix(arma_zgemm)(transA, transB, m, n, k, alpha, A, ldA, B, ldB, beta, C, ldC);
-      }
-    
-  #endif
-  
-  
-  
-  #if defined(ARMA_USE_LAPACK)
-    
-    void arma_fortran_prefix(arma_sgetrf)(blas_int* m, blas_int* n,  float* a, blas_int* lda, blas_int* ipiv, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_sgetrf)(m, n, a, lda, ipiv, info);
-      }
-    
-    void arma_fortran_prefix(arma_dgetrf)(blas_int* m, blas_int* n, double* a, blas_int* lda, blas_int* ipiv, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dgetrf)(m, n, a, lda, ipiv, info);
-      }
-
-    void arma_fortran_prefix(arma_cgetrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda, blas_int* ipiv, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_cgetrf)(m, n, a, lda, ipiv, info);
-      }
-    
-    void arma_fortran_prefix(arma_zgetrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda, blas_int* ipiv, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zgetrf)(m, n, a, lda, ipiv, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_sgetri)(blas_int* n,  float* a, blas_int* lda, blas_int* ipiv,  float* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_sgetri)(n, a, lda, ipiv, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_dgetri)(blas_int* n, double* a, blas_int* lda, blas_int* ipiv, double* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dgetri)(n, a, lda, ipiv, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_cgetri)(blas_int* n,  void*  a, blas_int* lda, blas_int* ipiv,   void* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_cgetri)(n, a, lda, ipiv, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_zgetri)(blas_int* n,  void*  a, blas_int* lda, blas_int* ipiv,   void* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zgetri)(n, a, lda, ipiv, work, lwork, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_strtri)(char* uplo, char* diag, blas_int* n,  float* a, blas_int* lda, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_strtri)(uplo, diag, n, a, lda, info);
-      }
-    
-    void arma_fortran_prefix(arma_dtrtri)(char* uplo, char* diag, blas_int* n, double* a, blas_int* lda, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dtrtri)(uplo, diag, n, a, lda, info);
-      }
-    
-    void arma_fortran_prefix(arma_ctrtri)(char* uplo, char* diag, blas_int* n,   void* a, blas_int* lda, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_ctrtri)(uplo, diag, n, a, lda, info);
-      }
-    
-    void arma_fortran_prefix(arma_ztrtri)(char* uplo, char* diag, blas_int* n,   void* a, blas_int* lda, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_ztrtri)(uplo, diag, n, a, lda, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_ssyev)(char* jobz, char* uplo, blas_int* n,  float* a, blas_int* lda,  float* w,  float* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_ssyev)(jobz, uplo, n, a, lda, w, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_dsyev)(char* jobz, char* uplo, blas_int* n, double* a, blas_int* lda, double* w, double* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dsyev)(jobz, uplo, n, a, lda, w, work, lwork, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_cheev)(char* jobz, char* uplo, blas_int* n,   void* a, blas_int* lda,  float* w,   void* work, blas_int* lwork,  float* rwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_cheev)(jobz, uplo, n, a, lda, w, work, lwork, rwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_zheev)(char* jobz, char* uplo, blas_int* n,   void* a, blas_int* lda, double* w,   void* work, blas_int* lwork, double* rwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zheev)(jobz, uplo, n, a, lda, w, work, lwork, rwork, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_sgeev)(char* jobvl, char* jobvr, blas_int* n,  float* a, blas_int* lda,  float* wr,  float* wi,  float* vl, blas_int* ldvl,  float* vr, blas_int* ldvr,  float* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_sgeev)(jobvl, jobvr, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_dgeev)(char* jobvl, char* jobvr, blas_int* n, double* a, blas_int* lda, double* wr, double* wi, double* vl, blas_int* ldvl, double* vr, blas_int* ldvr, double* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dgeev)(jobvl, jobvr, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_cgeev)(char* jobvl, char* jobvr, blas_int* n, void* a, blas_int* lda, void* w, void* vl, blas_int* ldvl, void* vr, blas_int* ldvr, void* work, blas_int* lwork,  float* rwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_cgeev)(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_zgeev)(char* jobvl, char* jobvr, blas_int* n, void* a, blas_int* lda, void* w, void* vl, blas_int* ldvl, void* vr, blas_int* ldvr, void* work, blas_int* lwork, double* rwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zgeev)(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_spotrf)(char* uplo, blas_int* n,  float* a, blas_int* lda, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_spotrf)(uplo, n, a, lda, info);
-      }
-    
-    void arma_fortran_prefix(arma_dpotrf)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dpotrf)(uplo, n, a, lda, info);
-      }
-    
-    void arma_fortran_prefix(arma_cpotrf)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_cpotrf)(uplo, n, a, lda, info);
-      }
-    
-    void arma_fortran_prefix(arma_zpotrf)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zpotrf)(uplo, n, a, lda, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_spotri)(char* uplo, blas_int* n,  float* a, blas_int* lda, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_spotri)(uplo, n, a, lda, info);
-      }
-    
-    void arma_fortran_prefix(arma_dpotri)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dpotri)(uplo, n, a, lda, info);
-      }
-    
-    void arma_fortran_prefix(arma_cpotri)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_cpotri)(uplo, n, a, lda, info);
-      }
-    
-    void arma_fortran_prefix(arma_zpotri)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zpotri)(uplo, n, a, lda, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_sgeqrf)(blas_int* m, blas_int* n,  float* a, blas_int* lda,  float* tau,  float* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_sgeqrf)(m, n, a, lda, tau, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_dgeqrf)(blas_int* m, blas_int* n, double* a, blas_int* lda, double* tau, double* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dgeqrf)(m, n, a, lda, tau, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_cgeqrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_cgeqrf)(m, n, a, lda, tau, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_zgeqrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zgeqrf)(m, n, a, lda, tau, work, lwork, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_sorgqr)(blas_int* m, blas_int* n, blas_int* k,  float* a, blas_int* lda,  float* tau,  float* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_sorgqr)(m, n, k, a, lda, tau, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_dorgqr)(blas_int* m, blas_int* n, blas_int* k, double* a, blas_int* lda, double* tau, double* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dorgqr)(m, n, k, a, lda, tau, work, lwork, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_cungqr)(blas_int* m, blas_int* n, blas_int* k,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_cungqr)(m, n, k, a, lda, tau, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_zungqr)(blas_int* m, blas_int* n, blas_int* k,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zungqr)(m, n, k, a, lda, tau, work, lwork, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_sgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, float*  a, blas_int* lda, float*  s, float*  u, blas_int* ldu, float*  vt, blas_int* ldvt, float*  work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_sgesvd)(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_dgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, double* a, blas_int* lda, double* s, double* u, blas_int* ldu, double* vt, blas_int* ldvt, double* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dgesvd)(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_cgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, void*   a, blas_int* lda, float*  s, void*   u, blas_int* ldu, void*   vt, blas_int* ldvt, void*   work, blas_int* lwork, float*  rwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_cgesvd)(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_zgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, void*   a, blas_int* lda, double* s, void*   u, blas_int* ldu, void*   vt, blas_int* ldvt, void*   work, blas_int* lwork, double* rwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zgesvd)(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_sgesv)(blas_int* n, blas_int* nrhs, float*  a, blas_int* lda, blas_int* ipiv, float*  b, blas_int* ldb, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_sgesv)(n, nrhs, a, lda, ipiv, b, ldb, info);
-      }
-    
-    void arma_fortran_prefix(arma_dgesv)(blas_int* n, blas_int* nrhs, double* a, blas_int* lda, blas_int* ipiv, double* b, blas_int* ldb, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dgesv)(n, nrhs, a, lda, ipiv, b, ldb, info);
-      }
-    
-    void arma_fortran_prefix(arma_cgesv)(blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, blas_int* ipiv, void*   b, blas_int* ldb, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_cgesv)(n, nrhs, a, lda, ipiv, b, ldb, info);
-      }
-    
-    void arma_fortran_prefix(arma_zgesv)(blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, blas_int* ipiv, void*   b, blas_int* ldb, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zgesv)(n, nrhs, a, lda, ipiv, b, ldb, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_sgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, float*  a, blas_int* lda, float*  b, blas_int* ldb, float*  work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_sgels)(trans, m, n, nrhs, a, lda, b, ldb, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_dgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, double* a, blas_int* lda, double* b, blas_int* ldb, double* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dgels)(trans, m, n, nrhs, a, lda, b, ldb, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_cgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, void*   b, blas_int* ldb, void*   work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_cgels)(trans, m, n, nrhs, a, lda, b, ldb, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_zgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, void*   b, blas_int* ldb, void*   work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zgels)(trans, m, n, nrhs, a, lda, b, ldb, work, lwork, info);
-      }
-    
-    
-    
-    
-    void arma_fortran_prefix(arma_strtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const float*  a, blas_int* lda, float*  b, blas_int* ldb, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_strtrs)(uplo, trans, diag, n, nrhs, a, lda, b, ldb, info);
-      }
-    
-    void arma_fortran_prefix(arma_dtrtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const double* a, blas_int* lda, double* b, blas_int* ldb, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dtrtrs)(uplo, trans, diag, n, nrhs, a, lda, b, ldb, info);
-      }
-    
-    void arma_fortran_prefix(arma_ctrtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const void*   a, blas_int* lda, void*   b, blas_int* ldb, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_ctrtrs)(uplo, trans, diag, n, nrhs, a, lda, b, ldb, info);
-      }
-    
-    void arma_fortran_prefix(arma_ztrtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const void*   a, blas_int* lda, void*   b, blas_int* ldb, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_ztrtrs)(uplo, trans, diag, n, nrhs, a, lda, b, ldb, info);
-      }
-    
-    
-    
-    
-    void arma_fortran_prefix(arma_sgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, float*  a, blas_int* lda, blas_int* sdim, float*  wr, float*  wi, float*  vs, blas_int* ldvs, float*  work, blas_int* lwork, blas_int* bwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_sgees)(jobvs, sort, select, n, a, lda, sdim, wr, wi, vs, ldvs, work, lwork, bwork, info);
-      }
-      
-    void arma_fortran_prefix(arma_dgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, double* a, blas_int* lda, blas_int* sdim, double* wr, double* wi, double* vs, blas_int* ldvs, double* work, blas_int* lwork, blas_int* bwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dgees)(jobvs, sort, select, n, a, lda, sdim, wr, wi, vs, ldvs, work, lwork, bwork, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_cgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, void* a, blas_int* lda, blas_int* sdim, void* w, void* vs, blas_int* ldvs, void* work, blas_int* lwork, float*  rwork, blas_int* bwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_cgees)(jobvs, sort, select, n, a, lda, sdim, w, vs, ldvs, work, lwork, rwork, bwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_zgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, void* a, blas_int* lda, blas_int* sdim, void* w, void* vs, blas_int* ldvs, void* work, blas_int* lwork, double* rwork, blas_int* bwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zgees)(jobvs, sort, select, n, a, lda, sdim, w, vs, ldvs, work, lwork, rwork, bwork, info);
-      }
-    
-    
-    
-    void arma_fortran_prefix(arma_strsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const float*  a, blas_int* lda, const float*  b, blas_int* ldb, float*  c, blas_int* ldc, float*  scale, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_strsyl)(transa, transb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, info);
-      }
-    
-    void arma_fortran_prefix(arma_dtrsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const double* a, blas_int* lda, const double* b, blas_int* ldb, double* c, blas_int* ldc, double* scale, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dtrsyl)(transa, transb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, info);
-      }
-    
-    void arma_fortran_prefix(arma_ctrsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const void*   a, blas_int* lda, const void*   b, blas_int* ldb, void*   c, blas_int* ldc, float*  scale, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_ctrsyl)(transa, transb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, info);
-      }
-    
-    void arma_fortran_prefix(arma_ztrsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const void*   a, blas_int* lda, const void*   b, blas_int* ldb, void*   c, blas_int* ldc, double* scale, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_ztrsyl)(transa, transb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, info);
-      }
-    
-    
-    
-    
-    void arma_fortran_prefix(arma_ssytrf)(char* uplo, blas_int* n, float*  a, blas_int* lda, blas_int* ipiv, float*  work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_ssytrf)(uplo, n, a, lda, ipiv, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_dsytrf)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* ipiv, double* work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dsytrf)(uplo, n, a, lda, ipiv, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_csytrf)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_csytrf)(uplo, n, a, lda, ipiv, work, lwork, info);
-      }
-    
-    void arma_fortran_prefix(arma_zsytrf)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* lwork, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zsytrf)(uplo, n, a, lda, ipiv, work, lwork, info);
-      }
-    
-    
-    
-    
-    void arma_fortran_prefix(arma_ssytri)(char* uplo, blas_int* n, float*  a, blas_int* lda, blas_int* ipiv, float*  work, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_ssytri)(uplo, n, a, lda, ipiv, work, info);
-      }
-    
-    void arma_fortran_prefix(arma_dsytri)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* ipiv, double* work, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_dsytri)(uplo, n, a, lda, ipiv, work, info);
-      }
-    
-    void arma_fortran_prefix(arma_csytri)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_csytri)(uplo, n, a, lda, ipiv, work, info);
-      }
-    
-    void arma_fortran_prefix(arma_zsytri)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* info)
-      {
-      arma_fortran_noprefix(arma_zsytri)(uplo, n, a, lda, ipiv, work, info);
-      }
-    
-  #endif
-  
-  
-  
-  #if defined(ARMA_USE_ATLAS)
-    
-    float wrapper_cblas_sdot(const int N, const float  *X, const int incX, const float  *Y, const int incY)
-      {
-      return      cblas_sdot(N, X, incX, Y, incY);
-      }
-    
-    double wrapper_cblas_ddot(const int N, const double *X, const int incX, const double *Y, const int incY)
-      {
-      return       cblas_ddot(N, X, incX, Y, incY);
-      }
-    
-    void wrapper_cblas_cdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu)
-      {
-                 cblas_cdotu_sub(N, X, incX, Y, incY, dotu);
-      }
-    
-    void wrapper_cblas_zdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu)
-      {
-                 cblas_zdotu_sub(N, X, incX, Y, incY, dotu);
-      }
-    
-    
-    
-    void wrapper_cblas_sgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const float alpha,
-                             const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY)
-      {
-                 cblas_sgemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
-      }
-    
-    void wrapper_cblas_dgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const double alpha,
-                             const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY)
-      {
-                 cblas_dgemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
-      }
-    
-    void wrapper_cblas_cgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha,
-                             const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY)
-      {
-                 cblas_cgemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
-      }
-    
-    void wrapper_cblas_zgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha,
-                             const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY)
-      {
-                 cblas_zgemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
-      }
-    
-    
-    
-    void wrapper_cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
-                             const int M, const int N, const int K, const float alpha,
-                             const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc)
-      {
-                 cblas_sgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
-      }
-    
-    void wrapper_cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
-                             const int M, const int N, const int K, const double alpha,
-                             const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc)
-      {
-                 cblas_dgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
-      }
-    
-    void wrapper_cblas_cgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
-                             const int M, const int N, const int K, const void *alpha,
-                             const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc)
-      {
-                 cblas_cgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
-      }
-    
-    void wrapper_cblas_zgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
-                             const int M, const int N, const int K, const void *alpha,
-                             const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc)
-      {
-                 cblas_zgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
-      }
-    
-    
-    
-    int wrapper_clapack_sgetrf(const enum CBLAS_ORDER Order, const int M, const int N, float  *A, const int lda, int *ipiv)
-      {
-      return    clapack_sgetrf(Order, M, N, A, lda, ipiv);
-      }
-    
-    int wrapper_clapack_dgetrf(const enum CBLAS_ORDER Order, const int M, const int N, double *A, const int lda, int *ipiv)
-      {
-      return    clapack_dgetrf(Order, M, N, A, lda, ipiv);
-      }
-    
-    int wrapper_clapack_cgetrf(const enum CBLAS_ORDER Order, const int M, const int N, void   *A, const int lda, int *ipiv)
-      {
-      return    clapack_cgetrf(Order, M, N, A, lda, ipiv);
-      }
-    
-    int wrapper_clapack_zgetrf(const enum CBLAS_ORDER Order, const int M, const int N, void   *A, const int lda, int *ipiv)
-      {
-      return    clapack_zgetrf(Order, M, N, A, lda, ipiv);
-      }
-    
-    
-    
-    int wrapper_clapack_sgetri(const enum CBLAS_ORDER Order, const int N, float  *A, const int lda, const int *ipiv)
-      {
-      return    clapack_sgetri(Order, N, A, lda, ipiv);
-      }
-    
-    int wrapper_clapack_dgetri(const enum CBLAS_ORDER Order, const int N, double *A, const int lda, const int *ipiv)
-      {
-      return    clapack_dgetri(Order, N, A, lda, ipiv);
-      }
-    
-    int wrapper_clapack_cgetri(const enum CBLAS_ORDER Order, const int N, void   *A, const int lda, const int *ipiv)
-      {
-      return    clapack_cgetri(Order, N, A, lda, ipiv);
-      }
-    
-    int wrapper_clapack_zgetri(const enum CBLAS_ORDER Order, const int N, void   *A, const int lda, const int *ipiv)
-      {
-      return    clapack_zgetri(Order, N, A, lda, ipiv);
-      }
-    
-    
-    
-    int wrapper_clapack_sgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, float  *A, const int lda, int *ipiv, float  *B, const int ldb)
-      {
-      return    clapack_sgesv(Order, N, NRHS, A, lda, ipiv, B, ldb);
-      }
-    
-    int wrapper_clapack_dgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, double *A, const int lda, int *ipiv, double *B, const int ldb)
-      {
-      return    clapack_dgesv(Order, N, NRHS, A, lda, ipiv, B, ldb);
-      }
-    
-    int wrapper_clapack_cgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, void   *A, const int lda, int *ipiv, void   *B, const int ldb)
-      {
-      return    clapack_cgesv(Order, N, NRHS, A, lda, ipiv, B, ldb);
-      }
-    
-    int wrapper_clapack_zgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, void   *A, const int lda, int *ipiv, void   *B, const int ldb)
-      {
-      return    clapack_zgesv(Order, N, NRHS, A, lda, ipiv, B, ldb);
-      }
-    
-  #endif
-  }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/CMakeLists.txt	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,455 @@
+
+# Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+# Copyright (C) 2008-2013 Conrad Sanderson
+# Copyright (C) 2011 Clement Creusot
+# 
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
+
+set(ARMA_MAJOR 3)
+set(ARMA_MINOR 900)
+set(ARMA_PATCH 4)
+
+message(STATUS "Configuring Armadillo ${ARMA_MAJOR}.${ARMA_MINOR}.${ARMA_PATCH}")
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/build_aux/cmake/Modules/")
+
+include(CheckIncludeFileCXX)
+include(CheckLibraryExists)
+include(FindBoost)
+include(ARMA_CheckProto)
+include(ARMA_CheckMathProto)
+
+project(armadillo CXX)
+
+set(ARMA_USE_LAPACK  false)
+set(ARMA_USE_BLAS    false)
+set(ARMA_USE_ATLAS   false)
+set(ARMA_USE_BOOST   false)
+set(ARMA_USE_HDF5    false)
+set(ARMA_USE_WRAPPER true )
+
+# NOTE:
+# Set ARMA_USE_WRAPPER to false if you're getting linking errors when compiling your programs,
+# or if you prefer to directly link with BLAS and/or LAPACK.
+# You will then need to link your programs with -lblas -llapack instead of -larmadillo
+# If you're using OpenBLAS, link your programs with -lopenblas -llapack instead of -larmadillo
+
+
+message(STATUS "CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME}")
+
+
+if(WIN32)
+  message(STATUS "")
+  message(STATUS "WARNING:")
+  message(STATUS "Automatic installation is currently not available for this platform.")
+  message(STATUS "Please use the manual installation, as described in the README.txt file.")
+  message(STATUS "You can also use the 'include' folder directly, but you may want to edit")
+  message(STATUS "'include/armadillo_bits/config.hpp' if you have LAPACK installed.")
+  message(STATUS "")
+endif()
+
+
+
+#
+# Find LAPACK and BLAS libraries, or their optimised versions
+#
+
+if(APPLE)
+  set(ARMA_OS macos)
+  
+  set(ARMA_USE_LAPACK true)
+  set(ARMA_USE_BLAS   true)
+  
+  # Under MacOS, the current version of ARMA_FindCLAPACK can get confused between
+  # two incompatible versions of "clapack.h" (one provided by the system and one
+  # provided by ATLAS).  As such, use of ATLAS under MacOS is disabled for now.
+  
+else()
+  set(ARMA_OS unix)
+  
+  include(ARMA_FindMKL)
+  include(ARMA_FindACMLMP)
+  include(ARMA_FindACML)
+  
+  message(STATUS "   MKL_FOUND   = ${MKL_FOUND}")
+  message(STATUS "ACMLMP_FOUND   = ${ACMLMP_FOUND}")
+  message(STATUS "  ACML_FOUND   = ${ACML_FOUND}")
+  
+  if(MKL_FOUND OR ACMLMP_FOUND OR ACML_FOUND)
+    
+    set(ARMA_USE_BLAS   true)
+    set(ARMA_USE_LAPACK true)
+    
+    message(STATUS "")
+    message(STATUS "*** If the MKL or ACML libraries are installed in")
+    message(STATUS "*** /opt or /usr/local, make sure the run-time linker can find them.")
+    message(STATUS "*** On Linux systems this can be done by editing /etc/ld.so.conf")
+    message(STATUS "*** or modifying the LD_LIBRARY_PATH environment variable.")
+    message(STATUS "*** On systems with SELinux enabled (eg. Fedora, RHEL),")
+    message(STATUS "*** you may need to change the SELinux type of all MKL/ACML libraries")
+    message(STATUS "*** to fix permission problems that may occur during run-time.")
+    message(STATUS "*** See README.txt for more information")
+    
+  else()
+    
+    include(ARMA_FindLAPACK)
+    include(ARMA_FindOpenBLAS)
+    include(ARMA_FindBLAS)
+    include(ARMA_FindCLAPACK)
+    include(ARMA_FindCBLAS)
+    
+    message(STATUS "  LAPACK_FOUND = ${LAPACK_FOUND}")
+    message(STATUS "    BLAS_FOUND = ${BLAS_FOUND}")
+    message(STATUS "OpenBLAS_FOUND = ${OpenBLAS_FOUND}")
+    message(STATUS " CLAPACK_FOUND = ${CLAPACK_FOUND}")
+    message(STATUS "   CBLAS_FOUND = ${CBLAS_FOUND}")
+    
+    if(LAPACK_FOUND)
+      set(ARMA_USE_LAPACK true)
+    endif()
+    
+    if(BLAS_FOUND)
+      set(ARMA_USE_BLAS true)
+    endif()
+    
+    if(OpenBLAS_FOUND AND CLAPACK_FOUND AND CBLAS_FOUND)
+      message(STATUS "")
+      message(STATUS "*** WARNING: both OpenBLAS and ATLAS have been found; ATLAS will not be used")
+    endif()
+    
+    if(OpenBLAS_FOUND)
+      
+      set(ARMA_USE_BLAS true)
+      
+      message(STATUS "")
+      message(STATUS "*** If the OpenBLAS library is installed in")
+      message(STATUS "*** /usr/local/lib or /usr/local/lib64")
+      message(STATUS "*** make sure the run-time linker can find it.")
+      message(STATUS "*** On Linux systems this can be done by editing /etc/ld.so.conf")
+      message(STATUS "*** or modifying the LD_LIBRARY_PATH environment variable.")
+      
+    else()
+      
+      if(CLAPACK_FOUND AND CBLAS_FOUND)
+        message(STATUS "CLAPACK_INCLUDE_DIR = ${CLAPACK_INCLUDE_DIR}")
+        message(STATUS "  CBLAS_INCLUDE_DIR = ${CBLAS_INCLUDE_DIR}")
+        
+        if(${CLAPACK_INCLUDE_DIR} STREQUAL ${CBLAS_INCLUDE_DIR})
+          set(ARMA_USE_ATLAS true)
+          set(ARMA_ATLAS_INCLUDE_DIR ${CLAPACK_INCLUDE_DIR})
+        endif()
+      endif()
+      
+    endif()
+    
+  endif()
+  
+endif()
+
+
+if(MKL_FOUND OR ACMLMP_FOUND OR ACML_FOUND)
+  
+  if(MKL_FOUND)
+    set(ARMA_LIBS ${ARMA_LIBS} ${MKL_LIBRARIES})
+    
+    if(ACMLMP_FOUND OR ACML_FOUND)
+      message(STATUS "*** Intel MKL as well as AMD ACML libraries were found.")
+      message(STATUS "*** Using only the MKL library to avoid linking conflicts.")
+      message(STATUS "*** If you wish to use ACML instead, please link manually with")
+      message(STATUS "*** acml or acml_mp instead of the armadillo run-time component.")
+      message(STATUS "*** Alternatively, remove MKL from your system and rerun")
+      message(STATUS "*** Armadillo's configuration using ./configure") 
+    endif()
+    
+  else()
+    
+    if(ACMLMP_FOUND)
+      set(ARMA_LIBS ${ARMA_LIBS} ${ACMLMP_LIBRARIES})
+      
+      message(STATUS "*** Both single-core and multi-core ACML libraries were found.")
+      message(STATUS "*** Using only the multi-core library to avoid linking conflicts.")
+    else()
+      if(ACML_FOUND)
+        set(ARMA_LIBS ${ARMA_LIBS} ${ACML_LIBRARIES})
+      endif()
+    endif()
+    
+  endif()
+  
+else()
+  
+  if(ARMA_USE_BLAS STREQUAL true)
+    if(OpenBLAS_FOUND)
+      set(ARMA_LIBS ${ARMA_LIBS} ${OpenBLAS_LIBRARIES})
+    else()
+      set(ARMA_LIBS ${ARMA_LIBS} ${BLAS_LIBRARIES})
+    endif()
+  endif()
+  
+  if(ARMA_USE_LAPACK STREQUAL true)
+    set(ARMA_LIBS ${ARMA_LIBS} ${LAPACK_LIBRARIES})
+  endif()
+  
+  if(ARMA_USE_ATLAS STREQUAL true)
+    set(ARMA_LIBS ${ARMA_LIBS} ${CBLAS_LIBRARIES})
+    set(ARMA_LIBS ${ARMA_LIBS} ${CLAPACK_LIBRARIES})
+  endif()
+  
+endif()
+
+
+if(APPLE)
+  set(ARMA_LIBS ${ARMA_LIBS} "-framework Accelerate")  # or "-framework accelerate" ?
+  message(STATUS "MacOS X detected. Added '-framework Accelerate' to compiler flags")
+  
+  if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+    add_definitions(
+        -stdlib=libc++
+    )
+  message(STATUS "Clang compiler on MacOS X detected. Added '-stdlib=libc++' to compiler flags")
+  endif()
+
+endif()
+
+
+# if(CMAKE_VERSION VERSION_GREATER "2.7")
+#   find_package(HDF5)
+#   message(STATUS "HDF5_FOUND     = ${HDF5_FOUND}")
+#   
+#   if(HDF5_FOUND)
+#     set(ARMA_USE_HDF5 true)
+#     set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${HDF5_INCLUDE_DIRS})
+#     set(ARMA_LIBS ${ARMA_LIBS} ${HDF5_LIBRARIES})
+#   endif()
+# endif()
+
+
+message(STATUS "")
+message(STATUS "*** The run-time library component of Armadillo will be an alias for the following libraries:")
+message(STATUS "*** ARMA_LIBS = ${ARMA_LIBS}")
+message(STATUS "")
+
+find_package(Boost)
+
+if(Boost_FOUND)
+  
+  message(STATUS "Boost_MAJOR_VERSION = ${Boost_MAJOR_VERSION}")
+  message(STATUS "Boost_MINOR_VERSION = ${Boost_MINOR_VERSION}")
+  
+  if(Boost_MAJOR_VERSION GREATER 0)
+    if(Boost_MINOR_VERSION GREATER 33)
+      set(ARMA_USE_BOOST true)
+      message(STATUS "Boost_INCLUDE_DIR = ${Boost_INCLUDE_DIR}")
+    endif()
+  endif()
+  
+endif()
+
+if(ARMA_USE_BOOST STREQUAL false)
+  message(STATUS "Boost libraries either not found or their version is too low (1.34 or later is good).")
+  message(STATUS "( It's possible that CMake didn't find the particular version of Boost you may have. )")
+  message(STATUS "( If that's the case, please edit include/armadillo_bits/config.hpp manually. )")
+endif()
+
+
+# If Boost libraries were found, explicitly check if Boost's date_time library is also present.
+
+if(ARMA_USE_BOOST STREQUAL true)
+  set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${Boost_INCLUDE_DIR})
+  CHECK_INCLUDE_FILE_CXX("boost/date_time/posix_time/posix_time.hpp" ARMA_USE_BOOST_DATE)
+endif()
+
+ARMA_CHECK_MATH_PROTO("isfinite" "std" "cmath"  ARMA_HAVE_STD_ISFINITE)
+ARMA_CHECK_MATH_PROTO("isinf"    "std" "cmath"  ARMA_HAVE_STD_ISINF)
+ARMA_CHECK_MATH_PROTO("isnan"    "std" "cmath"  ARMA_HAVE_STD_ISNAN)
+ARMA_CHECK_MATH_PROTO("log1p"    ""    "cmath"  ARMA_HAVE_LOG1P)
+
+ARMA_CHECK_PROTO("snprintf"     "std" "cstdio"     ARMA_HAVE_STD_SNPRINTF)
+ARMA_CHECK_PROTO("gettimeofday" ""    "sys/time.h" ARMA_HAVE_GETTIMEOFDAY)
+
+
+message(STATUS "Generating 'include/armadillo_bits/config.hpp'")
+configure_file(include/armadillo_bits/config.hpp.cmake include/armadillo_bits/config.hpp)
+
+message(STATUS "Generating 'examples/Makefile'")
+configure_file(examples/Makefile.cmake examples/Makefile)
+
+
+if(ARMA_USE_BOOST STREQUAL true)
+  include_directories(include ${Boost_INCLUDE_DIR})
+else()
+  include_directories(include)
+endif()
+
+
+## For any library that is not in a default location,
+## embed its path into the Armadillo runtime library.
+## Examples of default locations are "/lib", "/usr/lib",
+## or as specified in "/etc/ld.so.conf".
+##
+## Path embedding is not recommended unless you know
+## what you're doing.  It might be better to add the
+## path to the "/etc/ld.so.conf" file and then run "ldconfig".
+##
+#set(CMAKE_SKIP_BUILD_RPATH  FALSE)
+#set(CMAKE_BUILD_WITH_INSTALL_RPATH  FALSE)
+#set(CMAKE_INSTALL_RPATH_USE_LINK_PATH  TRUE)
+
+
+# work around a silly limitation in Mac OS X
+if(APPLE)
+  if(${ARMA_MINOR} GREATER 99)
+    math(EXPR ARMA_MINOR_ALT "${ARMA_MINOR} / 10")
+  else()
+    set(ARMA_MINOR_ALT ${ARMA_MINOR})
+  endif()
+else()
+  set(ARMA_MINOR_ALT ${ARMA_MINOR})
+endif()
+
+
+# necessary when linking with Intel MKL on Linux systems
+if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-as-needed")
+  message(STATUS "CMAKE_SHARED_LINKER_FLAGS = ${CMAKE_SHARED_LINKER_FLAGS}")
+endif()
+
+add_library( armadillo SHARED src/wrap_libs )
+target_link_libraries( armadillo ${ARMA_LIBS} )
+set_target_properties(armadillo PROPERTIES VERSION ${ARMA_MAJOR}.${ARMA_MINOR_ALT}.${ARMA_PATCH} SOVERSION ${ARMA_MAJOR})
+
+
+################################################################################
+# INSTALL CONFIGURATION
+
+
+# As Red Hat Enterprise Linux (and related systems such as Fedora)
+# does not search /usr/local/lib by default, we need to place the
+# library in either /usr/lib or /usr/lib64
+
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+  message(STATUS "*** CMAKE_INSTALL_PREFIX was initalised by cmake to the default value of ${CMAKE_INSTALL_PREFIX}")
+  message(STATUS "*** CMAKE_INSTALL_PREFIX changed to /usr")
+  unset(CMAKE_INSTALL_PREFIX)
+  set(CMAKE_INSTALL_PREFIX "/usr")
+  #set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "install prefix" FORCE)
+endif()
+
+# Allow for the "lib" directory to be specified on the command line
+if(NOT INSTALL_LIB_DIR)
+  set(INSTALL_LIB_DIR "lib")
+  if(UNIX AND NOT APPLE)   # I don't know how Mac OS handles 64 bit systems
+    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+      message(STATUS "*** Detected 64 bit system")
+      # use "lib64" only on systems that have it (eg. Fedora, Red Hat).
+      # if installing in /usr/local/, the use of lib64 might be unreliable on systems which have /usr/local/lib64 but don't use it
+      if(IS_DIRECTORY "${CMAKE_INSTALL_PREFIX}/lib64")
+        unset(INSTALL_LIB_DIR)
+        set(INSTALL_LIB_DIR "lib64")
+        message(STATUS "*** ${CMAKE_INSTALL_PREFIX}/lib64/ exists, so destination directory for the run-time library changed to ${CMAKE_INSTALL_PREFIX}/lib64/")
+        message(STATUS "*** Your system and/or compiler must search ${CMAKE_INSTALL_PREFIX}/lib64/ during linking")
+      endif()
+    endif()
+  endif()
+endif()
+
+# Allow for the "include" directory to be specified on the command line
+
+if(NOT INSTALL_INCLUDE_DIR)
+  set(INSTALL_INCLUDE_DIR "include")
+endif()
+
+# We use data dir to store files shared with other programs 
+# like the ArmadilloConfig.cmake file.
+if(NOT INSTALL_DATA_DIR)
+  set(INSTALL_DATA_DIR "share")
+endif()
+
+# Make relative paths absolute so we can write them in Config.cmake files
+foreach(p LIB INCLUDE DATA)
+  set(var INSTALL_${p}_DIR)
+  if(NOT IS_ABSOLUTE "${${var}}")
+    set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
+  endif()
+endforeach()
+
+message(STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}")
+message(STATUS "INSTALL_LIB_DIR      = ${INSTALL_LIB_DIR}"     )
+message(STATUS "INSTALL_INCLUDE_DIR  = ${INSTALL_INCLUDE_DIR}" )
+message(STATUS "INSTALL_DATA_DIR     = ${INSTALL_DATA_DIR}"    )
+
+
+# Note that the trailing / character in "include/" is critical
+
+install(DIRECTORY include/ DESTINATION ${INSTALL_INCLUDE_DIR}
+PATTERN ".svn" EXCLUDE
+PATTERN "*.cmake" EXCLUDE
+PATTERN "*~" EXCLUDE
+PATTERN "*orig" EXCLUDE
+)
+
+install(FILES ${PROJECT_BINARY_DIR}/include/armadillo_bits/config.hpp
+DESTINATION ${INSTALL_INCLUDE_DIR}/armadillo_bits
+)
+
+install(TARGETS armadillo 
+  DESTINATION ${INSTALL_LIB_DIR}
+  EXPORT ArmadilloLibraryDepends)
+
+# Export the package for use from the build-tree
+# (this registers the build-tree with a global CMake-registry)
+if(CMAKE_VERSION VERSION_GREATER "2.7")
+ export(PACKAGE armadillo)
+endif()
+
+## LOCAL FILES
+# Create ArmadilloConfig.cmake file for the use from the build tree
+set(ARMADILLO_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}")
+set(ARMADILLO_LIB_DIR      "${PROJECT_BINARY_DIR}")
+set(ARMADILLO_CMAKE_DIR    "${PROJECT_BINARY_DIR}")
+
+
+message(STATUS "Generating '${PROJECT_BINARY_DIR}/ArmadilloConfig.cmake'")
+# copy/change config and configVersion file (modify only the @xyz@ variables)
+configure_file(build_aux/cmake/InstallFiles/ArmadilloConfig.cmake.in
+  "${PROJECT_BINARY_DIR}/ArmadilloConfig.cmake" @ONLY)
+
+message(STATUS "Generating '${PROJECT_BINARY_DIR}/ArmadilloConfigVersion.cmake'")
+configure_file(build_aux/cmake/InstallFiles/ArmadilloConfigVersion.cmake.in
+  "${PROJECT_BINARY_DIR}/ArmadilloConfigVersion.cmake" @ONLY)
+
+
+# Install the export set for use with the install-tree
+install(EXPORT ArmadilloLibraryDepends DESTINATION
+  "${INSTALL_DATA_DIR}/Armadillo/CMake"
+  COMPONENT dev)
+
+
+## GLOBAL INSTALL FILES
+# Create ArmadilloConfig.cmake file for the use from the install tree
+# and install it
+set(ARMADILLO_INCLUDE_DIRS "${INSTALL_INCLUDE_DIR}")
+set(ARMADILLO_LIB_DIR      "${INSTALL_LIB_DIR}")
+set(ARMADILLO_CMAKE_DIR    "${INSTALL_DATA_DIR}/Armadillo/CMake")
+
+
+message(STATUS "Generating '${PROJECT_BINARY_DIR}/InstallFiles/ArmadilloConfig.cmake'")
+# copy/change config and configVersion file (modify only the @xyz@ variables)
+configure_file(build_aux/cmake/InstallFiles/ArmadilloConfig.cmake.in
+  "${PROJECT_BINARY_DIR}/InstallFiles/ArmadilloConfig.cmake" @ONLY)
+
+message(STATUS "Generating '${PROJECT_BINARY_DIR}/InstallFiles/ArmadilloConfigVersion.cmake'")
+configure_file(build_aux/cmake/InstallFiles/ArmadilloConfigVersion.cmake.in
+  "${PROJECT_BINARY_DIR}/InstallFiles/ArmadilloConfigVersion.cmake" @ONLY)
+
+# Install files to be found by cmake users with find_package()
+install(FILES
+  "${PROJECT_BINARY_DIR}/InstallFiles/ArmadilloConfig.cmake"
+  "${PROJECT_BINARY_DIR}/InstallFiles/ArmadilloConfigVersion.cmake"
+  DESTINATION "${ARMADILLO_CMAKE_DIR}" COMPONENT dev)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/LICENSE.txt	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+    means each individual or legal entity that creates, contributes to
+    the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+    means the combination of the Contributions of others (if any) used
+    by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+    means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+    means Source Code Form to which the initial Contributor has attached
+    the notice in Exhibit A, the Executable Form of such Source Code
+    Form, and Modifications of such Source Code Form, in each case
+    including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+    means
+
+    (a) that the initial Contributor has attached the notice described
+        in Exhibit B to the Covered Software; or
+
+    (b) that the Covered Software was made available under the terms of
+        version 1.1 or earlier of the License, but not also under the
+        terms of a Secondary License.
+
+1.6. "Executable Form"
+    means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+    means a work that combines Covered Software with other material, in 
+    a separate file or files, that is not Covered Software.
+
+1.8. "License"
+    means this document.
+
+1.9. "Licensable"
+    means having the right to grant, to the maximum extent possible,
+    whether at the time of the initial grant or subsequently, any and
+    all of the rights conveyed by this License.
+
+1.10. "Modifications"
+    means any of the following:
+
+    (a) any file in Source Code Form that results from an addition to,
+        deletion from, or modification of the contents of Covered
+        Software; or
+
+    (b) any new file in Source Code Form that contains any Covered
+        Software.
+
+1.11. "Patent Claims" of a Contributor
+    means any patent claim(s), including without limitation, method,
+    process, and apparatus claims, in any patent Licensable by such
+    Contributor that would be infringed, but for the grant of the
+    License, by the making, using, selling, offering for sale, having
+    made, import, or transfer of either its Contributions or its
+    Contributor Version.
+
+1.12. "Secondary License"
+    means either the GNU General Public License, Version 2.0, the GNU
+    Lesser General Public License, Version 2.1, the GNU Affero General
+    Public License, Version 3.0, or any later versions of those
+    licenses.
+
+1.13. "Source Code Form"
+    means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+    means an individual or a legal entity exercising rights under this
+    License. For legal entities, "You" includes any entity that
+    controls, is controlled by, or is under common control with You. For
+    purposes of this definition, "control" means (a) the power, direct
+    or indirect, to cause the direction or management of such entity,
+    whether by contract or otherwise, or (b) ownership of more than
+    fifty percent (50%) of the outstanding shares or beneficial
+    ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+    Licensable by such Contributor to use, reproduce, make available,
+    modify, display, perform, distribute, and otherwise exploit its
+    Contributions, either on an unmodified basis, with Modifications, or
+    as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+    for sale, have made, import, and otherwise transfer either its
+    Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+    or
+
+(b) for infringements caused by: (i) Your and any other third party's
+    modifications of Covered Software, or (ii) the combination of its
+    Contributions with other software (except as part of its Contributor
+    Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+    its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+    Form, as described in Section 3.1, and You must inform recipients of
+    the Executable Form how they can obtain a copy of such Source Code
+    Form by reasonable means in a timely manner, at a charge no more
+    than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+    License, or sublicense it under different terms, provided that the
+    license for the Executable Form does not attempt to limit or alter
+    the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+*                                                                      *
+*  6. Disclaimer of Warranty                                           *
+*  -------------------------                                           *
+*                                                                      *
+*  Covered Software is provided under this License on an "as is"       *
+*  basis, without warranty of any kind, either expressed, implied, or  *
+*  statutory, including, without limitation, warranties that the       *
+*  Covered Software is free of defects, merchantable, fit for a        *
+*  particular purpose or non-infringing. The entire risk as to the     *
+*  quality and performance of the Covered Software is with You.        *
+*  Should any Covered Software prove defective in any respect, You     *
+*  (not any Contributor) assume the cost of any necessary servicing,   *
+*  repair, or correction. This disclaimer of warranty constitutes an   *
+*  essential part of this License. No use of any Covered Software is   *
+*  authorized under this License except under this disclaimer.         *
+*                                                                      *
+************************************************************************
+
+************************************************************************
+*                                                                      *
+*  7. Limitation of Liability                                          *
+*  --------------------------                                          *
+*                                                                      *
+*  Under no circumstances and under no legal theory, whether tort      *
+*  (including negligence), contract, or otherwise, shall any           *
+*  Contributor, or anyone who distributes Covered Software as          *
+*  permitted above, be liable to You for any direct, indirect,         *
+*  special, incidental, or consequential damages of any character      *
+*  including, without limitation, damages for lost profits, loss of    *
+*  goodwill, work stoppage, computer failure or malfunction, or any    *
+*  and all other commercial damages or losses, even if such party      *
+*  shall have been informed of the possibility of such damages. This   *
+*  limitation of liability shall not apply to liability for death or   *
+*  personal injury resulting from such party's negligence to the       *
+*  extent applicable law prohibits such limitation. Some               *
+*  jurisdictions do not allow the exclusion or limitation of           *
+*  incidental or consequential damages, so this exclusion and          *
+*  limitation may not apply to You.                                    *
+*                                                                      *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+  This Source Code Form is "Incompatible With Secondary Licenses", as
+  defined by the Mozilla Public License, v. 2.0.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/README.txt	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,502 @@
+=== Contents ===
+
+1: Introduction
+
+2: Citation Details
+
+3: Installation
+   3.0: Preliminaries
+   3.1: Installation on Linux and Mac OS X
+   3.2: Manual Installation / Installation on Windows
+
+4: Compiling Programs and Linking
+   4.0: Examples
+   4.1: Compiling & Linking on Linux and Mac OS X
+   4.2: Compiling & Linking on Windows
+
+5: Support for high-speed BLAS & LAPACK replacements
+   5.0: Support for OpenBLAS, Intel MKL and AMD ACML
+   5.1: Support for ATLAS
+
+6: Documentation / API Reference Manual
+
+7: FAQs and Bug Reports
+
+8: Developers and Contributors
+
+9: License
+
+
+
+
+=== 1: Introduction ===
+
+Armadillo is a C++ linear algebra library (matrix maths)
+aiming towards a good balance between speed and ease of use.
+The syntax is deliberately similar to Matlab.
+
+Integer, floating point and complex numbers are supported,
+as well as a subset of trigonometric and statistics functions.
+Various matrix decompositions are provided through optional
+integration with LAPACK or high-performance LAPACK-compatible
+libraries (such as Intel MKL or AMD ACML).
+
+A delayed evaluation approach is employed (during compile time)
+to combine several operations into one and reduce (or eliminate)
+the need for temporaries. This is accomplished through recursive
+templates and template meta-programming.
+
+This library is useful for conversion of research code into
+production environments, or if C++ has been decided as the
+language of choice, due to speed and/or integration capabilities.
+
+The library is open-source software, and is distributed under a
+license that is useful in both open-source and commercial/proprietary
+contexts. 
+
+Armadillo is primarily developed at NICTA (Australia),
+with contributions from around the world.  More information
+about NICTA can be obtained from http://nicta.com.au
+
+
+
+=== 2: Citation Details ===
+
+Please cite the following tech report if you use Armadillo in your
+research and/or software. Citations are useful for the continued
+development and maintenance of the library.
+
+  Conrad Sanderson.
+  Armadillo: An Open Source C++ Linear Algebra Library for
+  Fast Prototyping and Computationally Intensive Experiments.
+  Technical Report, NICTA, 2010.
+
+
+
+=== 3.0: Installation: Preliminaries ===
+
+Armadillo makes extensive use of template meta-programming,
+recursive templates and template based function overloading.
+As such, C++ compilers which do not fully implement the C++
+standard may not work correctly.
+
+The functionality of Armadillo is partly dependent on other
+libraries: mainly LAPACK and BLAS. Armadillo can work without
+LAPACK or BLAS, but its functionality will be reduced.
+In particular, basic functionality will be available
+(eg. matrix addition and multiplication), but things like
+eigen decomposition or matrix inversion will not be.
+Matrix multiplication (mainly for big matrices) may not be as fast.
+
+* For automatic installation on Linux and Mac OS X systems,
+  see section 3.1. This installation is also likely to work on
+  other Unix-like systems, such as FreeBSD, NetBSD, OpenBSD,
+  Solaris, CygWin, etc.
+  
+* For manual installation and/or installation on Windows,
+  see section 3.2.
+  
+* If you have a previous version of Armadillo already installed,
+  we recommend removing it before installing a newer version.
+
+
+
+=== 3.1: Installation on Linux and Mac OS X ===
+
+You can use the manual installation process as described in
+section 3.2, or the following CMake based automatic installation.
+
+* Step 1:
+  If CMake is not already be present on your system, download
+  it from http://www.cmake.org
+  
+  On major Linux systems (such as Fedora, Ubuntu, Debian, etc),
+  cmake is available as a pre-built package, though it may need
+  to be explicitly installed (using a tool such as PackageKit,
+  yum, rpm, apt, aptitude).
+  
+* Step 2:
+  If you have BLAS and/or LAPACK, install them before installing
+  Armadillo. Under Mac OS X this is not necessary.
+  
+  On Linux systems it is recommended that the following libraries
+  are present: LAPACK, BLAS, ATLAS and Boost. LAPACK and BLAS are
+  the most important. If you have ATLAS and Boost, it's also necessary
+  to have the corresponding header files installed.
+  
+  For best performance, we recommend using the multi-threaded OpenBLAS
+  library instead of standard BLAS.  See http://xianyi.github.com/OpenBLAS/
+  
+* Step 3:
+  Open a shell (command line), change into the directory that was
+  created by unpacking the armadillo archive, and type the following
+  commands:
+  
+  cmake .
+  make 
+  
+  The full stop separated from "cmake" by a space is important.
+  CMake will figure out what other libraries are currently installed
+  and will modify Armadillo's configuration correspondingly.
+  CMake will also generate a run-time armadillo library, which is a 
+  combined alias for all the relevant libraries present on your system
+  (eg. BLAS, LAPACK and ATLAS).
+  
+  If you need to re-run cmake, it's a good idea to first delete the
+  "CMakeCache.txt" file (not "CMakeLists.txt").
+  
+* Step 4:
+  If you have access to root/administrator/superuser privileges,
+  first enable the privileges (eg. through "su" or "sudo")
+  and then type the following command:
+  
+  make install
+  
+  If you don't have root/administrator/superuser privileges, 
+  type the following command:
+  
+  make install DESTDIR=my_usr_dir
+  
+  where "my_usr_dir" is for storing C++ headers and library files.
+  Make sure your C++ compiler is configured to use the sub-directories
+  present within this directory.
+
+
+
+=== 3.2: Manual Installation / Installation on Windows ===
+
+The manual installation is comprised of 3 steps:
+
+* Step 1:
+  Copy the entire "include" folder to a convenient location
+  and tell your compiler to use that location for header files
+  (in addition to the locations it uses already).
+  Alternatively, you can use the "include" folder directly.
+  
+* Step 2:
+  Modify "include/armadillo_bits/config.hpp" to indicate 
+  which libraries are currently available on your system.
+  For example, if you have LAPACK and BLAS (or OpenBLAS) present, 
+  uncomment the following lines:
+  
+  #define ARMA_USE_LAPACK
+  #define ARMA_USE_BLAS
+  
+* Step 3:
+  If you have LAPACK and/or BLAS present, configure your 
+  compiler to link with these libraries. 
+  
+  If using Linux, link using -llapack -lblas
+  If using Mac OS X, link using -framework Accelerate
+  If using Windows, see section 4.2.
+  
+  You can also link with high-speed replacements for LAPACK and BLAS,
+  such as OpenBLAS, or Intel MKL, or AMD ACML. See section 5 for more info.
+
+
+
+=== 4.0: Compiling Programs and Linking: Examples ===
+
+The "examples" directory contains several quick example programs
+that use the Armadillo library. If Armadillo was installed manually
+(ie. according to section 3.2), you will also need to explicitly
+link your programs with the libraries that were specified in
+"include/armadillo_bits/config.hpp".
+
+"example1.cpp" may require the BLAS library or its equivalent.
+"example2.cpp" requires the LAPACK library or its equivalent
+(eg. the Accelerate framework on Mac OS X).
+
+You may get errors at compile or run time if BLAS and/or LAPACK
+functions are not available.
+
+NOTE: As Armadillo is a template library, we recommended that
+      optimisation is enabled during compilation. For example,
+      for the GCC compiler use -O1 or -O2
+
+
+
+=== 4.1: Compiling & Linking on Linux and Mac OS X ===
+
+Please see "examples/Makefile", which may may need to be configured
+for your system. If Armadillo header files were installed in a
+non-standard location, you will need to modify "examples/Makefile"
+to tell the compiler where they are.
+
+In general, programs which use Armadillo are compiled along these lines:
+  g++ example1.cpp -o example1 -O2 -larmadillo
+
+(you may also need to specify the include directory via the -I switch)
+
+If you get linking errors, or if Armadillo was installed manually
+and you specified that LAPACK and BLAS are available, you will
+need to explicitly link with LAPACK and BLAS (or their equivalents),
+for example:
+  g++ example1.cpp -o example1 -O2 -llapack -lblas
+
+(you may also need to specify the library directory via the -L switch)
+
+Notes:
+
+  * under most Linux systems, using "-llapack -lblas" should be enough;
+    however, on Ubuntu and Debian you may need to add "-lgfortran"
+    
+  * under Mac OS X, try "-framework Accelerate" or "-llapack -lblas"
+    (the Accelerate option is usually the fastest)
+    
+  * under the Sun Studio compiler, try "-library=sunperf"
+
+
+
+=== 4.2: Compiling & Linking on Windows ===
+
+As a courtesy, we've provided pre-compiled 32 bit versions of
+standard LAPACK and BLAS for Windows, as well as MSVC project
+files to compile example1.cpp and example2.cpp.
+The project files are stored in the following folders:
+  examples/example1_win32
+  examples/example2_win32
+
+The standard 32 bit versions of the LAPACK and BLAS libraries
+are stored in:
+  examples/lib_win32
+
+If you're getting messages such as "use of LAPACK needs to be enabled",
+you will need to manually modify "include/armadillo_bits/config.hpp"
+to enable the use of LAPACK. See section 3.2 for more information.
+
+Note that on 64 bit systems (such as Windows 7), dedicated
+64 bit versions of BLAS and LAPACK are considerably faster.
+If you don't have a 64 bit BLAS library, it's better to
+explicitly disable the use of BLAS by defining ARMA_DONT_USE_BLAS
+before including the armadillo header:
+
+#define ARMA_DONT_USE_BLAS
+#include <armadillo>
+
+The MSCV project files were tested on 32 bit Windows XP with
+Visual C++ 2008 (Express Edition). You may need to make adaptations
+for 64 bit systems, later versions of Windows and/or the compiler.
+For example, you may have to enable or disable the ARMA_BLAS_LONG
+and ARMA_BLAS_UNDERSCORE macros in "armadillo_bits/config.hpp".
+
+The pre-compiled versions of LAPACK and BLAS were downloaded from:
+  http://www.fi.muni.cz/~xsvobod2/misc/lapack/
+
+If the provided libraries don't work for you, or you want more speed,
+try these versions:
+  http://software.intel.com/en-us/intel-mkl/
+  http://developer.amd.com/tools-and-sdks/cpu-development/amd-core-math-library-acml/
+  http://xianyi.github.com/OpenBLAS/
+  http://www.stanford.edu/~vkl/code/libs.html
+  http://icl.cs.utk.edu/lapack-for-windows/lapack/
+
+The OpenBLAS, MKL and ACML libraries are generally the fastest.
+See section 5 for more info on making Armadillo use these libraries.
+
+
+You can find the original sources for standard BLAS and LAPACK at:
+  http://www.netlib.org/blas/
+  http://www.netlib.org/lapack/
+
+
+We recommend the following high-quality compilers:
+
+  * GCC (part MinGW)
+    http://www.mingw.org/
+
+  * GCC (part of CygWin)
+    http://www.cygwin.com/
+
+  * Intel C++ compiler
+    http://software.intel.com/en-us/intel-compilers/
+
+For the GCC compiler, use version 4.0 or later.
+For the Intel compiler, use version 10.0 or later.
+
+For best results we also recommend using an operating system
+that's more reliable and more suitable for heavy duty work,
+such as Mac OS X or the various flavours of Linux,
+eg. Scientific Linux: http://www.scientificlinux.org/
+
+
+
+=== 5.0: Support for OpenBLAS, Intel MKL and AMD ACML ===
+
+Armadillo can use OpenBLAS, or Intel Math Kernel Library (MKL), or the
+AMD Core Math Library (ACML) as high-speed replacements for BLAS and LAPACK.
+Generally this just involves linking with the replacement libraries
+instead of BLAS and LAPACK.
+
+You may need to make minor modifications to "include/armadillo_bits/config.hpp"
+in order to make sure Armadillo uses the same style of function names
+as used by MKL or ACML. For example, the function names might be in capitals.
+
+On Linux systems, MKL and ACML might be installed in a non-standard
+location, such as /opt, which can cause problems during linking.
+Before installing Armadillo, the system should know where the MKL or ACML
+libraries are located. For example, "/opt/intel/mkl/lib/intel64/".
+This can be achieved by setting the LD_LIBRARY_PATH environment variable,
+or for a more permanent solution, adding the directory locations
+to "/etc/ld.so.conf". It may also be possible to store a text file 
+with the locations in the "/etc/ld.so.conf.d" directory.
+For example, "/etc/ld.so.conf.d/mkl.conf".
+If you modify "/etc/ld.so.conf" or create "/etc/ld.so.conf.d/mkl.conf",
+you will need to run "/sbin/ldconfig" afterwards.
+
+Example of the contents of "/etc/ld.so.conf.d/mkl.conf" on a RHEL 6 system,
+where Intel MKL version 11.0.3 is installed in "/opt/intel":
+
+/opt/intel/lib/intel64
+/opt/intel/mkl/lib/intel64
+
+The default installations of ACML 4.4.0 and MKL 10.2.2.025 are known 
+to have issues with SELinux, which is turned on by default in Fedora
+(and possibly RHEL). The problem may manifest itself during run-time,
+where the run-time linker reports permission problems.
+It is possible to work around the problem by applying an appropriate
+SELinux type to all ACML and MKL libraries.
+
+If you have ACML or MKL installed and they are persistently giving
+you problems during linking, you can disable the support for them
+by editing the "CMakeLists.txt" file, deleting "CMakeCache.txt" and
+re-running the CMake based installation. Specifically, comment out
+the lines containing:
+  INCLUDE(ARMA_FindMKL)
+  INCLUDE(ARMA_FindACMLMP)
+  INCLUDE(ARMA_FindACML)
+
+
+
+=== 5.1: Support for ATLAS ===
+
+Armadillo can use the ATLAS library for faster versions of
+certain LAPACK and BLAS functions. Not all ATLAS functions are
+currently used, and as such LAPACK should still be installed.
+
+The minimum recommended version of ATLAS is 3.8.
+Old versions (eg. 3.6) can produce incorrect results
+as well as corrupting memory, leading to random crashes.
+
+Users of Ubuntu and Debian based systems should explicitly
+check that version 3.6 is not installed.  It's better to
+remove the old version and use the standard LAPACK library.
+
+
+
+=== 6: Documentation / API Reference Manual ===
+
+A reference manual (documentation of APIs) is available at
+
+  http://arma.sourceforge.net/docs.html
+
+and in the "docs.html" file in this archive,
+which can be viewed with a web browser.
+
+The documentation explains how to use Armadillo's
+classes and functions, with snippets of example code.
+
+
+
+=== 7: FAQs and Bug Reports ===
+
+Answers to Frequently Asked Questions (FAQs) can be found at:
+
+  http://arma.sourceforge.net/faq.html
+
+This library has gone through extensive testing and
+has been successfully used in production environments.
+However, as with almost all software, it's impossible
+to guarantee 100% correct functionality.
+
+If you find a bug in the library (or the documentation),
+we are interested in hearing about it. Please make a
+_small_ _self-contained_ program which exposes the bug
+and send the program source (as well as the bug description)
+to the developers.  The developers' contact details are at:
+
+  http://arma.sourceforge.net/contact.html
+
+
+
+=== 8: Developers and Contributors ===
+
+Main sponsoring organisation:
+- NICTA
+  http://nicta.com.au
+
+Main developers:
+- Conrad Sanderson - http://itee.uq.edu.au/~conrad/
+- Ryan Curtin
+- Ian Cullinan
+- Dimitrios Bouzas
+- Stanislav Funiak
+
+Contributors:
+- Matthew Amidon
+- Eric R. Anderson
+- Benoît Bayol
+- Salim Bcoin
+- Justin Bedo
+- Evan Bollig
+- Darius Braziunas
+- Filip Bruman
+- Ted Campbell
+- James Cline
+- Chris Cooper
+- Clement Creusot
+- Chris Davey
+- Dirk Eddelbuettel
+- Romain Francois
+- Michael McNeil Forbes
+- Piotr Gawron
+- Charles Gretton
+- Benjamin Herzog
+- Edmund Highcock
+- Szabolcs Horvat
+- Friedrich Hust
+- Kshitij Kulshreshtha
+- Oka Kurniawan
+- Simen Kvaal
+- David Lawrence
+- Jussi Lehtola
+- Jeremy Mason
+- Nikolay Mayorov
+- Carlos Mendes
+- Sergey Nenakhov
+- Artem Novikov
+- Martin Orlob
+- Ken Panici
+- Adam PiÄ…tyszek
+- Jayden Platell
+- Vikas Reddy
+- Ola Rinta-Koski
+- Boris Sabanin
+- James Sanders
+- Alexander Scherbatey
+- Gerhard Schreiber
+- Ruslan Shestopalyuk
+- Shane Stainsby
+- Petter Strandmark
+- Eric Jon Sundstrom
+- Paul Torfs
+- Martin Uhrin
+- Simon Urbanek
+- Juergen Wiest
+- Arnold Wiliem
+- Yong Kang Wong
+- Buote Xu
+- Sean Young
+
+
+
+=== 9: License ===
+
+Unless specified otherwise, the Mozilla Public License v2.0 is used.
+See the "LICENSE.txt" file for license details.
+
+The file "include/armadillo_bits/fft_engine.hpp" is licensed under
+both the Mozilla Public License v2.0 and a 3-clause BSD license.
+See "include/armadillo_bits/fft_engine.hpp" for license details.
+
+
Binary file armadillo-3.900.4/armadillo_icon.png has changed
Binary file armadillo-3.900.4/armadillo_nicta_2010.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/cmake/InstallFiles/ArmadilloConfig.cmake.in	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,16 @@
+# - Config file for the Armadillo package
+# It defines the following variables
+#  ARMADILLO_INCLUDE_DIRS - include directories for Armadillo
+#  ARMADILLO_LIBRARY_DIRS - library directories for Armadillo (normally not used!)
+#  ARMADILLO_LIBRARIES    - libraries to link against
+
+# Tell the user project where to find our headers and libraries
+set(ARMADILLO_INCLUDE_DIRS "@ARMADILLO_INCLUDE_DIRS@")
+set(ARMADILLO_LIBRARY_DIRS "@ARMADILLO_LIB_DIR@")
+
+# Our library dependencies (contains definitions for IMPORTED targets)
+include("@ARMADILLO_CMAKE_DIR@/ArmadilloLibraryDepends.cmake")
+
+# These are IMPORTED targets created by ArmadilloLibraryDepends.cmake
+set(ARMADILLO_LIBRARIES armadillo)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/cmake/InstallFiles/ArmadilloConfigVersion.cmake.in	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,11 @@
+set(PACKAGE_VERSION "@ARMADILLO_VERSION@")
+
+# Check whether the requested PACKAGE_FIND_VERSION is compatible
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
+  set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+  set(PACKAGE_VERSION_COMPATIBLE TRUE)
+  if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
+    set(PACKAGE_VERSION_EXACT TRUE)
+  endif()
+endif()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/cmake/Modules/ARMA_CheckMathProto.cmake	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,51 @@
+# - Check if the prototype for a single argument math function exists.
+# ARMA_CHECK_MATH_PROTO (FUNCTION NAMESPACE HEADER VARIABLE)
+#
+#  FUNCTION  - the name of the single argument math function you are looking for
+#  NAMESPACE - the name of the namespace
+#  HEADER    - the header(s) where the prototype should be declared
+#  VARIABLE  - variable to store the result
+#
+# The following variables may be set before calling this macro to
+# modify the way the check is run:
+#
+#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
+#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+#  CMAKE_REQUIRED_INCLUDES = list of include directories
+
+# adapted from "CheckPrototypeExists.cmake"
+# ( http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/CheckPrototypeExists.cmake )
+# on 2009-06-19 by Conrad Sanderson (conradsand at ieee dot org)
+
+# original copyright for "CheckPrototypeExists.cmake":
+#
+# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+INCLUDE(CheckCXXSourceCompiles)
+
+MACRO (ARMA_CHECK_MATH_PROTO _SYMBOL _NAMESPACE _HEADER _RESULT)
+
+  SET(_INCLUDE_FILES)
+
+  FOREACH (it ${_HEADER})
+    SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
+  ENDFOREACH (it)
+   
+  SET(_TMP_SOURCE_CODE "
+${_INCLUDE_FILES}
+int main()
+  {
+  #if !defined(${_SYMBOL})
+    int i = (${_NAMESPACE}::${_SYMBOL})(1.0);
+  #endif
+  return 0;
+  }
+")
+
+  CHECK_CXX_SOURCE_COMPILES("${_TMP_SOURCE_CODE}" ${_RESULT})
+
+ENDMACRO (ARMA_CHECK_MATH_PROTO _SYMBOL _NAMESPACE _HEADER _RESULT)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/cmake/Modules/ARMA_CheckProto.cmake	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,53 @@
+# - Check if the prototype for a non-overloaded function exists in a specified namespace.
+# ARMA_CHECK_PROTO (FUNCTION NAMESPACE HEADER VARIABLE)
+#
+#  FUNCTION  - the name of the function you are looking for
+#  NAMESPACE - the name of the namespace
+#  HEADER    - the header(s) where the prototype should be declared
+#  VARIABLE  - variable to store the result
+#
+# The following variables may be set before calling this macro to
+# modify the way the check is run:
+#
+#  CMAKE_REQUIRED_FLAGS = string of compile command line flags
+#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+#  CMAKE_REQUIRED_INCLUDES = list of include directories
+
+# adapted from "CheckPrototypeExists.cmake"
+# ( http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/CheckPrototypeExists.cmake )
+# on 2009-06-19 by Conrad Sanderson (conradsand at ieee dot org)
+
+# original copyright for "CheckPrototypeExists.cmake":
+# 
+# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+INCLUDE(CheckCXXSourceCompiles)
+
+MACRO (ARMA_CHECK_PROTO _SYMBOL _NAMESPACE _HEADER _RESULT)
+
+  SET(_INCLUDE_FILES)
+
+  FOREACH (it ${_HEADER})
+    SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
+  ENDFOREACH (it)
+
+  SET(_TMP_SOURCE_CODE "
+${_INCLUDE_FILES}
+int
+main()
+  {
+  #if !defined(${_SYMBOL})
+    int i = sizeof(&(${_NAMESPACE}::${_SYMBOL}));
+  #endif
+  return 0;
+  }
+")
+
+  CHECK_CXX_SOURCE_COMPILES("${_TMP_SOURCE_CODE}" ${_RESULT})
+
+ENDMACRO (ARMA_CHECK_PROTO _SYMBOL _NAMESPACE _HEADER _RESULT)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindACML.cmake	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,37 @@
+# - Find AMD's ACML library (no includes) which provides optimised BLAS and LAPACK functions
+# This module defines
+#  ACML_LIBRARIES, the libraries needed to use ACML.
+#  ACML_FOUND, If false, do not try to use ACML.
+# also defined, but not for general use are
+#  ACML_LIBRARY, where to find the ACML library.
+
+SET(ACML_NAMES ${ACML_NAMES} acml)
+FIND_LIBRARY(ACML_LIBRARY
+  NAMES ${ACML_NAMES}
+  PATHS /usr/lib64 /usr/lib /usr/*/lib64 /usr/*/lib /usr/*/gfortran64/lib/ /usr/*/gfortran32/lib/ /usr/local/lib64 /usr/local/lib /opt/lib64 /opt/lib /opt/*/lib64 /opt/*/lib /opt/*/gfortran64/lib/ /opt/*/gfortran32/lib/
+  )
+
+IF (ACML_LIBRARY)
+  SET(ACML_LIBRARIES ${ACML_LIBRARY})
+  SET(ACML_FOUND "YES")
+ELSE (ACML_LIBRARY)
+  SET(ACML_FOUND "NO")
+ENDIF (ACML_LIBRARY)
+
+
+IF (ACML_FOUND)
+   IF (NOT ACML_FIND_QUIETLY)
+      MESSAGE(STATUS "Found the ACML library: ${ACML_LIBRARIES}")
+   ENDIF (NOT ACML_FIND_QUIETLY)
+ELSE (ACML_FOUND)
+   IF (ACML_FIND_REQUIRED)
+      MESSAGE(FATAL_ERROR "Could not find the ACML library")
+   ENDIF (ACML_FIND_REQUIRED)
+ENDIF (ACML_FOUND)
+
+# Deprecated declarations.
+GET_FILENAME_COMPONENT (NATIVE_ACML_LIB_PATH ${ACML_LIBRARY} PATH)
+
+MARK_AS_ADVANCED(
+  ACML_LIBRARY
+  )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindACMLMP.cmake	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,37 @@
+# - Find AMD's ACMLMP library (no includes) which provides optimised and parallelised BLAS and LAPACK functions
+# This module defines
+#  ACMLMP_LIBRARIES, the libraries needed to use ACMLMP.
+#  ACMLMP_FOUND, If false, do not try to use ACMLMP.
+# also defined, but not for general use are
+#  ACMLMP_LIBRARY, where to find the ACMLMP library.
+
+SET(ACMLMP_NAMES ${ACMLMP_NAMES} acml_mp)
+FIND_LIBRARY(ACMLMP_LIBRARY
+  NAMES ${ACMLMP_NAMES}
+  PATHS /usr/lib64 /usr/lib /usr/*/lib64 /usr/*/lib /usr/*/gfortran64_mp/lib/ /usr/*/gfortran32_mp/lib/ /usr/local/lib64 /usr/local/lib /opt/lib64 /opt/lib /opt/*/lib64 /opt/*/lib /opt/*/gfortran64_mp/lib/ /opt/*/gfortran32_mp/lib/
+  )
+
+IF (ACMLMP_LIBRARY)
+  SET(ACMLMP_LIBRARIES ${ACMLMP_LIBRARY})
+  SET(ACMLMP_FOUND "YES")
+ELSE (ACMLMP_LIBRARY)
+  SET(ACMLMP_FOUND "NO")
+ENDIF (ACMLMP_LIBRARY)
+
+
+IF (ACMLMP_FOUND)
+   IF (NOT ACMLMP_FIND_QUIETLY)
+      MESSAGE(STATUS "Found the ACMLMP library: ${ACMLMP_LIBRARIES}")
+   ENDIF (NOT ACMLMP_FIND_QUIETLY)
+ELSE (ACMLMP_FOUND)
+   IF (ACMLMP_FIND_REQUIRED)
+      MESSAGE(FATAL_ERROR "Could not find the ACMLMP library")
+   ENDIF (ACMLMP_FIND_REQUIRED)
+ENDIF (ACMLMP_FOUND)
+
+# Deprecated declarations.
+GET_FILENAME_COMPONENT (NATIVE_ACMLMP_LIB_PATH ${ACMLMP_LIBRARY} PATH)
+
+MARK_AS_ADVANCED(
+  ACMLMP_LIBRARY
+  )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindBLAS.cmake	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,37 @@
+# - Find a BLAS library (no includes)
+# This module defines
+#  BLAS_LIBRARIES, the libraries needed to use BLAS.
+#  BLAS_FOUND, If false, do not try to use BLAS.
+# also defined, but not for general use are
+#  BLAS_LIBRARY, where to find the BLAS library.
+
+SET(BLAS_NAMES ${BLAS_NAMES} blas)
+FIND_LIBRARY(BLAS_LIBRARY
+  NAMES ${BLAS_NAMES}
+  PATHS /usr/lib64/atlas /usr/lib/atlas /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib
+  )
+
+IF (BLAS_LIBRARY)
+  SET(BLAS_LIBRARIES ${BLAS_LIBRARY})
+  SET(BLAS_FOUND "YES")
+ELSE (BLAS_LIBRARY)
+  SET(BLAS_FOUND "NO")
+ENDIF (BLAS_LIBRARY)
+
+
+IF (BLAS_FOUND)
+   IF (NOT BLAS_FIND_QUIETLY)
+      MESSAGE(STATUS "Found a BLAS library: ${BLAS_LIBRARIES}")
+   ENDIF (NOT BLAS_FIND_QUIETLY)
+ELSE (BLAS_FOUND)
+   IF (BLAS_FIND_REQUIRED)
+      MESSAGE(FATAL_ERROR "Could not find a BLAS library")
+   ENDIF (BLAS_FIND_REQUIRED)
+ENDIF (BLAS_FOUND)
+
+# Deprecated declarations.
+GET_FILENAME_COMPONENT (NATIVE_BLAS_LIB_PATH ${BLAS_LIBRARY} PATH)
+
+MARK_AS_ADVANCED(
+  BLAS_LIBRARY
+  )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindCBLAS.cmake	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,47 @@
+# - Find CBLAS (includes and library)
+# This module defines
+#  CBLAS_INCLUDE_DIR
+#  CBLAS_LIBRARIES
+#  CBLAS_FOUND
+# also defined, but not for general use are
+#  CBLAS_LIBRARY, where to find the library.
+
+FIND_PATH(CBLAS_INCLUDE_DIR cblas.h
+/usr/include/atlas/
+/usr/local/include/atlas/
+/usr/include/
+/usr/local/include/
+)
+
+SET(CBLAS_NAMES ${CBLAS_NAMES} cblas)
+FIND_LIBRARY(CBLAS_LIBRARY
+  NAMES ${CBLAS_NAMES}
+  PATHS /usr/lib64/atlas-sse3 /usr/lib64/atlas /usr/lib64 /usr/local/lib64/atlas /usr/local/lib64 /usr/lib/atlas-sse3 /usr/lib/atlas-sse2 /usr/lib/atlas-sse /usr/lib/atlas-3dnow /usr/lib/atlas /usr/lib /usr/local/lib/atlas /usr/local/lib
+  )
+
+IF (CBLAS_LIBRARY AND CBLAS_INCLUDE_DIR)
+    SET(CBLAS_LIBRARIES ${CBLAS_LIBRARY})
+    SET(CBLAS_FOUND "YES")
+ELSE (CBLAS_LIBRARY AND CBLAS_INCLUDE_DIR)
+  SET(CBLAS_FOUND "NO")
+ENDIF (CBLAS_LIBRARY AND CBLAS_INCLUDE_DIR)
+
+
+IF (CBLAS_FOUND)
+   IF (NOT CBLAS_FIND_QUIETLY)
+      MESSAGE(STATUS "Found a CBLAS library: ${CBLAS_LIBRARIES}")
+   ENDIF (NOT CBLAS_FIND_QUIETLY)
+ELSE (CBLAS_FOUND)
+   IF (CBLAS_FIND_REQUIRED)
+      MESSAGE(FATAL_ERROR "Could not find a CBLAS library")
+   ENDIF (CBLAS_FIND_REQUIRED)
+ENDIF (CBLAS_FOUND)
+
+# Deprecated declarations.
+SET (NATIVE_CBLAS_INCLUDE_PATH ${CBLAS_INCLUDE_DIR} )
+GET_FILENAME_COMPONENT (NATIVE_CBLAS_LIB_PATH ${CBLAS_LIBRARY} PATH)
+
+MARK_AS_ADVANCED(
+  CBLAS_LIBRARY
+  CBLAS_INCLUDE_DIR
+  )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindCLAPACK.cmake	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,48 @@
+# - Find a version of CLAPACK (includes and library)
+# This module defines
+#  CLAPACK_INCLUDE_DIR
+#  CLAPACK_LIBRARIES
+#  CLAPACK_FOUND
+# also defined, but not for general use are
+#  CLAPACK_LIBRARY, where to find the library.
+
+FIND_PATH(CLAPACK_INCLUDE_DIR clapack.h
+/usr/include/atlas/
+/usr/local/include/atlas/
+/usr/include/
+/usr/local/include/
+)
+
+SET(CLAPACK_NAMES ${CLAPACK_NAMES} lapack_atlas)
+SET(CLAPACK_NAMES ${CLAPACK_NAMES} clapack)
+FIND_LIBRARY(CLAPACK_LIBRARY
+  NAMES ${CLAPACK_NAMES}
+  PATHS /usr/lib64/atlas-sse3 /usr/lib64/atlas /usr/lib64 /usr/local/lib64/atlas /usr/local/lib64 /usr/lib/atlas-sse3 /usr/lib/atlas-sse2 /usr/lib/atlas-sse /usr/lib/atlas-3dnow /usr/lib/atlas /usr/lib /usr/local/lib/atlas /usr/local/lib
+  )
+
+IF (CLAPACK_LIBRARY AND CLAPACK_INCLUDE_DIR)
+    SET(CLAPACK_LIBRARIES ${CLAPACK_LIBRARY})
+    SET(CLAPACK_FOUND "YES")
+ELSE (CLAPACK_LIBRARY AND CLAPACK_INCLUDE_DIR)
+  SET(CLAPACK_FOUND "NO")
+ENDIF (CLAPACK_LIBRARY AND CLAPACK_INCLUDE_DIR)
+
+
+IF (CLAPACK_FOUND)
+   IF (NOT CLAPACK_FIND_QUIETLY)
+      MESSAGE(STATUS "Found a CLAPACK library: ${CLAPACK_LIBRARIES}")
+   ENDIF (NOT CLAPACK_FIND_QUIETLY)
+ELSE (CLAPACK_FOUND)
+   IF (CLAPACK_FIND_REQUIRED)
+      MESSAGE(FATAL_ERROR "Could not find a CLAPACK library")
+   ENDIF (CLAPACK_FIND_REQUIRED)
+ENDIF (CLAPACK_FOUND)
+
+# Deprecated declarations.
+SET (NATIVE_CLAPACK_INCLUDE_PATH ${CLAPACK_INCLUDE_DIR} )
+GET_FILENAME_COMPONENT (NATIVE_CLAPACK_LIB_PATH ${CLAPACK_LIBRARY} PATH)
+
+MARK_AS_ADVANCED(
+  CLAPACK_LIBRARY
+  CLAPACK_INCLUDE_DIR
+  )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindLAPACK.cmake	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,37 @@
+# - Find a LAPACK library (no includes)
+# This module defines
+#  LAPACK_LIBRARIES, the libraries needed to use LAPACK.
+#  LAPACK_FOUND, If false, do not try to use LAPACK.
+# also defined, but not for general use are
+#  LAPACK_LIBRARY, where to find the LAPACK library.
+
+SET(LAPACK_NAMES ${LAPACK_NAMES} lapack)
+FIND_LIBRARY(LAPACK_LIBRARY
+  NAMES ${LAPACK_NAMES}
+  PATHS /usr/lib64/atlas /usr/lib/atlas /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib
+  )
+
+IF (LAPACK_LIBRARY)
+  SET(LAPACK_LIBRARIES ${LAPACK_LIBRARY})
+  SET(LAPACK_FOUND "YES")
+ELSE (LAPACK_LIBRARY)
+  SET(LAPACK_FOUND "NO")
+ENDIF (LAPACK_LIBRARY)
+
+
+IF (LAPACK_FOUND)
+   IF (NOT LAPACK_FIND_QUIETLY)
+      MESSAGE(STATUS "Found a LAPACK library: ${LAPACK_LIBRARIES}")
+   ENDIF (NOT LAPACK_FIND_QUIETLY)
+ELSE (LAPACK_FOUND)
+   IF (LAPACK_FIND_REQUIRED)
+      MESSAGE(FATAL_ERROR "Could not find a LAPACK library")
+   ENDIF (LAPACK_FIND_REQUIRED)
+ENDIF (LAPACK_FOUND)
+
+# Deprecated declarations.
+GET_FILENAME_COMPONENT (NATIVE_LAPACK_LIB_PATH ${LAPACK_LIBRARY} PATH)
+
+MARK_AS_ADVANCED(
+  LAPACK_LIBRARY
+  )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindMKL.cmake	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,49 @@
+# - Find the MKL libraries (no includes)
+# This module defines
+#  MKL_LIBRARIES, the libraries needed to use Intel's implementation of BLAS & LAPACK.
+#  MKL_FOUND, If false, do not try to use MKL.
+
+SET(MKL_NAMES ${MKL_NAMES} mkl_lapack)
+SET(MKL_NAMES ${MKL_NAMES} mkl_intel_thread)
+SET(MKL_NAMES ${MKL_NAMES} mkl_core)
+SET(MKL_NAMES ${MKL_NAMES} guide)
+SET(MKL_NAMES ${MKL_NAMES} mkl)
+SET(MKL_NAMES ${MKL_NAMES} iomp5)
+#SET(MKL_NAMES ${MKL_NAMES} pthread)
+
+IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
+  SET(MKL_NAMES ${MKL_NAMES} mkl_intel_lp64)
+ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8)
+  SET(MKL_NAMES ${MKL_NAMES} mkl_intel)
+ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
+
+FOREACH (MKL_NAME ${MKL_NAMES})
+  FIND_LIBRARY(${MKL_NAME}_LIBRARY
+    NAMES ${MKL_NAME}
+    PATHS /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /opt/intel/lib/intel64 /opt/intel/lib/ia32 /opt/intel/mkl/lib/lib64 /opt/intel/mkl/lib/intel64 /opt/intel/mkl/lib/ia32 /opt/intel/mkl/lib /opt/intel/*/mkl/lib/intel64 /opt/intel/*/mkl/lib/ia32/ /opt/mkl/*/lib/em64t /opt/mkl/*/lib/32 /opt/intel/mkl/*/lib/em64t /opt/intel/mkl/*/lib/32
+    )
+
+  SET(TMP_LIBRARY ${${MKL_NAME}_LIBRARY})
+
+  IF(TMP_LIBRARY)
+    SET(MKL_LIBRARIES ${MKL_LIBRARIES} ${TMP_LIBRARY})
+  ENDIF(TMP_LIBRARY)
+ENDFOREACH(MKL_NAME)
+
+IF (MKL_LIBRARIES)
+  SET(MKL_FOUND "YES")
+ELSE (MKL_LIBRARIES)
+  SET(MKL_FOUND "NO")
+ENDIF (MKL_LIBRARIES)
+
+IF (MKL_FOUND)
+  IF (NOT MKL_FIND_QUIETLY)
+    MESSAGE(STATUS "Found MKL libraries: ${MKL_LIBRARIES}")
+  ENDIF (NOT MKL_FIND_QUIETLY)
+ELSE (MKL_FOUND)
+  IF (MKL_FIND_REQUIRED)
+    MESSAGE(FATAL_ERROR "Could not find MKL libraries")
+  ENDIF (MKL_FIND_REQUIRED)
+ENDIF (MKL_FOUND)
+
+# MARK_AS_ADVANCED(MKL_LIBRARY)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/cmake/Modules/ARMA_FindOpenBLAS.cmake	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,37 @@
+# - Find the OpenBLAS library (no includes)
+# This module defines
+#  OpenBLAS_LIBRARIES, the libraries needed to use OpenBLAS.
+#  OpenBLAS_FOUND, If false, do not try to use OpenBLAS.
+# also defined, but not for general use are
+#  OpenBLAS_LIBRARY, where to find the OpenBLAS library.
+
+SET(OpenBLAS_NAMES ${OpenBLAS_NAMES} openblas)
+FIND_LIBRARY(OpenBLAS_LIBRARY
+  NAMES ${OpenBLAS_NAMES}
+  PATHS /lib64 /lib /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib
+  )
+
+IF (OpenBLAS_LIBRARY)
+  SET(OpenBLAS_LIBRARIES ${OpenBLAS_LIBRARY})
+  SET(OpenBLAS_FOUND "YES")
+ELSE (OpenBLAS_LIBRARY)
+  SET(OpenBLAS_FOUND "NO")
+ENDIF (OpenBLAS_LIBRARY)
+
+
+IF (OpenBLAS_FOUND)
+   IF (NOT OpenBLAS_FIND_QUIETLY)
+      MESSAGE(STATUS "Found the OpenBLAS library: ${OpenBLAS_LIBRARIES}")
+   ENDIF (NOT OpenBLAS_FIND_QUIETLY)
+ELSE (OpenBLAS_FOUND)
+   IF (OpenBLAS_FIND_REQUIRED)
+      MESSAGE(FATAL_ERROR "Could not find the OpenBLAS library")
+   ENDIF (OpenBLAS_FIND_REQUIRED)
+ENDIF (OpenBLAS_FOUND)
+
+# Deprecated declarations.
+GET_FILENAME_COMPONENT (NATIVE_OpenBLAS_LIB_PATH ${OpenBLAS_LIBRARY} PATH)
+
+MARK_AS_ADVANCED(
+  OpenBLAS_LIBRARY
+  )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/doxygen/blank_footer.html	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,2 @@
+</BODY>
+</HTML>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/doxygen/doxygen.config	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,298 @@
+# Doxyfile 1.5.8
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+DOXYFILE_ENCODING      = UTF-8
+PROJECT_NAME           = "Armadillo Technical"
+PROJECT_NUMBER         = ""
+OUTPUT_DIRECTORY       = 
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = 
+ALWAYS_DETAILED_SEC    = YES
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = YES
+JAVADOC_AUTOBRIEF      = NO
+QT_AUTOBRIEF           = NO
+MULTILINE_CPP_IS_BRIEF = YES
+INHERIT_DOCS           = YES
+SEPARATE_MEMBER_PAGES  = NO
+TAB_SIZE               = 2
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+OPTIMIZE_FOR_FORTRAN   = NO
+OPTIMIZE_OUTPUT_VHDL   = NO
+EXTENSION_MAPPING      = 
+BUILTIN_STL_SUPPORT    = YES
+CPP_CLI_SUPPORT        = NO
+SIP_SUPPORT            = NO
+IDL_PROPERTY_SUPPORT   = YES
+DISTRIBUTE_GROUP_DOC   = NO
+SUBGROUPING            = YES
+TYPEDEF_HIDES_STRUCT   = NO
+SYMBOL_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+EXTRACT_ANON_NSPACES   = YES
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = NO
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = NO
+SORT_BRIEF_DOCS        = NO
+SORT_GROUP_NAMES       = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = NO
+SHOW_DIRECTORIES       = YES
+SHOW_FILES             = YES
+SHOW_NAMESPACES        = YES
+FILE_VERSION_FILTER    = 
+LAYOUT_FILE            = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+QUIET                  = YES
+WARNINGS               = NO
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+INPUT                  = build_aux/doxygen/ \
+                         include/ \
+                         include/armadillo_bits
+
+INPUT_ENCODING         = UTF-8
+
+FILE_PATTERNS          = armadillo \
+                         armadillo_itpp \
+                         *.hpp \
+                         *.doxy
+
+RECURSIVE              = NO
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXCLUDE_SYMBOLS        = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+SOURCE_BROWSER         = YES
+INLINE_SOURCES         = YES
+STRIP_CODE_COMMENTS    = NO
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS              = NO
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+ALPHABETICAL_INDEX     = YES
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+GENERATE_HTML          = YES
+HTML_OUTPUT            = docs_tech
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = build_aux/doxygen/blank_footer.html
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+HTML_DYNAMIC_SECTIONS  = NO
+GENERATE_DOCSET        = NO
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+CHM_INDEX_ENCODING     = 
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+GENERATE_QHP           = NO
+QCH_FILE               = 
+QHP_NAMESPACE          = 
+QHP_VIRTUAL_FOLDER     = doc
+QHP_CUST_FILTER_NAME   = 
+QHP_CUST_FILTER_ATTRS  = 
+QHP_SECT_FILTER_ATTRS  = 
+QHG_LOCATION           = 
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = YES
+TREEVIEW_WIDTH         = 250
+FORMULA_FONTSIZE       = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+ENABLE_PREPROCESSING   = NO
+MACRO_EXPANSION        = YES
+EXPAND_ONLY_PREDEF     = YES
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = NO
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+CLASS_DIAGRAMS         = YES
+MSCGEN_PATH            = 
+HIDE_UNDOC_RELATIONS   = NO
+HAVE_DOT               = NO
+DOT_FONTNAME           = FreeSans
+DOT_FONTSIZE           = 10
+DOT_FONTPATH           = 
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+GROUP_GRAPHS           = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = YES
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+CALLER_GRAPH           = NO
+GRAPHICAL_HIERARCHY    = YES
+DIRECTORY_GRAPH        = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+DOT_GRAPH_MAX_NODES    = 50
+MAX_DOT_GRAPH_DEPTH    = 0
+DOT_TRANSPARENT        = YES
+DOT_MULTI_TARGETS      = NO
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Options related to the search engine
+#---------------------------------------------------------------------------
+
+SEARCHENGINE           = NO
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/doxygen/main.doxy	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,19 @@
+/*!
+\mainpage
+
+\htmlonly
+
+<br>
+See the associated technical report for an overview of the internal architecture:
+<br>
+<ul>
+Conrad Sanderson.
+<br>Armadillo: An Open Source C++ Linear Algebra Library for Fast Prototyping and Computationally Intensive Experiments.
+<br>Technical Report, NICTA, 2010. 
+<br>
+<br><a href="http://arma.sourceforge.net/armadillo_nicta_2010.pdf">online PDF</a>
+
+</ul>
+
+\endhtmlonly
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/build_aux/rpm/armadillo.spec	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,260 @@
+Name:           armadillo
+Version:        3.800.0
+Release:        1%{?dist}
+Summary:        Fast C++ matrix library with interfaces to LAPACK and ATLAS
+
+Group:          Development/Libraries
+License:        MPLv2.0
+URL:            http://arma.sourceforge.net/
+Source:         http://sourceforge.net/projects/arma/files/%{name}-%{version}.tar.gz
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildRequires:  cmake, boost-devel, blas-devel, lapack-devel, atlas-devel
+
+%description
+Armadillo is a C++ linear algebra library (matrix maths)
+aiming towards a good balance between speed and ease of use.
+Integer, floating point and complex numbers are supported,
+as well as a subset of trigonometric and statistics functions.
+Various matrix decompositions are provided through optional
+integration with LAPACK and ATLAS libraries.
+A delayed evaluation approach is employed (during compile time)
+to combine several operations into one and reduce (or eliminate)
+the need for temporaries. This is accomplished through recursive
+templates and template meta-programming.
+This library is useful if C++ has been decided as the language
+of choice (due to speed and/or integration capabilities), rather
+than another language like Matlab or Octave.
+
+
+%package devel
+Summary:        Development headers and documentation for the Armadillo C++ library
+Group:          Development/Libraries
+Requires:       %{name} = %{version}-%{release}
+Requires:       boost-devel, blas-devel, lapack-devel, atlas-devel, libstdc++-devel
+
+# The header files of Armadillo include some Boost and ATLAS header files,
+# delivered within the boost-devel and atlas-devel sub-packages, respectively.
+# However, since there is no explicit dependency on Boost or ATLAS libraries
+# (most of Boost is delivered as header files only), the RPM building process
+# does not detect these dependencies.  These dependencies must therefore be
+# added manually.
+
+%description devel
+This package contains files necessary for development using the
+Armadillo C++ library. It contains header files, example programs,
+and user documentation (reference guide).
+
+
+%prep
+%setup -q
+
+# convert DOS end-of-line to UNIX end-of-line
+
+for file in README.txt; do
+  sed 's/\r//' $file >$file.new && \
+  touch -r $file $file.new && \
+  mv $file.new $file
+done
+
+%build
+%{cmake}
+%{__make} VERBOSE=1 %{?_smp_mflags}
+
+
+%install
+rm -rf $RPM_BUILD_ROOT
+%{__make} install DESTDIR=$RPM_BUILD_ROOT
+rm -f examples/Makefile.cmake
+rm -rf examples/example1_win32
+rm -rf examples/example2_win32
+rm -rf examples/lib_win32
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+
+%files
+%defattr(-,root,root,-)
+%{_libdir}/*.so.*
+%doc LICENSE.txt
+
+%files devel
+%defattr(-,root,root,-)
+%{_libdir}/*.so
+%{_includedir}/armadillo
+%{_includedir}/armadillo_bits/
+%{_datadir}/Armadillo/
+%doc README.txt index.html docs.html
+%doc examples armadillo_icon.png
+%doc armadillo_nicta_2010.pdf rcpp_armadillo_csda_2013.pdf
+
+%changelog
+* Sat Mar  2 2013 José Matos <jamatos@fedoraproject.org> - 3.800.0-1
+- Update to latest stable version
+- License changed from LGPLv3+ to MPLv2.0
+- Added another documentation file (rcpp related)
+- Spec changelog trimmed
+
+* Thu Feb 21 2013 José Matos <jamatos@fedoraproject.org> - 3.6.3-1
+- Update to latest stable release
+
+* Sun Feb 10 2013 Denis Arnaud <denis.arnaud_fedora@m4x.org> - 3.6.2-3
+- Rebuild for Boost-1.53.0
+
+* Sat Feb 09 2013 Denis Arnaud <denis.arnaud_fedora@m4x.org> - 3.6.2-2
+- Rebuild for Boost-1.53.0
+
+* Fri Feb  8 2013 José Matos <jamatos@fedoraproject.org> - 3.6.2-1
+- Update to latest stable release
+
+* Mon Dec 17 2012 José Matos <jamatos@fedoraproject.org> - 3.6.1-1
+- Update to latest stable release
+
+* Sat Dec  8 2012 José Matos <jamatos@fedoraproject.org> - 3.6.0-1
+- Update to latest stable release
+
+* Mon Dec  3 2012 José Matos <jamatos@fedoraproject.org> - 3.4.4-1
+- Update to latest stable release
+- Clean the spec files (documentation has a special treatment with rpm)
+
+* Wed Jul 25 2012 José Matos <jamatos@fedoraproject.org> - 3.2.4-1
+- Update to version 3.2.4
+
+* Wed Jul 18 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.2.3-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Thu Jan 12 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.2.3-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Thu Sep 15 2011 Conrad Sanderson - 2.2.3-1
+- spec updated for Armadillo 2.2.3
+
+* Mon Apr 18 2011 Conrad Sanderson - 1.2.0-1
+- spec updated for Armadillo 1.2.0
+
+* Mon Nov 15 2010 Conrad Sanderson - 1.0.0-1
+- spec updated for Armadillo 1.0.0
+
+* Thu Oct 14 2010 Conrad Sanderson - 0.9.90-1
+- spec updated for Armadillo 0.9.90
+
+* Tue Sep 21 2010 Conrad Sanderson - 0.9.80-1
+- spec updated for Armadillo 0.9.80
+
+* Wed Sep 01 2010 Conrad Sanderson - 0.9.70-1
+- spec updated for Armadillo 0.9.70
+
+* Wed Aug 04 2010 Conrad Sanderson - 0.9.60-1
+- spec updated for Armadillo 0.9.60
+
+* Wed Jul 14 2010 Conrad Sanderson - 0.9.52-1
+- spec updated for Armadillo 0.9.52
+
+* Wed Jul 07 2010 Conrad Sanderson - 0.9.50-1
+- spec updated for Armadillo 0.9.50
+
+* Wed Jun 02 2010 Conrad Sanderson - 0.9.10-1
+- spec updated for Armadillo 0.9.10
+
+* Fri May 14 2010 Conrad Sanderson - 0.9.8-1
+- spec updated for Armadillo 0.9.8
+
+* Tue Apr 28 2010 Conrad Sanderson - 0.9.6-1
+- spec updated for Armadillo 0.9.6
+
+* Tue Mar 16 2010 Conrad Sanderson - 0.9.4-1
+- spec updated for Armadillo 0.9.4
+
+* Tue Mar 02 2010 Conrad Sanderson - 0.9.2-2
+- added explicit dependencies to the devel package
+
+* Tue Mar 02 2010 Conrad Sanderson - 0.9.2-1
+- spec updated for Armadillo 0.9.2
+
+* Fri Feb 05 2010 Conrad Sanderson - 0.9.0-1
+- spec updated for Armadillo 0.9.0
+
+* Mon Jan 27 2010 Conrad Sanderson - 0.8.2-1
+- spec updated for Armadillo 0.8.2
+
+* Mon Dec 14 2009 Conrad Sanderson - 0.8.0-1
+- spec updated for Armadillo 0.8.0
+
+* Fri Oct 23 2009 Conrad Sanderson - 0.7.2-1
+- spec updated for Armadillo 0.7.2
+
+* Mon Oct 05 2009 Conrad Sanderson - 0.7.0-1
+- spec updated for Armadillo 0.7.0
+
+* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.12-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Wed Jul 06 2009  Conrad Sanderson - 0.6.12-2
+- added conversion of DOS end-of-line to UNIX end-of-line for README.txt
+
+* Wed Jun 22 2009  Conrad Sanderson - 0.6.12-1
+- spec updated for Armadillo 0.6.12
+
+* Wed Jun 15 2009  Conrad Sanderson - 0.6.11-8
+- cleanup of dependencies
+- explanation as to why boost-devel and atlas-devel are required by armadillo-devel
+
+* Wed Jun 09 2009  Conrad Sanderson - 0.6.11-7
+- explicit declaration of doc directory in the main package
+- explicitly marked doc files in both packages
+
+* Wed Jun 09 2009  Conrad Sanderson - 0.6.11-6
+- removed symlinks
+- placed all documentation and license files into one directory that is shared by both packages
+
+* Wed Jun 09 2009  Conrad Sanderson - 0.6.11-5
+- added symlinks to LICENSE.txt and licenses in the devel package
+
+* Wed Jun 08 2009  Conrad Sanderson - 0.6.11-4
+- added LICENSE.txt to the main package
+
+* Wed May 22 2009  Conrad Sanderson - 0.6.11-3
+- using cmake macro instead of directly calling cmake
+
+* Wed May 21 2009  Conrad Sanderson - 0.6.11-2
+- moved all text files to devel package to retain consistency with the layout in the original .tar.gz
+
+* Wed May 08 2009  Conrad Sanderson - 0.6.10-2
+- Removed several explicit build dependencies that are provided by default in Fedora
+- Simplified handling of doc files
+
+* Wed May 02 2009  Conrad Sanderson - 0.6.10-1
+- Updated spec file for Armadillo 0.6.10
+
+* Wed Apr 02 2009  Conrad Sanderson
+- Updated list of files in 0.6.7 release
+
+* Wed Apr 02 2009  Conrad Sanderson
+- Updated description
+
+* Wed Mar 24 2009  Conrad Sanderson
+- Added explicit dependence on libstdc++-devel
+
+* Wed Mar 17 2009  Conrad Sanderson
+- Simplified specification of directories
+- Removed library packages specified by "Requires", as library dependencies are detected automatically
+
+* Wed Mar 12 2009  Conrad Sanderson
+- Modified to generate separate devel package (subsumes previous doc package)
+- Removed redundant packages specified by "BuildRequires"
+- Added CMake installation prefixes to allow for x86_64
+
+* Wed Feb  4 2009  Conrad Sanderson
+- Modified to generate separate doc package
+
+* Thu Jan 28 2009  Conrad Sanderson
+- Added argument to cmake: -DCMAKE_INSTALL_PREFIX=/usr
+
+* Thu Jan 22 2009  Conrad Sanderson
+- Initial spec file prepared
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/configure	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+ABORT=no
+
+check_cmake()
+  {
+  (cmake --version) </dev/null >/dev/null 2>&1 ||
+    {
+    echo "error: cmake (version 2.6 or later) must be present to configure and install Armadillo"
+    echo ""
+    echo "cmake might be available as a package for your system,"
+    echo "or can be downloaded from http://cmake.org"
+    ABORT=yes
+    }
+  }
+
+check_cmake
+
+test "$ABORT" = yes && exit -1
+
+rm -f CMakeCache.txt
+cmake .
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/docs.html	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,11447 @@
+<!-- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -->
+<html>
+<head>
+  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
+  <title>Armadillo: API Reference</title>
+  <link rel="icon" href="armadillo_icon.png" type="image/png">
+  <style type="text/css">
+  <!--
+body
+  {
+  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
+  color: #000000;
+  background-color: #FFFFFF;
+  /* font-size: 10pt; */
+  /* line-height: 120%; */
+  height: 110%;
+  }
+
+pre
+  {
+  font-family: "DejaVu Sans Mono", "Liberation Mono", "Andale Mono", "Bitstream Vera Sans Mono", "Luxi Mono", monospace;
+  font-size: smaller;
+  color: #666666;
+  }
+
+a
+  {
+  text-decoration: none;
+  color: #498c05;
+  }
+
+a:hover
+  {
+  text-decoration: underline;
+  color: #498c05;
+  }
+
+a.menu
+  {
+  text-decoration: none;
+  color: #CCCCCC;
+  }
+
+a.menu:hover
+  {
+  text-decoration: none;
+  color: #498c05;
+  }
+
+a.hidden, a.hidden:hover, a.hidden:active, a.hidden:link, a.hidden:visited
+  {
+  text-decoration: none;
+  border-bottom: 0px
+  }
+
+table
+  {
+  /* border: 1px solid #000; */
+  /* display: block; */
+  border-collapse: collapse;
+  }
+
+td.line
+  {
+  border-left: 2px solid rgb(204, 204, 204);
+  }
+
+.footertext
+  {
+  position: relative;
+  bottom: 0px;
+  }
+
+hr.greyline
+  {
+  color: rgb(204, 204, 204);
+  /* background-color: rgb(204, 204, 204); */
+  }
+
+
+#nobreak
+  {
+  white-space: nowrap;
+  } 
+
+.noindent
+  {
+  text-indent:    0px;
+  margin-left:    1ex;
+  margin-right:   0ex;
+  margin-top:     0ex;
+  margin-bottom:  0ex;
+  padding-left:   1ex;
+  padding-right:  0ex;
+  padding-top:    0ex;
+  padding-bottom: 0ex;
+  list-style:     disc;
+  }
+  -->
+  </style>
+</head>
+<body>
+<center>
+<table style="text-align: left; width: 80%; margin-left: auto; margin-right: auto;" border="0" cellpadding="0" cellspacing="0">
+<tbody>
+<tr>
+<td style="vertical-align: top;">
+
+<table style="text-align: left; width: 100%;" border="0" cellpadding="0" cellspacing="0">
+  <tbody>
+    <tr>
+      <td style="text-align: left; vertical-align: top;">
+        <font size=+2><b>Reference for Armadillo 3.900</b></font>
+        <br>
+        <b>(Bavarian Sunflower)</b>
+      </td>
+      <td style="text-align: right; vertical-align: top;">
+        <b><a href="http://arma.sourceforge.net">to Armadillo home page</a></b>
+        <br>
+        <b><a href="http://nicta.com.au">to NICTA home page</a></b>
+        <br>
+      </td>
+    </tr>
+  </tbody>
+</table>
+<hr>
+<br>
+<br>
+<a name="top"></a>
+<a style="display:scroll; position:fixed; bottom:5px; right:5px;" href="#top"><font size=-1>[top]</font></a> 
+
+
+<!-- BEGIN CONTENT -->
+
+
+<b>Preamble</b>
+<br>
+<br>
+<table border="0" cellpadding="0" cellspacing="0">
+<tbody>
+<tr>
+<td style="text-align: left; vertical-align: top; width: 50%;">
+<ul>
+<li>
+To aid the conversion of Matlab/Octave programs,
+there is a <a href="#syntax">syntax conversion table</a>
+</li>
+<br>
+<li>
+First time users may want to have a look at a short <a href="#example_prog">example program</a>
+</li>
+<br>
+<li>
+If you find any bugs or regressions, please <a href="http://arma.sourceforge.net/faq.html">report them</a>
+</li>
+<br>
+<li>
+Notes on <a href="#api_additions">API additions</a>
+</li>
+</ul>
+</td>
+<td>
+&nbsp;
+</td>
+<td class="line" style="vertical-align: top;">
+<br>
+</td>
+<td style="text-align: left; vertical-align: top; width: 45%;">
+<ul>
+<li>
+Please cite the following tech report if you use Armadillo in your research and/or software.
+Citations are useful for the continued development and maintenance of the library.
+<br>
+<br>
+<font size=-1>
+Conrad Sanderson.
+<br>
+<i><a href="armadillo_nicta_2010.pdf">Armadillo: An Open Source C++ Linear Algebra Library for Fast Prototyping and Computationally Intensive Experiments</a></i>.
+<br>
+Technical Report, NICTA, 2010.
+</font>
+</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+
+<br>
+<br>
+
+<b>Matrix, Vector, Cube and Field Classes</b>
+<ul>
+<a href="#Mat">Mat&lt;<i>type</i>&gt;, mat and cx_mat</a>&nbsp;&middot;
+<a href="#Col">Col&lt;<i>type</i>&gt;, colvec and vec</a>&nbsp;&middot;
+<a href="#Row">Row&lt;<i>type</i>&gt;, rowvec</a>&nbsp;&middot;
+<a href="#Cube">Cube&lt;<i>type</i>&gt;, cube</a>&nbsp;&middot;
+<a href="#field">field&lt;<i>object&nbsp;type</i>&gt;</a>&nbsp;&middot;
+<a href="#SpMat">SpMat&lt;<i>type</i>&gt;, sp_mat and sp_cx_mat</a>
+</ul>
+<br>
+
+<b>Member Functions &amp; Variables</b>
+<ul>
+<a href="#attributes">attributes</a>&nbsp;&middot;
+<a href="#colptr">colptr</a>&nbsp;&middot;
+<a href="#copy_size">copy_size</a>&nbsp;&middot;
+<a href="#diag">diag</a>&nbsp;&middot;
+<a href="#each_colrow">each_col/each_row</a>&nbsp;&middot;
+<a href="#element_access">element&nbsp;access</a>&nbsp;&middot;
+<a href="#element_initialisation">element&nbsp;initialisation</a>&nbsp;&middot;
+<a href="#eval_member">eval</a>&nbsp;&middot;
+<a href="#eye_member">eye</a>&nbsp;&middot;
+<a href="#fill">fill</a>&nbsp;&middot;
+<a href="#i_member">i (inverse)</a>&nbsp;&middot;
+<a href="#imbue">imbue</a>&nbsp;&middot;
+<a href="#insert">insert rows/cols/slices</a>&nbsp;&middot;
+<a href="#in_range">in_range</a>&nbsp;&middot;
+<a href="#is_empty">is_empty</a>&nbsp;&middot;
+<a href="#is_finite">is_finite</a>&nbsp;&middot;
+<a href="#is_square">is_square</a>&nbsp;&middot;
+<a href="#is_vec">is_vec</a>&nbsp;&middot;
+<a href="#iterators_mat">iterators (matrices)</a>&nbsp;&middot;
+<a href="#iterators_cube">iterators (cubes)</a>&nbsp;&middot;
+<a href="#memptr">memptr</a>&nbsp;&middot;
+<a href="#min_and_max_member">min/max</a>&nbsp;&middot;
+<a href="#ones_member">ones</a>&nbsp;&middot;
+<a href="#operators">operators</a>&nbsp;&middot;
+<a href="#print">print</a>&nbsp;&middot;
+<a href="#raw_print">raw_print</a>&nbsp;&middot;
+<a href="#randu_randn_member">randu/randn</a>&nbsp;&middot;
+<a href="#reset">reset</a>&nbsp;&middot;
+<a href="#reshape_member">reshape</a>&nbsp;&middot;
+<a href="#resize_member">resize</a>&nbsp;&middot;
+<a href="#save_load_mat">save/load (matrices &amp; cubes)</a>&nbsp;&middot;
+<a href="#save_load_field">save/load (fields)</a>&nbsp;&middot;
+<a href="#set_imag">set_imag/real</a>&nbsp;&middot;
+<a href="#set_size">set_size</a>&nbsp;&middot;
+<a href="#shed">shed rows/cols/slices</a>&nbsp;&middot;
+<a href="#stl_container_fns">STL container functions</a>&nbsp;&middot;
+<a href="#submat">submatrix&nbsp;views</a>&nbsp;&middot;
+<a href="#subcube">subcube&nbsp;views</a>&nbsp;&middot;
+<a href="#subfield">subfield&nbsp;views</a>&nbsp;&middot;
+<a href="#swap">swap</a>&nbsp;&middot;
+<a href="#swap_rows">swap_rows/cols</a>&nbsp;&middot;
+<a href="#t_st_members">t/st (transpose)</a>&nbsp;&middot;
+<a href="#transform">transform</a>&nbsp;&middot;
+<a href="#zeros_member">zeros</a>
+</ul>
+<br>
+
+<b>Other Classes</b>
+<ul>
+<a href="#running_stat">running_stat&lt;<i>type</i>&gt;</a>&nbsp;&middot;
+<a href="#running_stat_vec">running_stat_vec&lt;<i>type</i>&gt;</a>&nbsp;&middot;
+<a href="#wall_clock">wall_clock</a>
+</ul>
+<br>
+
+<b>Generated Vectors/Matrices/Cubes</b>
+<ul>
+<a href="#eye_standalone">eye</a>&nbsp;&middot;
+<a href="#linspace">linspace</a>&nbsp;&middot;
+<a href="#ones_standalone">ones</a>&nbsp;&middot;
+<a href="#randu_randn_standalone">randu/randn</a>&nbsp;&middot;
+<a href="#repmat">repmat</a>&nbsp;&middot;
+<a href="#speye">speye</a>&nbsp;&middot;
+<a href="#sprandu_sprandn">sprandu/sprandn</a>&nbsp;&middot;
+<a href="#toeplitz">toeplitz/circ_toeplitz</a>&nbsp;&middot;
+<a href="#zeros_standalone">zeros</a>
+</ul>
+<br>
+
+<b>Functions Individually Applied to Each Element of a Matrix/Cube</b>
+<ul>
+<a href="#abs">abs</a>&nbsp;&middot;
+<a href="#eps">eps</a>&nbsp;&middot;
+<a href="#misc_fns">misc functions (exp, log, pow, sqrt, ...)</a>&nbsp;&middot;
+<a href="#trig_fns">trigonometric functions (cos, sin, ...)</a>
+</ul>
+<br>
+
+<b>Scalar Valued Functions of Vectors/Matrices/Cubes</b>
+<ul>
+<a href="#accu">accu</a>&nbsp;&middot;
+<a href="#as_scalar">as_scalar</a>&nbsp;&middot;
+<a href="#det">det</a>&nbsp;&middot;
+<a href="#dot">dot/cdot/norm_dot</a>&nbsp;&middot;
+<a href="#log_det">log_det</a>&nbsp;&middot;
+<a href="#norm">norm</a>&nbsp;&middot;
+<a href="#rank">rank</a>&nbsp;&middot;
+<a href="#trace">trace</a>
+</ul>
+<br>
+
+<b>Scalar/Vector Valued Functions of Vectors/Matrices</b>
+<ul>
+<a href="#diagvec">diagvec</a>&nbsp;&middot;
+<a href="#min_and_max">min/max</a>&nbsp;&middot;
+<a href="#prod">prod</a>&nbsp;&middot;
+<a href="#sum">sum</a>&nbsp;&middot;
+<a href="#stats_fns">statistics (mean, stddev, ...)</a>
+</ul>
+<br>
+
+<b>Vector/Matrix/Cube Valued Functions of Vectors/Matrices/Cubes</b>
+<ul>
+<a href="#conv">conv</a>&nbsp;&middot;
+<a href="#conv_to">conv_to</a>&nbsp;&middot;
+<a href="#conj">conj</a>&nbsp;&middot;
+<a href="#cor">cor</a>&nbsp;&middot;
+<a href="#cov">cov</a>&nbsp;&middot;
+<a href="#cross">cross</a>&nbsp;&middot;
+<a href="#cumsum">cumsum</a>&nbsp;&middot;
+<a href="#diagmat">diagmat</a>&nbsp;&middot;
+<a href="#find">find</a>&nbsp;&middot;
+<a href="#flip">fliplr/flipud</a>&nbsp;&middot;
+<a href="#hist">hist</a>&nbsp;&middot;
+<a href="#histc">histc</a>&nbsp;&middot;
+<a href="#imag_real">imag/real</a>&nbsp;&middot;
+<a href="#join">join&nbsp;rows/cols/slices</a>&nbsp;&middot;
+<a href="#kron">kron</a>&nbsp;&middot;
+<a href="#reshape">reshape</a>&nbsp;&middot;
+<a href="#resize">resize</a>&nbsp;&middot;
+<a href="#shuffle">shuffle</a>&nbsp;&middot;
+<a href="#sort">sort</a>&nbsp;&middot;
+<a href="#sort_index">sort_index</a>&nbsp;&middot;
+<a href="#symmat">symmatu/symmatl</a>&nbsp;&middot;
+<a href="#strans">strans</a>&nbsp;&middot;
+<a href="#trans">trans</a>&nbsp;&middot;
+<a href="#trimat">trimatu/trimatl</a>&nbsp;&middot;
+<a href="#unique">unique</a>
+</ul>
+<br>
+
+<b>Decompositions, Factorisations, Inverses and Equation Solvers</b>
+<ul>
+<a href="#chol">chol</a>&nbsp;&middot;
+<a href="#eig_sym">eig_sym</a>&nbsp;&middot;
+<a href="#eig_gen">eig_gen</a>&nbsp;&middot;
+<a href="#fft">fft/ifft</a>&nbsp;&middot;
+<a href="#inv">inv</a>&nbsp;&middot;
+<a href="#lu">lu</a>&nbsp;&middot;
+<a href="#pinv">pinv</a>&nbsp;&middot;
+<a href="#princomp">princomp</a>&nbsp;&middot;
+<a href="#qr">qr</a>&nbsp;&middot;
+<a href="#qr_econ">qr_econ</a>&nbsp;&middot;
+<a href="#solve">solve</a>&nbsp;&middot;
+<a href="#svd">svd</a>&nbsp;&middot;
+<a href="#svd_econ">svd_econ</a>&nbsp;&middot;
+<a href="#syl">syl</a>
+</ul>
+<br>
+
+<b>Miscellaneous</b>
+<ul>
+<a href="#is_finite_standalone">is_finite()</a>&nbsp;&middot;
+<a href="#logging">logging of errors/warnings</a>&nbsp;&middot;
+<a href="#constants">various constants (pi, inf, speed of light, ...)</a>&nbsp;&middot;
+<!--<a href="#log_add">log_add</a>&nbsp;&middot;-->
+<a href="#uword">uword/sword</a>&nbsp;&middot;
+<a href="#cx_float_double">cx_float/cx_double</a>&nbsp;&middot;
+<a href="#syntax">Matlab/Armadillo syntax differences</a>&nbsp;&middot;
+<a href="#example_prog">example program</a>&nbsp;&middot;
+<!--<a href="#catching_exceptions">catching exceptions</a>&nbsp;&middot;-->
+<a href="#config_hpp">config.hpp</a>&nbsp;&middot;
+<a href="#api_additions">API additions</a>
+</ul>
+<br>
+
+<br>
+<br>
+<hr class="greyline">
+<hr class="greyline">
+<br>
+<br>
+<font size=+1><b>Matrix, Vector, Cube and Field Classes</b></font>
+<br>
+<br>
+<hr class="greyline">
+<br>
+
+<a name="Mat"></a><b>Mat&lt;</b><i>type</i><b>&gt;</b>
+<br><b>mat</b>
+<br><b>cx_mat</b>
+<ul>
+<li>
+The root matrix class is <b>Mat&lt;</b><i>type</i><b>&gt;</b>, where <i>type</i> can be one of:
+<ul>
+<li>
+<i>float</i>, <i>double</i>, <i>std::complex&lt;float&gt;</i>, <i>std::complex&lt;double&gt;</i>,
+<i>char</i>, <i>short</i>, <i>int</i>, and unsigned versions of <i>char</i>, <i>short</i>, <i>int</i>.
+</li>
+</ul>
+</li>
+<br>
+<li>
+For convenience the following typedefs have been defined:
+<ul>
+<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      mat
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Mat&lt;double&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      fmat
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Mat&lt;float&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      cx_mat
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Mat&lt;<a href="#cx_float_double">cx_double</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      cx_fmat
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Mat&lt;<a href="#cx_float_double">cx_float</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      umat
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Mat&lt;<a href="#uword">uword</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      imat
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Mat&lt;<a href="#uword">sword</a>&gt;
+      </td>
+    </tr>
+  </tbody>
+</table>
+</ul>
+</li>
+<br>
+<li>
+In this documentation the <i>mat</i> type is used for convenience;
+it is possible to use other types instead, eg. <i>fmat</i>
+</li>
+<br>
+<li>
+Functions which are wrappers for LAPACK or ATLAS functions (generally matrix decompositions) are only valid for the following types:
+<i>fmat</i>, <i>mat</i>, <i>cx_fmat</i>, <i>cx_mat</i>
+</li>
+<br>
+<li>
+Elements are stored with column-major ordering (ie. column by column)
+</li>
+<br>
+<a name="constructors_mat"></a>
+<li>
+Constructors:
+<ul>
+<li>mat()</li>
+<li>mat(n_rows, n_cols)</li>
+<li>mat(mat)</li>
+<li>mat(vec)</li>
+<li>mat(rowvec)</li>
+<li>mat(string)</li>
+<li>mat(std::vector) &nbsp; (treated as a column vector)</li>
+<li>mat(initialiser_list) &nbsp; (C++11 only)</li>
+<li>cx_mat(mat,mat) &nbsp; (for constructing a complex matrix out of two real matrices)</li>
+</ul>
+</li>
+<br>
+<li>
+The string format for the constructor is elements separated by spaces, and rows denoted by semicolons.
+For example, the 2x2 identity matrix can be created using the format string <code>"1 0; 0 1"</code>.
+While string based initialisation is compact,
+directly <a href="#element_access">setting the elements</a>
+or using <a href="#element_initialisation">element initialisation</a> is considerably faster.
+</li>
+<br>
+<a name="adv_constructors_mat"></a>
+<li>
+Advanced constructors:
+<br>
+<br>
+<ul>
+<li>mat(aux_mem*, n_rows, n_cols, copy_aux_mem = true, strict = true)
+<br>
+<br>
+<ul>
+Create a matrix using data from writeable auxiliary memory.
+By default the matrix allocates its own memory and copies data from the auxiliary memory (for safety).
+However, if <i>copy_aux_mem</i> is set to <i>false</i>,
+the matrix will instead directly use the auxiliary memory (ie. no copying).
+This is faster, but can be dangerous unless you know what you're doing!
+<br>
+<br>
+The <i>strict</i> variable comes into effect only if <i>copy_aux_mem</i> is set to <i>false</i>
+(ie. the matrix is directly using auxiliary memory).
+If <i>strict</i> is set to <i>true</i>,
+the matrix will be bound to the auxiliary memory for its lifetime;
+the number of elements in the matrix can't be changed (directly or indirectly).
+If <i>strict</i> is set to <i>false</i>, the matrix will not be bound to the auxiliary memory for its lifetime,
+ie., the size of the matrix can be changed.
+If the requested number of elements is different to the size of the auxiliary memory,
+new memory will be allocated and the auxiliary memory will no longer be used.
+</ul>
+</li>
+<br>
+<li>mat(const aux_mem*, n_rows, n_cols)
+<br>
+<br>
+<ul>
+Create a matrix by copying data from read-only auxiliary memory.
+</ul>
+</li>
+<a name="adv_constructors_mat_fixed"></a>
+<br>
+<li>mat::fixed&lt;n_rows, n_cols&gt;
+<br>
+<br>
+<ul>
+Create a fixed size matrix, with the size specified via template arguments.
+Memory for the matrix is allocated at compile time.
+This is generally faster than dynamic memory allocation, but the size of the matrix can't be changed afterwards (directly or indirectly).
+<br>
+<br>
+For convenience, there are several pre-defined typedefs for each matrix type
+(where the types are: <i>umat</i>, <i>imat</i>, <i>fmat</i>, <i>mat</i>, <i>cx_fmat</i>, <i>cx_mat</i>).
+The typedefs specify a square matrix size, ranging from 2x2 to 9x9.
+The typedefs were defined by simply appending a two digit form of the size to the matrix type
+-- for example, <i>mat33</i> is equivalent to <i>mat::fixed&lt;3,3&gt;</i>,
+while <i>cx_mat44</i> is equivalent to <i>cx_mat::fixed&lt;4,4&gt;</i>.
+</ul>
+</li>
+<br>
+<li>mat::fixed&lt;n_rows, n_cols&gt;(const aux_mem*)
+<br>
+<br>
+<ul>
+Create a fixed size matrix, with the size specified via template arguments,
+and copying data from auxiliary memory.
+</ul>
+</li>
+</ul>
+</li>
+<br>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+double x = A(1,2);
+
+mat B = A + A;
+mat C = A * B;
+mat D = A % B;
+
+cx_mat X(A,B);
+
+B.zeros();
+B.set_size(10,10);
+B.zeros(5,6);
+
+//
+// fixed size matrices:
+
+mat::fixed&lt;5,6&gt; F;
+F.ones();
+
+mat44 G;
+G.randn();
+
+cout &lt;&lt; mat22().randu() &lt;&lt; endl;
+
+//
+// constructing matrices from
+// auxiliary (external) memory:
+
+double aux_mem[24];
+mat H(aux_mem, 4, 6, false);
+</pre>
+</ul>
+</li>
+<br>
+<li><b>Caveat:</b>
+For mathematical correctness, scalars are treated as 1x1 matrices during initialisation.
+As such, the code below <b>will not</b> generate a 5x5 matrix with every element equal to 123.0:
+<ul>
+<pre>
+mat A(5,5);  A = 123.0;
+</pre>
+</ul>
+Use the following code instead:
+<ul>
+<pre>
+mat A(5,5);  A.fill(123.0);
+</pre>
+</ul>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#attributes">matrix attributes</a></li>
+<li><a href="#element_access">accessing elements</a></li>
+<li><a href="#element_initialisation">initialising elements</a></li>
+<li><a href="#operators">math &amp; relational operators</a></li>
+<li><a href="#submat">submatrix views</a></li>
+<li><a href="#save_load_mat">saving &amp; loading matrices</a></li>
+<li><a href="#print">printing matrices</a></li>
+<li><a href="#iterators_mat">STL-style element iterators</a></li>
+<li><a href="#eval_member">.eval()</a></li>
+<li><a href="#conv_to">conv_to()</a> (convert between matrix types)</li>
+<li><a href="http://www.cplusplus.com/doc/tutorial/other_data_types/">explanation of <i>typedef</i></a> (cplusplus.com)
+<li><a href="#Col">Col class</a></li>
+<li><a href="#Row">Row class</a></li>
+<li><a href="#Cube">Cube class</a></li>
+<li><a href="#SpMat">SpMat class</a> (sparse matrix)</li>
+<li><a href="#config_hpp">config.hpp</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline">
+<br>
+
+<a name="Col"></a><b>Col&lt;</b><i>type</i><b>&gt;</b>
+<br><b>colvec</b>
+<br><b>vec</b>
+<ul>
+<li>
+Classes for column vectors (matrices with one column)
+</li>
+<br>
+<li>The <b>Col&lt;</b><i>type</i><b>&gt;</b> class is derived from the <b>Mat&lt;</b><i>type</i><b>&gt;</b> class
+and inherits most of the member functions
+</li>
+<br>
+<li>
+For convenience the following typedefs have been defined:
+<ul>
+<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      vec, colvec
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Col&lt;double&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      fvec, fcolvec
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Col&lt;float&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      cx_vec, cx_colvec
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Col&lt;<a href="#cx_float_double">cx_double</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      cx_fvec, cx_fcolvec
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Col&lt;<a href="#cx_float_double">cx_float</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      uvec, ucolvec
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Col&lt;<a href="#uword">uword</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      ivec, icolvec
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Col&lt;<a href="#uword">sword</a>&gt;
+      </td>
+    </tr>
+  </tbody>
+</table>
+</ul>
+</li>
+<br>
+<li>
+In this documentation, the <b><i>vec</i></b> and <b><i>colvec</i></b> types have the <b>same meaning</b> and are used <b>interchangeably</b>
+</li>
+<br>
+<li>
+In this documentation, the types <i>vec</i> or <i>colvec</i> are used for convenience; it is possible to use other types instead, eg.&nbsp;<i>fvec</i>, <i>fcolvec</i>
+</li>
+<br>
+<li>
+Functions which take <i>Mat</i> as input can generally also take <i>Col</i> as input.
+Main exceptions are functions which require square matrices
+</li>
+<br>
+<li>
+Constructors
+<ul>
+<li>vec(n_elem=0)</li>
+<li>vec(vec)</li>
+<li>vec(mat) &nbsp; (a <i>std::logic_error</i> exception is thrown if the given matrix has more than one column)</li>
+<li>vec(string) &nbsp; (elements separated by spaces)</li>
+<li>vec(std::vector)</li>
+<li>vec(initialiser_list) &nbsp; (C++11 only)</li>
+</ul>
+</li>
+<br>
+<a name="adv_constructors_col"></a>
+<li>
+Advanced constructors:
+<br>
+<br>
+<ul>
+<li>vec(aux_mem*, number_of_elements, copy_aux_mem = true, strict = true)
+<br>
+<br>
+<ul>
+Create a column vector using data from writeable auxiliary memory.
+By default the vector allocates its own memory and copies data from the auxiliary memory (for safety).
+However, if <i>copy_aux_mem</i> is set to <i>false</i>,
+the vector will instead directly use the auxiliary memory (ie. no copying).
+This is faster, but can be dangerous unless you know what you're doing!
+<br>
+<br>
+The <i>strict</i> variable comes into effect only if <i>copy_aux_mem</i> is set to <i>false</i>
+(ie. the vector is directly using auxiliary memory).
+If <i>strict</i> is set to <i>true</i>,
+the vector will be bound to the auxiliary memory for its lifetime;
+the number of elements in the vector can't be changed (directly or indirectly).
+If <i>strict</i> is set to <i>false</i>, the vector will not be bound to the auxiliary memory for its lifetime,
+ie., the vector's size can be changed.
+If the requested number of elements is different to the size of the auxiliary memory,
+new memory will be allocated and the auxiliary memory will no longer be used.
+</ul>
+</li>
+<br>
+<li>vec(const aux_mem*, number_of_elements)
+<br>
+<br>
+<ul>
+Create a column vector by copying data from read-only auxiliary memory.
+</ul>
+</li>
+<a name="adv_constructors_col_fixed"></a>
+<br>
+<li>vec::fixed&lt;number_of_elements&gt;
+<br>
+<br>
+<ul>
+Create a fixed size column vector, with the size specified via the template argument.
+Memory for the vector is allocated at compile time.
+This is generally faster than dynamic memory allocation, but the size of the vector can't be changed afterwards (directly or indirectly).
+<br>
+<br>
+For convenience, there are several pre-defined typedefs for each vector type
+(where the types are: <i>uvec</i>, <i>ivec</i>, <i>fvec</i>, <i>vec</i>, <i>cx_fvec</i>, <i>cx_vec</i> as well as the corresponding <i>colvec</i> versions).
+The pre-defined typedefs specify vector sizes ranging from 2 to 9.
+The typedefs were defined by simply appending a single digit form of the size to the vector type
+-- for example, <i>vec3</i> is equivalent to <i>vec::fixed&lt;3&gt;</i>,
+while <i>cx_vec4</i> is equivalent to <i>cx_vec::fixed&lt;4&gt;</i>.
+</ul>
+</li>
+<br>
+<li>vec::fixed&lt;number_of_elements&gt;(const aux_mem*)
+<br>
+<br>
+<ul>
+Create a fixed size column vector, with the size specified via the template argument,
+and copying data from auxiliary memory.
+</ul>
+</li>
+</ul>
+</li>
+<br>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec x(10);
+vec y = zeros&lt;vec&gt;(10,1);
+
+mat A = randu&lt;mat&gt;(10,10);
+vec z = A.col(5); // extract a column vector
+</pre>
+</ul>
+</li>
+<br>
+<li><b>Caveat:</b>
+For mathematical correctness, scalars are treated as 1x1 matrices during initialisation.
+As such, the code below <b>will not</b> generate a column vector with every element equal to 123.0:
+<ul>
+<pre>
+vec a(5);  a = 123.0;
+</pre>
+</ul>
+Use the following code instead:
+<ul>
+<pre>
+vec a(5);  a.fill(123.0);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#Mat">Mat class</a></li>
+<li><a href="#Row">Row class</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="Row"></a>
+<b>Row&lt;</b><i>type</i><b>&gt;</b>
+<br><b>rowvec</b>
+<ul>
+<li>
+Classes for row vectors (matrices with one row)
+</li>
+<br>
+<li>The template <b>Row&lt;</b><i>type</i><b>&gt;</b> class is derived from the <b>Mat&lt;</b><i>type</i><b>&gt;</b> class
+and inherits most of the member functions
+</li>
+<br>
+<li>
+For convenience the following typedefs have been defined:
+<ul>
+<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      rowvec
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Row&lt;double&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      frowvec
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Row&lt;float&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      cx_rowvec
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Row&lt;<a href="#cx_float_double">cx_double</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      cx_frowvec
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Row&lt;<a href="#cx_float_double">cx_float</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      urowvec
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Row&lt;<a href="#uword">uword</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      irowvec
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Row&lt;<a href="#uword">sword</a>&gt;
+      </td>
+    </tr>
+  </tbody>
+</table>
+</ul>
+</li>
+<br>
+<li>
+In this documentation, the <i>rowvec</i> type is used for convenience;
+it is possible to use other types instead, eg. <i>frowvec</i>
+</li>
+<br>
+<li>
+Functions which take <i>Mat</i> as input can generally also take <i>Row</i> as input.
+Main exceptions are functions which require square matrices
+</li>
+<br>
+<li>
+Constructors
+<ul>
+<li>rowvec(n_elem=0)</li>
+<li>rowvec(rowvec)</li>
+<li>rowvec(mat) &nbsp; (a <i>std::logic_error</i> exception is thrown if the given matrix has more than one row)</li>
+<li>rowvec(string) &nbsp; (elements separated by spaces)</li>
+<li>rowvec(std::vector)</li>
+<li>rowvec(initialiser_list) &nbsp; (C++11 only)</li>
+</ul>
+</li>
+<br>
+<a name="adv_constructors_row"></a>
+<li>
+Advanced constructors:
+<br>
+<br>
+<ul>
+<li>rowvec(aux_mem*, number_of_elements, copy_aux_mem = true, strict = true)
+<br>
+<br>
+<ul>
+Create a row vector using data from writeable auxiliary memory.
+By default the vector allocates its own memory and copies data from the auxiliary memory (for safety).
+However, if <i>copy_aux_mem</i> is set to <i>false</i>,
+the vector will instead directly use the auxiliary memory (ie. no copying).
+This is faster, but can be dangerous unless you know what you're doing!
+<br>
+<br>
+The <i>strict</i> variable comes into effect only if <i>copy_aux_mem</i> is set to <i>false</i>
+(ie. the vector is directly using auxiliary memory).
+If <i>strict</i> is set to <i>true</i>,
+the vector will be bound to the auxiliary memory for its lifetime;
+the number of elements in the vector can't be changed (directly or indirectly).
+If <i>strict</i> is set to <i>false</i>, the vector will not be bound to the auxiliary memory for its lifetime,
+ie., the vector's size can be changed.
+If the requested number of elements is different to the size of the auxiliary memory,
+new memory will be allocated and the auxiliary memory will no longer be used.
+</ul>
+</li>
+<br>
+<li>rowvec(const aux_mem*, number_of_elements)
+<br>
+<br>
+<ul>
+Create a row vector by copying data from read-only auxiliary memory.
+</ul>
+</li>
+<br>
+<li>rowvec::fixed&lt;number_of_elements&gt;
+<br>
+<br>
+<ul>
+Create a fixed size row vector, with the size specified via the template argument.
+Memory for the vector is allocated at compile time.
+This is generally faster than dynamic memory allocation, but the size of the vector can't be changed afterwards (directly or indirectly).
+<br>
+<br>
+For convenience, there are several pre-defined typedefs for each vector type
+(where the types are: <i>urowvec</i>, <i>irowvec</i>, <i>frowvec</i>, <i>rowvec</i>, <i>cx_frowvec</i>, <i>cx_rowvec</i>).
+The pre-defined typedefs specify vector sizes ranging from 2 to 9.
+The typedefs were defined by simply appending a single digit form of the size to the vector type
+-- for example, <i>rowvec3</i> is equivalent to <i>rowvec::fixed&lt;3&gt;</i>,
+while <i>cx_rowvec4</i> is equivalent to <i>cx_rowvec::fixed&lt;4&gt;</i>.
+</ul>
+</li>
+<br>
+<li>rowvec::fixed&lt;number_of_elements&gt;(const aux_mem*)
+<br>
+<br>
+<ul>
+Create a fixed size row vector, with the size specified via the template argument,
+and copying data from auxiliary memory.
+</ul>
+</li>
+</ul>
+</li>
+<br>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+rowvec x(10);
+rowvec y = zeros&lt;mat&gt;(1,10);
+
+mat A = randu&lt;mat&gt;(10,10);
+rowvec z = A.row(5); // extract a row vector
+</pre>
+</ul>
+</li>
+<br>
+<li>
+<b>Caveat:</b>
+For mathematical correctness, scalars are treated as 1x1 matrices during initialisation.
+As such, the code below <b>will not</b> generate a row vector with every element equal to 123.0:
+<ul>
+<pre>
+rowvec r(5);  r = 123.0;
+</pre>
+</ul>
+Use the following code instead:
+<ul>
+<pre>
+rowvec r(5);  r.fill(123.0);
+</pre>
+</ul>
+<br>
+<li>See also:
+<ul>
+<li><a href="#Mat">Mat class</a></li>
+<li><a href="#Col">Col class</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline">
+<br>
+
+<a name="Cube"></a>
+<b>Cube&lt;</b><i>type</i><b>&gt;</b>
+<br><b>cube</b>
+<br><b>cx_cube</b>
+<ul>
+<li>
+Classes for cubes, also known as "3D matrices" or 3rd order tensors
+</li>
+<br>
+<li>
+The cube class is <b>Cube&lt;</b><i>type</i><b>&gt;</b>, where <i>type</i> can be one of:
+<i>char</i>, <i>int</i>, <i>float</i>, <i>double</i>, <i>std::complex&lt;double&gt;</i>, etc
+</li>
+<br>
+<li>
+For convenience the following typedefs have been defined:
+<ul>
+<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      cube
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Cube&lt;double&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      fcube
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Cube&lt;float&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      cx_cube
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Cube&lt;<a href="#cx_float_double">cx_double</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      cx_fcube
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Cube&lt;<a href="#cx_float_double">cx_float</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      ucube
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Cube&lt;<a href="#uword">uword</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      icube
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      Cube&lt;<a href="#uword">sword</a>&gt;
+      </td>
+    </tr>
+  </tbody>
+</table>
+</ul>
+</li>
+<br>
+<li>
+In this documentation the <i>cube</i> type is used for convenience;
+it is possible to use other types instead, eg. <i>fcube</i>
+</li>
+<br>
+<li>
+Cube data is stored as a set of slices (matrices) stored contiguously within memory.
+Within each slice, elements are stored with column-major ordering (ie. column by column)
+</li>
+<br>
+<li>
+Each slice can be interpreted as a matrix, hence functions which take <i>Mat</i> as input can generally also take cube slices as input
+</li>
+<br>
+<a name="constructors_cube"></a>
+<li>
+Constructors:
+<ul>
+cube()
+<br>cube(cube)
+<br>cube(n_rows, n_cols, n_slices)
+<br>cx_cube(cube, cube) (for constructing a complex cube out of two real cubes)
+</ul>
+</li>
+<br>
+
+<a name="adv_constructors_cube"></a>
+<li>
+Advanced constructors:
+<br>
+<br>
+<ul>
+<li>
+cube::fixed&lt;n_rows, n_cols, n_slices&gt;
+<br>
+<br>
+<ul>
+Create a fixed size cube, with the size specified via template arguments.
+Memory for the cube is allocated at compile time.
+This is generally faster than dynamic memory allocation, but the size of the cube can't be changed afterwards (directly or indirectly).
+</ul>
+</li>
+<br>
+<li>cube(aux_mem*, n_rows, n_cols, n_slices, copy_aux_mem = true, strict = true)
+<br>
+<br>
+<ul>
+Create a cube using data from writeable auxiliary memory.
+By default the cube allocates its own memory and copies data from the auxiliary memory (for safety).
+However, if <i>copy_aux_mem</i> is set to <i>false</i>,
+the cube will instead directly use the auxiliary memory (ie. no copying).
+This is faster, but can be dangerous unless you know what you're doing!
+<br>
+<br>
+The <i>strict</i> variable comes into effect only if <i>copy_aux_mem</i> is set to <i>false</i>
+(ie. the cube is directly using auxiliary memory).
+If <i>strict</i> is set to <i>true</i>,
+the cube will be bound to the auxiliary memory for its lifetime;
+the number of elements in the cube can't be changed (directly or indirectly).
+If <i>strict</i> is set to <i>false</i>, the cube will not be bound to the auxiliary memory for its lifetime,
+ie., the size of the cube can be changed.
+If the requested number of elements is different to the size of the auxiliary memory,
+new memory will be allocated and the auxiliary memory will no longer be used.
+</ul>
+</li>
+<br>
+<li>cube(const aux_mem*, n_rows, n_cols, n_slices)
+<br>
+<br>
+<ul>
+Create a cube by copying data from read-only auxiliary memory.
+</ul>
+</li>
+</ul>
+</li>
+<br>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+cube x(1,2,3);
+cube y = randu&lt;cube&gt;(4,5,6);
+
+mat A = y.slice(1);  // extract a slice from the cube
+                     // (each slice is a matrix)
+
+mat B = randu&lt;mat&gt;(4,5);
+y.slice(2) = B;     // set a slice in the cube
+
+cube q = y + y;     // cube addition
+cube r = y % y;     // element-wise cube multiplication
+
+cube::fixed&lt;4,5,6&gt; f;
+f.ones();
+</pre>
+</ul>
+</li>
+<br>
+<li>
+<b>Caveats</b>
+<br>
+<br>
+<ul>
+<li>
+The size of individual slices can't be changed.
+For example, the following <b>will not</b> work:
+<ul>
+<pre>
+cube c(5,6,7);
+c.slice(0) = randu&lt;mat&gt;(10,20); // wrong size
+</pre>
+</ul>
+</li>
+<li>
+For mathematical correctness, scalars are treated as 1x1x1 cubes during initialisation.
+As such, the code below <b>will not</b> generate a cube with every element equal to 123.0:
+<ul>
+<pre>
+cube c(5,6,7);  c = 123.0;
+</pre>
+</ul>
+Use the following code instead:
+<ul>
+<pre>
+cube c(5,6,7);  c.fill(123.0);
+</pre>
+</ul>
+<br>
+</ul>
+<li>
+See also:
+<ul>
+<li><a href="#attributes">cube attributes</a></li>
+<li><a href="#element_access">accessing elements</a></li>
+<li><a href="#operators">math &amp; relational operators</a></li>
+<li><a href="#subcube">subcube views and slices</a></li>
+<li><a href="#save_load_mat">saving &amp; loading cubes</a></li>
+<li><a href="#iterators_cube">STL-style element iterators</a></li>
+<li><a href="#Mat">Mat class</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline">
+<br>
+
+<a name="field"></a>
+<b>field&lt;</b><i>object type</i><b>&gt;</b>
+<ul>
+<li>
+Class for one and two dimensional fields of arbitrary objects
+</li>
+<br>
+<li>
+Constructors (where <i>object type</i> is another class, eg. <i>std::string</i>, <i>mat</i>, <i>vec</i>, <i>rowvec</i>, etc):
+<ul>
+field&lt;<i>object type</i>&gt;(n_elem=0)
+<br>field&lt;<i>object type</i>&gt;(n_rows, n_cols)
+<br>field&lt;<i>object type</i>&gt;(field&lt;<i>object type</i>&gt;)
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+// create a field of strings
+field&lt;std::string&gt; S(3,2);
+
+S(0,0) = "hello";
+S(1,0) = "there";
+
+// string fields can be saved as plain text files
+S.save("string_field");
+
+// create a vec field with 3 rows and 2 columns
+field&lt;vec&gt; F(3,2);
+
+// access components of the field
+F(0,0) = vec(5);
+F(1,1) = randu&lt;vec&gt;(6);
+F(2,0).set_size(7);
+
+// access element 1 of the vec stored at 2,0
+double x = F(2,0)(1);
+
+// copy rows
+F.row(0) = F.row(2);
+
+// extract a row of vecs from F
+field&lt;vec&gt; G = F.row(1);
+
+// print the field to the standard output
+G.print("G =");
+
+// save the field to a binary file
+G.save("vec_field");
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#attributes">field attributes</a></li>
+<li><a href="#subfield">subfield views</a></li>
+<li><a href="#save_load_field">saving/loading fields</a></li>
+<li><a href="http://cplusplus.com/reference/string/string/">string class in the standard C++ library</a> (cplusplus.com)</li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline">
+<br>
+
+
+<a name="SpMat"></a><b>SpMat&lt;</b><i>type</i><b>&gt;</b>
+<br><b>sp_mat</b>
+<br><b>sp_cx_mat</b>
+<ul>
+<li>
+The root sparse matrix class is <b>SpMat&lt;</b><i>type</i><b>&gt;</b>, where <i>type</i> can be one of:
+<i>char</i>, <i>int</i>, <i>float</i>, <i>double</i>, <i>std::complex&lt;double&gt;</i>, etc.
+</li>
+<br>
+<li>
+For convenience the following typedefs have been defined:
+<ul>
+<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      sp_mat
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      SpMat&lt;double&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      sp_fmat
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      SpMat&lt;float&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      sp_cx_mat
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      SpMat&lt;<a href="#cx_float_double">cx_double</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      sp_cx_fmat
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      SpMat&lt;<a href="#cx_float_double">cx_float</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      sp_umat
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      SpMat&lt;<a href="#uword">uword</a>&gt;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      sp_imat
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;=&nbsp;
+      </td>
+      <td style="vertical-align: top;">
+      SpMat&lt;<a href="#uword">sword</a>&gt;
+      </td>
+    </tr>
+  </tbody>
+</table>
+</ul>
+</li>
+<br>
+<li>
+In this documentation the <i>sp_mat</i> type is used for convenience;
+it is possible to use other types instead, eg. <i>sp_fmat</i>
+</li>
+<br>
+<a name="constructors_sp_mat"></a>
+<li>
+Constructors:
+<ul>
+<li>sp_mat()</li>
+<li>sp_mat(n_rows, n_cols)</li>
+<li>sp_mat(sp_mat)</li>
+<li>sp_mat(string)</li>
+<li>sp_cx_mat(sp_mat,sp_mat) &nbsp; (for constructing a complex matrix out of two real matrices)</li>
+</ul>
+<br>
+<li>
+<a name="batch_constructors_sp_mat"></a>
+Batch insertion constructors:
+<ul>
+<li>sp_mat(locations, values, n_rows, n_cols, sort_locations = true)</li>
+<li>sp_mat(locations, values, sort_locations = true)</li>
+</ul>
+<br>
+<li>
+Elements are stored in the <i>compressed sparse column</i> (CSC) format
+</li>
+<br>
+<li>
+All elements are treated as zero by default
+</li>
+<br>
+<li>
+This class behaves in a similar manner to the <a href="#Mat">Mat</a> class,
+however, member functions which set all elements to non-zero values (and hence do not make sense for sparse matrices) have been deliberately omitted;
+examples of omitted functions: <a href="#fill">.fill()</a>, <a href="#ones_member">.ones()</a>, +=&nbsp;scalar, etc.
+</li>
+<br>
+
+<li>Batch insertion of values:
+<ul>
+<li>
+Using batch insertion constructors is generally much faster than consecutively inserting values using <a href="#element_access">element access operators</a>
+</li>
+<br>
+<li>
+<i>locations</i> is a dense matrix of type <i>umat</i>, with a size of <i>2</i>&nbsp;x&nbsp;<i>N</i>, where <i>N</i> is the number of values to be inserted.
+The row and column of the <i>i</i>-th element are specified as <i>locations(0,i)</i> and <i>locations(1,i)</i>, respectively.
+</li>
+<br>
+<li>
+<i>values</i> is a dense column vector containing the values to be inserted.
+It must have the same element type as the sparse matrix.
+The value in <i>values[i]</i> will be inserted at the location specified by the <i>i</i>-th column of the <i>locations</i> matrix.
+</li>
+<br>
+<li>
+The size of the constructed matrix is either manually specified via <i>n_rows</i> and <i>n_cols</i>,
+or automatically determined from the maximal locations in the <i>locations</i> matrix.
+</li>
+<br>
+<li>
+If <i>sort_locations</i> is set to <i>false</i>, the <i>locations</i> matrix is assumed to contain locations that are already sorted according to column-major ordering.
+</li>
+</ul>
+</li>
+<br>
+
+<li>
+<b>Caveat:</b>
+support for sparse matrices in this version is <b>preliminary</b>;
+it is not yet fully optimised, and sparse matrix decompositions/factorisations are not yet implemented.
+The following subset of operations currently works with sparse matrices:
+<ul>
+<li>element access</li>
+<li>fundamental arithmetic operations (such as addition and multiplication)</li>
+<li>submatrix views</li>
+<li>saving and loading (in <i>arma_binary</i> format)</li>
+<li>
+<a href="#abs">abs()</a>,
+<a href="#accu">accu()</a>,
+<a href="#as_scalar">as_scalar()</a>,
+<a href="#dot">dot()</a>,
+<a href="#stats_fns">mean()</a>,
+<a href="#min_and_max">min()</a>,
+<a href="#min_and_max">max()</a>,
+<a href="#norm">norm()</a>,
+<a href="#print">print()</a>,
+<a href="#speye">speye()</a>,
+<a href="#sprandu_sprandn">sprandu()/sprandn()</a>,
+<a href="#misc_fns">square()</a>,
+<a href="#misc_fns">sqrt()</a>,
+<a href="#sum">sum()</a>,
+<a href="#trace">trace()</a>,
+<a href="#trans">trans()</a>,
+<a href="#stats_fns">var()</a>
+</li>
+</ul>
+</li>
+<br>
+
+<li>
+Examples:
+<ul>
+<pre>
+sp_mat A(5,6);
+sp_mat B(6,5);
+
+A(0,0) = 1;
+A(1,0) = 2;
+
+B(0,0) = 3;
+B(0,1) = 4;
+
+sp_mat C = 2*B;
+
+sp_mat D = A*C;
+
+
+// batch insertion of two values at (5, 6) and (9, 9)
+umat locations;
+locations &lt;&lt; 5 &lt;&lt; 9 &lt;&lt; endr
+          &lt;&lt; 6 &lt;&lt; 9 &lt;&lt; endr;
+
+vec values;
+values &lt;&lt; 1.5 &lt;&lt; 3.2 &lt;&lt; endr;
+
+sp_mat X(locations, values);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#element_access">accessing elements</a></li>
+<li><a href="#print">printing matrices</a></li>
+<!--
+<li><a href="#SpCol">SpCol class</a> (TODO: add to documentation)</li>
+<li><a href="#SpRow">SpRow class</a> (TODO: add to documentation)</li>
+-->
+<li><a href="http://en.wikipedia.org/wiki/Sparse_matrix">Sparse Matrix in Wikipedia</a></li>
+<li><a href="#Mat">Mat class</a> (dense matrix)</li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline">
+<hr class="greyline">
+<br>
+<br>
+<font size=+1><b>Member Functions &amp; Variables</b></font>
+<br>
+<br>
+<hr class="greyline">
+<br>
+
+<a name="attributes"></a>
+
+<b>attributes</b>
+<ul>
+<table style="text-align: left;" border="0" cellpadding="0" cellspacing="0">
+<tbody>
+<tr>
+<td>
+<b>.n_rows</b>
+</td>
+<td>&nbsp;&nbsp;</td>
+<td>
+(number of rows)
+</td>
+</tr>
+<tr>
+<td>
+<b>.n_cols</b>
+</td>
+<td>&nbsp;&nbsp;</td>
+<td>
+(number of columns)
+</td>
+</tr>
+<tr>
+<td>
+<b>.n_elem</b>
+</td>
+<td>&nbsp;&nbsp;</td>
+<td>
+(total number of elements)
+</td>
+</tr>
+<tr>
+<td>
+<b>.n_slices</b>
+</td>
+<td>&nbsp;&nbsp;</td>
+<td>
+(number of slices)
+</td>
+</tr>
+<tr>
+<td>
+<b>.n_nonzero</b>
+</td>
+<td>&nbsp;&nbsp;</td>
+<td>
+(number of nonzero elements)
+</td>
+</tr>
+</tbody>
+</table>
+</ul>
+<br>
+<ul>
+<li>
+Member variables which are read-only;
+to change the size, use
+<a href="#set_size">.set_size()</a>,
+<a href="#copy_size">.copy_size()</a>,
+<a href="#zeros_member">.zeros()</a>,
+<a href="#ones_member">.ones()</a>,
+or
+<a href="#reset">.reset()</a>
+</li>
+<br>
+<li><i>n_rows</i>, <i>n_cols</i> and <i>n_elem</i> are applicable to <i>Mat</i>, <i>SpMat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i> classes</li>
+<br>
+<li><i>n_slices</i> is applicable only to the <i>Cube</i> class</li>
+<br>
+<li><i>n_nonzero</i> is applicable only to the <i>SpMat</i> class</li>
+<br>
+<li>
+For the <i>Col</i> and <i>Row</i> classes, <i>n_elem</i> also indicates vector length</li>
+<br>
+<li>The variables are of type <a href="#uword">uword</a></li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat X(4,5);
+cout &lt;&lt; "X has " &lt;&lt; X.n_cols &lt;&lt; " columns" &lt;&lt; endl;
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#set_size">.set_size()</a></li>
+<li><a href="#copy_size">.copy_size()</a></li>
+<li><a href="#zeros_member">.zeros()</a></li>
+<li><a href="#ones_member">.ones()</a></li>
+<li><a href="#reset">.reset()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="colptr"></a>
+<b>.colptr(col_number)</b>
+<ul>
+<li>
+Member function of <i>Mat</i>
+</li>
+<br>
+<li>
+Obtain a raw pointer to the memory used by the specified column
+</li>
+<br>
+<li>
+As soon as the size of the matrix is changed, the pointer is no longer valid
+</li>
+<br>
+<li>This function is not recommended for use unless you know what you're doing
+-- you may wish to use <a href="#submat">submatrix views</a> instead
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+
+double* mem = A.colptr(2);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#memptr">.memptr()</a></li>
+<li><a href="#submat">submatrix views</a></li>
+<li><a href="#element_access">element access</a></li>
+<li><a href="#iterators_mat">iterators (matrices)</a></li>
+<li><a href="#adv_constructors_mat">advanced constructors (matrices)</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="copy_size"></a>
+<b>.copy_size(A)</b>
+<ul>
+<li>
+Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i>
+</li>
+<br>
+<li>
+Set the size to be the same as object <i>A</i>
+</li>
+<br>
+<li>
+Object <i>A</i> must be of the same root type as the object being modified
+(eg. you can't set the size of a matrix by providing a cube)
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,6);
+mat B;
+B.copy_size(A);
+
+cout &lt;&lt; B.n_rows &lt;&lt; endl;
+cout &lt;&lt; B.n_cols &lt;&lt; endl;
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#reset">.reset()</a></li>
+<li><a href="#set_size">.set_size()</a></li>
+<li><a href="#reshape_member">.reshape()</a></li>
+<li><a href="#resize_member">.resize()</a></li>
+<li><a href="#zeros_member">.zeros()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="diag"></a>
+<b>.diag(</b><i>k=0</i><b>)</b>
+<ul>
+<li>
+Member function of <i>Mat</i>
+</li>
+<br>
+<li>
+Read/write access to the <i>k</i>-th diagonal in a matrix
+</li>
+<br>
+<li>The argument <i>k</i> is optional -- by default the main diagonal is accessed (<i>k=0</i>)</li>
+<br>
+<li>For <i>k &gt; 0</i>, the <i>k</i>-th super-diagonal is accessed (top-right corner)</li>
+<br>
+<li>For <i>k &lt; 0</i>, the <i>k</i>-th sub-diagonal is accessed (bottom-left corner)</li>
+<br>
+<li>
+An extracted diagonal is interpreted as a column vector
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat    X = randu&lt;mat&gt;(5,5);
+
+vec a = X.diag();
+vec b = X.diag(1);
+vec c = X.diag(-2);
+
+X.diag()  = randu&lt;vec&gt;(5);
+X.diag() += 6;
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#eye_member">.eye()</a></li>
+<li><a href="#diagvec">diagvec()</a></li>
+<li><a href="#diagmat">diagmat()</a></li>
+<li><a href="#submat">submatrix views</a></li>
+<li><a href="#each_colrow">.each_col() &amp; .each_row()</a></li>
+<li><a href="#trace">trace()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="each_colrow"></a>
+<b>.each_col()</b>
+<br>
+<b>.each_row()</b>
+<br>
+<br>
+<b>.each_col(</b><i>vector_of_indices</i><b>)</b>
+<br>
+<b>.each_row(</b><i>vector_of_indices</i><b>)</b>
+<ul>
+<li>
+Member functions of <i>Mat</i>
+</li>
+<br>
+<li>
+Write access to each column or row of a matrix/submatrix,
+allowing a vector operation to be repeated on each column or row
+</li>
+<br>
+<li>
+The operation can be in-place vector addition, subtraction, element-wise multiplication, element-wise division, or simply vector copy
+</li>
+<br>
+<li>The argument <i>vector_of_indices</i> is optional -- by default all columns or rows are accessed</li>
+<br>
+<li>
+If the argument <i>vector_of_indices</i> is used, it must evaluate to be a vector of type <i><a href="#Col">uvec</a></i>;
+the vector contains a list of indices of the columns or rows to be accessed
+</li>
+<br>
+<li>
+These functions were added in version 3.4
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat X = ones&lt;mat&gt;(6,5);
+vec v = linspace&lt;vec&gt;(10,15,6);
+
+// add v to each column in X
+X.each_col() += v;
+
+// subtract v from columns 0 through to 3 in X
+X.cols(0,3).each_col() -= v;
+
+uvec indices(2);
+indices(0) = 2;
+indices(1) = 4;
+
+// copy v to columns 2 and 4 in X
+X.each_col(indices) = v;
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#diag">diagonal views</a></li>
+<li><a href="#submat">submatrix views</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="element_access"></a>
+<b>element/object access via (), [] and .at()</b>
+<ul>
+<li>
+Provide access to individual elements or objects stored in a container object
+(ie., <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i>, <i>field</i>)<br>
+                    <br>
+<ul>
+                    <table style="text-align: left; width: 100%;"
+ border="0" cellpadding="2" cellspacing="2">
+                      <tbody>
+                        <tr>
+                          <td style="vertical-align: top;">
+                          <pre>(n)</pre>
+                          </td>
+                          <td style="vertical-align: top;">&nbsp;<br>
+                          </td>
+                          <td style="vertical-align: top;">
+For <i>vec</i> and <i>rowvec</i>, access the <i>n</i>-th element.
+For <i>mat</i>, <i>cube</i> and <i>field</i>, access the <i>n</i>-th element/object under the assumption of a flat layout,
+with column-major ordering of data (ie. column by column).
+A <i>std::logic_error</i> exception is thrown if the requested element is out of bounds.
+The bounds check can be <a href="#element_access_bounds_check_note">optionally disabled</a> at compile-time to get more speed.
+                          </td>
+                        </tr>
+<tr>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+</tr>
+                        <tr>
+                          <td style="vertical-align: top;">
+                          <pre>.at(n) and [n]</pre>
+                          </td>
+                          <td style="vertical-align: top;"><br>
+                          </td>
+                          <td style="vertical-align: top;">
+As for <i>(n)</i>, but without a bounds check.
+Not recommended for use unless your code has been thoroughly debugged.
+                          </td>
+                        </tr>
+<tr>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+</tr>
+                        <tr>
+                          <td style="vertical-align: top;">
+                          <pre>(i,j)</pre>
+                          </td>
+                          <td style="vertical-align: top;"><br>
+                          </td>
+                          <td style="vertical-align: top;">
+For <i>mat</i> and <i>field</i> classes, access the element/object stored at the <i>i</i>-th row and <i>j</i>-th column.
+A <i>std::logic_error</i> exception is thrown if the requested element is out of bounds.
+The bounds check can be <a href="#element_access_bounds_check_note">optionally disabled</a> at compile-time to get more speed.
+                          </td>
+                        </tr>
+<tr>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+</tr>
+                        <tr>
+                          <td style="vertical-align: top;">
+                          <pre>.at(i,j)</pre>
+                          </td>
+                          <td style="vertical-align: top;"><br>
+                          </td>
+                          <td style="vertical-align: top;">
+As for <i>(i,j)</i>, but without a bounds check.
+Not recommended for use unless your code has been thoroughly debugged.
+</td>
+                          <td style="vertical-align: top;"><br>
+                          </td>
+                        </tr>
+<tr>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+</tr>
+                        <tr>
+                          <td style="vertical-align: top;">
+                          <pre>(i,j,k)</pre>
+                          </td>
+                          <td style="vertical-align: top;"><br>
+                          </td>
+                          <td style="vertical-align: top;">
+Cube only: access the element stored at the <i>i</i>-th row, <i>j</i>-th column and <i>k</i>-th slice.
+A <i>std::logic_error</i> exception is thrown if the requested element is out of bounds.
+The bounds check can be <a href="#element_access_bounds_check_note">optionally disabled</a> at compile-time to get more speed.
+                          </td>
+                        </tr>
+<tr>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+</tr>
+                        <tr>
+                          <td style="vertical-align: top;">
+                          <pre>.at(i,j,k)</pre>
+                          </td>
+                          <td style="vertical-align: top;"><br>
+                          </td>
+                          <td style="vertical-align: top;">
+As for <i>(i,j,k)</i>, but without a bounds check.
+Not recommended for use unless your code has been thoroughly debugged.</td>
+                        </tr>
+                      </tbody>
+                    </table>
+</ul>
+</li>
+<br>
+<a name="element_access_bounds_check_note"></a>
+<li>
+The bounds checks used by the <i>(n)</i>, <i>(i,j)</i> and <i>(i,j,k)</i> access forms
+can be disabled by defining <a href="#config_hpp_arma_no_debug"><i>ARMA_NO_DEBUG</i></a> or <i>NDEBUG</i> macros 
+before including the <i>armadillo</i> header file (eg. <i>#define ARMA_NO_DEBUG</i>).
+Disabling the bounds checks is not recommended until your code has been thoroughly debugged
+-- it's better to write correct code first, and then maximise its speed.
+</li>
+<br>
+<li>
+<b>Note</b>: for <a href="#SpMat">sparse matrices</a>, using element access operators to insert values via loops can be inefficient;
+you may wish to use <a href="#batch_constructors_sp_mat">batch insertion constructors</a> instead
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(10,10);
+A(9,9) = 123.0;
+double x = A.at(9,9);
+double y = A[99];
+
+vec p = randu&lt;vec&gt;(10,1);
+p(9) = 123.0;
+double z = p[9];
+</pre>
+</ul>
+</li>                  
+<br>
+<li>See also:
+<ul>
+<li><a href="#in_range">.in_range()</a></li>
+<li><a href="#element_initialisation">element initialisation</a></li>
+<li><a href="#submat">submatrix views</a></li>
+<li><a href="#memptr">.memptr()</a></li>
+<li><a href="#iterators_mat">iterators (matrices)</a></li>
+<li><a href="#iterators_cube">iterators (cubes)</a></li>
+<li><a href="#config_hpp">config.hpp</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="element_initialisation"></a>
+<b>element initialisation</b>
+<ul>
+<li>
+Instances of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>field</i> classes can be initialised via repeated use of the &lt;&lt; operator
+</li>
+<br>
+<li>
+Special element <i>endr</i> indicates "end of row" (conceptually similar to <i>std::endl</i>)
+</li>
+<br>
+<li>
+Setting elements via &lt;&lt; is a bit slower than directly <a href="#element_access">accessing</a> the elements,
+but code using &lt;&lt; is generally more readable as well as being easier to write
+</li>
+<br>
+<li>
+If you have a C++11 compiler, instances of <i>Mat</i>, <i>Col</i> and <i>Row</i> classes can be also initialised via initialiser lists;
+this requires support for the C++11 standard to be <a href="#config_hpp_arma_use_cxx11">explicitly enabled</a>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A;
+
+A &lt;&lt; 1 &lt;&lt; 2 &lt;&lt; 3 &lt;&lt; endr
+  &lt;&lt; 4 &lt;&lt; 5 &lt;&lt; 6 &lt;&lt; endr;
+
+mat B = { 1, 2, 3, 4, 5, 6 };  // C++11 only
+B.reshape(2,3);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#element_access">element access</a></li>
+<li><a href="#print">.print()</a></li>
+<li><a href="#save_load_mat">saving &amp; loading matrices</a></li>
+<li><a href="#adv_constructors_mat">advanced constructors (matrices)</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="eval_member"></a>
+<b>.eval()</b>
+<br>
+<ul>
+<li>
+Member function of any matrix or vector expression
+</li>
+<br>
+<li>
+Explicitly forces the evaluation of a delayed expression and outputs a matrix
+</li>
+<br>
+<li>
+This function should be used sparingly and only in cases where it is absolutely necessary; indiscriminate use can cause slow downs
+</li>
+<br>
+<li>
+This function was added in version 3.2
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+cx_mat A( randu&lt;mat&gt;(4,4), randu&lt;mat&gt;(4,4) );
+
+real(A).eval().save("A_real.dat", raw_ascii);
+imag(A).eval().save("A_imag.dat", raw_ascii);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#Mat">Mat class</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="eye_member"></a>
+<b>.eye()</b>
+<br>
+<b>.eye(n_rows, n_cols)</b>
+<ul>
+<li>
+Set the elements along the main diagonal to one and off-diagonal elements set to zero,
+optionally first resizing to specified dimensions
+</li>
+<br>
+<li>
+An identity matrix is generated when <i>n_rows</i> = <i>n_cols</i>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A(5,5);
+A.eye();
+
+mat B;
+B.eye(5,5);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#ones_member">.ones()</a></li>
+<li><a href="#diag">.diag()</a></li>
+<li><a href="#diagmat">diagmat()</a></li>
+<li><a href="#diagvec">diagvec()</a></li>
+<li><a href="#eye_standalone">eye()</a> (standalone function)</li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="fill"></a>
+<b>.fill(</b>value<b>)</b>
+<ul>
+<li>
+Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i> classes.
+</li>
+<br>
+<li>Sets the elements to a specified value</li>
+<br>
+<li>the type of value must match the type of elements used by the container object (eg. for <i>mat</i> the type is double)
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A(5,5);
+A.fill(123.0);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#imbue">.imbue()</a></li>
+<li><a href="#ones_member">.ones()</a></li>
+<li><a href="#zeros_member">.zeros()</a></li>
+<li><a href="#randu_randn_member">.randu() &amp; .randn()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="i_member"></a>
+<b>.i(</b> <i>slow=false</i> <b>)</b>
+<ul>
+<li>
+Member function of any matrix expression
+</li>
+<br>
+<li>
+Provides an inverse of the matrix expression
+</li>
+<br>
+<li>the <i>slow</i> argument is optional</li>
+<br>
+<li>
+If the matrix expression is not square, a <i>std::logic_error</i> exception is thrown
+</li>
+<br>
+<li>
+If the matrix expression appears to be singular, the output matrix is reset and a <i>std::runtime_error</i> exception is thrown
+</li>
+<br>
+<li>
+For matrix sizes &le; 4x4, a fast inverse algorithm is used by default.
+In rare instances, the fast algorithm might be less precise than the standard algorithm.
+To force the use of the standard algorithm, set the <i>slow</i> argument to <i>true</i>
+</li>
+<br>
+<li>
+<b>NOTE:</b> in many cases it is more efficient/faster to use the <a href="#solve">solve()</a> function instead of performing a matrix inverse
+</li>
+<br>
+<li>
+This function was added in version 3.0
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(4,4);
+
+mat X = A.i();
+mat Y = (A+A).i();
+
+mat B = randu&lt;mat&gt;(4,1);
+mat Z = A.i() * B; // automatically converted to Z=solve(A,B)
+
+</pre>
+</ul>
+</li>
+<li>
+See also:
+<ul>
+<li><a href="#inv">inv()</a></li>
+<li><a href="#pinv">pinv()</a></li>
+<li><a href="#solve">solve()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="in_range"></a>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;"><b>.in_range(</b> i <b>)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i>)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.in_range( span(</b>start<b>,</b> end<b>) )</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i>)
+      </td>
+    </tr>
+    <tr>
+      <td>
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.in_range(</b> row<b>,</b> col <b>)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>field</i>)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.in_range( <font size=-1>span(</b>start_row<b>,</b> end_row<b>), span(</b>start_col<b>,</b> end_col<b>)</font> )</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>field</i>)
+      </td>
+    </tr>
+    <tr>
+      <td>
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.in_range(</b> row<b>,</b> col<b>,</b> slice <b>)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member of <i>Cube</i>)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.in_range( <font size=-1>span(</b>start_row<b>,</b> end_row<b>), span(</b>start_col<b>,</b> end_col<b>), span(</b>start_slice<b>,</b> end_slice<b>)</font> )</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member of <i>Cube</i>)
+      </td>
+    </tr>
+  </tbody>
+</table>
+<br>
+<ul>
+<li>Returns <i>true</i> if the given location or span is currently valid
+</li>
+<br>
+<li>Returns <i>false</i> if the object is empty, the location is out of bounds, or the span is out of bounds
+</li>
+<br>
+<li>
+Instances of <i>span(a,b)</i> can be replaced by:
+<ul>
+<li><i>span()</i> or <i>span::all</i>, to indicate the entire range</li>
+<li><i>span(a)</i>, to indicate a particular row, column or slice</li>
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(4,5);
+
+cout &lt;&lt; A.in_range(0,0) &lt;&lt; endl;  // true
+cout &lt;&lt; A.in_range(3,4) &lt;&lt; endl;  // true
+cout &lt;&lt; A.in_range(4,5) &lt;&lt; endl;  // false
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#element_access">element access</a></li>
+<li><a href="#submat">submatrix views</a></li>
+<li><a href="#subcube">subcube views</a></li>
+<li><a href="#subfield">subfield views</a></li>
+<li><a href="#set_size">.set_size()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="is_empty"></a>
+<b>.is_empty()</b>
+<ul>
+<li>
+Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i> classes
+</li>
+<br>
+<li>Returns true if the object has no elements
+</li>
+<br>
+<li>Returns false if the object has one or more elements
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+cout &lt;&lt; A.is_empty() &lt;&lt; endl;
+
+A.reset();
+cout &lt;&lt; A.is_empty() &lt;&lt; endl;
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#is_square">.is_square()</a></li>
+<li><a href="#is_vec">.is_vec()</a></li>
+<li><a href="#is_finite">.is_finite()</a></li>
+<li><a href="#reset">.reset()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="is_finite"></a>
+<b>.is_finite()</b>
+<ul>
+<li>
+Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i> classes
+</li>
+<br>
+<li>Returns <i>true</i> if all elements of the object are finite
+</li>
+<br>
+<li>Returns <i>false</i> if at least one of the elements of the object is non-finite (&plusmn;infinity or NaN)
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+mat B = randu&lt;mat&gt;(5,5);
+
+B(1,1) = datum::nan;
+
+cout &lt;&lt; A.is_finite() &lt;&lt; endl;
+cout &lt;&lt; B.is_finite() &lt;&lt; endl;
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#constants">datum::nan</a></li>
+<li><a href="#constants">datum::inf</a></li>
+<li><a href="#is_finite_standalone">is_finite()</a> (standalone function)</li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="is_square"></a>
+<b>.is_square()</b>
+<ul>
+<li>
+Member function of the <i>Mat</i> class
+</li>
+<br>
+<li>Returns <i>true</i> if the matrix is square, ie., number of rows is equal to the number of columns
+</li>
+<br>
+<li>Returns <i>false</i> if the matrix is not square
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+mat B = randu&lt;mat&gt;(6,7);
+
+cout &lt;&lt; A.is_square() &lt;&lt; endl;
+cout &lt;&lt; B.is_square() &lt;&lt; endl;
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#is_empty">.is_empty()</a></li>
+<li><a href="#is_vec">.is_vec()</a></li>
+<li><a href="#is_finite">.is_finite()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="is_vec"></a>
+<b>.is_vec()</b>
+<br><b>.is_colvec()</b>
+<br><b>.is_rowvec()</b>
+<ul>
+<li>
+Member functions of the <i>Mat</i> class
+</li>
+<br>
+
+<li>.is_vec():
+<ul>
+<li>Returns <i>true</i> if the matrix can be interpreted as a vector (either column or row vector)
+</li>
+<li>Returns <i>false</i> if the matrix does not have exactly one column or one row
+</li>
+</ul>
+</li>
+<br>
+
+<li>.is_colvec():
+<ul>
+<li>Returns <i>true</i> if the matrix can be interpreted as a column vector
+</li>
+<li>Returns <i>false</i> if the matrix does not have exactly one column
+</li>
+</ul>
+</li>
+<br>
+
+<li>.is_rowvec():
+<ul>
+<li>Returns <i>true</i> if the matrix can be interpreted as a row vector
+</li>
+<li>Returns <i>false</i> if the matrix does not have exactly one row
+</li>
+</ul>
+</li>
+<br>
+
+<li><b>Caveat:</b> do not assume that the vector has elements if these functions return <i>true</i> -- it is possible to have an empty vector (eg. 0x1)
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(1,5);
+mat B = randu&lt;mat&gt;(5,1);
+mat C = randu&lt;mat&gt;(5,5);
+
+cout &lt;&lt; A.is_vec() &lt;&lt; endl;
+cout &lt;&lt; B.is_vec() &lt;&lt; endl;
+cout &lt;&lt; C.is_vec() &lt;&lt; endl;
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#is_empty">.is_empty()</a></li>
+<li><a href="#is_square">.is_square()</a></li>
+<li><a href="#is_finite">.is_finite()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="imbue"></a>
+<b>.imbue(&nbsp;</b>functor<b>&nbsp;)</b>
+<br>
+<b>.imbue(&nbsp;</b>lambda function<b>&nbsp;)</b>&nbsp;&nbsp;&nbsp;<i>(C++11 only)</i>
+<br>
+<ul>
+<li>
+Imbue (fill) with values provided by a functor or lambda function
+</li>
+<br>
+<li>
+For matrices, filling is done column-by-column (ie. column 0 is filled, then column 1, ...)
+</li>
+<br>
+<li>
+For cubes, filling is done slice-by-slice; each slice is filled column-by-column
+</li>
+<br>
+<li>
+This function was added in version 3.800
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+// C++11 only example
+// need to include &lt;random&gt;
+
+std::mt19937 engine;  // Mersenne twister random number engine
+
+std::uniform_real_distribution&lt;double&gt; distr(0.0, 1.0);
+  
+mat A(4,5);
+  
+A.imbue( [&amp;]() { return distr(engine); } );
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#fill">.fill()</a></li>
+<li><a href="#transform">.transform()</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Function_object">function object</a> at Wikipedia</li>
+<li><a href="http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions">C++11 lambda functions</a> at Wikipedia</li>
+<li><a href="http://www.cprogramming.com/c++11/c++11-lambda-closures.html">lambda function</a> at cprogramming.com</li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="insert"></a>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.insert_rows(&nbsp;</b>row_number, X<b>&nbsp;)</b>
+      <br>
+      <b>.insert_rows(&nbsp;</b>row_number, number_of_rows, set_to_zero&nbsp;=&nbsp;true<b>&nbsp;)</b>
+      </td>
+      <td style="vertical-align: top;"><br></td>
+      <td style="vertical-align: top;">(member functions of <i>Mat</i> and <i>Col</i>)
+      </td>
+    </tr>
+    <tr>
+    <td>&nbsp;</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.insert_cols(&nbsp;</b>col_number, X<b>&nbsp;)</b>
+      <br>
+      <b>.insert_cols(&nbsp;</b>col_number, number_of_cols, set_to_zero&nbsp;=&nbsp;true<b>&nbsp;)</b>
+      </td>
+      <td style="vertical-align: top;"><br></td>
+      <td style="vertical-align: top;">(member functions of <i>Mat</i> and <i>Row</i>)
+      </td>
+    </tr>
+    <tr>
+    <td>&nbsp;</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.insert_slices(&nbsp;</b>slice_number, X<b>&nbsp;)</b>
+      <br>
+      <b>.insert_slices(&nbsp;</b>slice_number, number_of_slices, set_to_zero&nbsp;=&nbsp;true<b>&nbsp;)</b>
+      </td>
+      <td style="vertical-align: top;"><br></td>
+      <td style="vertical-align: top;">(member functions of <i>Cube</i>)
+      </td>
+    </tr>
+  </tbody>
+</table>
+<br>
+<ul>
+<li>
+Functions with the <i>X</i> argument: insert a copy of X at the specified row/column/slice
+<ul>
+<li>if inserting rows, X must have the same number of columns as the recipient object</li>
+<li>if inserting columns, X must have the same number of rows as the recipient object</li>
+<li>if inserting slices, X must have the same number of rows and columns as the recipient object (ie. all slices must have the same size)</li>
+</ul>
+</li>
+<br>
+<li>
+Functions with the <i>number_of_...</i> argument: expand the object by creating new rows/columns/slices.
+By default, the new rows/columns/slices are set to zero.
+If <i>set_to_zero</i> is <i>false</i>, the memory used by the new rows/columns/slices will not be initialised.
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,10);
+mat B = ones&lt;mat&gt;(5,2);
+
+// at column 2, insert a copy of B;
+// A will now have 12 columns
+A.insert_cols(2, B);
+
+// at column 1, insert 5 zeroed columns;
+// B will now have 7 columns
+B.insert_cols(1, 5);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#shed">shed rows/columns/slices</a></li>
+<li><a href="#join">join rows/columns/slices</a></li>
+<li><a href="#resize_member">.resize()</a></li>
+<li><a href="#submat">submatrix views</a></li>
+<li><a href="#subcube">subcube views</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="iterators_mat"></a>
+<b>iterators (matrices &amp; vectors)</b>
+<ul>
+<li>
+STL-style iterators and associated member functions of the <i>Mat</i>, <i>Col</i> and <i>Row</i> classes
+</li>
+<br>
+<li>
+iterator types:
+<br>
+<br>
+<ul>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>mat::iterator</b>
+      <br>
+      <b>vec::iterator</b>
+      <br>
+      <b>rowvec::iterator</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        random access iterators, for read/write access to elements
+        (which are stored column by column)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>mat::const_iterator</b>
+      <br>
+      <b>vec::const_iterator</b>
+      <br>
+      <b>rowvec::const_iterator</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        random access iterators, for read-only access to elements
+        (which are stored column by column)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>mat::col_iterator</b>
+      <br>
+      <b>vec::col_iterator</b>
+      <br>
+      <b>rowvec::col_iterator</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        random access iterators, for read/write access to the elements of a specific column
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>mat::const_col_iterator</b>
+      <br>
+      <b>vec::const_col_iterator</b>
+      <br>
+      <b>rowvec::const_col_iterator</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        random access iterators, for read-only access to the elements of a specific column
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>mat::row_iterator</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        rudimentary forward iterator, for read/write access to the elements of a specific row
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>mat::const_row_iterator</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        rudimentary forward iterator, for read-only access to the elements of a specific row
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>vec::row_iterator</b>
+      <br>
+      <b>rowvec::row_iterator</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        random access iterators, for read/write access to the elements of a specific row
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>vec::const_row_iterator</b>
+      <br>
+      <b>rowvec::const_row_iterator</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        random access iterators, for read-only access to the elements of a specific row
+      </td>
+    </tr>
+  </tbody>
+</table>
+</ul>
+</li>
+<br>
+<br>
+<li>
+Member functions:
+<br>
+<br>
+<ul>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.begin()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        iterator referring to the first element
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.end()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        iterator referring to the <i>past-the-end</i> element
+      </td>
+    </tr>
+    <tr>
+      <td>
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.begin_row(</b><i>row_number</i><b>)</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        iterator referring to the first element of the specified row
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.end_row(</b><i>row_number</i><b>)</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        iterator referring to the <i>past-the-end</i> element of the specified row
+      </td>
+    </tr>
+    <tr>
+      <td>
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.begin_col(</b><i>col_number</i><b>)</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        iterator referring to the first element of the specified column
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.end_col(</b><i>col_number</i><b>)</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        iterator referring to the <i>past-the-end</i> element of the specified column
+      </td>
+    </tr>
+  </tbody>
+</table>
+</ul>
+</li>
+<br>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat X = randu&lt;mat&gt;(5,5);
+
+
+mat::iterator a = X.begin();
+mat::iterator b = X.end();
+
+for(mat::iterator i=a; i!=b; ++i)
+  {
+  cout &lt;&lt; *i &lt;&lt; endl;
+  }
+
+
+mat::col_iterator c = X.begin_col(1);  // start of column 1
+mat::col_iterator d = X.end_col(3);    // end of column 3
+
+for(mat::col_iterator i=c; i!=d; ++i)
+  {
+  cout &lt;&lt; *i &lt;&lt; endl;
+  (*i) = 123.0;
+  }
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#stl_container_fns">STL container functions</a></li>
+<li><a href="http://cplusplus.com/reference/std/iterator/">iterator at cplusplus.com</a></li>
+<li><a href="#element_access">element access</a></li>
+<li><a href="#memptr">.memptr()</a></li>
+<li><a href="#colptr">.colptr()</a></li>
+<li><a href="#submat">submatrix views</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="iterators_cube"></a>
+<b>iterators (cubes)</b>
+<ul>
+<li>
+STL-style iterators and associated member functions of the <i>Cube</i> class
+</li>
+<br>
+<li>
+iterator types:
+<br>
+<br>
+<ul>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>cube::iterator</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        random access iterator, for read/write access to elements;
+        the elements are ordered slice by slice;
+        the elements within each slice are ordered column by column
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>cube::const_iterator</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        random access iterators, for read-only access to elements
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>cube::slice_iterator</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        random access iterator, for read/write access to the elements of a particular slice;
+        the elements are ordered column by column
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>cube::const_slice_iterator</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        random access iterators, for read-only access to the elements of a particular slice
+      </td>
+    </tr>
+  </tbody>
+</table>
+</ul>
+</li>
+<br>
+<br>
+<li>
+Member functions:
+<br>
+<br>
+<ul>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.begin()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        iterator referring to the first element
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.end()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        iterator referring to the <i>past-the-end</i> element
+      </td>
+    </tr>
+    <tr>
+      <td>
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.begin_slice(</b><i>slice_number</i><b>)</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        iterator referring to the first element of the specified slice
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.end_slice(</b><i>slice_number</i><b>)</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        iterator referring to the <i>past-the-end</i> element of the specified slice
+      </td>
+    </tr>
+  </tbody>
+</table>
+</ul>
+</li>
+<br>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+cube X = randu&lt;cube&gt;(2,3,4);
+
+
+cube::iterator a = X.begin();
+cube::iterator b = X.end();
+
+for(cube::iterator i=a; i!=b; ++i)
+  {
+  cout &lt;&lt; *i &lt;&lt; endl;
+  }
+
+
+cube::slice_iterator c = X.begin_slice(1);  // start of slice 1
+cube::slice_iterator d = X.end_slice(2);    // end of slice 2
+
+for(cube::slice_iterator i=c; i!=d; ++i)
+  {
+  cout &lt;&lt; *i &lt;&lt; endl;
+  (*i) = 123.0;
+  }
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="http://cplusplus.com/reference/std/iterator/">iterator at cplusplus.com</a></li>
+<li><a href="#element_access">element access</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="memptr"></a>
+<b>.memptr()</b>
+<ul>
+<li>
+Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i> classes
+</li>
+<br>
+<li>
+Obtain a raw pointer to the memory used for storing elements. Not recommended for use unless you know what you're doing!
+</li>
+<br>
+<li>
+The function can be used for interfacing with libraries such as <a href="http://www.fftw.org/">FFTW</a>
+</li>
+<br>
+<li>
+As soon as the size of the matrix/vector/cube is changed, the pointer is no longer valid
+</li>
+<br>
+<li>
+Data for matrices is stored in a column-by-column order
+</li>
+<br>
+<li>
+Data for cubes is stored in a slice-by-slice (matrix-by-matrix) order
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+      mat A = randu&lt;mat&gt;(5,5);
+const mat B = randu&lt;mat&gt;(5,5);
+
+      double* A_mem = A.memptr();
+const double* B_mem = B.memptr();
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#colptr">.colptr()</a></li>
+<li><a href="#element_access">element_access</a></li>
+<li><a href="#iterators_mat">iterators (matrices)</a></li>
+<li><a href="#iterators_cube">iterators (cubes)</a></li>
+<li><a href="#adv_constructors_mat">advanced constructors (matrices)</a></li>
+<li><a href="#adv_constructors_cube">advanced constructors (cubes)</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="min_and_max_member"></a>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;"><b>.min()</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member functions of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i>)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.max()</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">&nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">&nbsp;</td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">&nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.min(</b>&nbsp;index_of_min_val&nbsp;<b>)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member functions of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i>)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.max(</b>&nbsp;index_of_max_val&nbsp;<b>)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">&nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">&nbsp;</td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">&nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.min(</b>&nbsp;row_of_min_val<b>,</b> col_of_min_val&nbsp;<b>)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member functions of <i>Mat</i>)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.max(</b>&nbsp;row_of_max_val<b>,</b> col_of_max_val&nbsp;<b>)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">&nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">&nbsp;</td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">&nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.min(</b>&nbsp;row_of_min_val<b>,</b> col_of_min_val<b>,</b> slice_of_min_val&nbsp;<b>)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member functions of <i>Cube</i>)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.max(</b>&nbsp;row_of_max_val<b>,</b> col_of_max_val<b>,</b> slice_of_max_val&nbsp;<b>)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">&nbsp;
+      </td>
+    </tr>
+  </tbody>
+</table>
+<ul>
+<br>
+<li>
+Without arguments: return the extremum value of an object
+</li>
+<br>
+<li>
+With one or more arguments: return the extremum value of an object and store the location of the extremum value in the provided variable(s)
+</li>
+<br>
+<li>
+The provided variables must be of type <a href="#uword">uword</a>.
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec v = randu&lt;vec&gt;(10);
+
+cout &lt;&lt; "min value is " &lt;&lt; v.min() &lt;&lt; endl;
+
+
+uword  index;
+double min_val = v.min(index);
+
+cout &lt;&lt; "index of min value is " &lt;&lt; index &lt;&lt; endl;
+
+
+mat A = randu&lt;mat&gt;(5,5);
+
+uword  row;
+uword  col;
+double min_val2 = A.max(row,col);
+
+cout &lt;&lt; "max value is at " &lt;&lt; row &lt;&lt; ',' &lt;&lt; col &lt;&lt; endl;
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#min_and_max">min() &amp; max()</a> (standalone functions)</li>
+<li><a href="#running_stat">running_stat</a></li>
+<li><a href="#running_stat_vec">running_stat_vec</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="ones_member"></a>
+<b>.ones()</b>
+<br><b>.ones(n_elem)</b>
+<br><b>.ones(n_rows, n_cols)</b>
+<br><b>.ones(n_rows, n_cols, n_slices)</b>
+<ul>
+<li>
+Set the elements of an object to one, optionally first resizing to specified dimensions
+</li>
+<br>
+<li>
+<i>.ones()</i> and <i>.ones(n_elem)</i> are member functions of <i>Col</i> and <i>Row</i>
+</li>
+<br>
+<li>
+<i>.ones()</i> and <i>.ones(n_rows, n_cols)</i> are member functions of <i>Mat</i>
+</li>
+<br>
+<li>
+<i>.ones()</i> and <i>.ones(n_rows, n_cols, n_slices)</i> are member functions of <i>Cube</i>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,10);
+A.ones();      // sets all elements to one
+A.ones(10,20); // sets the size to 10 rows and 20 columns
+               // followed by setting all elements to one
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#ones_standalone">ones()</a> (standalone function)</li>
+<li><a href="#eye_member">.eye()</a></li>
+<li><a href="#zeros_member">.zeros()</a></li>
+<li><a href="#fill">.fill()</a></li>
+<li><a href="#imbue">.imbue()</a></li>
+<li><a href="#randu_randn_member">.randu()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="operators"></a>
+<b>operators: &nbsp; + &nbsp; - &nbsp; * &nbsp; / &nbsp; % &nbsp; == &nbsp; != &nbsp; &lt;= &nbsp; &gt;= &nbsp; &lt; &nbsp; &gt;</b>
+<ul>
+<li>
+Overloaded operators for <i>mat</i>, <i>vec</i>, <i>rowvec</i> and <i>cube</i> classes
+</li>
+<br>
+<li>
+Meanings:
+<br>
+<br>
+<ul>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;"><b>+</b></td>
+      <td style="vertical-align: top;">&nbsp;&nbsp;&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">Addition of two objects</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>-</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">Subtraction of one object from another or negation of an object</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>/</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">Element-wise division of an object by another object or a scalar</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>*</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">Matrix multiplication of two objects; not applicable to the <i>cube</i> class unless multiplying a cube by a scalar</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>%</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;"><a name="schur_product"></a>Schur product: element-wise multiplication of two objects</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>==</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">Element-wise equality evaluation of two objects; generates a matrix of type <i>umat</i> with entries that indicate whether at a given position the two elements from the two objects are equal (1) or not equal (0)</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>!=</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">Element-wise non-equality evaluation of two objects</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>&gt;=</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">As for ==, but the check is for "greater than or equal to"</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>&lt;=</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">As for ==, but the check is for "less than or equal to"</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>&gt;</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">As for ==, but the check is for "greater than"</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>&lt;</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">As for ==, but the check is for "less than"</td>
+    </tr>
+  </tbody>
+</table>
+</ul>
+</li>
+<br>
+<li>
+A <i>std::logic_error</i> exception is thrown if incompatible object sizes are used
+</li>
+<br>
+<li>
+If the +, - and % operators are chained, Armadillo will try to avoid the generation of temporaries;
+no temporaries are generated if all given objects are of the same type and size
+</li>
+<br>
+<li>
+If the * operator is chained, Armadillo will try to find an efficient ordering of the matrix multiplications
+</li>
+<br>
+<li>
+<b>Caveat:</b> operators involving an equality comparison (ie., ==, !=, &gt;=, &lt;=)
+may not work as expected for floating point element types (ie., <i>float</i>, <i>double</i>)
+due to the necessarily limited precision of these types;
+in other words, these operators are (in general) not recommended for matrices of type <i>mat</i> or <i>fmat</i>
+</li>
+<br>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,10);
+mat B = randu&lt;mat&gt;(5,10);
+mat C = randu&lt;mat&gt;(10,5);
+
+mat P = A + B;
+mat Q = A - B;
+mat R = -B;
+mat S = A / 123.0;
+mat T = A % B;
+mat U = A * C;
+
+// V is constructed without temporaries
+mat V = A + B + A + B;
+
+imat AA = "1 2 3; 4 5 6; 7 8 9;";
+imat BB = "3 2 1; 6 5 4; 9 8 7;";
+
+// compare elements
+umat ZZ = (AA >= BB);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#accu">accu()</a></li>
+<li><a href="#as_scalar">as_scalar()</a></li>
+<li><a href="#find">find()</a></li>
+<li><a href="#transform">.transform()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="print"></a>
+<b>.print(header="")</b>
+<br><b>.print(stream, header="")</b>
+<ul>
+<li>
+Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i>
+</li>
+<br>
+<li>
+The first form prints the contents of an object to the <i>std::cout</i> stream, with an optional header line
+</li>
+<br>
+<li>
+The second form prints to a user specified stream
+</li>
+<br>
+<li>
+It's also possible to print objects using the &lt;&lt; stream operator
+</li>
+<br>
+<li>
+Elements of a field can only be printed if there is an associated <i>operator&lt;&lt;</i> function defined
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+mat B = randu&lt;mat&gt;(6,6);
+
+A.print();
+
+// print a transposed version of A
+A.t().print();
+
+// "B:" is the optional header line
+B.print("B:");
+
+cout &lt;&lt; A &lt;&lt; endl;
+cout &lt;&lt; "B:" &lt;&lt; endl &lt;&lt; B &lt;&lt; endl;
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#raw_print">.raw_print()</a></li>
+<li><a href="#save_load_mat">saving &amp; loading matrices</a></li>
+<li><a href="#element_initialisation">initialising elements</a></li>
+<li><a href="#logging">logging of errors and warnings</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="raw_print"></a>
+<b>.raw_print(header="")</b>
+<br><b>.raw_print(stream, header="")</b>
+<ul>
+<li>
+Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i>
+</li>
+<br>
+<li>
+Similar to the <a href="#print">.print()</a> member function,
+with the difference being that no formatting of the output is done -- ie. the user can set the stream's parameters such as precision, cell width, etc.
+</li>
+<br>
+<li>
+If the cell width is set to zero, a space is printed between the elements
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+
+cout.precision(11);
+cout.setf(ios::fixed);
+
+A.raw_print(cout, "A =");
+</pre>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="randu_randn_member"></a>
+<b>.randu()</b>
+<br><b>.randu(n_elem)</b>
+<br><b>.randu(n_rows, n_cols)</b>
+<br><b>.randu(n_rows, n_cols, n_slices)</b>
+<br>
+<br>
+<b>.randn()</b>
+<br><b>.randn(n_elem)</b>
+<br><b>.randn(n_rows, n_cols)</b>
+<br><b>.randn(n_rows, n_cols, n_slices)</b>
+<ul>
+<li>
+Fill an object with random values, optionally first resizing to specified dimensions
+</li>
+<br>
+<li><i>.randu()</i> uses a uniform distribution in the [0,1] interval
+</li>
+<br>
+<li><i>.randn()</i> uses a normal/Gaussian distribution with zero mean and unit variance
+</li>
+<br>
+<li>
+To change the seed, use the <a href="http://cplusplus.com/reference/clibrary/cstdlib/srand/">std::srand()</a> function
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A(4,5);
+A.randu();
+
+mat B;
+B.randu(6,7);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#randu_randn_standalone">randu() &amp; randn()</a> (standalone functions)</li>
+<li><a href="#fill">.fill()</a></li>
+<li><a href="#imbue">.imbue()</a></li>
+<li><a href="#ones_member">.ones()</a></li>
+<li><a href="#zeros_member">.zeros()</a></li>
+<li><a href="http://cplusplus.com/reference/clibrary/cstdlib/srand/">std::srand()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="reset"></a>
+<b>
+.reset()
+</b>
+<ul>
+<li>
+Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i> and <i>field</i>
+</li>
+<br>
+<li>
+Causes an object to have no elements
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5, 5);
+A.reset();
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#set_size">.set_size()</a></li>
+<li><a href="#is_empty">.is_empty()</a></li>
+<li><a href="#zeros_member">.zeros()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="reshape_member"></a>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;"><b>.reshape(n_rows, n_cols, dim=0)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.reshape(n_rows, n_cols, n_slices, dim=0)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member function of <i>Cube</i>)
+      </td>
+    </tr>
+  </tbody>
+</table>
+<br>
+<ul>
+<li>
+Recreate the object according to given size specifications,
+with the elements taken from the previous version of the object,
+either column-wise (dim=0) or row-wise (dim=1);
+the elements in the generated object are placed column-wise (ie. the first column is filled up before filling the second column)
+</li>
+<br>
+<li>
+The layout of the elements in the recreated object will be different to the layout in the previous version of the object
+</li>
+<br>
+<li>
+This function can be used to vectorise a matrix (ie. concatenate all the columns or rows)
+</li>
+<br>
+<li>
+The new total number of elements (according to the specified size) doesn't have to be the same as the previous total number of elements in the object
+</li>
+<br>
+<li>
+If the total number of elements in the previous version of the object is less than the specified size,
+the extra elements in the recreated object are set to zero
+</li>
+<br>
+<li>
+If the total number of elements in the previous version of the object is greater than the specified size,
+only a subset of the elements is taken
+</li>
+<br>
+<li>
+<b>Caveat:</b>
+.reshape() is slower than <a href="#set_size">.set_size()</a>, which doesn't preserve data
+</li>
+<br>
+<li>
+<b>Caveat:</b>
+if you wish to grow/shrink the object while preserving the elements <b>as well as</b> the layout of the elements,
+use <a href="#resize_member">.resize()</a> instead
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(4,5);
+A.reshape(5,4);
+
+// vectorise A into a column vector:
+A.reshape(A.n_elem, 1);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#resize_member">.resize()</a></li>
+<li><a href="#set_size">.set_size()</a></li>
+<li><a href="#copy_size">.copy_size()</a></li>
+<li><a href="#zeros_member">.zeros()</a></li>
+<li><a href="#reset">.reset()</a></li>
+<li><a href="#reshape">reshape()</a> (standalone function)</li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="resize_member"></a>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;"><b>.resize(n_elem)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member function of <i>Col</i>, <i>Row</i>)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.resize(n_rows, n_cols)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member function of <i>Mat</i>)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.resize(n_rows, n_cols, n_slices)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member function of <i>Cube</i>)
+      </td>
+    </tr>
+  </tbody>
+</table>
+<br>
+<ul>
+<li>
+Recreate the object according to given size specifications, while preserving the elements as well as the layout of the elements
+</li>
+<br>
+<li>
+Can be used for growing or shrinking an object (ie. adding/removing rows, and/or columns, and/or slices)
+</li>
+<br>
+<li>
+<b>Caveat:</b>
+.resize() is slower than <a href="#set_size">.set_size()</a>, which doesn't preserve data
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(4,5);
+A.resize(7,6);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+This function was added in version 2.4
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#reshape_member">.reshape()</a></li>
+<li><a href="#set_size">.set_size()</a></li>
+<li><a href="#copy_size">.copy_size()</a></li>
+<li><a href="#zeros_member">.zeros()</a></li>
+<li><a href="#reset">.reset()</a></li>
+<li><a href="#insert">insert rows/cols/slices</a></li>
+<li><a href="#shed">shed rows/cols/slices</a></li>
+<li><a href="#resize">resize()</a> (standalone function)</li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="save_load_mat"></a>
+<b>
+.save(name, file_type = arma_binary)
+<br>
+.save(stream, file_type = arma_binary)
+<br>
+<br>
+.load(name, file_type = auto_detect)
+<br>
+.load(stream, file_type = auto_detect)
+<br>
+<br>
+.quiet_save(name, file_type = arma_binary)
+<br>
+.quiet_save(stream, file_type = arma_binary)
+<br>
+<br>
+.quiet_load(name, file_type = auto_detect)
+<br>
+.quiet_load(stream, file_type = auto_detect)
+</b>
+<ul>
+<li>Member functions of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i> classes</li>
+<br>
+<li>Store/retrieve data in files or streams</li>
+<br>
+<li>On success, <i>save()</i>, <i>load()</i>, <i>quiet_save()</i>, and <i>quite_load()</i> will return a <i>bool</i> set to <i>true</i></li>
+<br>
+<li><i>save()</i> and <i>quiet_save()</i> will return a <i>bool</i> set to <i>false</i> if the saving process fails</li>
+<br>
+<li>
+<i>load()</i> and <i>quiet_load()</i> will return a <i>bool</i> set to <i>false</i> if the loading process fails;
+additionally, the object will be reset so it has no elements
+</li>
+<br>
+<li><i>load()</i> and <i>save()</i> will print warning messages if any problems are encountered</li>
+<br>
+<li><i>quiet_load()</i> and <i>quiet_save()</i> do not print any error messages</li>
+<br>
+<li>
+The following file formats are supported:
+<br>
+<br>
+<ul>
+                  <table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+                    <tbody>
+                      <tr>
+                        <td style="vertical-align: top;"><b>auto_detect</b></td>
+                        <td style="vertical-align: top;"><br>
+                        </td>
+                        <td style="vertical-align: top;">
+for <i>load()</i> and <i>quiet_load()</i>:
+try to automatically detect the file type as one of the formats described below.
+This is the default operation.
+<br>
+<br>
+                        </td>
+                      </tr>
+                      <tr>
+                        <td style="vertical-align: top;"><b>raw_ascii</b></td>
+                        <td style="vertical-align: top;"><br>
+                        </td>
+                        <td style="vertical-align: top;">
+Numerical data stored in raw ASCII format, without a header.
+The numbers are separated by whitespace.
+The number of columns must be the same in each row.
+Cubes are loaded as one slice.
+Data which was saved in Matlab/Octave using the <i>-ascii</i> option can be read in Armadillo, except for complex numbers.
+Complex numbers are stored in standard C++ notation, which is a tuple surrounded by brackets: eg. (1.23,4.56) indicates 1.24&nbsp;+&nbsp;4.56i.
+<br>
+<br>
+                        </td>
+                      </tr>
+                      <tr>
+                        <td style="vertical-align: top;"><b>raw_binary</b></td>
+                        <td style="vertical-align: top;"><br>
+                        </td>
+                        <td style="vertical-align: top;">
+Numerical data stored in machine dependent raw binary format, without a header.
+Matrices are loaded to have one column,
+while cubes are loaded to have one slice with one column.
+The <a href="#reshape_member">.reshape()</a> function can be used to alter the size of the loaded matrix/cube without losing data.
+<br>
+<br>
+                        </td>
+                      </tr>
+                      <tr>
+                        <td style="vertical-align: top;"><b>arma_ascii</b></td>
+                        <td style="vertical-align: top;"><br>
+                        </td>
+                        <td style="vertical-align: top;">
+Numerical data stored in human readable text format, with a simple header to speed up loading.
+The header indicates the type of matrix as well as the number of rows and columns.
+For cubes, the header additionally specifies the number of slices.
+<br>
+<br>
+                        </td>
+                      </tr>
+                      <tr>
+                        <td style="vertical-align: top;"><b>arma_binary</b></td>
+                        <td style="vertical-align: top;"><br>
+                        </td>
+                        <td style="vertical-align: top;">
+Numerical data stored in machine dependent binary format, with a simple header to speed up loading.
+The header indicates the type of matrix as well as the number of rows and columns.
+For cubes, the header additionally specifies the number of slices.
+<br>
+<br>
+                        </td>
+                      </tr>
+                      <tr>
+                        <td style="vertical-align: top;"><b>csv_ascii</b></td>
+                        <td style="vertical-align: top;"><br>
+                        </td>
+                        <td style="vertical-align: top;">
+Numerical data stored in comma separated value (CSV) text format, without a header.
+Applicable to <i>Mat</i> only.
+<br>
+<br>
+                        </td>
+                      </tr>
+                      <tr>
+                        <td style="vertical-align: top;"><b>hdf5_binary</b></td>
+                        <td style="vertical-align: top;"><br>
+                        </td>
+                        <td style="vertical-align: top;">
+Numerical data stored in portable HDF5 binary format.
+<br>
+<b>Caveat</b>:
+support for HDF5 must be enabled within Armadillo's <a href="#config_hpp">configuration</a>;
+the <i>hdf5.h</i> header file must be available on your system and you will need to link with the hdf5 library (eg. -lhdf5).
+Support for saving &amp; loading of <i>Cube</i> objects was added in version 3.830.
+<br>
+<br>
+                        </td>
+                      </tr>
+                      <tr>
+                        <td style="vertical-align: top;"><b>pgm_binary</b></td>
+                        <td style="vertical-align: top;"><br>
+                        </td>
+                        <td style="vertical-align: top;">
+Image data stored in Portable Gray Map (PGM) format.
+Applicable to <i>Mat</i> only.
+Saving <i>int</i>, <i>float</i> or <i>double</i> matrices is a lossy operation, as each element is copied and converted to an 8 bit representation.
+As such the matrix should have values in the [0,255] interval, otherwise the resulting image may not display correctly.
+<br>
+<br>
+                        </td>
+                      </tr>
+                      <tr>
+                        <td style="vertical-align: top;"><b>ppm_binary</b></td>
+                        <td style="vertical-align: top;"><br>
+                        </td>
+                        <td style="vertical-align: top;">
+Image data stored in Portable Pixel Map (PPM) format.
+Applicable to <i>Cube</i> only.
+Saving <i>int</i>, <i>float</i> or <i>double</i> matrices is a lossy operation, as each element is copied and converted to an 8 bit representation.
+As such the cube/field should have values in the [0,255] interval, otherwise the resulting image may not display correctly.
+                        </td>
+                      </tr>
+                    </tbody>
+                  </table>
+</ul>
+</li>
+<br>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+
+A.save("A1.mat");  // default save format is arma_binary
+A.save("A2.mat", arma_ascii);
+
+mat B;
+// automatically detect format type
+B.load("A1.mat");
+
+mat C;
+// force loading in the arma_ascii format
+C.load("A2.mat", arma_ascii);
+
+
+// example of saving/loading using a stream
+std::stringstream s;
+A.save(s);
+
+mat D;
+D.load(s);
+
+
+// example of testing for success
+mat E;
+bool status = E.load("A2.mat");
+
+if(status == true)
+  {
+  cout &lt;&lt; "loaded okay" &lt;&lt; endl;
+  }
+else
+  {
+  cout &lt;&lt; "problem with loading" &lt;&lt; endl;
+  }
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#save_load_field">saving/loading fields</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="save_load_field"></a>
+<b>
+.save(name, file_type = arma_binary)
+<br>
+.save(stream, file_type = arma_binary)
+<br>
+<br>
+.load(name, file_type = auto_detect)
+<br>
+.load(stream, file_type = auto_detect)
+<br>
+<br>
+.quiet_save(name, file_type = arma_binary)
+<br>
+.quiet_save(stream, file_type = arma_binary)
+<br>
+<br>
+.quiet_load(name, file_type = auto_detect)
+<br>
+.quiet_load(stream, file_type = auto_detect)
+</b>
+<ul>
+<li>Member functions of the <i>field</i> class</li>
+<br>
+<li>Store/retrieve fields in files or stream</li>
+<br>
+<li>On success, save(), load(), quiet_save(), and quite_load() will return a <i>bool</i> set to <i>true</i></li>
+<br>
+<li>save() and quiet_save() will return a <i>bool</i> set to <i>false</i> if the saving process fails</li>
+<br>
+<li>
+load() and quiet_load() will return a <i>bool</i> set to <i>false</i> if the loading process fails;
+additionally, the field will be reset so it has no elements
+</li>
+<br>
+<li>load() and save() will print warning messages if any problems are encountered</li>
+<br>
+<li>quiet_load() and quiet_save() do not print any error messages</li>
+<br>
+<li>
+Fields with objects of type <i>std::string</i> are saved and loaded as raw text files.
+The text files do not have a header.
+Each string is separated by a whitespace.
+load() and quiet_load() will only accept text files that have the same number of strings on each line.
+The strings can have variable lengths.
+</li>
+<br>
+<li>
+Other than storing string fields as text files, the following file formats are supported:
+<br>
+<br>
+<ul>
+                  <table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+                    <tbody>
+                      <tr>
+                        <td style="vertical-align: top;"><b>auto_detect</b></td>
+                        <td style="vertical-align: top;"><br>
+                        </td>
+                        <td style="vertical-align: top;">
+<br>
+<li>
+load(): try to automatically detect the field format type as one of the formats described below.
+This is the default operation.
+</li>
+<br>
+                        </td>
+                      </tr>
+                      <tr>
+                        <td style="vertical-align: top;"><b>arma_binary</b></td>
+                        <td style="vertical-align: top;"><br>
+                        </td>
+                        <td style="vertical-align: top;">
+<br>
+<li>
+Objects are stored in machine dependent binary format.
+<li>
+Default type for fields of type <i>Mat</i>, <i>Col</i> or <i>Row</i>.
+</li>
+<li>
+Only applicable to fields of type <i>Mat</i>, <i>Col</i> or <i>Row</i>.
+</li>
+<br>
+                        </td>
+                      </tr>
+                      <tr>
+                        <td style="vertical-align: top;"><b>ppm_binary</b></td>
+                        <td style="vertical-align: top;"><br>
+                        </td>
+                        <td style="vertical-align: top;">
+<br>
+<li>
+Image data stored in Portable Pixmap Map (PPM) format.
+</li>
+<li>
+Only applicable to fields of type <i>Mat</i>, <i>Col</i> or <i>Row</i>.
+</li>
+<li>
+.load(): Loads the specified image and stores the red, green and blue components as three separate matrices.
+The resulting field is comprised of the three matrices,
+with the red, green and blue components in the first, second and third matrix, respectively.
+</li>
+<li>
+.save(): Saves a field with exactly three matrices of equal size as an image.
+It is assumed that the red, green and blue components are stored in the first, second and third matrix, respectively.
+Saving <i>int</i>, <i>float</i> or <i>double</i> matrices is a lossy operation,
+as each matrix element is copied and converted to an 8 bit representation.
+</li>
+
+                        </td>
+                      </tr>
+                    </tbody>
+                  </table>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#save_load_mat">saving/loading matrices and cubes</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="set_imag"></a>
+<b>.set_imag(X)</b>
+<br>
+<b>.set_real(X)</b>
+<br>  
+<ul>
+<li>Member functions of Mat, Col, Row and Cube</li>
+<br>
+<li>
+Set the imaginary/real part of an object
+</li>
+<br>
+<li>
+<i>X</i> must have the same size as the recipient object
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+   mat A = randu&lt;mat&gt;(4,5);
+   mat B = randu&lt;mat&gt;(4,5);
+
+cx_mat C = zeros&lt;cx_mat&gt;(4,5);
+
+C.set_real(A);
+C.set_imag(B);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+<b>Caveat:</b>
+if you want to directly construct a complex matrix out of two real matrices,
+the following code is faster:
+<ul>
+<pre>
+   mat A = randu&lt;mat&gt;(4,5);
+   mat B = randu&lt;mat&gt;(4,5);
+
+cx_mat C = cx_mat(A,B);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#constructors_mat">matrix constructors</a></li>
+<li><a href="#constructors_cube">cube constructors</a></li>
+<li><a href="#imag_real">imag()&nbsp;/&nbsp;real()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="set_size"></a>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;"><b>.set_size(n_elem)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member function of <i>Col</i>, <i>Row</i>, and <i>field</i>)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.set_size(n_rows, n_cols)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member function of <i>Mat</i> and <i>field</i>)
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;"><b>.set_size(n_rows, n_cols, n_slices)</b></td>
+      <td style="vertical-align: top;"><br>
+      </td>
+      <td style="vertical-align: top;">(member function of <i>Cube</i>)
+      </td>
+    </tr>
+  </tbody>
+</table>
+<br>  
+<ul>
+<li>Changes the size of an object</li>
+<br>
+<li>
+If the requested number of elements is equal to the old number of elements, existing memory is reused
+</li>
+<br>
+<li>
+If the requested number of elements is not equal to the old number of elements, new memory is used;
+the memory is uninitilised
+</li>
+<br>
+<li>
+If you need to initialise the memory, use <a href="#zeros_member">.zeros()</a> instead
+</li>
+<br>
+<li>
+If you need to explicitly preserve data, use <a href="#reshape_member">.reshape()</a> or <a href="#resize_member">.resize()</a>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A;
+A.set_size(5,10);
+
+vec q;
+q.set_size(100);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#reset">.reset()</a></li>
+<li><a href="#copy_size">.copy_size()</a></li>
+<li><a href="#reshape_member">.reshape()</a></li>
+<li><a href="#resize_member">.resize()</a></li>
+<li><a href="#zeros_member">.zeros()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="shed"></a>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.shed_row(&nbsp;</b>row_number<b>&nbsp;)</b>
+      <br>
+      <b>.shed_rows(&nbsp;</b>first_row, last_row<b>&nbsp;)</b>
+      </td>
+      <td style="vertical-align: top;"><br></td>
+      <td style="vertical-align: top;">(member functions of <i>Mat</i> and <i>Col</i>)
+      </td>
+    </tr>
+    <tr>
+    <td>&nbsp;</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.shed_col(&nbsp;</b>column_number<b>&nbsp;)</b>
+      <br>
+      <b>.shed_cols(&nbsp;</b>first_column, last_column<b>&nbsp;)</b>
+      </td>
+      <td style="vertical-align: top;"><br></td>
+      <td style="vertical-align: top;">(member functions of <i>Mat</i> and <i>Row</i>)
+      </td>
+    </tr>
+    <tr>
+    <td>&nbsp;</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.shed_slice(&nbsp;</b>slice_number<b>&nbsp;)</b>
+      <br>
+      <b>.shed_slices(&nbsp;</b>first_slice, last_slice<b>&nbsp;)</b>
+      </td>
+      <td style="vertical-align: top;"><br></td>
+      <td style="vertical-align: top;">(member functions of <i>Cube</i>)
+      </td>
+    </tr>
+  </tbody>
+</table>
+<br>
+<ul>
+<li>
+Single argument functions:
+remove the specified row/column/slice
+</li>
+<br>
+<li>
+Two argument functions:
+remove the specified range of rows/columns/slices
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,10);
+
+A.shed_row(2);
+A.shed_cols(2,4);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#insert">insert rows/columns/slices</a></li>
+<li><a href="#join">join rows/columns/slices</a></li>
+<li><a href="#resize_member">.resize()</a></li>
+<li><a href="#submat">submatrix views</a></li>
+<li><a href="#subcube">subcube views</a></li>
+<li><a href="http://thesaurus.com/browse/shed"><i>shed</i> in thesaurus.com</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="stl_container_fns"></a>
+<b>STL container functions</b>
+<ul>
+<li><i>Mat</i>, <i>Col</i> and <i>Row</i> classes provide the following member functions that mimic the containers in the C++ Standard Template Library:<br>
+<br>
+
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.clear()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        causes an object to have no elements
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.empty()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        returns true if the object has no elements; returns false if the object has one or more elements
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      &nbsp;
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.size()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+        returns the total number of elements
+      </td>
+    </tr>
+  </tbody>
+</table>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+cout &lt;&lt; A.size() &lt;&lt; endl;
+
+A.clear();
+cout &lt;&lt; A.empty() &lt;&lt; endl;
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#iterators_mat">iterators (matrices)</a></li>
+<li><a href="#attributes">matrix and vector attributes</a></li>
+<li><a href="#is_empty">.is_empty()</a></li>
+<li><a href="#reset">.reset()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="submat"></a>
+<b>submatrix views</b>
+<ul>
+<li>A collection of member functions of <i>Mat</i>, <i>Col</i> and <i>Row</i> classes that provide read/write access to submatrix views<br>
+<br>
+<li>For a matrix or vector <i>X</i>, the subviews are accessed as:</li>
+<br>
+<ul>
+<li>contiguous views:
+<ul>
+<br>
+X.<b>col(&nbsp;</b>col_number<b>&nbsp;)</b><br>
+X.<b>row(&nbsp;</b>row_number<b>&nbsp;)</b><br>
+<br>
+X.<b>cols(&nbsp;</b>first_col<b>,</b> last_col<b>&nbsp;)</b><br>
+X.<b>rows(&nbsp;</b>first_row<b>,</b> last_row<b>&nbsp;)</b><br>
+<br>
+X<b>(</b>&nbsp;<b>span::all,</b> col_number&nbsp;<b>)</b><br>
+X<b>(</b>&nbsp;<b>span(</b>first_row<b>,</b> last_row<b>),</b> col_number&nbsp;<b>)</b><br>
+<br>
+X<b>(</b>&nbsp;row_number<b>,</b> <b>span::all</b>&nbsp;<b>)</b><br>
+X<b>(</b>&nbsp;row_number<b>,</b> <b>span(</b>first_col<b>,</b> last_col<b>)&nbsp;)</b><br>
+<br>
+X.<b>submat(&nbsp;</b>first_row<b>,</b> first_col<b>,</b> last_row<b>,</b> last_col<b>&nbsp;)</b><br>
+X.<b>submat(&nbsp;span(</b>first_row<b>,</b> last_row<b>), span(</b>first_col<b>,</b> last_col<b>)&nbsp;)</b><br>
+<br>
+X<b>(&nbsp;span(</b>first_row<b>,</b> last_row<b>), span(</b>first_col<b>,</b> last_col<b>)&nbsp;)</b><br>
+<br>
+X.<b>unsafe_col(&nbsp;</b>col_number<b>&nbsp;)</b><br>
+<br>
+V.<b>subvec(&nbsp;</b>first_index<b>,</b> last_index<b>&nbsp;)</b> &nbsp;&nbsp;&nbsp; <i>(for vectors only)</i><br>
+V<b>(&nbsp;span(</b>first_index<b>,</b> last_index<b>)&nbsp;)</b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <i>(for vectors only)</i><br>
+</ul>
+</li>
+<br>
+<li>non-contiguous views (added in version 3.0):
+<ul>
+<br>
+X.<b>elem(</b>&nbsp;vector_of_indices&nbsp;<b>)</b><br>
+X<b>(</b>&nbsp;vector_of_indices&nbsp;<b>)</b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <i>(added in version 3.810)</i><br>
+<br>
+X.<b>cols(&nbsp;</b>vector_of_column_indices<b>&nbsp;)</b><br>
+X.<b>rows(&nbsp;</b>vector_of_row_indices<b>&nbsp;)</b><br>
+<br>
+X<b>(</b>&nbsp;vector_of_row_indices<b>,</b>&nbsp;vector_of_column_indices&nbsp;<b>)</b><br>
+X.<b>submat(</b>&nbsp;vector_of_row_indices<b>,</b>&nbsp;vector_of_column_indices&nbsp;<b>)</b><br>
+<!--X.<b>elem(</b>&nbsp;vector_of_row_indices<b>,</b>&nbsp;vector_of_column_indices&nbsp;<b>)</b><br>-->
+</ul>
+</li>
+</ul>
+<br>
+<li>
+Instances of <i>span::all</i>, to indicate an entire range, can be replaced by <i>span()</i>, where no number is specified
+</li>
+<br>
+<li>
+For functions requiring one or more vector of indices,
+eg. <i>X.submat(vector_of_row_indices,vector_of_column_indices)</i>,
+each vector of indices must be of type <i><a href="#Col">uvec</a></i>.
+</li>
+<br>
+<li>
+In the function <i>X.elem(vector_of_indices)</i>,
+elements specified in <i>vector_of_indices</i> are accessed.
+<i>X</i> is interpreted as one long vector,
+with column-by-column ordering of the elements of <i>X</i>.
+The <i>vector_of_indices</i> must evaluate to be a vector of type <i><a href="#Col">uvec</a></i>
+(eg., generated by <i><a href="#find">find()</a></i>).
+The aggregate set of the specified elements is treated as a column vector
+(eg., the output of <i>X.elem()</i> is always a column vector).
+</li>
+<br>
+<li>
+The function <i>.unsafe_col()</i> is provided for speed reasons and should be used only if you know what you're doing.
+The function creates a seemingly independent <i>Col</i> vector object (eg. <i>vec</i>),
+but the vector actually uses memory from the existing matrix object.
+As such, the created <i>Col</i> vector is currently not alias safe
+and does not take into account that the parent matrix object could be deleted.
+If deleted memory is accessed through the created <i>Col</i> vector,
+it will cause memory corruption and/or a crash.
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = zeros&lt;mat&gt;(5,10);
+
+A.submat(0,1,2,3) = randu&lt;mat&gt;(3,3);
+
+// the following three statements
+// access the same part of A
+mat B = A.submat(0,1,2,3);
+mat C = A.submat( span(0,2), span(1,3) );
+mat D = A( span(0,2), span(1,3) );
+
+// the following two statements
+// access the same part of A
+A.col(1)        = randu&lt;mat&gt;(5,1);
+A(span::all, 1) = randu&lt;mat&gt;(5,1);
+
+mat X = randu&lt;mat&gt;(5,5);
+
+// get all elements of X that are greater than 0.5
+vec q = X.elem( find(X > 0.5) );
+
+// set four specific elements of X to 1
+uvec indices;
+indices &lt;&lt; 2 &lt;&lt; 3 &lt;&lt; 6 &lt;&lt; 8;
+
+X.elem(indices) = ones&lt;vec&gt;(4);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#diag">diagonal views</a> &nbsp;&nbsp; (read/write access to diagonals)</li>
+<li><a href="#each_colrow">.each_col() &amp; .each_row()</a> &nbsp;&nbsp; (vector operations repeated on each column or row)</li>
+<li><a href="#colptr">.colptr()</a></li>
+<li><a href="#in_range">.in_range()</a></li>
+<li><a href="#find">find()</a></li>
+<li><a href="#join">join rows/columns/slices</a></li>
+<li><a href="#shed">shed rows/columns/slices</a></li>
+<li><a href="#insert">insert rows/columns/slices</a></li>
+<li><a href="#subcube">subcube views</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="subcube"></a>
+<b>subcube views and slices</b>
+<ul>
+<li>A collection of member functions of the <i>Cube</i> class that provide subcube views<br>
+<br>
+<li>For a cube <i>Q</i>, the subviews are accessed as:</li>
+<br>
+<ul>
+Q.<b>slice(&nbsp;</b>slice_number&nbsp;<b>)</b><br>
+Q.<b>slices(&nbsp;</b>first_slice<b>,</b> last_slice&nbsp;<b>)</b><br>
+<br>
+Q.<b>subcube(&nbsp;</b>first_row<b>,</b> first_col<b>,</b> first_slice<b>, </b>last_row<b>,</b> last_col<b>, </b>last_slice&nbsp;<b>)</b><br>
+Q.<b>subcube(&nbsp;span(</b>first_row<b>,</b> last_row<b>), span(</b>first_col<b>,</b> last_col<b>), span(</b>first_slice<b>,</b> last_slice<b>)&nbsp;)</b><br>
+<br>
+Q<b>(&nbsp;span(</b>first_row<b>,</b> last_row<b>), span(</b>first_col<b>,</b> last_col<b>), span(</b>first_slice<b>,</b> last_slice<b>)&nbsp;)</b><br>
+</ul>
+</li>
+<br>
+<li>
+Instances of <i>span(a,b)</i> can be replaced by:
+<ul>
+<li><i>span()</i> or <i>span::all</i>, to indicate the entire range</li>
+<li><i>span(a)</i>, to indicate a particular row, column or slice</li>
+</ul>
+</li>
+<br>
+<li>
+An individual slice, accessed via <i>.slice()</i>, is an instance of the <i>Mat</i> class
+(a reference to a matrix is provided)
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+cube A = randu&lt;cube&gt;(2,3,4);
+mat B = A.slice(1);
+
+A.slice(0) = randu&lt;mat&gt;(2,3);
+A.slice(0)(1,2) = 99.0;
+
+A.subcube(0,0,1,  1,1,2) = randu&lt;cube&gt;(2,2,2);
+A( span(0,1), span(0,1), span(1,2) ) = randu&lt;cube&gt;(2,2,2);
+
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#in_range">.in_range()</a></li>
+<li><a href="#join">join slices</a></li>
+<li><a href="#shed">shed slices</a></li>
+<li><a href="#insert">insert slices</a></li>
+<li><a href="#submat">submatrix views</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="subfield"></a>
+<b>subfield views</b>
+<ul>
+<li>A collection of member functions of the <i>field</i> class that provide subfield views<br>
+<br>
+<li>For a field <i>F</i>, the subfields are accessed as:</li>
+<br>
+<ul>
+F.<b>row(&nbsp;</b>row_number&nbsp;<b>)</b><br>
+F.<b>col(&nbsp;</b>col_number&nbsp;<b>)</b><br>
+<br>
+F.<b>rows(&nbsp;</b>first_row<b>,</b> last_row&nbsp;<b>)</b><br>
+F.<b>cols(&nbsp;</b>first_col<b>,</b> last_col&nbsp;<b>)</b><br>
+<br>
+F.<b>subfield(&nbsp;</b>first_row<b>,</b>&nbsp;first_col<b>,</b> last_row<b>,</b>&nbsp;last_col <b>)</b><br>
+F.<b>subfield(&nbsp;span(</b>first_row<b>,</b>&nbsp;last_row<b>), span(</b>first_col<b>,</b>&nbsp;last_col<b>) )</b><br>
+<br>
+F<b>(&nbsp;span(</b>first_row<b>,</b> last_row<b>), span(</b>first_col<b>,</b>&nbsp;last_col<b>) )</b><br>
+</ul>
+</li>
+<br>
+<li>
+Instances of <i>span(a,b)</i> can be replaced by:
+<ul>
+<li><i>span()</i> or <i>span::all</i>, to indicate the entire range</li>
+<li><i>span(a)</i>, to indicate a particular row or column</li>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#in_range">.in_range()</a></li>
+<li><a href="#submat">submatrix views</a></li>
+<li><a href="#subcube">subcube views</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="swap"></a>
+<b>.swap(</b>X<b>)</b>
+<ul>
+<li>
+Swap contents with matrix <i>X</i>
+</li>
+<br>
+<li>
+This function was added in version 3.800
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = zeros&lt;mat&gt;(4,5);
+mat B =  ones&lt;mat&gt;(6,7);
+
+A.swap(B);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#swap_rows">.swap_rows() &amp; .swap_cols()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="swap_rows"></a>
+<b>
+.swap_rows(row1, row2)
+<br>.swap_cols(col1, col2)
+</b>
+<ul>
+<li>
+Member functions of <i>Mat</i>, <i>Col</i> and <i>Row</i> classes
+</li>
+<br>
+<li>
+Swap the contents of specified rows or columns
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat X = randu&lt;mat&gt;(5,5);
+X.swap_rows(0,4);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#flip">fliplr() &amp; flipud()</a></li>
+<li><a href="#swap">.swap()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="t_st_members"></a>
+<b>
+.t()
+<br>.st()
+</b>
+<ul>
+<li>
+Member functions of any matrix or vector expression
+</li>
+<br>
+<li>
+<i>.t()</i> provides a transposed copy of the object; if a given object has complex elements, a Hermitian transpose is done (ie. the conjugate of the elements is taken during the transpose operation) 
+</li>
+<br>
+<li>
+<i>.st()</i> provides a transposed copy of the object, without taking the conjugate of the elements (complex matrices)
+</li>
+<br>
+<li>
+For non-complex objects, the <i>.t()</i> and <i>.st()</i> functions are equivalent
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(4,5);
+mat B = A.t();
+</pre>
+</ul>
+</li>
+<br>
+<li>
+The <i>.t()</i> and <i>.st()</i> functions were added in version 2.4
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#trans">trans()</a></li>
+<li><a href="#strans">strans()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="transform"></a>
+<b>.transform(&nbsp;</b>functor<b>&nbsp;)</b>
+<br>
+<b>.transform(&nbsp;</b>lambda function<b>&nbsp;)</b>&nbsp;&nbsp;&nbsp;<i>(C++11 only)</i>
+<br>
+<ul>
+<li>
+Transform each element using a functor or lambda function
+</li>
+<br>
+<li>
+For matrices, transformation is done column-by-column (ie. column 0 is transformed, then column 1, ...)
+</li>
+<br>
+<li>
+For cubes, transformation is done slice-by-slice; each slice is transformed column-by-column
+</li>
+<br>
+<li>
+This function was added in version 3.800
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+// C++11 only example
+
+mat A = ones&lt;mat&gt;(4,5);
+
+// add 123 to every element
+A.transform( [](double val) { return (val + 123.0); } );
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#operators">overloaded operators</a></li>
+<li><a href="#imbue">.imbue()</a></li>
+<li><a href="#fill">.fill()</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Function_object">function object</a> at Wikipedia</li>
+<li><a href="http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions">C++11 lambda functions</a> at Wikipedia</li>
+<li><a href="http://www.cprogramming.com/c++11/c++11-lambda-closures.html">lambda function</a> at cprogramming.com</li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="zeros_member"></a>
+<b>.zeros()</b>
+<br><b>.zeros(n_elem)</b>
+<br><b>.zeros(n_rows, n_cols)</b>
+<br><b>.zeros(n_rows, n_cols, n_slices)</b>
+<ul>
+<li>
+Set the elements of an object to zero, optionally first resizing to specified dimensions
+</li>
+<br>
+<li>
+<i>.zeros()</i> and <i>.zeros(n_elem)</i> are member function of <i>Col</i> and <i>Row</i>
+</li>
+<br>
+<li>
+<i>.zeros()</i> and <i>.zeros(n_rows, n_cols)</i> are member functions of <i>Mat</i>
+</li>
+<br>
+<li>
+<i>.zeros()</i> and <i>.zeros(n_rows, n_cols, n_slices)</i> are member functions of <i>Cube</i>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,10);
+A.zeros();      // sets all elements to zero
+A.zeros(10,20); // sets the size to 10 rows and 20 columns
+                // followed by setting all elements to zero
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#zeros_standalone">zeros()</a> (standalone function)</li>
+<li><a href="#ones_member">.ones()</a></li>
+<li><a href="#randu_randn_member">.randu()</a></li>
+<li><a href="#fill">.fill()</a></li>
+<li><a href="#imbue">.imbue()</a></li>
+<li><a href="#reset">.reset()</a></li>
+<li><a href="#set_size">.set_size()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline">
+
+
+<hr class="greyline">
+<br>
+<br>
+<font size=+1><b>Other Classes</b></font>
+<br>
+<br>
+<hr class="greyline">
+<br>
+
+<a name="running_stat"></a>
+<b>running_stat&lt;</b><i>type</i><b>&gt;</b>
+<ul>
+<li>
+Class for keeping statistics of a continuously sampled one dimensional process/signal.
+Useful if the storage of individual samples (scalars) is not necessary or desired.
+Also useful if the number of samples is not known beforehand or exceeds available memory.
+</li>
+<br>
+<li>
+<i>type</i> should be one of: <i>float</i>, <i>double</i>, <i><a href="#cx_float_double">cx_float</a></i>, <i><a href="#cx_float_double">cx_double</a></i>
+</li>
+<br>
+<li>
+Member functions:
+<ul>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.operator()(</b>scalar<b>)</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      update the statistics so far using the given scalar
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.mean()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      get the mean or average value so far
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.var(</b>norm_type=0<b>)</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      get the variance so far
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.stddev(</b>norm_type=0<b>)</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      get the standard deviation so far
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.min()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      get the minimum value so far
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.max()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      get the maximum value so far
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.reset()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      reset all statistics and set the number of samples to zero
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.count()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      get the number of samples so far
+      </td>
+    </tr>
+  </tbody>
+</table>
+</ul>
+</li>
+<br>
+<li>
+For the .var() and .stddev() functions, the default <i>norm_type=0</i> performs normalisation using <i>N-1</i>
+(where <i>N</i> is the number of samples so far),
+providing the best unbiased estimator.
+Using <i>norm_type=1</i> causes normalisation to be done using <i>N</i>, which provides the second moment around the mean.
+</li>
+<br>
+<li>
+The return type of .count() depends on the underlying form of <i>type</i>: it is either <i>float</i> or <i>double</i>.
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+running_stat&lt;double&gt; stats;
+
+for(uword i=0; i&lt;10000; ++i)
+  {
+  double sample = double(rand())/RAND_MAX;
+  stats(sample);
+  }
+
+cout &lt;&lt; "mean = " &lt;&lt; stats.mean() &lt;&lt; endl;
+cout &lt;&lt; "var  = " &lt;&lt; stats.var()  &lt;&lt; endl;
+cout &lt;&lt; "min  = " &lt;&lt; stats.min()  &lt;&lt; endl;
+cout &lt;&lt; "max  = " &lt;&lt; stats.max()  &lt;&lt; endl;
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#stats_fns">statistics functions</a></li>
+<li><a href="#running_stat_vec">running_stat_vec</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="running_stat_vec"></a>
+<b>running_stat_vec&lt;</b><i>type</i><b>&gt;(calc_cov = false)</b>
+<ul>
+<li>
+Class for keeping statistics of a continuously sampled multi-dimensional process/signal.
+Useful if the storage of individual samples is not necessary or desired.
+Also useful if the number of samples is not known beforehand or exceeds available memory.
+</li>
+<br>
+<li>
+This class is similar to <i>running_stat</i>, with the difference being that vectors are processed instead of single values.
+</li>
+<br>
+<li>
+<i>type</i> must match the element type used by the sample vectors
+(ie. it must be one of <i>float</i>, <i>double</i>, <i><a href="#cx_float_double">cx_float</a></i>, <i><a href="#cx_float_double">cx_double</a></i>)
+</li>
+<br>
+<li>
+<i>type</i> can be inferred via the use of the <i>elem_type</i> member typedef of a vector class.
+For example, <i>fvec::elem_type</i> will be interpreted as <i>float</i>,
+while <i>cx_vec::elem_type</i> will be interpreted as <i><a href="#cx_float_double">cx_double</a></i>.
+</li>
+<br>
+<li>
+Member functions:
+<ul>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.operator()(</b>vector<b>)</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      update the statistics so far using the given vector
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.mean()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      get the mean vector so far
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.var(</b>norm_type=0<b>)</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      get the vector of variances so far
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.stddev(</b>norm_type=0<b>)</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      get the vector of standard deviations so far
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.min()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      get the vector of minimum values so far
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.max()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      get the vector of maximum values so far
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.cov(</b>norm_type=0<b>)</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      get the covariance matrix so far
+      <br>NOTE: this only works if <i>calc_cov</i> is set to <i>true</i> during the construction of the class
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.reset()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      reset all statistics and set the number of samples to zero
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">
+      <b>.count()</b>
+      </td>
+      <td style="vertical-align: top;">&nbsp;<br>
+      </td>
+      <td style="vertical-align: top;">
+      get the number of samples so far
+      </td>
+    </tr>
+  </tbody>
+</table>
+</ul>
+</li>
+<br>
+<li>
+For the .var() and .stddev() functions, the default <i>norm_type=0</i> performs normalisation using <i>N-1</i>
+(where <i>N</i> is the number of samples so far),
+providing the best unbiased estimator.
+Using <i>norm_type=1</i> causes normalisation to be done using <i>N</i>, which provides the second moment around the mean.
+</li>
+<br>
+<li>
+The return type of .count() depends on the underlying form of <i>type</i>: it is either <i>float</i> or <i>double</i>.
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+running_stat_vec&lt;rowvec::elem_type&gt; stats;
+
+rowvec sample;
+
+for(uword i=0; i&lt;10000; ++i)
+  {
+  sample = randu&lt;rowvec&gt;(5);
+  stats(sample);
+  }
+
+cout &lt;&lt; "mean = " &lt;&lt; stats.mean() &lt;&lt; endl;
+cout &lt;&lt; "var  = " &lt;&lt; stats.var()  &lt;&lt; endl;
+cout &lt;&lt; "min  = " &lt;&lt; stats.min()  &lt;&lt; endl;
+cout &lt;&lt; "max  = " &lt;&lt; stats.max()  &lt;&lt; endl;
+
+//
+//
+
+running_stat_vec&lt;rowvec::elem_type&gt; more_stats(true);
+
+for(uword i=0; i&lt;20; ++i)
+  {
+  sample = randu&lt;rowvec&gt;(3);
+  
+  sample(1) -= sample(0);
+  sample(2) += sample(1);
+  
+  more_stats(sample);
+  }
+
+cout &lt;&lt; "covariance matrix = " &lt;&lt; endl;
+cout &lt;&lt; more_stats.cov() &lt;&lt; endl;
+
+rowvec sd = more_stats.stddev();
+
+cout &lt;&lt; "correlations = " &lt;&lt; endl;
+cout &lt;&lt; more_stats.cov() / (sd.t() * sd);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#cov">cov()</a></li>
+<li><a href="#cor">cor()</a></li>
+<li><a href="#running_stat">running_stat</a></li>
+<li><a href="#stats_fns">statistics functions</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="wall_clock"></a>
+<b>wall_clock</b>
+<ul>
+<li>
+Simple wall clock timer class, for measuring the number of elapsed seconds between two intervals
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+wall_clock timer;
+
+mat A = randu&lt;mat&gt;(4,4);
+mat B = randu&lt;mat&gt;(4,4);
+mat C;
+
+timer.tic();
+for(uword i=0; i&lt;100000; ++i)
+  C = A + B + A + B;
+
+double n_secs = timer.toc();
+cout &lt;&lt; "took " &lt;&lt; n_secs &lt;&lt; " seconds" &lt;&lt; endl;
+</pre>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline">
+
+<hr class="greyline">
+<br>
+<br>
+<font size=+1><b>Generated Vectors/Matrices</b></font>
+<br>
+<br>
+<hr class="greyline">
+<br>
+
+<a name="eye_standalone"></a>
+<b>eye(n_rows, n_cols)</b>
+<ul>
+<li>
+Generate a matrix with the elements along the main diagonal set to one
+and off-diagonal elements set to zero
+</li>
+<br>
+<li>
+An identity matrix is generated when <i>n_rows</i> = <i>n_cols</i>
+</li>
+<br>
+<li>
+Usage:
+<ul>
+<li>
+<i>matrix_type</i> X = eye&lt;<i>matrix_type</i>&gt;(n_rows, n_cols)
+</li>
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = eye&lt;mat&gt;(5,5);
+mat B = 123.0 * eye&lt;mat&gt;(5,5);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#eye_member">.eye()</a> (member function of Mat)</li>
+<li><a href="#diag">.diag()</a></li>
+<li><a href="#ones_standalone">ones()</a></li>
+<li><a href="#diagmat">diagmat()</a></li>
+<li><a href="#diagvec">diagvec()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="linspace"></a>
+<b>linspace(start, end, N=100)</b>
+<ul>
+<li>
+Generate a vector with <i>N</i> elements;
+the values of the elements linearly increase from <i>start</i> upto (and including) <i>end</i>
+<br>
+</li>
+<br>
+<li>
+Usage:
+<ul>
+<li><i>vector_type</i> v = linspace&lt;<i>vector_type</i>&gt;(start, end, N)</li>
+<li><i>matrix_type</i> X = linspace&lt;<i>matrix_type</i>&gt;(start, end, N)</li>
+</ul>
+</li>
+<br>
+<li>
+If a <i>matrix_type</i> is specified, the resultant matrix will have one column
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec v = linspace&lt;vec&gt;(10, 20, 5);
+mat X = linspace&lt;mat&gt;(10, 20, 5);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#ones_standalone">ones()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+
+
+<a name="ones_standalone"></a>
+<b>
+ones(n_elem)
+<br>ones(n_rows, n_cols)
+<br>ones(n_rows, n_cols, n_slices)
+</b>
+<ul>
+<li>
+Generate a vector, matrix or cube with all elements set to one
+</li>
+<br>
+<li>
+Usage:
+<ul>
+<li><i>vector_type</i> v = ones&lt;<i>vector_type</i>&gt;(n_elem)</li>
+<li><i>matrix_type</i> X = ones&lt;<i>matrix_type</i>&gt;(n_rows, n_cols)</li>
+<li><i>cube_type</i> Q = ones&lt;<i>cube_type</i>&gt;(n_rows, n_cols, n_slices)</li>
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec  v = ones&lt;vec&gt;(10);
+uvec u = ones&lt;uvec&gt;(11);
+mat  A = ones&lt;mat&gt;(5,6);
+cube Q = ones&lt;cube&gt;(5,6,7);
+
+mat  B = 123.0 * ones&lt;mat&gt;(5,6);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#ones_member">.ones()</a> (member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i>)</li>
+<li><a href="#eye_standalone">eye()</a></li>
+<li><a href="#linspace">linspace()</a></li>
+<li><a href="#zeros_standalone">zeros()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="randu_randn_standalone"></a>
+<b>randu(n_elem)</b> 
+<br><b>randu(n_rows, n_cols)</b>
+<br><b>randu(n_rows, n_cols, n_slices)</b>
+<br>
+<br><b>randn(n_elem)</b>
+<br><b>randn(n_rows, n_cols)</b>
+<br><b>randn(n_rows, n_cols, n_slices)</b>
+<ul>
+<li>
+Generate a vector, matrix or cube with the elements set to random values
+</li>
+<br>
+<li><i>randu()</i> uses a uniform distribution in the [0,1] interval
+</li>
+<br>
+<li><i>randn()</i> uses a normal/Gaussian distribution with zero mean and unit variance
+</li>
+<br>
+<li>
+Usage:
+<ul>
+<li><i>vector_type</i> v = randu&lt;<i>vector_type</i>&gt;(n_elem)</li>
+<li><i>matrix_type</i> X = randu&lt;<i>matrix_type</i>&gt;(n_rows, n_cols)</li>
+<li><i>cube_type</i> Q = randu&lt;<i>cube_type</i>&gt;(n_rows, n_cols, n_slices)</li>
+</ul>
+</li>
+<br>
+<li>
+To change the seed, use the <a href="http://cplusplus.com/reference/clibrary/cstdlib/srand/">std::srand()</a> function.
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec  v = randu&lt;vec&gt;(5);
+mat  A = randu&lt;mat&gt;(5,6);
+cube Q = randu&lt;cube&gt;(5,6,7);
+</pre>
+</ul>
+</li>
+<li>See also:
+<ul>
+<li><a href="#randu_randn_member">.randu() &amp; .randn()</a> (member functions)</li>
+<li><a href="#imbue">.imbue()</a></li>
+<li><a href="#ones_standalone">ones()</a></li>
+<li><a href="#zeros_standalone">zeros()</a></li>
+<li><a href="#shuffle">shuffle()</a></li>
+<li><a href="http://cplusplus.com/reference/clibrary/cstdlib/srand/">std::srand()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="repmat"></a>
+<b>repmat(A, num_copies_per_row, num_copies_per_col)</b>
+<ul>
+<li>Generate a matrix by replicating matrix A in a block-like fashion</li>
+<br>
+<li>The generated matrix has the following size:
+<ul>
+rows = num_copies_per_row * A.n_rows
+<br>
+cols = num_copies_per_col * A.n_cols
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(2, 3);
+
+mat B = repmat(A, 4, 5);
+</pre>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline">
+<br>
+
+<a name="speye"></a>
+<b>speye(n_rows, n_cols)</b>
+<ul>
+<li>
+Generate a sparse matrix with the elements along the main diagonal set to one
+and off-diagonal elements set to zero
+</li>
+<br>
+<li>
+An identity matrix is generated when <i>n_rows</i> = <i>n_cols</i>
+</li>
+<br>
+<li>
+Usage:
+<ul>
+<li>
+<i>sparse_matrix_type</i> X = speye&lt;<i>sparse_matrix_type</i>&gt;(n_rows, n_cols)
+</li>
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+sp_mat A = speye&lt;sp_mat&gt;(5,5);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#sprandu_sprandn">sprandu()/sprandn()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="sprandu_sprandn"></a>
+<b>sprandu(n_rows, n_cols, density)</b>
+<br><b>sprandn(n_rows, n_cols, density)</b>
+<ul>
+<li>
+Generate a sparse matrix with the non-zero elements set to random values
+</li>
+<br>
+<li>
+The <i>density</i> argument specifies the percentage of non-zero elements; it must be in the [0,1] interval
+</li>
+<br>
+<li><i>sprandu()</i> uses a uniform distribution in the [0,1] interval
+</li>
+<br>
+<li><i>sprandn()</i> uses a normal/Gaussian distribution with zero mean and unit variance
+</li>
+<br>
+<li>
+Usage:
+<ul>
+<li><i>sparse_matrix_type</i> X = sprandu&lt;<i>sparse_matrix_type</i>&gt;(n_rows, n_cols, density)</li>
+</ul>
+</li>
+<br>
+<li>
+To change the seed, use the <a href="http://cplusplus.com/reference/clibrary/cstdlib/srand/">std::srand()</a> function.
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+sp_mat A = sprandu&lt;sp_mat&gt;(100, 200, 0.1);
+</pre>
+</ul>
+</li>
+<li>See also:
+<ul>
+<li><a href="#speye">speye()</a></li>
+<li><a href="http://cplusplus.com/reference/clibrary/cstdlib/srand/">std::srand()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="toeplitz"></a>
+<b>toeplitz(A)</b>
+<br><b>toeplitz(A,B)</b>
+<br><b>circ_toeplitz(A)</b>
+<ul>
+<li>
+toeplitz(): generate a Toeplitz matrix, with the first column specified by <i>A</i>, and (optionally) the first row specified by <i>B</i>
+</li>
+<br>
+<li>
+circ_toeplitz(): generate a circulant Toeplitz matrix
+</li>
+<br>
+<li>
+A and B must be vectors
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec A = randu&lt;vec&gt;(5);
+mat X = toeplitz(A);
+mat Y = circ_toeplitz(A);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="http://mathworld.wolfram.com/ToeplitzMatrix.html">Toeplitz matrix in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Toeplitz_matrix">Toeplitz matrix in Wikipedia</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Circulant_matrix">Circulant matrix in Wikipedia</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline">
+<br>
+
+<a name="zeros_standalone"></a>
+<b>zeros(n_elem)</b>
+<br><b>zeros(n_rows, n_cols)</b>
+<br><b>zeros(n_rows, n_cols, n_slices)</b>
+<ul>
+<li>
+Generate a vector, matrix or cube with the elements set to zero
+</li>
+<br>
+<li>
+Usage:
+<ul>
+<li><i>vector_type</i> v = zeros&lt;<i>vector_type</i>&gt;(n_elem)</li>
+<li><i>matrix_type</i> X = zeros&lt;<i>matrix_type</i>&gt;(n_rows, n_cols)</li>
+<li><i>cube_type</i> X = zeros&lt;<i>cube_type</i>&gt;(n_rows, n_cols, n_slices)</li>
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec  v = zeros&lt;vec&gt;(10);
+uvec u = zeros&lt;uvec&gt;(11);
+mat  A = zeros&lt;mat&gt;(5,6);
+cube Q = zeros&lt;cube&gt;(5,6,7);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#zeros_member">.zeros()</a> (member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i>)</li>
+<li><a href="#ones_member">.ones()</a> (member function of <i>Mat</i>, <i>Col</i>, <i>Row</i> and <i>Cube</i>)</li>
+<li><a href="#ones_standalone">ones()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline">
+
+<hr class="greyline">
+<br>
+<br>
+<font size=+1><b>Functions Individually Applied to Each Element of a Matrix/Cube</b></font>
+<br>
+<br>
+<hr class="greyline">
+<br>
+
+<a name="abs"></a>
+<b>abs(mat)</b>
+<br><b>abs(cube)</b>
+<br><b>abs(cx_mat)</b>
+<br><b>abs(cx_cube)</b>
+<ul>
+<li>
+Obtain the magnitude of each element
+</li>
+<br>
+<li>
+Usage for non-complex matrices:
+<ul>
+<li><i>matrix_type</i> Y = abs(X)</li>
+<li>X and Y must have the same <i>matrix_type</i></li>
+</ul>
+</li>
+<br>
+<li>
+Usage for non-complex cubes:
+<ul>
+<li><i>cube_type</i> Y = abs(X)</li>
+<li>X and Y must have the same <i>cube_type</i></li>
+</ul>
+</li>
+<br>
+<li>
+Usage for complex matrices:
+<ul>
+<li><i>non_complex_matrix_type</i> Y = abs(X)</li>
+<li>X must be a have complex matrix type, eg., <i>cx_mat</i> or <i>cx_fmat</i></li>
+<li>The type of Y must be related to the type of X,
+eg., if X has the type <i>cx_mat</i>, then the type of Y must be <i>mat</i>
+</ul>
+</li>
+<br>
+<li>
+Usage for complex cubes:
+<ul>
+<li><i>non_complex_cube_type</i> Y = abs(X)</li>
+<li>X must be a have complex cube type, eg., <i>cx_cube</i> or <i>cx_fcube</i></li>
+<li>The type of Y must be related to the type of X,
+eg., if X has the type <i>cx_cube</i>, then the type of Y must be <i>cube</i>
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+mat B = abs(A); 
+
+cx_mat X = randu&lt;cx_mat&gt;(5,5);
+mat    Y = abs(X);
+</pre>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="eps"></a>
+<b>eps(X)</b>
+<ul>
+<li>
+Obtain the positive distance of the absolute value of each element of <i>X</i> to the next largest representable floating point number
+</li>
+<br>
+<li>
+<i>X</i> can be a scalar (eg. <i>double</i>), vector or matrix
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(4,5);
+mat B = eps(A);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#constants">datum::eps</a></li>
+<li><a href="http://mathworld.wolfram.com/Floating-PointArithmetic.html">Floating-Point Arithmetic in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/IEEE_754-2008">IEEE Standard for Floating-Point Arithmetic in Wikipedia</a></li>
+
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="misc_fns"></a>
+<b>
+miscellaneous functions:
+<br>&nbsp; exp, exp2, exp10, trunc_exp, 
+<br>&nbsp; log, log2, log10, trunc_log,
+<br>&nbsp; pow, sqrt, square
+<br>&nbsp; floor, ceil, round
+</b>
+<br>
+<ul>
+<li>
+Apply a function to each element
+</li>
+<br>
+<li>
+Usage:
+<ul>
+<li>
+<i>matrix_type</i> B = misc_fn(A)
+</li>
+<li>
+<i>cube_type</i> B = misc_fn(A)
+</li>
+<li>
+A and B must have the same <i>matrix_type/cube_type</i>
+</li>
+<li>
+misc_fn(A) is one of:
+<ul>
+
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+<tbody>
+  <tr>
+    <td style="vertical-align: top;">
+       exp(A)<sup>&nbsp;</sup>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      base-e exponential, <i>e<sup>x</sup></i>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+       exp2(A)<sup>&nbsp;</sup>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      base-2 exponential, <i>2<sup>x</sup></i>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+       exp10(A)<sup>&nbsp;</sup>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      base-10 exponential, <i>10<sup>x</sup></i>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      trunc_exp(A)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      base-e exponential,
+      truncated to avoid infinity
+      <br>
+      <font size=-1>(only for elements with type <i>float</i> or <i>double</i>)</font>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+       log(A)<sub>&nbsp;</sub>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      natural log, <i>log<sub>e</sub>&nbsp;x</i>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+       log2(A)<sub>&nbsp;</sub>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      base-2 log, <i>log<sub>2</sub>&nbsp;x</i>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+       log10(A)<sub>&nbsp;</sub>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      base-10 log, <i>log<sub>10</sub>&nbsp;x</i>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      trunc_log(A)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      natural log,
+      truncated to avoid &plusmn;infinity
+      <br>
+      <font size=-1>(only for elements with type <i>float</i> or <i>double</i>)</font>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+       pow(A, p)<sup>&nbsp;</sup>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      raise to the power of p, <i>x<sup>p</sup></i>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+       sqrt(A)<sup>&nbsp;</sup>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      square root, <i>x<sup>&frac12;</sup></i>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      square(A)<sup>&nbsp;</sup>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      square, <i>x<sup>2</sup></i>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      floor(A)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      largest integral value that is not greater than the input value
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      ceil(A)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      smallest integral value that is not less than the input value
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      round(A)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      round to nearest integer, away from zero
+    </td>
+  </tr>
+</tbody>
+</table>
+
+
+</ul>
+</li>
+
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+mat B = exp(A);
+</pre>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="trig_fns"></a>
+<b>trigonometric functions (cos, sin, tan, ...)</b>
+<ul>
+<li>
+Apply a trigonometric function to each element
+</li>
+<br>
+<li>
+Usage:
+<ul>
+<li>
+<i>matrix_type</i> Y = trig_fn(X)
+</li>
+<li>
+<i>cube_type</i> Y = trig_fn(X)
+</li>
+<li>
+X and Y must have the same <i>matrix_type/cube_type</i>
+</li>
+<li>
+trig_fn is one of:
+<ul>
+<li>
+cos family: <i>cos</i>, <i>acos</i>, <i>cosh</i>, <i>acosh</i>
+</li>
+<li>
+sin family: <i>sin</i>, <i>asin</i>, <i>sinh</i>, <i>asinh</i>
+</li>
+<li>
+tan family: <i>tan</i>, <i>atan</i>, <i>tanh</i>, <i>atanh</i>
+</li>
+</ul>
+</li>
+
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat X = randu&lt;mat&gt;(5,5);
+mat Y = cos(X);
+</pre>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline">
+
+<hr class="greyline">
+<br>
+<br>
+<font size=+1><b>Scalar Valued Functions of Vectors/Matrices/Cubes</b></font>
+<br>
+<br>
+<hr class="greyline">
+<br>
+
+<a name="accu"></a>
+<b>accu(mat)</b>
+<br><b>accu(cube)</b>
+<ul>
+<li>
+Accumulate (sum) all elements
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+double x = accu(A);
+
+mat B = randu&lt;mat&gt;(5,5);
+double y = accu(A % B);
+
+// operator % performs element-wise multiplication,
+// hence accu(A % B) is a "multiply-and-accumulate"
+// operation
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#sum">sum()</a></li>
+<li><a href="#cumsum">cumsum()</a></li>
+<li><a href="#as_scalar">as_scalar()</a></li>
+<li><a href="#trace">trace()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="as_scalar"></a>
+<b>as_scalar(expression)</b>
+<ul>
+<li>
+Evaluate an expression that results in a 1x1 matrix,
+followed by converting the 1x1 matrix to a pure scalar
+</li>
+<br>
+<li>
+If a binary or trinary expression is given (ie. 2 or 3 terms),
+the function will try to exploit the fact that the result is a 1x1 matrix
+by using optimised expression evaluations
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+rowvec r = randu&lt;rowvec&gt;(5);
+colvec q = randu&lt;colvec&gt;(5);
+mat    X = randu&lt;mat&gt;(5,5);
+
+// examples of some expressions
+// for which optimised implementations exist
+
+double a = as_scalar(r*q);
+double b = as_scalar(r*X*q);
+double c = as_scalar(r*diagmat(X)*q);
+double d = as_scalar(r*inv(diagmat(X))*q);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#accu">accu()</a></li>
+<li><a href="#conv_to">conv_to()</a></li>
+<li><a href="#dot">dot()</a></li>
+<li><a href="#norm">norm()</a></li>
+<li><a href="#reshape">reshape()</a></li>
+<li><a href="#resize">resize()</a></li>
+<li><a href="#trace">trace()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+                  
+<a name="det"></a>
+<b>det(A, </b><i>slow=false</i><b>)</b>
+<ul>
+<li>
+Determinant of square matrix <i>A</i>
+</li>
+<br>
+<li>
+If <i>A</i> is not square, a <i>std::logic_error</i> exception is thrown 
+</li>
+<br>
+<li>
+<b>Caveat</b>: for large matrices you may want to use <a href="#log_det">log_det()</a> instead
+</li>
+<br>
+<li>
+For matrix sizes &le; 4x4, a fast algorithm is used by default.
+In rare instances, the fast algorithm might be less precise than the standard algorithm.
+To force the use of the standard algorithm, set the <i>slow</i> argument to <i>true</i>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat    A = randu&lt;mat&gt;(5,5);
+double x = det(A);
+
+mat44  B = randu&lt;mat&gt;(4,4);
+
+double y = det(B);       // use fast algorithm by default
+double z = det(B, true); // use slow algorithm
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#log_det">log_det()</a></li>
+<li><a href="http://mathworld.wolfram.com/Determinant.html">determinant in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Determinant">determinant in Wikipedia</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="dot"></a>
+<b>dot(A, B)</b>
+<br><b>cdot(A, B)</b>
+<br><b>norm_dot(A, B)</b>
+<ul>
+<li>
+<i>dot(A,B)</i>: dot product of <i>A</i> and <i>B</i>, under the assumption that <i>A</i> and <i>B</i> are vectors with the same number of elements
+</li>
+<br>
+<li>
+<i>cdot(A,B)</i>: as per <i>dot(A,B)</i>, but the complex conjugate of <i>A</i> is used
+</li>
+<br>
+<li>
+<i>norm_dot(A,B)</i>: normalised version of <i>dot(A,B)</i>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec a = randu&lt;vec&gt;(10);
+vec b = randu&lt;vec&gt;(10);
+
+double x = dot(a,b);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#as_scalar">as_scalar()</a></li>
+<li><a href="#cross">cross()</a></li>
+<li><a href="#conj">conj()</a></li>
+<li><a href="#norm">norm()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="log_det"></a>
+<b>log_det(val, sign, A)</b>
+<ul>
+<li>
+Log determinant of square matrix <i>A</i>, such that the determinant is equal to <i>exp(val)*sign</i>
+</li>
+<br>
+<li>
+If <i>A</i> is not square, a <i>std::logic_error</i> exception is thrown 
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+
+double val;
+double sign;
+
+log_det(val, sign, A);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#det">det()</a></li>
+<li><a href="http://mathworld.wolfram.com/Determinant.html">determinant in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Determinant">determinant in Wikipedia</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="norm"></a>
+<b>
+norm(X, p)
+</b>
+<ul>
+<li>
+Compute the <i>p</i>-norm of <i>X</i>, where <i>X</i> can be a vector or a matrix
+</li>
+<br>
+<li>
+For vectors, <i>p</i> is an integer &ge;1, or one of: "-inf", "inf", "fro"
+</li>
+<br>
+<li>
+For matrices, <i>p</i> is one of: 1, 2, "inf", "fro"; the calculated norm is the <i>induced norm</i> (not entrywise norm)
+</li>
+<br>
+<li>
+"-inf" is the minimum norm, "inf" is the maximum norm, while "fro" is the Frobenius norm
+</li>
+<br>
+<li>
+To obtain the zero norm or Hamming norm (ie. the number of non-zero elements),
+you may want to use this expression: <a href="#accu">accu</a>(X&nbsp;!=&nbsp;0).
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec    q = randu&lt;vec&gt;(5);
+double x = norm(q, 2);
+double y = norm(q, "inf");
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#dot">dot()</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Norm_(mathematics)">Vector Norm in Wikipedia</a></li>
+<li><a href="http://mathworld.wolfram.com/VectorNorm.html">Vector Norm in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Matrix_norm">Matrix Norm in Wikipedia</a></li>
+<li><a href="http://mathworld.wolfram.com/MatrixNorm.html">Matrix Norm in MathWorld</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="rank"></a>
+<b>rank(X, tolerance = default)</b>
+
+<ul>
+<li>Returns the rank of matrix <i>X</i></li><br>
+<li>Any singular values less than default tolerance are treated as zero</li><br>
+<li>The default tolerance is <i>max(X.n_rows, X.n_cols)*eps(sigma)</i>,
+where <i>sigma</i> is the largest singular value of <i>X</i>
+</li><br>
+<li>The computation is based on singular value decomposition;
+if the decomposition fails, a <i>std::runtime_error</i> exception is thrown</li><br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(4,5);
+uword r = rank(A);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#eps">eps()</a></li>
+<li><a href="http://mathworld.wolfram.com/MatrixRank.html">Rank in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Rank_(linear_algebra)">Rank in Wikipedia</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="trace"></a>
+<b>trace(X)</b>
+<ul>
+<li>
+Sum of the diagonal elements of square matrix <i>X</i>
+</li>
+<br>
+<li>
+If <i>X</i> is an expression,
+the function will try to use optimised expression evaluations to calculate only the diagonal elements
+</li>
+<br>
+<li>
+A <i>std::logic_error</i> exception is thrown if <i>X</i> does not evaluate to a square matrix
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+double x = trace(A);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#accu">accu()</a></li>
+<li><a href="#as_scalar">as_scalar()</a></li>
+<li><a href="#diag">.diag()</a></li>
+<li><a href="#diagvec">diagvec()</a></li>
+<li><a href="#sum">sum()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline">
+
+<hr class="greyline">
+<br>
+<br>
+<font size=+1><b>Scalar/Vector Valued Functions of Vectors/Matrices</b></font>
+<br>
+<br>
+<hr class="greyline">
+<br>
+
+<a name="diagvec"></a>
+<b>diagvec(A, k=0)</b>
+<ul>
+<li>
+Extract the <i>k</i>-th diagonal from matrix <i>A</i>
+</li>
+<br>
+<li>
+The argument <i>k</i> is optional -- by default the main diagonal is extracted (<i>k=0</i>)
+</li>
+<br>
+<li>For <i>k &gt; 0</i>, the <i>k</i>-th super-diagonal is extracted (top-right corner)</li>
+<br>
+<li>For <i>k &lt; 0</i>, the <i>k</i>-th sub-diagonal is extracted (bottom-left corner)</li>
+<br>
+<li>
+An extracted a diagonal is interpreted as a column vector
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+vec d = diagvec(A);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#diag">.diag()</a></li>
+<li><a href="#diagmat">diagmat()</a></li>
+<li><a href="#trace">trace()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline">
+<br>
+
+<a name="min_and_max"></a>
+<b>min(mat, dim=0)</b>
+<br><b>min(rowvec)</b>
+<br><b>min(colvec)</b>
+<br>
+<br><b>max(mat, dim=0)</b>
+<br><b>max(rowvec)</b>
+<br><b>max(colvec)</b>
+<ul>
+<li>
+For a matrix argument, return the extremum value for each column (dim=0), or each row (dim=1)
+</li>
+<br>
+<li>
+For a vector argument, return the extremum value
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+colvec q = randu&lt;colvec&gt;(10,1);
+double x = max(q);
+
+mat    A = randu&lt;mat&gt;(10,10);
+rowvec b = max(A);
+
+// same result as max(A)
+// the 0 explicitly indicates
+// "traverse across rows"
+rowvec c = max(A,0); 
+
+// the 1 explicitly indicates
+// "traverse across columns"
+colvec d = max(A,1);
+
+// find the overall maximum value
+double y = max(max(A));
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#min_and_max_member">.min() &amp; .max()</a> (member functions of Mat and Cube)</li>
+<li><a href="#running_stat">running_stat</a></li>
+<li><a href="#running_stat_vec">running_stat_vec</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="prod"></a>
+<b>prod(mat, dim=0)</b>
+<br><b>prod(rowvec)</b>
+<br><b>prod(colvec)</b>
+<ul>
+<li>
+For a matrix argument, return the product of elements in each column (dim=0), or each row (dim=1)
+</li>
+<br>
+<li>
+For a vector argument, return the product of all elements
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+colvec q = randu&lt;colvec&gt;(10,1);
+double x = prod(q);
+
+mat    A = randu&lt;mat&gt;(10,10);
+rowvec b = prod(A);
+
+// same result as prod(A)
+// the 0 explicitly indicates
+// "traverse across rows"
+rowvec c = prod(A,0);
+
+// the 1 explicitly indicates
+// "traverse across columns"
+colvec d = prod(A,1);
+
+// find the overall product
+double y = prod(prod(A));
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#schur_product">Schur product</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+
+<a name="sum"></a>
+<b>sum(mat, dim=0)</b>
+<br><b>sum(rowvec)</b>
+<br><b>sum(colvec)</b>
+<ul>
+<li>
+For a matrix argument, return the sum of elements in each column (dim=0), or each row (dim=1)
+</li>
+<br>
+<li>
+For a vector argument, return the sum of all elements
+</li>
+<br>
+<li>
+To get a sum of all the elements regardless of the argument type (ie. matrix or vector),
+you may wish to use <a href="#accu">accu()</a> instead
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+colvec q = randu&lt;colvec&gt;(10,1);
+double x = sum(q);
+
+mat    A = randu&lt;mat&gt;(10,10);
+rowvec b = sum(A);
+
+// same result as sum(A)
+// the 0 explicitly indicates
+// "traverse across rows"
+rowvec c = sum(A,0);
+
+// the 1 explicitly indicates
+// "traverse across columns"
+colvec d = sum(A,1);
+
+// find the overall sum
+double y = sum(sum(A));
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#accu">accu()</a></li>
+<li><a href="#cumsum">cumsum()</a></li>
+<li><a href="#trace">trace()</a></li>
+<li><a href="#as_scalar">as_scalar()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+
+<a name="stats_fns"></a>
+<b>statistics: mean, median, stddev, var</b>
+
+<ul>
+<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
+<tbody>
+  <tr>
+    <td style="vertical-align: top;">
+       <b>mean(mat, dim=0)</b>
+       <br><b>mean(colvec)</b>
+       <br><b>mean(rowvec)</b>
+       <br>
+       <br>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      mean (average value)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+       <b>median(mat, dim=0)</b>
+       <br><b>median(colvec)</b>
+       <br><b>median(rowvec)</b>
+       <br>
+       <br>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      median
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+       <b>stddev(mat, norm_type=0, dim=0)</b>
+       <br><b>stddev(colvec, norm_type=0)</b>
+       <br><b>stddev(rowvec, norm_type=0)</b>
+       <br>
+       <br>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      standard deviation
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+       <b>var(mat, norm_type=0, dim=0)</b>
+       <br><b>var(colvec, norm_type=0)</b>
+       <br><b>var(rowvec, norm_type=0)</b>
+       <br>
+       <br>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      variance
+    </td>
+  </tr>
+</tbody>
+</table>
+<br>
+<li>
+For a matrix argument, find a particular statistic for each column (<i>dim=0</i>), or each row (<i>dim=1</i>)
+</li>
+<br>
+<li>
+For a vector argument, return a particular statistic calculated using all the elements of the vector
+</li>
+<br>
+<li>
+For the var() and stddev() functions, the default <i>norm_type=0</i> performs normalisation using <i>N-1</i> (where <i>N</i> is the number of samples),
+providing the best unbiased estimator.
+Using <i>norm_type=1</i> causes normalisation to be done using <i>N</i>, which provides the second moment around the mean
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A    = randu&lt;mat&gt;(5,5);
+mat B    = mean(A);
+mat C    = var(A);
+double m = mean(mean(A));
+
+vec    q = randu&lt;vec&gt;(5);
+double v = var(q);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#cov">cov()</a></li>
+<li><a href="#cor">cor()</a></li>
+<li><a href="#running_stat">running_stat</a></li>
+<li><a href="#running_stat_vec">running_stat_vec</a></li>
+<li><a href="#hist">hist()</a></li>
+<li><a href="#histc">histc()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline">
+
+<hr class="greyline">
+<br>
+<br>
+<font size=+1><b>Vector/Matrix/Cube Valued Functions of Vectors/Matrices/Cubes</b></font>
+<br>
+<br>
+<hr class="greyline">
+<br>
+
+<a name="conv"></a>
+<b>
+C = conv(A, B)
+</b>
+<ul>
+<li>
+Convolution of vectors <i>A</i> and <i>B</i>
+</li>
+<br>
+<li>
+If <i>A</i> and <i>B</i> are polynomial coefficient vectors, convolving them is equivalent to multiplying the two polynomials
+</li>
+<br>
+<li>
+The convolution operation is also equivalent to FIR filtering
+</li>
+<br>
+<li>
+The orientation of the result vector is the same as the orientation of <i>A</i> (ie. column or row vector)
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec A = randu&lt;vec&gt;(128) - 0.5;
+vec B = randu&lt;vec&gt;(128) - 0.5;
+
+vec C = conv(A,B);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#fft">fft()</a></li>
+<li><a href="#cor">cor()</a></li>
+<li><a href="http://mathworld.wolfram.com/Convolution.html">Convolution in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Convolution">Convolution in Wikipedia</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Finite_impulse_response">FIR filter in Wikipedia</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="conv_to"></a>
+<b>
+conv_to&lt;<i>type</i>&gt;::from(X)
+</b>
+<ul>
+<li>
+A form of casting
+</li>
+<br>
+<li>
+Convert between matrix/vector types (eg. <i>mat</i> to <i>fmat</i>), as well as cube types (eg. <i>cube</i> to <i>fcube</i>)
+</li>
+<br>
+<li>
+Conversion between <i>std::vector</i> and Armadillo matrices/vectors is also possible
+</li>
+<br>
+<li>
+Conversion of a <i>mat</i> object into <i>colvec</i>, <i>rowvec</i> or <i>std::vector</i> is possible if the object can be interpreted as a vector
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat  A = randu&lt;mat&gt;(5,5);
+fmat B = conv_to&lt;fmat&gt;::from(A);
+
+typedef std::vector&lt;double&gt; stdvec;
+
+stdvec x(3);
+x[0] = 0.0; x[1] = 1.0;  x[2] = 2.0;
+
+colvec y = conv_to&lt; colvec &gt;::from(x);
+stdvec z = conv_to&lt; stdvec &gt;::from(y); 
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#as_scalar">as_scalar()</a></li>
+<li><a href="#reshape">reshape()</a></li>
+<li><a href="#resize">resize()</a></li>
+<li><a href="#adv_constructors_mat">advanced constructors (matrices)</a></li>
+<li><a href="#adv_constructors_cube">advanced constructors (cubes)</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="conj"></a>
+<b>conj(cx_mat)</b>
+<br><b>conj(cx_cube)</b>
+<ul>
+<li>
+Obtain the complex conjugate of each element in a complex matrix/cube
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+cx_mat X = randu&lt;cx_mat&gt;(5,5);
+cx_mat Y = conj(X);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#trans">trans()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="cor"></a>
+<b>cor(X, Y, norm_type=0)</b>
+<br><b>cor(X, norm_type=0)</b>
+<ul>
+<li>
+For two matrix arguments <i>X</i> and <i>Y</i>,
+if each row of <i>X</i> and <i>Y</i>  is an observation and each column is a variable,
+the <i>(i,j)</i>-th entry of <i>cor(X,Y)</i> is the correlation coefficient between the <i>i</i>-th variable in <i>X</i> and the <i>j</i>-th variable in <i>Y</i>
+</li>
+<br>
+<li>
+For vector arguments, the type of vector is ignored and each element in the vector is treated as an observation 
+</li>
+<br>
+<li>
+For matrices, <i>X</i> and <i>Y</i> must have the same dimensions
+</li>
+<br>
+<li>
+For vectors, <i>X</i> and <i>Y</i> must have the same number of elements
+</li>
+<br>
+<li>
+<i>cor(X)</i> is equivalent to <i>cor(X, X)</i>, also called autocorrelation
+</li>
+<br>
+<li>
+The default <i>norm_type=0</i> performs normalisation of the correlation matrix using <i>N-1</i> (where <i>N</i> is the number of observations).
+Using <i>norm_type=1</i> causes normalisation to be done using <i>N</i>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat X = randu&lt;mat&gt;(4,5);
+mat Y = randu&lt;mat&gt;(4,5);
+
+mat R = cor(X,Y);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also: 
+<ul>
+<li><a href="http://mathworld.wolfram.com/Correlation.html">Correlation in MathWorld</a></li>
+<li><a href="http://mathworld.wolfram.com/Autocorrelation.html">Autocorrelation in MathWorld</a></li>
+<li><a href="#cov">cov()</a></li>
+<li><a href="#conv">conv()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="cov"></a>
+<b>cov(X, Y, norm_type=0)</b>
+<br><b>cov(X, norm_type=0)</b>
+<ul>
+<li>
+For two matrix arguments <i>X</i> and <i>Y</i>,
+if each row of <i>X</i> and <i>Y</i>  is an observation and each column is a variable,
+the <i>(i,j)</i>-th entry of <i>cov(X,Y)</i> is the covariance between the <i>i</i>-th variable in <i>X</i> and the <i>j</i>-th variable in <i>Y</i>
+</li>
+<br>
+<li>
+For vector arguments, the type of vector is ignored and each element in the vector is treated as an observation
+</li>
+<br>
+<li>
+For matrices, <i>X</i> and <i>Y</i> must have the same dimensions
+</li>
+<br>
+<li>
+For vectors, <i>X</i> and <i>Y</i> must have the same number of elements
+</li>
+<br>
+<li>
+<i>cov(X)</i> is equivalent to <i>cov(X, X)</i>
+</li>
+<br>
+<li>
+The default <i>norm_type=0</i> performs normalisation using <i>N-1</i> (where <i>N</i> is the number of observations),
+providing the best unbiased estimation of the covariance matrix (if the observations are from a normal distribution).
+Using <i>norm_type=1</i> causes normalisation to be done using <i>N</i>, which provides the second moment matrix of the observations about their mean
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat X = randu&lt;mat&gt;(4,5);
+mat Y = randu&lt;mat&gt;(4,5);
+
+mat C = cov(X,Y);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#running_stat_vec">running_stat_vec</a></li>
+<li><a href="#stats_fns">statistics functions</a></li>
+<li><a href="http://mathworld.wolfram.com/Covariance.html">Covariance in MathWorld</a></li>
+<li><a href="#cor">cor()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="cross"></a>
+<b>cross(A, B)</b>
+<ul>
+<li>
+Calculate the cross product between A and B, under the assumption that A and B are 3 dimensional vectors
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec a = randu&lt;vec&gt;(3);
+vec b = randu&lt;vec&gt;(3);
+
+vec c = cross(a,b);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#dot">dot()</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Cross_product">Cross product in Wikipedia</a></li>
+<li><a href="http://mathworld.wolfram.com/CrossProduct.html">Cross product in MathWorld</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="cumsum"></a>
+<b>cumsum(mat, dim=0)</b>
+<br><b>cumsum(rowvec)</b>
+<br><b>cumsum(colvec)</b>
+<ul>
+<li>
+For a matrix argument, return a matrix containing the cumulative sum of elements in each column (dim=0, the default), or each row (dim=1)
+</li>
+<br>
+<li>
+For a vector argument, return a vector of the same orientation, containing the cumulative sum of elements
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+mat B = cumsum(A);
+
+vec x = randu&lt;vec&gt;(10);
+vec y = cumsum(x);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#accu">accu()</a></li>
+<li><a href="#sum">sum()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="diagmat"></a>
+<b>diagmat(X)</b>
+<ul>
+<li>
+Interpret a matrix or vector <i>X</i> as a diagonal matrix
+</li>
+<br>
+<li>
+If <i>X</i> is a matrix, the matrix must be square; the main diagonal is copied and all other elements in the generated matrix are set to zero
+</li>
+<br>
+<li>
+If <i>X</i> is a vector, elements of the vector are placed on the main diagonal in the generated matrix and all other elements are set to zero
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+mat B = diagmat(A);
+mat C = A*diagmat(A);
+
+rowvec q = randu&lt;rowvec&gt;(5);
+colvec r = randu&lt;colvec&gt;(5);
+mat    X = diagmat(q)*diagmat(r);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#diagvec">diagvec()</a></li>
+<li><a href="#diag">.diag()</a></li>
+<li><a href="#trimat">trimatu() / trimatl()</a></li>
+<li><a href="#symmat">symmatu() / symmatl()</a></li>
+<li><a href="#reshape">reshape()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline">
+<br>
+
+<a name="find"></a>
+<b>find(X, k=0, s="first")</b>
+<ul>
+<li>Return a column vector of the indices of non-zero elements of <i>X</i></li>
+<br>
+<li>The output vector must have the type <a href="#Col">uvec</a> or <a href="#Mat">umat</a>
+(ie. the indices are stored as unsigned integers of type <a href="#uword">uword</a>)
+</li>
+<br>
+<li>
+The input matrix <i>X</i> is interpreted as a vector, with column-by-column ordering of the elements of <i>X</i>
+</li>
+<br>
+<li>Relational operators can be used instead of <i>X</i>, eg.&nbsp;<i>A&nbsp;&gt;&nbsp;0.5</i>
+</li>
+<br>
+<li>If <i>k=0</i> (default), return the indices of all non-zero elements, otherwise return at most <i>k</i> of their indices</li>
+<br>
+<li>If <i>s="first"</i> (default), return at most the first <i>k</i> indices of the non-zero elements
+</li>
+<br>
+<li>If <i>s="last"</i>, return at most the last <i>k</i> indices of the non-zero elements
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat  A  = randu&lt;mat&gt;(5,5);
+mat  B  = randu&lt;mat&gt;(5,5);
+
+uvec q1 = find(A &gt; B);
+uvec q2 = find(A &gt; 0.5);
+uvec q3 = find(A &gt; 0.5, 3, "last");
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#unique">unique()</a></li>
+<li><a href="#conv_to">conv_to()</a> (convert between matrix/vector types)</li>
+<li><a href="#submat">submatrix views</a></li>
+<li><a href="#sort_index">sort_index()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline">
+<br>
+
+<a name="flip"></a>
+<b>fliplr(mat)</b>
+<br><b>flipud(mat)</b>
+<ul>
+<li>
+fliplr(): generate a copy of the input matrix, with the order of the columns reversed
+</li>
+<br>
+<li>
+flipud(): generate a copy of the input matrix, with the order of the rows reversed
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+
+mat B = fliplr(A);
+mat C = flipud(A);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#swap_rows">.swap_rows() &amp; .swap_cols()</a> (member functions of <i>Mat</i>, <i>Col</i> and <i>Row</i> classes)</li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="hist"></a>
+<b>hist(V, n_bins=10)</b>
+<br><b>hist(X, n_bins=10, dim=0)</b>
+<br>
+<br><b>hist(V, centers)</b>
+<br><b>hist(X, centers, dim=0)</b>
+<ul>
+<li>
+For vector <i>V</i>,
+produce an unsigned vector of the same orientation as <i>V</i> (ie. either <a href="#Col">uvec</a> or <a href="#Row">urowvec</a>)
+that represents a histogram of counts
+</li>
+<br>
+<li>
+For matrix <i>X</i>,
+produce a <a href="#Mat">umat</a> matrix containing either
+column histogram counts (for <i>dim=0</i>, default),
+or
+row histogram counts (for <i>dim=1</i>)
+</li>
+<br>
+<li>
+The bin centers can be automatically determined from the data, with the number of bins specified via <i>n_bins</i> (default is 10);
+the range of the bins is determined by the range of the data
+</li>
+<br>
+<li>
+The bin centers can also be explicitly specified via the <i>centers</i> vector;
+the vector must contain monotonically increasing values (eg. 0.1, 0.2, 0.3, ...)
+</li>
+<br>
+<li>
+This function was added in version 3.0
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec  v  = randn&lt;vec&gt;(1000); // Gaussian distribution
+
+uvec h1 = hist(v, 11);
+uvec h2 = hist(v, linspace&lt;vec&gt;(-2,2,11));
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#histc">histc()</a></li>
+<li><a href="#stats_fns">statistics functions</a></li>
+<li><a href="#conv_to">conv_to()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="histc"></a>
+<b>histc(V, edges)</b>
+<br><b>histc(X, edges, dim=0)</b>
+<ul>
+<li>
+For vector <i>V</i>,
+produce an unsigned vector of the same orientation as <i>V</i> (ie. either <a href="#Col">uvec</a> or <a href="#Row">urowvec</a>)
+that contains the counts of the number of values that fall between the elements in the <i>edges</i> vector
+</li>
+<br>
+<li>
+For matrix <i>X</i>,
+produce a <i>umat</i> matrix containing either
+column histogram counts (for <i>dim=0</i>, default),
+or
+row histogram counts (for <i>dim=1</i>)
+</li>
+<br>
+<li>
+The <i>edges</i> vector must contain monotonically increasing values (eg. 0.1, 0.2, 0.3, ...)
+</li>
+<br>
+<li>
+This function was added in version 3.0
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec  v = randn&lt;vec&gt;(1000);  // Gaussian distribution
+
+uvec h = histc(v, linspace&lt;vec&gt;(-2,2,11));
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#hist">hist()</a></li>
+<li><a href="#stats_fns">statistics functions</a></li>
+<li><a href="#conv_to">conv_to()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="imag_real"></a>
+<b>imag(cx_mat)</b>
+<br><b>imag(cx_cube)</b>
+<br>
+<br><b>real(cx_mat)</b>
+<br><b>real(cx_cube)</b>
+<ul>
+<li>
+Extract the imaginary/real part of a complex matrix/cube
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+cx_mat C = randu&lt;cx_mat&gt;(5,5);
+
+mat    A = imag(C);
+mat    B = real(C);
+</pre>
+</ul>
+</li>
+<br>
+<li><b>Caveat:</b> versions 4.4, 4.5 and 4.6 of the GCC C++ compiler have a bug when using the <i>-std=c++0x</i> compiler option (ie. experimental support for C++11);
+to work around this bug, preface Armadillo's imag() and real() with the <i>arma</i> namespace qualification, eg. arma::imag(C)
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#set_imag">set_imag()&nbsp;/&nbsp;set_real()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="join"></a>
+<b>join_rows(mat A, mat B)</b>
+<br><b>join_cols(mat A, mat B)</b>
+<br><b>join_slices(cube A, cube B)</b>
+<ul>
+<li>
+join_rows():
+for two matrices A and B, append each row of B to its respective row of A;
+matrices A and B must have the same number of rows
+</li>
+<br>
+<li>
+join_cols():
+for two matrices A and B, append each column of B to its respective column of A;
+matrices A and B must have the same number of columns
+</li>
+<br>
+<li>
+join_slices():
+for two cubes A and B, append the slices of B to the slices of A;
+cubes A and B have the same number of rows and columns (ie. all slices must have the same size)
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(4,5);
+mat B = randu&lt;mat&gt;(4,6);
+mat C = randu&lt;mat&gt;(6,5);
+
+mat X = join_rows(A,B);
+mat Y = join_cols(A,C);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#shed">shed rows/columns/slices</a></li>
+<li><a href="#insert">insert rows/columns/slices</a></li>
+<li><a href="#submat">submatrix views</a></li>
+<li><a href="#subcube">subcube views</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="kron"></a>
+<b>kron(A,B)</b>
+
+<ul>
+<li>Kronecker tensor product.</li>
+<br>
+<li>Using matrix <i>A</i> (with <i>n</i> rows and <i>p</i> columns) and matrix <i>B</i> (with <i>m</i> rows and <i>q</i> columns),
+<i>kron(A,B)</i> returns a matrix (with <i>nm</i> rows and <i>pq</i> columns) which denotes the tensor product of <i>A</i> and <i>B</i>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(4,5);
+mat B = randu&lt;mat&gt;(5,4);
+
+mat K = kron(A,B);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="http://mathworld.wolfram.com/KroneckerProduct.html">Kronecker Product in MathWorld</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="reshape"></a>
+<b>reshape(mat, n_rows, n_cols, dim=0)</b>
+<br><b>reshape(cube, n_rows, n_cols, n_slices, dim=0)</b>
+<ul>
+<li>
+Generate a matrix/cube sized according to given size specifications,
+whose elements are taken from the given matrix/cube, either column-wise (dim=0) or row-wise (dim=1);
+the elements in the generated object are placed column-wise (ie. the first column is filled up before filling the second column)
+</li>
+<br>
+<li>
+The layout of the elements in the generated object will be different to the layout in the given object
+</li>
+<br>
+<li>
+This function can be used to create a vector representation of a matrix (ie. concatenate all the columns or rows)
+</li>
+<br>
+<li>
+The total number of elements in the generated matrix/cube doesn't have to be the same as the total number of elements in the given matrix/cube
+</li>
+<br>
+<li>
+If the total number of elements in the given matrix/cube is less than the specified size,
+the remaining elements in the generated matrix/cube are set to zero
+</li>
+<br>
+<li>
+If the total number of elements in the given matrix/cube is greater than the specified size,
+only a subset of elements is taken from the given matrix/cube
+</li>
+<br>
+<li>
+<b>Caveat:</b>
+reshape() is slower than <a href="#set_size">.set_size()</a>, which doesn't preserve data
+</li>
+<br>
+<li>
+<b>Caveat:</b>
+if you wish to grow/shrink a matrix while preserving the elements <b>as well as</b> the layout of the elements,
+use <a href="#resize">resize()</a> instead
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(10, 5);
+mat B = reshape(A, 5, 10);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#reshape_member">.reshape()</a> (member function of Mat and Cube)</li>
+<li><a href="#set_size">.set_size()</a> (member function of Mat and Cube)</li>
+<li><a href="#resize">resize()</a></li>
+<li><a href="#as_scalar">as_scalar()</a></li>
+<li><a href="#conv_to">conv_to()</a></li>
+<li><a href="#diagmat">diagmat()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="resize"></a>
+<b>resize(mat, n_rows, n_cols)</b>
+<br><b>resize(cube, n_rows, n_cols, n_slices)</b>
+<ul>
+<li>
+Generate a matrix/cube sized according to given size specifications,
+whose elements as well as the layout of the elements are taken from the given matrix/cube
+</li>
+<br>
+<li>
+<b>Caveat:</b>
+resize() is slower than <a href="#set_size">.set_size()</a>, which doesn't preserve data
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(4, 5);
+mat B = resize(A, 7, 6);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+This function was added in version 2.4
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#resize_member">.resize()</a> (member function of Mat and Cube)</li>
+<li><a href="#set_size">.set_size()</a> (member function of Mat and Cube)</li>
+<li><a href="#reshape">reshape()</a></li>
+<li><a href="#as_scalar">as_scalar()</a></li>
+<li><a href="#conv_to">conv_to()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="shuffle"></a>
+<b>shuffle(mat, dim=0)</b>
+<br><b>shuffle(rowvec, dim=0)</b>
+<br><b>shuffle(colvec, dim=0)</b>
+<ul>
+<li>
+Shuffle the rows (dim=0) or columns (dim=1) of a matrix or vector
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(4,5);
+mat B = shuffle(A);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#randu_randn_standalone">randu() / randn()</a></li>
+<li><a href="#sort">sort()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="sort"></a>
+<b>sort(mat, sort_type=0, dim=0)</b>
+<br><b>sort(rowvec, sort_type=0)</b>
+<br><b>sort(colvec, sort_type=0)</b>
+<ul>
+<li>For a matrix argument, return a matrix with the elements of the input matrix sorted in each column (<i>dim=0</i>), or each row (<i>dim=1</i>)</li>
+<br>
+<li><i>sort_type=0</i> (default) indicates an ascending sort</li>
+<br>
+<li><i>sort_type=1</i> indicates a descending sort</li>
+<br>
+<li>For a vector argument, return a vector which is a sorted version of the input vector</li>
+<br>
+<li>For matrices and vectors with complex numbers, sorting is via absolute values</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(10,10);
+mat B = sort(A);
+</pre>
+</ul>
+</li>
+<li>
+See also:
+<ul>
+<li><a href="#sort_index">sort_index()</a></li>
+<li><a href="#shuffle">shuffle()</a></li>
+<li><a href="#randu_randn_standalone">randu() / randn()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="sort_index"></a>
+<b>sort_index(colvec, sort_type=0)</b>
+<br><b>sort_index(rowvec, sort_type=0)</b>
+<br>
+<br><b>stable_sort_index(colvec, sort_type=0)</b>
+<br><b>stable_sort_index(rowvec, sort_type=0)</b>
+<ul>
+<li>Return a vector which describes the sorted order of the given vector's elements 
+(ie. it contains the indices of the given vector's elements)
+</li>
+<br>
+<li>The output vector must have the type <a href="#Col">uvec</a> or <a href="#Mat">umat</a>
+(ie. the indices are stored as unsigned integers of type <a href="#uword">uword</a>)
+</li>
+<br>
+<li><i>sort_type=0</i> (default) indicates an ascending sort</li>
+<br>
+<li><i>sort_type=1</i> indicates a descending sort</li>
+<br>
+<li>The <i>stable_sort_index()</i> variant preserves the relative order of elements with equivalent values; the variant was added in version 3.6</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+vec  q       = randu&lt;vec&gt;(10);
+uvec indices = sort_index(q);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#find">find()</a></li>
+<li><a href="#sort">sort()</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="symmat"></a>
+<b>symmatu(A)</b>
+<br><b>symmatl(A)</b>
+<ul>
+<li>
+<i>symmatu(A)</i>: interpret square matrix <i>A</i> as symmetric, reflecting the upper triangle to the lower triangle
+</li>
+<br>
+<li>
+<i>symmatl(A)</i>: interpret square matrix <i>A</i> as symmetric, reflecting the lower triangle to the upper triangle
+</li>
+<br>
+<li>
+If <i>A</i> is non-square, a <i>std::logic_error</i> exception is thrown
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+
+mat B = symmatu(A);
+mat C = symmatl(A);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#diagmat">diagmat()</a></li>
+<li><a href="#trimat">trimatu() / trimatl()</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Symmetric_matrix">Symmetric matrix in Wikipedia</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="strans"></a>
+<b>strans(mat)</b>
+<br><b>strans(colvec)</b>
+<br><b>strans(rowvec)</b>
+<ul>
+<li>
+Simple matrix transpose, without taking the conjugate of the elements (complex matrices)
+</li>
+<br>
+<li>
+Use <a href="#trans">trans()</a> instead, unless you explicitly need to take the transpose of a complex matrix without taking the conjugate of the elements
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#t_st_members">.st()</a></li>
+<li><a href="#trans">trans()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+
+<a name="trans"></a>
+<b>trans(mat)</b>
+<br><b>trans(colvec)</b>
+<br><b>trans(rowvec)</b>
+<ul>
+<li>
+Matrix transpose / Hermitian transpose
+</li>
+<br>
+<li>
+If a given object has real elements, a normal transpose is done
+</li>
+<br>
+<li>
+If a given object has complex elements, a Hermitian transpose is done (ie. the conjugate of the elements is taken during the transpose operation)
+</li>
+<br>
+<li>
+<b>Caveat:</b> for complex matrices, the functionality of trans() has changed in version 2.0:
+<ul>
+<li>in version 1.x, <i>trans()</i> does not take the conjugate of complex elements</li>
+<li>in version 1.x, the <i>htrans()</i> function is used for the Hermitian transpose</li>
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>mat A = randu&lt;mat&gt;(5,10);
+mat B = trans(A);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#t_st_members">.t()</a></li>
+<li><a href="#strans">strans()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+
+<a name="trimat"></a>
+<b>trimatu(A)</b>
+<br><b>trimatl(A)</b>
+<ul>
+<li>
+<i>trimatu(A)</i>: interpret square matrix <i>A</i> as upper triangular
+</li>
+<br>
+<li>
+<i>trimatl(A)</i>: interpret square matrix <i>A</i> as lower triangular
+</li>
+<br>
+<li>
+A <i>std::logic_error</i> exception is thrown if <i>A</i> is non-square
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>mat A = randu&lt;mat&gt;(5,5);
+mat U = trimatu(A);
+mat L = trimatl(A);
+
+// tell the inv() function to look only
+// at the upper triangular part
+mat X = inv( trimatu(U) );
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#symmat">symmatu() / symmatl()</a></li>
+<li><a href="#diagmat">diagmat()</a></li>
+<li><a href="#inv">inv()</a></li>
+<li><a href="#solve">solve()</a></li>
+<li><a href="http://mathworld.wolfram.com/TriangularMatrix.html">Triangular matrix in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Triangular_matrix">Triangular matrix in Wikipedia</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline">
+<br>
+
+
+<a name="unique"></a>
+<b>unique(A)</b>
+<br>
+<ul>
+<li>
+Return the unique elements of <i>A</i>, sorted in ascending order
+</li>
+<br>
+<li>
+If <i>A</i> is a vector, the output is also a vector with the same orientation (row or column) as <i>A</i>;
+if <i>A</i> is a matrix, the output is always a column vector
+</li>
+<br>
+<li>
+This function was added in version 3.2
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat X;
+X &lt;&lt; 1 &lt;&lt; 2 &lt;&lt; endr
+  &lt;&lt; 2 &lt;&lt; 3 &lt;&lt; endr;
+
+mat Y = unique(X);
+</pre>
+</ul>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="#find">find()</a></li>
+<li><a href="#sort">sort()</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline">
+
+
+<hr class="greyline">
+<br>
+<br>
+<font size=+1><b>Decompositions, Factorisations, Inverses and Equation Solvers</b></font>
+<br>
+<br>
+<hr class="greyline">
+<br>
+
+<a name="chol"></a>
+<b>R = chol(X)</b>
+<br><b>chol(R, X)</b>
+<ul>
+<li>
+Cholesky decomposition of <i>X</i>, such that <i>R.t()*R = X</i>
+</li>
+<br>
+<li>
+X must be a symmetric, positive-definite matrix
+</li>
+<br>
+<li>If the decomposition fails, <i>R</i> is reset and:
+<ul>
+<li><i>chol(X)</i> throws a <i>std::runtime_error</i> exception</li>
+<li><i>chol(R,X)</i> returns a bool set to <i>false</i></li>
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat X = randu&lt;mat&gt;(5,5);
+mat Y = X.t()*X;
+
+mat R = chol(Y);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="http://mathworld.wolfram.com/CholeskyDecomposition.html">Cholesky decomposition in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Cholesky_decomposition">Cholesky decomposition in Wikipedia</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="eig_sym"></a>
+<b>vec eigval = eig_sym(mat X)</b>
+<br><b>vec eigval = eig_sym(cx_mat X)</b>
+<br>
+<br><b>eig_sym(vec eigval, mat X)</b>
+<br><b>eig_sym(vec eigval, cx_mat X)</b>
+<br>
+<br><b>eig_sym(vec eigval, mat eigvec, mat X, method = "standard")</b>
+<br><b>eig_sym(vec eigval, cx_mat eigvec, cx_mat X, method = "standard")</b>
+<ul>
+<li>Eigen decomposition of symmetric/hermitian matrix <i>X</i></li>
+<br>
+<li>The eigenvalues and corresponding eigenvectors are stored in <i>eigval</i> and <i>eigvec</i>, respectively</li>
+<br>
+<li>The eigenvalues are in ascending order</li>
+<br>
+<li>If <i>X</i> is not square, a <i>std::logic_error</i> exception is thrown</li>
+<br>
+<li>The <i>method</i> argument is optional</li>
+<br>
+<li>
+By default, a standard eigen decomposition algorithm is used;
+a divide-and-conquer algorithm can be used instead by explicitly setting <i>method</i> to <i>"dc"</i>
+</li>
+<br>
+<li>
+The divide-and-conquer algorithm provides slightly different results, but is notably faster for large matrices
+</li>
+<br>
+<li>If the decomposition fails, the output objects are reset and:
+<ul>
+<li><i>eig_sym(X)</i> throws a <i>std::runtime_error</i> exception</li>
+<li><i>eig_sym(eigval, X)</i> and <i>eig_sym(eigval, eigvec, X)</i> return a bool set to <i>false</i></li>
+</ul>
+</li>
+<br>
+<li>There is currently no check whether <i>X</i> is symmetric</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(50,50);
+mat B = A.t()*A;  // generate a symmetric matrix
+
+vec eigval;
+mat eigvec;
+
+eig_sym(eigval, eigvec, B);        // use standard algorithm by default
+
+eig_sym(eigval, eigvec, B, "dc");  // use "divide &amp; conquer" algorithm
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#eig_gen">eig_gen()</a></li>
+<li><a href="#svd">svd()</a></li>
+<li><a href="#svd_econ">svd_econ()</a></li>
+<li><a href="http://mathworld.wolfram.com/EigenDecomposition.html">eigen decomposition in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Eigenvalues_and_eigenvectors">eigenvalues &amp; eigenvectors in Wikipedia</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Divide-and-conquer_eigenvalue_algorithm">divide &amp; conquer eigenvalue algorithm in Wikipedia</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="eig_gen"></a>
+<b>eig_gen(cx_vec eigval, cx_mat eigvec, mat X, side='r')</b>
+<br>
+<b>eig_gen(cx_vec eigval, cx_mat eigvec, cx_mat X, side='r')</b>
+<br>
+<br>
+<b>eig_gen(cx_vec eigval, mat l_eigvec, mat r_eigvec, mat X)</b>
+<br>
+<b>eig_gen(cx_vec eigval, cx_mat l_eigvec, cx_mat r_eigvec, cx_mat X)</b>
+<ul>
+<li>
+Eigen decomposition of general (non-symmetric/non-hermitian) square matrix <i>X</i></li>
+<br>
+<li>The eigenvalues and corresponding eigenvectors are stored in <i>eigval</i> and <i>eigvec</i>, respectively</li>
+<br>
+<li>
+For the first two forms, <i>side='r'</i> (default) specifies that right eigenvectors are computed,
+while <i>side='l'</i> specifies that left eigenvectors are computed
+</li>
+<br>
+<li>For the last two forms, both left and right eigenvectors are computed</li>
+<br>
+<li>
+The eigenvalues are not guaranteed to be ordered
+</li>
+<br>
+<li>If <i>X</i> is not square, a <i>std::logic_error</i> exception is thrown</li>
+<br>
+<li>If the decomposition fails, the output objects are reset and <i>eig_gen()</i> returns a bool set to <i>false</i></li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(10,10);
+
+cx_vec eigval;
+cx_mat eigvec;
+
+eig_gen(eigval, eigvec, A);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#eig_sym">eig_sym()</a></li>
+<li><a href="#svd">svd()</a></li>
+<li><a href="#svd_econ">svd_econ()</a></li>
+<li><a href="http://mathworld.wolfram.com/EigenDecomposition.html">eigen decomposition in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Eigenvalues_and_eigenvectors">eigenvalues &amp; eigenvectors in Wikipedia</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="fft"></a>
+<b>cx_mat Y = &nbsp;fft(X)</b><br>
+<b>cx_mat Y = &nbsp;fft(X, n)</b><br>
+<br>
+<b>cx_mat Z = ifft(cx_mat Y)</b><br>
+<b>cx_mat Z = ifft(cx_mat Y, n)</b><br>
+<ul>
+<li>fft(): fast Fourier transform of a vector or matrix (real or complex)</li>
+<br>
+<li>ifft(): inverse fast Fourier transform of a vector or matrix (complex only)</li>
+<br>
+<li>If given a matrix, the transform is done on each column vector of the matrix</li>
+<br>
+<li>
+The optional <i>n</i> argument specifies the transform length:
+<ul>
+<li>if <i>n</i> is larger than the length of the input vector, a zero-padded version of the vector is used</li>
+<li>if <i>n</i> is smaller than the length of the input vector, only the first <i>n</i> elements of the vector are used</li>
+</ul>
+</li>
+<br>
+<li>
+If <i>n</i> is not specified, the transform length is the same as the length of the input vector
+</li>
+<br>
+<li><b>Caveat:</b> the transform is fastest when the transform length is a power of 2, eg. 64, 128, 256, 512, 1024, ...</li>
+<br>
+<li>The implementation of the transform in this version is preliminary; it is not yet fully optimised</li>
+<br>
+<li>This function was added in version 3.810</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+   vec X = randu&lt;vec&gt;(100);
+cx_vec Y = fft(X, 128);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#conv">conv()</a></li>
+<li><a href="#imag_real">real()</a></li>
+<li><a href="http://mathworld.wolfram.com/FastFourierTransform.html">fast Fourier transform in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Fast_Fourier_transform">fast Fourier transform in Wikipedia</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="inv"></a>
+<b>B = inv(A, </b><i>slow=false</i><b>)</b>
+<br>
+<b>inv(B, A, </b><i>slow=false</i><b>)</b>
+<ul>
+<li>
+Inverse of square matrix <i>A</i>
+</li>
+<br>
+<li>the <i>slow</i> argument is optional</li>
+<br>
+<li>
+If <i>A</i> is known to be a triangular matrix,
+the inverse can be computed faster by explicitly marking the matrix as triangular
+through <a href="#trimat">trimatu()</a> or <a href="#trimat">trimatl()</a>
+</li>
+<br>
+<li>
+If <i>A</i> is known to be a positive-definite symmetric matrix,
+the inverse can be computed faster by explicitly marking the matrix using sympd()
+</li>
+<br>
+<li>
+If <i>A</i> is not square, a <i>std::logic_error</i> exception is thrown
+</li>
+<br>
+<li>If <i>A</i> appears to be singular, <i>B</i> is reset and:
+<ul>
+<li><i>inv(A)</i> throws a <i>std::runtime_error</i> exception</li>
+<li><i>inv(B,A)</i> returns a bool set to <i>false</i></li>
+</ul>
+</li>
+<br>
+<li>
+<b>NOTE:</b> in many cases it is more efficient/faster to use the <a href="#solve">solve()</a> function instead of performing a matrix inverse;
+for example, if you want to solve a system of linear equations, eg., <i>X = inv(A)*B</i>,
+use <a href="#solve">solve()</a> instead
+</li>
+<br>
+<li>
+For matrix sizes &le; 4x4, a fast inverse algorithm is used by default.
+In rare instances, the fast algorithm might be less precise than the standard algorithm.
+To force the use of the standard algorithm, set the <i>slow</i> argument to <i>true</i>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+mat B = inv(A);
+
+
+// Diagonal elements in C are set to the
+// reciprocal of the corresponding elements in A.
+// Off-diagonal elements in C are set to zero.
+mat C = inv( diagmat(A) );
+
+
+// tell inv() to look only at the upper triangular part of A
+mat D = inv( trimatu(A) );
+
+
+// tell inv() that AA is a symmetric positive definite matrix
+mat AA = A*A.t();
+mat E  = inv( sympd(AA) );
+
+
+mat44 F = randu&lt;mat&gt;(4,4);
+
+mat G = inv(F);       // use fast algorithm by default
+mat H = inv(F, true); // use slow algorithm
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also: 
+<ul>
+<li><a href="#i_member">.i()</a>
+<li><a href="#pinv">pinv()</a>
+<li><a href="#solve">solve()</a></li>
+<li><a href="#trimat">trimatu() / trimatl()</a></li>
+<li><a href="http://mathworld.wolfram.com/MatrixInverse.html">matrix inverse in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Invertible_matrix">invertible matrix in Wikipedia</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+
+
+<a name="lu"></a>
+<b>lu(mat L, mat U, mat P, mat X)</b>
+<br>
+<b>lu(mat L, mat U, mat X)</b>
+<ul>
+<li>
+Lower-upper decomposition (with partial pivoting) of matrix <i>X</i>
+</li>
+<br>
+<li>
+The first form provides 
+a lower-triangular matrix <i>L</i>,
+an upper-triangular matrix <i>U</i>,
+and a permutation matrix <i>P</i>,
+such that <i>P.t()*L*U&nbsp;=&nbsp;X</i>
+</li>
+<br>
+<li>
+The second form provides permuted <i>L</i> and <i>U</i>, such that <i>L*U = X</i>.
+Note that in this case <i>L</i> is generally not lower-triangular
+</li>
+<br>
+<li>
+If the decomposition fails, the output objects are reset and <i>lu()</i> returns a bool set to <i>false</i>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+
+mat L, U, P;
+
+lu(L, U, P, A);
+
+mat B = P.t()*L*U;
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="http://en.wikipedia.org/wiki/LU_decomposition">LU decomposition in Wikipedia</a></li>
+<li><a href="http://mathworld.wolfram.com/LUDecomposition.html">LU decomposition in MathWorld</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="pinv"></a>
+<b>B = pinv(A, tolerance = default)</b>
+<br><b>pinv(B, A, tolerance = default)</b>
+<ul>
+<li>Moore-Penrose pseudo-inverse of matrix <i>A</i></li>
+<br>
+<li>The <i>tolerance</i> argument is optional</li>
+<br>
+<li>The computation is based on singular value decomposition;
+if the decomposition fails, <i>B</i> is reset and:
+<ul>
+<li><i>pinv(A)</i> throws a <i>std::runtime_error</i> exception</li>
+<li><i>pinv(B,A)</i> returns a bool set to <i>false</i></li>
+</ul>
+<br>
+<li>Any singular values less than <i>tolerance</i> are treated as zero</li>
+<br>
+<li>For matrix <i>A</i> with <i>m</i> rows and <i>n</i> columns,
+the default tolerance is <i>max(m,n)*norm(A)*datum::eps</i>,
+where <i>datum::eps</i> denotes the difference between 1 and the least value greater than 1 that is representable</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(4,5);
+mat B = pinv(A);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#i_member">.i()</a></li>
+<li><a href="#inv">inv()</a></li>
+<li><a href="#solve">solve()</a></li>
+<li><a href="#constants">datum::eps</a></li>
+<li><a href="http://mathworld.wolfram.com/Pseudoinverse.html">Pseudoinverse in MathWorld</a></li>
+<li><a href="http://mathworld.wolfram.com/Moore-PenroseMatrixInverse.html">Moore-Penrose Matrix Inverse in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Moore-Penrose_pseudoinverse">Moore-Penrose pseudoinverse in Wikipedia</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="princomp"></a>
+<b>mat coeff = princomp(mat X)</b>
+<br><b>cx_mat coeff = princomp(cx_mat X)</b><br>
+
+<br><b>princomp(mat coeff, mat X)</b>
+<br><b>princomp(cx_mat coeff, cx_mat X)</b><br>
+
+<br><b>princomp(mat coeff, mat score, mat X)</b>
+<br><b>princomp(cx_mat coeff, cx_mat score, cx_mat X)</b><br>
+
+<br><b>princomp(mat coeff, mat score, vec latent, mat X)</b>
+<br><b>princomp(cx_mat coeff, cx_mat score, vec latent, cx_mat X)</b><br>
+
+<br><b>princomp(mat coeff, mat score, vec latent, vec tsquared, mat X)</b>
+<br><b>princomp(cx_mat coeff, cx_mat score, vec latent, cx_vec tsquared, cx_mat X)</b><br>
+<br>
+<ul>
+<li>Principal component analysis of matrix <i>X</i></li><br>
+<li>Each row of <i>X</i> is an observation and each column is a variable</li><br>
+<li>output objects:
+<ul>
+<li><i>coeff</i>: principal component coefficients</li>
+<li><i>score</i>: projected data</li>
+<li><i>latent</i>: eigenvalues of the covariance matrix of <i>X</i></li>
+<li><i>tsquared</i>: Hotteling's statistic for each sample</li>
+</ul>
+</li>
+<br>
+<li>The computation is based on singular value decomposition;
+if the decomposition fails, the output objects are reset and:
+<ul>
+<li><i>princomp(X)</i> throws a <i>std::runtime_error</i> exception</li>
+<li>remaining forms of <i>princomp()</i> return a bool set to <i>false</i></li>
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,4);
+
+mat coeff;
+mat score;
+vec latent;
+vec tsquared;
+
+princomp(coeff, score, latent, tsquared, A);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="http://en.wikipedia.org/wiki/Principal_component_analysis">principal components analysis in Wikipedia</a></li>
+<li><a href="http://mathworld.wolfram.com/PrincipalComponentAnalysis.html">principal components analysis in MathWorld</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="qr"></a>
+<b>qr(Q,R,X)</b>
+<ul>
+<li>
+Decomposition of <i>X</i> into an orthogonal matrix <i>Q</i> and a right triangular matrix <i>R</i>, such that <i>Q*R = X</i>
+</li>
+<br>
+<li>
+If the decomposition fails, <i>Q</i> and <i>R</i> are reset and the function returns a bool set to <i>false</i>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat X = randu&lt;mat&gt;(5,5);
+mat Q, R;
+
+qr(Q,R,X);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#qr_econ">qr_econ()</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Orthogonal_matrix">Orthogonal matrix in Wikipedia</a></li>
+<li><a href="http://en.wikipedia.org/wiki/QR_decomposition">QR decomposition in Wikipedia</a></li>
+<li><a href="http://mathworld.wolfram.com/QRDecomposition.html">QR decomposition in MathWorld</a></li>
+<li><a href="http://octave.sourceforge.net/octave/function/qr.html">QR decomposition in Octave</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="qr_econ"></a>
+<b>qr_econ(Q,R,X)</b>
+<ul>
+<li>
+Economical decomposition of <i>X</i> (with size <i>m</i> x <i>n</i>) into an orthogonal matrix <i>Q</i> and a right triangular matrix <i>R</i>, such that <i>Q*R = X</i>
+</li>
+<br>
+<li>
+If <i>m</i> &gt; <i>n</i>, only the first <i>n</i> rows of <i>R</i> and the first <i>n</i> columns of <i>Q</i> are calculated 
+(ie. the zero rows of <i>R</i> and the corresponding columns of <i>Q</i> are omitted)
+</li>
+<br>
+<li>
+If the decomposition fails, <i>Q</i> and <i>R</i> are reset and the function returns a bool set to <i>false</i>
+</li>
+<br>
+<li>
+This function was added in version 3.4
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat X = randu&lt;mat&gt;(6,5);
+mat Q, R;
+
+qr_econ(Q,R,X);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#qr">qr()</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Orthogonal_matrix">Orthogonal matrix in Wikipedia</a></li>
+<li><a href="http://en.wikipedia.org/wiki/QR_decomposition">QR decomposition in Wikipedia</a></li>
+<li><a href="http://octave.sourceforge.net/octave/function/qr.html">QR decomposition in Octave</a></li>
+<li><a href="http://mathworld.wolfram.com/QRDecomposition.html">QR decomposition in MathWorld</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<a name="solve"></a>
+<b>X = solve(A, B, </b><i>slow=false</i><b>)</b>
+<br><b>solve(X, A, B, </b><i>slow=false</i><b>)</b>
+<ul>
+<li>Solve a system of linear equations, ie., <i>A*X = B</i>, where <i>X</i> is unknown</li>
+<br>
+<li>The <i>slow</i> argument is optional</li>
+<br>
+<li>For a square matrix <i>A</i>, this function is conceptually the same as <i>X = inv(A)*B</i>, but is more efficient</li>
+<br>
+<li>Similar functionality to the "\" (left division operator) operator in Matlab/Octave, ie. <i>X&nbsp;=&nbsp;A&nbsp;\&nbsp;B</i></li>
+<br>
+<li>The number of rows in <i>A</i> and <i>B</i> must be the same</li>
+<br>
+<li>
+If <i>A</i> is known to be a triangular matrix,
+the solution can be computed faster by explicitly marking the matrix as triangular
+through <a href="#trimat">trimatu()</a> or <a href="#trimat">trimatl()</a>
+</li>
+<br>
+<li>
+If <i>A</i> is non-square (and hence also non-triangular),
+solve() will also try to provide approximate solutions to under-determined as well as over-determined systems</li>
+<br>
+<li>
+If no solution is found, <i>X</i> is reset and:
+<ul>
+<li><i>solve(A,B)</i> throws a <i>std::runtime_error</i> exception</li>
+<li><i>solve(X,A,B)</i> returns a bool set to <i>false</i></li>
+</ul>
+</li>
+<br>
+<li>
+For matrix sizes &le; 4x4, a fast algorithm is used by default.
+In rare instances, the fast algorithm might be less precise than the standard algorithm.
+To force the use of the standard algorithm, set the <i>slow</i> argument to <i>true</i>
+</li>
+<br>
+<li>
+<b>NOTE:</b> Old versions of the ATLAS library (eg.&nbsp;3.6) can corrupt memory and crash your program;
+the standard LAPACK library and later versions of ATLAS (eg.&nbsp;3.8) work without problems
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+vec b = randu&lt;vec&gt;(5);
+mat B = randu&lt;mat&gt;(5,5);
+
+vec x = solve(A, b);
+mat X = solve(A, B);
+
+vec x2;
+solve(x2, A, b);
+
+// tell solve() to look only at the upper triangular part of A
+mat Y = solve( trimatu(A), B );
+
+
+mat44 C = randu&lt;mat&gt;(4,4);
+mat44 D = randu&lt;mat&gt;(4,4);
+
+mat E = solve(C, D);       // use fast algorithm by default
+mat F = solve(C, D, true); // use slow algorithm
+
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#i_member">.i()</a></li>
+<li><a href="#inv">inv()</a></li>
+<li><a href="#pinv">pinv()</a></li>
+<li><a href="#syl">syl()</a></li>
+<li><a href="#trimat">trimatu() / trimatl()</a></li>
+<li><a href="http://mathworld.wolfram.com/LinearSystemofEquations.html">linear system of equations in MathWorld</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Linear_system_of_equations">system of linear equations in Wikipedia</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+
+<a name="svd"></a>
+<b>vec s = svd(mat X)</b>
+<br><b>vec s = svd(cx_mat X)</b>
+<br>
+<br><b>svd(vec s, mat X)</b>, 
+<br><b>svd(vec s, cx_mat X)</b> 
+<br>
+<br><b>svd(mat U, vec s, mat V, mat X, method = "standard")</b>
+<br><b>svd(cx_mat U, vec s, cx_mat V, cx_mat X, method = "standard")</b>
+<ul>
+<li>
+The first four forms compute the singular values of <i>X</i>
+</li>
+<br>
+<li>
+The last two forms compute the full singular value decomposition of <i>X</i>
+</li>
+<br>
+<li>The <i>method</i> argument is optional</li>
+<br>
+<li>
+By default, a standard decomposition algorithm is used;
+a divide-and-conquer algorithm can be used instead by explicitly setting <i>method</i> to <i>"dc"</i>
+</li>
+<br>
+<li>
+The divide-and-conquer algorithm provides slightly different results, but is notably faster for large matrices
+</li>
+<br>
+<li>If <i>X</i> is square, it can be reconstructed using <i>X = U*diagmat(s)*V.t()</i>
+</li>
+<br>
+<li>
+The singular values are in descending order
+</li>
+<br>
+<li>
+If the decomposition fails, the output objects are reset and:
+<ul>
+<li><i>svd(X)</i> throws a <i>std::runtime_error</i> exception</li>
+<li><i>svd(s,X)</i> and <i>svd(U,s,V,X)</i> return a bool set to <i>false</i></li>
+</ul>
+</li>
+<br>
+<li>
+<b>NOTE:</b> Old versions of the ATLAS library (eg.&nbsp;3.6) can corrupt memory and crash your program;
+the standard LAPACK library and later versions of ATLAS (eg.&nbsp;3.8) work without problems
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat X = randu&lt;mat&gt;(5,5);
+
+mat U;
+vec s;
+mat V;
+
+svd(U,s,V,X);        // use standard algorithm by default
+
+svd(U,s,V,X, "dc");  // use "divide &amp; conquer" algorithm
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#svd_econ">svd_econ()</a></li>
+<li><a href="#eig_gen">eig_gen()</a></li>
+<li><a href="#eig_sym">eig_sym()</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Singular_value_decomposition">singular value decomposition in Wikipedia</a></li>
+<li><a href="http://mathworld.wolfram.com/SingularValueDecomposition.html">singular value decomposition in MathWorld</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline">
+<br>
+
+<a name="svd_econ"></a>
+<b>svd_econ(mat U, vec s, mat V, mat X, mode = 'b')</b>
+<br><b>svd_econ(cx_mat U, vec s, cx_mat V, cx_mat X, mode = 'b')</b>
+<ul>
+<li>
+Economical singular value decomposition of <i>X</i>
+</li>
+<br>
+<li>
+mode is one of:
+<ul>
+<li><i>'l'</i>: compute only left singular vectors</li>
+<li><i>'r'</i>: compute only right singular vectors</li>
+<li><i>'b'</i>: compute both left and right singular vectors (default)</li>
+</ul>
+</li>
+<br>
+<li>
+The singular values are in descending order
+</li>
+<br>
+<li>
+If the decomposition fails, the output objects are reset and bool set to <i>false</i> is returned
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat X = randu&lt;mat&gt;(4,5);
+
+mat U;
+vec s;
+mat V;
+svd_econ(U, s, V, X, 'l');
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#svd">svd()</a></li>
+<li><a href="#eig_gen">eig_gen()</a></li>
+<li><a href="#eig_sym">eig_sym()</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Singular_value_decomposition">singular value decomposition in Wikipedia</a></li>
+<li><a href="http://mathworld.wolfram.com/SingularValueDecomposition.html">singular value decomposition in MathWorld</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline">
+<br>
+
+<a name="syl"></a>
+<b>X = syl(A, B, C)</b>
+<br><b>syl(X, A, B, C)</b>
+<ul>
+<li>Solve the Sylvester equation, ie., <i>AX + XB + C = 0</i>, where <i>X</i> is unknown.</li>
+<br>
+<li>Matrices <i>A</i>, <i>B</i> and <i>C</i> must be square sized.</li>
+<br>
+<li>
+If no solution is found, <i>X</i> is reset and:
+<ul>
+<li><i>syl(A,B,C)</i> throws a <i>std::runtime_error</i> exception</li>
+<li><i>svd(X,A,B,C)</i> returns a bool set to <i>false</i></li>
+</ul>
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+mat B = randu&lt;mat&gt;(5,5);
+mat C = randu&lt;mat&gt;(5,5);
+
+mat X1 = syl(A, B, C);
+
+mat X2;
+syl(X2, A, B, C);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#solve">solve()</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Sylvester_equation">Sylvester equation in Wikipedia</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline">
+
+
+<hr class="greyline">
+<br>
+<br>
+<font size=+1><b>Miscellaneous</b></font>
+<br>
+<br>
+<hr class="greyline">
+<br>
+
+<a name="is_finite_standalone"></a>
+<b>is_finite(X)</b>
+<ul>
+<li>
+Returns <i>true</i> if all elements in <i>X</i> are finite
+</li>
+<br>
+<li>
+Returns <i>false</i> if at least one element in <i>X</i> is non-finite (&plusmn;infinity or NaN)
+</li>
+<br>
+<li>
+<i>X</i> can be a scalar (eg. <i>double</i>), vector, matrix or cube
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+mat A = randu&lt;mat&gt;(5,5);
+mat B = randu&lt;mat&gt;(5,5);
+
+B(1,1) = datum::nan;
+
+cout &lt;&lt; is_finite(A) &lt;&lt; endl;
+cout &lt;&lt; is_finite(B) &lt;&lt; endl;
+
+cout &lt;&lt; is_finite( 0.123456789 ) &lt;&lt; endl;
+cout &lt;&lt; is_finite( datum::nan  ) &lt;&lt; endl;
+cout &lt;&lt; is_finite( datum::inf  ) &lt;&lt; endl;
+</pre>
+</ul>
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#constants">datum::nan</a></li>
+<li><a href="#constants">datum::inf</a></li>
+<li><a href="#is_finite">.is_finite()</a> (member function of <i>Mat</i> and <i>Cube</i>)</li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="logging"></a>
+<b>logging of warnings and errors</b>
+<br>
+<br>
+<b>set_stream_err1(user_stream)</b><br>
+<b>set_stream_err2(user_stream)</b><br>
+<br>
+<b>std::ostream&amp; x = get_stream_err1()</b>
+<br>
+<b>std::ostream&amp; x = get_stream_err2()</b>
+<br>
+<ul>
+<li>
+By default, Armadillo prints warnings and messages associated with <i>std::logic_error</i> and <i>std::runtime_error</i> exceptions to the <i>std::cout</i> stream
+</li>
+<br>
+<li><b>set_stream_err1()</b>: change the stream for messages associated with <i>std::logic_error</i> exceptions (eg. out of bounds accesses)</li>
+<br>
+<li><b>set_stream_err2()</b>: change the stream for warnings and messages associated with <i>std::runtime_error</i> exceptions (eg. failed decompositions)</li>
+<br>
+<li><b>get_stream_err1()</b>: get a reference to the stream for messages associated with <i>std::logic_error</i> exceptions</li>
+<br>
+<li><b>get_stream_err2()</b>: get a reference to the stream for warnings and messages associated with <i>std::runtime_error</i> exceptions</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+// print "hello" to the current err1 stream
+get_stream_err1() &lt;&lt; "hello" &lt;&lt; endl;
+
+// change the err2 stream to be a file
+ofstream f("my_log.txt");
+set_stream_err2(f);
+
+// trying to invert a singular matrix
+// will print a message to the err2 stream
+// and throw an exception
+mat X = zeros&lt;mat&gt;(5,5);
+mat Y = inv(X);
+
+// disable messages being printed to the err2 stream
+std::ostream nullstream(0);
+set_stream_err2(nullstream);
+</pre>
+</ul>
+</li>
+<br>
+<li>
+<b>Caveat</b>: set_stream_err1() and set_stream_err2() will not change the stream used by .print()
+</li>
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#print">.print()</a></li>
+<li><a href="http://cplusplus.com/reference/iostream/cout/">std::cout</a></li>
+<li><a href="http://cplusplus.com/reference/iostream/ostream/">std::ostream</a></li>
+<li><a href="http://cplusplus.com/reference/std/stdexcept/logic_error/">std::logic_error</a></li>
+<li><a href="http://cplusplus.com/reference/std/stdexcept/runtime_error/">std::runtime_error</a></li>
+<li><a href="http://cplusplus.com/doc/tutorial/exceptions/">tutorial on exceptions</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+
+
+<a name="constants"></a>
+<b>various constants (pi, inf, speed of light, ...)</b>
+<br>
+<ul>
+<li>
+Collection of math and fundamental physical constants
+</li>
+<br>
+<li>
+Physical constants were mainly taken from
+<a href="http://physics.nist.gov/cuu/Constants">NIST</a>
+and some from
+<a href="http://www.wolframalpha.com">WolframAlpha</a>
+on 2009-06-23;
+constants from NIST are in turn sourced from the <a href="http://physics.nist.gov/cuu/Constants/papers.html">2006 CODATA values</a>
+</li>
+<br>
+<li>
+The constants are stored in the <i>Datum&lt;type&gt;</i> class,
+where <i>type</i> is either <i>float</i> or <i>double</i>
+</li>
+<br>
+<li>
+For convenience,
+<i>Datum&lt;double&gt;</i> has been typedefed as <i>datum</i>
+while 
+<i>Datum&lt;float&gt;</i> has been typedefed as <i>fdatum</i>
+</li>
+<br>
+<li>
+In previous versions of Armadillo (eg. 2.x), the constants are accessed via static functions in <i>math</i> and <i>phy</i> classes, eg. <i>math::pi()</i>;
+for compatibility, these classes are still available in version 3.x, but are not explicitly documented
+</li>
+<br>
+<li>
+Meaning of the constants:
+<br>
+<br>
+<ul>
+<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
+<tbody>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::pi
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &pi;, the ratio of any circle's circumference to its diameter
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::inf
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      infinity
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::nan
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &ldquo;not a number&rdquo; (NaN); <b>caveat:</b> NaN is not equal to anything, even itself
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::e
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      base of the natural logarithm
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::sqrt2
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      square root of 2
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::eps
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      the difference between 1 and the least value greater than 1 that is representable  (type and machine dependant)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::log_min
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      log of minimum non-zero value (type and machine dependant)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::log_max
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      log of maximum value  (type and machine dependant)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::euler
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Euler's constant, aka Euler-Mascheroni constant
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::gratio
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      golden ratio
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::m_u
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      atomic mass constant (in kg)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::N_A
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Avogadro constant
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::k
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Boltzmann constant (in joules per kelvin)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::k_evk
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Boltzmann constant (in eV/K)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::a_0
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Bohr radius (in meters)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::mu_B
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Bohr magneton
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::Z_0
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      characteristic impedance of vacuum (in ohms)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::G_0
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      conductance quantum (in siemens)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::k_e
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Coulomb's constant (in meters per farad)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::eps_0
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      electric constant (in farads per meter)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::m_e
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      electron mass (in kg)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::eV
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      electron volt (in joules)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::ec
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      elementary charge (in coulombs)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::F
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Faraday constant (in coulombs)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::alpha
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      fine-structure constant
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::alpha_inv
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      inverse fine-structure constant
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::K_J
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Josephson constant
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::mu_0
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      magnetic constant (in henries per meter)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::phi_0
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      magnetic flux quantum (in webers)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::R
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      molar gas constant (in joules per mole kelvin)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::G
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Newtonian constant of gravitation (in newton square meters per kilogram squared)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::h
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Planck constant (in joule seconds)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::h_bar
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Planck constant over 2 pi, aka reduced Planck constant (in joule seconds)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::m_p
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      proton mass (in kg)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::R_inf
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Rydberg constant (in reciprocal meters)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::c_0
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      speed of light in vacuum (in meters per second)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::sigma
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Stefan-Boltzmann constant
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::R_k
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      von Klitzing constant (in ohms)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      datum::b
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Wien wavelength displacement law constant
+    </td>
+  </tr>
+</tbody>
+</table>
+</ul>
+</li>
+<br>
+<li>
+<b>Caveat:</b>
+datum::nan is not equal to anything, even itself;
+if you wish to check whether a given number <i>x</i> is finite,
+use <a href="#is_finite_standalone">is_finite</a>(<i>x</i>).
+</li>
+<br>
+<li>
+Examples:
+<ul>
+<pre>
+cout &lt;&lt; "2.0 * pi = " &lt;&lt; 2.0 * datum::pi &lt;&lt; endl;
+
+cout &lt;&lt; "speed of light = " &lt;&lt; datum::c_0 &lt;&lt; endl;
+
+cout &lt;&lt; "log_max for floats = ";
+cout &lt;&lt; fdatum::log_max &lt;&lt; endl;
+
+cout &lt;&lt; "log_max for doubles = ";
+cout &lt;&lt; datum::log_max &lt;&lt; endl;
+</pre>
+</ul>
+</li>
+<li>
+See also:
+<ul>
+<li><a href="#is_finite_standalone">is_finite()</a></li>
+<li><a href="http://en.wikipedia.org/wiki/NaN">NaN</a> in Wikipedia</li>
+<li><a href="http://en.wikipedia.org/wiki/Physical_constant">physical constant</a> in Wikipedia</li>
+<li><a href="http://cplusplus.com/reference/std/limits/numeric_limits/">std::numeric_limits</a></li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+
+<!--
+<a name="log_add"></a>
+<b>log_add(log_a, log_b)</b>
+<ul>
+<li>
+Safe replacement for log(exp(log_a) + exp(log_b))
+</li>
+<br>
+<li>
+Usage:
+<ul>
+<li>
+<i>scalar_type</i> log_c = log_add(log_a, log_b)
+</li>
+<li>
+<i>scalar_type</i> is either <i>float</i> or <i>double</i>
+</li>
+<li>
+log_a, log_b and log_c must have the same type
+</li>
+</ul>
+</li>
+</ul>
+<br>
+<hr class="greyline"><br>
+-->
+
+<a name="uword"></a>
+<b>uword</b>, <b>sword</b>
+<ul>
+<li>
+<i>uword</i> is a typedef for an unsigned integer with a minimum width of 32 bits; if <i>ARMA_64BIT_WORD</i> is enabled, the minimum width is 64 bits
+</li>
+<br>
+<li>
+<i>sword</i> is a typedef for a signed integer with a minimum width of 32 bits; if <i>ARMA_64BIT_WORD</i> is enabled, the minimum width is 64 bits
+</li>
+<br>
+<li>
+<a href="#config_hpp_arma_64bit_word"><i>ARMA_64BIT_WORD</i></a> can be enabled via editing <i>include/armadillo_bits/config.hpp</i>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="http://cplusplus.com/doc/tutorial/variables/">C++ variable types</a></li>
+<li><a href="http://www.cplusplus.com/doc/tutorial/other_data_types/">explanation of <i>typedef</i></a></li>
+<li><a href="#Mat">imat &amp; umat</a> matrix types
+<li><a href="#Col">ivec &amp; uvec</a> vector types
+</ul>
+</li>
+<br>
+</ul>
+<hr class="greyline"><br>
+
+<a name="cx_float_double"></a>
+<b>cx_float</b>, <b>cx_double</b>
+<ul>
+<li>
+cx_float is a typedef for <i>std::complex&lt;float&gt;</i>
+</li>
+<br>
+<li>
+cx_double is a typedef for <i>std::complex&lt;double&gt;</i>
+</li>
+<br>
+<li>See also:
+<ul>
+<li><a href="http://cplusplus.com/reference/std/complex/">complex numbers in the standard C++ library</a></li>
+<li><a href="http://www.cplusplus.com/doc/tutorial/other_data_types/">explanation of <i>typedef</i></a></li>
+<li><a href="#Mat">cx_mat</a> matrix type
+<li><a href="#Col">cx_vec</a> vector type
+</ul>
+</li>
+<br>
+</ul>
+
+<a name="syntax"></a>
+<hr class="greyline">
+<br>
+<b>
+Examples of Matlab/Octave syntax and conceptually corresponding Armadillo syntax
+</b>
+<br>
+<br>
+<ul>
+<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
+<tbody>
+  <tr>
+    <td style="vertical-align: top;">
+      <b>Matlab/Octave</b>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <b>Armadillo</b>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <b>Notes</b>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A(1, 1)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A(0, 0)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      indexing in Armadillo starts at 0
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A(k, k)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A(k-1, k-1)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      size(A,1)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A<a href="#attributes">.n_rows</a>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      read only
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      size(A,2)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A<a href="#attributes">.n_cols</a>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      size(Q,3)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Q<a href="#attributes">.n_slices</a>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Q is a <a href="#Cube">cube</a> (3D array)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      numel(A)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A<a href="#attributes">.n_elem</a>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A(:, k)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A<a href="#submat">.col</a>(k)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+this is a conceptual example only; 
+exact conversion from Matlab/Octave to Armadillo syntax
+will require taking into account that indexing starts at 0
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A(k, :)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A<a href="#submat">.row</a>(k)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A(:, p:q)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A<a href="#submat">.cols</a>(p, q)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A(p:q, :)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A<a href="#submat">.rows</a>(p, q)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A(p:q, r:s)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <font size=-1>
+      A<a href="#submat">.submat</a>(p, r, q, s)
+      </font>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <font size=-1>
+      A.submat(first_row, first_col, last_row, last_col)
+      </font>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <font size=-1>
+      or
+      </font>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <font size=-1>
+      A(&nbsp;<a href="#submat">span</a>(p,q),&nbsp;<a href="#submat">span</a>(r,s)&nbsp;)
+      </font>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <font size=-1>
+      A(&nbsp;span(first_row,&nbsp;last_row), span(first_col,&nbsp;last_col)&nbsp;)
+      </font>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      Q(:, :, k)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Q<a href="#subcube">.slice</a>(k)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Q is a <a href="#Cube">cube</a> (3D array)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      Q(:, :, t:u)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Q<a href="#subcube">.slices</a>(t, u)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      Q(p:q, r:s, t:u)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <font size=-1>
+      Q<a href="#subcube">.subcube</a>(p,&nbsp;r,&nbsp;t,&nbsp;q,&nbsp;s,&nbsp;u)
+      </font>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <font size=-1>
+      .subcube(first_row, first_col, first_slice, last_row, last_col, last_slice)
+      </font>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <font size=-1>
+      or
+      </font>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <font size=-1>
+      Q(&nbsp;<a href="#subcube">span</a>(p,q),&nbsp;<a href="#subcube">span</a>(r,s),&nbsp;<a href="#subcube">span</a>(t,u)&nbsp;)
+      </font>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A'
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A<a href="#t_st_members">.t()</a> or <a href="#trans">trans</a>(A)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      matrix transpose / Hermitian transpose
+      <br>
+      (for complex matrices, the conjugate of each element is taken)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A.'
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+       A<a href="#t_st_members">.st()</a> or <a href="#strans">strans</a>(A)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      simple matrix transpose
+      <br>
+      (for complex matrices, the conjugate of each element is not taken)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A = zeros(size(A))
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A<a href="#zeros_member">.zeros()</a>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A = ones(size(A))
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A.<a href="#ones_member">ones()</a>
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A = zeros(k)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A = <a href="#zeros_standalone">zeros</a>&lt;mat&gt;(k,k)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A = ones(k)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A = <a href="#ones_standalone">ones</a>&lt;mat&gt;(k,k)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      C = complex(A,B)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      cx_mat C = <a href="#Mat">cx_mat</a>(A,B)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A .* B
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A % B
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <a href="#operators">element-wise multiplication</a>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A ./ B
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A / B
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <a href="#operators">element-wise division</a>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A \ B
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <a href="#solve">solve</a>(A,B)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      conceptually similar to <a href="#inv">inv</a>(A)*B, but more efficient
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A = A + 1;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A++
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A = A - 1;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A--
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A = [ 1 2; 3 4; ]
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+A&nbsp;<font size=-1>&lt;&lt;</font> 1 <font size=-1>&lt;&lt;</font> 2 <font size=-1>&lt;&lt;</font> endr<br>
+&nbsp;&nbsp;&nbsp;<font size=-1>&lt;&lt;</font> 3 <font size=-1>&lt;&lt;</font> 4 <font size=-1>&lt;&lt;</font> endr;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <a href="#element_initialisation">element initialisation</a>,
+      with special element <i>endr</i> indicating <i>end of row</i>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      X = [&nbsp;A&nbsp;&nbsp;B&nbsp;]
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      X = <a href="#join">join_rows</a>(A,B)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      X = [&nbsp;A;&nbsp;B&nbsp;]
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      X = <a href="#join">join_cols</a>(A,B)
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      A
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      cout <font size=-1>&lt;&lt;</font> A <font size=-1>&lt;&lt;</font> endl;
+      <br>or
+      <br>A<a href="#print">.print</a>("A =");
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      save&nbsp;-ascii&nbsp;'A.dat'&nbsp;A
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A<a href="#save_load_mat">.save</a>("A.dat",&nbsp;raw_ascii);
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      Matlab/Octave matrices saved as ascii are readable by Armadillo (and vice-versa)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      load&nbsp;-ascii&nbsp;'A.dat'
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      A<a href="#save_load_mat">.load</a>("A.dat",&nbsp;raw_ascii);
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      S&nbsp;=&nbsp;{&nbsp;'abc';&nbsp;'def'&nbsp;}
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <a href="#field">field</a>&lt;std::string&gt; S(2);
+      <br>S(0) = "abc";
+      <br>S(1) = "def";
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      <a href="#field">fields</a> can store arbitrary objects, in a 1D or 2D layout
+    </td>
+  </tr>
+</tbody>
+</table>
+</ul>
+<br>
+
+<a name="example_prog"></a>
+<hr class="greyline">
+<br>
+<b>example program</b>
+<br>
+<br>
+<ul>
+<li>
+If you save the program below as <i>example.cpp</i>,
+under Linux you can compile it using:
+<br>
+g++ example.cpp -o example -O1 -larmadillo
+</li>
+<ul>
+<pre>
+#include &lt;iostream&gt;
+#include &lt;armadillo&gt;
+
+using namespace std;
+using namespace arma;
+
+int main(int argc, char** argv)
+  {
+  mat A = randu&lt;mat&gt;(4,5);
+  mat B = randu&lt;mat&gt;(4,5);
+  
+  cout &lt;&lt; A*B.t() &lt;&lt; endl;
+  
+  return 0;
+  }
+</pre>
+</ul>
+<li>
+You may also want to have a look at the example programs that come with the Armadillo archive.
+</li>
+<br>
+<li>
+As Armadillo is a template library, we strongly recommended to have optimisation enabled when compiling programs
+(eg. when compiling with GCC, use the -O1 or -O2 options).
+</li>
+</ul>
+<br>
+
+
+
+<a name="config_hpp"></a>
+<hr class="greyline">
+<br>
+<b>config.hpp</b>
+<br>
+<br>
+<ul>
+<li>
+Armadillo can be configured via editing the file <i>include/armadillo_bits/config.hpp</i>.
+Specific functionality can be enabled or disabled by uncommenting or commenting out a particular <i>#define</i>, listed below.
+<br>
+<br>
+<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
+<tbody>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_USE_LAPACK
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Enable the use of LAPACK, or a high-speed replacement for LAPACK (eg. Intel MKL, AMD ACML or the Accelerate framework).
+Armadillo requires LAPACK for functions such as <a href="#svd">svd()</a>, <a href="#inv">inv()</a>, <a href="#eig_sym">eig_sym()</a>, <a href="#solve">solve()</a>, etc.
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_USE_BLAS
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Enable the use of BLAS, or a high-speed replacement for BLAS (eg. OpenBLAS, Intel MKL, AMD ACML or the Accelerate framework).
+BLAS is used for <a href="#operators">matrix multiplication</a>.
+Without BLAS, Armadillo will use a built-in matrix multiplication routine, which might be slower for large matrices.
+<!--However, if you're using  64 bit operating system with 32 bit BLAS, it's better to disable the use of BLAS.-->
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_BLAS_CAPITALS
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Use capitalised (uppercase) BLAS and LAPACK function names (eg. DGEMM vs dgemm)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_BLAS_UNDERSCORE
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Append an underscore to BLAS and LAPACK function names (eg. dgemm_ vs dgemm). Enabled by default.
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_BLAS_LONG
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Use "long" instead of "int" when calling BLAS and LAPACK functions
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_BLAS_LONG_LONG
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Use "long long" instead of "int" when calling BLAS and LAPACK functions
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_USE_TBB_ALLOC
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Use Intel TBB <i>scalable_malloc()</i> and <i>scalable_free()</i> instead of standard <i>new[]</i> and <i>delete[]</i> for managing matrix memory
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_USE_MKL_ALLOC
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Use Intel MKL <i>mkl_malloc()</i> and <i>mkl_free()</i> instead of standard <i>new[]</i> and <i>delete[]</i> for managing matrix memory
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+<a name="config_hpp_arma_64bit_word"></a>
+ARMA_64BIT_WORD
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Use 64 bit integers. Useful if you require matrices/vectors capable of holding more than 4 billion elements.
+Your machine and compiler must have support for 64 bit integers (eg. via "long" or "long long").
+This can also be enabled by adding <i>#define&nbsp;ARMA_64BIT_WORD</i> before each instance of <i>#include&nbsp;&lt;armadillo&gt;</i>.
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+<a name="config_hpp_arma_use_cxx11"></a>
+ARMA_USE_CXX11
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Use C++11 features, such as <a href="#element_initialisation">initialiser lists</a>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_USE_HDF5
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Enable the the ability to <a href="#save_load_mat">save and load</a> matrices stored in the HDF5 format;
+the <i>hdf5.h</i> header file must be available on your system and you will need to link with the hdf5 library (eg. -lhdf5)
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+<a name="config_hpp_arma_no_debug"></a>
+ARMA_NO_DEBUG
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Disable all run-time checks, such as <a href="#element_access">bounds checking</a>.
+This will result in faster code, but you first need to make sure that your code runs correctly!
+We strongly recommend to have the run-time checks enabled during development,
+as this greatly aids in finding mistakes in your code, and hence speeds up development.
+We recommend that run-time checks be disabled <b>only</b> for the shipped version of your program.
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_EXTRA_DEBUG
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Print out the trace of internal functions used for evaluating expressions.
+Not recommended for normal use.
+This is mainly useful for debugging the library.
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_MAT_PREALLOC
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+The number of preallocated elements used by matrices and vectors.
+Must be always enabled and set to an integer that is at least&nbsp;1.
+By default set to 16.
+If you mainly use lots of very small vectors (eg. &le; 4 elements), change the number to the size of your vectors.
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_DEFAULT_OSTREAM
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+The default stream used for printing <a href="#logging">error messages</a> and by <a href="#print">.print()</a>.
+Must be always enabled.
+By default this is set to <i>std::cout</i>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_DONT_USE_LAPACK
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Disable use of LAPACK. Overrides <i>ARMA_USE_LAPACK</i>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+ARMA_DONT_USE_BLAS
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+Disable use of BLAS. Overrides <i>ARMA_USE_BLAS</i>
+    </td>
+  </tr>
+  <tr>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+    <td style="vertical-align: top;">
+      &nbsp;
+    </td>
+  </tr>
+</tbody>
+</table>
+</li>
+
+<br>
+<li>
+See also:
+<ul>
+<li><a href="#logging">logging of warnings and errors</a></li>
+<li><a href="#element_access">element access</a></li>
+<li><a href="#element_initialisation">element initialisation</a></li>
+<li><a href="#uword">uword/sword</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<br>
+
+
+
+<!--
+<a name="catching_exceptions"></a>
+<hr class="greyline">
+<br>
+<b>how to catch std::runtime_error exceptions</b>
+<br>
+<br>
+<ul>
+<li>
+If a function such as <a href="#inv">inv()</a> fails to find a solution,
+an error message is printed and a <i>std::runtime_error</i> exception is thrown.
+If the exception is not caught, the program typically terminates.
+Below is an example of how to catch exceptions:
+<ul>
+<pre>
+#include &lt;iostream&gt;
+#include &lt;armadillo&gt;
+
+using namespace std;
+using namespace arma;
+
+int main(int argc, char** argv)
+  {
+  // create a non-invertible matrix
+  mat A = zeros&lt;mat&gt;(5,5);
+  
+  mat B;
+  
+  try
+    {
+    B = inv(A);
+    }
+  catch (std::runtime_error&amp; x)
+    {
+    cout &lt;&lt; "caught an exception" &lt;&lt; endl;
+    }
+  
+  return 0;
+  }
+</pre>
+</ul>
+<li>
+See also:
+<ul>
+<li><a href="#logging">logging of warnings and errors</a></li>
+<li><a href="http://cplusplus.com/doc/tutorial/exceptions/">tutorial on exceptions</a></li>
+<li><a href="http://cplusplus.com/reference/std/stdexcept/runtime_error/">std::runtime_error</a></li>
+</ul>
+</li>
+<br>
+</ul>
+<br>
+-->
+
+<a name="api_additions"></a>
+<a name="api_changes"></a>
+<hr class="greyline">
+<br>
+<b>API Additions, Changes and Deprecations</b>
+<br>
+<br>
+<li>API and Version Policy
+<ul>
+<li>
+Armadillo's version number is X.Y.Z, where X is a major version, Y is a minor version, and Z is the patch level (indicating bug fixes).
+</li>
+<br>
+<li>
+Within each major version (eg. 3.x), minor versions with an even number (eg. 3.2) are backwards compatible with earlier even minor versions (eg. 3.0).
+For example, code written for version 3.0 will work with version 3.2.
+However, as each minor version may have more features (ie. API extensions) than earlier versions,
+code specifically written for version 3.2 doesn't necessarily work with 3.0.
+</li>
+<br>
+<li>
+An odd minor version number (eg. 3.3) indicates an experimental version.
+Experimental versions are generally faster and have more functionality,
+but their APIs have not been finalised yet.
+</li>
+<br>
+<li>
+In general, we don't like changes to existing APIs and prefer not to break any user software.
+However, to allow evolution and help code maintenance, we reserve the right to change the APIs in future major versions of Armadillo,
+while remaining backwards compatible wherever possible
+(eg. 4.0 may have slightly different APIs than 3.x).
+Also, in a rare instance the user API may need to be altered if a bug fix absolutely requires it.
+</li>
+</ul>
+</li>
+
+<!--
+<br>
+<li>
+<a name="deprecated"></a>
+List of deprecated functionality; this functionality will be <b>removed</b> in version 4.0:
+<ul>
+<li>
+...
+</li>
+</ul>
+</li>
+-->
+
+<br>
+<br>
+<li>
+List of additions and changes for each version:
+<br>
+<br>
+<ul>
+<a name="added_in_3900"></a>
+<li>Added in 3.900:
+<ul>
+<li>automatic SSE2 vectorisation of elementary expressions (eg. matrix addition) when using GCC 4.7+ with -O3 optimisation</li>
+<li>faster <a href="#stats_fns">median()</a></li>
+<li>faster handling of compound expressions with transposes of <a href="#submat">submatrix</a> rows</li>
+<li>faster handling of compound expressions with transposes of complex vectors</li>
+<li>added support for <a href="#save_load_mat">saving &amp; loading</a> of <a href="#Cube">cubes</a> in HDF5 format</li>
+</ul>
+</li>
+<br>
+<a name="added_in_3820"></a>
+<li>Added in 3.820:
+<ul>
+<li>faster <a href="#as_scalar">as_scalar()</a> for compound expressions</li>
+<li>faster transpose of small vectors</li>
+<li>faster matrix-vector product for small vectors</li>
+<li>faster multiplication of small <a href="#adv_constructors_mat_fixed">fixed size matrices</a></li>
+</ul>
+</li>
+<br>
+<a name="added_in_3810"></a>
+<li>Added in 3.810:
+<ul>
+<li>fast Fourier transform: <a href="#fft">fft()</a></li>
+<li>handling of <a href="#imbue">.imbue()</a> and <a href="#transform">.transform()</a> by submatrices and subcubes</li>
+<li><a href="#batch_constructors_sp_mat">batch insertion constructors</a> for sparse matrices
+</ul>
+</li>
+<br>
+<a name="added_in_3800"></a>
+<li>Added in 3.800:
+<ul>
+<li><a href="#imbue">.imbue()</a> for filling a matrix/cube with values provided by a functor or lambda expression</li>
+<li><a href="#swap">.swap()</a> for swapping contents with another matrix</li>
+<li><a href="#transform">.transform()</a> for transforming a matrix/cube using a functor or lambda expression</li>
+<li><a href="#misc_fns">round()</a> for rounding matrix elements towards nearest integer</li>
+<li>faster <a href="#find">find()</a></li>
+</ul>
+</li>
+<br>
+<li>Changed in 3.800:
+<ul>
+<li>Armadillo is now licensed using the <a href="http://www.mozilla.org/MPL/2.0/">Mozilla Public License 2.0</a>;
+<br>
+see also the associated <a href="http://www.mozilla.org/MPL/2.0/FAQ.html">frequently asked questions</a> about the license</li>
+</ul>
+<br>
+</li>
+<a name="added_in_36"></a>
+<li>Added in 3.6:
+<ul>
+<li>faster handling of compound expressions with submatrices and subcubes</li>
+<li>faster <a href="#trace">trace()</a></li>
+<li>support for loading matrices as text files with <i>NaN</i> and <i>Inf</i> elements</li>
+<li><a href="#sort_index">stable_sort_index()</a>, which preserves the relative order of elements with equivalent values</li>
+<li>handling of <a href="#SpMat">sparse matrices</a> by <a href="#stats_fns">mean()</a>, <a href="#stats_fns">var()</a>, <a href="#norm">norm()</a>, <a href="#abs">abs()</a>, <a href="#misc_fns">square()</a>, <a href="#misc_fns">sqrt()</a></li>
+<li>saving and loading of sparse matrices in <i>arma_binary</i> format</li>
+</ul>
+<br>
+</li>
+<a name="added_in_34"></a>
+<li>Added in 3.4:
+<ul>
+<li>economical QR decomposition: <a href="#qr_econ">qr_econ()</a></li>
+<li><a href="#each_colrow">.each_col() &amp; .each_row()</a> for vector operations repeated on each column or row of a matrix</li>
+<li>preliminary support for <a href="#SpMat">sparse matrices</a></li>
+<li>ability to <a href="#save_load_mat">save and load</a> matrices in HDF5 format</li>
+<li>faster <a href="#svd">singular value decomposition</a> via optional use of divide-and-conquer algorithm</li>
+<li>faster <a href="#randu_randn_member">.randn()</a></li>
+<li>faster <a href="#dot">dot() and cdot()</a> for complex numbers</li>
+</ul>
+<br>
+</li>
+<a name="added_in_32"></a>
+<li>Added in 3.2:
+<ul>
+<li><a href="#unique">unique()</a>, for finding unique elements of a matrix</li>
+<li><a href="#eval_member">.eval()</a>, for forcing the evaluation of delayed expressions</li>
+<li>faster <a href="#eig_sym">eigen decomposition</a> via optional use of divide-and-conquer algorithm</li>
+<li>faster <a href="#t_st_members">transpose</a> of vectors and compound expressions</li>
+<li>faster handling of <a href="#diag">diagonal views</a></li>
+<li>faster handling of tiny <a href="#adv_constructors_col_fixed">fixed size</a> vectors (&le; 4 elements)</li>
+</ul>
+<br>
+</li>
+<a name="added_in_30"></a>
+<li>Added in 3.0:
+<ul>
+<li>shorthand for inverse: <a href="#i_member">.i()</a></li>
+<li><a href="#constants">datum</a> class</li>
+<li><a href="#hist">hist()</a> and <a href="#histc">histc()</a></li>
+<li>non-contiguous <a href="#submat">submatrix views</a></li>
+<li>faster handling of <a href="#submat">submatrix views</a> with a single row or column</li>
+<li>faster element access in <a href="#adv_constructors_mat_fixed">fixed size matrices</a></li>
+<li>faster <a href="#repmat">repmat()</a></li>
+</ul>
+<br>
+</li>
+<li>Changed in 3.0:
+<ul>
+<li>expressions <i>X=<a href="#inv">inv</a>(A)*B</i> and <i>X=A<a href="#i_member">.i()</a>*B</i> are automatically converted to <i>X=<a href="#solve">solve</a>(A,B)</i>
+<li>better detection of vector expressions by <a href="#sum">sum()</a>, <a href="#cumsum">cumsum()</a>, <a href="#prod">prod()</a>, <a href="#min_and_max">min()</a>, <a href="#min_and_max">max()</a>, <a href="#stats_fns">mean()</a>, <a href="#stats_fns">median()</a>, <a href="#stats_fns">stddev()</a>, <a href="#stats_fns">var()</a>
+<li>faster generation of random numbers
+(eg. <a href="#randu_randn_standalone">randu()</a> and <a href="#randu_randn_standalone">randn()</a>),
+via an algorithm that produces slightly different numbers than in 2.x
+</li>
+<li>
+support for tying writeable auxiliary (external) memory to fixed size matrices has been removed;
+instead, you can use standard matrices with <a href="#adv_constructors_mat">writeable auxiliary memory</a>,
+or initialise fixed size matrices by <a href="#adv_constructors_mat">copying the memory</a>.
+Using auxiliary memory with standard matrices is unaffected.
+</li>
+<li>
+<i>.print_trans()</i> and <i>.raw_print_trans()</i> have been removed;
+instead, you can chain <i><a href="#t_st_members">.t()</a></i> and <i><a href="#print">.print()</a></i> to achieve a similar result: <i>X.t().print()</i>
+</li>
+</ul>
+<br>
+</li>
+<a name="added_in_24"></a>
+<li>Added in 2.4:
+<ul>
+<li>shorter forms of transposes: <a href="#t_st_members">.t()</a> and <a href="#t_st_members">.st()</a></li>
+<li><a href="#resize_member">.resize()</a> and <a href="#resize">resize()</a></li>
+<li>optional use of 64 bit indices (allowing matrices to have more than 4 billion elements),
+<br>enabled via ARMA_64BIT_WORD in <i>include/armadillo_bits/config.hpp</i></li>
+<li>experimental support for C++11 initialiser lists,
+<br>enabled via ARMA_USE_CXX11 in <i>include/armadillo_bits/config.hpp</i></li>
+</ul>
+<br>
+<li>Changed in 2.4:
+<ul>
+<li>refactored code to eliminate warnings when using the Clang C++ compiler</li>
+<li><a href="#Mat">umat</a>, <a href="#Col">uvec</a>, <a href="#min_and_max_member">.min()</a> and <a href="#min_and_max_member">.max()</a>
+have been changed to use the <a href="#uword"><i>uword</i></a> type instead of the <i>u32</i> type;
+by default the <i>uword</i> and <i>u32</i> types are equivalent (ie. unsigned integer type with a minimum width 32 bits);
+however, when the use of 64 bit indices is enabled via ARMA_64BIT_WORD in <i>include/armadillo_bits/config.hpp</i>,
+the <i>uword</i> type then has a minimum width of 64 bits
+</ul>
+</li>
+<br>
+<li>Added in 2.2:
+<ul>
+<li><a href="#svd_econ">svd_econ()</a></li>
+<li><a href="#toeplitz">circ_toeplitz()</a></li>
+<li><a href="#is_vec">.is_colvec()</a> and <a href="#is_vec">.is_rowvec()</a></li>
+</ul>
+<br>
+<li>Added in 2.0:
+<ul>
+<li><a href="#det">det()</a>, <a href="#inv">inv()</a> and <a href="#solve">solve()</a> can be forced to use more precise algorithms for tiny matrices (&le;&nbsp;4x4)</li>
+<li><a href="#syl">syl()</a>, for solving Sylvester's equation</li>
+<li><a href="#strans">strans()</a>, for transposing a complex matrix without taking the complex conjugate</li>
+<li><a href="#symmat">symmatu()</a> and <a href="#symmat">symmatl()</a></li>
+<li>submatrices of <a href="#submat">submatrices</a></li>
+<li>faster <a href="#inv">inverse</a> of symmetric positive definite matrices</li>
+<li>faster element access for <a href="#adv_constructors_mat_fixed">fixed size</a> matrices</li>
+<li>faster multiplication of tiny matrices (eg. 4x4)</li>
+<li>faster compound expressions containing <a href="#submat">submatrices</a></li>
+<li>handling of arbitrarily sized empty matrices (eg. 5x0)</li>
+<li>.count() member function in <a href="#running_stat">running_stat</a> and <a href="#running_stat_vec">running_stat_vec</a></li>
+<li><a href="#save_load_mat">loading &amp; saving</a> of matrices as CSV text files</li>
+</ul>
+<br>
+<li>Changed in 2.0:
+<ul>
+<li><a href="#trans">trans()</a> now takes the complex conjugate when transposing a complex matrix</li>
+<li>Forms of
+<a href="#chol">chol()</a>, <a href="#eig_sym">eig_sym()</a>, <a href="#eig_gen">eig_gen()</a>,
+<a href="#inv">inv()</a>, <a href="#lu">lu()</a>, <a href="#pinv">pinv()</a>, <a href="#princomp">princomp()</a>,
+<a href="#qr">qr()</a>, <a href="#solve">solve()</a>, <a href="#svd">svd()</a>, <a href="#syl">syl()</a>
+that do not return a bool indicating success now throw <i>std::runtime_error</i> exceptions when failures are detected</li>
+<li>princomp_cov() has been removed; <a href="#eig_sym">eig_sym()</a> in conjunction with <a href="#cov">cov()</a> can be used instead</li>
+<li><a href="#is_vec">.is_vec()</a> now outputs <i>true</i> for empty vectors (eg. 0x1)</li>
+<li>set_log_stream() &amp; get_log_stream() have been replaced by <a href="#logging">set_stream_err1()</a> &amp; <a href="#logging">get_stream_err1()</a></li>
+</ul>
+<br>
+<li>Added in 1.2:
+<ul>
+<li><a href="#min_and_max_member">.min() &amp; .max()</a> member functions of Mat and Cube</li>
+<li><a href="#misc_fns">floor()</a> and <a href="#misc_fns">ceil()</a></li>
+<li>representation of &ldquo;not a number&rdquo;: math::nan()</li>
+<li>representation of infinity: math::inf()</li>
+<li>standalone <a href="#is_finite_standalone">is_finite()</a></li>
+<li><a href="#in_range">.in_range()</a> can use <b>span()</b> arguments</li>
+<li><a href="#adv_constructors_mat">fixed size</a> matrices and vectors can use auxiliary (external) memory</li>
+<li><a href="#submat">submatrices</a> and <a href="#subfield">subfields</a> can be accessed via <i><b>X(</b>&nbsp;<b>span(</b>a,b<b>)</b>,&nbsp;<b>span(</b>c,d<b>)</b>&nbsp;<b>)</b></i></li>
+<li><a href="#subcube">subcubes</a> can be accessed via <i><b>X(</b>&nbsp;<b>span(</b>a,b<b>)</b>,&nbsp;<b>span(</b>c,d<b>)</b>,&nbsp;<b>span(</b>e,f<b>)</b>&nbsp;<b>)</b></i></li>
+<li>the two argument version of <i><b>span</b></i> can be replaced by
+<i><b>span::all</b></i> or <i><b>span()</b></i>, to indicate an entire range
+</li>
+<li>for cubes, the two argument version of <i><b>span</b></i> can be replaced by
+a single argument version, <i><b>span(</b>a<b>)</b></i>, to indicate a single column, row or slice
+</li>
+<li>arbitrary "flat" subcubes can be interpreted as matrices; for example:
+<ul>
+<pre>
+cube Q = randu&lt;cube&gt;(5,3,4);
+mat  A = Q(&nbsp;span(1),&nbsp;span(1,2),&nbsp;span::all&nbsp;);
+// A has a size of 2x4
+
+vec v = ones&lt;vec&gt;(4);
+Q(&nbsp;span(1),&nbsp;span(1),&nbsp;span::all&nbsp;)&nbsp;=&nbsp;v;
+</pre>
+</ul>
+</li>
+<li>interpretation of matrices as triangular through <a href="#trimat">trimatu() / trimatl()</a></li>
+<li>explicit handling of triangular matrices by <a href="#solve">solve()</a> and <a href="#inv">inv()</a></li>
+<li>extended syntax for <a href="#submat">submatrices</a>, including access to elements whose indices are specified in a vector</li>
+<li>ability to change the stream used for <a href="#logging">logging</a> of errors and warnings</li>
+<li>ability to <a href="#save_load_mat">save/load matrices</a> in raw binary format</li>
+<li>cumulative sum function: <a href="#cumsum">cumsum()</a></li>
+</ul>
+</li>
+<br>
+<li>
+Changed in 1.0 (compared to earlier 0.x development versions):
+<ul>
+<li>
+the 3 argument version of <a href="#lu">lu()</a>,
+eg. lu(L,U,X),
+provides L and U which should be the same as produced by Octave 3.2
+(this was not the case in versions prior to 0.9.90)
+</li>
+<br>
+<li>
+rand() has been replaced by <a href="#randu_randn_standalone">randu()</a>;
+this has been done to avoid confusion with <a href="http://cplusplus.com/reference/clibrary/cstdlib/rand/">std::rand()</a>,
+which generates random numbers in a different interval
+</li>
+<br>
+<li>
+In versions earlier than 0.9.0,
+some multiplication operations directly converted result matrices with a size of 1x1 into scalars.
+This is no longer the case.
+If you know the result of an expression will be a 1x1 matrix and wish to treat it as a pure scalar,
+use the <a href="#as_scalar">as_scalar()</a> wrapping function
+</li>
+<br>
+<li>
+Almost all functions have been placed in the delayed operations framework (for speed purposes).
+This may affect code which assumed that the output of some functions was a pure matrix.
+The solution is easy, as explained below.
+<br>
+<br>
+In general, Armadillo queues operations before executing them.
+As such, the direct output of an operation or function cannot be assumed to be a directly accessible matrix.
+The queued operations are executed when the output needs to be stored in a matrix,
+eg. <i>mat&nbsp;B&nbsp;=&nbsp;trans(A)</i> or <i>mat&nbsp;B(trans(A))</i>.
+If you need to force the execution of the delayed operations,
+place the operation or function inside the corresponding Mat constructor.
+For example, if your code assumed that the output of some functions was a pure matrix,
+eg. <i>chol(m).diag()</i>, change the code to <i>mat(chol(m)).diag()</i>.
+Similarly, if you need to pass the result of an operation such as <i>A+B</i> to one of your own functions,
+use <i>my_function(&nbsp;mat(A+B)&nbsp;)</i>.
+</li>
+</ul>
+</li>
+</ul>
+</li>
+<br>
+<br>
+<br>
+
+
+<!-- END CONTENT -->
+
+
+<hr>
+<br>
+<br>
+
+</td>
+</tr>
+</tbody>
+</table>
+</center>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/examples/Makefile	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,109 @@
+# NOTE:
+# This file is mainly useful when doing a manual installation of Armadillo.
+# It is overwritten by CMake when doing an automatic installation.
+#
+# You may need to edit this file to reflect the type and capabilities
+# of your system.  The defaults are for a Linux system and will need
+# to be changed for other systems (e.g. Mac OS X).
+
+
+CXX=g++
+#CXX=g++-4.2
+## Under MacOS you may have an old compiler as default (e.g. GCC 4.0).
+## However, GCC 4.2 or later is available and preferable due to better
+## handling of template code.
+
+#CXX=CC
+## When using the Sun Studio compiler
+
+
+ARMA_INCLUDE_FLAG = -I ../include
+## If you've installed Armadillo's headers manually, 
+## you may need to tell the compiler where they are.
+## For example, change ../include to /usr/local/include
+## and uncomment the above line.
+
+
+#BOOST_INCLUDE_FLAG = -I /usr/include
+## If you have Boost libraries, change /usr/include
+## to point to where they are installed and uncomment
+## the above line.
+
+
+#EXTRA_LIB_FLAGS = -llapack -lblas
+## The above line is an example of the extra libraries
+## that can be used by Armadillo. You will also need
+## to modify "include/armadillo_bits/config.hpp"
+## to indicate which extra libraries are present.
+## If you're using Mac OS, comment out the line and
+## instead use the line below.
+
+
+#EXTRA_LIB_FLAGS = -framework Accelerate
+## Uncomment the above line when using Mac OS
+## and modify "include/armadillo_bits/config.hpp"
+## to indicate that LAPACK and BLAS libraries
+## are present
+
+
+#EXTRA_LIB_FLAGS = -library=sunperf
+## When using the Sun Studio compiler
+
+
+LIB_FLAGS = $(EXTRA_LIB_FLAGS)
+## NOTE: on Ubuntu and Debian based systems you may need to add 
+## -lgfortran to LIB_FLAGS
+
+
+OPT = -O2
+## As the Armadillo library uses recursive templates,
+## compilation times depend on the level of optimisation:
+##
+## -O0: quick compilation, but the resulting program will be slow
+## -O1: good trade-off between compilation time and execution speed
+## -O2: produces programs which have almost all possible speedups,
+##      but compilation takes longer
+
+
+#OPT = -xO4 -xannotate=no
+## When using the Sun Studio compiler
+
+
+#EXTRA_OPT = -fwhole-program
+## Uncomment the above line if you're compiling 
+## all source files into one program in a single hit.
+
+
+#DEBUG = -DARMA_EXTRA_DEBUG
+## Uncomment the above line to enable low-level
+## debugging.  Lots of debugging information will
+## be printed when a compiled program is run.
+## Please enable this option when reporting bugs.
+
+
+#FINAL = -DARMA_NO_DEBUG
+## Uncomment the above line to disable Armadillo's checks.
+## DANGEROUS!  Not recommended unless your code has been
+## thoroughly tested.
+
+
+#
+#
+#
+
+CXXFLAGS = $(ARMA_INCLUDE_FLAG) $(BOOST_INCLUDE_FLAG) $(DEBUG) $(FINAL) $(OPT) $(EXTRA_OPT) 
+
+all: example1 example2
+
+example1: example1.cpp
+	$(CXX) $(CXXFLAGS)  -o $@  $<  $(LIB_FLAGS)
+
+example2: example2.cpp
+	$(CXX) $(CXXFLAGS)  -o $@  $<  $(LIB_FLAGS)
+
+
+.PHONY: clean
+
+clean:
+	rm -f example1 example2
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/examples/Makefile.cmake	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,86 @@
+# The generated "Makefile" from "Makefile.cmake" is only usable after
+# the Armadillo library has been configured and installed by CMake.
+
+CXX=g++
+#CXX=g++-4.2
+## Under MacOS you may have an old compiler as default (e.g. GCC 4.0).
+## However, GCC 4.2 or later is available and preferable due to better
+## handling of template code.
+
+#CXX=CC
+## When using the Sun Studio compiler
+
+
+# flags configured by CMake
+ifeq (${ARMA_OS},macos)
+  EXTRA_LIB_FLAGS = -framework Accelerate
+endif
+
+#EXTRA_LIB_FLAGS = -library=sunperf
+## When using the Sun Studio compiler
+
+
+ifeq (${ARMA_USE_BOOST},true)
+  BOOST_INCLUDE_FLAG = -I ${Boost_INCLUDE_DIR}
+endif
+
+
+
+LIB_FLAGS = -larmadillo $(EXTRA_LIB_FLAGS)
+## NOTE: on Ubuntu and Debian based systems you may need to add 
+## -lgfortran to LIB_FLAGS
+
+
+
+OPT = -O2
+## As the Armadillo library uses recursive templates,
+## compilation times depend on the level of optimisation:
+##
+## -O0: quick compilation, but the resulting program will be slow
+## -O1: good trade-off between compilation time and execution speed
+## -O2: produces programs which have almost all possible speedups,
+##      but compilation takes longer
+
+
+#OPT = -xO4 -xannotate=no
+## When using the Sun Studio compiler
+
+
+#EXTRA_OPT = -fwhole-program
+## Uncomment the above line if you're compiling 
+## all source files into one program in a single hit.
+
+
+#DEBUG = -DARMA_EXTRA_DEBUG
+## Uncomment the above line to enable low-level
+## debugging.  Lots of debugging information will
+## be printed when a compiled program is run.
+## Please enable this option when reporting bugs.
+
+
+#FINAL = -DARMA_NO_DEBUG
+## Uncomment the above line to disable Armadillo's checks.
+## DANGEROUS!  Not recommended unless your code has been
+## thoroughly tested.
+
+
+#
+#
+#
+
+CXXFLAGS = $(BOOST_INCLUDE_FLAG) $(DEBUG) $(FINAL) $(OPT) $(EXTRA_OPT)
+
+all: example1 example2
+
+example1: example1.cpp
+	$(CXX) $(CXXFLAGS)  -o $@  $<  $(LIB_FLAGS)
+
+example2: example2.cpp
+	$(CXX) $(CXXFLAGS)  -o $@  $<  $(LIB_FLAGS)
+
+
+.PHONY: clean
+
+clean:
+	rm -f example1 example2
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/examples/example1.cpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,183 @@
+#include <iostream>
+
+#include "armadillo"
+
+using namespace arma;
+using namespace std;
+
+
+int main(int argc, char** argv)
+  {
+  cout << "Armadillo version: " << arma_version::as_string() << endl;
+  
+  // directly specify the matrix size (elements are uninitialised)
+  mat A(2,3);
+  
+  // .n_rows = number of rows    (read only)
+  // .n_cols = number of columns (read only)
+  cout << "A.n_rows = " << A.n_rows << endl;
+  cout << "A.n_cols = " << A.n_cols << endl;
+  
+  // directly access an element (indexing starts at 0)
+  A(1,2) = 456.0;
+  
+  A.print("A:");
+  
+  // scalars are treated as a 1x1 matrix,
+  // hence the code below will set A to have a size of 1x1
+  A = 5.0;
+  A.print("A:");
+  
+  // if you want a matrix with all elements set to a particular value
+  // the .fill() member function can be used
+  A.set_size(3,3);
+  A.fill(5.0);
+  A.print("A:");
+  
+  
+  mat B;
+  
+  // endr indicates "end of row"
+  B << 0.555950 << 0.274690 << 0.540605 << 0.798938 << endr
+    << 0.108929 << 0.830123 << 0.891726 << 0.895283 << endr
+    << 0.948014 << 0.973234 << 0.216504 << 0.883152 << endr
+    << 0.023787 << 0.675382 << 0.231751 << 0.450332 << endr;
+  
+  // print to the cout stream
+  // with an optional string before the contents of the matrix
+  B.print("B:");
+  
+  // the << operator can also be used to print the matrix
+  // to an arbitrary stream (cout in this case) 
+  cout << "B:" << endl << B << endl;
+  
+  // save to disk
+  B.save("B.txt", raw_ascii);
+  
+  // load from disk
+  mat C;
+  C.load("B.txt");
+  
+  C += 2.0 * B;
+  C.print("C:");
+  
+  
+  // submatrix types:
+  //
+  // .submat(first_row, first_column, last_row, last_column)
+  // .row(row_number)
+  // .col(column_number)
+  // .cols(first_column, last_column)
+  // .rows(first_row, last_row)
+  
+  cout << "C.submat(0,0,3,1) =" << endl;
+  cout << C.submat(0,0,3,1) << endl;
+  
+  // generate the identity matrix
+  mat D = eye<mat>(4,4);
+  
+  D.submat(0,0,3,1) = C.cols(1,2);
+  D.print("D:");
+  
+  // transpose
+  cout << "trans(B) =" << endl;
+  cout << trans(B) << endl;
+  
+  // maximum from each column (traverse along rows)
+  cout << "max(B) =" << endl;
+  cout << max(B) << endl;
+  
+  // maximum from each row (traverse along columns)
+  cout << "max(B,1) =" << endl;
+  cout << max(B,1) << endl;
+  
+  // maximum value in B
+  cout << "max(max(B)) = " << max(max(B)) << endl;
+  
+  // sum of each column (traverse along rows)
+  cout << "sum(B) =" << endl;
+  cout << sum(B) << endl;
+  
+  // sum of each row (traverse along columns)
+  cout << "sum(B,1) =" << endl;
+  cout << sum(B,1) << endl;
+  
+  // sum of all elements
+  cout << "sum(sum(B)) = " << sum(sum(B)) << endl;
+  cout << "accu(B)     = " << accu(B) << endl;
+  
+  // trace = sum along diagonal
+  cout << "trace(B)    = " << trace(B) << endl;
+  
+  // random matrix -- values are uniformly distributed in the [0,1] interval
+  mat E = randu<mat>(4,4);
+  E.print("E:");
+  
+  cout << endl;
+  
+  // row vectors are treated like a matrix with one row
+  rowvec r;
+  r << 0.59499 << 0.88807 << 0.88532 << 0.19968;
+  r.print("r:");
+  
+  // column vectors are treated like a matrix with one column
+  colvec q;
+  q << 0.81114 << 0.06256 << 0.95989 << 0.73628;
+  q.print("q:");
+  
+  // dot or inner product
+  cout << "as_scalar(r*q) = " << as_scalar(r*q) << endl;
+  
+  
+  // outer product
+  cout << "q*r =" << endl;
+  cout << q*r << endl;
+  
+  // multiply-and-accumulate operation
+  // (no temporary matrices are created)
+  cout << "accu(B % C) = " << accu(B % C) << endl;
+  
+  // sum of three matrices (no temporary matrices are created)
+  mat F = B + C + D;
+  F.print("F:");
+  
+  // imat specifies an integer matrix
+  imat AA;
+  imat BB;
+  
+  AA << 1 << 2 << 3 << endr << 4 << 5 << 6 << endr << 7 << 8 << 9;
+  BB << 3 << 2 << 1 << endr << 6 << 5 << 4 << endr << 9 << 8 << 7;
+  
+  // comparison of matrices (element-wise)
+  // output of a relational operator is a umat
+  umat ZZ = (AA >= BB);
+  ZZ.print("ZZ =");
+  
+  
+  // 2D field of arbitrary length row vectors
+  // (fields can also store abitrary objects, e.g. instances of std::string)
+  field<rowvec> xyz(3,2);
+  
+  xyz(0,0) = randu(1,2);
+  xyz(1,0) = randu(1,3);
+  xyz(2,0) = randu(1,4);
+  xyz(0,1) = randu(1,5);
+  xyz(1,1) = randu(1,6);
+  xyz(2,1) = randu(1,7);
+  
+  cout << "xyz:" << endl;
+  cout << xyz << endl;
+  
+  
+  // cubes ("3D matrices")
+  cube Q( B.n_rows, B.n_cols, 2 );
+  
+  Q.slice(0) = B;
+  Q.slice(1) = 2.0 * B;
+  
+  Q.print("Q:");
+  
+  
+  return 0;
+  }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/examples/example1_win32/example1_win32.sln	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example1_win32", "example1_win32.vcproj", "{3D5424A0-4AFB-4477-9D2B-792D5FE32734}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Debug|Win32.ActiveCfg = Debug|Win32
+		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Debug|Win32.Build.0 = Debug|Win32
+		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Release|Win32.ActiveCfg = Release|Win32
+		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/examples/example1_win32/example1_win32.vcproj	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="example1_win32"
+	ProjectGUID="{3D5424A0-4AFB-4477-9D2B-792D5FE32734}"
+	RootNamespace="example1_win32"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\include"
+				PreprocessorDefinitions="ARMA_USE_LAPACK;ARMA_USE_BLAS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="lapack_win32_MT.lib blas_win32_MT.lib"
+				OutputFile="$(OutDir)\example1.exe"
+				AdditionalLibraryDirectories="..\lib_win32"
+				GenerateDebugInformation="true"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				Description="Copy .DLL to output directory"
+				CommandLine="copy ..\lib_win32\*.dll $(ConfigurationName)"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories="..\..\include"
+				PreprocessorDefinitions="ARMA_USE_LAPACK;ARMA_USE_BLAS"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="lapack_win32_MT.lib blas_win32_MT.lib"
+				OutputFile="$(OutDir)\example1.exe"
+				AdditionalLibraryDirectories="..\lib_win32"
+				GenerateDebugInformation="true"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				Description="Copy .DLL to output directory"
+				CommandLine="copy ..\lib_win32\*.dll $(ConfigurationName)"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\example1.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/examples/example2.cpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,70 @@
+#include <iostream>
+
+#include "armadillo"
+
+using namespace arma;
+using namespace std;
+
+
+int main(int argc, char** argv)
+  {
+  cout << "Armadillo version: " << arma_version::as_string() << endl;
+  
+  mat A;
+  
+  A << 0.165300 << 0.454037 << 0.995795 << 0.124098 << 0.047084 << endr
+    << 0.688782 << 0.036549 << 0.552848 << 0.937664 << 0.866401 << endr
+    << 0.348740 << 0.479388 << 0.506228 << 0.145673 << 0.491547 << endr
+    << 0.148678 << 0.682258 << 0.571154 << 0.874724 << 0.444632 << endr
+    << 0.245726 << 0.595218 << 0.409327 << 0.367827 << 0.385736 << endr;
+  
+  A.print("A =");
+  
+  // determinant
+  cout << "det(A) = " << det(A) << endl;
+  
+  // inverse
+  cout << "inv(A) = " << endl << inv(A) << endl;
+  
+  
+  //
+  
+  double k = 1.23;
+  
+  mat    B = randu<mat>(5,5);
+  mat    C = randu<mat>(5,5);
+  
+  rowvec r = randu<rowvec>(5);
+  colvec q = randu<colvec>(5);
+  
+  
+  // examples of some expressions
+  // for which optimised implementations exist
+  
+  // optimised implementation of a trinary expression
+  // that results in a scalar
+  cout << "as_scalar( r*inv(diagmat(B))*q ) = ";
+  cout << as_scalar( r*inv(diagmat(B))*q ) << endl;
+  
+  // example of an expression which is optimised 
+  // as a call to the dgemm() function in BLAS:
+  cout << "k*trans(B)*C = " << endl << k*trans(B)*C;
+  
+  
+  // If you want to see a trace of how Armadillo
+  // evaluates expressions, compile with the
+  // ARMA_EXTRA_DEBUG macro defined.
+  // This was designed to work with the GCC compiler,
+  // but it may also work with other compilers
+  // if you have the Boost libraries installed
+  // and told Armadillo to use them.
+  // 
+  // Example for GCC:
+  // g++ example2.cpp -o example2 -larmadillo -DARMA_EXTRA_DEBUG
+  // 
+  // Running example2 will now produce a truckload of messages,
+  // so you may want to redirect the output to a log file.
+  
+  return 0;
+  }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/examples/example2_win32/example2_win32.sln	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example2_win32", "example2_win32.vcproj", "{3D5424A0-4AFB-4477-9D2B-792D5FE32734}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Debug|Win32.ActiveCfg = Debug|Win32
+		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Debug|Win32.Build.0 = Debug|Win32
+		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Release|Win32.ActiveCfg = Release|Win32
+		{3D5424A0-4AFB-4477-9D2B-792D5FE32734}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/examples/example2_win32/example2_win32.vcproj	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="example2_win32"
+	ProjectGUID="{3D5424A0-4AFB-4477-9D2B-792D5FE32734}"
+	RootNamespace="example1_win32"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\include"
+				PreprocessorDefinitions="ARMA_USE_LAPACK;ARMA_USE_BLAS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="lapack_win32_MT.lib blas_win32_MT.lib"
+				OutputFile="$(OutDir)\example2.exe"
+				AdditionalLibraryDirectories="..\lib_win32"
+				GenerateDebugInformation="true"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				Description="Copy .DLL to output directory"
+				CommandLine="copy ..\lib_win32\*.dll $(ConfigurationName)"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories="..\..\include"
+				PreprocessorDefinitions="ARMA_USE_LAPACK;ARMA_USE_BLAS"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="lapack_win32_MT.lib blas_win32_MT.lib"
+				OutputFile="$(OutDir)\example2.exe"
+				AdditionalLibraryDirectories="..\lib_win32"
+				GenerateDebugInformation="true"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				Description="Copy .DLL to output directory"
+				CommandLine="copy ..\lib_win32\*.dll $(ConfigurationName)"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\example2.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/examples/example_lsq.cpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,64 @@
+// Tutorial for linear least square fitting
+// Author: Pierre Moulon
+// Date: 8 December 2009
+// Objective:
+// Fit a 2D line with to a set of points
+// Specifically, find a and b in the model y = ax + b
+// 
+// Direct application of the example in:
+// http://en.wikipedia.org/wiki/Linear_least_squares#Motivational_example
+
+
+#include <iostream>
+
+#include "armadillo"
+
+using namespace arma;
+using namespace std;
+
+
+
+int main(int argc, char** argv)
+  {
+  // points to which we will fit the line
+  mat data = "1 6; 2 5; 3 7; 4 10";
+
+  cout << "Points used for the estimation:" << endl;
+  cout << data << endl;
+
+  // Build matrices to solve Ax = b problem:
+  vec b(data.n_rows);
+  mat C(data.n_rows, 2);
+
+  for(u32 i=0; i<data.n_rows; ++i)
+    {
+    b(i)   = data(i,1);
+    
+    C(i,0) = 1;
+    C(i,1) = data(i,0);
+    }
+  
+  cout << "b:" << endl;
+  cout << b << endl;
+  
+  cout << "Constraint matrix:" << endl;
+  cout << C << endl;
+  
+  // Compute least-squares solution:
+  vec solution = solve(C,b);
+  
+  // solution should be "3.5; 1.4"
+  cout << "solution:" << endl;
+  cout << solution << endl;
+  
+
+  cout << "Reprojection error:" << endl;
+  
+  for(u32 i=0; i<data.n_rows; ++i)
+    {
+    cout << "  residual: " << ( data(i,1) - (solution(0) + solution(1) * data(i,0)) ) << endl;
+    }
+    
+  return 0;
+  }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/examples/lib_win32/README.txt	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,10 @@
+The lib and dll files in this folder are for 32 bit Windows XP.
+They are compiled versions of the BLAS and LAPACK libraries,
+which are distributed under a BSD license.
+
+The compiled versions were downloaded from:
+http://www.fi.muni.cz/~xsvobod2/misc/lapack/
+
+Sources for BLAS and LAPACK can be found at:
+http://www.netlib.org/blas/
+http://www.netlib.org/lapack/
Binary file armadillo-3.900.4/examples/lib_win32/blas_win32_MT.dll has changed
Binary file armadillo-3.900.4/examples/lib_win32/blas_win32_MT.lib has changed
Binary file armadillo-3.900.4/examples/lib_win32/lapack_win32_MT.dll has changed
Binary file armadillo-3.900.4/examples/lib_win32/lapack_win32_MT.lib has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,542 @@
+// Copyright (C) 2008-2013 Conrad Sanderson
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+#ifndef ARMA_INCLUDES
+#define ARMA_INCLUDES
+
+
+#include <cstdlib>
+#include <cstring>
+#include <climits>
+#include <cmath>
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <stdexcept>
+#include <limits>
+#include <algorithm>
+#include <complex>
+#include <vector>
+
+
+#include "armadillo_bits/config.hpp"
+#include "armadillo_bits/compiler_setup.hpp"
+#include "armadillo_bits/undefine_conflicts.hpp"
+
+
+#if defined(ARMA_USE_CXX11)
+  #include <initializer_list>
+  #include <cstdint>
+#endif
+
+
+#if !defined(ARMA_HAVE_GETTIMEOFDAY) && !defined(ARMA_USE_BOOST_DATE)
+  #include <ctime>
+#endif
+
+#if defined(ARMA_HAVE_GETTIMEOFDAY)
+  #include <sys/time.h>
+  #undef ARMA_USE_BOOST_DATE
+#endif
+
+#if defined(ARMA_USE_BOOST_DATE)
+  #include <boost/date_time/posix_time/posix_time.hpp>
+#endif
+
+
+#if defined(ARMA_USE_TBB_ALLOC)
+  #include <tbb/scalable_allocator.h>
+#endif
+
+#if defined(ARMA_USE_MKL_ALLOC)
+  #include <mkl_service.h>
+#endif
+
+
+#if defined(ARMA_HAVE_STD_TR1)
+  // TODO: add handling of this functionality when use of C++11 is enabled
+  #include <tr1/cmath>
+  #include <tr1/complex>
+#elif defined(ARMA_USE_BOOST)
+  #include <boost/math/complex.hpp>
+  #include <boost/math/special_functions/acosh.hpp>
+  #include <boost/math/special_functions/asinh.hpp>
+  #include <boost/math/special_functions/atanh.hpp>
+#endif
+
+
+#if defined(ARMA_USE_BOOST)
+  #if defined(ARMA_EXTRA_DEBUG)
+    #include <boost/format.hpp>
+    #include <boost/current_function.hpp>
+    #define ARMA_USE_BOOST_FORMAT
+  #endif
+#endif
+
+
+#include "armadillo_bits/include_atlas.hpp"
+
+
+#if defined(ARMA_USE_HDF5)
+  #include <hdf5.h>
+#endif
+
+
+
+//! \namespace arma namespace for Armadillo classes and functions
+namespace arma
+  {
+  
+  // preliminaries
+  
+  #include "armadillo_bits/forward_bones.hpp"
+  #include "armadillo_bits/arma_static_check.hpp"
+  #include "armadillo_bits/typedef.hpp"
+  #include "armadillo_bits/typedef_blas_int.hpp"
+  #include "armadillo_bits/format_wrap.hpp"
+  #include "armadillo_bits/arma_version.hpp"
+  #include "armadillo_bits/arma_config.hpp"
+  #include "armadillo_bits/traits.hpp"
+  #include "armadillo_bits/promote_type.hpp"
+  #include "armadillo_bits/upgrade_val.hpp"
+  #include "armadillo_bits/restrictors.hpp"
+  #include "armadillo_bits/access.hpp"
+  #include "armadillo_bits/memory.hpp"
+  #include "armadillo_bits/span.hpp"
+  #include "armadillo_bits/constants.hpp"
+  #include "armadillo_bits/constants_compat.hpp"
+  
+  
+  //
+  // class prototypes
+  
+  #include "armadillo_bits/Base_bones.hpp"
+  #include "armadillo_bits/BaseCube_bones.hpp"
+  #include "armadillo_bits/SpBase_bones.hpp"
+  
+  #include "armadillo_bits/blas_bones.hpp"
+  #include "armadillo_bits/lapack_bones.hpp"
+  #include "armadillo_bits/atlas_bones.hpp"
+  
+  #include "armadillo_bits/blas_wrapper.hpp"
+  #include "armadillo_bits/lapack_wrapper.hpp"
+  #include "armadillo_bits/atlas_wrapper.hpp"
+  
+  #include "armadillo_bits/cond_rel_bones.hpp"
+  #include "armadillo_bits/arrayops_bones.hpp"
+  #include "armadillo_bits/podarray_bones.hpp"
+  #include "armadillo_bits/auxlib_bones.hpp"
+  
+  #include "armadillo_bits/injector_bones.hpp"
+  
+  #include "armadillo_bits/Mat_bones.hpp"
+  #include "armadillo_bits/Col_bones.hpp"
+  #include "armadillo_bits/Row_bones.hpp"
+  #include "armadillo_bits/Cube_bones.hpp"
+  #include "armadillo_bits/xvec_htrans_bones.hpp"
+  
+  #include "armadillo_bits/SpValProxy_bones.hpp"
+  #include "armadillo_bits/SpMat_bones.hpp"
+  #include "armadillo_bits/SpCol_bones.hpp"
+  #include "armadillo_bits/SpRow_bones.hpp"
+  #include "armadillo_bits/SpSubview_bones.hpp"
+  
+  #include "armadillo_bits/typedef_fixed.hpp"
+  
+  #include "armadillo_bits/field_bones.hpp"
+  #include "armadillo_bits/subview_bones.hpp"
+  #include "armadillo_bits/subview_elem1_bones.hpp"
+  #include "armadillo_bits/subview_elem2_bones.hpp"
+  #include "armadillo_bits/subview_field_bones.hpp"
+  #include "armadillo_bits/subview_cube_bones.hpp"
+  #include "armadillo_bits/diagview_bones.hpp"
+  #include "armadillo_bits/subview_each_bones.hpp"
+  
+  
+  #include "armadillo_bits/diskio_bones.hpp"
+  #include "armadillo_bits/wall_clock_bones.hpp"
+  #include "armadillo_bits/running_stat_bones.hpp"
+  #include "armadillo_bits/running_stat_vec_bones.hpp"
+  
+  #include "armadillo_bits/Op_bones.hpp"
+  #include "armadillo_bits/OpCube_bones.hpp"
+  #include "armadillo_bits/SpOp_bones.hpp"
+  
+  #include "armadillo_bits/eOp_bones.hpp"
+  #include "armadillo_bits/eOpCube_bones.hpp"
+  
+  #include "armadillo_bits/mtOp_bones.hpp"
+  #include "armadillo_bits/mtOpCube_bones.hpp"
+  #include "armadillo_bits/mtSpOp_bones.hpp"
+  
+  #include "armadillo_bits/Glue_bones.hpp"
+  #include "armadillo_bits/eGlue_bones.hpp"
+  #include "armadillo_bits/mtGlue_bones.hpp"
+  #include "armadillo_bits/SpGlue_bones.hpp"
+  
+  #include "armadillo_bits/GlueCube_bones.hpp"
+  #include "armadillo_bits/eGlueCube_bones.hpp"
+  #include "armadillo_bits/mtGlueCube_bones.hpp"
+  
+  #include "armadillo_bits/eop_core_bones.hpp"
+  #include "armadillo_bits/eglue_core_bones.hpp"
+  
+  #include "armadillo_bits/Gen_bones.hpp"
+  #include "armadillo_bits/GenCube_bones.hpp"
+  
+  #include "armadillo_bits/op_diagmat_bones.hpp"
+  #include "armadillo_bits/op_diagvec_bones.hpp"
+  #include "armadillo_bits/op_dot_bones.hpp"
+  #include "armadillo_bits/op_inv_bones.hpp"
+  #include "armadillo_bits/op_htrans_bones.hpp"
+  #include "armadillo_bits/op_max_bones.hpp"
+  #include "armadillo_bits/op_min_bones.hpp"
+  #include "armadillo_bits/op_mean_bones.hpp"
+  #include "armadillo_bits/op_median_bones.hpp"
+  #include "armadillo_bits/op_sort_bones.hpp"
+  #include "armadillo_bits/op_sum_bones.hpp"
+  #include "armadillo_bits/op_stddev_bones.hpp"
+  #include "armadillo_bits/op_strans_bones.hpp"
+  #include "armadillo_bits/op_var_bones.hpp"
+  #include "armadillo_bits/op_repmat_bones.hpp"
+  #include "armadillo_bits/op_reshape_bones.hpp"
+  #include "armadillo_bits/op_resize_bones.hpp"
+  #include "armadillo_bits/op_cov_bones.hpp"
+  #include "armadillo_bits/op_cor_bones.hpp"
+  #include "armadillo_bits/op_shuffle_bones.hpp"
+  #include "armadillo_bits/op_prod_bones.hpp"
+  #include "armadillo_bits/op_pinv_bones.hpp"
+  #include "armadillo_bits/op_dotext_bones.hpp"
+  #include "armadillo_bits/op_flip_bones.hpp"
+  #include "armadillo_bits/op_princomp_bones.hpp"
+  #include "armadillo_bits/op_misc_bones.hpp"
+  #include "armadillo_bits/op_relational_bones.hpp"
+  #include "armadillo_bits/op_find_bones.hpp"
+  #include "armadillo_bits/op_chol_bones.hpp"
+  #include "armadillo_bits/op_cx_scalar_bones.hpp"
+  #include "armadillo_bits/op_trimat_bones.hpp"
+  #include "armadillo_bits/op_cumsum_bones.hpp"
+  #include "armadillo_bits/op_symmat_bones.hpp"
+  #include "armadillo_bits/op_hist_bones.hpp"
+  #include "armadillo_bits/op_unique_bones.hpp"
+  #include "armadillo_bits/op_toeplitz_bones.hpp"
+  #include "armadillo_bits/op_fft_bones.hpp"
+  
+  #include "armadillo_bits/glue_times_bones.hpp"
+  #include "armadillo_bits/glue_mixed_bones.hpp"
+  #include "armadillo_bits/glue_cov_bones.hpp"
+  #include "armadillo_bits/glue_cor_bones.hpp"
+  #include "armadillo_bits/glue_kron_bones.hpp"
+  #include "armadillo_bits/glue_cross_bones.hpp"
+  #include "armadillo_bits/glue_join_bones.hpp"
+  #include "armadillo_bits/glue_relational_bones.hpp"
+  #include "armadillo_bits/glue_solve_bones.hpp"
+  #include "armadillo_bits/glue_conv_bones.hpp"
+  #include "armadillo_bits/glue_toeplitz_bones.hpp"
+  #include "armadillo_bits/glue_hist_bones.hpp"
+  #include "armadillo_bits/glue_histc_bones.hpp"
+  
+  #include "armadillo_bits/spop_max_bones.hpp"
+  #include "armadillo_bits/spop_min_bones.hpp"
+  #include "armadillo_bits/spop_sum_bones.hpp"
+  #include "armadillo_bits/spop_strans_bones.hpp"
+  #include "armadillo_bits/spop_htrans_bones.hpp"
+  #include "armadillo_bits/spop_misc_bones.hpp"
+  #include "armadillo_bits/spop_mean_bones.hpp"
+  #include "armadillo_bits/spop_var_bones.hpp"
+  
+  #include "armadillo_bits/spglue_plus_bones.hpp"
+  #include "armadillo_bits/spglue_minus_bones.hpp"
+  #include "armadillo_bits/spglue_times_bones.hpp"
+  
+  //
+  // debugging functions
+  
+  #include "armadillo_bits/debug.hpp"
+  
+  //
+  //
+  
+  #include "armadillo_bits/cmath_wrap.hpp"
+  
+  //
+  // classes that underlay metaprogramming 
+  
+  #include "armadillo_bits/unwrap.hpp"
+  #include "armadillo_bits/unwrap_cube.hpp"
+  #include "armadillo_bits/unwrap_spmat.hpp"
+  
+  #include "armadillo_bits/Proxy.hpp"
+  #include "armadillo_bits/ProxyCube.hpp"
+  #include "armadillo_bits/SpProxy.hpp"
+  
+  #include "armadillo_bits/diagmat_proxy.hpp"
+
+  #include "armadillo_bits/strip.hpp"
+  
+  #include "armadillo_bits/Op_meat.hpp"
+  #include "armadillo_bits/OpCube_meat.hpp"
+  #include "armadillo_bits/SpOp_meat.hpp"
+  
+  #include "armadillo_bits/mtOp_meat.hpp"
+  #include "armadillo_bits/mtOpCube_meat.hpp"
+  #include "armadillo_bits/mtSpOp_meat.hpp"
+  
+  #include "armadillo_bits/Glue_meat.hpp"
+  #include "armadillo_bits/GlueCube_meat.hpp"
+  #include "armadillo_bits/SpGlue_meat.hpp"
+  
+  #include "armadillo_bits/eop_aux.hpp"
+  
+  #include "armadillo_bits/eOp_meat.hpp"
+  #include "armadillo_bits/eOpCube_meat.hpp"
+  
+  #include "armadillo_bits/eGlue_meat.hpp"
+  #include "armadillo_bits/eGlueCube_meat.hpp"
+
+  #include "armadillo_bits/mtGlue_meat.hpp"
+  #include "armadillo_bits/mtGlueCube_meat.hpp"
+  
+  #include "armadillo_bits/Base_meat.hpp"
+  #include "armadillo_bits/BaseCube_meat.hpp"
+  #include "armadillo_bits/SpBase_meat.hpp"
+  
+  #include "armadillo_bits/Gen_meat.hpp"
+  #include "armadillo_bits/GenCube_meat.hpp"
+  
+  
+  //
+  // ostream
+  
+  #include "armadillo_bits/arma_ostream_bones.hpp"
+  #include "armadillo_bits/arma_ostream_meat.hpp"
+  
+  //
+  // n_unique, which is used by some sparse operators
+
+  #include "armadillo_bits/fn_n_unique.hpp"
+  
+  //
+  // operators
+  
+  #include "armadillo_bits/operator_plus.hpp"
+  #include "armadillo_bits/operator_minus.hpp"
+  #include "armadillo_bits/operator_times.hpp"
+  #include "armadillo_bits/operator_schur.hpp"
+  #include "armadillo_bits/operator_div.hpp"
+  #include "armadillo_bits/operator_relational.hpp"
+  
+  #include "armadillo_bits/operator_cube_plus.hpp"
+  #include "armadillo_bits/operator_cube_minus.hpp"
+  #include "armadillo_bits/operator_cube_times.hpp"
+  #include "armadillo_bits/operator_cube_schur.hpp"
+  #include "armadillo_bits/operator_cube_div.hpp"
+  #include "armadillo_bits/operator_cube_relational.hpp"
+  
+  #include "armadillo_bits/operator_ostream.hpp"
+  
+  
+  //
+  // user accessible functions
+  
+  // the order of the fn_*.hpp include files matters,
+  // as some files require functionality given in preceding files
+  
+  #include "armadillo_bits/fn_conv_to.hpp"
+  #include "armadillo_bits/fn_min.hpp"
+  #include "armadillo_bits/fn_max.hpp"
+  #include "armadillo_bits/fn_accu.hpp"
+  #include "armadillo_bits/fn_sum.hpp"
+  #include "armadillo_bits/fn_diagmat.hpp"
+  #include "armadillo_bits/fn_diagvec.hpp"
+  #include "armadillo_bits/fn_inv.hpp"
+  #include "armadillo_bits/fn_trace.hpp"
+  #include "armadillo_bits/fn_trans.hpp"
+  #include "armadillo_bits/fn_det.hpp"
+  #include "armadillo_bits/fn_log_det.hpp"
+  #include "armadillo_bits/fn_eig.hpp"
+  #include "armadillo_bits/fn_lu.hpp"
+  #include "armadillo_bits/fn_zeros.hpp"
+  #include "armadillo_bits/fn_ones.hpp"
+  #include "armadillo_bits/fn_eye.hpp"
+  #include "armadillo_bits/fn_misc.hpp"
+  #include "armadillo_bits/fn_elem.hpp"
+  #include "armadillo_bits/fn_norm.hpp"
+  #include "armadillo_bits/fn_dot.hpp"
+  #include "armadillo_bits/fn_randu.hpp"
+  #include "armadillo_bits/fn_randn.hpp"
+  #include "armadillo_bits/fn_trig.hpp"
+  #include "armadillo_bits/fn_mean.hpp"
+  #include "armadillo_bits/fn_median.hpp"
+  #include "armadillo_bits/fn_stddev.hpp"
+  #include "armadillo_bits/fn_var.hpp"
+  #include "armadillo_bits/fn_sort.hpp"
+  #include "armadillo_bits/fn_sort_index.hpp"
+  #include "armadillo_bits/fn_strans.hpp"
+  #include "armadillo_bits/fn_chol.hpp"
+  #include "armadillo_bits/fn_qr.hpp"
+  #include "armadillo_bits/fn_svd.hpp"
+  #include "armadillo_bits/fn_solve.hpp"
+  #include "armadillo_bits/fn_repmat.hpp"
+  #include "armadillo_bits/fn_reshape.hpp"
+  #include "armadillo_bits/fn_resize.hpp"
+  #include "armadillo_bits/fn_cov.hpp"
+  #include "armadillo_bits/fn_cor.hpp"
+  #include "armadillo_bits/fn_shuffle.hpp"
+  #include "armadillo_bits/fn_prod.hpp"
+  #include "armadillo_bits/fn_eps.hpp"
+  #include "armadillo_bits/fn_pinv.hpp"
+  #include "armadillo_bits/fn_rank.hpp"
+  #include "armadillo_bits/fn_kron.hpp"
+  #include "armadillo_bits/fn_flip.hpp"
+  #include "armadillo_bits/fn_as_scalar.hpp"
+  #include "armadillo_bits/fn_princomp.hpp"
+  #include "armadillo_bits/fn_cross.hpp"
+  #include "armadillo_bits/fn_join.hpp"
+  #include "armadillo_bits/fn_conv.hpp"
+  #include "armadillo_bits/fn_trunc_exp.hpp"
+  #include "armadillo_bits/fn_trunc_log.hpp"
+  #include "armadillo_bits/fn_toeplitz.hpp"
+  #include "armadillo_bits/fn_trimat.hpp"
+  #include "armadillo_bits/fn_cumsum.hpp"
+  #include "armadillo_bits/fn_symmat.hpp"
+  #include "armadillo_bits/fn_syl_lyap.hpp"
+  #include "armadillo_bits/fn_hist.hpp"
+  #include "armadillo_bits/fn_histc.hpp"
+  #include "armadillo_bits/fn_unique.hpp"
+  #include "armadillo_bits/fn_fft.hpp"
+  
+  #include "armadillo_bits/fn_speye.hpp"
+  #include "armadillo_bits/fn_spones.hpp"
+  #include "armadillo_bits/fn_sprandn.hpp"
+  #include "armadillo_bits/fn_sprandu.hpp"
+  
+  
+  // misc stuff
+  
+  #include "armadillo_bits/hdf5_misc.hpp"
+  #include "armadillo_bits/fft_engine.hpp"
+  
+  
+  //
+  // class meat
+  
+  #include "armadillo_bits/gemv.hpp"
+  #include "armadillo_bits/gemm.hpp"
+  #include "armadillo_bits/gemm_mixed.hpp"
+  
+  #include "armadillo_bits/eop_core_meat.hpp"
+  #include "armadillo_bits/eglue_core_meat.hpp"
+  
+  #include "armadillo_bits/cond_rel_meat.hpp"
+  #include "armadillo_bits/arrayops_meat.hpp"
+  #include "armadillo_bits/podarray_meat.hpp"
+  #include "armadillo_bits/auxlib_meat.hpp"
+  
+  #include "armadillo_bits/injector_meat.hpp"
+  
+  #include "armadillo_bits/Mat_meat.hpp"
+  #include "armadillo_bits/Col_meat.hpp"
+  #include "armadillo_bits/Row_meat.hpp"
+  #include "armadillo_bits/Cube_meat.hpp"
+  #include "armadillo_bits/xvec_htrans_meat.hpp"
+  
+  #include "armadillo_bits/field_meat.hpp"
+  #include "armadillo_bits/subview_meat.hpp"
+  #include "armadillo_bits/subview_elem1_meat.hpp"
+  #include "armadillo_bits/subview_elem2_meat.hpp"
+  #include "armadillo_bits/subview_field_meat.hpp"
+  #include "armadillo_bits/subview_cube_meat.hpp"
+  #include "armadillo_bits/diagview_meat.hpp"
+  #include "armadillo_bits/subview_each_meat.hpp"
+
+  #include "armadillo_bits/SpValProxy_meat.hpp"
+  #include "armadillo_bits/SpMat_meat.hpp"
+  #include "armadillo_bits/SpMat_iterators_meat.hpp"
+  #include "armadillo_bits/SpCol_meat.hpp"
+  #include "armadillo_bits/SpRow_meat.hpp"
+  #include "armadillo_bits/SpSubview_meat.hpp"
+  #include "armadillo_bits/SpSubview_iterators_meat.hpp"
+  
+  #include "armadillo_bits/diskio_meat.hpp"
+  #include "armadillo_bits/wall_clock_meat.hpp"
+  #include "armadillo_bits/running_stat_meat.hpp"
+  #include "armadillo_bits/running_stat_vec_meat.hpp"
+  
+  #include "armadillo_bits/op_diagmat_meat.hpp"
+  #include "armadillo_bits/op_diagvec_meat.hpp"
+  #include "armadillo_bits/op_dot_meat.hpp"
+  #include "armadillo_bits/op_inv_meat.hpp"
+  #include "armadillo_bits/op_htrans_meat.hpp"
+  #include "armadillo_bits/op_max_meat.hpp"
+  #include "armadillo_bits/op_min_meat.hpp"
+  #include "armadillo_bits/op_mean_meat.hpp"
+  #include "armadillo_bits/op_median_meat.hpp"
+  #include "armadillo_bits/op_sort_meat.hpp"
+  #include "armadillo_bits/op_sum_meat.hpp"
+  #include "armadillo_bits/op_stddev_meat.hpp"
+  #include "armadillo_bits/op_strans_meat.hpp"
+  #include "armadillo_bits/op_var_meat.hpp"
+  #include "armadillo_bits/op_repmat_meat.hpp"
+  #include "armadillo_bits/op_reshape_meat.hpp"
+  #include "armadillo_bits/op_resize_meat.hpp"
+  #include "armadillo_bits/op_cov_meat.hpp"
+  #include "armadillo_bits/op_cor_meat.hpp"
+  #include "armadillo_bits/op_shuffle_meat.hpp"
+  #include "armadillo_bits/op_prod_meat.hpp"
+  #include "armadillo_bits/op_pinv_meat.hpp"
+  #include "armadillo_bits/op_dotext_meat.hpp"
+  #include "armadillo_bits/op_flip_meat.hpp"
+  #include "armadillo_bits/op_princomp_meat.hpp"
+  #include "armadillo_bits/op_misc_meat.hpp"
+  #include "armadillo_bits/op_relational_meat.hpp"
+  #include "armadillo_bits/op_find_meat.hpp"
+  #include "armadillo_bits/op_chol_meat.hpp"
+  #include "armadillo_bits/op_cx_scalar_meat.hpp"
+  #include "armadillo_bits/op_trimat_meat.hpp"
+  #include "armadillo_bits/op_cumsum_meat.hpp"
+  #include "armadillo_bits/op_symmat_meat.hpp"
+  #include "armadillo_bits/op_hist_meat.hpp"
+  #include "armadillo_bits/op_unique_meat.hpp"
+  #include "armadillo_bits/op_toeplitz_meat.hpp"
+  #include "armadillo_bits/op_fft_meat.hpp"
+  
+  #include "armadillo_bits/glue_times_meat.hpp"
+  #include "armadillo_bits/glue_mixed_meat.hpp"
+  #include "armadillo_bits/glue_cov_meat.hpp"
+  #include "armadillo_bits/glue_cor_meat.hpp"
+  #include "armadillo_bits/glue_kron_meat.hpp"
+  #include "armadillo_bits/glue_cross_meat.hpp"
+  #include "armadillo_bits/glue_join_meat.hpp"
+  #include "armadillo_bits/glue_relational_meat.hpp"
+  #include "armadillo_bits/glue_solve_meat.hpp"
+  #include "armadillo_bits/glue_conv_meat.hpp"
+  #include "armadillo_bits/glue_toeplitz_meat.hpp"
+  #include "armadillo_bits/glue_hist_meat.hpp"
+  #include "armadillo_bits/glue_histc_meat.hpp"
+  
+  #include "armadillo_bits/spop_max_meat.hpp"
+  #include "armadillo_bits/spop_min_meat.hpp"
+  #include "armadillo_bits/spop_sum_meat.hpp"
+  #include "armadillo_bits/spop_strans_meat.hpp"
+  #include "armadillo_bits/spop_htrans_meat.hpp"
+  #include "armadillo_bits/spop_misc_meat.hpp"
+  #include "armadillo_bits/spop_mean_meat.hpp"
+  #include "armadillo_bits/spop_var_meat.hpp"
+  
+  #include "armadillo_bits/spglue_plus_meat.hpp"
+  #include "armadillo_bits/spglue_minus_meat.hpp"
+  #include "armadillo_bits/spglue_times_meat.hpp"
+  }
+
+
+
+#include "armadillo_bits/compiler_setup_post.hpp"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/BaseCube_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,29 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup BaseCube
+//! @{
+
+
+
+//! Analog of the Base class, intended for cubes
+template<typename elem_type, typename derived>
+struct BaseCube
+  {
+  arma_inline const derived& get_ref() const;
+  
+  inline void print(const std::string extra_text = "") const;
+  inline void print(std::ostream& user_stream, const std::string extra_text = "") const;
+  
+  inline void raw_print(const std::string extra_text = "") const;
+  inline void raw_print(std::ostream& user_stream, const std::string extra_text = "") const;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/BaseCube_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,72 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup BaseCube
+//! @{
+
+
+
+template<typename elem_type, typename derived>
+arma_inline
+const derived&
+BaseCube<elem_type,derived>::get_ref() const
+  {
+  return static_cast<const derived&>(*this);
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+void
+BaseCube<elem_type,derived>::print(const std::string extra_text) const
+  {
+  const unwrap_cube<derived> tmp( (*this).get_ref() );
+  
+  tmp.M.impl_print(extra_text);
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+void
+BaseCube<elem_type,derived>::print(std::ostream& user_stream, const std::string extra_text) const
+  {
+  const unwrap_cube<derived> tmp( (*this).get_ref() );
+  
+  tmp.M.impl_print(user_stream, extra_text);
+  }
+  
+
+
+template<typename elem_type, typename derived>
+inline
+void
+BaseCube<elem_type,derived>::raw_print(const std::string extra_text) const
+  {
+  const unwrap_cube<derived> tmp( (*this).get_ref() );
+  
+  tmp.M.impl_raw_print(extra_text);
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+void
+BaseCube<elem_type,derived>::raw_print(std::ostream& user_stream, const std::string extra_text) const
+  {
+  const unwrap_cube<derived> tmp( (*this).get_ref() );
+  
+  tmp.M.impl_raw_print(user_stream, extra_text);
+  }
+  
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Base_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,88 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Base
+//! @{
+
+
+
+template<typename derived>
+struct Base_blas_elem_type
+  {
+  arma_inline const Op<derived,op_inv> i(const bool slow = false) const;   //!< matrix inverse
+  };
+
+
+template<typename derived>
+struct Base_other_elem_type
+  {
+  };
+
+
+template<typename derived, bool condition>
+struct Base_extra {};
+
+template<typename derived>
+struct Base_extra<derived, true>  { typedef Base_blas_elem_type<derived>  result; };
+
+template<typename derived>
+struct Base_extra<derived, false> { typedef Base_other_elem_type<derived> result; };
+
+
+
+template<typename elem_type, typename derived>
+struct Base_eval_Mat
+  {
+  const derived& eval() const;
+  };
+
+
+template<typename elem_type, typename derived>
+struct Base_eval_expr
+  {
+  Mat<elem_type> eval() const;   //!< force the immediate evaluation of a delayed expression
+  };
+
+
+template<typename elem_type, typename derived, bool condition>
+struct Base_eval {};
+
+template<typename elem_type, typename derived>
+struct Base_eval<elem_type, derived, true>  { typedef Base_eval_Mat<elem_type, derived>  result; };
+
+template<typename elem_type, typename derived>
+struct Base_eval<elem_type, derived, false> { typedef Base_eval_expr<elem_type, derived> result; };
+
+
+
+//! Class for static polymorphism, modelled after the "Curiously Recurring Template Pattern" (CRTP).
+//! Used for type-safe downcasting in functions that restrict their input(s) to be classes that are
+//! derived from Base (e.g. Mat, Op, Glue, diagview, subview).
+//! A Base object can be converted to a Mat object by the unwrap class.
+
+template<typename elem_type, typename derived>
+struct Base
+  : public Base_extra<derived, is_supported_blas_type<elem_type>::value>::result
+  , public Base_eval<elem_type, derived, is_Mat<derived>::value>::result
+  {
+  arma_inline const derived& get_ref() const;
+  
+  arma_inline const Op<derived,op_htrans>  t() const;  //!< Hermitian transpose
+  arma_inline const Op<derived,op_htrans> ht() const;  //!< Hermitian transpose
+  arma_inline const Op<derived,op_strans> st() const;  //!< simple transpose
+  
+  inline void print(const std::string extra_text = "") const;
+  inline void print(std::ostream& user_stream, const std::string extra_text = "") const;
+  
+  inline void raw_print(const std::string extra_text = "") const;
+  inline void raw_print(std::ostream& user_stream, const std::string extra_text = "") const;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Base_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,154 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Base
+//! @{
+
+
+
+template<typename elem_type, typename derived>
+arma_inline
+const derived&
+Base<elem_type,derived>::get_ref() const
+  {
+  return static_cast<const derived&>(*this);
+  }
+
+
+
+template<typename elem_type, typename derived>
+arma_inline
+const Op<derived,op_htrans>
+Base<elem_type,derived>::t() const
+  {
+  return Op<derived,op_htrans>( (*this).get_ref() );
+  }
+
+
+
+template<typename elem_type, typename derived>
+arma_inline
+const Op<derived,op_htrans>
+Base<elem_type,derived>::ht() const
+  {
+  return Op<derived,op_htrans>( (*this).get_ref() );
+  }
+
+
+
+template<typename elem_type, typename derived>
+arma_inline
+const Op<derived,op_strans>
+Base<elem_type,derived>::st() const
+  {
+  return Op<derived,op_strans>( (*this).get_ref() );
+  }
+
+
+
+
+template<typename elem_type, typename derived>
+inline
+void
+Base<elem_type,derived>::print(const std::string extra_text) const
+  {
+  const Proxy<derived> P( (*this).get_ref() );
+  
+  const quasi_unwrap< typename Proxy<derived>::stored_type > tmp(P.Q);
+  
+  tmp.M.impl_print(extra_text);
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+void
+Base<elem_type,derived>::print(std::ostream& user_stream, const std::string extra_text) const
+  {
+  const Proxy<derived> P( (*this).get_ref() );
+  
+  const quasi_unwrap< typename Proxy<derived>::stored_type > tmp(P.Q);
+  
+  tmp.M.impl_print(user_stream, extra_text);
+  }
+  
+
+
+template<typename elem_type, typename derived>
+inline
+void
+Base<elem_type,derived>::raw_print(const std::string extra_text) const
+  {
+  const Proxy<derived> P( (*this).get_ref() );
+  
+  const quasi_unwrap< typename Proxy<derived>::stored_type > tmp(P.Q);
+  
+  tmp.M.impl_raw_print(extra_text);
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+void
+Base<elem_type,derived>::raw_print(std::ostream& user_stream, const std::string extra_text) const
+  {
+  const Proxy<derived> P( (*this).get_ref() );
+  
+  const quasi_unwrap< typename Proxy<derived>::stored_type > tmp(P.Q);
+  
+  tmp.M.impl_raw_print(user_stream, extra_text);
+  }
+
+
+
+//
+// extra functions defined in Base_blas_elem_type
+
+template<typename derived>
+arma_inline
+const Op<derived,op_inv>
+Base_blas_elem_type<derived>::i(const bool slow) const
+  {
+  return Op<derived,op_inv>( static_cast<const derived&>(*this), ((slow == false) ? 0 : 1), 0 );
+  }
+
+
+
+//
+// extra functions defined in Base_eval_Mat
+
+template<typename elem_type, typename derived>
+arma_inline
+const derived&
+Base_eval_Mat<elem_type, derived>::eval() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return static_cast<const derived&>(*this);
+  }
+
+
+
+//
+// extra functions defined in Base_eval_expr
+
+template<typename elem_type, typename derived>
+arma_inline
+Mat<elem_type>
+Base_eval_expr<elem_type, derived>::eval() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return Mat<elem_type>( static_cast<const derived&>(*this) );
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Col_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,209 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Col
+//! @{
+
+//! Class for column vectors (matrices with only one column)
+
+template<typename eT>
+class Col : public Mat<eT>
+  {
+  public:
+  
+  typedef eT                                elem_type;
+  typedef typename get_pod_type<eT>::result pod_type;
+  
+  static const bool is_col = true;
+  static const bool is_row = false;
+  
+  inline          Col();
+  inline          Col(const Col<eT>& X);
+  inline explicit Col(const uword n_elem);
+  inline          Col(const uword in_rows, const uword in_cols);
+  
+  inline                  Col(const char*        text);
+  inline const Col& operator=(const char*        text);
+  
+  inline                  Col(const std::string& text);
+  inline const Col& operator=(const std::string& text);
+  
+  inline                  Col(const std::vector<eT>& x);
+  inline const Col& operator=(const std::vector<eT>& x);
+  
+  #if defined(ARMA_USE_CXX11)
+  inline                  Col(const std::initializer_list<eT>& list);
+  inline const Col& operator=(const std::initializer_list<eT>& list);
+  #endif
+  
+  inline explicit Col(const SpCol<eT>& X);
+  
+  inline const Col& operator=(const eT val);
+    
+  template<typename T1> inline                   Col(const Base<eT,T1>& X);
+  template<typename T1> inline const Col&  operator=(const Base<eT,T1>& X);
+  
+  inline Col(      eT* aux_mem, const uword aux_length, const bool copy_aux_mem = true, const bool strict = true);
+  inline Col(const eT* aux_mem, const uword aux_length);
+  
+  template<typename T1, typename T2>
+  inline explicit Col(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
+  
+  template<typename T1> inline                  Col(const BaseCube<eT,T1>& X);
+  template<typename T1> inline const Col& operator=(const BaseCube<eT,T1>& X);
+  
+  inline                  Col(const subview_cube<eT>& X);
+  inline const Col& operator=(const subview_cube<eT>& X);
+  
+  inline mat_injector<Col> operator<<(const eT val);
+  
+  arma_inline const Op<Col<eT>,op_htrans>  t() const;
+  arma_inline const Op<Col<eT>,op_htrans> ht() const;
+  arma_inline const Op<Col<eT>,op_strans> st() const;
+  
+  arma_inline eT& row(const uword row_num);
+  arma_inline eT  row(const uword row_num) const;
+  
+  arma_inline       subview_col<eT> rows(const uword in_row1, const uword in_row2);
+  arma_inline const subview_col<eT> rows(const uword in_row1, const uword in_row2) const;
+  
+  arma_inline       subview_col<eT> subvec(const uword in_row1, const uword in_row2);
+  arma_inline const subview_col<eT> subvec(const uword in_row1, const uword in_row2) const;
+  
+  arma_inline       subview_col<eT> subvec(const span& row_span);
+  arma_inline const subview_col<eT> subvec(const span& row_span) const;
+  
+  using Mat<eT>::operator();
+  
+  arma_inline       subview_col<eT> operator()(const span& row_span);
+  arma_inline const subview_col<eT> operator()(const span& row_span) const;
+  
+  
+  inline void shed_row (const uword row_num);
+  inline void shed_rows(const uword in_row1, const uword in_row2);
+  
+                        inline void insert_rows(const uword row_num, const uword N, const bool set_to_zero = true);
+  template<typename T1> inline void insert_rows(const uword row_num, const Base<eT,T1>& X);
+  
+  
+  arma_inline arma_warn_unused       eT& at(const uword i);
+  arma_inline arma_warn_unused const eT& at(const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& at(const uword in_row, const uword in_col);
+  arma_inline arma_warn_unused const eT& at(const uword in_row, const uword in_col) const;
+  
+  
+  typedef       eT*       row_iterator;
+  typedef const eT* const_row_iterator;
+  
+  inline       row_iterator begin_row(const uword row_num);
+  inline const_row_iterator begin_row(const uword row_num) const;
+  
+  inline       row_iterator end_row  (const uword row_num);
+  inline const_row_iterator end_row  (const uword row_num) const;
+  
+  
+  template<uword fixed_n_elem> class fixed;
+  
+  
+  protected:
+  
+  inline Col(const arma_fixed_indicator&, const uword in_n_elem, const eT* in_mem);
+  
+  
+  public:
+  
+  #ifdef ARMA_EXTRA_COL_PROTO
+    #include ARMA_INCFILE_WRAP(ARMA_EXTRA_COL_PROTO)
+  #endif
+  };
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+class Col<eT>::fixed : public Col<eT>
+  {
+  private:
+  
+  static const bool use_extra = (fixed_n_elem > arma_config::mat_prealloc);
+  
+  arma_align_mem eT mem_local_extra[ (use_extra) ? fixed_n_elem : 1 ];
+  
+  arma_inline void change_to_row();
+  
+  
+  public:
+  
+  typedef fixed<fixed_n_elem>               Col_fixed_type;
+  
+  typedef eT                                elem_type;
+  typedef typename get_pod_type<eT>::result pod_type;
+  
+  static const bool is_col = true;
+  static const bool is_row = false;
+  
+  static const uword n_rows = fixed_n_elem;
+  static const uword n_cols = 1;
+  static const uword n_elem = fixed_n_elem;
+  
+  arma_inline fixed();
+  arma_inline fixed(const fixed<fixed_n_elem>& X);
+       inline fixed(const subview_cube<eT>& X);
+  
+  template<typename T1>              inline fixed(const Base<eT,T1>& A);
+  template<typename T1, typename T2> inline fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
+  
+  inline fixed(const eT* aux_mem);
+  
+  inline fixed(const char*        text);
+  inline fixed(const std::string& text);
+  
+  template<typename T1> inline const Col& operator=(const Base<eT,T1>& A);
+  
+  inline const Col& operator=(const eT val);
+  inline const Col& operator=(const char*        text);
+  inline const Col& operator=(const std::string& text);
+  inline const Col& operator=(const subview_cube<eT>& X);
+  
+  using Col<eT>::operator();
+  
+  #if defined(ARMA_USE_CXX11)
+    inline                fixed(const std::initializer_list<eT>& list);
+    inline const Col& operator=(const std::initializer_list<eT>& list);
+  #endif
+  
+  arma_inline const Op< Col_fixed_type, op_htrans >  t() const;
+  arma_inline const Op< Col_fixed_type, op_htrans > ht() const;
+  arma_inline const Op< Col_fixed_type, op_strans > st() const;
+  
+  arma_inline arma_warn_unused const eT& at_alt     (const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& operator[] (const uword i);
+  arma_inline arma_warn_unused const eT& operator[] (const uword i) const;
+  arma_inline arma_warn_unused       eT& at         (const uword i);
+  arma_inline arma_warn_unused const eT& at         (const uword i) const;
+  arma_inline arma_warn_unused       eT& operator() (const uword i);
+  arma_inline arma_warn_unused const eT& operator() (const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& at         (const uword in_row, const uword in_col);
+  arma_inline arma_warn_unused const eT& at         (const uword in_row, const uword in_col) const;
+  arma_inline arma_warn_unused       eT& operator() (const uword in_row, const uword in_col);
+  arma_inline arma_warn_unused const eT& operator() (const uword in_row, const uword in_col) const;
+  
+  arma_inline arma_warn_unused       eT* memptr();
+  arma_inline arma_warn_unused const eT* memptr() const;
+  
+  arma_hot inline const Col<eT>& fill(const eT val);
+  arma_hot inline const Col<eT>& zeros();
+  arma_hot inline const Col<eT>& ones();
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Col_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,1303 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Col
+//! @{
+
+
+//! construct an empty column vector
+template<typename eT>
+inline
+Col<eT>::Col()
+  : Mat<eT>(arma_vec_indicator(), 1)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+Col<eT>::Col(const Col<eT>& X)
+  : Mat<eT>(arma_vec_indicator(), X.n_elem, 1, 1)
+  {
+  arma_extra_debug_sigprint();
+  
+  arrayops::copy((*this).memptr(), X.memptr(), X.n_elem);
+  }
+
+
+
+//! construct a column vector with the specified number of n_elem
+template<typename eT>
+inline
+Col<eT>::Col(const uword in_n_elem)
+  : Mat<eT>(arma_vec_indicator(), in_n_elem, 1, 1)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+Col<eT>::Col(const uword in_n_rows, const uword in_n_cols)
+  : Mat<eT>(arma_vec_indicator(), 0, 0, 1)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::init_warm(in_n_rows, in_n_cols);
+  }
+
+
+
+//! construct a column vector from specified text
+template<typename eT>
+inline
+Col<eT>::Col(const char* text)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 2;
+  
+  Mat<eT>::operator=(text);
+  
+  std::swap( access::rw(Mat<eT>::n_rows), access::rw(Mat<eT>::n_cols) );
+  
+  access::rw(Mat<eT>::vec_state) = 1;
+  }
+
+
+
+//! construct a column vector from specified text
+template<typename eT>
+inline
+const Col<eT>&
+Col<eT>::operator=(const char* text)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 2;
+  
+  Mat<eT>::operator=(text);
+  
+  std::swap( access::rw(Mat<eT>::n_rows), access::rw(Mat<eT>::n_cols) );
+  
+  access::rw(Mat<eT>::vec_state) = 1;
+  
+  return *this;
+  }
+
+
+
+//! construct a column vector from specified text
+template<typename eT>
+inline
+Col<eT>::Col(const std::string& text)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 2;
+  
+  Mat<eT>::operator=(text);
+  
+  std::swap( access::rw(Mat<eT>::n_rows), access::rw(Mat<eT>::n_cols) );
+  
+  access::rw(Mat<eT>::vec_state) = 1;
+  }
+
+
+
+//! construct a column vector from specified text
+template<typename eT>
+inline
+const Col<eT>&
+Col<eT>::operator=(const std::string& text)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 2;
+  
+  Mat<eT>::operator=(text);
+  
+  std::swap( access::rw(Mat<eT>::n_rows), access::rw(Mat<eT>::n_cols) );
+  
+  access::rw(Mat<eT>::vec_state) = 1;
+  
+  return *this;
+  }
+
+
+
+//! create a column vector from std::vector
+template<typename eT>
+inline
+Col<eT>::Col(const std::vector<eT>& x)
+  : Mat<eT>(arma_vec_indicator(), uword(x.size()), 1, 1)
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  if(x.size() > 0)
+    {
+    arrayops::copy( Mat<eT>::memptr(), &(x[0]), uword(x.size()) );
+    }
+  }
+  
+  
+  
+//! create a column vector from std::vector
+template<typename eT>
+inline
+const Col<eT>&
+Col<eT>::operator=(const std::vector<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::init_warm(uword(x.size()), 1);
+  
+  if(x.size() > 0)
+    {
+    arrayops::copy( Mat<eT>::memptr(), &(x[0]), uword(x.size()) );
+    }
+  
+  return *this;
+  }
+
+
+
+#if defined(ARMA_USE_CXX11)
+  
+  template<typename eT>
+  inline
+  Col<eT>::Col(const std::initializer_list<eT>& list)
+    {
+    arma_extra_debug_sigprint();
+    
+    access::rw(Mat<eT>::vec_state) = 2;
+    
+    Mat<eT>::operator=(list);
+    
+    std::swap( access::rw(Mat<eT>::n_rows), access::rw(Mat<eT>::n_cols) );
+    
+    access::rw(Mat<eT>::vec_state) = 1;
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  const Col<eT>&
+  Col<eT>::operator=(const std::initializer_list<eT>& list)
+    {
+    arma_extra_debug_sigprint();
+    
+    access::rw(Mat<eT>::vec_state) = 2;
+    
+    Mat<eT>::operator=(list);
+    
+    std::swap( access::rw(Mat<eT>::n_rows), access::rw(Mat<eT>::n_cols) );
+    
+    access::rw(Mat<eT>::vec_state) = 1;
+    
+    return *this;
+    }
+  
+#endif
+
+
+
+template<typename eT>
+inline
+Col<eT>::Col(const SpCol<eT>& X)
+  : Mat<eT>(arma_vec_indicator(), X.n_elem, 1, 1)
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  arrayops::inplace_set(Mat<eT>::memptr(), eT(0), X.n_elem);
+
+  for(typename SpCol<eT>::const_iterator it = X.begin(); it != X.end(); ++it)
+    at(it.row()) = (*it);
+  }
+
+
+
+template<typename eT>
+inline
+const Col<eT>&
+Col<eT>::operator=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::operator=(val);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+Col<eT>::Col(const Base<eT,T1>& X)
+  : Mat<eT>(arma_vec_indicator(), 1)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::operator=(X.get_ref());
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Col<eT>&
+Col<eT>::operator=(const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::operator=(X.get_ref());
+  
+  return *this;
+  }
+
+
+
+//! construct a column vector from a given auxiliary array of eTs
+template<typename eT>
+inline
+Col<eT>::Col(eT* aux_mem, const uword aux_length, const bool copy_aux_mem, const bool strict)
+  : Mat<eT>(aux_mem, aux_length, 1, copy_aux_mem, strict)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 1;
+  }
+
+
+
+//! construct a column vector from a given auxiliary array of eTs
+template<typename eT>
+inline
+Col<eT>::Col(const eT* aux_mem, const uword aux_length)
+  : Mat<eT>(aux_mem, aux_length, 1)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 1;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+inline
+Col<eT>::Col
+  (
+  const Base<typename Col<eT>::pod_type, T1>& A,
+  const Base<typename Col<eT>::pod_type, T2>& B
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 1;
+  
+  Mat<eT>::init(A,B);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+Col<eT>::Col(const BaseCube<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 1;
+  
+  Mat<eT>::operator=(X);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Col<eT>&
+Col<eT>::operator=(const BaseCube<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::operator=(X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+Col<eT>::Col(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 1;
+  
+  Mat<eT>::operator=(X);
+  }
+
+
+
+template<typename eT>
+inline
+const Col<eT>&
+Col<eT>::operator=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::operator=(X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+mat_injector< Col<eT> >
+Col<eT>::operator<<(const eT val)
+  {
+  return mat_injector< Col<eT> >(*this, val);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<Col<eT>,op_htrans>
+Col<eT>::t() const
+  {
+  return Op<Col<eT>,op_htrans>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<Col<eT>,op_htrans>
+Col<eT>::ht() const
+  {
+  return Op<Col<eT>,op_htrans>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<Col<eT>,op_strans>
+Col<eT>::st() const
+  {
+  return Op<Col<eT>,op_strans>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT&
+Col<eT>::row(const uword row_num)
+  {
+  arma_debug_check( (row_num >= Mat<eT>::n_rows), "Col::row(): index out of bounds" );
+  
+  return access::rw(Mat<eT>::mem[row_num]);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+Col<eT>::row(const uword row_num) const
+  {
+  arma_debug_check( (row_num >= Mat<eT>::n_rows), "Col::row(): index out of bounds" );
+  
+  return Mat<eT>::mem[row_num];
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_col<eT>
+Col<eT>::rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= Mat<eT>::n_rows) ), "Col::rows(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  return subview_col<eT>(*this, 0, in_row1, subview_n_rows);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_col<eT>
+Col<eT>::rows(const uword in_row1, const uword in_row2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= Mat<eT>::n_rows) ), "Col::rows(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  return subview_col<eT>(*this, 0, in_row1, subview_n_rows);
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_col<eT>
+Col<eT>::subvec(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= Mat<eT>::n_rows) ), "Col::subvec(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  return subview_col<eT>(*this, 0, in_row1, subview_n_rows);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_col<eT>
+Col<eT>::subvec(const uword in_row1, const uword in_row2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= Mat<eT>::n_rows) ), "Col::subvec(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  return subview_col<eT>(*this, 0, in_row1, subview_n_rows);
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_col<eT>
+Col<eT>::subvec(const span& row_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+
+  const uword local_n_rows = Mat<eT>::n_rows;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword subvec_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+
+  arma_debug_check( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ), "Col::subvec(): indices out of bounds or incorrectly used");
+  
+  return subview_col<eT>(*this, 0, in_row1, subvec_n_rows);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_col<eT>
+Col<eT>::subvec(const span& row_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+
+  const uword local_n_rows = Mat<eT>::n_rows;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword subvec_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+
+  arma_debug_check( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ), "Col::subvec(): indices out of bounds or incorrectly used");
+  
+  return subview_col<eT>(*this, 0, in_row1, subvec_n_rows);
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_col<eT>
+Col<eT>::operator()(const span& row_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  return subvec(row_span);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_col<eT>
+Col<eT>::operator()(const span& row_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return subvec(row_span);
+  }
+
+
+
+//! remove specified row
+template<typename eT>
+inline
+void
+Col<eT>::shed_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( row_num >= Mat<eT>::n_rows, "Col::shed_row(): index out of bounds");
+  
+  shed_rows(row_num, row_num);
+  }
+
+
+
+//! remove specified rows
+template<typename eT>
+inline
+void
+Col<eT>::shed_rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_row2 >= Mat<eT>::n_rows),
+    "Col::shed_rows(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword n_keep_front = in_row1;
+  const uword n_keep_back  = Mat<eT>::n_rows - (in_row2 + 1);
+  
+  Col<eT> X(n_keep_front + n_keep_back);
+  
+        eT* X_mem = X.memptr();
+  const eT* t_mem = (*this).memptr();
+  
+  if(n_keep_front > 0)
+    {
+    arrayops::copy( X_mem, t_mem, n_keep_front );
+    }
+  
+  if(n_keep_back > 0)
+    {
+    arrayops::copy( &(X_mem[n_keep_front]), &(t_mem[in_row2+1]), n_keep_back);
+    }
+  
+  Mat<eT>::steal_mem(X);
+  }
+
+
+
+//! insert N rows at the specified row position,
+//! optionally setting the elements of the inserted rows to zero
+template<typename eT>
+inline
+void
+Col<eT>::insert_rows(const uword row_num, const uword N, const bool set_to_zero)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword t_n_rows = Mat<eT>::n_rows;
+  
+  const uword A_n_rows = row_num;
+  const uword B_n_rows = t_n_rows - row_num;
+  
+  // insertion at row_num == n_rows is in effect an append operation
+  arma_debug_check( (row_num > t_n_rows), "Col::insert_rows(): index out of bounds");
+  
+  if(N > 0)
+    {
+    Col<eT> out(t_n_rows + N);
+    
+          eT* out_mem = out.memptr();
+    const eT*   t_mem = (*this).memptr();
+    
+    if(A_n_rows > 0)
+      {
+      arrayops::copy( out_mem, t_mem, A_n_rows );
+      }
+    
+    if(B_n_rows > 0)
+      {
+      arrayops::copy( &(out_mem[row_num + N]), &(t_mem[row_num]), B_n_rows );
+      }
+    
+    if(set_to_zero == true)
+      {
+      arrayops::inplace_set( &(out_mem[row_num]), eT(0), N );
+      }
+    
+    Mat<eT>::steal_mem(out);
+    }
+  }
+
+
+
+//! insert the given object at the specified row position; 
+//! the given object must have one column
+template<typename eT>
+template<typename T1>
+inline
+void
+Col<eT>::insert_rows(const uword row_num, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::insert_rows(row_num, X);
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Col<eT>::at(const uword i)
+  {
+  return access::rw(Mat<eT>::mem[i]);
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Col<eT>::at(const uword i) const
+  {
+  return Mat<eT>::mem[i];
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Col<eT>::at(const uword in_row, const uword)
+  {
+  return access::rw( Mat<eT>::mem[in_row] );
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Col<eT>::at(const uword in_row, const uword) const
+  {
+  return Mat<eT>::mem[in_row];
+  }
+
+
+
+template<typename eT>
+inline
+typename Col<eT>::row_iterator
+Col<eT>::begin_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= Mat<eT>::n_rows), "begin_row(): index out of bounds");
+  
+  return Mat<eT>::memptr() + row_num;
+  }
+
+
+
+template<typename eT>
+inline
+typename Col<eT>::const_row_iterator
+Col<eT>::begin_row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= Mat<eT>::n_rows), "begin_row(): index out of bounds");
+  
+  return Mat<eT>::memptr() + row_num;
+  }
+
+
+
+template<typename eT>
+inline
+typename Col<eT>::row_iterator
+Col<eT>::end_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= Mat<eT>::n_rows), "end_row(): index out of bounds");
+  
+  return Mat<eT>::memptr() + row_num + 1;
+  }
+
+
+
+template<typename eT>
+inline
+typename Col<eT>::const_row_iterator
+Col<eT>::end_row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= Mat<eT>::n_rows), "end_row(): index out of bounds");
+  
+  return Mat<eT>::memptr() + row_num + 1;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+void
+Col<eT>::fixed<fixed_n_elem>::change_to_row()
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::n_cols) = fixed_n_elem;
+  access::rw(Mat<eT>::n_rows) = 1;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+Col<eT>::fixed<fixed_n_elem>::fixed()
+  : Col<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+Col<eT>::fixed<fixed_n_elem>::fixed(const fixed<fixed_n_elem>& X)
+  : Col<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  eT* dest = (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
+  
+  arrayops::copy( dest, X.mem, fixed_n_elem );
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+inline
+Col<eT>::fixed<fixed_n_elem>::fixed(const subview_cube<eT>& X)
+  : Col<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  Col<eT>::operator=(X);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+template<typename T1>
+inline
+Col<eT>::fixed<fixed_n_elem>::fixed(const Base<eT,T1>& A)
+  : Col<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  Col<eT>::operator=(A.get_ref());
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+template<typename T1, typename T2>
+inline
+Col<eT>::fixed<fixed_n_elem>::fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B)
+  : Col<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  Col<eT>::init(A,B);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+inline
+Col<eT>::fixed<fixed_n_elem>::fixed(const eT* aux_mem)
+  : Col<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  eT* dest = (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
+  
+  arrayops::copy( dest, aux_mem, fixed_n_elem );
+  }
+
+
+
+//! NOTE: this function relies on
+//! Col::operator=(text), to change vec_state as well as swapping n_rows and n_cols,
+//! and Mat::init(), to check that the given vector will not have a different size than fixed_n_elem.
+template<typename eT>
+template<uword fixed_n_elem>
+inline
+Col<eT>::fixed<fixed_n_elem>::fixed(const char* text)
+  : Col<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  change_to_row();
+  
+  Col<eT>::operator=(text);
+  }
+
+
+
+//! NOTE: this function relies on
+//! Col::operator=(text), to change vec_state as well as swapping n_rows and n_cols,
+//! and Mat::init(), to check that the given vector will not have a different size than fixed_n_elem.
+template<typename eT>
+template<uword fixed_n_elem>
+inline
+Col<eT>::fixed<fixed_n_elem>::fixed(const std::string& text)
+  : Col<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  change_to_row();
+  
+  Col<eT>::operator=(text);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+template<typename T1>
+const Col<eT>&
+Col<eT>::fixed<fixed_n_elem>::operator=(const Base<eT,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  Col<eT>::operator=(A.get_ref());
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+const Col<eT>&
+Col<eT>::fixed<fixed_n_elem>::operator=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  Col<eT>::operator=(val);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+const Col<eT>&
+Col<eT>::fixed<fixed_n_elem>::operator=(const char* text)
+  {
+  arma_extra_debug_sigprint();
+  
+  change_to_row();
+  
+  Col<eT>::operator=(text);
+  
+  return *this; 
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+const Col<eT>&
+Col<eT>::fixed<fixed_n_elem>::operator=(const std::string& text)
+  {
+  arma_extra_debug_sigprint();
+  
+  change_to_row();
+  
+  Col<eT>::operator=(text);
+  
+  return *this; 
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+const Col<eT>&
+Col<eT>::fixed<fixed_n_elem>::operator=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Col<eT>::operator=(X);
+  
+  return *this; 
+  }
+
+
+
+#if defined(ARMA_USE_CXX11)
+  
+  template<typename eT>
+  template<uword fixed_n_elem>
+  inline
+  Col<eT>::fixed<fixed_n_elem>::fixed(const std::initializer_list<eT>& list)
+    : Col<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+    {
+    arma_extra_debug_sigprint_this(this);
+    
+    (*this).operator=(list);
+    }
+  
+  
+  
+  template<typename eT>
+  template<uword fixed_n_elem>
+  inline
+  const Col<eT>&
+  Col<eT>::fixed<fixed_n_elem>::operator=(const std::initializer_list<eT>& list)
+    {
+    arma_extra_debug_sigprint();
+    
+    const uword N = list.size();
+    
+    arma_debug_check( (N > fixed_n_elem), "Col::fixed: initialiser list is too long" );
+    
+    eT* this_mem = (*this).memptr();
+    
+    arrayops::copy( this_mem, list.begin(), N );
+    
+    for(uword iq=N; iq < fixed_n_elem; ++iq) { this_mem[iq] = eT(0); }
+    
+    return *this;
+    }
+  
+#endif
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+const Op< typename Col<eT>::template fixed<fixed_n_elem>::Col_fixed_type, op_htrans >
+Col<eT>::fixed<fixed_n_elem>::t() const
+  {
+  return Op< typename Col<eT>::template fixed<fixed_n_elem>::Col_fixed_type, op_htrans >(*this);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+const Op< typename Col<eT>::template fixed<fixed_n_elem>::Col_fixed_type, op_htrans >
+Col<eT>::fixed<fixed_n_elem>::ht() const
+  {
+  return Op< typename Col<eT>::template fixed<fixed_n_elem>::Col_fixed_type, op_htrans >(*this);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+const Op< typename Col<eT>::template fixed<fixed_n_elem>::Col_fixed_type, op_strans >
+Col<eT>::fixed<fixed_n_elem>::st() const
+  {
+  return Op< typename Col<eT>::template fixed<fixed_n_elem>::Col_fixed_type, op_strans >(*this);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT&
+Col<eT>::fixed<fixed_n_elem>::at_alt(const uword ii) const
+  {
+  #if defined(ARMA_HAVE_ALIGNED_ATTRIBUTE)
+  
+    return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+    
+  #else
+    const eT* mem_aligned = (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
+    
+    memory::mark_as_aligned(mem_aligned);
+    
+    return mem_aligned[ii];
+  #endif
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+eT&
+Col<eT>::fixed<fixed_n_elem>::operator[] (const uword ii)
+  {
+  return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT&
+Col<eT>::fixed<fixed_n_elem>::operator[] (const uword ii) const
+  {
+  return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+eT&
+Col<eT>::fixed<fixed_n_elem>::at(const uword ii)
+  {
+  return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT&
+Col<eT>::fixed<fixed_n_elem>::at(const uword ii) const
+  {
+  return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+eT&
+Col<eT>::fixed<fixed_n_elem>::operator() (const uword ii)
+  {
+  arma_debug_check( (ii >= fixed_n_elem), "Col::operator(): index out of bounds");
+  
+  return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT&
+Col<eT>::fixed<fixed_n_elem>::operator() (const uword ii) const
+  {
+  arma_debug_check( (ii >= fixed_n_elem), "Col::operator(): index out of bounds");
+  
+  return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+eT&
+Col<eT>::fixed<fixed_n_elem>::at(const uword in_row, const uword)
+  {
+  return (use_extra) ? mem_local_extra[in_row] : Mat<eT>::mem_local[in_row];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT&
+Col<eT>::fixed<fixed_n_elem>::at(const uword in_row, const uword) const
+  {
+  return (use_extra) ? mem_local_extra[in_row] : Mat<eT>::mem_local[in_row];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+eT&
+Col<eT>::fixed<fixed_n_elem>::operator() (const uword in_row, const uword in_col)
+  {
+  arma_debug_check( ((in_row >= fixed_n_elem) || (in_col > 0)), "Col::operator(): index out of bounds" );
+  
+  return (use_extra) ? mem_local_extra[in_row] : Mat<eT>::mem_local[in_row];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT&
+Col<eT>::fixed<fixed_n_elem>::operator() (const uword in_row, const uword in_col) const
+  {
+  arma_debug_check( ((in_row >= fixed_n_elem) || (in_col > 0)), "Col::operator(): index out of bounds" );
+  
+  return (use_extra) ? mem_local_extra[in_row] : Mat<eT>::mem_local[in_row];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+eT*
+Col<eT>::fixed<fixed_n_elem>::memptr()
+  {
+  return (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT*
+Col<eT>::fixed<fixed_n_elem>::memptr() const
+  {
+  return (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_hot
+inline
+const Col<eT>&
+Col<eT>::fixed<fixed_n_elem>::fill(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(Mat<eT>::mem_local[0]);
+  
+  arrayops::inplace_set_fixed<eT,fixed_n_elem>( mem_use, val );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_hot
+inline
+const Col<eT>&
+Col<eT>::fixed<fixed_n_elem>::zeros()
+  {
+  arma_extra_debug_sigprint();
+  
+  eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(Mat<eT>::mem_local[0]);
+  
+  arrayops::inplace_set_fixed<eT,fixed_n_elem>( mem_use, eT(0) );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_hot
+inline
+const Col<eT>&
+Col<eT>::fixed<fixed_n_elem>::ones()
+  {
+  arma_extra_debug_sigprint();
+  
+  eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(Mat<eT>::mem_local[0]);
+  
+  arrayops::inplace_set_fixed<eT,fixed_n_elem>( mem_use, eT(1) );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+Col<eT>::Col(const arma_fixed_indicator&, const uword in_n_elem, const eT* in_mem)
+  : Mat<eT>(arma_fixed_indicator(), in_n_elem, 1, 1, in_mem)
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+#ifdef ARMA_EXTRA_COL_MEAT
+  #include ARMA_INCFILE_WRAP(ARMA_EXTRA_COL_MEAT)
+#endif
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Cube_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,404 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Cube
+//! @{
+
+
+
+struct Cube_prealloc
+  {
+  static const uword mat_ptrs_size = 4;
+  static const uword mem_n_elem    = 64;
+  };
+
+
+
+//! Dense cube class
+
+template<typename eT>
+class Cube : public BaseCube< eT, Cube<eT> >
+  {
+  public:
+  
+  typedef eT                                elem_type; //!< the type of elements stored in the cube
+  typedef typename get_pod_type<eT>::result pod_type;  //!< if eT is non-complex, pod_type is same as eT. otherwise, pod_type is the underlying type used by std::complex
+  
+  const uword  n_rows;       //!< number of rows in each slice (read-only)
+  const uword  n_cols;       //!< number of columns in each slice (read-only)
+  const uword  n_elem_slice; //!< number of elements in each slice (read-only)
+  const uword  n_slices;     //!< number of slices in the cube (read-only)
+  const uword  n_elem;       //!< number of elements in the cube (read-only)
+  const uword  mem_state;
+  
+  // mem_state = 0: normal cube that can be resized; 
+  // mem_state = 1: use auxiliary memory until change in the number of elements is requested;  
+  // mem_state = 2: use auxiliary memory and don't allow the number of elements to be changed; 
+  // mem_state = 3: fixed size (e.g. via template based size specification).
+  
+  
+  arma_aligned const Mat<eT>** const mat_ptrs; //!< pointer to an array containing pointers to Mat instances (one for each slice)
+  arma_aligned const eT*       const mem;      //!< pointer to the memory used by the cube (memory is read-only)
+  
+  protected:
+  arma_align_mem Mat<eT>* mat_ptrs_local[ Cube_prealloc::mat_ptrs_size ];
+  arma_align_mem eT            mem_local[ Cube_prealloc::mem_n_elem    ];
+  
+  
+  public:
+  
+  inline ~Cube();
+  inline  Cube();
+  
+  inline Cube(const uword in_rows, const uword in_cols, const uword in_slices);
+  
+  inline Cube(      eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices, const bool copy_aux_mem = true, const bool strict = true);
+  inline Cube(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices);
+  
+  arma_inline const Cube&  operator=(const eT val);
+  arma_inline const Cube& operator+=(const eT val);
+  arma_inline const Cube& operator-=(const eT val);
+  arma_inline const Cube& operator*=(const eT val);
+  arma_inline const Cube& operator/=(const eT val);
+  
+  inline                   Cube(const Cube& m);
+  inline const Cube&  operator=(const Cube& m);
+  inline const Cube& operator+=(const Cube& m);
+  inline const Cube& operator-=(const Cube& m);
+  inline const Cube& operator%=(const Cube& m);
+  inline const Cube& operator/=(const Cube& m);
+  
+  template<typename T1, typename T2>
+  inline explicit Cube(const BaseCube<pod_type,T1>& A, const BaseCube<pod_type,T2>& B);
+  
+  inline                   Cube(const subview_cube<eT>& X);
+  inline const Cube&  operator=(const subview_cube<eT>& X);
+  inline const Cube& operator+=(const subview_cube<eT>& X);
+  inline const Cube& operator-=(const subview_cube<eT>& X);
+  inline const Cube& operator%=(const subview_cube<eT>& X);
+  inline const Cube& operator/=(const subview_cube<eT>& X);
+  
+  arma_inline       Mat<eT>& slice(const uword in_slice);
+  arma_inline const Mat<eT>& slice(const uword in_slice) const;
+  
+  arma_inline       subview_cube<eT> slices(const uword in_slice1, const uword in_slice2);
+  arma_inline const subview_cube<eT> slices(const uword in_slice1, const uword in_slice2) const;
+  
+  arma_inline       subview_cube<eT> subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2);
+  arma_inline const subview_cube<eT> subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2) const;
+  
+  inline            subview_cube<eT> subcube(const span& row_span, const span& col_span, const span& slice_span);
+  inline      const subview_cube<eT> subcube(const span& row_span, const span& col_span, const span& slice_span) const;
+  
+  inline            subview_cube<eT> operator()(const span& row_span, const span& col_span, const span& slice_span);
+  inline      const subview_cube<eT> operator()(const span& row_span, const span& col_span, const span& slice_span) const;
+  
+  
+  inline void shed_slice(const uword slice_num);
+  
+  inline void shed_slices(const uword in_slice1, const uword in_slice2);
+  
+  inline void insert_slices(const uword slice_num, const uword N, const bool set_to_zero = true);
+  
+  template<typename T1>
+  inline void insert_slices(const uword row_num, const BaseCube<eT,T1>& X);
+  
+  
+  template<typename gen_type> inline                   Cube(const GenCube<eT, gen_type>& X);
+  template<typename gen_type> inline const Cube&  operator=(const GenCube<eT, gen_type>& X);
+  template<typename gen_type> inline const Cube& operator+=(const GenCube<eT, gen_type>& X);
+  template<typename gen_type> inline const Cube& operator-=(const GenCube<eT, gen_type>& X);
+  template<typename gen_type> inline const Cube& operator%=(const GenCube<eT, gen_type>& X);
+  template<typename gen_type> inline const Cube& operator/=(const GenCube<eT, gen_type>& X);
+  
+  template<typename T1, typename op_type> inline                   Cube(const OpCube<T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Cube&  operator=(const OpCube<T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Cube& operator+=(const OpCube<T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Cube& operator-=(const OpCube<T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Cube& operator%=(const OpCube<T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Cube& operator/=(const OpCube<T1, op_type>& X);
+  
+  template<typename T1, typename eop_type> inline                   Cube(const eOpCube<T1, eop_type>& X);
+  template<typename T1, typename eop_type> inline const Cube&  operator=(const eOpCube<T1, eop_type>& X);
+  template<typename T1, typename eop_type> inline const Cube& operator+=(const eOpCube<T1, eop_type>& X);
+  template<typename T1, typename eop_type> inline const Cube& operator-=(const eOpCube<T1, eop_type>& X);
+  template<typename T1, typename eop_type> inline const Cube& operator%=(const eOpCube<T1, eop_type>& X);
+  template<typename T1, typename eop_type> inline const Cube& operator/=(const eOpCube<T1, eop_type>& X);
+  
+  template<typename T1, typename op_type> inline                   Cube(const mtOpCube<eT, T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Cube&  operator=(const mtOpCube<eT, T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Cube& operator+=(const mtOpCube<eT, T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Cube& operator-=(const mtOpCube<eT, T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Cube& operator%=(const mtOpCube<eT, T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Cube& operator/=(const mtOpCube<eT, T1, op_type>& X);
+  
+  template<typename T1, typename T2, typename glue_type> inline                   Cube(const GlueCube<T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Cube&  operator=(const GlueCube<T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Cube& operator+=(const GlueCube<T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Cube& operator-=(const GlueCube<T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Cube& operator%=(const GlueCube<T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Cube& operator/=(const GlueCube<T1, T2, glue_type>& X);
+  
+  template<typename T1, typename T2, typename eglue_type> inline                   Cube(const eGlueCube<T1, T2, eglue_type>& X);
+  template<typename T1, typename T2, typename eglue_type> inline const Cube&  operator=(const eGlueCube<T1, T2, eglue_type>& X);
+  template<typename T1, typename T2, typename eglue_type> inline const Cube& operator+=(const eGlueCube<T1, T2, eglue_type>& X);
+  template<typename T1, typename T2, typename eglue_type> inline const Cube& operator-=(const eGlueCube<T1, T2, eglue_type>& X);
+  template<typename T1, typename T2, typename eglue_type> inline const Cube& operator%=(const eGlueCube<T1, T2, eglue_type>& X);
+  template<typename T1, typename T2, typename eglue_type> inline const Cube& operator/=(const eGlueCube<T1, T2, eglue_type>& X);
+  
+  template<typename T1, typename T2, typename glue_type> inline                   Cube(const mtGlueCube<eT, T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Cube&  operator=(const mtGlueCube<eT, T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Cube& operator+=(const mtGlueCube<eT, T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Cube& operator-=(const mtGlueCube<eT, T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Cube& operator%=(const mtGlueCube<eT, T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Cube& operator/=(const mtGlueCube<eT, T1, T2, glue_type>& X);
+  
+  
+  arma_inline arma_warn_unused const eT& at_alt     (const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& operator[] (const uword i);
+  arma_inline arma_warn_unused const eT& operator[] (const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& at(const uword i);
+  arma_inline arma_warn_unused const eT& at(const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& operator() (const uword i);
+  arma_inline arma_warn_unused const eT& operator() (const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& at         (const uword in_row, const uword in_col, const uword in_slice);
+  arma_inline arma_warn_unused const eT& at         (const uword in_row, const uword in_col, const uword in_slice) const;
+  
+  arma_inline arma_warn_unused       eT& operator() (const uword in_row, const uword in_col, const uword in_slice);
+  arma_inline arma_warn_unused const eT& operator() (const uword in_row, const uword in_col, const uword in_slice) const;
+  
+  arma_inline const Cube& operator++();
+  arma_inline void        operator++(int);
+  
+  arma_inline const Cube& operator--();
+  arma_inline void        operator--(int);
+  
+  arma_inline arma_warn_unused bool is_finite() const;
+  arma_inline arma_warn_unused bool is_empty()  const;
+  
+  arma_inline arma_warn_unused bool in_range(const uword i) const;
+  arma_inline arma_warn_unused bool in_range(const span& x) const;
+  
+  arma_inline arma_warn_unused bool in_range(const uword   in_row, const uword   in_col, const uword   in_slice) const;
+       inline arma_warn_unused bool in_range(const span& row_span, const span& col_span, const span& slice_span) const;
+  
+  arma_inline arma_warn_unused       eT* memptr();
+  arma_inline arma_warn_unused const eT* memptr() const;
+  
+  arma_inline arma_warn_unused       eT* slice_memptr(const uword slice);
+  arma_inline arma_warn_unused const eT* slice_memptr(const uword slice) const;
+  
+  arma_inline arma_warn_unused       eT* slice_colptr(const uword in_slice, const uword in_col);
+  arma_inline arma_warn_unused const eT* slice_colptr(const uword in_slice, const uword in_col) const;
+  
+  inline void impl_print(const std::string& extra_text) const;
+  inline void impl_print(std::ostream& user_stream, const std::string& extra_text) const;
+  
+  inline void impl_raw_print(const std::string& extra_text) const;
+  inline void impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const;
+  
+  inline void  set_size(const uword in_rows, const uword in_cols, const uword in_slices);
+  inline void   reshape(const uword in_rows, const uword in_cols, const uword in_slices, const uword dim = 0);
+  inline void    resize(const uword in_rows, const uword in_cols, const uword in_slices);
+  
+  template<typename eT2> inline void copy_size(const Cube<eT2>& m);
+  
+  
+  template<typename functor>
+  inline const Cube& transform(functor F);
+  
+  template<typename functor>
+  inline const Cube& imbue(functor F);
+  
+  
+  inline const Cube& fill(const eT val);
+  
+  inline const Cube& zeros();
+  inline const Cube& zeros(const uword in_rows, const uword in_cols, const uword in_slices);
+  
+  inline const Cube& ones();
+  inline const Cube& ones(const uword in_rows, const uword in_cols, const uword in_slices);
+  
+  inline const Cube& randu();
+  inline const Cube& randu(const uword in_rows, const uword in_cols, const uword in_slices);
+  
+  inline const Cube& randn();
+  inline const Cube& randn(const uword in_rows, const uword in_cols, const uword in_slices);
+  
+  inline void reset();
+  
+  
+  template<typename T1> inline void set_real(const BaseCube<pod_type,T1>& X);
+  template<typename T1> inline void set_imag(const BaseCube<pod_type,T1>& X);
+  
+  
+  inline arma_warn_unused eT min() const;
+  inline arma_warn_unused eT max() const;
+  
+  inline eT min(uword& index_of_min_val) const;
+  inline eT max(uword& index_of_max_val) const;
+  
+  inline eT min(uword& row_of_min_val, uword& col_of_min_val, uword& slice_of_min_val) const;
+  inline eT max(uword& row_of_max_val, uword& col_of_max_val, uword& slice_of_max_val) const;
+  
+  
+  inline bool save(const std::string   name, const file_type type = arma_binary, const bool print_status = true) const;
+  inline bool save(      std::ostream& os,   const file_type type = arma_binary, const bool print_status = true) const;
+  
+  inline bool load(const std::string   name, const file_type type = auto_detect, const bool print_status = true);
+  inline bool load(      std::istream& is,   const file_type type = auto_detect, const bool print_status = true);
+  
+  inline bool quiet_save(const std::string   name, const file_type type = arma_binary) const;
+  inline bool quiet_save(      std::ostream& os,   const file_type type = arma_binary) const;
+  
+  inline bool quiet_load(const std::string   name, const file_type type = auto_detect);
+  inline bool quiet_load(      std::istream& is,   const file_type type = auto_detect);
+  
+  
+  // iterators
+  
+  typedef       eT*       iterator;
+  typedef const eT* const_iterator;
+  
+  typedef       eT*       slice_iterator;
+  typedef const eT* const_slice_iterator;
+  
+  inline       iterator  begin();
+  inline const_iterator  begin() const;
+  inline const_iterator cbegin() const;
+  
+  inline       iterator  end();
+  inline const_iterator  end() const;
+  inline const_iterator cend() const;
+  
+  inline       slice_iterator begin_slice(const uword slice_num);
+  inline const_slice_iterator begin_slice(const uword slice_num) const;
+  
+  inline       slice_iterator end_slice(const uword slice_num);
+  inline const_slice_iterator end_slice(const uword slice_num)   const;
+  
+  inline void  clear();
+  inline bool  empty() const;
+  inline uword size()  const;
+  
+  // inline void swap(Cube& B); // TODO
+  
+  inline void steal_mem(Cube& X);  //!< don't use this unless you're writing code internal to Armadillo
+  
+  template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices> class fixed;
+  
+  
+  protected:
+  
+  inline void init_cold();
+  inline void init_warm(const uword in_rows, const uword in_cols, const uword in_slices);
+  
+  template<typename T1, typename T2>
+  inline void init(const BaseCube<pod_type,T1>& A, const BaseCube<pod_type,T2>& B);
+  
+  inline void delete_mat();
+  inline void create_mat();
+  
+  friend class glue_join;
+  friend class op_reshape;
+  friend class op_resize;
+  
+  
+  public:
+  
+  #ifdef ARMA_EXTRA_CUBE_PROTO
+    #include ARMA_INCFILE_WRAP(ARMA_EXTRA_CUBE_PROTO)
+  #endif
+  };
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
+class Cube<eT>::fixed : public Cube<eT>
+  {
+  private:
+  
+  static const uword fixed_n_elem       = fixed_n_rows * fixed_n_cols * fixed_n_slices;
+  static const uword fixed_n_elem_slice = fixed_n_rows * fixed_n_cols;
+  
+  static const bool use_extra = (fixed_n_elem > Cube_prealloc::mem_n_elem);
+  
+  arma_aligned   Mat<eT>* mat_ptrs_local_extra[ (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? fixed_n_slices : 1 ];
+  arma_align_mem eT       mem_local_extra     [ use_extra                                       ? fixed_n_elem   : 1 ];
+  
+  arma_inline void mem_setup();
+  
+  
+  public:
+  
+  inline fixed() { mem_setup(); }
+  
+  inline const Cube& operator=(const eT val) { mem_setup(); Cube<eT>::operator=(val); return *this; }
+  
+  template<typename T1>
+  inline fixed(const BaseCube<eT,T1>& A) { mem_setup(); Cube<eT>::operator=(A.get_ref()); }
+  
+  template<typename T1>
+  inline const Cube& operator=(const BaseCube<eT,T1>& A) { Cube<eT>::operator=(A.get_ref()); return *this; }
+  
+  template<typename T1, typename T2>
+  inline explicit fixed(const BaseCube<pod_type,T1>& A, const BaseCube<pod_type,T2>& B) { mem_setup(); Cube<eT>::init(A,B); }
+  
+  
+  using Cube<eT>::operator();
+  
+  
+  arma_inline arma_warn_unused       eT& operator[] (const uword i);
+  arma_inline arma_warn_unused const eT& operator[] (const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& at         (const uword i);
+  arma_inline arma_warn_unused const eT& at         (const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& operator() (const uword i);
+  arma_inline arma_warn_unused const eT& operator() (const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& at         (const uword in_row, const uword in_col, const uword in_slice);
+  arma_inline arma_warn_unused const eT& at         (const uword in_row, const uword in_col, const uword in_slice) const;
+  
+  arma_inline arma_warn_unused       eT& operator() (const uword in_row, const uword in_col, const uword in_slice);
+  arma_inline arma_warn_unused const eT& operator() (const uword in_row, const uword in_col, const uword in_slice) const;
+  };
+
+
+
+class Cube_aux
+  {
+  public:
+  
+  template<typename eT> arma_inline static void prefix_pp(Cube<eT>& x);
+  template<typename T>  arma_inline static void prefix_pp(Cube< std::complex<T> >& x);
+  
+  template<typename eT> arma_inline static void postfix_pp(Cube<eT>& x);
+  template<typename T>  arma_inline static void postfix_pp(Cube< std::complex<T> >& x);
+  
+  template<typename eT> arma_inline static void prefix_mm(Cube<eT>& x);
+  template<typename T>  arma_inline static void prefix_mm(Cube< std::complex<T> >& x);
+  
+  template<typename eT> arma_inline static void postfix_mm(Cube<eT>& x);
+  template<typename T>  arma_inline static void postfix_mm(Cube< std::complex<T> >& x);
+  
+  template<typename eT, typename T1> inline static void set_real(Cube<eT>&                out, const BaseCube<eT,T1>& X);
+  template<typename eT, typename T1> inline static void set_imag(Cube<eT>&                out, const BaseCube<eT,T1>& X);
+  
+  template<typename T,  typename T1> inline static void set_real(Cube< std::complex<T> >& out, const BaseCube< T,T1>& X);
+  template<typename T,  typename T1> inline static void set_imag(Cube< std::complex<T> >& out, const BaseCube< T,T1>& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Cube_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,3733 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Cube
+//! @{
+
+
+template<typename eT>
+inline
+Cube<eT>::~Cube()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  delete_mat();
+  
+  if(mem_state == 0)
+    {
+    if(n_elem > Cube_prealloc::mem_n_elem)
+      {
+      memory::release( access::rw(mem) );
+      }
+    }
+  
+  if(arma_config::debug == true)
+    {
+    // try to expose buggy user code that accesses deleted objects
+    access::rw(mat_ptrs) = 0;
+    access::rw(mem)      = 0;
+    }
+  
+  arma_type_check(( is_supported_elem_type<eT>::value == false ));
+  }
+
+
+
+template<typename eT>
+inline
+Cube<eT>::Cube()
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem_slice(0)
+  , n_slices(0)
+  , n_elem(0)
+  , mem_state(0)
+  , mat_ptrs()
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+//! construct the cube to have user specified dimensions
+template<typename eT>
+inline
+Cube<eT>::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices)
+  : n_rows(in_n_rows)
+  , n_cols(in_n_cols)
+  , n_elem_slice(in_n_rows*in_n_cols)
+  , n_slices(in_n_slices)
+  , n_elem(in_n_rows*in_n_cols*in_n_slices)
+  , mem_state(0)
+  , mat_ptrs()
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold();
+  }
+
+
+
+template<typename eT>
+inline
+void
+Cube<eT>::init_cold()
+  {
+  arma_extra_debug_sigprint( arma_boost::format("n_rows = %d, n_cols = %d, n_slices = %d") % n_rows % n_cols % n_slices );
+  
+  arma_debug_check
+    (
+      (
+      ( (n_rows > 0x0FFF) || (n_cols > 0x0FFF) || (n_slices > 0xFF) )
+        ? ( (float(n_rows) * float(n_cols) * float(n_slices)) > float(ARMA_MAX_UWORD) )
+        : false
+      ),
+    "Cube::init(): requested size is too large"
+    );
+  
+  if(n_elem <= Cube_prealloc::mem_n_elem)
+    {
+    access::rw(mem) = mem_local;
+    }
+  else
+    {
+    arma_extra_debug_print("Cube::init(): allocating memory");
+    
+    access::rw(mem) = memory::acquire<eT>(n_elem);
+    
+    arma_check_bad_alloc( (mem == 0), "Cube::init(): out of memory" );
+    }
+  
+  
+  if(n_elem == 0)
+    {
+    access::rw(n_rows)       = 0;
+    access::rw(n_cols)       = 0;
+    access::rw(n_elem_slice) = 0;
+    access::rw(n_slices)     = 0;
+    }
+  else
+    {
+    create_mat();
+    }
+  }
+
+
+
+//! internal cube construction; if the requested size is small enough, memory from the stack is used.
+//! otherwise memory is allocated via 'new'
+template<typename eT>
+inline
+void
+Cube<eT>::init_warm(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices)
+  {
+  arma_extra_debug_sigprint( arma_boost::format("in_n_rows = %d, in_n_cols = %d, in_n_slices = %d") % in_n_rows % in_n_cols % in_n_slices );
+  
+  if( (n_rows == in_n_rows) && (n_cols == in_n_cols) && (n_slices == in_n_slices) )
+    {
+    return;
+    }
+  
+  const uword t_mem_state = mem_state;
+  
+  bool  err_state = false;
+  char* err_msg   = 0;
+  
+  arma_debug_set_error
+    (
+    err_state,
+    err_msg,
+    (t_mem_state == 3),
+    "Cube::init(): size is fixed and hence cannot be changed"
+    );
+  
+  arma_debug_set_error
+    (
+    err_state,
+    err_msg,
+      (
+      ( (in_n_rows > 0x0FFF) || (in_n_cols > 0x0FFF) || (in_n_slices > 0xFF) )
+        ? ( (float(in_n_rows) * float(in_n_cols) * float(in_n_slices)) > float(ARMA_MAX_UWORD) )
+        : false
+      ),
+    "Cube::init(): requested size is too large"
+    );
+  
+  arma_debug_check(err_state, err_msg);
+  
+  const uword old_n_elem = n_elem;
+  const uword new_n_elem = in_n_rows * in_n_cols * in_n_slices;
+  
+  if(old_n_elem == new_n_elem)
+    {
+    delete_mat();
+    
+    if(new_n_elem > 0)
+      {
+      access::rw(n_rows)       = in_n_rows;
+      access::rw(n_cols)       = in_n_cols;
+      access::rw(n_elem_slice) = in_n_rows*in_n_cols;
+      access::rw(n_slices)     = in_n_slices;
+      
+      create_mat();
+      }
+    }
+  else
+    {
+    arma_debug_check( (t_mem_state == 2), "Cube::init(): requested size is not compatible with the size of auxiliary memory" );
+    
+    delete_mat();
+    
+    if(t_mem_state == 0)
+      {
+      if(n_elem > Cube_prealloc::mem_n_elem )
+        {
+        arma_extra_debug_print("Cube::init(): freeing memory");
+        
+        memory::release( access::rw(mem) );
+        }
+      }
+    
+    access::rw(mem_state) = 0;
+    
+    if(new_n_elem <= Cube_prealloc::mem_n_elem)
+      {
+      access::rw(mem) = mem_local;
+      }
+    else
+      {
+      arma_extra_debug_print("Cube::init(): allocating memory");
+      
+      access::rw(mem) = memory::acquire<eT>(new_n_elem);
+      
+      arma_check_bad_alloc( (mem == 0), "Cube::init(): out of memory" );
+      }
+    
+    if(new_n_elem > 0)
+      {
+      access::rw(n_rows)       = in_n_rows;
+      access::rw(n_cols)       = in_n_cols;
+      access::rw(n_elem_slice) = in_n_rows*in_n_cols;
+      access::rw(n_slices)     = in_n_slices;
+      access::rw(n_elem)       = new_n_elem;
+      
+      create_mat();
+      }
+    }
+  
+  
+  if(new_n_elem == 0)
+    {
+    access::rw(n_rows)       = 0;
+    access::rw(n_cols)       = 0;
+    access::rw(n_elem_slice) = 0;
+    access::rw(n_slices)     = 0;
+    access::rw(n_elem)       = 0;
+    }
+  }
+
+
+
+//! for constructing a complex cube out of two non-complex cubes
+template<typename eT>
+template<typename T1, typename T2>
+inline
+void
+Cube<eT>::init
+  (
+  const BaseCube<typename Cube<eT>::pod_type,T1>& X,
+  const BaseCube<typename Cube<eT>::pod_type,T2>& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type T;
+  
+  arma_type_check(( is_complex<eT>::value == false ));   //!< compile-time abort if eT isn't std::complex
+  arma_type_check(( is_complex< T>::value == true  ));   //!< compile-time abort if T is std::complex
+  
+  arma_type_check(( is_same_type< std::complex<T>, eT >::value == false ));   //!< compile-time abort if types are not compatible
+  
+  const ProxyCube<T1> PX(X.get_ref());
+  const ProxyCube<T2> PY(Y.get_ref());
+  
+  arma_debug_assert_same_size(PX, PY, "Cube()");
+  
+  const uword local_n_rows   = PX.get_n_rows();
+  const uword local_n_cols   = PX.get_n_cols();
+  const uword local_n_slices = PX.get_n_slices();
+  
+  init_warm(local_n_rows, local_n_cols, local_n_slices);
+  
+  eT* out_mem = (*this).memptr();
+  
+  const bool prefer_at_accessor = ( ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor );
+  
+  if(prefer_at_accessor == false)
+    {
+    typedef typename ProxyCube<T1>::ea_type ea_type1;
+    typedef typename ProxyCube<T2>::ea_type ea_type2;
+    
+    const uword N = n_elem;
+    
+    ea_type1 A = PX.get_ea();
+    ea_type2 B = PY.get_ea();
+        
+    for(uword i=0; i<N; ++i)
+      {
+      out_mem[i] = std::complex<T>(A[i], B[i]);
+      }
+    }
+  else
+    {
+    for(uword uslice = 0; uslice < local_n_slices; ++uslice)
+    for(uword ucol   = 0;   ucol < local_n_cols;   ++ucol  )
+    for(uword urow   = 0;   urow < local_n_rows;   ++urow  )
+      {
+      *out_mem = std::complex<T>( PX.at(urow,ucol,uslice), PY.at(urow,ucol,uslice) );
+      out_mem++;
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+Cube<eT>::delete_mat()
+  {
+  arma_extra_debug_sigprint();
+  
+  for(uword uslice = 0; uslice < n_slices; ++uslice)
+    {
+    delete access::rw(mat_ptrs[uslice]);
+    }
+  
+  if(mem_state <= 2)
+    {
+    if(n_slices > Cube_prealloc::mat_ptrs_size)
+      {
+      delete [] mat_ptrs;
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+Cube<eT>::create_mat()
+  {
+  arma_extra_debug_sigprint();
+  
+  if(mem_state <= 2)
+    {
+    if(n_slices <= Cube_prealloc::mat_ptrs_size)
+      {
+      access::rw(mat_ptrs) = const_cast< const Mat<eT>** >(mat_ptrs_local);
+      }
+    else
+      {
+      access::rw(mat_ptrs) = new(std::nothrow) const Mat<eT>*[n_slices];
+      
+      arma_check_bad_alloc( (mat_ptrs == 0), "Cube::create_mat(): out of memory" );
+      }
+    }
+  
+  for(uword uslice = 0; uslice < n_slices; ++uslice)
+    {
+    mat_ptrs[uslice] = new Mat<eT>('j', slice_memptr(uslice), n_rows, n_cols);
+    }
+  }
+
+
+
+//! Set the cube to be equal to the specified scalar.
+//! NOTE: the size of the cube will be 1x1x1
+template<typename eT>
+arma_inline
+const Cube<eT>&
+Cube<eT>::operator=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  init_warm(1,1,1);
+  access::rw(mem[0]) = val;
+  return *this;
+  }
+
+
+
+//! In-place addition of a scalar to all elements of the cube
+template<typename eT>
+arma_inline
+const Cube<eT>&
+Cube<eT>::operator+=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  arrayops::inplace_plus( memptr(), val, n_elem );
+  
+  return *this;
+  }
+
+
+
+//! In-place subtraction of a scalar from all elements of the cube
+template<typename eT>
+arma_inline
+const Cube<eT>&
+Cube<eT>::operator-=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  arrayops::inplace_minus( memptr(), val, n_elem );
+  
+  return *this;
+  }
+
+
+
+//! In-place multiplication of all elements of the cube with a scalar
+template<typename eT>
+arma_inline
+const Cube<eT>&
+Cube<eT>::operator*=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  arrayops::inplace_mul( memptr(), val, n_elem );
+  
+  return *this;
+  }
+
+
+
+//! In-place division of all elements of the cube with a scalar
+template<typename eT>
+arma_inline
+const Cube<eT>&
+Cube<eT>::operator/=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  arrayops::inplace_div( memptr(), val, n_elem );
+  
+  return *this;
+  }
+
+
+
+//! construct a cube from a given cube
+template<typename eT>
+inline
+Cube<eT>::Cube(const Cube<eT>& x)
+  : n_rows(x.n_rows)
+  , n_cols(x.n_cols)
+  , n_elem_slice(x.n_elem_slice)
+  , n_slices(x.n_slices)
+  , n_elem(x.n_elem)
+  , mem_state(0)
+  , mat_ptrs()
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  arma_extra_debug_sigprint(arma_boost::format("this = %x   in_cube = %x") % this % &x);
+  
+  init_cold();
+  
+  arrayops::copy( memptr(), x.mem, n_elem );
+  }
+
+
+
+//! construct a cube from a given cube
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::operator=(const Cube<eT>& x)
+  {
+  arma_extra_debug_sigprint(arma_boost::format("this = %x   in_cube = %x") % this % &x);
+  
+  if(this != &x)
+    {
+    init_warm(x.n_rows, x.n_cols, x.n_slices);
+    
+    arrayops::copy( memptr(), x.mem, n_elem );
+    }
+  
+  return *this;
+  }
+
+
+
+//! construct a cube from a given auxiliary array of eTs.
+//! if copy_aux_mem is true, new memory is allocated and the array is copied.
+//! if copy_aux_mem is false, the auxiliary array is used directly (without allocating memory and copying).
+//! note that in the latter case 
+//! the default is to copy the array.
+
+template<typename eT>
+inline
+Cube<eT>::Cube(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices, const bool copy_aux_mem, const bool strict)
+  : n_rows      ( aux_n_rows                          )
+  , n_cols      ( aux_n_cols                          )
+  , n_elem_slice( aux_n_rows*aux_n_cols               )
+  , n_slices    ( aux_n_slices                        )
+  , n_elem      ( aux_n_rows*aux_n_cols*aux_n_slices  )
+  , mem_state   ( copy_aux_mem ? 0 : (strict ? 2 : 1) )
+  , mat_ptrs    ( 0                                   )
+  , mem         ( copy_aux_mem ? 0 : aux_mem          )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  if(copy_aux_mem == true)
+    {
+    init_cold();
+    
+    arrayops::copy( memptr(), aux_mem, n_elem );
+    }
+  else
+    {
+    create_mat();
+    }
+  }
+
+
+
+//! construct a cube from a given auxiliary read-only array of eTs.
+//! the array is copied.
+template<typename eT>
+inline
+Cube<eT>::Cube(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices)
+  : n_rows(aux_n_rows)
+  , n_cols(aux_n_cols)
+  , n_elem_slice(aux_n_rows*aux_n_cols)
+  , n_slices(aux_n_slices)
+  , n_elem(aux_n_rows*aux_n_cols*aux_n_slices)
+  , mem_state(0)
+  , mat_ptrs()
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold();
+  
+  arrayops::copy( memptr(), aux_mem, n_elem );
+  }
+
+
+
+//! in-place cube addition
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::operator+=(const Cube<eT>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(*this, m, "addition");
+  
+  arrayops::inplace_plus( memptr(), m.memptr(), n_elem );
+  
+  return *this;
+  }
+
+
+
+//! in-place cube subtraction
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::operator-=(const Cube<eT>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(*this, m, "subtraction");
+  
+  arrayops::inplace_minus( memptr(), m.memptr(), n_elem );
+  
+  return *this;
+  }
+
+
+
+//! in-place element-wise cube multiplication
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::operator%=(const Cube<eT>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(*this, m, "element-wise multiplication");
+  
+  arrayops::inplace_mul( memptr(), m.memptr(), n_elem );
+  
+  return *this;
+  }
+
+
+
+//! in-place element-wise cube division
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::operator/=(const Cube<eT>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(*this, m, "element-wise division");
+  
+  arrayops::inplace_div( memptr(), m.memptr(), n_elem );
+  
+  return *this;
+  }
+
+
+
+//! for constructing a complex cube out of two non-complex cubes
+template<typename eT>
+template<typename T1, typename T2>
+inline
+Cube<eT>::Cube
+  (
+  const BaseCube<typename Cube<eT>::pod_type,T1>& A,
+  const BaseCube<typename Cube<eT>::pod_type,T2>& B
+  )
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem_slice(0)
+  , n_slices(0)
+  , n_elem(0)
+  , mem_state(0)
+  , mat_ptrs()
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init(A,B);
+  }
+
+
+
+//! construct a cube from a subview_cube instance (e.g. construct a cube from a delayed subcube operation)
+template<typename eT>
+inline
+Cube<eT>::Cube(const subview_cube<eT>& X)
+  : n_rows(X.n_rows)
+  , n_cols(X.n_cols)
+  , n_elem_slice(X.n_elem_slice)
+  , n_slices(X.n_slices)
+  , n_elem(X.n_elem)
+  , mem_state(0)
+  , mat_ptrs()
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold();
+  
+  subview_cube<eT>::extract(*this, X);
+  }
+
+
+
+//! construct a cube from a subview_cube instance (e.g. construct a cube from a delayed subcube operation)
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::operator=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool alias = (this == &(X.m));
+  
+  if(alias == false)
+    {
+    init_warm(X.n_rows, X.n_cols, X.n_slices);
+    
+    subview_cube<eT>::extract(*this, X);
+    }
+  else
+    {
+    Cube<eT> tmp(X);
+    
+    steal_mem(tmp);
+    }
+  
+  return *this;
+  }
+
+
+
+//! in-place cube addition (using a subcube on the right-hand-side)
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::operator+=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_cube<eT>::plus_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place cube subtraction (using a subcube on the right-hand-side)
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::operator-=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_cube<eT>::minus_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place element-wise cube mutiplication (using a subcube on the right-hand-side)
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::operator%=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_cube<eT>::schur_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place element-wise cube division (using a subcube on the right-hand-side)
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::operator/=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_cube<eT>::div_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! provide the reference to the matrix representing a single slice
+template<typename eT>
+arma_inline
+Mat<eT>&
+Cube<eT>::slice(const uword in_slice)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_slice >= n_slices),
+    "Cube::slice(): index out of bounds"
+    );
+  
+  return const_cast< Mat<eT>& >( *(mat_ptrs[in_slice]) );
+  }
+
+
+
+//! provide the reference to the matrix representing a single slice
+template<typename eT>
+arma_inline
+const Mat<eT>&
+Cube<eT>::slice(const uword in_slice) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_slice >= n_slices),
+    "Cube::slice(): index out of bounds"
+    );
+   
+  return *(mat_ptrs[in_slice]);
+  }
+
+
+
+//! creation of subview_cube (subcube comprised of specified slices)
+template<typename eT>
+arma_inline
+subview_cube<eT>
+Cube<eT>::slices(const uword in_slice1, const uword in_slice2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_slice1 > in_slice2) || (in_slice2 >= n_slices),
+    "Cube::slices(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subcube_n_slices = in_slice2 - in_slice1 + 1;
+  
+  return subview_cube<eT>(*this, 0, 0, in_slice1, n_rows, n_cols, subcube_n_slices);
+  }
+
+
+
+//! creation of subview_cube (subcube comprised of specified slices)
+template<typename eT>
+arma_inline
+const subview_cube<eT>
+Cube<eT>::slices(const uword in_slice1, const uword in_slice2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_slice1 > in_slice2) || (in_slice2 >= n_slices),
+    "Cube::rows(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subcube_n_slices = in_slice2 - in_slice1 + 1;
+  
+  return subview_cube<eT>(*this, 0, 0, in_slice1, n_rows, n_cols, subcube_n_slices);
+  }
+
+
+
+//! creation of subview_cube (generic subcube)
+template<typename eT>
+arma_inline
+subview_cube<eT>
+Cube<eT>::subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 >  in_row2) || (in_col1 >  in_col2) || (in_slice1 >  in_slice2) ||
+    (in_row2 >= n_rows)  || (in_col2 >= n_cols)  || (in_slice2 >= n_slices),
+    "Cube::subcube(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subcube_n_rows   = in_row2   - in_row1   + 1;
+  const uword subcube_n_cols   = in_col2   - in_col1   + 1;
+  const uword subcube_n_slices = in_slice2 - in_slice1 + 1;
+  
+  return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices);
+  }
+
+
+
+//! creation of subview_cube (generic subcube)
+template<typename eT>
+arma_inline
+const subview_cube<eT>
+Cube<eT>::subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 >  in_row2) || (in_col1 >  in_col2) || (in_slice1 >  in_slice2) ||
+    (in_row2 >= n_rows)  || (in_col2 >= n_cols)  || (in_slice2 >= n_slices),
+    "Cube::subcube(): indices out of bounds or incorrectly used"
+    );
+    
+  const uword subcube_n_rows   = in_row2   - in_row1   + 1;
+  const uword subcube_n_cols   = in_col2   - in_col1   + 1;
+  const uword subcube_n_slices = in_slice2 - in_slice1 + 1;
+  
+  return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices);
+  }
+
+
+
+//! creation of subview_cube (generic subcube)
+template<typename eT>
+inline
+subview_cube<eT>
+Cube<eT>::subcube(const span& row_span, const span& col_span, const span& slice_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all   = row_span.whole;
+  const bool col_all   = col_span.whole;
+  const bool slice_all = slice_span.whole;
+  
+  const uword local_n_rows   = n_rows;
+  const uword local_n_cols   = n_cols;
+  const uword local_n_slices = n_slices;
+  
+  const uword in_row1          = row_all   ? 0              : row_span.a;
+  const uword in_row2          =                              row_span.b;
+  const uword subcube_n_rows   = row_all   ? local_n_rows   : in_row2 - in_row1 + 1;
+  
+  const uword in_col1          = col_all   ? 0              : col_span.a;
+  const uword in_col2          =                              col_span.b;
+  const uword subcube_n_cols   = col_all   ? local_n_cols   : in_col2 - in_col1 + 1;
+  
+  const uword in_slice1        = slice_all ? 0              : slice_span.a;
+  const uword in_slice2        =                              slice_span.b;
+  const uword subcube_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1;
+  
+  arma_debug_check
+    (
+    ( row_all   ? false : ((in_row1   >  in_row2)   || (in_row2   >= local_n_rows))   )
+    ||
+    ( col_all   ? false : ((in_col1   >  in_col2)   || (in_col2   >= local_n_cols))   )
+    ||
+    ( slice_all ? false : ((in_slice1 >  in_slice2) || (in_slice2 >= local_n_slices)) )
+    ,
+    "Cube::subcube(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices);
+  }
+
+
+
+//! creation of subview_cube (generic subcube)
+template<typename eT>
+inline
+const subview_cube<eT>
+Cube<eT>::subcube(const span& row_span, const span& col_span, const span& slice_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all   = row_span.whole;
+  const bool col_all   = col_span.whole;
+  const bool slice_all = slice_span.whole;
+  
+  const uword local_n_rows   = n_rows;
+  const uword local_n_cols   = n_cols;
+  const uword local_n_slices = n_slices;
+  
+  const uword in_row1          = row_all   ? 0              : row_span.a;
+  const uword in_row2          =                              row_span.b;
+  const uword subcube_n_rows   = row_all   ? local_n_rows   : in_row2 - in_row1 + 1;
+  
+  const uword in_col1          = col_all   ? 0              : col_span.a;
+  const uword in_col2          =                              col_span.b;
+  const uword subcube_n_cols   = col_all   ? local_n_cols   : in_col2 - in_col1 + 1;
+  
+  const uword in_slice1        = slice_all ? 0              : slice_span.a;
+  const uword in_slice2        =                              slice_span.b;
+  const uword subcube_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1;
+  
+  arma_debug_check
+    (
+    ( row_all   ? false : ((in_row1   >  in_row2)   || (in_row2   >= local_n_rows))   )
+    ||
+    ( col_all   ? false : ((in_col1   >  in_col2)   || (in_col2   >= local_n_cols))   )
+    ||
+    ( slice_all ? false : ((in_slice1 >  in_slice2) || (in_slice2 >= local_n_slices)) )
+    ,
+    "Cube::subcube(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices);
+  }
+
+
+
+template<typename eT>
+inline
+subview_cube<eT>
+Cube<eT>::operator()(const span& row_span, const span& col_span, const span& slice_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).subcube(row_span, col_span, slice_span);
+  }
+
+
+
+template<typename eT>
+inline
+const subview_cube<eT>
+Cube<eT>::operator()(const span& row_span, const span& col_span, const span& slice_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).subcube(row_span, col_span, slice_span);
+  }
+
+
+
+//! remove specified slice
+template<typename eT>
+inline
+void
+Cube<eT>::shed_slice(const uword slice_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( slice_num >= n_slices, "Cube::shed_slice(): index out of bounds");
+  
+  shed_slices(slice_num, slice_num);
+  }
+
+
+
+//! remove specified slices
+template<typename eT>
+inline
+void
+Cube<eT>::shed_slices(const uword in_slice1, const uword in_slice2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_slice1 > in_slice2) || (in_slice2 >= n_slices),
+    "Cube::shed_slices(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword n_keep_front = in_slice1;
+  const uword n_keep_back  = n_slices - (in_slice2 + 1);
+  
+  Cube<eT> X(n_rows, n_cols, n_keep_front + n_keep_back);
+  
+  if(n_keep_front > 0)
+    {
+    X.slices( 0, (n_keep_front-1) ) = slices( 0, (in_slice1-1) );
+    }
+  
+  if(n_keep_back > 0)
+    {
+    X.slices( n_keep_front,  (n_keep_front+n_keep_back-1) ) = slices( (in_slice2+1), (n_slices-1) );
+    }
+  
+  steal_mem(X);
+  }
+
+
+
+//! insert N slices at the specified slice position,
+//! optionally setting the elements of the inserted slices to zero
+template<typename eT>
+inline
+void
+Cube<eT>::insert_slices(const uword slice_num, const uword N, const bool set_to_zero)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword t_n_slices = n_slices;
+  
+  const uword A_n_slices = slice_num;
+  const uword B_n_slices = t_n_slices - slice_num;
+  
+  // insertion at slice_num == n_slices is in effect an append operation
+  arma_debug_check( (slice_num > t_n_slices), "Cube::insert_slices(): index out of bounds");
+  
+  if(N > 0)
+    {
+    Cube<eT> out(n_rows, n_cols, t_n_slices + N);
+    
+    if(A_n_slices > 0)
+      {
+      out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1);
+      }
+    
+    if(B_n_slices > 0)
+      {
+      out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices-1);
+      }
+    
+    if(set_to_zero == true)
+      {
+      //out.slices(slice_num, slice_num + N - 1).zeros();
+      
+      for(uword i=slice_num; i < (slice_num + N); ++i)
+        {
+        out.slice(i).zeros();
+        }
+      }
+    
+    steal_mem(out);
+    }
+  }
+
+
+
+//! insert the given object at the specified slice position; 
+//! the given object must have the same number of rows and columns as the cube
+template<typename eT>
+template<typename T1>
+inline
+void
+Cube<eT>::insert_slices(const uword slice_num, const BaseCube<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap_cube<T1> tmp(X.get_ref());
+  const Cube<eT>& C   = tmp.M;
+  
+  const uword N = C.n_slices;
+  
+  const uword t_n_slices = n_slices;
+  
+  const uword A_n_slices = slice_num;
+  const uword B_n_slices = t_n_slices - slice_num;
+  
+  // insertion at slice_num == n_slices is in effect an append operation
+  arma_debug_check( (slice_num  >  t_n_slices), "Cube::insert_slices(): index out of bounds");
+  
+  arma_debug_check
+    (
+    ( (C.n_rows != n_rows) || (C.n_cols != n_cols) ),
+    "Cube::insert_slices(): given object has incompatible dimensions"
+    );
+  
+  if(N > 0)
+    {
+    Cube<eT> out(n_rows, n_cols, t_n_slices + N);
+    
+    if(A_n_slices > 0)
+      {
+      out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1);
+      }
+    
+    if(B_n_slices > 0)
+      {
+      out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices - 1);
+      }
+    
+    out.slices(slice_num, slice_num + N - 1) = C;
+    
+    steal_mem(out);
+    }
+  }
+
+
+
+//! create a cube from OpCube, i.e. run the previously delayed unary operations
+template<typename eT>
+template<typename gen_type>
+inline
+Cube<eT>::Cube(const GenCube<eT, gen_type>& X)
+  : n_rows(X.n_rows)
+  , n_cols(X.n_cols)
+  , n_elem_slice(X.n_rows*X.n_cols)
+  , n_slices(X.n_slices)
+  , n_elem(X.n_rows*X.n_cols*X.n_slices)
+  , mem_state(0)
+  , mat_ptrs()
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold();
+  
+  X.apply(*this);
+  }
+
+
+
+template<typename eT>
+template<typename gen_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator=(const GenCube<eT, gen_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  init_warm(X.n_rows, X.n_cols, X.n_slices);
+  
+  X.apply(*this);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename gen_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator+=(const GenCube<eT, gen_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  X.apply_inplace_plus(*this);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename gen_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator-=(const GenCube<eT, gen_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  X.apply_inplace_minus(*this);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename gen_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator%=(const GenCube<eT, gen_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  X.apply_inplace_schur(*this);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename gen_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator/=(const GenCube<eT, gen_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  X.apply_inplace_div(*this);
+  
+  return *this;
+  }
+
+
+
+//! create a cube from OpCube, i.e. run the previously delayed unary operations
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+Cube<eT>::Cube(const OpCube<T1, op_type>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem_slice(0)
+  , n_slices(0)
+  , n_elem(0)
+  , mem_state(0)
+  , mat_ptrs()
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  op_type::apply(*this, X);
+  }
+
+
+
+//! create a cube from OpCube, i.e. run the previously delayed unary operations
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator=(const OpCube<T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  op_type::apply(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place cube addition, with the right-hand-side operand having delayed operations
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator+=(const OpCube<T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator+=(m);
+  }
+
+
+
+//! in-place cube subtraction, with the right-hand-side operand having delayed operations
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator-=(const OpCube<T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator-=(m);
+  }
+
+
+
+//! in-place cube element-wise multiplication, with the right-hand-side operand having delayed operations
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator%=(const OpCube<T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator%=(m);
+  }
+
+
+
+//! in-place cube element-wise division, with the right-hand-side operand having delayed operations
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator/=(const OpCube<T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator/=(m);
+  }
+
+
+
+//! create a cube from eOpCube, i.e. run the previously delayed unary operations
+template<typename eT>
+template<typename T1, typename eop_type>
+inline
+Cube<eT>::Cube(const eOpCube<T1, eop_type>& X)
+  : n_rows(X.get_n_rows())
+  , n_cols(X.get_n_cols())
+  , n_elem_slice(X.get_n_elem_slice())
+  , n_slices(X.get_n_slices())
+  , n_elem(X.get_n_elem())
+  , mem_state(0)
+  , mat_ptrs()
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  init_cold();
+  
+  eop_type::apply(*this, X);
+  }
+
+
+
+//! create a cube from eOpCube, i.e. run the previously delayed unary operations
+template<typename eT>
+template<typename T1, typename eop_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator=(const eOpCube<T1, eop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const bool bad_alias = ( X.P.has_subview  &&  X.P.is_alias(*this) );
+  
+  if(bad_alias == false)
+    {
+    init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices());
+    
+    eop_type::apply(*this, X);
+    }
+  else
+    {
+    Cube<eT> tmp(X);
+    
+    steal_mem(tmp);
+    }
+  
+  return *this;
+  }
+
+
+
+//! in-place cube addition, with the right-hand-side operand having delayed operations
+template<typename eT>
+template<typename T1, typename eop_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator+=(const eOpCube<T1, eop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  eop_type::apply_inplace_plus(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place cube subtraction, with the right-hand-side operand having delayed operations
+template<typename eT>
+template<typename T1, typename eop_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator-=(const eOpCube<T1, eop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  eop_type::apply_inplace_minus(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place cube element-wise multiplication, with the right-hand-side operand having delayed operations
+template<typename eT>
+template<typename T1, typename eop_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator%=(const eOpCube<T1, eop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+
+  eop_type::apply_inplace_schur(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place cube element-wise division, with the right-hand-side operand having delayed operations
+template<typename eT>
+template<typename T1, typename eop_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator/=(const eOpCube<T1, eop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+
+  eop_type::apply_inplace_div(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+Cube<eT>::Cube(const mtOpCube<eT, T1, op_type>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem_slice(0)
+  , n_slices(0)
+  , n_elem(0)
+  , mem_state(0)
+  , mat_ptrs()
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  op_type::apply(*this, X);
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator=(const mtOpCube<eT, T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  op_type::apply(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator+=(const mtOpCube<eT, T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator+=(m);
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator-=(const mtOpCube<eT, T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator-=(m);
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator%=(const mtOpCube<eT, T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator%=(m);
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator/=(const mtOpCube<eT, T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator/=(m);
+  }
+
+
+
+//! create a cube from Glue, i.e. run the previously delayed binary operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+Cube<eT>::Cube(const GlueCube<T1, T2, glue_type>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem_slice(0)
+  , n_slices(0)
+  , n_elem(0)
+  , mem_state(0)
+  , mat_ptrs()
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  this->operator=(X);
+  }
+
+
+
+//! create a cube from Glue, i.e. run the previously delayed binary operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator=(const GlueCube<T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  glue_type::apply(*this, X);
+  
+  return *this;
+  }
+
+
+//! in-place cube addition, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator+=(const GlueCube<T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator+=(m);
+  }
+
+
+
+//! in-place cube subtraction, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator-=(const GlueCube<T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator-=(m);
+  }
+
+
+
+//! in-place cube element-wise multiplication, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator%=(const GlueCube<T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator%=(m);
+  }
+
+
+
+//! in-place cube element-wise division, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator/=(const GlueCube<T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator/=(m);
+  }
+
+
+
+//! create a cube from eGlue, i.e. run the previously delayed binary operations
+template<typename eT>
+template<typename T1, typename T2, typename eglue_type>
+inline
+Cube<eT>::Cube(const eGlueCube<T1, T2, eglue_type>& X)
+  : n_rows(X.get_n_rows())
+  , n_cols(X.get_n_cols())
+  , n_elem_slice(X.get_n_elem_slice())
+  , n_slices(X.get_n_slices())
+  , n_elem(X.get_n_elem())
+  , mem_state(0)
+  , mat_ptrs()
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  init_cold();
+  
+  eglue_type::apply(*this, X);
+  }
+
+
+
+//! create a cube from Glue, i.e. run the previously delayed binary operations
+template<typename eT>
+template<typename T1, typename T2, typename eglue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator=(const eGlueCube<T1, T2, eglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  const bool bad_alias = ( (X.P1.has_subview  &&  X.P1.is_alias(*this))  ||  (X.P2.has_subview  &&  X.P2.is_alias(*this)) );
+  
+  if(bad_alias == false)
+    {
+    init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices());
+    
+    eglue_type::apply(*this, X);
+    }
+  else
+    {
+    Cube<eT> tmp(X);
+    
+    steal_mem(tmp);
+    }
+  
+  return *this;
+  }
+
+
+
+//! in-place cube addition, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename eglue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator+=(const eGlueCube<T1, T2, eglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  eglue_type::apply_inplace_plus(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place cube subtraction, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename eglue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator-=(const eGlueCube<T1, T2, eglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  eglue_type::apply_inplace_minus(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place cube element-wise multiplication, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename eglue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator%=(const eGlueCube<T1, T2, eglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  eglue_type::apply_inplace_schur(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place cube element-wise division, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename eglue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator/=(const eGlueCube<T1, T2, eglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  eglue_type::apply_inplace_div(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+Cube<eT>::Cube(const mtGlueCube<eT, T1, T2, glue_type>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem_slice(0)
+  , n_slices(0)
+  , n_elem(0)
+  , mem_state(0)
+  , mat_ptrs()
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  glue_type::apply(*this, X);
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator=(const mtGlueCube<eT, T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  glue_type::apply(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator+=(const mtGlueCube<eT, T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator+=(m);
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator-=(const mtGlueCube<eT, T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator-=(m);
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator%=(const mtGlueCube<eT, T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator%=(m);
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Cube<eT>&
+Cube<eT>::operator/=(const mtGlueCube<eT, T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Cube<eT> m(X);
+  
+  return (*this).operator/=(m);
+  }
+
+
+
+//! linear element accessor (treats the cube as a vector); no bounds check; assumes memory is aligned
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Cube<eT>::at_alt(const uword i) const
+  {
+  const eT* mem_aligned = mem;
+  memory::mark_as_aligned(mem_aligned);
+  
+  return mem_aligned[i];
+  }
+
+
+
+//! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Cube<eT>::operator() (const uword i)
+  {
+  arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds");
+  return access::rw(mem[i]);
+  }
+
+
+
+//! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Cube<eT>::operator() (const uword i) const
+  {
+  arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds");
+  return mem[i];
+  }
+
+
+//! linear element accessor (treats the cube as a vector); no bounds check.  
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Cube<eT>::operator[] (const uword i)
+  {
+  return access::rw(mem[i]);
+  }
+
+
+
+//! linear element accessor (treats the cube as a vector); no bounds check
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Cube<eT>::operator[] (const uword i) const
+  {
+  return mem[i];
+  }
+
+
+
+//! linear element accessor (treats the cube as a vector); no bounds check.  
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Cube<eT>::at(const uword i)
+  {
+  return access::rw(mem[i]);
+  }
+
+
+
+//! linear element accessor (treats the cube as a vector); no bounds check
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Cube<eT>::at(const uword i) const
+  {
+  return mem[i];
+  }
+
+
+
+//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Cube<eT>::operator() (const uword in_row, const uword in_col, const uword in_slice)
+  {
+  arma_debug_check
+    (
+    (in_row >= n_rows) ||
+    (in_col >= n_cols) ||
+    (in_slice >= n_slices)
+    ,
+    "Cube::operator(): index out of bounds"
+    );
+
+  return access::rw(mem[in_slice*n_elem_slice + in_col*n_rows + in_row]);
+  }
+
+
+
+//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Cube<eT>::operator() (const uword in_row, const uword in_col, const uword in_slice) const
+  {
+  arma_debug_check
+    (
+    (in_row >= n_rows) ||
+    (in_col >= n_cols) ||
+    (in_slice >= n_slices)
+    ,
+    "Cube::operator(): index out of bounds"
+    );
+
+  return mem[in_slice*n_elem_slice + in_col*n_rows + in_row];
+  }
+
+
+
+//! element accessor; no bounds check
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice)
+  {
+  return access::rw( mem[in_slice*n_elem_slice + in_col*n_rows + in_row] );
+  }
+
+
+
+//! element accessor; no bounds check
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice) const
+  {
+  return mem[in_slice*n_elem_slice + in_col*n_rows + in_row];
+  }
+
+
+
+//! prefix ++
+template<typename eT>
+arma_inline
+const Cube<eT>&
+Cube<eT>::operator++()
+  {
+  Cube_aux::prefix_pp(*this);
+  return *this;
+  }
+
+
+
+//! postfix ++  (must not return the object by reference)
+template<typename eT>
+arma_inline
+void
+Cube<eT>::operator++(int)
+  {
+  Cube_aux::postfix_pp(*this);
+  }
+
+
+
+//! prefix --
+template<typename eT>
+arma_inline
+const Cube<eT>&
+Cube<eT>::operator--()
+  {
+  Cube_aux::prefix_mm(*this);
+  return *this;
+  }
+
+
+
+//! postfix --  (must not return the object by reference)
+template<typename eT>
+arma_inline
+void
+Cube<eT>::operator--(int)
+  {
+  Cube_aux::postfix_mm(*this);
+  }
+
+
+
+//! returns true if all of the elements are finite
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Cube<eT>::is_finite() const
+  {
+  return arrayops::is_finite( memptr(), n_elem );
+  }
+
+
+
+//! returns true if the cube has no elements
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Cube<eT>::is_empty() const
+  {
+  return (n_elem == 0);
+  }
+
+
+
+//! returns true if the given index is currently in range
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Cube<eT>::in_range(const uword i) const
+  {
+  return (i < n_elem);
+  }
+
+
+
+//! returns true if the given start and end indices are currently in range
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Cube<eT>::in_range(const span& x) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(x.whole == true)
+    {
+    return true;
+    }
+  else
+    {
+    const uword a = x.a;
+    const uword b = x.b;
+    
+    return ( (a <= b) && (b < n_elem) );
+    }
+  }
+
+
+
+//! returns true if the given location is currently in range
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Cube<eT>::in_range(const uword in_row, const uword in_col, const uword in_slice) const
+  {
+  return ( (in_row < n_rows) && (in_col < n_cols) && (in_slice < n_slices) );
+  }
+
+
+
+template<typename eT>
+inline
+arma_warn_unused
+bool
+Cube<eT>::in_range(const span& row_span, const span& col_span, const span& slice_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword in_row1   = row_span.a;
+  const uword in_row2   = row_span.b;
+  
+  const uword in_col1   = col_span.a;
+  const uword in_col2   = col_span.b;
+  
+  const uword in_slice1 = slice_span.a;
+  const uword in_slice2 = slice_span.b;
+  
+  
+  const bool rows_ok   = row_span.whole   ? true : ( (in_row1   <= in_row2)   && (in_row2   < n_rows)   );
+  const bool cols_ok   = col_span.whole   ? true : ( (in_col1   <= in_col2)   && (in_col2   < n_cols)   );
+  const bool slices_ok = slice_span.whole ? true : ( (in_slice1 <= in_slice2) && (in_slice2 < n_slices) );
+  
+  
+  return ( (rows_ok == true) && (cols_ok == true) && (slices_ok == true) );
+  }
+
+
+
+//! returns a pointer to array of eTs used by the cube
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT*
+Cube<eT>::memptr()
+  {
+  return const_cast<eT*>(mem);
+  }
+
+
+
+//! returns a pointer to array of eTs used by the cube
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT*
+Cube<eT>::memptr() const
+  {
+  return mem;
+  }
+
+
+
+//! returns a pointer to array of eTs used by the specified slice in the cube
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT*
+Cube<eT>::slice_memptr(const uword uslice)
+  {
+  return const_cast<eT*>( &mem[ uslice*n_elem_slice ] );
+  }
+
+
+
+//! returns a pointer to array of eTs used by the specified slice in the cube
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT*
+Cube<eT>::slice_memptr(const uword uslice) const
+  {
+  return &mem[ uslice*n_elem_slice ];
+  }
+
+
+
+//! returns a pointer to array of eTs used by the specified slice in the cube
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT*
+Cube<eT>::slice_colptr(const uword uslice, const uword col)
+  {
+  return const_cast<eT*>( &mem[ uslice*n_elem_slice + col*n_rows] );
+  }
+
+
+
+//! returns a pointer to array of eTs used by the specified slice in the cube
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT*
+Cube<eT>::slice_colptr(const uword uslice, const uword col) const
+  {
+  return &mem[ uslice*n_elem_slice + col*n_rows ];
+  }
+
+
+
+//! print contents of the cube (to the cout stream),
+//! optionally preceding with a user specified line of text.
+//! the precision and cell width are modified.
+//! on return, the stream's state are restored to their original values.
+template<typename eT>
+inline
+void
+Cube<eT>::impl_print(const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(extra_text.length() != 0)
+    {
+    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
+    }
+  
+  arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, true);
+  }
+
+
+//! print contents of the cube to a user specified stream,
+//! optionally preceding with a user specified line of text.
+//! the precision and cell width are modified.
+//! on return, the stream's state are restored to their original values.
+template<typename eT>
+inline
+void
+Cube<eT>::impl_print(std::ostream& user_stream, const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(extra_text.length() != 0)
+    {
+    user_stream << extra_text << '\n';
+    }
+  
+  arma_ostream::print(user_stream, *this, true);
+  }
+
+
+
+//! print contents of the cube (to the cout stream),
+//! optionally preceding with a user specified line of text.
+//! the stream's state are used as is and are not modified
+//! (i.e. the precision and cell width are not modified).
+template<typename eT>
+inline
+void
+Cube<eT>::impl_raw_print(const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(extra_text.length() != 0)
+    {
+    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
+    }
+  
+  arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, false);
+  }
+
+
+
+//! print contents of the cube to a user specified stream,
+//! optionally preceding with a user specified line of text.
+//! the stream's state are used as is and are not modified.
+//! (i.e. the precision and cell width are not modified).
+template<typename eT>
+inline
+void
+Cube<eT>::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(extra_text.length() != 0)
+    {
+    user_stream << extra_text << '\n';
+    }
+  
+  arma_ostream::print(user_stream, *this, false);
+  }
+
+
+
+//! change the cube to have user specified dimensions (data is not preserved)
+template<typename eT>
+inline
+void
+Cube<eT>::set_size(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices)
+  {
+  arma_extra_debug_sigprint();
+  
+  init_warm(in_n_rows, in_n_cols, in_n_slices);
+  }
+
+
+
+//! change the cube to have user specified dimensions (data is preserved)
+template<typename eT>
+inline
+void
+Cube<eT>::reshape(const uword in_rows, const uword in_cols, const uword in_slices, const uword dim)
+  {
+  arma_extra_debug_sigprint();
+  
+  *this = arma::reshape(*this, in_rows, in_cols, in_slices, dim);
+  }
+
+
+
+//! change the cube to have user specified dimensions (data is preserved)
+template<typename eT>
+inline
+void
+Cube<eT>::resize(const uword in_rows, const uword in_cols, const uword in_slices)
+  {
+  arma_extra_debug_sigprint();
+  
+  *this = arma::resize(*this, in_rows, in_cols, in_slices);
+  }
+
+
+
+//! change the cube (without preserving data) to have the same dimensions as the given cube 
+template<typename eT>
+template<typename eT2>
+inline
+void
+Cube<eT>::copy_size(const Cube<eT2>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  init_warm(m.n_rows, m.n_cols, m.n_slices);
+  }
+
+
+
+//! transform each element in the cube using a functor
+template<typename eT>
+template<typename functor>
+inline
+const Cube<eT>&
+Cube<eT>::transform(functor F)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT* out_mem = memptr();
+  
+  const uword N = n_elem;
+  
+  uword ii, jj;
+  
+  for(ii=0, jj=1; jj < N; ii+=2, jj+=2)
+    {
+    eT tmp_ii = out_mem[ii];
+    eT tmp_jj = out_mem[jj];
+    
+    tmp_ii = eT( F(tmp_ii) );
+    tmp_jj = eT( F(tmp_jj) );
+    
+    out_mem[ii] = tmp_ii;
+    out_mem[jj] = tmp_jj;
+    }
+  
+  if(ii < N)
+    {
+    out_mem[ii] = eT( F(out_mem[ii]) );
+    }
+  
+  return *this;
+  }
+
+
+
+//! imbue (fill) the cube with values provided by a functor
+template<typename eT>
+template<typename functor>
+inline
+const Cube<eT>&
+Cube<eT>::imbue(functor F)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT* out_mem = memptr();
+  
+  const uword N = n_elem;
+  
+  uword ii, jj;
+  
+  for(ii=0, jj=1; jj < N; ii+=2, jj+=2)
+    {
+    const eT tmp_ii = eT( F() );
+    const eT tmp_jj = eT( F() );
+    
+    out_mem[ii] = tmp_ii;
+    out_mem[jj] = tmp_jj;
+    }
+  
+  if(ii < N)
+    {
+    out_mem[ii] = eT( F() );
+    }
+  
+  return *this;
+  }
+
+
+
+//! fill the cube with the specified value
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::fill(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  arrayops::inplace_set( memptr(), val, n_elem );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::zeros()
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).fill(eT(0));
+  }
+
+
+
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::zeros(const uword in_rows, const uword in_cols, const uword in_slices)
+  {
+  arma_extra_debug_sigprint();
+  
+  set_size(in_rows, in_cols, in_slices);
+  
+  return (*this).fill(eT(0));
+  }
+
+
+
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::ones()
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).fill(eT(1));
+  }
+
+
+
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::ones(const uword in_rows, const uword in_cols, const uword in_slices)
+  {
+  arma_extra_debug_sigprint();
+  
+  set_size(in_rows, in_cols, in_slices);
+  
+  return (*this).fill(eT(1));
+  }
+
+
+
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::randu()
+  {
+  arma_extra_debug_sigprint();
+  
+  eop_aux_randu<eT>::fill( memptr(), n_elem );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::randu(const uword in_rows, const uword in_cols, const uword in_slices)
+  {
+  arma_extra_debug_sigprint();
+  
+  set_size(in_rows, in_cols, in_slices);
+  
+  return (*this).randu();
+  }
+
+
+
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::randn()
+  {
+  arma_extra_debug_sigprint();
+  
+  eop_aux_randn<eT>::fill( memptr(), n_elem );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const Cube<eT>&
+Cube<eT>::randn(const uword in_rows, const uword in_cols, const uword in_slices)
+  {
+  arma_extra_debug_sigprint();
+  
+  set_size(in_rows, in_cols, in_slices);
+  
+  return (*this).randn();
+  }
+
+
+
+template<typename eT>
+inline
+void
+Cube<eT>::reset()
+  {
+  arma_extra_debug_sigprint();
+  
+  init_warm(0,0,0);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+Cube<eT>::set_real(const BaseCube<typename Cube<eT>::pod_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Cube_aux::set_real(*this, X);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+Cube<eT>::set_imag(const BaseCube<typename Cube<eT>::pod_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Cube_aux::set_imag(*this, X);
+  }
+
+
+
+template<typename eT>
+inline
+arma_warn_unused
+eT
+Cube<eT>::min() const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (n_elem == 0), "min(): object has no elements" );
+  
+  return op_min::direct_min(memptr(), n_elem);
+  }
+
+
+
+template<typename eT>
+inline
+arma_warn_unused
+eT
+Cube<eT>::max() const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (n_elem == 0), "max(): object has no elements" );
+  
+  return op_max::direct_max(memptr(), n_elem);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+Cube<eT>::min(uword& index_of_min_val) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (n_elem == 0), "min(): object has no elements" );
+  
+  return op_min::direct_min(memptr(), n_elem, index_of_min_val);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+Cube<eT>::max(uword& index_of_max_val) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (n_elem == 0), "max(): object has no elements" );
+  
+  return op_max::direct_max(memptr(), n_elem, index_of_max_val);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+Cube<eT>::min(uword& row_of_min_val, uword& col_of_min_val, uword& slice_of_min_val) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (n_elem == 0), "min(): object has no elements" );
+  
+  uword i;
+  
+  eT val = op_min::direct_min(memptr(), n_elem, i);
+  
+  const uword in_slice = i / n_elem_slice;
+  const uword offset   = in_slice * n_elem_slice;
+  const uword j        = i - offset;
+  
+    row_of_min_val = j % n_rows;
+    col_of_min_val = j / n_rows;
+  slice_of_min_val = in_slice;
+  
+  return val;
+  }
+
+
+
+template<typename eT>
+inline
+eT
+Cube<eT>::max(uword& row_of_max_val, uword& col_of_max_val, uword& slice_of_max_val) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (n_elem == 0), "max(): object has no elements" );
+  
+  uword i;
+  
+  eT val = op_max::direct_max(memptr(), n_elem, i);
+  
+  const uword in_slice = i / n_elem_slice;
+  const uword offset   = in_slice * n_elem_slice;
+  const uword j        = i - offset;
+  
+    row_of_max_val = j % n_rows;
+    col_of_max_val = j / n_rows;
+  slice_of_max_val = in_slice;
+  
+  return val;
+  }
+
+
+
+//! save the cube to a file
+template<typename eT>
+inline
+bool
+Cube<eT>::save(const std::string name, const file_type type, const bool print_status) const
+  {
+  arma_extra_debug_sigprint();
+  
+  bool save_okay;
+  
+  switch(type)
+    {
+    case raw_ascii:
+      save_okay = diskio::save_raw_ascii(*this, name);
+      break;
+    
+    case arma_ascii:
+      save_okay = diskio::save_arma_ascii(*this, name);
+      break;
+    
+    case raw_binary:
+      save_okay = diskio::save_raw_binary(*this, name);
+      break;
+    
+    case arma_binary:
+      save_okay = diskio::save_arma_binary(*this, name);
+      break;
+    
+    case ppm_binary:
+      save_okay = diskio::save_ppm_binary(*this, name);
+      break;
+
+    case hdf5_binary:
+      save_okay = diskio::save_hdf5_binary(*this, name);
+      break;
+    
+    default:
+      arma_warn(print_status, "Cube::save(): unsupported file type");
+      save_okay = false;
+    }
+  
+  arma_warn( (print_status && (save_okay == false)), "Cube::save(): couldn't write to ", name);
+  
+  return save_okay;
+  }
+
+
+
+//! save the cube to a stream
+template<typename eT>
+inline
+bool
+Cube<eT>::save(std::ostream& os, const file_type type, const bool print_status) const
+  {
+  arma_extra_debug_sigprint();
+  
+  bool save_okay;
+  
+  switch(type)
+    {
+    case raw_ascii:
+      save_okay = diskio::save_raw_ascii(*this, os);
+      break;
+    
+    case arma_ascii:
+      save_okay = diskio::save_arma_ascii(*this, os);
+      break;
+    
+    case raw_binary:
+      save_okay = diskio::save_raw_binary(*this, os);
+      break;
+    
+    case arma_binary:
+      save_okay = diskio::save_arma_binary(*this, os);
+      break;
+    
+    case ppm_binary:
+      save_okay = diskio::save_ppm_binary(*this, os);
+      break;
+    
+    default:
+      arma_warn(print_status, "Cube::save(): unsupported file type");
+      save_okay = false;
+    }
+  
+  arma_warn( (print_status && (save_okay == false)), "Cube::save(): couldn't write to given stream");
+  
+  return save_okay;
+  }
+
+
+
+//! load a cube from a file
+template<typename eT>
+inline
+bool
+Cube<eT>::load(const std::string name, const file_type type, const bool print_status)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay;
+  std::string err_msg;
+  
+  switch(type)
+    {
+    case auto_detect:
+      load_okay = diskio::load_auto_detect(*this, name, err_msg);
+      break;
+    
+    case raw_ascii:
+      load_okay = diskio::load_raw_ascii(*this, name, err_msg);
+      break;
+    
+    case arma_ascii:
+      load_okay = diskio::load_arma_ascii(*this, name, err_msg);
+      break;
+    
+    case raw_binary:
+      load_okay = diskio::load_raw_binary(*this, name, err_msg);
+      break;
+    
+    case arma_binary:
+      load_okay = diskio::load_arma_binary(*this, name, err_msg);
+      break;
+    
+    case ppm_binary:
+      load_okay = diskio::load_ppm_binary(*this, name, err_msg);
+      break;
+
+    case hdf5_binary:
+      load_okay = diskio::load_hdf5_binary(*this, name, err_msg);
+      break;
+    
+    default:
+      arma_warn(print_status, "Cube::load(): unsupported file type");
+      load_okay = false;
+    }
+  
+  if( (print_status == true) && (load_okay == false) )
+    {
+    if(err_msg.length() > 0)
+      {
+      arma_warn(true, "Cube::load(): ", err_msg, name);
+      }
+    else
+      {
+      arma_warn(true, "Cube::load(): couldn't read ", name);
+      }
+    }
+  
+  if(load_okay == false)
+    {
+    (*this).reset();
+    }
+    
+  return load_okay;
+  }
+
+
+
+//! load a cube from a stream
+template<typename eT>
+inline
+bool
+Cube<eT>::load(std::istream& is, const file_type type, const bool print_status)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay;
+  std::string err_msg;
+  
+  switch(type)
+    {
+    case auto_detect:
+      load_okay = diskio::load_auto_detect(*this, is, err_msg);
+      break;
+    
+    case raw_ascii:
+      load_okay = diskio::load_raw_ascii(*this, is, err_msg);
+      break;
+    
+    case arma_ascii:
+      load_okay = diskio::load_arma_ascii(*this, is, err_msg);
+      break;
+    
+    case raw_binary:
+      load_okay = diskio::load_raw_binary(*this, is, err_msg);
+      break;
+    
+    case arma_binary:
+      load_okay = diskio::load_arma_binary(*this, is, err_msg);
+      break;
+    
+    case ppm_binary:
+      load_okay = diskio::load_ppm_binary(*this, is, err_msg);
+      break;
+    
+    default:
+      arma_warn(print_status, "Cube::load(): unsupported file type");
+      load_okay = false;
+    }
+  
+  
+  if( (print_status == true) && (load_okay == false) )
+    {
+    if(err_msg.length() > 0)
+      {
+      arma_warn(true, "Cube::load(): ", err_msg, "the given stream");
+      }
+    else
+      {
+      arma_warn(true, "Cube::load(): couldn't load from the given stream");
+      }
+    }
+  
+  if(load_okay == false)
+    {
+    (*this).reset();
+    }
+    
+  return load_okay;
+  }
+
+
+
+//! save the cube to a file, without printing any error messages
+template<typename eT>
+inline
+bool
+Cube<eT>::quiet_save(const std::string name, const file_type type) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).save(name, type, false);
+  }
+
+
+
+//! save the cube to a stream, without printing any error messages
+template<typename eT>
+inline
+bool
+Cube<eT>::quiet_save(std::ostream& os, const file_type type) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).save(os, type, false);
+  }
+
+
+
+//! load a cube from a file, without printing any error messages
+template<typename eT>
+inline
+bool
+Cube<eT>::quiet_load(const std::string name, const file_type type)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).load(name, type, false);
+  }
+
+
+
+//! load a cube from a stream, without printing any error messages
+template<typename eT>
+inline
+bool
+Cube<eT>::quiet_load(std::istream& is, const file_type type)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).load(is, type, false);
+  }
+
+
+
+template<typename eT>
+inline
+typename Cube<eT>::iterator
+Cube<eT>::begin()
+  {
+  arma_extra_debug_sigprint();
+  
+  return memptr();
+  }
+
+
+
+template<typename eT>
+inline
+typename Cube<eT>::const_iterator
+Cube<eT>::begin() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return memptr();
+  }
+
+
+
+template<typename eT>
+inline
+typename Cube<eT>::const_iterator
+Cube<eT>::cbegin() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return memptr();
+  }
+
+
+
+template<typename eT>
+inline
+typename Cube<eT>::iterator
+Cube<eT>::end()
+  {
+  arma_extra_debug_sigprint();
+  
+  return memptr() + n_elem;
+  }
+
+
+
+template<typename eT>
+inline
+typename Cube<eT>::const_iterator
+Cube<eT>::end() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return memptr() + n_elem;
+  }
+
+
+
+template<typename eT>
+inline
+typename Cube<eT>::const_iterator
+Cube<eT>::cend() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return memptr() + n_elem;
+  }
+
+
+
+template<typename eT>
+inline
+typename Cube<eT>::slice_iterator
+Cube<eT>::begin_slice(const uword slice_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds");
+  
+  return slice_memptr(slice_num);
+  }
+
+
+
+template<typename eT>
+inline
+typename Cube<eT>::const_slice_iterator
+Cube<eT>::begin_slice(const uword slice_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds");
+  
+  return slice_memptr(slice_num);
+  }
+
+
+
+template<typename eT>
+inline
+typename Cube<eT>::slice_iterator
+Cube<eT>::end_slice(const uword slice_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds");
+  
+  return slice_memptr(slice_num) + n_elem_slice;
+  }
+
+
+
+template<typename eT>
+inline
+typename Cube<eT>::const_slice_iterator
+Cube<eT>::end_slice(const uword slice_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds");
+  
+  return slice_memptr(slice_num) + n_elem_slice;
+  }
+
+
+
+//! resets this cube to an empty matrix
+template<typename eT>
+inline
+void
+Cube<eT>::clear()
+  {
+  reset();
+  }
+
+
+
+//! returns true if the cube has no elements
+template<typename eT>
+inline
+bool
+Cube<eT>::empty() const
+  {
+  return (n_elem == 0);
+  }
+
+
+
+//! returns the number of elements in this cube
+template<typename eT>
+inline
+uword
+Cube<eT>::size() const
+  {
+  return n_elem;
+  }
+
+
+
+// template<typename eT>
+// inline
+// void
+// Cube<eT>::swap(Cube<eT>& B)
+//   {
+//   // TODO
+//   }
+
+
+
+//! try to steal the memory from a given cube; 
+//! if memory can't be stolen, copy the given cube
+template<typename eT>
+inline
+void
+Cube<eT>::steal_mem(Cube<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(this != &x)
+    {
+    if( (x.mem_state == 0) && (x.n_elem > Cube_prealloc::mem_n_elem) )
+      {
+      reset();
+      
+      const uword x_n_slices = x.n_slices;
+      
+      access::rw(n_rows)       = x.n_rows;
+      access::rw(n_cols)       = x.n_cols;
+      access::rw(n_elem_slice) = x.n_elem_slice;
+      access::rw(n_slices)     = x_n_slices;
+      access::rw(n_elem)       = x.n_elem;
+      access::rw(mem)          = x.mem;
+      
+      if(x_n_slices > Cube_prealloc::mat_ptrs_size)
+        {
+        access::rw(  mat_ptrs) = x.mat_ptrs;
+        access::rw(x.mat_ptrs) = 0;
+        }
+      else
+        {
+        access::rw(mat_ptrs) = const_cast< const Mat<eT>** >(mat_ptrs_local);
+        
+        for(uword i=0; i < x_n_slices; ++i)
+          {
+            mat_ptrs[i] = x.mat_ptrs[i];
+          x.mat_ptrs[i] = 0;
+          }
+        }
+      
+      access::rw(x.n_rows)       = 0;
+      access::rw(x.n_cols)       = 0;
+      access::rw(x.n_elem_slice) = 0;
+      access::rw(x.n_slices)     = 0;
+      access::rw(x.n_elem)       = 0;
+      access::rw(x.mem)          = 0;
+      }
+    else
+      {
+      (*this).operator=(x);
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
+arma_inline
+void
+Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::mem_setup()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  if(fixed_n_elem > 0)
+    {
+    access::rw(Cube<eT>::n_rows)       = fixed_n_rows;
+    access::rw(Cube<eT>::n_cols)       = fixed_n_cols;
+    access::rw(Cube<eT>::n_elem_slice) = fixed_n_rows * fixed_n_cols;
+    access::rw(Cube<eT>::n_slices)     = fixed_n_slices;
+    access::rw(Cube<eT>::n_elem)       = fixed_n_elem;
+    access::rw(Cube<eT>::mem_state)    = 3;
+    access::rw(Cube<eT>::mat_ptrs)     = const_cast< const Mat<eT>** >( \
+                                         (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? mat_ptrs_local_extra : mat_ptrs_local );
+    access::rw(Cube<eT>::mem)          = (fixed_n_elem   > Cube_prealloc::mem_n_elem)    ? mem_local_extra      : mem_local;
+    
+    create_mat();
+    }
+  else
+    {
+    access::rw(Cube<eT>::n_rows)       = 0;
+    access::rw(Cube<eT>::n_cols)       = 0;
+    access::rw(Cube<eT>::n_elem_slice) = 0;
+    access::rw(Cube<eT>::n_slices)     = 0;
+    access::rw(Cube<eT>::n_elem)       = 0;
+    access::rw(Cube<eT>::mem_state)    = 3;
+    access::rw(Cube<eT>::mat_ptrs)     = 0;
+    access::rw(Cube<eT>::mem)          = 0;
+    }
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
+arma_inline
+arma_warn_unused
+eT&
+Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::operator[] (const uword i)
+  {
+  return (use_extra) ? mem_local_extra[i] : mem_local[i];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
+arma_inline
+arma_warn_unused
+const eT&
+Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::operator[] (const uword i) const
+  {
+  return (use_extra) ? mem_local_extra[i] : mem_local[i];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
+arma_inline
+arma_warn_unused
+eT&
+Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::at(const uword i)
+  {
+  return (use_extra) ? mem_local_extra[i] : mem_local[i];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
+arma_inline
+arma_warn_unused
+const eT&
+Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::at(const uword i) const
+  {
+  return (use_extra) ? mem_local_extra[i] : mem_local[i];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
+arma_inline
+arma_warn_unused
+eT&
+Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::operator() (const uword i)
+  {
+  arma_debug_check( (i >= fixed_n_elem), "Cube::operator(): index out of bounds");
+  
+  return (use_extra) ? mem_local_extra[i] : mem_local[i];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
+arma_inline
+arma_warn_unused
+const eT&
+Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::operator() (const uword i) const
+  {
+  arma_debug_check( (i >= fixed_n_elem), "Cube::operator(): index out of bounds");
+  
+  return (use_extra) ? mem_local_extra[i] : mem_local[i];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
+arma_inline
+arma_warn_unused
+eT&
+Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::at(const uword in_row, const uword in_col, const uword in_slice)
+  {
+  const uword i = in_slice*fixed_n_elem_slice + in_col*fixed_n_rows + in_row;
+  
+  return (use_extra) ? mem_local_extra[i] : mem_local[i];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
+arma_inline
+arma_warn_unused
+const eT&
+Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::at(const uword in_row, const uword in_col, const uword in_slice) const
+  {
+  const uword i = in_slice*fixed_n_elem_slice + in_col*fixed_n_rows + in_row;
+  
+  return (use_extra) ? mem_local_extra[i] : mem_local[i];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
+arma_inline
+arma_warn_unused
+eT&
+Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::operator() (const uword in_row, const uword in_col, const uword in_slice)
+  {
+  arma_debug_check
+    (
+    (in_row   >= fixed_n_rows  ) ||
+    (in_col   >= fixed_n_cols  ) ||
+    (in_slice >= fixed_n_slices)
+    ,
+    "operator(): index out of bounds"
+    );
+  
+  const uword i = in_slice*fixed_n_elem_slice + in_col*fixed_n_rows + in_row;
+  
+  return (use_extra) ? mem_local_extra[i] : mem_local[i];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
+arma_inline
+arma_warn_unused
+const eT&
+Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::operator() (const uword in_row, const uword in_col, const uword in_slice) const
+  {
+  arma_debug_check
+    (
+    (in_row   >= fixed_n_rows  ) ||
+    (in_col   >= fixed_n_cols  ) ||
+    (in_slice >= fixed_n_slices)
+    ,
+    "Cube::operator(): index out of bounds"
+    );
+  
+  const uword i = in_slice*fixed_n_elem_slice + in_col*fixed_n_rows + in_row;
+  
+  return (use_extra) ? mem_local_extra[i] : mem_local[i];
+  }
+
+
+
+//! prefix ++
+template<typename eT>
+arma_inline
+void
+Cube_aux::prefix_pp(Cube<eT>& x)
+  {
+        eT*   memptr = x.memptr();
+  const uword n_elem = x.n_elem;
+  
+  uword i,j;
+
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    ++(memptr[i]);
+    ++(memptr[j]);
+    }
+  
+  if(i < n_elem)
+    {
+    ++(memptr[i]);
+    }
+  }
+
+
+
+//! prefix ++ for complex numbers (work around for limitations of the std::complex class)
+template<typename T>
+arma_inline
+void
+Cube_aux::prefix_pp(Cube< std::complex<T> >& x)
+  {
+  x += T(1);
+  }
+
+
+
+//! postfix ++
+template<typename eT>
+arma_inline
+void
+Cube_aux::postfix_pp(Cube<eT>& x)
+  {
+        eT* memptr = x.memptr();
+  const uword n_elem = x.n_elem;
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    (memptr[i])++;
+    (memptr[j])++;
+    }
+  
+  if(i < n_elem)
+    {
+    (memptr[i])++;
+    }
+  }
+
+
+
+//! postfix ++ for complex numbers (work around for limitations of the std::complex class)
+template<typename T>
+arma_inline
+void
+Cube_aux::postfix_pp(Cube< std::complex<T> >& x)
+  {
+  x += T(1);
+  }
+
+
+
+//! prefix --
+template<typename eT>
+arma_inline
+void
+Cube_aux::prefix_mm(Cube<eT>& x)
+  {
+        eT* memptr = x.memptr();
+  const uword n_elem = x.n_elem;
+
+  uword i,j;
+
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    --(memptr[i]);
+    --(memptr[j]);
+    }
+  
+  if(i < n_elem)
+    {
+    --(memptr[i]);
+    }
+  }
+
+
+
+//! prefix -- for complex numbers (work around for limitations of the std::complex class)
+template<typename T>
+arma_inline
+void
+Cube_aux::prefix_mm(Cube< std::complex<T> >& x)
+  {
+  x -= T(1);
+  }
+
+
+
+//! postfix --
+template<typename eT>
+arma_inline
+void
+Cube_aux::postfix_mm(Cube<eT>& x)
+  {
+        eT* memptr = x.memptr();
+  const uword n_elem = x.n_elem;
+
+  uword i,j;
+
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    (memptr[i])--;
+    (memptr[j])--;
+    }
+  
+  if(i < n_elem)
+    {
+    (memptr[i])--;
+    }
+  }
+
+
+
+//! postfix ++ for complex numbers (work around for limitations of the std::complex class)
+template<typename T>
+arma_inline
+void
+Cube_aux::postfix_mm(Cube< std::complex<T> >& x)
+  {
+  x -= T(1);
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+Cube_aux::set_real(Cube<eT>& out, const BaseCube<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap_cube<T1> tmp(X.get_ref());
+  const Cube<eT>& A   = tmp.M;
+  
+  arma_debug_assert_same_size( out, A, "Cube::set_real()" );
+  
+  out = A;
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+Cube_aux::set_imag(Cube<eT>&, const BaseCube<eT,T1>&)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T, typename T1>
+inline
+void
+Cube_aux::set_real(Cube< std::complex<T> >& out, const BaseCube<T,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<T> eT;
+  
+  const ProxyCube<T1> P(X.get_ref());
+  
+  const uword local_n_rows   = P.get_n_rows();
+  const uword local_n_cols   = P.get_n_cols();
+  const uword local_n_slices = P.get_n_slices();
+  
+  arma_debug_assert_same_size
+    (
+    out.n_rows,   out.n_cols,   out.n_slices,
+    local_n_rows, local_n_cols, local_n_slices,
+    "Cube::set_real()"
+    );
+  
+  eT* out_mem = out.memptr();
+  
+  if(ProxyCube<T1>::prefer_at_accessor == false)
+    {
+    typedef typename ProxyCube<T1>::ea_type ea_type;
+    
+    ea_type A = P.get_ea();
+    
+    const uword N = out.n_elem;
+    
+    for(uword i=0; i<N; ++i)
+      {
+      //out_mem[i].real() = PA[i];
+      out_mem[i] = std::complex<T>( A[i], out_mem[i].imag() );
+      }
+    }
+  else
+    {
+    for(uword slice = 0; slice < local_n_slices; ++slice)
+    for(uword col   = 0; col   < local_n_cols;   ++col  )
+    for(uword row   = 0; row   < local_n_rows;   ++row  )
+      {
+      (*out_mem) = std::complex<T>( P.at(row,col,slice), (*out_mem).imag() );
+      out_mem++;
+      }
+    }
+  }
+
+
+
+template<typename T, typename T1>
+inline
+void
+Cube_aux::set_imag(Cube< std::complex<T> >& out, const BaseCube<T,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<T> eT;
+  
+  const ProxyCube<T1> P(X.get_ref());
+  
+  const uword local_n_rows   = P.get_n_rows();
+  const uword local_n_cols   = P.get_n_cols();
+  const uword local_n_slices = P.get_n_slices();
+  
+  arma_debug_assert_same_size
+    (
+    out.n_rows,   out.n_cols,   out.n_slices,
+    local_n_rows, local_n_cols, local_n_slices,
+    "Cube::set_imag()"
+    );
+  
+  eT* out_mem = out.memptr();
+  
+  if(ProxyCube<T1>::prefer_at_accessor == false)
+    {
+    typedef typename ProxyCube<T1>::ea_type ea_type;
+    
+    ea_type A = P.get_ea();
+    
+    const uword N = out.n_elem;
+    
+    for(uword i=0; i<N; ++i)
+      {
+      //out_mem[i].imag() = PA[i];
+      out_mem[i] = std::complex<T>( out_mem[i].real(), A[i] );
+      }
+    }
+  else
+    {
+    for(uword slice = 0; slice < local_n_slices; ++slice)
+    for(uword col   = 0; col   < local_n_cols;   ++col  )
+    for(uword row   = 0; row   < local_n_rows;   ++row  )
+      {
+      (*out_mem) = std::complex<T>( (*out_mem).real(), P.at(row,col,slice) );
+      out_mem++;
+      }
+    }
+  }
+
+
+
+#ifdef ARMA_EXTRA_CUBE_MEAT
+  #include ARMA_INCFILE_WRAP(ARMA_EXTRA_CUBE_MEAT)
+#endif
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/GenCube_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,47 @@
+// Copyright (C) 2011-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2011-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup GenCube
+//! @{
+
+
+//! support class for generator functions (eg. zeros, randu, randn, ...)
+template<typename eT, typename gen_type>
+class GenCube : public BaseCube<eT, GenCube<eT, gen_type> >
+  {
+  public:
+  
+  typedef          eT                              elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool is_simple          = (is_same_type<gen_type, gen_ones_full>::value) || (is_same_type<gen_type, gen_zeros>::value); 
+  
+  arma_aligned const uword n_rows;
+  arma_aligned const uword n_cols;
+  arma_aligned const uword n_slices;
+  
+  arma_inline  GenCube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices);
+  arma_inline ~GenCube();
+  
+  arma_inline static eT generate();
+  
+  arma_inline eT operator[] (const uword i)                                       const;
+  arma_inline eT at         (const uword row, const uword col, const uword slice) const;
+  arma_inline eT at_alt     (const uword i)                                       const;
+  
+  inline void apply              (Cube<eT>& out) const;
+  inline void apply_inplace_plus (Cube<eT>& out) const;
+  inline void apply_inplace_minus(Cube<eT>& out) const;
+  inline void apply_inplace_schur(Cube<eT>& out) const;
+  inline void apply_inplace_div  (Cube<eT>& out) const;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/GenCube_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,229 @@
+// Copyright (C) 2011-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2011-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Gen
+//! @{
+
+
+
+template<typename eT, typename gen_type>
+arma_inline
+GenCube<eT, gen_type>::GenCube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices)
+  : n_rows  (in_n_rows  )
+  , n_cols  (in_n_cols  )
+  , n_slices(in_n_slices)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT, typename gen_type>
+arma_inline
+GenCube<eT, gen_type>::~GenCube()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT, typename gen_type>
+arma_inline
+eT
+GenCube<eT, gen_type>::generate()
+  {
+       if(is_same_type<gen_type, gen_ones_full>::value == true) { return eT(1);                   }
+  else if(is_same_type<gen_type, gen_zeros    >::value == true) { return eT(0);                   }
+  else if(is_same_type<gen_type, gen_randu    >::value == true) { return eT(eop_aux_randu<eT>()); }
+  else if(is_same_type<gen_type, gen_randn    >::value == true) { return eT(eop_aux_randn<eT>()); }
+  else                                                          { return eT();                    }
+  }
+
+
+
+template<typename eT, typename gen_type>
+arma_inline
+eT
+GenCube<eT, gen_type>::operator[](const uword) const
+  {
+  return GenCube<eT, gen_type>::generate();
+  }
+
+
+
+template<typename eT, typename gen_type>
+arma_inline
+eT
+GenCube<eT, gen_type>::at(const uword, const uword, const uword) const
+  {
+  return GenCube<eT, gen_type>::generate();
+  }
+
+
+
+template<typename eT, typename gen_type>
+arma_inline
+eT
+GenCube<eT, gen_type>::at_alt(const uword) const
+  {
+  return GenCube<eT, gen_type>::generate();
+  }
+
+
+
+template<typename eT, typename gen_type>
+inline
+void
+GenCube<eT, gen_type>::apply(Cube<eT>& out) const
+  {
+  arma_extra_debug_sigprint();
+  
+  // NOTE: we're assuming that the cube has already been set to the correct size;
+  // this is done by either the Cube contructor or operator=()
+  
+       if(is_same_type<gen_type, gen_ones_full>::value == true) { out.ones();  }
+  else if(is_same_type<gen_type, gen_zeros    >::value == true) { out.zeros(); }
+  else if(is_same_type<gen_type, gen_randu    >::value == true) { out.randu(); }
+  else if(is_same_type<gen_type, gen_randn    >::value == true) { out.randn(); }
+  }
+
+
+
+template<typename eT, typename gen_type>
+inline
+void
+GenCube<eT, gen_type>::apply_inplace_plus(Cube<eT>& out) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "addition");
+  
+  
+        eT*   out_mem = out.memptr();
+  const uword n_elem  = out.n_elem;
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = GenCube<eT, gen_type>::generate();
+    const eT tmp_j = GenCube<eT, gen_type>::generate();
+    
+    out_mem[i] += tmp_i;
+    out_mem[j] += tmp_j;
+    }
+  
+  if(i < n_elem)
+    {
+    out_mem[i] += GenCube<eT, gen_type>::generate();
+    }
+  }
+
+
+
+
+template<typename eT, typename gen_type>
+inline
+void
+GenCube<eT, gen_type>::apply_inplace_minus(Cube<eT>& out) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "subtraction");
+  
+  
+        eT*   out_mem = out.memptr();
+  const uword n_elem  = out.n_elem;
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = GenCube<eT, gen_type>::generate();
+    const eT tmp_j = GenCube<eT, gen_type>::generate();
+    
+    out_mem[i] -= tmp_i;
+    out_mem[j] -= tmp_j;
+    }
+  
+  if(i < n_elem)
+    {
+    out_mem[i] -= GenCube<eT, gen_type>::generate();
+    }
+  }
+
+
+
+
+template<typename eT, typename gen_type>
+inline
+void
+GenCube<eT, gen_type>::apply_inplace_schur(Cube<eT>& out) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise multiplication");
+  
+  
+        eT*   out_mem = out.memptr();
+  const uword n_elem  = out.n_elem;
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = GenCube<eT, gen_type>::generate();
+    const eT tmp_j = GenCube<eT, gen_type>::generate();
+    
+    out_mem[i] *= tmp_i;
+    out_mem[j] *= tmp_j;
+    }
+  
+  if(i < n_elem)
+    {
+    out_mem[i] *= GenCube<eT, gen_type>::generate();
+    }
+  }
+
+
+
+
+template<typename eT, typename gen_type>
+inline
+void
+GenCube<eT, gen_type>::apply_inplace_div(Cube<eT>& out) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise division");
+  
+  
+        eT*   out_mem = out.memptr();
+  const uword n_elem  = out.n_elem;
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = GenCube<eT, gen_type>::generate();
+    const eT tmp_j = GenCube<eT, gen_type>::generate();
+    
+    out_mem[i] /= tmp_i;
+    out_mem[j] /= tmp_j;
+    }
+  
+  if(i < n_elem)
+    {
+    out_mem[i] /= GenCube<eT, gen_type>::generate();
+    }
+  }
+
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Gen_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,49 @@
+// Copyright (C) 2011-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2011-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Gen
+//! @{
+
+
+//! support class for generator functions (eg. zeros, randu, randn, ...)
+template<typename T1, typename gen_type>
+class Gen : public Base<typename T1::elem_type, Gen<T1, gen_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool prefer_at_accessor = (is_same_type<gen_type, gen_ones_diag>::value) ? true : false;
+  static const bool is_simple          = (is_same_type<gen_type, gen_ones_full>::value) || (is_same_type<gen_type, gen_zeros>::value); 
+  
+  static const bool is_row = T1::is_row;
+  static const bool is_col = T1::is_col;
+  
+  arma_aligned const uword n_rows;
+  arma_aligned const uword n_cols;
+  
+  arma_inline  Gen(const uword in_n_rows, const uword in_n_cols);
+  arma_inline ~Gen();
+  
+  arma_inline static elem_type generate();
+  
+  arma_inline elem_type operator[] (const uword ii)                   const;
+  arma_inline elem_type at         (const uword row, const uword col) const;
+  arma_inline elem_type at_alt     (const uword ii)                   const;
+  
+  inline void apply              (Mat<elem_type>& out) const;
+  inline void apply_inplace_plus (Mat<elem_type>& out) const;
+  inline void apply_inplace_minus(Mat<elem_type>& out) const;
+  inline void apply_inplace_schur(Mat<elem_type>& out) const;
+  inline void apply_inplace_div  (Mat<elem_type>& out) const;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Gen_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,310 @@
+// Copyright (C) 2011-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2011-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Gen
+//! @{
+
+
+
+template<typename T1, typename gen_type>
+arma_inline
+Gen<T1, gen_type>::Gen(const uword in_n_rows, const uword in_n_cols)
+  : n_rows(in_n_rows)
+  , n_cols(in_n_cols)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename gen_type>
+arma_inline
+Gen<T1, gen_type>::~Gen()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename gen_type>
+arma_inline
+typename T1::elem_type
+Gen<T1, gen_type>::generate()
+  {
+  typedef typename T1::elem_type eT;
+  
+       if(is_same_type<gen_type, gen_ones_full>::value == true) { return eT(1);                   }
+  else if(is_same_type<gen_type, gen_zeros    >::value == true) { return eT(0);                   }
+  else if(is_same_type<gen_type, gen_randu    >::value == true) { return eT(eop_aux_randu<eT>()); }
+  else if(is_same_type<gen_type, gen_randn    >::value == true) { return eT(eop_aux_randn<eT>()); }
+  else                                                          { return eT();                    }
+  }
+
+
+
+template<typename T1, typename gen_type>
+arma_inline
+typename T1::elem_type
+Gen<T1, gen_type>::operator[](const uword ii) const
+  {
+  typedef typename T1::elem_type eT;
+  
+  if(is_same_type<gen_type, gen_ones_diag>::value == true)
+    {
+    return ((ii % n_rows) == (ii / n_rows)) ? eT(1) : eT(0);
+    }
+  else
+    {
+    return Gen<T1, gen_type>::generate();
+    }
+  }
+
+
+
+template<typename T1, typename gen_type>
+arma_inline
+typename T1::elem_type
+Gen<T1, gen_type>::at(const uword row, const uword col) const
+  {
+  typedef typename T1::elem_type eT;
+  
+  if(is_same_type<gen_type, gen_ones_diag>::value == true)
+    {
+    return (row == col) ? eT(1) : eT(0);
+    }
+  else
+    {
+    return Gen<T1, gen_type>::generate();
+    }
+  }
+
+
+
+template<typename T1, typename gen_type>
+arma_inline
+typename T1::elem_type
+Gen<T1, gen_type>::at_alt(const uword ii) const
+  {
+  return operator[](ii);
+  }
+
+
+
+template<typename T1, typename gen_type>
+inline
+void
+Gen<T1, gen_type>::apply(Mat<typename T1::elem_type>& out) const
+  {
+  arma_extra_debug_sigprint();
+  
+  // NOTE: we're assuming that the matrix has already been set to the correct size;
+  // this is done by either the Mat contructor or operator=()
+  
+       if(is_same_type<gen_type, gen_ones_diag>::value == true) { out.eye();   }
+  else if(is_same_type<gen_type, gen_ones_full>::value == true) { out.ones();  }
+  else if(is_same_type<gen_type, gen_zeros    >::value == true) { out.zeros(); }
+  else if(is_same_type<gen_type, gen_randu    >::value == true) { out.randu(); }
+  else if(is_same_type<gen_type, gen_randn    >::value == true) { out.randn(); }
+  }
+
+
+
+template<typename T1, typename gen_type>
+inline
+void
+Gen<T1, gen_type>::apply_inplace_plus(Mat<typename T1::elem_type>& out) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "addition");
+  
+  typedef typename T1::elem_type eT;
+  
+  
+  if(is_same_type<gen_type, gen_ones_diag>::value == true)
+    {
+    const uword N = (std::min)(n_rows, n_cols);
+    
+    for(uword iq=0; iq < N; ++iq)
+      {
+      out.at(iq,iq) += eT(1);
+      }
+    }
+  else
+    {
+          eT*   out_mem = out.memptr();
+    const uword n_elem  = out.n_elem;
+    
+    uword iq,jq;
+    for(iq=0, jq=1; jq < n_elem; iq+=2, jq+=2)
+      {
+      const eT tmp_i = Gen<T1, gen_type>::generate();
+      const eT tmp_j = Gen<T1, gen_type>::generate();
+      
+      out_mem[iq] += tmp_i;
+      out_mem[jq] += tmp_j;
+      }
+    
+    if(iq < n_elem)
+      {
+      out_mem[iq] += Gen<T1, gen_type>::generate();
+      }
+    }
+  
+  }
+
+
+
+
+template<typename T1, typename gen_type>
+inline
+void
+Gen<T1, gen_type>::apply_inplace_minus(Mat<typename T1::elem_type>& out) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "subtraction");
+  
+  typedef typename T1::elem_type eT;
+  
+  
+  if(is_same_type<gen_type, gen_ones_diag>::value == true)
+    {
+    const uword N = (std::min)(n_rows, n_cols);
+    
+    for(uword iq=0; iq < N; ++iq)
+      {
+      out.at(iq,iq) -= eT(1);
+      }
+    }
+  else
+    {
+          eT*   out_mem = out.memptr();
+    const uword n_elem  = out.n_elem;
+    
+    uword iq,jq;
+    for(iq=0, jq=1; jq < n_elem; iq+=2, jq+=2)
+      {
+      const eT tmp_i = Gen<T1, gen_type>::generate();
+      const eT tmp_j = Gen<T1, gen_type>::generate();
+      
+      out_mem[iq] -= tmp_i;
+      out_mem[jq] -= tmp_j;
+      }
+    
+    if(iq < n_elem)
+      {
+      out_mem[iq] -= Gen<T1, gen_type>::generate();
+      }
+    }
+  
+  }
+
+
+
+
+template<typename T1, typename gen_type>
+inline
+void
+Gen<T1, gen_type>::apply_inplace_schur(Mat<typename T1::elem_type>& out) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise multiplication");
+  
+  typedef typename T1::elem_type eT;
+  
+  
+  if(is_same_type<gen_type, gen_ones_diag>::value == true)
+    {
+    const uword N = (std::min)(n_rows, n_cols);
+    
+    for(uword iq=0; iq < N; ++iq)
+      {
+      for(uword row=0;    row < iq;     ++row) { out.at(row,iq) = eT(0); }
+      for(uword row=iq+1; row < n_rows; ++row) { out.at(row,iq) = eT(0); }
+      }
+    }
+  else
+    {
+          eT*   out_mem = out.memptr();
+    const uword n_elem  = out.n_elem;
+    
+    uword iq,jq;
+    for(iq=0, jq=1; jq < n_elem; iq+=2, jq+=2)
+      {
+      const eT tmp_i = Gen<T1, gen_type>::generate();
+      const eT tmp_j = Gen<T1, gen_type>::generate();
+      
+      out_mem[iq] *= tmp_i;
+      out_mem[jq] *= tmp_j;
+      }
+    
+    if(iq < n_elem)
+      {
+      out_mem[iq] *= Gen<T1, gen_type>::generate();
+      }
+    }
+  
+  }
+
+
+
+
+template<typename T1, typename gen_type>
+inline
+void
+Gen<T1, gen_type>::apply_inplace_div(Mat<typename T1::elem_type>& out) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise division");
+  
+  typedef typename T1::elem_type eT;
+  
+  
+  if(is_same_type<gen_type, gen_ones_diag>::value == true)
+    {
+    const uword N = (std::min)(n_rows, n_cols);
+    
+    for(uword iq=0; iq < N; ++iq)
+      {
+      const eT zero = eT(0);
+      
+      for(uword row=0;    row < iq;     ++row) { out.at(row,iq) /= zero; }
+      for(uword row=iq+1; row < n_rows; ++row) { out.at(row,iq) /= zero; }
+      }
+    }
+  else
+    {
+          eT*   out_mem = out.memptr();
+    const uword n_elem  = out.n_elem;
+    
+    uword iq,jq;
+    for(iq=0, jq=1; jq < n_elem; iq+=2, jq+=2)
+      {
+      const eT tmp_i = Gen<T1, gen_type>::generate();
+      const eT tmp_j = Gen<T1, gen_type>::generate();
+      
+      out_mem[iq] /= tmp_i;
+      out_mem[jq] /= tmp_j;
+      }
+    
+    if(iq < n_elem)
+      {
+      out_mem[iq] /= Gen<T1, gen_type>::generate();
+      }
+    }
+  
+  }
+
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/GlueCube_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,33 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup GlueCube
+//! @{
+
+
+
+//! analog of the Glue class, intended for Cube objects
+template<typename T1, typename T2, typename glue_type>
+class GlueCube : public BaseCube<typename T1::elem_type, GlueCube<T1, T2, glue_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+
+  arma_inline  GlueCube(const BaseCube<typename T1::elem_type, T1>& in_A, const BaseCube<typename T1::elem_type, T2>& in_B);
+  arma_inline ~GlueCube();
+  
+  const T1& A;  //!< first operand
+  const T2& B;  //!< second operand
+  
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/GlueCube_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,34 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup GlueCube
+//! @{
+
+
+
+template<typename T1, typename T2, typename glue_type>
+inline
+GlueCube<T1,T2,glue_type>::GlueCube(const BaseCube<typename T1::elem_type, T1>& in_A, const BaseCube<typename T1::elem_type, T2>& in_B)
+  : A(in_A.get_ref())
+  , B(in_B.get_ref())
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename T2, typename glue_type>
+inline
+GlueCube<T1,T2,glue_type>::~GlueCube()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Glue_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,49 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Glue
+//! @{
+
+
+
+//! Class for storing data required for delayed binary operations,
+//! such as the operands (e.g. two matrices) and the binary operator (e.g. addition).
+//! The operands are stored as references (which can be optimised away),
+//! while the operator is "stored" through the template definition (glue_type).
+//! The operands can be 'Mat', 'Row', 'Col', 'Op', and 'Glue'.
+//! Note that as 'Glue' can be one of the operands, more than two matrices can be stored.
+//!
+//! For example, we could have: Glue<Mat, Mat, glue_times>
+//! 
+//! Another example is: Glue< Op<Mat, op_htrans>, Op<Mat, op_inv>, glue_times >
+
+
+
+template<typename T1, typename T2, typename glue_type>
+class Glue : public Base<typename T1::elem_type, Glue<T1, T2, glue_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool is_row = (is_same_type<glue_type, glue_times>::value) ? T1::is_row : false;
+  static const bool is_col = (is_same_type<glue_type, glue_times>::value) ? T2::is_col : false;
+  
+  arma_inline  Glue(const T1& in_A, const T2& in_B);
+  arma_inline  Glue(const T1& in_A, const T2& in_B, const uword in_aux_uword);
+  arma_inline ~Glue();
+  
+  const T1&   A;          //!< first operand
+  const T2&   B;          //!< second operand
+        uword aux_uword;  //!< storage of auxiliary data, uword format
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Glue_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,46 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Glue
+//! @{
+
+
+
+template<typename T1, typename T2, typename glue_type>
+inline
+Glue<T1,T2,glue_type>::Glue(const T1& in_A, const T2& in_B)
+  : A(in_A)
+  , B(in_B)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename T2, typename glue_type>
+inline
+Glue<T1,T2,glue_type>::Glue(const T1& in_A, const T2& in_B, const uword in_aux_uword)
+  : A(in_A)
+  , B(in_B)
+  , aux_uword(in_aux_uword)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename T2, typename glue_type>
+inline
+Glue<T1,T2,glue_type>::~Glue()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Mat_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,643 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Mat
+//! @{
+
+
+
+//! Dense matrix class
+
+template<typename eT>
+class Mat : public Base< eT, Mat<eT> >
+  {
+  public:
+  
+  typedef eT                                elem_type;  //!< the type of elements stored in the matrix
+  typedef typename get_pod_type<eT>::result pod_type;   //!< if eT is non-complex, pod_type is same as eT. otherwise, pod_type is the underlying type used by std::complex
+  
+  const uword  n_rows;    //!< number of rows in the matrix (read-only)
+  const uword  n_cols;    //!< number of columns in the matrix (read-only)
+  const uword  n_elem;    //!< number of elements in the matrix (read-only)
+  const uhword vec_state; //!< 0: matrix layout; 1: column vector layout; 2: row vector layout
+  const uhword mem_state;
+  
+  // mem_state = 0: normal matrix that can be resized; 
+  // mem_state = 1: use auxiliary memory until change in the number of elements is requested;  
+  // mem_state = 2: use auxiliary memory and don't allow the number of elements to be changed; 
+  // mem_state = 3: fixed size (e.g. via template based size specification).
+  
+  arma_aligned const eT* const mem;  //!< pointer to the memory used by the matrix (memory is read-only)
+  
+  protected:
+  arma_align_mem eT mem_local[ arma_config::mat_prealloc ];
+  
+  
+  public:
+  
+  static const bool is_col = false;
+  static const bool is_row = false;
+  
+  inline ~Mat();
+  inline  Mat();
+  
+  inline Mat(const uword in_rows, const uword in_cols);
+  
+  inline                  Mat(const char*        text);
+  inline const Mat& operator=(const char*        text);
+  
+  inline                  Mat(const std::string& text);
+  inline const Mat& operator=(const std::string& text);
+  
+  inline                  Mat(const std::vector<eT>& x);
+  inline const Mat& operator=(const std::vector<eT>& x);
+  
+  #if defined(ARMA_USE_CXX11)
+  inline                  Mat(const std::initializer_list<eT>& list);
+  inline const Mat& operator=(const std::initializer_list<eT>& list);
+  #endif
+  
+  inline Mat(      eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const bool copy_aux_mem = true, const bool strict = true);
+  inline Mat(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols);
+  
+  arma_inline const Mat&  operator=(const eT val);
+  arma_inline const Mat& operator+=(const eT val);
+  arma_inline const Mat& operator-=(const eT val);
+  arma_inline const Mat& operator*=(const eT val);
+  arma_inline const Mat& operator/=(const eT val);
+  
+  inline                   Mat(const Mat& m);
+  inline const Mat&  operator=(const Mat& m);
+  inline const Mat& operator+=(const Mat& m);
+  inline const Mat& operator-=(const Mat& m);
+  inline const Mat& operator*=(const Mat& m);
+  inline const Mat& operator%=(const Mat& m);
+  inline const Mat& operator/=(const Mat& m);
+  
+  template<typename T1> inline                   Mat(const BaseCube<eT,T1>& X);
+  template<typename T1> inline const Mat&  operator=(const BaseCube<eT,T1>& X);
+  template<typename T1> inline const Mat& operator+=(const BaseCube<eT,T1>& X);
+  template<typename T1> inline const Mat& operator-=(const BaseCube<eT,T1>& X);
+  template<typename T1> inline const Mat& operator*=(const BaseCube<eT,T1>& X);
+  template<typename T1> inline const Mat& operator%=(const BaseCube<eT,T1>& X);
+  template<typename T1> inline const Mat& operator/=(const BaseCube<eT,T1>& X);
+  
+  template<typename T1, typename T2>
+  inline explicit Mat(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
+
+  inline                   Mat(const subview<eT>& X);
+  inline const Mat&  operator=(const subview<eT>& X);
+  inline const Mat& operator+=(const subview<eT>& X);
+  inline const Mat& operator-=(const subview<eT>& X);
+  inline const Mat& operator*=(const subview<eT>& X);
+  inline const Mat& operator%=(const subview<eT>& X);
+  inline const Mat& operator/=(const subview<eT>& X);
+  
+  inline Mat(const subview_row_strans<eT>& X);  // subview_row_strans can only be generated by the Proxy class
+  inline Mat(const subview_row_htrans<eT>& X);  // subview_row_htrans can only be generated by the Proxy class
+  inline Mat(const        xvec_htrans<eT>& X);  //        xvec_htrans can only be generated by the Proxy class
+  
+  //inline explicit          Mat(const subview_cube<eT>& X);
+  inline                   Mat(const subview_cube<eT>& X);
+  inline const Mat&  operator=(const subview_cube<eT>& X);
+  inline const Mat& operator+=(const subview_cube<eT>& X);
+  inline const Mat& operator-=(const subview_cube<eT>& X);
+  inline const Mat& operator*=(const subview_cube<eT>& X);
+  inline const Mat& operator%=(const subview_cube<eT>& X);
+  inline const Mat& operator/=(const subview_cube<eT>& X);
+
+  //inline explicit          Mat(const diagview<eT>& X);
+  inline                   Mat(const diagview<eT>& X);
+  inline const Mat&  operator=(const diagview<eT>& X);
+  inline const Mat& operator+=(const diagview<eT>& X);
+  inline const Mat& operator-=(const diagview<eT>& X);
+  inline const Mat& operator*=(const diagview<eT>& X);
+  inline const Mat& operator%=(const diagview<eT>& X);
+  inline const Mat& operator/=(const diagview<eT>& X);
+  
+  template<typename T1> inline                   Mat(const subview_elem1<eT,T1>& X);
+  template<typename T1> inline const Mat& operator= (const subview_elem1<eT,T1>& X);
+  template<typename T1> inline const Mat& operator+=(const subview_elem1<eT,T1>& X);
+  template<typename T1> inline const Mat& operator-=(const subview_elem1<eT,T1>& X);
+  template<typename T1> inline const Mat& operator*=(const subview_elem1<eT,T1>& X);
+  template<typename T1> inline const Mat& operator%=(const subview_elem1<eT,T1>& X);
+  template<typename T1> inline const Mat& operator/=(const subview_elem1<eT,T1>& X);
+  
+  template<typename T1, typename T2> inline                   Mat(const subview_elem2<eT,T1,T2>& X);
+  template<typename T1, typename T2> inline const Mat& operator= (const subview_elem2<eT,T1,T2>& X);
+  template<typename T1, typename T2> inline const Mat& operator+=(const subview_elem2<eT,T1,T2>& X);
+  template<typename T1, typename T2> inline const Mat& operator-=(const subview_elem2<eT,T1,T2>& X);
+  template<typename T1, typename T2> inline const Mat& operator*=(const subview_elem2<eT,T1,T2>& X);
+  template<typename T1, typename T2> inline const Mat& operator%=(const subview_elem2<eT,T1,T2>& X);
+  template<typename T1, typename T2> inline const Mat& operator/=(const subview_elem2<eT,T1,T2>& X);
+
+  // Operators on sparse matrices (and subviews).
+  template<typename T1> inline explicit          Mat(const SpBase<eT, T1>& m);
+  template<typename T1> inline const Mat&  operator=(const SpBase<eT, T1>& m);
+  template<typename T1> inline const Mat& operator+=(const SpBase<eT, T1>& m);
+  template<typename T1> inline const Mat& operator-=(const SpBase<eT, T1>& m);
+  template<typename T1> inline const Mat& operator*=(const SpBase<eT, T1>& m);
+  template<typename T1> inline const Mat& operator%=(const SpBase<eT, T1>& m);
+  template<typename T1> inline const Mat& operator/=(const SpBase<eT, T1>& m);
+  
+  inline mat_injector<Mat> operator<<(const eT val);
+  inline mat_injector<Mat> operator<<(const injector_end_of_row<>& x);
+  
+  
+  arma_inline       subview_row<eT> row(const uword row_num);
+  arma_inline const subview_row<eT> row(const uword row_num) const;
+  
+  inline            subview_row<eT> operator()(const uword row_num, const span& col_span);
+  inline      const subview_row<eT> operator()(const uword row_num, const span& col_span) const;
+  
+  
+  arma_inline       subview_col<eT> col(const uword col_num);
+  arma_inline const subview_col<eT> col(const uword col_num) const;
+  
+  inline            subview_col<eT> operator()(const span& row_span, const uword col_num);
+  inline      const subview_col<eT> operator()(const span& row_span, const uword col_num) const;
+  
+  inline            Col<eT>  unsafe_col(const uword col_num);
+  inline      const Col<eT>  unsafe_col(const uword col_num) const;
+  
+  
+  arma_inline       subview<eT> rows(const uword in_row1, const uword in_row2);
+  arma_inline const subview<eT> rows(const uword in_row1, const uword in_row2) const;
+  
+  arma_inline       subview<eT> cols(const uword in_col1, const uword in_col2);
+  arma_inline const subview<eT> cols(const uword in_col1, const uword in_col2) const;
+  
+  arma_inline       subview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2);
+  arma_inline const subview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const;
+  
+  
+  inline            subview<eT> submat    (const span& row_span, const span& col_span);
+  inline      const subview<eT> submat    (const span& row_span, const span& col_span) const;
+  
+  inline            subview<eT> operator()(const span& row_span, const span& col_span);
+  inline      const subview<eT> operator()(const span& row_span, const span& col_span) const;
+  
+  
+  template<typename T1> arma_inline       subview_elem1<eT,T1> elem(const Base<uword,T1>& a);
+  template<typename T1> arma_inline const subview_elem1<eT,T1> elem(const Base<uword,T1>& a) const;
+  
+  template<typename T1> arma_inline       subview_elem1<eT,T1> operator()(const Base<uword,T1>& a);
+  template<typename T1> arma_inline const subview_elem1<eT,T1> operator()(const Base<uword,T1>& a) const;
+  
+  
+  template<typename T1, typename T2> arma_inline       subview_elem2<eT,T1,T2> elem(const Base<uword,T1>& ri, const Base<uword,T2>& ci);
+  template<typename T1, typename T2> arma_inline const subview_elem2<eT,T1,T2> elem(const Base<uword,T1>& ri, const Base<uword,T2>& ci) const;
+  
+  template<typename T1, typename T2> arma_inline       subview_elem2<eT,T1,T2> submat(const Base<uword,T1>& ri, const Base<uword,T2>& ci);
+  template<typename T1, typename T2> arma_inline const subview_elem2<eT,T1,T2> submat(const Base<uword,T1>& ri, const Base<uword,T2>& ci) const;
+  
+  template<typename T1, typename T2> arma_inline       subview_elem2<eT,T1,T2> operator()(const Base<uword,T1>& ri, const Base<uword,T2>& ci);
+  template<typename T1, typename T2> arma_inline const subview_elem2<eT,T1,T2> operator()(const Base<uword,T1>& ri, const Base<uword,T2>& ci) const;
+  
+  
+  template<typename T1> arma_inline       subview_elem2<eT,T1,T1> rows(const Base<uword,T1>& ri);
+  template<typename T1> arma_inline const subview_elem2<eT,T1,T1> rows(const Base<uword,T1>& ri) const;
+  
+  template<typename T2> arma_inline       subview_elem2<eT,T2,T2> cols(const Base<uword,T2>& ci);
+  template<typename T2> arma_inline const subview_elem2<eT,T2,T2> cols(const Base<uword,T2>& ci) const;
+  
+  
+  arma_inline subview_each1< Mat<eT>, 0 > each_col();
+  arma_inline subview_each1< Mat<eT>, 1 > each_row();
+  
+  template<typename T1> inline subview_each2< Mat<eT>, 0, T1 > each_col(const Base<uword, T1>& indices);
+  template<typename T1> inline subview_each2< Mat<eT>, 1, T1 > each_row(const Base<uword, T1>& indices);
+  
+  arma_inline       diagview<eT> diag(const sword in_id = 0);
+  arma_inline const diagview<eT> diag(const sword in_id = 0) const;
+  
+  
+  inline void swap_rows(const uword in_row1, const uword in_row2);
+  inline void swap_cols(const uword in_col1, const uword in_col2);
+  
+  inline void shed_row(const uword row_num);
+  inline void shed_col(const uword col_num);
+  
+  inline void shed_rows(const uword in_row1, const uword in_row2);
+  inline void shed_cols(const uword in_col1, const uword in_col2);
+  
+  inline void insert_rows(const uword row_num, const uword N, const bool set_to_zero = true);
+  inline void insert_cols(const uword col_num, const uword N, const bool set_to_zero = true);
+  
+  template<typename T1> inline void insert_rows(const uword row_num, const Base<eT,T1>& X);
+  template<typename T1> inline void insert_cols(const uword col_num, const Base<eT,T1>& X);
+  
+  
+  template<typename T1, typename gen_type> inline                   Mat(const Gen<T1, gen_type>& X);
+  template<typename T1, typename gen_type> inline const Mat&  operator=(const Gen<T1, gen_type>& X);
+  template<typename T1, typename gen_type> inline const Mat& operator+=(const Gen<T1, gen_type>& X);
+  template<typename T1, typename gen_type> inline const Mat& operator-=(const Gen<T1, gen_type>& X);
+  template<typename T1, typename gen_type> inline const Mat& operator*=(const Gen<T1, gen_type>& X);
+  template<typename T1, typename gen_type> inline const Mat& operator%=(const Gen<T1, gen_type>& X);
+  template<typename T1, typename gen_type> inline const Mat& operator/=(const Gen<T1, gen_type>& X);
+  
+  template<typename T1, typename op_type> inline                   Mat(const Op<T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Mat&  operator=(const Op<T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Mat& operator+=(const Op<T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Mat& operator-=(const Op<T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Mat& operator*=(const Op<T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Mat& operator%=(const Op<T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Mat& operator/=(const Op<T1, op_type>& X);
+  
+  template<typename T1, typename eop_type> inline                   Mat(const eOp<T1, eop_type>& X);
+  template<typename T1, typename eop_type> inline const Mat&  operator=(const eOp<T1, eop_type>& X);
+  template<typename T1, typename eop_type> inline const Mat& operator+=(const eOp<T1, eop_type>& X);
+  template<typename T1, typename eop_type> inline const Mat& operator-=(const eOp<T1, eop_type>& X);
+  template<typename T1, typename eop_type> inline const Mat& operator*=(const eOp<T1, eop_type>& X);
+  template<typename T1, typename eop_type> inline const Mat& operator%=(const eOp<T1, eop_type>& X);
+  template<typename T1, typename eop_type> inline const Mat& operator/=(const eOp<T1, eop_type>& X);
+  
+  template<typename T1, typename op_type> inline                   Mat(const mtOp<eT, T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Mat&  operator=(const mtOp<eT, T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Mat& operator+=(const mtOp<eT, T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Mat& operator-=(const mtOp<eT, T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Mat& operator*=(const mtOp<eT, T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Mat& operator%=(const mtOp<eT, T1, op_type>& X);
+  template<typename T1, typename op_type> inline const Mat& operator/=(const mtOp<eT, T1, op_type>& X);
+  
+  template<typename T1, typename T2, typename glue_type> inline                   Mat(const Glue<T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Mat&  operator=(const Glue<T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Mat& operator+=(const Glue<T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Mat& operator-=(const Glue<T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Mat& operator*=(const Glue<T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Mat& operator%=(const Glue<T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Mat& operator/=(const Glue<T1, T2, glue_type>& X);
+  
+  template<typename T1, typename T2>                     inline const Mat& operator+=(const Glue<T1, T2, glue_times>& X);
+  template<typename T1, typename T2>                     inline const Mat& operator-=(const Glue<T1, T2, glue_times>& X);
+  
+  template<typename T1, typename T2, typename eglue_type> inline                   Mat(const eGlue<T1, T2, eglue_type>& X);
+  template<typename T1, typename T2, typename eglue_type> inline const Mat&  operator=(const eGlue<T1, T2, eglue_type>& X);
+  template<typename T1, typename T2, typename eglue_type> inline const Mat& operator+=(const eGlue<T1, T2, eglue_type>& X);
+  template<typename T1, typename T2, typename eglue_type> inline const Mat& operator-=(const eGlue<T1, T2, eglue_type>& X);
+  template<typename T1, typename T2, typename eglue_type> inline const Mat& operator*=(const eGlue<T1, T2, eglue_type>& X);
+  template<typename T1, typename T2, typename eglue_type> inline const Mat& operator%=(const eGlue<T1, T2, eglue_type>& X);
+  template<typename T1, typename T2, typename eglue_type> inline const Mat& operator/=(const eGlue<T1, T2, eglue_type>& X);
+  
+  template<typename T1, typename T2, typename glue_type> inline                   Mat(const mtGlue<eT, T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Mat&  operator=(const mtGlue<eT, T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Mat& operator+=(const mtGlue<eT, T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Mat& operator-=(const mtGlue<eT, T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Mat& operator*=(const mtGlue<eT, T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Mat& operator%=(const mtGlue<eT, T1, T2, glue_type>& X);
+  template<typename T1, typename T2, typename glue_type> inline const Mat& operator/=(const mtGlue<eT, T1, T2, glue_type>& X);
+  
+  
+  arma_inline arma_warn_unused const eT& at_alt     (const uword ii) const;
+  
+  arma_inline arma_warn_unused       eT& operator[] (const uword ii);
+  arma_inline arma_warn_unused const eT& operator[] (const uword ii) const;
+  arma_inline arma_warn_unused       eT& at         (const uword ii);
+  arma_inline arma_warn_unused const eT& at         (const uword ii) const;
+  arma_inline arma_warn_unused       eT& operator() (const uword ii);
+  arma_inline arma_warn_unused const eT& operator() (const uword ii) const;
+  
+  arma_inline arma_warn_unused       eT& at         (const uword in_row, const uword in_col);
+  arma_inline arma_warn_unused const eT& at         (const uword in_row, const uword in_col) const;
+  arma_inline arma_warn_unused       eT& operator() (const uword in_row, const uword in_col);
+  arma_inline arma_warn_unused const eT& operator() (const uword in_row, const uword in_col) const;
+  
+  arma_inline const Mat& operator++();
+  arma_inline void       operator++(int);
+  
+  arma_inline const Mat& operator--();
+  arma_inline void       operator--(int);
+  
+  arma_inline arma_warn_unused bool is_empty()  const;
+  arma_inline arma_warn_unused bool is_vec()    const;
+  arma_inline arma_warn_unused bool is_rowvec() const;
+  arma_inline arma_warn_unused bool is_colvec() const;
+  arma_inline arma_warn_unused bool is_square() const;
+       inline arma_warn_unused bool is_finite() const;
+  
+  arma_inline arma_warn_unused bool in_range(const uword ii) const;
+  arma_inline arma_warn_unused bool in_range(const span& x ) const;
+  
+  arma_inline arma_warn_unused bool in_range(const uword   in_row, const uword   in_col) const;
+  arma_inline arma_warn_unused bool in_range(const span& row_span, const uword   in_col) const;
+  arma_inline arma_warn_unused bool in_range(const uword   in_row, const span& col_span) const;
+  arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span) const;
+  
+  arma_inline arma_warn_unused       eT* colptr(const uword in_col);
+  arma_inline arma_warn_unused const eT* colptr(const uword in_col) const;
+  
+  arma_inline arma_warn_unused       eT* memptr();
+  arma_inline arma_warn_unused const eT* memptr() const;
+  
+  
+  inline void impl_print(const std::string& extra_text) const;
+  inline void impl_print(std::ostream& user_stream, const std::string& extra_text) const;
+  
+  inline void impl_raw_print(const std::string& extra_text) const;
+  inline void impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const;
+  
+  
+  template<typename eT2, typename expr>
+  inline void copy_size(const Base<eT2,expr>& X);
+  
+  inline void set_size(const uword in_elem);
+  inline void set_size(const uword in_rows, const uword in_cols);
+  
+  inline void   resize(const uword in_elem);
+  inline void   resize(const uword in_rows, const uword in_cols);
+  inline void  reshape(const uword in_rows, const uword in_cols, const uword dim = 0);
+  
+  
+  template<typename functor>
+  inline const Mat& transform(functor F);
+  
+  template<typename functor>
+  inline const Mat& imbue(functor F);
+  
+  
+  arma_hot inline const Mat& fill(const eT val);
+  
+  inline const Mat& zeros();
+  inline const Mat& zeros(const uword in_elem);
+  inline const Mat& zeros(const uword in_rows, const uword in_cols);
+  
+  inline const Mat& ones();
+  inline const Mat& ones(const uword in_elem);
+  inline const Mat& ones(const uword in_rows, const uword in_cols);
+  
+  inline const Mat& randu();
+  inline const Mat& randu(const uword in_elem);
+  inline const Mat& randu(const uword in_rows, const uword in_cols);
+  
+  inline const Mat& randn();
+  inline const Mat& randn(const uword in_elem);
+  inline const Mat& randn(const uword in_rows, const uword in_cols);
+  
+  inline const Mat& eye();
+  inline const Mat& eye(const uword in_rows, const uword in_cols);
+  
+  inline void reset();
+  
+  
+  template<typename T1> inline void set_real(const Base<pod_type,T1>& X);
+  template<typename T1> inline void set_imag(const Base<pod_type,T1>& X);
+  
+  
+  inline arma_warn_unused eT min() const;
+  inline arma_warn_unused eT max() const;
+  
+  inline eT min(uword& index_of_min_val) const;
+  inline eT max(uword& index_of_max_val) const;
+  
+  inline eT min(uword& row_of_min_val, uword& col_of_min_val) const;
+  inline eT max(uword& row_of_max_val, uword& col_of_max_val) const;
+  
+  
+  inline bool save(const std::string   name, const file_type type = arma_binary, const bool print_status = true) const;
+  inline bool save(      std::ostream& os,   const file_type type = arma_binary, const bool print_status = true) const;
+  
+  inline bool load(const std::string   name, const file_type type = auto_detect, const bool print_status = true);
+  inline bool load(      std::istream& is,   const file_type type = auto_detect, const bool print_status = true);
+  
+  inline bool quiet_save(const std::string   name, const file_type type = arma_binary) const;
+  inline bool quiet_save(      std::ostream& os,   const file_type type = arma_binary) const;
+  
+  inline bool quiet_load(const std::string   name, const file_type type = auto_detect);
+  inline bool quiet_load(      std::istream& is,   const file_type type = auto_detect);
+  
+  
+  // for container-like functionality
+  
+  typedef eT    value_type;
+  typedef uword size_type;
+  
+  typedef       eT*       iterator;
+  typedef const eT* const_iterator;
+  
+  typedef       eT*       col_iterator;
+  typedef const eT* const_col_iterator;
+  
+  class row_iterator
+    {
+    public:
+    
+    inline row_iterator(Mat<eT>& in_M, const uword in_row);
+    
+    inline eT& operator* ();
+    
+    inline row_iterator& operator++();
+    inline void          operator++(int);
+    
+    inline row_iterator& operator--();
+    inline void          operator--(int);
+    
+    inline bool operator!=(const row_iterator& X) const;
+    inline bool operator==(const row_iterator& X) const;
+    
+    arma_aligned Mat<eT>& M;
+    arma_aligned uword    row;
+    arma_aligned uword    col;
+    };
+  
+  
+  class const_row_iterator
+    {
+    public:
+    
+    const_row_iterator(const Mat<eT>& in_M, const uword in_row);
+    const_row_iterator(const row_iterator& X);
+    
+    inline eT operator*() const;
+    
+    inline const_row_iterator& operator++();
+    inline void                operator++(int);
+    
+    inline const_row_iterator& operator--();
+    inline void                operator--(int);
+    
+    inline bool operator!=(const const_row_iterator& X) const;
+    inline bool operator==(const const_row_iterator& X) const;
+    
+    arma_aligned const Mat<eT>& M;
+    arma_aligned       uword    row;
+    arma_aligned       uword    col;
+    };
+  
+  inline       iterator  begin();
+  inline const_iterator  begin() const;
+  inline const_iterator cbegin() const;
+  
+  inline       iterator  end();
+  inline const_iterator  end() const;
+  inline const_iterator cend() const;
+  
+  inline       col_iterator begin_col(const uword col_num);
+  inline const_col_iterator begin_col(const uword col_num) const;
+  
+  inline       col_iterator end_col  (const uword col_num);
+  inline const_col_iterator end_col  (const uword col_num) const;
+  
+  inline       row_iterator begin_row(const uword row_num);
+  inline const_row_iterator begin_row(const uword row_num) const;
+  
+  inline       row_iterator end_row  (const uword row_num);
+  inline const_row_iterator end_row  (const uword row_num) const;
+  
+  inline void  clear();
+  inline bool  empty() const;
+  inline uword size()  const;
+  
+  inline void swap(Mat& B);
+  
+  inline void steal_mem(Mat& X);  //!< don't use this unless you're writing code internal to Armadillo
+  
+  template<uword fixed_n_rows, uword fixed_n_cols> class fixed;
+  
+  
+  protected:
+  
+  inline void init_cold();
+  inline void init_warm(uword in_rows, uword in_cols);
+  
+  inline void init(const std::string& text);
+  
+  #if defined(ARMA_USE_CXX11)
+  inline void init(const std::initializer_list<eT>& list);
+  #endif
+  
+  template<typename T1, typename T2>
+  inline void init(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
+  
+  inline Mat(const char junk, const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols);
+  
+  inline Mat(const arma_vec_indicator&, const uhword in_vec_state);
+  inline Mat(const arma_vec_indicator&, const uword in_n_rows, const uword in_n_cols, const uhword in_vec_state);
+  
+  inline Mat(const arma_fixed_indicator&, const uword in_n_rows, const uword in_n_cols, const uhword in_vec_state, const eT* in_mem);
+  
+  
+  friend class Cube<eT>;
+  friend class glue_join;
+  friend class op_strans;
+  friend class op_htrans;
+  friend class op_resize;
+  
+  public:
+  
+  #ifdef ARMA_EXTRA_MAT_PROTO
+    #include ARMA_INCFILE_WRAP(ARMA_EXTRA_MAT_PROTO)
+  #endif
+  };
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols> 
+class Mat<eT>::fixed : public Mat<eT>
+  {
+  private:
+  
+  static const uword fixed_n_elem = fixed_n_rows * fixed_n_cols;
+  static const bool  use_extra    = (fixed_n_elem > arma_config::mat_prealloc);
+  
+  arma_align_mem eT mem_local_extra[ (use_extra) ? fixed_n_elem : 1 ];
+  
+  
+  public:
+  
+  typedef fixed<fixed_n_rows, fixed_n_cols> Mat_fixed_type;
+  
+  typedef eT                                elem_type;
+  typedef typename get_pod_type<eT>::result pod_type;
+  
+  static const bool is_col = (fixed_n_cols == 1) ? true : false;
+  static const bool is_row = (fixed_n_rows == 1) ? true : false;
+  
+  static const uword n_rows = fixed_n_rows;
+  static const uword n_cols = fixed_n_cols;
+  static const uword n_elem = fixed_n_elem;
+  
+  arma_inline fixed();
+  arma_inline fixed(const fixed<fixed_n_rows, fixed_n_cols>& X);
+  
+  template<typename T1>              inline fixed(const Base<eT,T1>& A);
+  template<typename T1, typename T2> inline fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
+  
+  inline fixed(const eT* aux_mem);
+  
+  inline fixed(const char*        text);
+  inline fixed(const std::string& text);
+  
+  using Mat<eT>::operator=;
+  using Mat<eT>::operator();
+  
+  #if defined(ARMA_USE_CXX11)
+    inline                fixed(const std::initializer_list<eT>& list);
+    inline const Mat& operator=(const std::initializer_list<eT>& list);
+  #endif
+  
+  arma_inline const Op< Mat_fixed_type, op_htrans >  t() const;
+  arma_inline const Op< Mat_fixed_type, op_htrans > ht() const;
+  arma_inline const Op< Mat_fixed_type, op_strans > st() const;
+  
+  arma_inline arma_warn_unused const eT& at_alt     (const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& operator[] (const uword i);
+  arma_inline arma_warn_unused const eT& operator[] (const uword i) const;
+  arma_inline arma_warn_unused       eT& at         (const uword i);
+  arma_inline arma_warn_unused const eT& at         (const uword i) const;
+  arma_inline arma_warn_unused       eT& operator() (const uword i);
+  arma_inline arma_warn_unused const eT& operator() (const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& at         (const uword in_row, const uword in_col);
+  arma_inline arma_warn_unused const eT& at         (const uword in_row, const uword in_col) const;
+  arma_inline arma_warn_unused       eT& operator() (const uword in_row, const uword in_col);
+  arma_inline arma_warn_unused const eT& operator() (const uword in_row, const uword in_col) const;
+  
+  arma_inline arma_warn_unused       eT* colptr(const uword in_col);
+  arma_inline arma_warn_unused const eT* colptr(const uword in_col) const;
+  
+  arma_inline arma_warn_unused       eT* memptr();
+  arma_inline arma_warn_unused const eT* memptr() const;
+  
+  arma_inline arma_warn_unused bool is_vec() const;
+  
+  arma_hot inline const Mat<eT>& fill(const eT val);
+  arma_hot inline const Mat<eT>& zeros();
+  arma_hot inline const Mat<eT>& ones();
+  };
+
+
+
+class Mat_aux
+  {
+  public:
+
+  template<typename eT> arma_inline static void prefix_pp(Mat<eT>& x);
+  template<typename T>  arma_inline static void prefix_pp(Mat< std::complex<T> >& x);
+  
+  template<typename eT> arma_inline static void postfix_pp(Mat<eT>& x);
+  template<typename T>  arma_inline static void postfix_pp(Mat< std::complex<T> >& x);
+  
+  template<typename eT> arma_inline static void prefix_mm(Mat<eT>& x);
+  template<typename T>  arma_inline static void prefix_mm(Mat< std::complex<T> >& x);
+  
+  template<typename eT> arma_inline static void postfix_mm(Mat<eT>& x);
+  template<typename T>  arma_inline static void postfix_mm(Mat< std::complex<T> >& x);
+  
+  template<typename eT, typename T1> inline static void set_real(Mat<eT>&                out, const Base<eT,T1>& X);
+  template<typename T,  typename T1> inline static void set_real(Mat< std::complex<T> >& out, const Base< T,T1>& X);
+  
+  template<typename eT, typename T1> inline static void set_imag(Mat<eT>&                out, const Base<eT,T1>& X);
+  template<typename T,  typename T1> inline static void set_imag(Mat< std::complex<T> >& out, const Base< T,T1>& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Mat_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,6897 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Mat
+//! @{
+
+
+template<typename eT>
+inline
+Mat<eT>::~Mat()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  if(mem_state == 0)
+    {
+    if(n_elem > arma_config::mat_prealloc)
+      {
+      memory::release( access::rw(mem) );
+      }
+    }
+    
+  if(arma_config::debug == true)
+    {
+    // try to expose buggy user code that accesses deleted objects
+    access::rw(mem) = 0;
+    }
+  
+  arma_type_check(( is_supported_elem_type<eT>::value == false ));
+  }
+
+
+
+template<typename eT>
+inline
+Mat<eT>::Mat()
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+//! construct the matrix to have user specified dimensions
+template<typename eT>
+inline
+Mat<eT>::Mat(const uword in_n_rows, const uword in_n_cols)
+  : n_rows(in_n_rows)
+  , n_cols(in_n_cols)
+  , n_elem(in_n_rows*in_n_cols)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold();
+  }
+
+
+
+//! constructor used by Row and Col classes
+template<typename eT>
+inline
+Mat<eT>::Mat(const arma_vec_indicator&, const uhword in_vec_state)
+  : n_rows( (in_vec_state == 2) ? 1 : 0 )
+  , n_cols( (in_vec_state == 1) ? 1 : 0 )
+  , n_elem(0)
+  , vec_state(in_vec_state)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+//! constructor used by Row and Col classes
+template<typename eT>
+inline
+Mat<eT>::Mat(const arma_vec_indicator&, const uword in_n_rows, const uword in_n_cols, const uhword in_vec_state)
+  : n_rows(in_n_rows)
+  , n_cols(in_n_cols)
+  , n_elem(in_n_rows*in_n_cols)
+  , vec_state(in_vec_state)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold();
+  }
+
+
+
+template<typename eT>
+inline
+Mat<eT>::Mat(const arma_fixed_indicator&, const uword in_n_rows, const uword in_n_cols, const uhword in_vec_state, const eT* in_mem)
+  : n_rows    (in_n_rows)
+  , n_cols    (in_n_cols)
+  , n_elem    (in_n_rows*in_n_cols)
+  , vec_state (in_vec_state)
+  , mem_state (3)
+  , mem       (in_mem)
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+template<typename eT>
+inline
+void
+Mat<eT>::init_cold()
+  {
+  arma_extra_debug_sigprint( arma_boost::format("n_rows = %d, n_cols = %d") % n_rows % n_cols );
+  
+  // ensure that n_elem can hold the result of (n_rows * n_cols)
+  
+  arma_debug_check
+    (
+      (
+      ( (n_rows > ARMA_MAX_UHWORD) || (n_cols > ARMA_MAX_UHWORD) )
+        ? ( (float(n_rows) * float(n_cols)) > float(ARMA_MAX_UWORD) )
+        : false
+      ),
+    "Mat::init(): requested size is too large"
+    );
+  
+  if(n_elem <= arma_config::mat_prealloc)
+    {
+    access::rw(mem) = mem_local;
+    }
+  else
+    {
+    arma_extra_debug_print("Mat::init(): allocating memory");
+    
+    access::rw(mem) = memory::acquire<eT>(n_elem);
+    
+    arma_check_bad_alloc( (mem == 0), "Mat::init(): out of memory" );
+    }
+  }
+
+
+
+//! internal matrix construction; if the requested size is small enough, memory from the stack is used. otherwise memory is allocated via 'new'
+template<typename eT>
+inline
+void
+Mat<eT>::init_warm(uword in_n_rows, uword in_n_cols)
+  {
+  arma_extra_debug_sigprint( arma_boost::format("in_n_rows = %d, in_n_cols = %d") % in_n_rows % in_n_cols );
+  
+  if( (n_rows == in_n_rows) && (n_cols == in_n_cols) )
+    {
+    return;
+    }
+  
+  bool  err_state = false;
+  char* err_msg   = 0;
+  
+  const uhword t_vec_state = vec_state;
+  const uhword t_mem_state = mem_state;
+  
+  arma_debug_set_error
+    (
+    err_state,
+    err_msg,
+    (t_mem_state == 3),
+    "Mat::init(): size is fixed and hence cannot be changed"
+    );
+  
+  if(t_vec_state > 0)
+    {
+    if( (in_n_rows == 0) && (in_n_cols == 0) )
+      {
+      if(t_vec_state == 1)
+        {
+        in_n_cols = 1;
+        }
+      else
+      if(t_vec_state == 2)
+        {
+        in_n_rows = 1;
+        }
+      }
+    else
+      {
+      arma_debug_set_error
+        (
+        err_state,
+        err_msg,
+        ( ((t_vec_state == 1) && (in_n_cols != 1)) || ((t_vec_state == 2) && (in_n_rows != 1)) ),
+        "Mat::init(): object is a row or column vector; requested size is not compatible"
+        );
+      }
+    }
+  
+  // ensure that n_elem can hold the result of (n_rows * n_cols)
+  
+  arma_debug_set_error
+    (
+    err_state,
+    err_msg,
+      (
+      ( (in_n_rows > ARMA_MAX_UHWORD) || (in_n_cols > ARMA_MAX_UHWORD) )
+        ? ( (float(in_n_rows) * float(in_n_cols)) > float(ARMA_MAX_UWORD) )
+        : false
+      ),
+    "Mat::init(): requested size is too large"
+    );
+  
+  arma_debug_check(err_state, err_msg);
+  
+  const uword old_n_elem = n_elem;
+  const uword new_n_elem = in_n_rows * in_n_cols;
+  
+  if(old_n_elem == new_n_elem)
+    {
+    arma_extra_debug_print("Mat::init(): reusing memory");
+    
+    access::rw(n_rows) = in_n_rows;
+    access::rw(n_cols) = in_n_cols;
+    }
+  else
+    {
+    arma_debug_check
+      (
+      (t_mem_state == 2),
+      "Mat::init(): mismatch between size of auxiliary memory and requested size"
+      );
+    
+    if(t_mem_state == 0)
+      {
+      if(old_n_elem > arma_config::mat_prealloc)
+        {
+        arma_extra_debug_print("Mat::init(): freeing memory");
+        
+        memory::release( access::rw(mem) );
+        }
+      }
+    
+    
+    if(new_n_elem <= arma_config::mat_prealloc)
+      {
+      access::rw(mem) = mem_local;
+      }
+    else
+      {
+      arma_extra_debug_print("Mat::init(): allocating memory");
+      
+      access::rw(mem) = memory::acquire<eT>(new_n_elem);
+      
+      arma_check_bad_alloc( (mem == 0), "Mat::init(): out of memory" );
+      }
+    
+    access::rw(n_rows)    = in_n_rows;
+    access::rw(n_cols)    = in_n_cols;
+    access::rw(n_elem)    = new_n_elem;
+    access::rw(mem_state) = 0;
+    }
+  }
+
+
+
+//! create the matrix from a textual description
+template<typename eT>
+inline
+Mat<eT>::Mat(const char* text)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init( std::string(text) );
+  }
+  
+  
+  
+//! create the matrix from a textual description
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const char* text)
+  {
+  arma_extra_debug_sigprint();
+  
+  init( std::string(text) );
+  return *this;
+  }
+  
+  
+
+//! create the matrix from a textual description
+template<typename eT>
+inline
+Mat<eT>::Mat(const std::string& text)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init(text);
+  }
+  
+  
+  
+//! create the matrix from a textual description
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const std::string& text)
+  {
+  arma_extra_debug_sigprint();
+  
+  init(text);
+  return *this;
+  }
+
+
+
+//! internal function to create the matrix from a textual description
+template<typename eT>
+inline 
+void
+Mat<eT>::init(const std::string& text)
+  {
+  arma_extra_debug_sigprint();
+  
+  //
+  // work out the size
+  
+  uword t_n_rows = 0;
+  uword t_n_cols = 0;
+  
+  bool t_n_cols_found = false;
+  
+  std::string token;
+  
+  std::string::size_type line_start = 0;
+  std::string::size_type   line_end = 0;
+  
+  while( line_start < text.length() )
+    {
+    
+    line_end = text.find(';', line_start);
+    
+    if(line_end == std::string::npos)
+      line_end = text.length()-1;
+    
+    std::string::size_type line_len = line_end - line_start + 1;
+    std::stringstream line_stream( text.substr(line_start,line_len) );
+    
+    
+    uword line_n_cols = 0;
+    while(line_stream >> token)
+      {
+      ++line_n_cols;
+      }
+    
+    
+    if(line_n_cols > 0)
+      {
+      if(t_n_cols_found == false)
+        {
+        t_n_cols = line_n_cols;
+        t_n_cols_found = true;
+        }
+      else
+        arma_check( (line_n_cols != t_n_cols), "Mat::init(): inconsistent number of columns in given string");
+      
+      ++t_n_rows;
+      }
+    line_start = line_end+1;
+    
+    }
+    
+  Mat<eT>& x = *this;
+  x.set_size(t_n_rows, t_n_cols);
+  
+  line_start = 0;
+  line_end = 0;
+  
+  uword urow = 0;
+  
+  while( line_start < text.length() )
+    {
+    
+    line_end = text.find(';', line_start);
+    
+    if(line_end == std::string::npos)
+      line_end = text.length()-1;
+    
+    std::string::size_type line_len = line_end - line_start + 1;
+    std::stringstream line_stream( text.substr(line_start,line_len) );
+    
+//     uword ucol = 0;
+//     while(line_stream >> token)
+//       {
+//       x.at(urow,ucol) = strtod(token.c_str(), 0);
+//       ++ucol;
+//       }
+    
+    uword ucol = 0;
+    eT val;
+    while(line_stream >> val)
+      {
+      x.at(urow,ucol) = val;
+      ++ucol;
+      }
+    
+    ++urow;
+    line_start = line_end+1;
+    }
+  
+  }
+
+
+
+//! create the matrix from std::vector
+template<typename eT>
+inline
+Mat<eT>::Mat(const std::vector<eT>& x)
+  : n_rows(uword(x.size()))
+  , n_cols(1)
+  , n_elem(uword(x.size()))
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold();
+  
+  if(n_elem > 0)
+    {
+    arrayops::copy( memptr(), &(x[0]), n_elem );
+    }
+  }
+  
+  
+  
+//! create the matrix from std::vector
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const std::vector<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  init_warm(uword(x.size()), 1);
+  
+  if(x.size() > 0)
+    {
+    arrayops::copy( memptr(), &(x[0]), uword(x.size()) );
+    }
+  
+  return *this;
+  }
+
+
+
+#if defined(ARMA_USE_CXX11)
+  
+  template<typename eT>
+  inline
+  Mat<eT>::Mat(const std::initializer_list<eT>& list)
+    : n_rows(0)
+    , n_cols(0)
+    , n_elem(0)
+    , vec_state(0)
+    , mem_state(0)
+    , mem()
+    {
+    arma_extra_debug_sigprint_this(this);
+    
+    init(list);
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  const Mat<eT>&
+  Mat<eT>::operator=(const std::initializer_list<eT>& list)
+    {
+    arma_extra_debug_sigprint();
+    
+    init(list);
+    
+    return *this;
+    }
+  
+#endif
+  
+
+
+//! Set the matrix to be equal to the specified scalar.
+//! NOTE: the size of the matrix will be 1x1
+template<typename eT>
+arma_inline
+const Mat<eT>&
+Mat<eT>::operator=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  init_warm(1,1);
+  access::rw(mem[0]) = val;
+  return *this;
+  }
+
+
+
+//! In-place addition of a scalar to all elements of the matrix
+template<typename eT>
+arma_inline
+const Mat<eT>&
+Mat<eT>::operator+=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  arrayops::inplace_plus( memptr(), val, n_elem );
+  
+  return *this;
+  }
+
+
+
+//! In-place subtraction of a scalar from all elements of the matrix
+template<typename eT>
+arma_inline
+const Mat<eT>&
+Mat<eT>::operator-=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  arrayops::inplace_minus( memptr(), val, n_elem );
+  
+  return *this;
+  }
+
+
+
+//! In-place multiplication of all elements of the matrix with a scalar
+template<typename eT>
+arma_inline
+const Mat<eT>&
+Mat<eT>::operator*=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  arrayops::inplace_mul( memptr(), val, n_elem );
+  
+  return *this;
+  }
+
+
+
+//! In-place division of all elements of the matrix with a scalar
+template<typename eT>
+arma_inline
+const Mat<eT>&
+Mat<eT>::operator/=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  arrayops::inplace_div( memptr(), val, n_elem );
+  
+  return *this;
+  }
+
+
+
+//! construct a matrix from a given matrix
+template<typename eT>
+inline
+Mat<eT>::Mat(const Mat<eT>& in_mat)
+  : n_rows(in_mat.n_rows)
+  , n_cols(in_mat.n_cols)
+  , n_elem(in_mat.n_elem)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint(arma_boost::format("this = %x   in_mat = %x") % this % &in_mat);
+  
+  init_cold();
+  
+  arrayops::copy( memptr(), in_mat.mem, in_mat.n_elem );
+  }
+
+
+
+//! construct a matrix from a given matrix
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const Mat<eT>& in_mat)
+  {
+  arma_extra_debug_sigprint(arma_boost::format("this = %x   in_mat = %x") % this % &in_mat);
+  
+  if(this != &in_mat)
+    {
+    init_warm(in_mat.n_rows, in_mat.n_cols);
+    
+    arrayops::copy( memptr(), in_mat.mem, in_mat.n_elem );
+    }
+  
+  return *this;
+  }
+
+
+
+#if defined(ARMA_USE_CXX11)
+
+template<typename eT>
+inline
+void
+Mat<eT>::init(const std::initializer_list<eT>& list)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword N = list.size();
+  
+  set_size(1, N);
+  
+  arrayops::copy( memptr(), list.begin(), N );
+  }
+
+#endif
+
+
+
+//! for constructing a complex matrix out of two non-complex matrices
+template<typename eT>
+template<typename T1, typename T2>
+inline
+void
+Mat<eT>::init
+  (
+  const Base<typename Mat<eT>::pod_type, T1>& X,
+  const Base<typename Mat<eT>::pod_type, T2>& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type T;
+  
+  arma_type_check(( is_complex<eT>::value == false ));   //!< compile-time abort if eT isn't std::complex
+  arma_type_check(( is_complex< T>::value == true  ));   //!< compile-time abort if T is std::complex
+  
+  arma_type_check(( is_same_type< std::complex<T>, eT >::value == false ));   //!< compile-time abort if types are not compatible
+  
+  const Proxy<T1> PX(X.get_ref());
+  const Proxy<T2> PY(Y.get_ref());
+  
+  arma_debug_assert_same_size(PX, PY, "Mat()");
+  
+  const uword local_n_rows = PX.get_n_rows();
+  const uword local_n_cols = PX.get_n_cols();
+  
+  init_warm(local_n_rows, local_n_cols);
+  
+  eT* out_mem = (*this).memptr();
+  
+  const bool prefer_at_accessor = ( Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor );
+  
+  if(prefer_at_accessor == false)
+    {
+    typedef typename Proxy<T1>::ea_type ea_type1;
+    typedef typename Proxy<T2>::ea_type ea_type2;
+  
+    const uword N = n_elem;
+    
+    ea_type1 A = PX.get_ea();
+    ea_type2 B = PY.get_ea();
+    
+    for(uword ii=0; ii < N; ++ii)
+      {
+      out_mem[ii] = std::complex<T>(A[ii], B[ii]);
+      }
+    }
+  else
+    {
+    for(uword ucol=0; ucol < local_n_cols; ++ucol)
+    for(uword urow=0; urow < local_n_rows; ++urow)
+      {
+      *out_mem = std::complex<T>(PX.at(urow,ucol), PY.at(urow,ucol));
+      out_mem++;
+      }
+    }
+  }
+
+
+
+//! EXPERIMENTAL: swap the contents of this matrix, denoted as matrix A, with given matrix B
+template<typename eT>
+inline
+void
+Mat<eT>::swap(Mat<eT>& B)
+  {
+  Mat<eT>& A = (*this);
+  
+  arma_extra_debug_sigprint(arma_boost::format("A = %x   B = %x") % &A % &B);
+  
+  arma_debug_check( (A.vec_state != B.vec_state), "Mat::swap(): incompatible object types" );
+  
+  const uhword A_mem_state = A.mem_state;
+  const uhword B_mem_state = B.mem_state;
+  
+  if( (A_mem_state == 0) && (B_mem_state == 0) )
+    {
+    const uword A_n_elem = A.n_elem;
+    const uword B_n_elem = B.n_elem;
+    
+    const bool A_use_local_mem = (A_n_elem <= arma_config::mat_prealloc);
+    const bool B_use_local_mem = (B_n_elem <= arma_config::mat_prealloc);
+    
+    if( (A_use_local_mem == false) && (B_use_local_mem == false) )
+      {
+      std::swap( access::rw(A.mem), access::rw(B.mem) );
+      }
+    else
+    if( (A_use_local_mem == true) && (B_use_local_mem == true) )
+      {
+      const uword N = (std::max)(A_n_elem, B_n_elem);
+      
+      eT* A_mem = A.memptr();
+      eT* B_mem = B.memptr();
+      
+      for(uword ii=0; ii < N; ++ii)  { std::swap( A_mem[ii], B_mem[ii] ); }
+      }
+    else
+    if( (A_use_local_mem == true) && (B_use_local_mem == false) )
+      {
+      eT* A_mem_local = &(A.mem_local[0]);
+      eT* B_mem_local = &(B.mem_local[0]);
+      
+      arrayops::copy(B_mem_local, A_mem_local, A_n_elem);
+      
+      access::rw(A.mem) = B.mem;
+      access::rw(B.mem) = B_mem_local;
+      }
+    else
+    if( (A_use_local_mem == false) && (B_use_local_mem == true) )
+      {
+      eT* A_mem_local = &(A.mem_local[0]);
+      eT* B_mem_local = &(B.mem_local[0]);
+      
+      arrayops::copy(A_mem_local, B_mem_local, B_n_elem);
+      
+      access::rw(B.mem) = A.mem;
+      access::rw(A.mem) = A_mem_local;
+      }
+    
+    std::swap( access::rw(A.n_rows), access::rw(B.n_rows) );
+    std::swap( access::rw(A.n_cols), access::rw(B.n_cols) );
+    std::swap( access::rw(A.n_elem), access::rw(B.n_elem) );
+    }
+  else
+  if( (A_mem_state == 3) && (B_mem_state == 3) )
+    {
+    arma_debug_check( ((A.n_rows != B.n_rows) || (A.n_cols != B.n_cols)), "Mat::swap(): incompatible object types" );
+    
+    const uword N = A.n_elem;
+    
+    eT* A_mem = A.memptr();
+    eT* B_mem = B.memptr();
+    
+    for(uword ii=0; ii < N; ++ii)  { std::swap(A_mem[ii], B_mem[ii]); }
+    }
+  else
+    {
+    arma_bad("Mat::swap(): incompatible object types");
+    }
+  }
+
+
+
+//! try to steal the memory from a given matrix; 
+//! if memory can't be stolen, copy the given matrix
+template<typename eT>
+inline
+void
+Mat<eT>::steal_mem(Mat<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(this != &x)
+    {
+    const uword x_n_rows    = x.n_rows;
+    const uword x_n_cols    = x.n_cols;
+    const uword x_n_elem    = x.n_elem;
+    const uword x_vec_state = x.vec_state;
+    const uword x_mem_state = x.mem_state;
+    
+    const uword t_vec_state = vec_state;
+    
+    bool layout_ok = false;
+    
+    if(t_vec_state == x_vec_state)
+      {
+      layout_ok = true;
+      }
+    else
+      {
+      if( (t_vec_state == 1) && ( x_n_cols == 1) )
+        {
+        layout_ok = true;
+        }
+      
+      if( (t_vec_state == 2) && ( x_n_rows == 1) )
+        {
+        layout_ok = true;
+        }
+      }
+    
+    
+    if( (x_mem_state == 0) && (x_n_elem > arma_config::mat_prealloc) && (layout_ok == true) )
+      {
+      reset();
+      // note: calling reset() also prevents fixed size matrices from changing size or using non-local memory
+      
+      access::rw(n_rows) = x_n_rows;
+      access::rw(n_cols) = x_n_cols;
+      access::rw(n_elem) = x_n_elem;
+      access::rw(mem)    = x.mem;
+      
+      access::rw(x.n_rows) = 0;
+      access::rw(x.n_cols) = 0;
+      access::rw(x.n_elem) = 0;
+      access::rw(x.mem)    = 0;
+      }
+    else
+      {
+      (*this).operator=(x);
+      }
+    }
+  }
+
+
+
+//! construct a matrix from a given auxiliary array of eTs.
+//! if copy_aux_mem is true, new memory is allocated and the array is copied.
+//! if copy_aux_mem is false, the auxiliary array is used directly (without allocating memory and copying).
+//! the default is to copy the array.
+
+template<typename eT>
+inline
+Mat<eT>::Mat(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const bool copy_aux_mem, const bool strict)
+  : n_rows   ( aux_n_rows                            )
+  , n_cols   ( aux_n_cols                            )
+  , n_elem   ( aux_n_rows*aux_n_cols                 )
+  , vec_state( 0                                     )
+  , mem_state( copy_aux_mem ? 0 : ( strict ? 2 : 1 ) )
+  , mem      ( copy_aux_mem ? 0 : aux_mem            )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  if(copy_aux_mem == true)
+    {
+    init_cold();
+    
+    arrayops::copy( memptr(), aux_mem, n_elem );
+    }
+  }
+
+
+
+//! construct a matrix from a given auxiliary read-only array of eTs.
+//! the array is copied.
+template<typename eT>
+inline
+Mat<eT>::Mat(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols)
+  : n_rows(aux_n_rows)
+  , n_cols(aux_n_cols)
+  , n_elem(aux_n_rows*aux_n_cols)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold();
+  
+  arrayops::copy( memptr(), aux_mem, n_elem );
+  }
+
+
+
+//! DANGEROUS! Construct a temporary matrix, using auxiliary memory.
+//! This constructor is NOT intended for usage by user code.
+//! Its sole purpose is to be used by the Cube class.
+
+template<typename eT>
+inline
+Mat<eT>::Mat(const char junk, const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols)
+  : n_rows   (aux_n_rows           )
+  , n_cols   (aux_n_cols           )
+  , n_elem   (aux_n_rows*aux_n_cols)
+  , vec_state(0                    )
+  , mem_state(3                    )
+  , mem      (aux_mem              )
+  {
+  arma_extra_debug_sigprint_this(this);
+  arma_ignore(junk);
+  }
+
+
+
+//! in-place matrix addition
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const Mat<eT>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(*this, m, "addition");
+  
+  arrayops::inplace_plus( memptr(), m.memptr(), n_elem );
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix subtraction
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const Mat<eT>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(*this, m, "subtraction");
+  
+  arrayops::inplace_minus( memptr(), m.memptr(), n_elem );
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix multiplication
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const Mat<eT>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  glue_times::apply_inplace(*this, m);
+  
+  return *this;
+  }
+
+
+
+//! in-place element-wise matrix multiplication
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const Mat<eT>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(*this, m, "element-wise multiplication");
+  
+  arrayops::inplace_mul( memptr(), m.memptr(), n_elem );
+  
+  return *this;
+  }
+
+
+
+//! in-place element-wise matrix division
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const Mat<eT>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(*this, m, "element-wise division");
+  
+  arrayops::inplace_div( memptr(), m.memptr(), n_elem );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+Mat<eT>::Mat(const BaseCube<eT,T1>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  (*this).operator=(X);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const BaseCube<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& out = *this;
+  
+  const unwrap_cube<T1> tmp(X.get_ref());
+  const Cube<eT>& in  = tmp.M;
+  
+  arma_debug_assert_cube_as_mat(out, in, "copy into matrix", false);
+  
+  const uword in_n_rows   = in.n_rows;
+  const uword in_n_cols   = in.n_cols;
+  const uword in_n_slices = in.n_slices;
+  
+  const uword out_vec_state = out.vec_state;
+  
+  if(in_n_slices == 1)
+    {
+    out.set_size(in_n_rows, in_n_cols);
+    
+    for(uword ucol=0; ucol < in_n_cols; ++ucol)
+      {
+      arrayops::copy( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows );
+      }
+    }
+  else
+    {
+    if(out_vec_state == 0)
+      {
+      if(in_n_cols == 1)
+        {
+        out.set_size(in_n_rows, in_n_slices);
+        
+        for(uword i=0; i < in_n_slices; ++i)
+          {
+          arrayops::copy( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
+          }
+        }
+      else
+      if(in_n_rows == 1)
+        {
+        out.set_size(in_n_cols, in_n_slices);
+        
+        for(uword slice=0; slice < in_n_slices; ++slice)
+          {
+          eT* out_colptr = out.colptr(slice);
+          
+          uword i,j;
+          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
+            {
+            const eT tmp_i = in.at(0, i, slice);
+            const eT tmp_j = in.at(0, j, slice);
+            
+            out_colptr[i] = tmp_i;
+            out_colptr[j] = tmp_j;
+            }
+          
+          if(i < in_n_cols)
+            {
+            out_colptr[i] = in.at(0, i, slice);
+            }
+          }
+        }
+      }
+    else
+      {
+      out.set_size(in_n_slices);
+      
+      eT* out_mem = out.memptr();
+      
+      for(uword i=0; i<in_n_slices; ++i)
+        {
+        out_mem[i] = in.at(0, 0, i);
+        }
+      }
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const BaseCube<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& out = *this;
+  
+  const unwrap_cube<T1> tmp(X.get_ref());
+  const Cube<eT>& in  = tmp.M;
+  
+  arma_debug_assert_cube_as_mat(out, in, "addition", true);
+  
+  const uword in_n_rows   = in.n_rows;
+  const uword in_n_cols   = in.n_cols;
+  const uword in_n_slices = in.n_slices;
+  
+  const uword out_n_rows    = out.n_rows;
+  const uword out_n_cols    = out.n_cols;
+  const uword out_vec_state = out.vec_state;
+  
+  if(in_n_slices == 1)
+    {
+    for(uword ucol=0; ucol < in_n_cols; ++ucol)
+      {
+      arrayops::inplace_plus( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows );
+      }
+    }
+  else
+    {
+    if(out_vec_state == 0)
+      {
+      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
+        {
+        for(uword i=0; i < in_n_slices; ++i)
+          {
+          arrayops::inplace_plus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
+          }
+        }
+      else
+      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
+        {
+        for(uword slice=0; slice < in_n_slices; ++slice)
+          {
+          eT* out_colptr = out.colptr(slice);
+          
+          uword i,j;
+          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
+            {
+            const eT tmp_i = in.at(0, i, slice);
+            const eT tmp_j = in.at(0, j, slice);
+            
+            out_colptr[i] += tmp_i;
+            out_colptr[j] += tmp_j;
+            }
+          
+          if(i < in_n_cols)
+            {
+            out_colptr[i] += in.at(0, i, slice);
+            }
+          }
+        }
+      }
+    else
+      {
+      eT* out_mem = out.memptr();
+      
+      for(uword i=0; i<in_n_slices; ++i)
+        {
+        out_mem[i] += in.at(0, 0, i);
+        }
+      }
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const BaseCube<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& out = *this;
+  
+  const unwrap_cube<T1> tmp(X.get_ref());
+  const Cube<eT>& in  = tmp.M;
+  
+  arma_debug_assert_cube_as_mat(out, in, "subtraction", true);
+  
+  const uword in_n_rows   = in.n_rows;
+  const uword in_n_cols   = in.n_cols;
+  const uword in_n_slices = in.n_slices;
+  
+  const uword out_n_rows    = out.n_rows;
+  const uword out_n_cols    = out.n_cols;
+  const uword out_vec_state = out.vec_state;
+  
+  if(in_n_slices == 1)
+    {
+    for(uword ucol=0; ucol < in_n_cols; ++ucol)
+      {
+      arrayops::inplace_minus( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows );
+      }
+    }
+  else
+    {
+    if(out_vec_state == 0)
+      {
+      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
+        {
+        for(uword i=0; i < in_n_slices; ++i)
+          {
+          arrayops::inplace_minus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
+          }
+        }
+      else
+      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
+        {
+        for(uword slice=0; slice < in_n_slices; ++slice)
+          {
+          eT* out_colptr = out.colptr(slice);
+          
+          uword i,j;
+          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
+            {
+            const eT tmp_i = in.at(0, i, slice);
+            const eT tmp_j = in.at(0, j, slice);
+            
+            out_colptr[i] -= tmp_i;
+            out_colptr[j] -= tmp_j;
+            }
+          
+          if(i < in_n_cols)
+            {
+            out_colptr[i] -= in.at(0, i, slice);
+            }
+          }
+        }
+      }
+    else
+      {
+      eT* out_mem = out.memptr();
+      
+      for(uword i=0; i<in_n_slices; ++i)
+        {
+        out_mem[i] -= in.at(0, 0, i);
+        }
+      }
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const BaseCube<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> B(X);
+  
+  (*this).operator*=(B);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const BaseCube<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& out = *this;
+  
+  const unwrap_cube<T1> tmp(X.get_ref());
+  const Cube<eT>& in  = tmp.M;
+  
+  arma_debug_assert_cube_as_mat(out, in, "element-wise multiplication", true);
+  
+  const uword in_n_rows   = in.n_rows;
+  const uword in_n_cols   = in.n_cols;
+  const uword in_n_slices = in.n_slices;
+  
+  const uword out_n_rows    = out.n_rows;
+  const uword out_n_cols    = out.n_cols;
+  const uword out_vec_state = out.vec_state;
+  
+  if(in_n_slices == 1)
+    {
+    for(uword ucol=0; ucol < in_n_cols; ++ucol)
+      {
+      arrayops::inplace_mul( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows );
+      }
+    }
+  else
+    {
+    if(out_vec_state == 0)
+      {
+      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
+        {
+        for(uword i=0; i < in_n_slices; ++i)
+          {
+          arrayops::inplace_mul( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
+          }
+        }
+      else
+      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
+        {
+        for(uword slice=0; slice < in_n_slices; ++slice)
+          {
+          eT* out_colptr = out.colptr(slice);
+          
+          uword i,j;
+          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
+            {
+            const eT tmp_i = in.at(0, i, slice);
+            const eT tmp_j = in.at(0, j, slice);
+            
+            out_colptr[i] *= tmp_i;
+            out_colptr[j] *= tmp_j;
+            }
+          
+          if(i < in_n_cols)
+            {
+            out_colptr[i] *= in.at(0, i, slice);
+            }
+          }
+        }
+      }
+    else
+      {
+      eT* out_mem = out.memptr();
+      
+      for(uword i=0; i<in_n_slices; ++i)
+        {
+        out_mem[i] *= in.at(0, 0, i);
+        }
+      }
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const BaseCube<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& out = *this;
+  
+  const unwrap_cube<T1> tmp(X.get_ref());
+  const Cube<eT>& in  = tmp.M;
+  
+  arma_debug_assert_cube_as_mat(out, in, "element-wise division", true);
+  
+  const uword in_n_rows   = in.n_rows;
+  const uword in_n_cols   = in.n_cols;
+  const uword in_n_slices = in.n_slices;
+  
+  const uword out_n_rows    = out.n_rows;
+  const uword out_n_cols    = out.n_cols;
+  const uword out_vec_state = out.vec_state;
+  
+  if(in_n_slices == 1)
+    {
+    for(uword ucol=0; ucol < in_n_cols; ++ucol)
+      {
+      arrayops::inplace_div( out.colptr(ucol), in.slice_colptr(0, ucol), in_n_rows );
+      }
+    }
+  else
+    {
+    if(out_vec_state == 0)
+      {
+      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
+        {
+        for(uword i=0; i < in_n_slices; ++i)
+          {
+          arrayops::inplace_div( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
+          }
+        }
+      else
+      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
+        {
+        for(uword slice=0; slice < in_n_slices; ++slice)
+          {
+          eT* out_colptr = out.colptr(slice);
+          
+          uword i,j;
+          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
+            {
+            const eT tmp_i = in.at(0, i, slice);
+            const eT tmp_j = in.at(0, j, slice);
+            
+            out_colptr[i] /= tmp_i;
+            out_colptr[j] /= tmp_j;
+            }
+          
+          if(i < in_n_cols)
+            {
+            out_colptr[i] /= in.at(0, i, slice);
+            }
+          }
+        }
+      }
+    else
+      {
+      eT* out_mem = out.memptr();
+      
+      for(uword i=0; i<in_n_slices; ++i)
+        {
+        out_mem[i] /= in.at(0, 0, i);
+        }
+      }
+    }
+  
+  return *this;
+  }
+
+
+
+//! for constructing a complex matrix out of two non-complex matrices
+template<typename eT>
+template<typename T1, typename T2>
+inline
+Mat<eT>::Mat
+  (
+  const Base<typename Mat<eT>::pod_type,T1>& A,
+  const Base<typename Mat<eT>::pod_type,T2>& B
+  )
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init(A,B);
+  }
+
+
+
+//! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation)
+template<typename eT>
+inline
+Mat<eT>::Mat(const subview<eT>& X)
+  : n_rows(X.n_rows)
+  , n_cols(X.n_cols)
+  , n_elem(X.n_elem)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold();
+  
+  subview<eT>::extract(*this, X);
+  }
+
+
+
+//! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool alias = (this == &(X.m));
+  
+  if(alias == false)
+    {
+    init_warm(X.n_rows, X.n_cols);
+    
+    subview<eT>::extract(*this, X);
+    }
+  else
+    {
+    Mat<eT> tmp(X);
+    
+    steal_mem(tmp);
+    }
+  
+  return *this;
+  }
+
+
+//! in-place matrix addition (using a submatrix on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview<eT>::plus_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+//! in-place matrix subtraction (using a submatrix on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview<eT>::minus_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix mutiplication (using a submatrix on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  glue_times::apply_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place element-wise matrix mutiplication (using a submatrix on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview<eT>::schur_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place element-wise matrix division (using a submatrix on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview<eT>::div_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+Mat<eT>::Mat(const subview_row_strans<eT>& X)
+  : n_rows(X.n_rows)
+  , n_cols(X.n_cols)
+  , n_elem(X.n_elem)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold();
+  
+  X.extract(*this);
+  }
+
+
+
+template<typename eT>
+inline
+Mat<eT>::Mat(const subview_row_htrans<eT>& X)
+  : n_rows(X.n_rows)
+  , n_cols(X.n_cols)
+  , n_elem(X.n_elem)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold();
+  
+  X.extract(*this);
+  }
+
+
+
+template<typename eT>
+inline
+Mat<eT>::Mat(const xvec_htrans<eT>& X)
+  : n_rows(X.n_rows)
+  , n_cols(X.n_cols)
+  , n_elem(X.n_elem)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold();
+  
+  X.extract(*this);
+  }
+
+
+
+//! construct a matrix from a subview_cube instance
+template<typename eT>
+inline
+Mat<eT>::Mat(const subview_cube<eT>& x)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  this->operator=(x);
+  }
+
+
+
+//! construct a matrix from a subview_cube instance
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_cube<eT>::extract(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix addition (using a single-slice subcube on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  subview_cube<eT>::plus_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix subtraction (using a single-slice subcube on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_cube<eT>::minus_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix mutiplication (using a single-slice subcube on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  const Mat<eT> tmp(X);
+  glue_times::apply_inplace(*this, tmp);
+  
+  return *this;
+  }
+
+
+
+//! in-place element-wise matrix mutiplication (using a single-slice subcube on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_cube<eT>::schur_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place element-wise matrix division (using a single-slice subcube on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_cube<eT>::div_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation)
+template<typename eT>
+inline
+Mat<eT>::Mat(const diagview<eT>& X)
+  : n_rows(X.n_rows)
+  , n_cols(X.n_cols)
+  , n_elem(X.n_elem)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold();
+  
+  diagview<eT>::extract(*this, X);
+  }
+
+
+
+//! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const diagview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool alias = (this == &(X.m));
+  
+  if(alias == false)
+    {
+    init_warm(X.n_rows, X.n_cols);
+    
+    diagview<eT>::extract(*this, X);
+    }
+  else
+    {
+    Mat<eT> tmp(X);
+    
+    steal_mem(tmp);
+    }
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix addition (using a diagview on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const diagview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  diagview<eT>::plus_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+//! in-place matrix subtraction (using a diagview on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const diagview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  diagview<eT>::minus_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix mutiplication (using a diagview on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const diagview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  glue_times::apply_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place element-wise matrix mutiplication (using a diagview on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const diagview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  diagview<eT>::schur_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place element-wise matrix division (using a diagview on the right-hand-side)
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const diagview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  diagview<eT>::div_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+Mat<eT>::Mat(const subview_elem1<eT,T1>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  this->operator=(X);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const subview_elem1<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_elem1<eT,T1>::extract(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const subview_elem1<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_elem1<eT,T1>::plus_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const subview_elem1<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_elem1<eT,T1>::minus_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const subview_elem1<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  glue_times::apply_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const subview_elem1<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_elem1<eT,T1>::schur_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const subview_elem1<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_elem1<eT,T1>::div_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+inline
+Mat<eT>::Mat(const subview_elem2<eT,T1,T2>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  this->operator=(X);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const subview_elem2<eT,T1,T2>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_elem2<eT,T1,T2>::extract(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const subview_elem2<eT,T1,T2>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_elem2<eT,T1,T2>::plus_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const subview_elem2<eT,T1,T2>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_elem2<eT,T1,T2>::minus_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const subview_elem2<eT,T1,T2>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  glue_times::apply_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const subview_elem2<eT,T1,T2>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_elem2<eT,T1,T2>::schur_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const subview_elem2<eT,T1,T2>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_elem2<eT,T1,T2>::div_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+Mat<eT>::Mat(const SpBase<eT, T1>& m)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  const SpProxy<T1> p(m.get_ref());
+  
+  access::rw(n_rows) = p.get_n_rows();
+  access::rw(n_cols) = p.get_n_cols();
+  access::rw(n_elem) = p.get_n_elem();
+  
+  init_cold();
+  fill(eT(0));
+  
+  typename SpProxy<T1>::const_iterator_type it     = p.begin();
+  typename SpProxy<T1>::const_iterator_type it_end = p.end();
+  
+  while(it != it_end)
+    {
+    at(it.row(), it.col()) = (*it);
+    ++it;
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const SpBase<eT, T1>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> p(m.get_ref());
+  
+  init_warm(p.get_n_rows(), p.get_n_cols());
+  
+  fill(eT(0));
+  
+  typename SpProxy<T1>::const_iterator_type it     = p.begin();
+  typename SpProxy<T1>::const_iterator_type it_end = p.end();
+  
+  while(it != it_end)
+    {
+    at(it.row(), it.col()) = (*it);
+    ++it;
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const SpBase<eT, T1>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> p(m.get_ref());
+  
+  arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "addition");
+  
+  typename SpProxy<T1>::const_iterator_type it     = p.begin();
+  typename SpProxy<T1>::const_iterator_type it_end = p.end();
+  
+  while(it != it_end)
+    {
+    at(it.row(), it.col()) += (*it);
+    ++it;
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const SpBase<eT, T1>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> p(m.get_ref());
+  
+  arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "subtraction");
+  
+  typename SpProxy<T1>::const_iterator_type it     = p.begin();
+  typename SpProxy<T1>::const_iterator_type it_end = p.end();
+  
+  while(it != it_end)
+    {
+    at(it.row(), it.col()) -= (*it);
+    ++it;
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const SpBase<eT, T1>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT> z;
+  z = (*this) * m.get_ref();
+  steal_mem(z);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const SpBase<eT, T1>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> p(m.get_ref());
+  
+  arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise multiplication");
+  
+  typename SpProxy<T1>::const_iterator_type it     = p.begin();
+  typename SpProxy<T1>::const_iterator_type it_end = p.end();
+  
+  // We have to zero everything that isn't being used.
+  arrayops::inplace_set(memptr(), eT(0), (it.col() * n_rows) + it.row());
+  
+  while(it != it_end)
+    {
+    const uword cur_loc = (it.col() * n_rows) + it.row();
+    
+    access::rw(mem[cur_loc]) *= (*it);
+    
+    ++it;
+    
+    const uword next_loc = (it == it_end)
+      ? (p.get_n_cols() * n_rows)
+      : (it.col() * n_rows) + it.row();
+    
+    arrayops::inplace_set(memptr() + cur_loc + 1, eT(0), (next_loc - cur_loc - 1));
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const SpBase<eT, T1>& m)
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> p(m.get_ref());
+  
+  arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise division");
+  
+  // If you use this method, you are probably stupid or misguided, but for completeness it is implemented.
+  // Unfortunately the best way to do this is loop over every element.
+  for(uword c = 0; c < n_cols; ++c)
+  for(uword r = 0; r < n_rows; ++r)
+    {
+    at(r, c) /= p.at(r, c);
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+mat_injector< Mat<eT> >
+Mat<eT>::operator<<(const eT val)
+  {
+  return mat_injector< Mat<eT> >(*this, val);
+  }
+
+
+
+template<typename eT>
+inline
+mat_injector< Mat<eT> >
+Mat<eT>::operator<<(const injector_end_of_row<>& x)
+  {
+  return mat_injector< Mat<eT> >(*this, x);
+  }
+
+
+
+//! creation of subview (row vector)
+template<typename eT>
+arma_inline
+subview_row<eT>
+Mat<eT>::row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( row_num >= n_rows, "Mat::row(): index out of bounds" );
+  
+  return subview_row<eT>(*this, row_num);
+  }
+
+
+
+//! creation of subview (row vector)
+template<typename eT>
+arma_inline
+const subview_row<eT>
+Mat<eT>::row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( row_num >= n_rows, "Mat::row(): index out of bounds" );
+  
+  return subview_row<eT>(*this, row_num);
+  }
+
+
+
+template<typename eT>
+inline
+subview_row<eT>
+Mat<eT>::operator()(const uword row_num, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_cols = n_cols;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  arma_debug_check
+    (
+    (row_num >= n_rows)
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "Mat::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview_row<eT>(*this, row_num, in_col1, submat_n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+const subview_row<eT>
+Mat<eT>::operator()(const uword row_num, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_cols = n_cols;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  arma_debug_check
+    (
+    (row_num >= n_rows)
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "Mat::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview_row<eT>(*this, row_num, in_col1, submat_n_cols);
+  }
+
+
+
+//! creation of subview (column vector)
+template<typename eT>
+arma_inline
+subview_col<eT>
+Mat<eT>::col(const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( col_num >= n_cols, "Mat::col(): index out of bounds");
+  
+  return subview_col<eT>(*this, col_num);
+  }
+
+
+
+//! creation of subview (column vector)
+template<typename eT>
+arma_inline
+const subview_col<eT>
+Mat<eT>::col(const uword col_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( col_num >= n_cols, "Mat::col(): index out of bounds");
+  
+  return subview_col<eT>(*this, col_num);
+  }
+
+
+
+template<typename eT>
+inline
+subview_col<eT>
+Mat<eT>::operator()(const span& row_span, const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  arma_debug_check
+    (
+    (col_num >= n_cols)
+    ||
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ,
+    "Mat::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview_col<eT>(*this, col_num, in_row1, submat_n_rows);
+  }
+
+
+
+template<typename eT>
+inline
+const subview_col<eT>
+Mat<eT>::operator()(const span& row_span, const uword col_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  arma_debug_check
+    (
+    (col_num >= n_cols)
+    ||
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ,
+    "Mat::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview_col<eT>(*this, col_num, in_row1, submat_n_rows);
+  }
+
+
+
+//! create a Col object which uses memory from an existing matrix object.
+//! this approach is currently not alias safe
+//! and does not take into account that the parent matrix object could be deleted.
+//! if deleted memory is accessed by the created Col object,
+//! it will cause memory corruption and/or a crash
+template<typename eT>
+inline
+Col<eT>
+Mat<eT>::unsafe_col(const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( col_num >= n_cols, "Mat::unsafe_col(): index out of bounds");
+  
+  return Col<eT>(colptr(col_num), n_rows, false, true);
+  }
+
+
+
+//! create a Col object which uses memory from an existing matrix object.
+//! this approach is currently not alias safe
+//! and does not take into account that the parent matrix object could be deleted.
+//! if deleted memory is accessed by the created Col object,
+//! it will cause memory corruption and/or a crash
+template<typename eT>
+inline
+const Col<eT>
+Mat<eT>::unsafe_col(const uword col_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( col_num >= n_cols, "Mat::unsafe_col(): index out of bounds");
+  
+  typedef const Col<eT> out_type;
+  
+  return out_type(const_cast<eT*>(colptr(col_num)), n_rows, false, true);
+  }
+
+
+
+//! creation of subview (submatrix comprised of specified row vectors)
+template<typename eT>
+arma_inline
+subview<eT>
+Mat<eT>::rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_row2 >= n_rows),
+    "Mat::rows(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  return subview<eT>(*this, in_row1, 0, subview_n_rows, n_cols );
+  }
+
+
+
+//! creation of subview (submatrix comprised of specified row vectors)
+template<typename eT>
+arma_inline
+const subview<eT>
+Mat<eT>::rows(const uword in_row1, const uword in_row2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_row2 >= n_rows),
+    "Mat::rows(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  return subview<eT>(*this, in_row1, 0, subview_n_rows, n_cols );
+  }
+
+
+
+//! creation of subview (submatrix comprised of specified column vectors)
+template<typename eT>
+arma_inline
+subview<eT>
+Mat<eT>::cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_col1 > in_col2) || (in_col2 >= n_cols),
+    "Mat::cols(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview<eT>(*this, 0, in_col1, n_rows, subview_n_cols);
+  }
+
+
+
+//! creation of subview (submatrix comprised of specified column vectors)
+template<typename eT>
+arma_inline
+const subview<eT>
+Mat<eT>::cols(const uword in_col1, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_col1 > in_col2) || (in_col2 >= n_cols),
+    "Mat::cols(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview<eT>(*this, 0, in_col1, n_rows, subview_n_cols);
+  }
+
+
+
+//! creation of subview (submatrix)
+template<typename eT>
+arma_inline
+subview<eT>
+Mat<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
+    "Mat::submat(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview<eT>(*this, in_row1, in_col1, subview_n_rows, subview_n_cols);
+  }
+
+
+
+//! creation of subview (generic submatrix)
+template<typename eT>
+arma_inline
+const subview<eT>
+Mat<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
+    "Mat::submat(): indices out of bounds or incorrectly used"
+    );
+    
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview<eT>(*this, in_row1, in_col1, subview_n_rows, subview_n_cols);
+  }
+
+
+
+//! creation of subview (submatrix)
+template<typename eT>
+inline
+subview<eT>
+Mat<eT>::submat(const span& row_span, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  const uword local_n_cols = n_cols;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  arma_debug_check
+    (
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "Mat::submat(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview<eT>(*this, in_row1, in_col1, submat_n_rows, submat_n_cols);
+  }
+
+
+
+//! creation of subview (generic submatrix)
+template<typename eT>
+inline
+const subview<eT>
+Mat<eT>::submat(const span& row_span, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  const uword local_n_cols = n_cols;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  arma_debug_check
+    (
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "Mat::submat(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview<eT>(*this, in_row1, in_col1, submat_n_rows, submat_n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+subview<eT>
+Mat<eT>::operator()(const span& row_span, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).submat(row_span, col_span);
+  }
+
+
+
+template<typename eT>
+inline
+const subview<eT>
+Mat<eT>::operator()(const span& row_span, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).submat(row_span, col_span);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+arma_inline
+subview_elem1<eT,T1>
+Mat<eT>::elem(const Base<uword,T1>& a)
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem1<eT,T1>(*this, a);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+arma_inline
+const subview_elem1<eT,T1>
+Mat<eT>::elem(const Base<uword,T1>& a) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem1<eT,T1>(*this, a);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+arma_inline
+subview_elem1<eT,T1>
+Mat<eT>::operator()(const Base<uword,T1>& a)
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem1<eT,T1>(*this, a);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+arma_inline
+const subview_elem1<eT,T1>
+Mat<eT>::operator()(const Base<uword,T1>& a) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem1<eT,T1>(*this, a);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+arma_inline
+subview_elem2<eT,T1,T2>
+Mat<eT>::elem(const Base<uword,T1>& ri, const Base<uword,T2>& ci)
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem2<eT,T1,T2>(*this, ri, ci, false, false);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+arma_inline
+const subview_elem2<eT,T1,T2>
+Mat<eT>::elem(const Base<uword,T1>& ri, const Base<uword,T2>& ci) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem2<eT,T1,T2>(*this, ri, ci, false, false);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+arma_inline
+subview_elem2<eT,T1,T2>
+Mat<eT>::submat(const Base<uword,T1>& ri, const Base<uword,T2>& ci)
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem2<eT,T1,T2>(*this, ri, ci, false, false);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+arma_inline
+const subview_elem2<eT,T1,T2>
+Mat<eT>::submat(const Base<uword,T1>& ri, const Base<uword,T2>& ci) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem2<eT,T1,T2>(*this, ri, ci, false, false);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+arma_inline
+subview_elem2<eT,T1,T2>
+Mat<eT>::operator()(const Base<uword,T1>& ri, const Base<uword,T2>& ci)
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem2<eT,T1,T2>(*this, ri, ci, false, false);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+arma_inline
+const subview_elem2<eT,T1,T2>
+Mat<eT>::operator()(const Base<uword,T1>& ri, const Base<uword,T2>& ci) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem2<eT,T1,T2>(*this, ri, ci, false, false);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+arma_inline
+subview_elem2<eT,T1,T1>
+Mat<eT>::rows(const Base<uword,T1>& ri)
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem2<eT,T1,T1>(*this, ri, ri, false, true);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+arma_inline
+const subview_elem2<eT,T1,T1>
+Mat<eT>::rows(const Base<uword,T1>& ri) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem2<eT,T1,T1>(*this, ri, ri, false, true);
+  }
+
+
+
+template<typename eT>
+template<typename T2>
+arma_inline
+subview_elem2<eT,T2,T2>
+Mat<eT>::cols(const Base<uword,T2>& ci)
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem2<eT,T2,T2>(*this, ci, ci, true, false);
+  }
+
+
+
+template<typename eT>
+template<typename T2>
+arma_inline
+const subview_elem2<eT,T2,T2>
+Mat<eT>::cols(const Base<uword,T2>& ci) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_elem2<eT,T2,T2>(*this, ci, ci, true, false);
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_each1< Mat<eT>, 0 >
+Mat<eT>::each_col()
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_each1< Mat<eT>, 0>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_each1< Mat<eT>, 1 >
+Mat<eT>::each_row()
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_each1< Mat<eT>, 1>(*this);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+subview_each2< Mat<eT>, 0, T1 >
+Mat<eT>::each_col(const Base<uword, T1>& indices)
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_each2< Mat<eT>, 0, T1 >(*this, indices);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+subview_each2< Mat<eT>, 1, T1 >
+Mat<eT>::each_row(const Base<uword, T1>& indices)
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_each2< Mat<eT>, 1, T1 >(*this, indices);
+  }
+
+
+
+//! creation of diagview (diagonal)
+template<typename eT>
+arma_inline
+diagview<eT>
+Mat<eT>::diag(const sword in_id)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword row_offset = (in_id < 0) ? uword(-in_id) : 0;
+  const uword col_offset = (in_id > 0) ? uword( in_id) : 0;
+  
+  arma_debug_check
+    (
+    ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
+    "Mat::diag(): requested diagonal out of bounds"
+    );
+  
+  const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
+  
+  return diagview<eT>(*this, row_offset, col_offset, len);
+  }
+
+
+
+//! creation of diagview (diagonal)
+template<typename eT>
+arma_inline
+const diagview<eT>
+Mat<eT>::diag(const sword in_id) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword row_offset = (in_id < 0) ? -in_id : 0;
+  const uword col_offset = (in_id > 0) ?  in_id : 0;
+  
+  arma_debug_check
+    (
+    ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
+    "Mat::diag(): requested diagonal out of bounds"
+    );
+  
+  const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
+  
+  return diagview<eT>(*this, row_offset, col_offset, len);
+  }
+
+
+
+template<typename eT>
+inline
+void
+Mat<eT>::swap_rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword local_n_rows = n_rows;
+  const uword local_n_cols = n_cols;
+  
+  arma_debug_check
+    (
+    (in_row1 >= local_n_rows) || (in_row2 >= local_n_rows),
+    "Mat::swap_rows(): index out of bounds"
+    );
+  
+  if(n_elem > 0)
+    {
+    for(uword ucol=0; ucol < local_n_cols; ++ucol)
+      {
+      const uword offset = ucol * local_n_rows;
+      const uword pos1   = in_row1 + offset;
+      const uword pos2   = in_row2 + offset;
+      
+      std::swap( access::rw(mem[pos1]), access::rw(mem[pos2]) );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+Mat<eT>::swap_cols(const uword in_colA, const uword in_colB)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword local_n_rows = n_rows;
+  const uword local_n_cols = n_cols;
+  
+  arma_debug_check
+    (
+    (in_colA >= local_n_cols) || (in_colB >= local_n_cols),
+    "Mat::swap_cols(): index out of bounds"
+    );
+  
+  if(n_elem > 0)
+    {
+    eT* ptrA = colptr(in_colA);
+    eT* ptrB = colptr(in_colB);
+    
+    eT tmp_i;
+    eT tmp_j;
+    
+    uword iq,jq;
+    for(iq=0, jq=1; jq < local_n_rows; iq+=2, jq+=2)
+      {
+      tmp_i = ptrA[iq];
+      tmp_j = ptrA[jq];
+      
+      ptrA[iq] = ptrB[iq];
+      ptrA[jq] = ptrB[jq];
+      
+      ptrB[iq] = tmp_i;
+      ptrB[jq] = tmp_j;
+      }
+    
+    if(iq < local_n_rows)
+      {
+      std::swap( ptrA[iq], ptrB[iq] );
+      }
+    }
+  }
+
+
+
+//! remove specified row
+template<typename eT>
+inline
+void
+Mat<eT>::shed_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( row_num >= n_rows, "Mat::shed_row(): index out of bounds");
+  
+  shed_rows(row_num, row_num);
+  }
+
+
+
+//! remove specified column
+template<typename eT>
+inline
+void
+Mat<eT>::shed_col(const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( col_num >= n_cols, "Mat::shed_col(): index out of bounds");
+  
+  shed_cols(col_num, col_num);
+  }
+
+
+
+//! remove specified rows
+template<typename eT>
+inline
+void
+Mat<eT>::shed_rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_row2 >= n_rows),
+    "Mat::shed_rows(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword n_keep_front = in_row1;
+  const uword n_keep_back  = n_rows - (in_row2 + 1);
+  
+  Mat<eT> X(n_keep_front + n_keep_back, n_cols);
+  
+  if(n_keep_front > 0)
+    {
+    X.rows( 0, (n_keep_front-1) ) = rows( 0, (in_row1-1) );
+    }
+  
+  if(n_keep_back > 0)
+    {
+    X.rows( n_keep_front,  (n_keep_front+n_keep_back-1) ) = rows( (in_row2+1), (n_rows-1) );
+    }
+  
+  steal_mem(X);
+  }
+
+
+
+//! remove specified columns
+template<typename eT>
+inline
+void
+Mat<eT>::shed_cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_col1 > in_col2) || (in_col2 >= n_cols),
+    "Mat::shed_cols(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword n_keep_front = in_col1;
+  const uword n_keep_back  = n_cols - (in_col2 + 1);
+  
+  Mat<eT> X(n_rows, n_keep_front + n_keep_back);
+  
+  if(n_keep_front > 0)
+    {
+    X.cols( 0, (n_keep_front-1) ) = cols( 0, (in_col1-1) );
+    }
+  
+  if(n_keep_back > 0)
+    {
+    X.cols( n_keep_front,  (n_keep_front+n_keep_back-1) ) = cols( (in_col2+1), (n_cols-1) );
+    }
+  
+  steal_mem(X);
+  }
+
+
+
+//! insert N rows at the specified row position,
+//! optionally setting the elements of the inserted rows to zero
+template<typename eT>
+inline
+void
+Mat<eT>::insert_rows(const uword row_num, const uword N, const bool set_to_zero)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword t_n_rows = n_rows;
+  const uword t_n_cols = n_cols;
+  
+  const uword A_n_rows = row_num;
+  const uword B_n_rows = t_n_rows - row_num;
+  
+  // insertion at row_num == n_rows is in effect an append operation
+  arma_debug_check( (row_num > t_n_rows), "Mat::insert_rows(): index out of bounds");
+  
+  if(N > 0)
+    {
+    Mat<eT> out(t_n_rows + N, t_n_cols);
+    
+    if(A_n_rows > 0)
+      {
+      out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1);
+      }
+    
+    if(B_n_rows > 0)
+      {
+      out.rows(row_num + N, t_n_rows + N - 1) = rows(row_num, t_n_rows-1);
+      }
+    
+    if(set_to_zero == true)
+      {
+      out.rows(row_num, row_num + N - 1).zeros();
+      }
+    
+    steal_mem(out);
+    }
+  }
+
+
+
+//! insert N columns at the specified column position,
+//! optionally setting the elements of the inserted columns to zero
+template<typename eT>
+inline
+void
+Mat<eT>::insert_cols(const uword col_num, const uword N, const bool set_to_zero)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword t_n_rows = n_rows;
+  const uword t_n_cols = n_cols;
+  
+  const uword A_n_cols = col_num;
+  const uword B_n_cols = t_n_cols - col_num;
+  
+  // insertion at col_num == n_cols is in effect an append operation
+  arma_debug_check( (col_num > t_n_cols), "Mat::insert_cols(): index out of bounds");
+  
+  if(N > 0)
+    {
+    Mat<eT> out(t_n_rows, t_n_cols + N);
+    
+    if(A_n_cols > 0)
+      {
+      out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1);
+      }
+    
+    if(B_n_cols > 0)
+      {
+      out.cols(col_num + N, t_n_cols + N - 1) = cols(col_num, t_n_cols-1);
+      }
+    
+    if(set_to_zero == true)
+      {
+      out.cols(col_num, col_num + N - 1).zeros();
+      }
+    
+    steal_mem(out);
+    }
+  }
+
+
+
+//! insert the given object at the specified row position; 
+//! the given object must have the same number of columns as the matrix
+template<typename eT>
+template<typename T1>
+inline
+void
+Mat<eT>::insert_rows(const uword row_num, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap<T1>   tmp(X.get_ref());
+  const Mat<eT>& C = tmp.M;
+  
+  const uword C_n_rows = C.n_rows;
+  const uword C_n_cols = C.n_cols;
+  
+  const uword t_n_rows = n_rows;
+  const uword t_n_cols = n_cols;
+  
+  const uword A_n_rows = row_num;
+  const uword B_n_rows = t_n_rows - row_num;
+  
+  bool  err_state = false;
+  char* err_msg   = 0;
+  
+  // insertion at row_num == n_rows is in effect an append operation
+  
+  arma_debug_set_error
+    (
+    err_state,
+    err_msg,
+    (row_num > t_n_rows),
+    "Mat::insert_rows(): index out of bounds"
+    );
+  
+  arma_debug_set_error
+    (
+    err_state,
+    err_msg,
+    ( (C_n_cols != t_n_cols) && ( (t_n_rows > 0) || (t_n_cols > 0) ) && ( (C_n_rows > 0) || (C_n_cols > 0) ) ),
+    "Mat::insert_rows(): given object has an incompatible number of columns"
+    );
+  
+  arma_debug_check(err_state, err_msg);
+  
+  if(C_n_rows > 0)
+    {
+    Mat<eT> out( t_n_rows + C_n_rows, (std::max)(t_n_cols, C_n_cols) );
+    
+    if(t_n_cols > 0)
+      {
+      if(A_n_rows > 0)
+        {
+        out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1);
+        }
+      
+      if( (t_n_cols > 0) && (B_n_rows > 0) )
+        {
+        out.rows(row_num + C_n_rows, t_n_rows + C_n_rows - 1) = rows(row_num, t_n_rows - 1);
+        }
+      }
+    
+    if(C_n_cols > 0)
+      {
+      out.rows(row_num, row_num + C_n_rows - 1) = C;
+      }
+    
+    steal_mem(out);
+    }
+  }
+
+
+
+//! insert the given object at the specified column position; 
+//! the given object must have the same number of rows as the matrix
+template<typename eT>
+template<typename T1>
+inline
+void
+Mat<eT>::insert_cols(const uword col_num, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap<T1>   tmp(X.get_ref());
+  const Mat<eT>& C = tmp.M;
+  
+  const uword C_n_rows = C.n_rows;
+  const uword C_n_cols = C.n_cols;
+  
+  const uword t_n_rows = n_rows;
+  const uword t_n_cols = n_cols;
+  
+  const uword A_n_cols = col_num;
+  const uword B_n_cols = t_n_cols - col_num;
+  
+  bool  err_state = false;
+  char* err_msg   = 0;
+  
+  // insertion at col_num == n_cols is in effect an append operation
+  
+  arma_debug_set_error
+    (
+    err_state,
+    err_msg,
+    (col_num > t_n_cols),
+    "Mat::insert_cols(): index out of bounds"
+    );
+  
+  arma_debug_set_error
+    (
+    err_state,
+    err_msg,
+    ( (C_n_rows != t_n_rows) && ( (t_n_rows > 0) || (t_n_cols > 0) ) && ( (C_n_rows > 0) || (C_n_cols > 0) ) ),
+    "Mat::insert_cols(): given object has an incompatible number of rows"
+    );
+  
+  arma_debug_check(err_state, err_msg);
+  
+  if(C_n_cols > 0)
+    {
+    Mat<eT> out( (std::max)(t_n_rows, C_n_rows), t_n_cols + C_n_cols );
+    
+    if(t_n_rows > 0)
+      {
+      if(A_n_cols > 0)
+        {
+        out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1);
+        }
+      
+      if(B_n_cols > 0)
+        {
+        out.cols(col_num + C_n_cols, t_n_cols + C_n_cols - 1) = cols(col_num, t_n_cols - 1);
+        }
+      }
+    
+    if(C_n_rows > 0)
+      {
+      out.cols(col_num, col_num + C_n_cols - 1) = C;
+      }
+    
+    steal_mem(out);
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename gen_type>
+inline
+Mat<eT>::Mat(const Gen<T1, gen_type>& X)
+  : n_rows(X.n_rows)
+  , n_cols(X.n_cols)
+  , n_elem(n_rows*n_cols)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  init_cold();
+  
+  X.apply(*this);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename gen_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const Gen<T1, gen_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  init_warm(X.n_rows, X.n_cols);
+  
+  X.apply(*this);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename gen_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const Gen<T1, gen_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  X.apply_inplace_plus(*this);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename gen_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const Gen<T1, gen_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  X.apply_inplace_minus(*this);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename gen_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const Gen<T1, gen_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const Mat<eT> tmp(X);
+  
+  return (*this).operator*=(tmp);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename gen_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const Gen<T1, gen_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  X.apply_inplace_schur(*this);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename gen_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const Gen<T1, gen_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  X.apply_inplace_div(*this);
+  
+  return *this;
+  }
+
+
+
+//! create a matrix from Op, i.e. run the previously delayed unary operations
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+Mat<eT>::Mat(const Op<T1, op_type>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  op_type::apply(*this, X);
+  }
+
+
+
+//! create a matrix from Op, i.e. run the previously delayed unary operations
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const Op<T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  op_type::apply(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix addition, with the right-hand-side operand having delayed operations
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const Op<T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator+=(m);
+  }
+
+
+
+//! in-place matrix subtraction, with the right-hand-side operand having delayed operations
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const Op<T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator-=(m);
+  }
+
+
+
+//! in-place matrix multiplication, with the right-hand-side operand having delayed operations
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const Op<T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  glue_times::apply_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix element-wise multiplication, with the right-hand-side operand having delayed operations
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const Op<T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator%=(m);
+  }
+
+
+
+//! in-place matrix element-wise division, with the right-hand-side operand having delayed operations
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const Op<T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator/=(m);
+  }
+
+
+
+//! create a matrix from eOp, i.e. run the previously delayed unary operations
+template<typename eT>
+template<typename T1, typename eop_type>
+inline
+Mat<eT>::Mat(const eOp<T1, eop_type>& X)
+  : n_rows(X.get_n_rows())
+  , n_cols(X.get_n_cols())
+  , n_elem(X.get_n_elem())
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  init_cold();
+  
+  eop_type::apply(*this, X);
+  }
+
+
+
+//! create a matrix from eOp, i.e. run the previously delayed unary operations
+template<typename eT>
+template<typename T1, typename eop_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const eOp<T1, eop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const bool bad_alias = (eOp<T1, eop_type>::proxy_type::has_subview  &&  X.P.is_alias(*this));
+  
+  if(bad_alias == false)
+    {
+    init_warm(X.get_n_rows(), X.get_n_cols());
+    
+    eop_type::apply(*this, X);
+    }
+  else
+    {
+    arma_extra_debug_print("bad_alias = true");
+    
+    Mat<eT> tmp(X);
+    
+    steal_mem(tmp);
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename eop_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const eOp<T1, eop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  eop_type::apply_inplace_plus(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename eop_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const eOp<T1, eop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  eop_type::apply_inplace_minus(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename eop_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const eOp<T1, eop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  glue_times::apply_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename eop_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const eOp<T1, eop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  eop_type::apply_inplace_schur(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename eop_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const eOp<T1, eop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  eop_type::apply_inplace_div(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+Mat<eT>::Mat(const mtOp<eT, T1, op_type>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  op_type::apply(*this, X);
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const mtOp<eT, T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  op_type::apply(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const mtOp<eT, T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator+=(m);
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const mtOp<eT, T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator-=(m);
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const mtOp<eT, T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator*=(m);
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const mtOp<eT, T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator%=(m);
+  }
+
+
+
+//! EXPERIMENTAL
+template<typename eT>
+template<typename T1, typename op_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const mtOp<eT, T1, op_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator/=(m);
+  }
+
+
+
+//! create a matrix from Glue, i.e. run the previously delayed binary operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+Mat<eT>::Mat(const Glue<T1, T2, glue_type>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  glue_type::apply(*this, X);
+  }
+
+
+
+//! create a matrix from Glue, i.e. run the previously delayed binary operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const Glue<T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  glue_type::apply(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix addition, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const Glue<T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator+=(m);
+  }
+
+
+
+//! in-place matrix subtraction, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const Glue<T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator-=(m);
+  }
+
+
+
+//! in-place matrix multiplications, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const Glue<T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  glue_times::apply_inplace(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix element-wise multiplication, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const Glue<T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator%=(m);
+  }
+
+
+
+//! in-place matrix element-wise division, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const Glue<T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator/=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const Glue<T1, T2, glue_times>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  glue_times::apply_inplace_plus(*this, X, sword(+1));
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const Glue<T1, T2, glue_times>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  glue_times::apply_inplace_plus(*this, X, sword(-1));
+  
+  return *this;
+  }
+
+
+
+//! create a matrix from eGlue, i.e. run the previously delayed binary operations
+template<typename eT>
+template<typename T1, typename T2, typename eglue_type>
+inline
+Mat<eT>::Mat(const eGlue<T1, T2, eglue_type>& X)
+  : n_rows(X.get_n_rows())
+  , n_cols(X.get_n_cols())
+  , n_elem(X.get_n_elem())
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  init_cold();
+  
+  eglue_type::apply(*this, X);
+  }
+
+
+
+//! create a matrix from eGlue, i.e. run the previously delayed binary operations
+template<typename eT>
+template<typename T1, typename T2, typename eglue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const eGlue<T1, T2, eglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  const bool bad_alias =
+    (
+    (eGlue<T1, T2, eglue_type>::proxy1_type::has_subview  &&  X.P1.is_alias(*this))
+    ||
+    (eGlue<T1, T2, eglue_type>::proxy2_type::has_subview  &&  X.P2.is_alias(*this))
+    );
+  
+  if(bad_alias == false)
+    {
+    init_warm(X.get_n_rows(), X.get_n_cols());
+    
+    eglue_type::apply(*this, X);
+    }
+  else
+    {
+    arma_extra_debug_print("bad_alias = true");
+    
+    Mat<eT> tmp(X);
+    
+    steal_mem(tmp);
+    }
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix addition, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename eglue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const eGlue<T1, T2, eglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  eglue_type::apply_inplace_plus(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! in-place matrix subtraction, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename eglue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const eGlue<T1, T2, eglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  eglue_type::apply_inplace_minus(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2, typename eglue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const eGlue<T1, T2, eglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  glue_times::apply_inplace(*this, X);
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2, typename eglue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const eGlue<T1, T2, eglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  eglue_type::apply_inplace_schur(*this, X);
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2, typename eglue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const eGlue<T1, T2, eglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
+  
+  eglue_type::apply_inplace_div(*this, X);
+  return *this;
+  }
+
+
+
+//! EXPERIMENTAL: create a matrix from mtGlue, i.e. run the previously delayed binary operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+Mat<eT>::Mat(const mtGlue<eT, T1, T2, glue_type>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , vec_state(0)
+  , mem_state(0)
+  , mem()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  glue_type::apply(*this, X);
+  }
+
+
+
+//! EXPERIMENTAL: create a matrix from Glue, i.e. run the previously delayed binary operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator=(const mtGlue<eT, T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  glue_type::apply(*this, X);
+  
+  return *this;
+  }
+
+
+
+//! EXPERIMENTAL: in-place matrix addition, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator+=(const mtGlue<eT, T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator+=(m);
+  }
+
+
+
+//! EXPERIMENTAL: in-place matrix subtraction, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator-=(const mtGlue<eT, T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator-=(m);
+  }
+
+
+
+//! EXPERIMENTAL: in-place matrix multiplications, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator*=(const mtGlue<eT, T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> m(X);
+  
+  glue_times::apply_inplace(*this, m);
+  
+  return *this;
+  }
+
+
+
+//! EXPERIMENTAL: in-place matrix element-wise multiplication, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator%=(const mtGlue<eT, T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator%=(m);
+  }
+
+
+
+//! EXPERIMENTAL: in-place matrix element-wise division, with the right-hand-side operands having delayed operations
+template<typename eT>
+template<typename T1, typename T2, typename glue_type>
+inline
+const Mat<eT>&
+Mat<eT>::operator/=(const mtGlue<eT, T1, T2, glue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> m(X);
+  
+  return (*this).operator/=(m);
+  }
+
+
+
+//! linear element accessor (treats the matrix as a vector); no bounds check; assumes memory is aligned
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Mat<eT>::at_alt(const uword ii) const
+  {
+  const eT* mem_aligned = mem;
+  memory::mark_as_aligned(mem_aligned);
+  
+  return mem_aligned[ii];
+  }
+
+
+
+//! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Mat<eT>::operator() (const uword ii)
+  {
+  arma_debug_check( (ii >= n_elem), "Mat::operator(): index out of bounds");
+  return access::rw(mem[ii]);
+  }
+
+
+
+//! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Mat<eT>::operator() (const uword ii) const
+  {
+  arma_debug_check( (ii >= n_elem), "Mat::operator(): index out of bounds");
+  return mem[ii];
+  }
+
+
+//! linear element accessor (treats the matrix as a vector); no bounds check.  
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Mat<eT>::operator[] (const uword ii)
+  {
+  return access::rw(mem[ii]);
+  }
+
+
+
+//! linear element accessor (treats the matrix as a vector); no bounds check
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Mat<eT>::operator[] (const uword ii) const
+  {
+  return mem[ii];
+  }
+
+
+
+//! linear element accessor (treats the matrix as a vector); no bounds check.  
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Mat<eT>::at(const uword ii)
+  {
+  return access::rw(mem[ii]);
+  }
+
+
+
+//! linear element accessor (treats the matrix as a vector); no bounds check
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Mat<eT>::at(const uword ii) const
+  {
+  return mem[ii];
+  }
+
+
+
+//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Mat<eT>::operator() (const uword in_row, const uword in_col)
+  {
+  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): index out of bounds");
+  return access::rw(mem[in_row + in_col*n_rows]);
+  }
+
+
+
+//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Mat<eT>::operator() (const uword in_row, const uword in_col) const
+  {
+  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): index out of bounds");
+  return mem[in_row + in_col*n_rows];
+  }
+
+
+
+//! element accessor; no bounds check
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Mat<eT>::at(const uword in_row, const uword in_col)
+  {
+  return access::rw( mem[in_row + in_col*n_rows] );
+  }
+
+
+
+//! element accessor; no bounds check
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Mat<eT>::at(const uword in_row, const uword in_col) const
+  {
+  return mem[in_row + in_col*n_rows];
+  }
+
+
+
+//! prefix ++
+template<typename eT>
+arma_inline
+const Mat<eT>&
+Mat<eT>::operator++()
+  {
+  Mat_aux::prefix_pp(*this);
+  return *this;
+  }
+
+
+
+//! postfix ++  (must not return the object by reference)
+template<typename eT>
+arma_inline
+void
+Mat<eT>::operator++(int)
+  {
+  Mat_aux::postfix_pp(*this);
+  }
+
+
+
+//! prefix --
+template<typename eT>
+arma_inline
+const Mat<eT>&
+Mat<eT>::operator--()
+  {
+  Mat_aux::prefix_mm(*this);
+  return *this;
+  }
+
+
+
+//! postfix --  (must not return the object by reference)
+template<typename eT>
+arma_inline
+void
+Mat<eT>::operator--(int)
+  {
+  Mat_aux::postfix_mm(*this);
+  }
+
+
+
+//! returns true if the matrix has no elements
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Mat<eT>::is_empty() const
+  {
+  return (n_elem == 0);
+  }
+
+
+
+//! returns true if the object can be interpreted as a column or row vector
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Mat<eT>::is_vec() const
+  {
+  return ( (n_rows == 1) || (n_cols == 1) );
+  }
+
+
+
+//! returns true if the object can be interpreted as a row vector
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Mat<eT>::is_rowvec() const
+  {
+  return (n_rows == 1);
+  }
+
+
+
+//! returns true if the object can be interpreted as a column vector
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Mat<eT>::is_colvec() const
+  {
+  return (n_cols == 1);
+  }
+
+
+
+//! returns true if the object has the same number of non-zero rows and columnns
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Mat<eT>::is_square() const
+  {
+  return (n_rows == n_cols);
+  }
+
+
+
+//! returns true if all of the elements are finite
+template<typename eT>
+inline
+arma_warn_unused
+bool
+Mat<eT>::is_finite() const
+  {
+  return arrayops::is_finite( memptr(), n_elem );
+  }
+
+
+
+//! returns true if the given index is currently in range
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Mat<eT>::in_range(const uword ii) const
+  {
+  return (ii < n_elem);
+  }
+
+
+
+//! returns true if the given start and end indices are currently in range
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Mat<eT>::in_range(const span& x) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(x.whole == true)
+    {
+    return true;
+    }
+  else
+    {
+    const uword a = x.a;
+    const uword b = x.b;
+    
+    return ( (a <= b) && (b < n_elem) );
+    }
+  }
+
+
+
+//! returns true if the given location is currently in range
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Mat<eT>::in_range(const uword in_row, const uword in_col) const
+  {
+  return ( (in_row < n_rows) && (in_col < n_cols) );
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Mat<eT>::in_range(const span& row_span, const uword in_col) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(row_span.whole == true)
+    {
+    return (in_col < n_cols);
+    }
+  else
+    {
+    const uword in_row1 = row_span.a;
+    const uword in_row2 = row_span.b;
+    
+    return ( (in_row1 <= in_row2) && (in_row2 < n_rows) && (in_col < n_cols) );
+    }
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Mat<eT>::in_range(const uword in_row, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(col_span.whole == true)
+    {
+    return (in_row < n_rows);
+    }
+  else
+    {
+    const uword in_col1 = col_span.a;
+    const uword in_col2 = col_span.b;
+  
+    return ( (in_row < n_rows) && (in_col1 <= in_col2) && (in_col2 < n_cols) );
+    }
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+Mat<eT>::in_range(const span& row_span, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword in_row1 = row_span.a;
+  const uword in_row2 = row_span.b;
+  
+  const uword in_col1 = col_span.a;
+  const uword in_col2 = col_span.b;
+  
+  const bool rows_ok = row_span.whole ? true : ( (in_row1 <= in_row2) && (in_row2 < n_rows) );
+  const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2) && (in_col2 < n_cols) );
+  
+  return ( (rows_ok == true) && (cols_ok == true) );
+  }
+
+
+
+//! returns a pointer to array of eTs for a specified column; no bounds check
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT*
+Mat<eT>::colptr(const uword in_col)
+  {
+  return & access::rw(mem[in_col*n_rows]);
+  }
+
+
+
+//! returns a pointer to array of eTs for a specified column; no bounds check
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT*
+Mat<eT>::colptr(const uword in_col) const
+  {
+  return & mem[in_col*n_rows];
+  }
+
+
+
+//! returns a pointer to array of eTs used by the matrix
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT*
+Mat<eT>::memptr()
+  {
+  return const_cast<eT*>(mem);
+  }
+
+
+
+//! returns a pointer to array of eTs used by the matrix
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT*
+Mat<eT>::memptr() const
+  {
+  return mem;
+  }
+
+
+
+//! print contents of the matrix (to the cout stream),
+//! optionally preceding with a user specified line of text.
+//! the precision and cell width are modified.
+//! on return, the stream's state are restored to their original values.
+template<typename eT>
+inline
+void
+Mat<eT>::impl_print(const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width();
+    
+    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
+  
+    ARMA_DEFAULT_OSTREAM.width(orig_width);
+    }
+  
+  arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, true);
+  }
+
+
+
+//! print contents of the matrix to a user specified stream,
+//! optionally preceding with a user specified line of text.
+//! the precision and cell width are modified.
+//! on return, the stream's state are restored to their original values.
+template<typename eT>
+inline
+void
+Mat<eT>::impl_print(std::ostream& user_stream, const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = user_stream.width();
+    
+    user_stream << extra_text << '\n';
+    
+    user_stream.width(orig_width);
+    }
+  
+  arma_ostream::print(user_stream, *this, true);
+  }
+
+
+
+//! print contents of the matrix (to the cout stream),
+//! optionally preceding with a user specified line of text.
+//! the stream's state are used as is and are not modified
+//! (i.e. the precision and cell width are not modified).
+template<typename eT>
+inline
+void
+Mat<eT>::impl_raw_print(const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width();
+    
+    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
+  
+    ARMA_DEFAULT_OSTREAM.width(orig_width);
+    }
+  
+  arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, false);
+  }
+
+
+
+//! print contents of the matrix to a user specified stream,
+//! optionally preceding with a user specified line of text.
+//! the stream's state are used as is and are not modified.
+//! (i.e. the precision and cell width are not modified).
+template<typename eT>
+inline
+void
+Mat<eT>::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = user_stream.width();
+  
+    user_stream << extra_text << '\n';
+  
+    user_stream.width(orig_width);
+    }
+  
+  arma_ostream::print(user_stream, *this, false);
+  }
+
+
+
+//! change the matrix to have user specified dimensions (data is not preserved)
+template<typename eT>
+inline
+void
+Mat<eT>::set_size(const uword in_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(vec_state)
+    {
+    case 0:
+    case 1:
+      init_warm(in_elem, 1);
+      break;
+    
+    case 2:
+      init_warm(1, in_elem);
+      break;
+      
+    default:
+      ;
+    }
+  }
+
+
+
+//! change the matrix to have user specified dimensions (data is not preserved)
+template<typename eT>
+inline
+void
+Mat<eT>::set_size(const uword in_rows, const uword in_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  init_warm(in_rows, in_cols);
+  }
+
+
+
+//! change the matrix to have user specified dimensions (data is preserved)
+template<typename eT>
+inline
+void
+Mat<eT>::resize(const uword in_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(vec_state)
+    {
+    case 0:
+    case 1:
+      (*this).resize(in_elem, 1);
+      break;
+    
+    case 2:
+      (*this).resize(1, in_elem);
+      break;
+      
+    default:
+      ;
+    }
+  }
+
+
+
+//! change the matrix to have user specified dimensions (data is preserved)
+template<typename eT>
+inline
+void
+Mat<eT>::resize(const uword in_rows, const uword in_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  *this = arma::resize(*this, in_rows, in_cols);
+  }
+
+
+
+//! change the matrix to have user specified dimensions (data is preserved)
+template<typename eT>
+inline
+void
+Mat<eT>::reshape(const uword in_rows, const uword in_cols, const uword dim)
+  {
+  arma_extra_debug_sigprint();
+  
+  *this = arma::reshape(*this, in_rows, in_cols, dim);
+  }
+
+
+
+//! change the matrix (without preserving data) to have the same dimensions as the given expression 
+template<typename eT>
+template<typename eT2, typename expr>
+inline
+void
+Mat<eT>::copy_size(const Base<eT2, expr>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Proxy<expr> P(X.get_ref());
+  
+  const uword X_n_rows = P.get_n_rows();
+  const uword X_n_cols = P.get_n_cols();
+  
+  init_warm(X_n_rows, X_n_cols);
+  }
+
+
+
+//! transform each element in the matrix using a functor
+template<typename eT>
+template<typename functor>
+inline
+const Mat<eT>&
+Mat<eT>::transform(functor F)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT* out_mem = memptr();
+  
+  const uword N = n_elem;
+  
+  uword ii, jj;
+  
+  for(ii=0, jj=1; jj < N; ii+=2, jj+=2)
+    {
+    eT tmp_ii = out_mem[ii];
+    eT tmp_jj = out_mem[jj];
+    
+    tmp_ii = eT( F(tmp_ii) );
+    tmp_jj = eT( F(tmp_jj) );
+    
+    out_mem[ii] = tmp_ii;
+    out_mem[jj] = tmp_jj;
+    }
+  
+  if(ii < N)
+    {
+    out_mem[ii] = eT( F(out_mem[ii]) );
+    }
+  
+  return *this;
+  }
+
+
+
+//! imbue (fill) the matrix with values provided by a functor
+template<typename eT>
+template<typename functor>
+inline
+const Mat<eT>&
+Mat<eT>::imbue(functor F)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT* out_mem = memptr();
+  
+  const uword N = n_elem;
+  
+  uword ii, jj;
+  
+  for(ii=0, jj=1; jj < N; ii+=2, jj+=2)
+    {
+    const eT tmp_ii = eT( F() );
+    const eT tmp_jj = eT( F() );
+    
+    out_mem[ii] = tmp_ii;
+    out_mem[jj] = tmp_jj;
+    }
+  
+  if(ii < N)
+    {
+    out_mem[ii] = eT( F() );
+    }
+  
+  return *this;
+  }
+
+
+
+//! fill the matrix with the specified value
+template<typename eT>
+arma_hot
+inline
+const Mat<eT>&
+Mat<eT>::fill(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  arrayops::inplace_set( memptr(), val, n_elem );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::zeros()
+  {
+  arma_extra_debug_sigprint();
+  
+  return fill(eT(0));
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::zeros(const uword in_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  set_size(in_elem);
+  
+  return fill(eT(0));
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::zeros(const uword in_rows, const uword in_cols)
+  {
+  arma_extra_debug_sigprint();
+
+  set_size(in_rows, in_cols);
+  
+  return fill(eT(0));
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::ones()
+  {
+  arma_extra_debug_sigprint();
+  
+  return fill(eT(1));
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::ones(const uword in_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  set_size(in_elem);
+  
+  return fill(eT(1));
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::ones(const uword in_rows, const uword in_cols)
+  {
+  arma_extra_debug_sigprint();
+
+  set_size(in_rows, in_cols);
+  
+  return fill(eT(1));
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::randu()
+  {
+  arma_extra_debug_sigprint();
+  
+  eop_aux_randu<eT>::fill( memptr(), n_elem );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::randu(const uword in_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  set_size(in_elem);
+  
+  return (*this).randu();
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::randu(const uword in_rows, const uword in_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  set_size(in_rows, in_cols);
+  
+  return (*this).randu();
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::randn()
+  {
+  arma_extra_debug_sigprint();
+  
+  eop_aux_randn<eT>::fill( memptr(), n_elem );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::randn(const uword in_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  set_size(in_elem);
+  
+  return (*this).randn();
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::randn(const uword in_rows, const uword in_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  set_size(in_rows, in_cols);
+  
+  return (*this).randn();
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::eye()
+  {
+  arma_extra_debug_sigprint();
+  
+  fill(eT(0));
+  
+  const uword N = (std::min)(n_rows, n_cols);
+  
+  for(uword ii=0; ii<N; ++ii)
+    {
+    at(ii,ii) = eT(1);
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const Mat<eT>&
+Mat<eT>::eye(const uword in_rows, const uword in_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  set_size(in_rows, in_cols);
+  
+  return (*this).eye();
+  }
+
+
+
+template<typename eT>
+inline
+void
+Mat<eT>::reset()
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(vec_state)
+    {
+    default:
+      init_warm(0, 0);
+      break;
+      
+    case 1:
+      init_warm(0, 1);
+      break;
+    
+    case 2:
+      init_warm(1, 0);
+      break;
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+Mat<eT>::set_real(const Base<typename Mat<eT>::pod_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat_aux::set_real(*this, X);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+Mat<eT>::set_imag(const Base<typename Mat<eT>::pod_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat_aux::set_imag(*this, X);
+  }
+
+
+
+template<typename eT>
+inline
+arma_warn_unused
+eT
+Mat<eT>::min() const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (n_elem == 0), "min(): object has no elements" );
+  
+  return op_min::direct_min(memptr(), n_elem);
+  }
+
+
+
+template<typename eT>
+inline
+arma_warn_unused
+eT
+Mat<eT>::max() const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (n_elem == 0), "max(): object has no elements" );
+  
+  return op_max::direct_max(memptr(), n_elem);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+Mat<eT>::min(uword& index_of_min_val) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (n_elem == 0), "min(): object has no elements" );
+  
+  return op_min::direct_min(memptr(), n_elem, index_of_min_val);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+Mat<eT>::max(uword& index_of_max_val) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (n_elem == 0), "max(): object has no elements" );
+  
+  return op_max::direct_max(memptr(), n_elem, index_of_max_val);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+Mat<eT>::min(uword& row_of_min_val, uword& col_of_min_val) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (n_elem == 0), "min(): object has no elements" );
+  
+  uword iq;
+  
+  eT val = op_min::direct_min(memptr(), n_elem, iq);
+  
+  row_of_min_val = iq % n_rows;
+  col_of_min_val = iq / n_rows;
+  
+  return val;
+  }
+
+
+
+template<typename eT>
+inline
+eT
+Mat<eT>::max(uword& row_of_max_val, uword& col_of_max_val) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (n_elem == 0), "max(): object has no elements" );
+  
+  uword iq;
+  
+  eT val = op_max::direct_max(memptr(), n_elem, iq);
+  
+  row_of_max_val = iq % n_rows;
+  col_of_max_val = iq / n_rows;
+  
+  return val;
+  }
+
+
+
+//! save the matrix to a file
+template<typename eT>
+inline
+bool
+Mat<eT>::save(const std::string name, const file_type type, const bool print_status) const
+  {
+  arma_extra_debug_sigprint();
+  
+  bool save_okay;
+  
+  switch(type)
+    {
+    case raw_ascii:
+      save_okay = diskio::save_raw_ascii(*this, name);
+      break;
+    
+    case arma_ascii:
+      save_okay = diskio::save_arma_ascii(*this, name);
+      break;
+    
+    case csv_ascii:
+      save_okay = diskio::save_csv_ascii(*this, name);
+      break;
+    
+    case raw_binary:
+      save_okay = diskio::save_raw_binary(*this, name);
+      break;
+    
+    case arma_binary:
+      save_okay = diskio::save_arma_binary(*this, name);
+      break;
+      
+    case pgm_binary:
+      save_okay = diskio::save_pgm_binary(*this, name);
+      break;
+    
+    case hdf5_binary:
+      save_okay = diskio::save_hdf5_binary(*this, name);
+      break;
+    
+    default:
+      arma_warn(print_status, "Mat::save(): unsupported file type");
+      save_okay = false;
+    }
+  
+  arma_warn( (print_status && (save_okay == false)), "Mat::save(): couldn't write to ", name);
+  
+  return save_okay;
+  }
+
+
+
+//! save the matrix to a stream
+template<typename eT>
+inline
+bool
+Mat<eT>::save(std::ostream& os, const file_type type, const bool print_status) const
+  {
+  arma_extra_debug_sigprint();
+  
+  bool save_okay;
+  
+  switch(type)
+    {
+    case raw_ascii:
+      save_okay = diskio::save_raw_ascii(*this, os);
+      break;
+    
+    case arma_ascii:
+      save_okay = diskio::save_arma_ascii(*this, os);
+      break;
+    
+    case csv_ascii:
+      save_okay = diskio::save_csv_ascii(*this, os);
+      break;
+    
+    case raw_binary:
+      save_okay = diskio::save_raw_binary(*this, os);
+      break;
+    
+    case arma_binary:
+      save_okay = diskio::save_arma_binary(*this, os);
+      break;
+      
+    case pgm_binary:
+      save_okay = diskio::save_pgm_binary(*this, os);
+      break;
+    
+    default:
+      arma_warn(print_status, "Mat::save(): unsupported file type");
+      save_okay = false;
+    }
+  
+  arma_warn( (print_status && (save_okay == false)), "Mat::save(): couldn't write to the given stream");
+  
+  return save_okay;
+  }
+
+
+
+//! load a matrix from a file
+template<typename eT>
+inline
+bool
+Mat<eT>::load(const std::string name, const file_type type, const bool print_status)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay;
+  std::string err_msg;
+  
+  switch(type)
+    {
+    case auto_detect:
+      load_okay = diskio::load_auto_detect(*this, name, err_msg);
+      break;
+    
+    case raw_ascii:
+      load_okay = diskio::load_raw_ascii(*this, name, err_msg);
+      break;
+    
+    case arma_ascii:
+      load_okay = diskio::load_arma_ascii(*this, name, err_msg);
+      break;
+    
+    case csv_ascii:
+      load_okay = diskio::load_csv_ascii(*this, name, err_msg);
+      break;
+    
+    case raw_binary:
+      load_okay = diskio::load_raw_binary(*this, name, err_msg);
+      break;
+    
+    case arma_binary:
+      load_okay = diskio::load_arma_binary(*this, name, err_msg);
+      break;
+      
+    case pgm_binary:
+      load_okay = diskio::load_pgm_binary(*this, name, err_msg);
+      break;
+    
+    case hdf5_binary:
+      load_okay = diskio::load_hdf5_binary(*this, name, err_msg);
+      break;
+
+    default:
+      arma_warn(print_status, "Mat::load(): unsupported file type");
+      load_okay = false;
+    }
+  
+  if( (print_status == true) && (load_okay == false) )
+    {
+    if(err_msg.length() > 0)
+      {
+      arma_warn(true, "Mat::load(): ", err_msg, name);
+      }
+    else
+      {
+      arma_warn(true, "Mat::load(): couldn't read ", name);
+      }
+    }
+  
+  if(load_okay == false)
+    {
+    (*this).reset();
+    }
+    
+  return load_okay;
+  }
+
+
+
+//! load a matrix from a stream
+template<typename eT>
+inline
+bool
+Mat<eT>::load(std::istream& is, const file_type type, const bool print_status)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay;
+  std::string err_msg;
+  
+  switch(type)
+    {
+    case auto_detect:
+      load_okay = diskio::load_auto_detect(*this, is, err_msg);
+      break;
+    
+    case raw_ascii:
+      load_okay = diskio::load_raw_ascii(*this, is, err_msg);
+      break;
+    
+    case arma_ascii:
+      load_okay = diskio::load_arma_ascii(*this, is, err_msg);
+      break;
+    
+    case csv_ascii:
+      load_okay = diskio::load_csv_ascii(*this, is, err_msg);
+      break;
+    
+    case raw_binary:
+      load_okay = diskio::load_raw_binary(*this, is, err_msg);
+      break;
+    
+    case arma_binary:
+      load_okay = diskio::load_arma_binary(*this, is, err_msg);
+      break;
+      
+    case pgm_binary:
+      load_okay = diskio::load_pgm_binary(*this, is, err_msg);
+      break;
+    
+    default:
+      arma_warn(print_status, "Mat::load(): unsupported file type");
+      load_okay = false;
+    }
+  
+  
+  if( (print_status == true) && (load_okay == false) )
+    {
+    if(err_msg.length() > 0)
+      {
+      arma_warn(true, "Mat::load(): ", err_msg, "the given stream");
+      }
+    else
+      {
+      arma_warn(true, "Mat::load(): couldn't load from the given stream");
+      }
+    }
+  
+  if(load_okay == false)
+    {
+    (*this).reset();
+    }
+    
+  return load_okay;
+  }
+
+
+
+//! save the matrix to a file, without printing any error messages
+template<typename eT>
+inline
+bool
+Mat<eT>::quiet_save(const std::string name, const file_type type) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).save(name, type, false);
+  }
+
+
+
+//! save the matrix to a stream, without printing any error messages
+template<typename eT>
+inline
+bool
+Mat<eT>::quiet_save(std::ostream& os, const file_type type) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).save(os, type, false);
+  }
+
+
+
+//! load a matrix from a file, without printing any error messages
+template<typename eT>
+inline
+bool
+Mat<eT>::quiet_load(const std::string name, const file_type type)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).load(name, type, false);
+  }
+
+
+
+//! load a matrix from a stream, without printing any error messages
+template<typename eT>
+inline
+bool
+Mat<eT>::quiet_load(std::istream& is, const file_type type)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).load(is, type, false);
+  }
+
+
+
+template<typename eT>
+inline
+Mat<eT>::row_iterator::row_iterator(Mat<eT>& in_M, const uword in_row)
+  : M  (in_M  )
+  , row(in_row)
+  , col(0     )
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+Mat<eT>::row_iterator::operator*()
+  {
+  return M.at(row,col);
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::row_iterator&
+Mat<eT>::row_iterator::operator++()
+  {
+  ++col;
+  
+  if(col >= M.n_cols)
+    {
+    col = 0;
+    ++row;
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+void
+Mat<eT>::row_iterator::operator++(int)
+  {
+  operator++();
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::row_iterator&
+Mat<eT>::row_iterator::operator--()
+  {
+  if(col > 0)
+    {
+    --col;
+    }
+  else
+    {
+    if(row > 0)
+      {
+      col = M.n_cols - 1;
+      --row;
+      }
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+void
+Mat<eT>::row_iterator::operator--(int)
+  {
+  operator--();
+  }
+
+
+
+template<typename eT>
+inline
+bool
+Mat<eT>::row_iterator::operator!=(const typename Mat<eT>::row_iterator& X) const
+  {
+  return ( (row != X.row) || (col != X.col) ) ? true : false;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+Mat<eT>::row_iterator::operator==(const typename Mat<eT>::row_iterator& X) const
+  {
+  return ( (row == X.row) && (col == X.col) ) ? true : false;
+  }
+
+
+
+template<typename eT>
+inline
+Mat<eT>::const_row_iterator::const_row_iterator(const Mat<eT>& in_M, const uword in_row)
+  : M  (in_M  )
+  , row(in_row)
+  , col(0     )
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+Mat<eT>::const_row_iterator::const_row_iterator(const typename Mat<eT>::row_iterator& X)
+  : M  (X.M)
+  , row(X.row)
+  , col(X.col)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+eT
+Mat<eT>::const_row_iterator::operator*() const
+  {
+  return M.at(row,col);
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::const_row_iterator&
+Mat<eT>::const_row_iterator::operator++()
+  {
+  ++col;
+  
+  if(col >= M.n_cols)
+    {
+    col = 0;
+    ++row;
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+void
+Mat<eT>::const_row_iterator::operator++(int)
+  {
+  operator++();
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::const_row_iterator&
+Mat<eT>::const_row_iterator::operator--()
+  {
+  if(col > 0)
+    {
+    --col;
+    }
+  else
+    {
+    if(row > 0)
+      {
+      col = M.n_cols - 1;
+      --row;
+      }
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+void
+Mat<eT>::const_row_iterator::operator--(int)
+  {
+  operator--();
+  }
+
+
+
+template<typename eT>
+inline
+bool
+Mat<eT>::const_row_iterator::operator!=(const typename Mat<eT>::const_row_iterator& X) const
+  {
+  return ( (row != X.row) || (col != X.col) ) ? true : false;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+Mat<eT>::const_row_iterator::operator==(const typename Mat<eT>::const_row_iterator& X) const
+  {
+  return ( (row == X.row) && (col == X.col) ) ? true : false;
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::iterator
+Mat<eT>::begin()
+  {
+  arma_extra_debug_sigprint();
+  
+  return memptr();
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::const_iterator
+Mat<eT>::begin() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return memptr();
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::const_iterator
+Mat<eT>::cbegin() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return memptr();
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::iterator
+Mat<eT>::end()
+  {
+  arma_extra_debug_sigprint();
+  
+  return memptr() + n_elem;
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::const_iterator
+Mat<eT>::end() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return memptr() + n_elem;
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::const_iterator
+Mat<eT>::cend() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return memptr() + n_elem;
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::col_iterator
+Mat<eT>::begin_col(const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (col_num >= n_cols), "begin_col(): index out of bounds");
+  
+  return colptr(col_num);
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::const_col_iterator
+Mat<eT>::begin_col(const uword col_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (col_num >= n_cols), "begin_col(): index out of bounds");
+  
+  return colptr(col_num);
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::col_iterator
+Mat<eT>::end_col(const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (col_num >= n_cols), "end_col(): index out of bounds");
+  
+  return colptr(col_num) + n_rows;
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::const_col_iterator
+Mat<eT>::end_col(const uword col_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (col_num >= n_cols), "end_col(): index out of bounds");
+  
+  return colptr(col_num) + n_rows;
+  }
+  
+
+
+template<typename eT>
+inline
+typename Mat<eT>::row_iterator
+Mat<eT>::begin_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" );
+  
+  return typename Mat<eT>::row_iterator(*this, row_num);
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::const_row_iterator
+Mat<eT>::begin_row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" );
+  
+  return typename Mat<eT>::const_row_iterator(*this, row_num);
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::row_iterator
+Mat<eT>::end_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of bounds" );
+  
+  return typename Mat<eT>::row_iterator(*this, row_num + 1);
+  }
+
+
+
+template<typename eT>
+inline
+typename Mat<eT>::const_row_iterator
+Mat<eT>::end_row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of bounds" );
+  
+  return typename Mat<eT>::const_row_iterator(*this, row_num + 1);
+  }
+
+
+
+//! resets this matrix to an empty matrix
+template<typename eT>
+inline
+void
+Mat<eT>::clear()
+  {
+  reset();
+  }
+
+
+
+//! returns true if the matrix has no elements
+template<typename eT>
+inline
+bool
+Mat<eT>::empty() const
+  {
+  return (n_elem == 0);
+  }
+
+
+
+//! returns the number of elements in this matrix
+template<typename eT>
+inline
+uword
+Mat<eT>::size() const
+  {
+  return n_elem;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed()
+  : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const fixed<fixed_n_rows, fixed_n_cols>& X)
+  : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  eT* dest = (use_extra) ? mem_local_extra : mem_local;
+  
+  arrayops::copy( dest, X.mem, fixed_n_elem );
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+template<typename T1>
+inline
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const Base<eT,T1>& A)
+  : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  Mat<eT>::operator=(A.get_ref()); 
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+template<typename T1, typename T2>
+inline
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B)
+  : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  Mat<eT>::init(A,B);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+inline
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const eT* aux_mem)
+  : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  eT* dest = (use_extra) ? mem_local_extra : mem_local;
+  
+  arrayops::copy( dest, aux_mem, fixed_n_elem );
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+inline
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const char* text)
+  : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  Mat<eT>::operator=(text);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+inline
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const std::string& text)
+  : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  Mat<eT>::operator=(text);
+  }
+
+
+
+#if defined(ARMA_USE_CXX11)
+  
+  template<typename eT>
+  template<uword fixed_n_rows, uword fixed_n_cols>
+  inline
+  Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const std::initializer_list<eT>& list)
+    : Mat<eT>( arma_fixed_indicator(), fixed_n_rows, fixed_n_cols, 0, ((use_extra) ? mem_local_extra : mem_local) )
+    {
+    arma_extra_debug_sigprint_this(this);
+    
+    (*this).operator=(list);
+    }
+
+
+
+  template<typename eT>
+  template<uword fixed_n_rows, uword fixed_n_cols>
+  inline
+  const Mat<eT>&
+  Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const std::initializer_list<eT>& list)
+    {
+    arma_extra_debug_sigprint();
+    
+    const uword N = list.size();
+    
+    arma_debug_check( (N > fixed_n_elem), "Mat::fixed: initialiser list is too long" );
+    
+    eT* this_mem = (*this).memptr();
+    
+    arrayops::copy( this_mem, list.begin(), N );
+    
+    for(uword iq=N; iq < fixed_n_elem; ++iq) { this_mem[iq] = eT(0); }
+    
+    return *this;
+    }
+  
+#endif
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+const Op< typename Mat<eT>::template fixed<fixed_n_rows, fixed_n_cols>::Mat_fixed_type, op_htrans >
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::t() const
+  {
+  return Op< typename Mat<eT>::template fixed<fixed_n_rows, fixed_n_cols>::Mat_fixed_type, op_htrans >(*this);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+const Op< typename Mat<eT>::template fixed<fixed_n_rows, fixed_n_cols>::Mat_fixed_type, op_htrans >
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::ht() const
+  {
+  return Op< typename Mat<eT>::template fixed<fixed_n_rows, fixed_n_cols>::Mat_fixed_type, op_htrans >(*this);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+const Op< typename Mat<eT>::template fixed<fixed_n_rows, fixed_n_cols>::Mat_fixed_type, op_strans >
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::st() const
+  {
+  return Op< typename Mat<eT>::template fixed<fixed_n_rows, fixed_n_cols>::Mat_fixed_type, op_strans >(*this);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+const eT&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at_alt(const uword ii) const
+  {
+  #if defined(ARMA_HAVE_ALIGNED_ATTRIBUTE)
+    
+    return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
+    
+  #else
+    const eT* mem_aligned = (use_extra) ? mem_local_extra : mem_local;
+    
+    memory::mark_as_aligned(mem_aligned);
+    
+    return mem_aligned[ii];
+  #endif
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+eT&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator[] (const uword ii)
+  {
+  return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+const eT&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator[] (const uword ii) const
+  {
+  return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+eT&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword ii)
+  {
+  return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+const eT&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword ii) const
+  {
+  return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+eT&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword ii)
+  {
+  arma_debug_check( (ii >= fixed_n_elem), "Mat::operator(): index out of bounds");
+  
+  return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+const eT&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword ii) const
+  {
+  arma_debug_check( (ii >= fixed_n_elem), "Mat::operator(): index out of bounds");
+  
+  return (use_extra) ? mem_local_extra[ii] : mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+eT&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword in_row, const uword in_col)
+  {
+  const uword iq = in_row + in_col*fixed_n_rows;
+  
+  return (use_extra) ? mem_local_extra[iq] : mem_local[iq];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+const eT&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword in_row, const uword in_col) const
+  {
+  const uword iq = in_row + in_col*fixed_n_rows;
+  
+  return (use_extra) ? mem_local_extra[iq] : mem_local[iq];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+eT&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword in_row, const uword in_col)
+  {
+  arma_debug_check( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::operator(): index out of bounds");
+  
+  const uword iq = in_row + in_col*fixed_n_rows;
+  
+  return (use_extra) ? mem_local_extra[iq] : mem_local[iq];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+const eT&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword in_row, const uword in_col) const
+  {
+  arma_debug_check( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::operator(): index out of bounds");
+  
+  const uword iq = in_row + in_col*fixed_n_rows;
+  
+  return (use_extra) ? mem_local_extra[iq] : mem_local[iq];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+eT*
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::colptr(const uword in_col)
+  {
+  eT* mem_actual = (use_extra) ? mem_local_extra : mem_local;
+  
+  return & access::rw(mem_actual[in_col*fixed_n_rows]);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+const eT*
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::colptr(const uword in_col) const
+  {
+  const eT* mem_actual = (use_extra) ? mem_local_extra : mem_local;
+  
+  return & mem_actual[in_col*fixed_n_rows];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+eT*
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::memptr()
+  {
+  return (use_extra) ? mem_local_extra : mem_local;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+const eT*
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::memptr() const
+  {
+  return (use_extra) ? mem_local_extra : mem_local;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_inline
+arma_warn_unused
+bool
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::is_vec() const
+  {
+  return ( (fixed_n_rows == 1) || (fixed_n_cols == 1) );
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_hot
+inline
+const Mat<eT>&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fill(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(mem_local[0]);
+  
+  arrayops::inplace_set_fixed<eT,fixed_n_elem>( mem_use, val );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_hot
+inline
+const Mat<eT>&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::zeros()
+  {
+  arma_extra_debug_sigprint();
+  
+  eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(mem_local[0]);
+  
+  arrayops::inplace_set_fixed<eT,fixed_n_elem>( mem_use, eT(0) );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_rows, uword fixed_n_cols>
+arma_hot
+inline
+const Mat<eT>&
+Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::ones()
+  {
+  arma_extra_debug_sigprint();
+  
+  eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(mem_local[0]);
+  
+  arrayops::inplace_set_fixed<eT,fixed_n_elem>( mem_use, eT(1) );
+  
+  return *this;
+  }
+
+
+
+//! prefix ++
+template<typename eT>
+arma_inline
+void
+Mat_aux::prefix_pp(Mat<eT>& x)
+  {
+        eT*   memptr = x.memptr();
+  const uword n_elem = x.n_elem;
+  
+  uword i,j;
+
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    ++(memptr[i]);
+    ++(memptr[j]);
+    }
+  
+  if(i < n_elem)
+    {
+    ++(memptr[i]);
+    }
+  }
+
+
+
+//! prefix ++ for complex numbers (work around for limitations of the std::complex class)
+template<typename T>
+arma_inline
+void
+Mat_aux::prefix_pp(Mat< std::complex<T> >& x)
+  {
+  x += T(1);
+  }
+
+
+
+//! postfix ++
+template<typename eT>
+arma_inline
+void
+Mat_aux::postfix_pp(Mat<eT>& x)
+  {
+        eT*   memptr = x.memptr();
+  const uword n_elem = x.n_elem;
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    (memptr[i])++;
+    (memptr[j])++;
+    }
+  
+  if(i < n_elem)
+    {
+    (memptr[i])++;
+    }
+  }
+
+
+
+//! postfix ++ for complex numbers (work around for limitations of the std::complex class)
+template<typename T>
+arma_inline
+void
+Mat_aux::postfix_pp(Mat< std::complex<T> >& x)
+  {
+  x += T(1);
+  }
+
+
+
+//! prefix --
+template<typename eT>
+arma_inline
+void
+Mat_aux::prefix_mm(Mat<eT>& x)
+  {
+        eT*   memptr = x.memptr();
+  const uword n_elem = x.n_elem;
+
+  uword i,j;
+
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    --(memptr[i]);
+    --(memptr[j]);
+    }
+  
+  if(i < n_elem)
+    {
+    --(memptr[i]);
+    }
+  }
+
+
+
+//! prefix -- for complex numbers (work around for limitations of the std::complex class)
+template<typename T>
+arma_inline
+void
+Mat_aux::prefix_mm(Mat< std::complex<T> >& x)
+  {
+  x -= T(1);
+  }
+
+
+
+//! postfix --
+template<typename eT>
+arma_inline
+void
+Mat_aux::postfix_mm(Mat<eT>& x)
+  {
+        eT*   memptr = x.memptr();
+  const uword n_elem = x.n_elem;
+
+  uword i,j;
+
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    (memptr[i])--;
+    (memptr[j])--;
+    }
+  
+  if(i < n_elem)
+    {
+    (memptr[i])--;
+    }
+  }
+
+
+
+//! postfix ++ for complex numbers (work around for limitations of the std::complex class)
+template<typename T>
+arma_inline
+void
+Mat_aux::postfix_mm(Mat< std::complex<T> >& x)
+  {
+  x -= T(1);
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+Mat_aux::set_real(Mat<eT>& out, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap<T1>   tmp(X.get_ref());
+  const Mat<eT>& A = tmp.M;
+  
+  arma_debug_assert_same_size( out, A, "Mat::set_real()" );
+  
+  out = A;
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+Mat_aux::set_imag(Mat<eT>&, const Base<eT,T1>&)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T, typename T1>
+inline
+void
+Mat_aux::set_real(Mat< std::complex<T> >& out, const Base<T,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<T> eT;
+  
+  const Proxy<T1> P(X.get_ref());
+  
+  const uword local_n_rows = P.get_n_rows();
+  const uword local_n_cols = P.get_n_cols();
+  
+  arma_debug_assert_same_size( out.n_rows, out.n_cols, local_n_rows, local_n_cols, "Mat::set_real()" );
+  
+  eT* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typedef typename Proxy<T1>::ea_type ea_type;
+    
+    ea_type A = P.get_ea();
+    
+    const uword N = out.n_elem;
+    
+    for(uword i=0; i<N; ++i)
+      {
+      out_mem[i] = std::complex<T>( A[i], out_mem[i].imag() );
+      }
+    }
+  else
+    {
+    for(uword col=0; col < local_n_cols; ++col)
+    for(uword row=0; row < local_n_rows; ++row)
+      {
+      (*out_mem) = std::complex<T>( P.at(row,col), (*out_mem).imag() );
+      out_mem++;
+      }
+    }
+  }
+
+
+
+template<typename T, typename T1>
+inline
+void
+Mat_aux::set_imag(Mat< std::complex<T> >& out, const Base<T,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<T> eT;
+  
+  const Proxy<T1> P(X.get_ref());
+  
+  const uword local_n_rows = P.get_n_rows();
+  const uword local_n_cols = P.get_n_cols();
+  
+  arma_debug_assert_same_size( out.n_rows, out.n_cols, local_n_rows, local_n_cols, "Mat::set_imag()" );
+  
+  eT* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typedef typename Proxy<T1>::ea_type ea_type;
+    
+    ea_type A = P.get_ea();
+    
+    const uword N = out.n_elem;
+    
+    for(uword i=0; i<N; ++i)
+      {
+      out_mem[i] = std::complex<T>( out_mem[i].real(), A[i] );
+      }
+    }
+  else
+    {
+    for(uword col=0; col < local_n_cols; ++col)
+    for(uword row=0; row < local_n_rows; ++row)
+      {
+      (*out_mem) = std::complex<T>( (*out_mem).real(), P.at(row,col) );
+      out_mem++;
+      }
+    }
+  }
+
+
+
+#ifdef ARMA_EXTRA_MAT_MEAT
+  #include ARMA_INCFILE_WRAP(ARMA_EXTRA_MAT_MEAT)
+#endif
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/OpCube_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,43 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup OpCube
+//! @{
+
+
+//! Analog of the Op class, intended for cubes
+
+template<typename T1, typename op_type>
+class OpCube : public BaseCube<typename T1::elem_type, OpCube<T1, op_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  
+  inline explicit OpCube(const BaseCube<typename T1::elem_type, T1>& in_m);
+  inline          OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const elem_type in_aux);
+  inline          OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
+  inline          OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
+  inline          OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
+  inline          OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const uword in_aux_uword_d, const char junk);
+  inline         ~OpCube();
+  
+  arma_aligned const T1&       m;            //!< storage of reference to the operand (e.g. a cube)
+  arma_aligned       elem_type aux;          //!< storage of auxiliary data, user defined format
+  arma_aligned       uword     aux_uword_a;  //!< storage of auxiliary data, uword format
+  arma_aligned       uword     aux_uword_b;  //!< storage of auxiliary data, uword format
+  arma_aligned       uword     aux_uword_c;  //!< storage of auxiliary data, uword format
+  arma_aligned       uword     aux_uword_d;  //!< storage of auxiliary data, uword format
+  
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/OpCube_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,90 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup OpCube
+//! @{
+
+
+
+template<typename T1, typename op_type>
+OpCube<T1, op_type>::OpCube(const BaseCube<typename T1::elem_type, T1>& in_m)
+  : m(in_m.get_ref())
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename op_type>
+OpCube<T1, op_type>::OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const typename T1::elem_type in_aux)
+  : m(in_m.get_ref())
+  , aux(in_aux)
+  {
+  arma_extra_debug_sigprint();
+  }
+  
+
+template<typename T1, typename op_type>
+OpCube<T1, op_type>::OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const typename T1::elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c)
+  : m(in_m.get_ref())
+  , aux(in_aux)
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  , aux_uword_c(in_aux_uword_c)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+
+template<typename T1, typename op_type>
+OpCube<T1, op_type>::OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b)
+  : m(in_m.get_ref())
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename op_type>
+OpCube<T1, op_type>::OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c)
+  : m(in_m.get_ref())
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  , aux_uword_c(in_aux_uword_c)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename op_type>
+OpCube<T1, op_type>::OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const uword in_aux_uword_d, const char)
+  : m(in_m.get_ref())
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  , aux_uword_c(in_aux_uword_c)
+  , aux_uword_d(in_aux_uword_d)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename op_type>
+OpCube<T1, op_type>::~OpCube()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Op_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,53 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Op
+//! @{
+
+
+
+//! Class for storing data required for delayed unary operations,
+//! such as the operand (e.g. the matrix to which the operation is to be applied) and the unary operator (e.g. inverse).
+//! The operand is stored as a reference (which can be optimised away),
+//! while the operator is "stored" through the template definition (op_type).
+//! The operands can be 'Mat', 'Row', 'Col', 'Op', and 'Glue'.
+//! Note that as 'Glue' can be one of the operands, more than one matrix can be stored.
+//!
+//! For example, we could have:
+//! Op< Glue< Mat, Mat, glue_times >, op_htrans >
+
+template<typename T1, typename op_type>
+class Op : public Base<typename T1::elem_type, Op<T1, op_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool is_row = ( T1::is_col && (is_same_type<op_type, op_strans>::value || is_same_type<op_type, op_htrans>::value || is_same_type<op_type, op_htrans2>::value) );
+  static const bool is_col = ( T1::is_row && (is_same_type<op_type, op_strans>::value || is_same_type<op_type, op_htrans>::value || is_same_type<op_type, op_htrans2>::value) ) || (is_same_type<op_type, op_diagvec>::value);
+  
+  inline explicit Op(const T1& in_m);
+  inline          Op(const T1& in_m, const elem_type in_aux);
+  inline          Op(const T1& in_m, const elem_type in_aux,         const uword in_aux_uword_a, const uword in_aux_uword_b);
+  inline          Op(const T1& in_m, const uword     in_aux_uword_a, const uword in_aux_uword_b);
+  inline          Op(const T1& in_m, const uword     in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const char junk);
+  inline         ~Op();
+    
+  
+  arma_aligned const T1&       m;            //!< storage of reference to the operand (eg. a matrix)
+  arma_aligned       elem_type aux;          //!< storage of auxiliary data, user defined format
+  arma_aligned       uword     aux_uword_a;  //!< storage of auxiliary data, uword format
+  arma_aligned       uword     aux_uword_b;  //!< storage of auxiliary data, uword format
+  arma_aligned       uword     aux_uword_c;  //!< storage of auxiliary data, uword format
+  
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Op_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,82 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Op
+//! @{
+
+
+
+template<typename T1, typename op_type>
+inline
+Op<T1, op_type>::Op(const T1& in_m)
+  : m(in_m)
+  {
+  arma_extra_debug_sigprint();
+  }
+  
+
+
+template<typename T1, typename op_type>
+inline
+Op<T1, op_type>::Op(const T1& in_m, const typename T1::elem_type in_aux)
+  : m(in_m)
+  , aux(in_aux)
+  {
+  arma_extra_debug_sigprint();
+  }
+  
+
+
+template<typename T1, typename op_type>
+inline
+Op<T1, op_type>::Op(const T1& in_m, const typename T1::elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b)
+  : m(in_m)
+  , aux(in_aux)
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  {
+  arma_extra_debug_sigprint();
+  }
+  
+
+
+template<typename T1, typename op_type>
+inline
+Op<T1, op_type>::Op(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b)
+  : m(in_m)
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename op_type>
+inline
+Op<T1, op_type>::Op(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c, const char)
+  : m(in_m)
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  , aux_uword_c(in_aux_uword_c)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename op_type>
+inline
+Op<T1, op_type>::~Op()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Proxy.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,1831 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Proxy
+//! @{
+
+
+// ea_type is the "element accessor" type,
+// which can provide access to elements via operator[]
+
+
+
+template<typename T1>
+struct Proxy_default
+  {
+  inline Proxy_default(const T1&)
+    {
+    arma_type_check(( is_arma_type<T1>::value == false ));
+    }
+  };
+
+
+
+template<typename T1>
+struct Proxy_fixed
+  {
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef T1                                       stored_type;
+  typedef const elem_type*                         ea_type;
+  typedef const T1&                                aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = true;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = T1::is_row;
+  static const bool is_col = T1::is_col;
+  
+  arma_aligned const T1& Q;
+  
+  inline explicit Proxy_fixed(const T1& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline static uword get_n_rows() { return T1::n_rows; }
+  arma_inline static uword get_n_cols() { return T1::n_cols; }
+  arma_inline static uword get_n_elem() { return T1::n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q.at_alt(i);    }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const
+    {
+    #if defined(ARMA_HAVE_ALIGNED_ATTRIBUTE)
+      return true;
+    #else
+      return memory::is_aligned(Q.memptr());
+    #endif
+    }
+  };
+
+
+
+template<typename T1, bool condition>
+struct Proxy_redirect {};
+
+template<typename T1>
+struct Proxy_redirect<T1, false> { typedef Proxy_default<T1> result; };
+
+template<typename T1>
+struct Proxy_redirect<T1, true>  { typedef Proxy_fixed<T1>   result; };
+
+
+
+template<typename T1>
+class Proxy : public Proxy_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  public:
+  inline Proxy(const T1& A)
+    : Proxy_redirect< T1, is_Mat_fixed<T1>::value >::result(A)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+class Proxy< Mat<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Mat<eT>                                  stored_type;
+  typedef const eT*                                ea_type;
+  typedef const Mat<eT>&                           aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = false;
+  
+  arma_aligned const Mat<eT>& Q;
+  
+  inline explicit Proxy(const Mat<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q.at_alt(i);    }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename eT>
+class Proxy< Col<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Col<eT>                                  stored_type;
+  typedef const eT*                                ea_type;
+  typedef const Col<eT>&                           aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const Col<eT>& Q;
+  
+  inline explicit Proxy(const Col<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return 1;        }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];        }
+  arma_inline elem_type at         (const uword row, const uword) const { return Q[row];      }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q.at_alt(i); }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename eT>
+class Proxy< Row<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Row<eT>                                  stored_type;
+  typedef const eT*                                ea_type;
+  typedef const Row<eT>&                           aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = true;
+  static const bool is_col = false;
+  
+  arma_aligned const Row<eT>& Q;
+  
+  inline explicit Proxy(const Row<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return 1;        }
+  arma_inline uword get_n_cols() const { return Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];        }
+  arma_inline elem_type at         (const uword, const uword col) const { return Q[col];      }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q.at_alt(i); }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename T1, typename gen_type>
+class Proxy< Gen<T1, gen_type > >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Gen<T1, gen_type>                        stored_type;
+  typedef const Gen<T1, gen_type>&                 ea_type;
+  typedef const Gen<T1, gen_type>&                 aligned_ea_type;
+  
+  static const bool prefer_at_accessor = Gen<T1, gen_type>::prefer_at_accessor;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = Gen<T1, gen_type>::is_row;
+  static const bool is_col = Gen<T1, gen_type>::is_col;
+  
+  arma_aligned const Gen<T1, gen_type>& Q;
+  
+  inline explicit Proxy(const Gen<T1, gen_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return (is_row ? 1 : Q.n_rows);                           }
+  arma_inline uword get_n_cols() const { return (is_col ? 1 : Q.n_cols);                           }
+  arma_inline uword get_n_elem() const { return (is_row ? 1 : Q.n_rows) * (is_col ? 1 : Q.n_cols); }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q[i];           }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return Gen<T1, gen_type>::is_simple; }
+  };
+
+
+
+template<typename T1, typename op_type>
+class Proxy< Op<T1, op_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Mat<elem_type>                           stored_type;
+  typedef const elem_type*                         ea_type;
+  typedef const Mat<elem_type>&                    aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = Op<T1, op_type>::is_row;
+  static const bool is_col = Op<T1, op_type>::is_col;
+  
+  arma_aligned const Mat<elem_type> Q;
+  
+  inline explicit Proxy(const Op<T1, op_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return is_row ? 1 : Q.n_rows; }
+  arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem;              }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q.at_alt(i);    }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename T1>
+class Proxy_diagvec_mat
+  {
+  inline Proxy_diagvec_mat(const T1&) {}
+  };
+
+
+
+template<typename T1>
+class Proxy_diagvec_mat< Op<T1, op_diagvec> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef diagview<elem_type>                      stored_type;
+  typedef const diagview<elem_type>&               ea_type;
+  typedef const diagview<elem_type>&               aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = true;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const Mat<elem_type>&     R;
+  arma_aligned const diagview<elem_type> Q;
+  
+  inline explicit Proxy_diagvec_mat(const Op<T1, op_diagvec>& A)
+    : R(A.m), Q( R.diag( (A.aux_uword_b > 0) ? -sword(A.aux_uword_a) : sword(A.aux_uword_a) ) )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return 1;        }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];         }
+  arma_inline elem_type at         (const uword row, const uword) const { return Q.at(row, 0); }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q[i];         }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&R) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const { return false; }
+  };
+
+
+
+template<typename T1>
+class Proxy_diagvec_expr
+  {
+  inline Proxy_diagvec_expr(const T1&) {}
+  };
+
+
+
+template<typename T1>
+class Proxy_diagvec_expr< Op<T1, op_diagvec> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Mat<elem_type>                           stored_type;
+  typedef const elem_type*                         ea_type;
+  typedef const Mat<elem_type>&                    aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const Mat<elem_type> Q;
+  
+  inline explicit Proxy_diagvec_expr(const Op<T1, op_diagvec>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return 1;        }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];         }
+  arma_inline elem_type at         (const uword row, const uword) const { return Q.at(row, 0); }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q.at_alt(i);  }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename T1, bool condition>
+struct Proxy_diagvec_redirect {};
+
+template<typename T1>
+struct Proxy_diagvec_redirect< Op<T1, op_diagvec>, true > { typedef Proxy_diagvec_mat < Op<T1, op_diagvec> > result; };
+
+template<typename T1>
+struct Proxy_diagvec_redirect< Op<T1, op_diagvec>, false> { typedef Proxy_diagvec_expr< Op<T1, op_diagvec> > result; };
+
+
+
+template<typename T1>
+class Proxy< Op<T1, op_diagvec> >
+  : public Proxy_diagvec_redirect< Op<T1, op_diagvec>, is_Mat<T1>::value >::result
+  {
+  public:
+  
+  typedef typename Proxy_diagvec_redirect< Op<T1, op_diagvec>, is_Mat<T1>::value >::result Proxy_diagvec;
+  
+  inline explicit Proxy(const Op<T1, op_diagvec>& A)
+    : Proxy_diagvec(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  };
+
+
+
+template<typename T1>
+struct Proxy_xtrans_default
+  {
+  typedef typename T1::elem_type eT;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  arma_aligned const Mat<eT> Q;
+  
+  arma_hot
+  inline Proxy_xtrans_default(const T1& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
+  };
+
+
+
+template<typename T1>
+struct Proxy_xtrans_vector
+  {
+  inline Proxy_xtrans_vector(const T1&) {}
+  };
+
+
+
+template<typename T1>
+struct Proxy_xtrans_vector< Op<T1, op_htrans> >
+  {
+  typedef typename T1::elem_type eT;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = quasi_unwrap<T1>::has_subview;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = true;
+  
+  arma_aligned const quasi_unwrap<T1> U; // avoid copy if T1 is a Row, Col or subview_col
+  arma_aligned const Mat<eT>          Q;
+  
+  inline Proxy_xtrans_vector(const Op<T1, op_htrans>& A)
+    : U(A.m)
+    , Q(const_cast<eT*>(U.M.memptr()), U.M.n_cols, U.M.n_rows, false, false)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return U.is_alias(X); }
+  };
+
+
+
+template<typename T1>
+struct Proxy_xtrans_vector< Op<T1, op_strans> >
+  {
+  typedef typename T1::elem_type eT;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = quasi_unwrap<T1>::has_subview;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = true;
+  
+  arma_aligned const quasi_unwrap<T1> U; // avoid copy if T1 is a Row, Col or subview_col
+  arma_aligned const Mat<eT>          Q;
+  
+  inline Proxy_xtrans_vector(const Op<T1, op_strans>& A)
+    : U(A.m)
+    , Q(const_cast<eT*>(U.M.memptr()), U.M.n_cols, U.M.n_rows, false, false)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return U.is_alias(X); }
+  };
+
+
+
+template<typename T1, bool condition>
+struct Proxy_xtrans_redirect {};
+
+template<typename T1>
+struct Proxy_xtrans_redirect<T1, false> { typedef Proxy_xtrans_default<T1> result; };
+
+template<typename T1>
+struct Proxy_xtrans_redirect<T1, true>  { typedef Proxy_xtrans_vector<T1>  result; };
+
+
+
+template<typename T1>
+class Proxy< Op<T1, op_htrans> >
+  : public
+    Proxy_xtrans_redirect
+      <
+      Op<T1, op_htrans>,
+      ((is_complex<typename T1::elem_type>::value == false) && ((Op<T1, op_htrans>::is_row) || (Op<T1, op_htrans>::is_col)) )
+      >::result
+  {
+  public:
+  
+  typedef
+  typename
+  Proxy_xtrans_redirect
+    <
+    Op<T1, op_htrans>,
+    ((is_complex<typename T1::elem_type>::value == false) && ((Op<T1, op_htrans>::is_row) || (Op<T1, op_htrans>::is_col)) )
+    >::result
+  Proxy_xtrans;
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Mat<elem_type>                           stored_type;
+  typedef const elem_type*                         ea_type;
+  typedef const Mat<elem_type>&                    aligned_ea_type;
+  
+  static const bool prefer_at_accessor = Proxy_xtrans::prefer_at_accessor;
+  static const bool has_subview        = Proxy_xtrans::has_subview;
+  static const bool is_fixed           = Proxy_xtrans::is_fixed;
+  static const bool fake_mat           = Proxy_xtrans::fake_mat;
+  
+  // NOTE: the Op class takes care of swapping row and col for op_htrans
+  static const bool is_row = Op<T1, op_htrans>::is_row;
+  static const bool is_col = Op<T1, op_htrans>::is_col;
+  
+  using Proxy_xtrans::Q;
+  
+  inline explicit Proxy(const Op<T1, op_htrans>& A)
+    : Proxy_xtrans(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return is_row ? 1 : Q.n_rows; }
+  arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem;              }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q.at_alt(i);    }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return Proxy_xtrans::is_alias(X); }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename T1>
+class Proxy< Op<T1, op_strans> >
+  : public
+    Proxy_xtrans_redirect
+      <
+      Op<T1, op_strans>,
+      ( (Op<T1, op_strans>::is_row) || (Op<T1, op_strans>::is_col) )
+      >::result
+  {
+  public:
+  
+  typedef
+  typename
+  Proxy_xtrans_redirect
+    <
+    Op<T1, op_strans>,
+    ( (Op<T1, op_strans>::is_row) || (Op<T1, op_strans>::is_col) )
+    >::result
+  Proxy_xtrans;
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Mat<elem_type>                           stored_type;
+  typedef const elem_type*                         ea_type;
+  typedef const Mat<elem_type>&                    aligned_ea_type;
+  
+  static const bool prefer_at_accessor = Proxy_xtrans::prefer_at_accessor;
+  static const bool has_subview        = Proxy_xtrans::has_subview;
+  static const bool is_fixed           = Proxy_xtrans::is_fixed;
+  static const bool fake_mat           = Proxy_xtrans::fake_mat;
+  
+  // NOTE: the Op class takes care of swapping row and col for op_strans
+  static const bool is_row = Op<T1, op_strans>::is_row;
+  static const bool is_col = Op<T1, op_strans>::is_col;
+  
+  using Proxy_xtrans::Q;
+  
+  inline explicit Proxy(const Op<T1, op_strans>& A)
+    : Proxy_xtrans(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return is_row ? 1 : Q.n_rows; }
+  arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem;              }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q.at_alt(i);    }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return Proxy_xtrans::is_alias(X); }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename eT>
+struct Proxy_subview_row_htrans_cx
+  {
+  typedef eT                                elem_type;
+  typedef typename get_pod_type<eT>::result pod_type;
+  typedef subview_row_htrans<eT>            stored_type;
+  typedef const subview_row_htrans<eT>&     ea_type;
+  typedef const subview_row_htrans<eT>&     aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = true;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const subview_row_htrans<eT> Q;
+  
+  inline explicit Proxy_subview_row_htrans_cx(const Op<subview_row<eT>, op_htrans>& A)
+    : Q(A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&(Q.sv_row.m)) == void_ptr(&X)); }
+  };
+
+
+
+template<typename eT>
+struct Proxy_subview_row_htrans_non_cx
+  {
+  typedef eT                                elem_type;
+  typedef typename get_pod_type<eT>::result pod_type;
+  typedef subview_row_strans<eT>            stored_type;
+  typedef const subview_row_strans<eT>&     ea_type;
+  typedef const subview_row_strans<eT>&     aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = true;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const subview_row_strans<eT> Q;
+  
+  inline explicit Proxy_subview_row_htrans_non_cx(const Op<subview_row<eT>, op_htrans>& A)
+    : Q(A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&(Q.sv_row.m)) == void_ptr(&X)); }
+  };
+
+
+
+template<typename eT, bool condition>
+struct Proxy_subview_row_htrans_redirect {};
+
+template<typename eT>
+struct Proxy_subview_row_htrans_redirect<eT, true>  { typedef Proxy_subview_row_htrans_cx<eT>      result; };
+
+template<typename eT>
+struct Proxy_subview_row_htrans_redirect<eT, false> { typedef Proxy_subview_row_htrans_non_cx<eT>  result; };
+
+
+
+template<typename eT>
+class Proxy< Op<subview_row<eT>, op_htrans> >
+  : public
+    Proxy_subview_row_htrans_redirect
+      <
+      eT,
+      is_complex<eT>::value
+      >::result
+  {
+  public:
+  
+  typedef
+  typename
+  Proxy_subview_row_htrans_redirect
+      <
+      eT,
+      is_complex<eT>::value
+      >::result
+  Proxy_sv_row_ht;
+  
+  typedef typename Proxy_sv_row_ht::elem_type   elem_type;
+  typedef typename Proxy_sv_row_ht::pod_type    pod_type;
+  typedef typename Proxy_sv_row_ht::stored_type stored_type;
+  typedef typename Proxy_sv_row_ht::ea_type     ea_type;
+  typedef typename Proxy_sv_row_ht::ea_type     aligned_ea_type;
+  
+  static const bool prefer_at_accessor = Proxy_sv_row_ht::prefer_at_accessor;
+  static const bool has_subview        = Proxy_sv_row_ht::has_subview;
+  static const bool is_fixed           = Proxy_sv_row_ht::is_fixed;
+  static const bool fake_mat           = Proxy_sv_row_ht::fake_mat;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  using Proxy_sv_row_ht::Q;
+  
+  inline explicit Proxy(const Op<subview_row<eT>, op_htrans>& A)
+    : Proxy_sv_row_ht(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return 1;        }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];   }
+  arma_inline elem_type at         (const uword row, const uword) const { return Q[row]; }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q[i];   }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return Proxy_sv_row_ht::is_alias(X); }
+  
+  arma_inline bool is_aligned() const { return false; }
+  };
+
+
+
+template<typename eT>
+class Proxy< Op<subview_row<eT>, op_strans> >
+  {
+  public:
+  
+  typedef eT                                elem_type;
+  typedef typename get_pod_type<eT>::result pod_type;
+  typedef subview_row_strans<eT>            stored_type;
+  typedef const subview_row_strans<eT>&     ea_type;
+  typedef const subview_row_strans<eT>&     aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = true;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const subview_row_strans<eT> Q;
+  
+  inline explicit Proxy(const Op<subview_row<eT>, op_strans>& A)
+    : Q(A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return 1;        }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];   }
+  arma_inline elem_type at         (const uword row, const uword) const { return Q[row]; }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q[i];   }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&(Q.sv_row.m)) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const { return false; }
+  };
+
+
+  
+template<typename T>
+class Proxy< Op< Row< std::complex<T> >, op_htrans> >
+  {
+  public:
+  
+  typedef typename std::complex<T>  eT;
+
+  typedef typename std::complex<T>  elem_type;
+  typedef T                         pod_type;
+  typedef xvec_htrans<eT>           stored_type;
+  typedef const xvec_htrans<eT>&    ea_type;
+  typedef const xvec_htrans<eT>&    aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  const xvec_htrans<eT> Q;
+  const Row<eT>&        src;
+  
+  inline explicit Proxy(const Op< Row< std::complex<T> >, op_htrans>& A)
+    : Q  (A.m.memptr(), A.m.n_rows, A.m.n_cols)
+    , src(A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return 1;        }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];   }
+  arma_inline elem_type at         (const uword row, const uword) const { return Q[row]; }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q[i];   }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return void_ptr(&src) == void_ptr(&X); }
+  
+  arma_inline bool is_aligned() const { return false; }
+  };
+
+
+
+template<typename T>
+class Proxy< Op< Col< std::complex<T> >, op_htrans> >
+  {
+  public:
+  
+  typedef typename std::complex<T>  eT;
+
+  typedef typename std::complex<T>  elem_type;
+  typedef T                         pod_type;
+  typedef xvec_htrans<eT>           stored_type;
+  typedef const xvec_htrans<eT>&    ea_type;
+  typedef const xvec_htrans<eT>&    aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = true;
+  static const bool is_col = false;
+  
+  const xvec_htrans<eT> Q;
+  const Col<eT>&        src;
+  
+  inline explicit Proxy(const Op< Col< std::complex<T> >, op_htrans>& A)
+    : Q  (A.m.memptr(), A.m.n_rows, A.m.n_cols)
+    , src(A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return 1;        }
+  arma_inline uword get_n_cols() const { return Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];   }
+  arma_inline elem_type at         (const uword, const uword col) const { return Q[col]; }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q[i];   }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return void_ptr(&src) == void_ptr(&X); }
+  
+  arma_inline bool is_aligned() const { return false; }
+  };
+
+
+
+template<typename T>
+class Proxy< Op< subview_col< std::complex<T> >, op_htrans> >
+  {
+  public:
+  
+  typedef typename std::complex<T>  eT;
+  
+  typedef typename std::complex<T>  elem_type;
+  typedef T                         pod_type;
+  typedef xvec_htrans<eT>           stored_type;
+  typedef const xvec_htrans<eT>&    ea_type;
+  typedef const xvec_htrans<eT>&    aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = true;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = true;
+  static const bool is_col = false;
+  
+  const xvec_htrans<eT>  Q;
+  const subview_col<eT>& src;
+  
+  inline explicit Proxy(const Op< subview_col< std::complex<T> >, op_htrans>& A)
+    : Q  (A.m.colptr(0), A.m.n_rows, A.m.n_cols)
+    , src(A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return 1;        }
+  arma_inline uword get_n_cols() const { return Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];   }
+  arma_inline elem_type at         (const uword, const uword col) const { return Q[col]; }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q[i];   }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return void_ptr(&src.m) == void_ptr(&X); }
+  
+  arma_inline bool is_aligned() const { return false; }
+  };
+
+
+
+template<typename T1>
+struct Proxy_htrans2_default
+  {
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Mat<elem_type>                           stored_type;
+  typedef const elem_type*                         ea_type;
+  typedef const Mat<elem_type>&                    aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = false;
+  
+  arma_aligned const Mat<elem_type> Q;
+  
+  arma_hot
+  inline Proxy_htrans2_default(const T1& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename T1>
+struct Proxy_htrans2_vector
+  {
+  inline Proxy_htrans2_vector(const T1&) {}
+  };
+
+
+
+template<typename T1>
+struct Proxy_htrans2_vector< Op<T1, op_htrans2> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                           elem_type;
+  typedef typename get_pod_type<elem_type>::result         pod_type;
+  typedef       eOp< Op<T1, op_htrans>, eop_scalar_times>  stored_type;
+  typedef const eOp< Op<T1, op_htrans>, eop_scalar_times>& ea_type;
+  typedef const eOp< Op<T1, op_htrans>, eop_scalar_times>& aligned_ea_type;
+  
+  static const bool prefer_at_accessor = eOp< Op<T1, op_htrans>, eop_scalar_times>::prefer_at_accessor;
+  static const bool has_subview        = eOp< Op<T1, op_htrans>, eop_scalar_times>::has_subview;
+  static const bool is_fixed           = eOp< Op<T1, op_htrans>, eop_scalar_times>::is_fixed;
+  static const bool fake_mat           = eOp< Op<T1, op_htrans>, eop_scalar_times>::fake_mat;
+  
+  // NOTE: the Op class takes care of swapping row and col for op_htrans
+  static const bool is_row = eOp< Op<T1, op_htrans>, eop_scalar_times>::is_row;
+  static const bool is_col = eOp< Op<T1, op_htrans>, eop_scalar_times>::is_col;
+  
+  arma_aligned const      Op<T1, op_htrans>                     R;
+  arma_aligned const eOp< Op<T1, op_htrans>, eop_scalar_times > Q;
+  
+  inline explicit Proxy_htrans2_vector(const Op<T1, op_htrans2>& A)
+    : R(A.m)
+    , Q(R, A.aux)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return is_row ? 1 : Q.get_n_rows(); }
+  arma_inline uword get_n_cols() const { return is_col ? 1 : Q.get_n_cols(); }
+  arma_inline uword get_n_elem() const { return Q.get_n_elem();              }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return Q.P.is_alias(X); }
+  
+  arma_inline bool is_aligned() const { return Q.P.is_aligned(); }
+  };
+
+
+
+template<typename T1, bool condition>
+struct Proxy_htrans2_redirect {};
+
+template<typename T1>
+struct Proxy_htrans2_redirect<T1, false> { typedef Proxy_htrans2_default<T1> result; };
+
+template<typename T1>
+struct Proxy_htrans2_redirect<T1, true>  { typedef Proxy_htrans2_vector<T1>  result; };
+
+
+
+template<typename T1>
+class Proxy< Op<T1, op_htrans2> >
+  : public
+    Proxy_htrans2_redirect
+      <
+      Op<T1, op_htrans2>,
+      ( (Op<T1, op_htrans2>::is_row) || (Op<T1, op_htrans2>::is_col) )
+      >::result
+  {
+  public:
+  
+  typedef
+  typename
+  Proxy_htrans2_redirect
+    <
+    Op<T1, op_htrans2>,
+    ( (Op<T1, op_htrans2>::is_row) || (Op<T1, op_htrans2>::is_col) )
+    >::result
+  Proxy_htrans2;
+  
+  typedef typename Proxy_htrans2::elem_type       elem_type;
+  typedef typename Proxy_htrans2::pod_type        pod_type;
+  typedef typename Proxy_htrans2::stored_type     stored_type;
+  typedef typename Proxy_htrans2::ea_type         ea_type;
+  typedef typename Proxy_htrans2::aligned_ea_type aligned_ea_type;
+  
+  static const bool prefer_at_accessor = Proxy_htrans2::prefer_at_accessor;
+  static const bool has_subview        = Proxy_htrans2::has_subview;
+  static const bool is_fixed           = Proxy_htrans2::is_fixed;
+  static const bool fake_mat           = Proxy_htrans2::fake_mat;
+  
+  static const bool is_row = Proxy_htrans2::is_row;
+  static const bool is_col = Proxy_htrans2::is_col;
+  
+  using Proxy_htrans2::Q;
+  
+  inline explicit Proxy(const Op<T1, op_htrans2>& A)
+    : Proxy_htrans2(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Proxy_htrans2::get_n_rows(); }
+  arma_inline uword get_n_cols() const { return Proxy_htrans2::get_n_cols(); }
+  arma_inline uword get_n_elem() const { return Proxy_htrans2::get_n_elem(); }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q.at_alt(i);    }
+  
+  arma_inline         ea_type         get_ea() const { return Proxy_htrans2::get_ea();         }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Proxy_htrans2::get_aligned_ea(); }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return Proxy_htrans2::is_alias(X); }
+  
+  arma_inline bool is_aligned() const { return Proxy_htrans2::is_aligned(); }
+  };
+
+
+
+template<typename T1, typename T2, typename glue_type>
+class Proxy< Glue<T1, T2, glue_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Mat<elem_type>                           stored_type;
+  typedef const elem_type*                         ea_type;
+  typedef const Mat<elem_type>&                    aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = Glue<T1, T2, glue_type>::is_row;
+  static const bool is_col = Glue<T1, T2, glue_type>::is_col;
+  
+  arma_aligned const Mat<elem_type> Q;
+  
+  inline explicit Proxy(const Glue<T1, T2, glue_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+
+  arma_inline uword get_n_rows() const { return is_row ? 1 : Q.n_rows; }
+  arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem;              }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q.at_alt(i);    }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename eT>
+class Proxy< subview<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef subview<eT>                              stored_type;
+  typedef const subview<eT>&                       ea_type;
+  typedef const subview<eT>&                       aligned_ea_type;
+  
+  static const bool prefer_at_accessor = true;
+  static const bool has_subview        = true;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = false;
+  
+  arma_aligned const subview<eT>& Q;
+  
+  inline explicit Proxy(const subview<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q[i];           }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&(Q.m)) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const { return false; }
+  };
+
+
+
+template<typename eT>
+class Proxy< subview_col<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef subview_col<eT>                          stored_type;
+  typedef const eT*                                ea_type;
+  typedef const subview_col<eT>&                   aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = true;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const subview_col<eT>& Q;
+  
+  inline explicit Proxy(const subview_col<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return 1;        }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];        }
+  arma_inline elem_type at         (const uword row, const uword) const { return Q[row];      }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q.at_alt(i); }
+  
+  arma_inline         ea_type         get_ea() const { return Q.colmem; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;        }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&(Q.m)) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.colmem); }
+  };
+
+
+
+template<typename eT>
+class Proxy< subview_row<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef subview_row<eT>                          stored_type;
+  typedef const subview_row<eT>&                   ea_type;
+  typedef const subview_row<eT>&                   aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = true;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = true;
+  static const bool is_col = false;
+  
+  arma_aligned const subview_row<eT>& Q;
+  
+  inline explicit Proxy(const subview_row<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return 1;        }
+  arma_inline uword get_n_cols() const { return Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];   }
+  arma_inline elem_type at         (const uword, const uword col) const { return Q[col]; }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q[i];   }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&(Q.m)) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const { return false; }
+  };
+
+
+
+template<typename eT>
+class Proxy< subview_row_strans<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef subview_row_strans<eT>                   stored_type;
+  typedef const subview_row_strans<eT>&            ea_type;
+  typedef const subview_row_strans<eT>&            aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = true;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const subview_row_strans<eT>& Q;
+  
+  inline explicit Proxy(const subview_row_strans<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return 1;        }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];   }
+  arma_inline elem_type at         (const uword row, const uword) const { return Q[row]; }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q[i];   }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&(Q.sv_row.m)) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const { return false; }
+  };
+
+
+
+template<typename eT>
+class Proxy< subview_row_htrans<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef subview_row_htrans<eT>                   stored_type;
+  typedef const subview_row_htrans<eT>&            ea_type;
+  typedef const subview_row_htrans<eT>&            aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = true;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const subview_row_htrans<eT>& Q;
+  
+  inline explicit Proxy(const subview_row_htrans<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return 1;        }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];   }
+  arma_inline elem_type at         (const uword row, const uword) const { return Q[row]; }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q[i];   }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&(Q.sv_row.m)) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const { return false; }
+  };
+
+
+
+template<typename eT>
+class Proxy< xvec_htrans<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Mat<eT>                                  stored_type;
+  typedef const eT*                                ea_type;
+  typedef const Mat<eT>&                           aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = false;
+  
+  arma_aligned const Mat<eT> Q;
+  
+  inline explicit Proxy(const xvec_htrans<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];          }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row,col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q.at_alt(i);   }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return false; }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename eT, typename T1>
+class Proxy< subview_elem1<eT,T1> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Mat<eT>                                  stored_type;
+  typedef const eT*                                ea_type;
+  typedef const Mat<eT>&                           aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const Mat<eT> Q;
+  
+  inline explicit Proxy(const subview_elem1<eT,T1>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return 1;        }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];        }
+  arma_inline elem_type at         (const uword row, const uword) const { return Q[row];      }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q.at_alt(i); }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename eT, typename T1, typename T2>
+class Proxy< subview_elem2<eT,T1,T2> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Mat<eT>                                  stored_type;
+  typedef const eT*                                ea_type;
+  typedef const Mat<eT>&                           aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = false;
+  
+  arma_aligned const Mat<eT> Q;
+  
+  inline explicit Proxy(const subview_elem2<eT,T1,T2>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q.at_alt(i);    }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename eT>
+class Proxy< diagview<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef diagview<eT>                             stored_type;
+  typedef const diagview<eT>&                      ea_type;
+  typedef const diagview<eT>&                      aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = true;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const diagview<eT>& Q;
+  
+  inline explicit Proxy(const diagview<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return Q.n_rows; }
+  arma_inline uword get_n_cols() const { return 1;        }
+  arma_inline uword get_n_elem() const { return Q.n_elem; }
+  
+  arma_inline elem_type operator[] (const uword i)                const { return Q[i];         }
+  arma_inline elem_type at         (const uword row, const uword) const { return Q.at(row, 0); }
+  arma_inline elem_type at_alt     (const uword i)                const { return Q[i];         }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&(Q.m)) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const { return false; }
+  };
+
+
+
+
+template<typename T1, typename eop_type>
+class Proxy< eOp<T1, eop_type > >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef eOp<T1, eop_type>                        stored_type;
+  typedef const eOp<T1, eop_type>&                 ea_type;
+  typedef const eOp<T1, eop_type>&                 aligned_ea_type;
+  
+  static const bool prefer_at_accessor = eOp<T1, eop_type>::prefer_at_accessor;
+  static const bool has_subview        = eOp<T1, eop_type>::has_subview;
+  static const bool is_fixed           = eOp<T1, eop_type>::is_fixed;
+  static const bool fake_mat           = eOp<T1, eop_type>::fake_mat;
+  
+  static const bool is_row = eOp<T1, eop_type>::is_row;
+  static const bool is_col = eOp<T1, eop_type>::is_col;
+  
+  arma_aligned const eOp<T1, eop_type>& Q;
+  
+  inline explicit Proxy(const eOp<T1, eop_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return is_row ? 1 : Q.get_n_rows(); }
+  arma_inline uword get_n_cols() const { return is_col ? 1 : Q.get_n_cols(); }
+  arma_inline uword get_n_elem() const { return Q.get_n_elem();              }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q.at_alt(i);    }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return Q.P.is_alias(X); }
+  
+  arma_inline bool is_aligned() const { return Q.P.is_aligned(); }
+  };
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+class Proxy< eGlue<T1, T2, eglue_type > >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef eGlue<T1, T2, eglue_type>                stored_type;
+  typedef const eGlue<T1, T2, eglue_type>&         ea_type;
+  typedef const eGlue<T1, T2, eglue_type>&         aligned_ea_type;
+  
+  static const bool prefer_at_accessor = eGlue<T1, T2, eglue_type>::prefer_at_accessor;
+  static const bool has_subview        = eGlue<T1, T2, eglue_type>::has_subview;
+  static const bool is_fixed           = eGlue<T1, T2, eglue_type>::is_fixed;
+  static const bool fake_mat           = eGlue<T1, T2, eglue_type>::fake_mat;
+  
+  static const bool is_row = eGlue<T1, T2, eglue_type>::is_row;
+  static const bool is_col = eGlue<T1, T2, eglue_type>::is_col;
+  
+  arma_aligned const eGlue<T1, T2, eglue_type>& Q;
+  
+  inline explicit Proxy(const eGlue<T1, T2, eglue_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return is_row ? 1 : Q.get_n_rows(); }
+  arma_inline uword get_n_cols() const { return is_col ? 1 : Q.get_n_cols(); }
+  arma_inline uword get_n_elem() const { return Q.get_n_elem();              }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row, col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q.at_alt(i);    }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (Q.P1.is_alias(X) || Q.P2.is_alias(X)); }
+  
+  arma_inline bool is_aligned() const { return (Q.P1.is_aligned() && Q.P2.is_aligned()); }
+  };
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+class Proxy< mtOp<out_eT, T1, op_type> >
+  {
+  public:
+  
+  typedef          out_eT                       elem_type;
+  typedef typename get_pod_type<out_eT>::result pod_type;
+  typedef          Mat<out_eT>                  stored_type;
+  typedef          const elem_type*             ea_type;
+  typedef          const Mat<out_eT>&           aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = mtOp<out_eT, T1, op_type>::is_row;
+  static const bool is_col = mtOp<out_eT, T1, op_type>::is_col;
+  
+  arma_aligned const Mat<out_eT> Q;
+  
+  inline explicit Proxy(const mtOp<out_eT, T1, op_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return is_row ? 1 : Q.n_rows; }
+  arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem;              }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];          }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row,col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q.at_alt(i);   }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename out_eT, typename T1, typename T2, typename glue_type>
+class Proxy< mtGlue<out_eT, T1, T2, glue_type > >
+  {
+  public:
+  
+  typedef          out_eT                       elem_type;
+  typedef typename get_pod_type<out_eT>::result pod_type;
+  typedef          Mat<out_eT>                  stored_type;
+  typedef          const elem_type*             ea_type;
+  typedef          const Mat<out_eT>&           aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  static const bool is_fixed           = false;
+  static const bool fake_mat           = false;
+  
+  static const bool is_row = mtGlue<out_eT, T1, T2, glue_type>::is_row;
+  static const bool is_col = mtGlue<out_eT, T1, T2, glue_type>::is_col;
+  
+  arma_aligned const Mat<out_eT> Q;
+  
+  inline explicit Proxy(const mtGlue<out_eT, T1, T2, glue_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows() const { return is_row ? 1 : Q.n_rows; }
+  arma_inline uword get_n_cols() const { return is_col ? 1 : Q.n_cols; }
+  arma_inline uword get_n_elem() const { return Q.n_elem;              }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return Q[i];          }
+  arma_inline elem_type at         (const uword row, const uword col) const { return Q.at(row,col); }
+  arma_inline elem_type at_alt     (const uword i)                    const { return Q.at_alt(i);   }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/ProxyCube.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,416 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup ProxyCube
+//! @{
+
+
+
+template<typename T1>
+class ProxyCube
+  {
+  public:
+  inline ProxyCube(const T1&)
+    {
+    arma_type_check(( is_arma_cube_type<T1>::value == false ));
+    }
+  };
+
+
+
+// ea_type is the "element accessor" type,
+// which can provide access to elements via operator[]
+
+template<typename eT>
+class ProxyCube< Cube<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Cube<eT>                                 stored_type;
+  typedef const eT*                                ea_type;
+  typedef const Cube<eT>&                          aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  
+  arma_aligned const Cube<eT>& Q;
+  
+  inline explicit ProxyCube(const Cube<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows()       const { return Q.n_rows;       }
+  arma_inline uword get_n_cols()       const { return Q.n_cols;       }
+  arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
+  arma_inline uword get_n_slices()     const { return Q.n_slices;     }
+  arma_inline uword get_n_elem()       const { return Q.n_elem;       }
+  
+  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
+  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
+  arma_inline elem_type at_alt     (const uword i)                                       const { return Q.at_alt(i);           }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Cube<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename eT, typename gen_type>
+class ProxyCube< GenCube<eT, gen_type > >
+  {
+  public:
+  
+  typedef          eT                              elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef GenCube<eT, gen_type>                    stored_type;
+  typedef const GenCube<eT, gen_type>&             ea_type;
+  typedef const GenCube<eT, gen_type>&             aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  
+  arma_aligned const GenCube<eT, gen_type>& Q;
+  
+  inline explicit ProxyCube(const GenCube<eT, gen_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows()       const { return Q.n_rows;                     }
+  arma_inline uword get_n_cols()       const { return Q.n_cols;                     }
+  arma_inline uword get_n_elem_slice() const { return Q.n_rows*Q.n_cols;            }
+  arma_inline uword get_n_slices()     const { return Q.n_slices;                   }
+  arma_inline uword get_n_elem()       const { return Q.n_rows*Q.n_cols*Q.n_slices; }
+  
+  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
+  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
+  arma_inline elem_type at_alt     (const uword i)                                       const { return Q[i];                  }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Cube<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return GenCube<eT, gen_type>::is_simple; }
+  };
+
+
+
+template<typename T1, typename op_type>
+class ProxyCube< OpCube<T1, op_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Cube<elem_type>                          stored_type;
+  typedef const elem_type*                         ea_type;
+  typedef const Cube<elem_type>&                   aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  
+  arma_aligned const Cube<elem_type> Q;
+  
+  inline explicit ProxyCube(const OpCube<T1, op_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows()       const { return Q.n_rows;       }
+  arma_inline uword get_n_cols()       const { return Q.n_cols;       }
+  arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
+  arma_inline uword get_n_slices()     const { return Q.n_slices;     }
+  arma_inline uword get_n_elem()       const { return Q.n_elem;       }
+  
+  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
+  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
+  arma_inline elem_type at_alt     (const uword i)                                       const { return Q.at_alt(i);           }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Cube<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename T1, typename T2, typename glue_type>
+class ProxyCube< GlueCube<T1, T2, glue_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef Cube<elem_type>                          stored_type;
+  typedef const elem_type*                         ea_type;
+  typedef const Cube<elem_type>&                   aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  
+  arma_aligned const Cube<elem_type> Q;
+  
+  inline explicit ProxyCube(const GlueCube<T1, T2, glue_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+
+  arma_inline uword get_n_rows()       const { return Q.n_rows;       }
+  arma_inline uword get_n_cols()       const { return Q.n_cols;       }
+  arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
+  arma_inline uword get_n_slices()     const { return Q.n_slices;     }
+  arma_inline uword get_n_elem()       const { return Q.n_elem;       }
+  
+  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
+  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
+  arma_inline elem_type at_alt     (const uword i)                                       const { return Q.at_alt(i);           }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Cube<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename eT>
+class ProxyCube< subview_cube<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef subview_cube<eT>                         stored_type;
+  typedef const subview_cube<eT>&                  ea_type;
+  typedef const subview_cube<eT>&                  aligned_ea_type;
+  
+  static const bool prefer_at_accessor = true;
+  static const bool has_subview        = true;
+  
+  arma_aligned const subview_cube<eT>& Q;
+  
+  inline explicit ProxyCube(const subview_cube<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows()       const { return Q.n_rows;       }
+  arma_inline uword get_n_cols()       const { return Q.n_cols;       }
+  arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
+  arma_inline uword get_n_slices()     const { return Q.n_slices;     }
+  arma_inline uword get_n_elem()       const { return Q.n_elem;       }
+  
+  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
+  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
+  arma_inline elem_type at_alt     (const uword i)                                       const { return Q.at_alt(i);           }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Cube<eT2>& X) const { return (void_ptr(&(Q.m)) == void_ptr(&X)); }
+  
+  arma_inline bool is_aligned() const { return false; }
+  };
+
+
+
+template<typename T1, typename eop_type>
+class ProxyCube< eOpCube<T1, eop_type > >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef eOpCube<T1, eop_type>                    stored_type;
+  typedef const eOpCube<T1, eop_type>&             ea_type;
+  typedef const eOpCube<T1, eop_type>&             aligned_ea_type;
+  
+  static const bool prefer_at_accessor = eOpCube<T1, eop_type>::prefer_at_accessor;
+  static const bool has_subview        = eOpCube<T1, eop_type>::has_subview;
+  
+  arma_aligned const eOpCube<T1, eop_type>& Q;
+  
+  inline explicit ProxyCube(const eOpCube<T1, eop_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows()       const { return Q.get_n_rows();       }
+  arma_inline uword get_n_cols()       const { return Q.get_n_cols();       }
+  arma_inline uword get_n_elem_slice() const { return Q.get_n_elem_slice(); }
+  arma_inline uword get_n_slices()     const { return Q.get_n_slices();     }
+  arma_inline uword get_n_elem()       const { return Q.get_n_elem();       }
+  
+  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
+  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
+  arma_inline elem_type at_alt     (const uword i)                                       const { return Q.at_alt(i);           }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Cube<eT2>& X) const { return Q.P.is_alias(X); }
+  
+  arma_inline bool is_aligned() const { return Q.P.is_aligned(); }
+  };
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+class ProxyCube< eGlueCube<T1, T2, eglue_type > >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef eGlueCube<T1, T2, eglue_type>            stored_type;
+  typedef const eGlueCube<T1, T2, eglue_type>&     ea_type;
+  typedef const eGlueCube<T1, T2, eglue_type>&     aligned_ea_type;
+  
+  static const bool prefer_at_accessor = eGlueCube<T1, T2, eglue_type>::prefer_at_accessor;
+  static const bool has_subview        = eGlueCube<T1, T2, eglue_type>::has_subview;
+  
+  arma_aligned const eGlueCube<T1, T2, eglue_type>& Q;
+  
+  inline explicit ProxyCube(const eGlueCube<T1, T2, eglue_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows()       const { return Q.get_n_rows();       }
+  arma_inline uword get_n_cols()       const { return Q.get_n_cols();       }
+  arma_inline uword get_n_elem_slice() const { return Q.get_n_elem_slice(); }
+  arma_inline uword get_n_slices()     const { return Q.get_n_slices();     }
+  arma_inline uword get_n_elem()       const { return Q.get_n_elem();       }
+  
+  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
+  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
+  arma_inline elem_type at_alt     (const uword i)                                       const { return Q.at_alt(i);           }
+  
+  arma_inline         ea_type         get_ea() const { return Q; }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Cube<eT2>& X) const { return (Q.P1.is_alias(X) || Q.P2.is_alias(X)); }
+  
+  arma_inline bool is_aligned() const { return Q.P1.is_aligned() && Q.P2.is_aligned(); }
+  };
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+class ProxyCube< mtOpCube<out_eT, T1, op_type> >
+  {
+  public:
+  
+  typedef          out_eT                       elem_type;
+  typedef typename get_pod_type<out_eT>::result pod_type;
+  typedef          Cube<out_eT>                 stored_type;
+  typedef          const elem_type*             ea_type;
+  typedef          const Cube<out_eT>&          aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  
+  arma_aligned const Cube<out_eT> Q;
+  
+  inline explicit ProxyCube(const mtOpCube<out_eT, T1, op_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows()       const { return Q.n_rows;       }
+  arma_inline uword get_n_cols()       const { return Q.n_cols;       }
+  arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
+  arma_inline uword get_n_slices()     const { return Q.n_slices;     }
+  arma_inline uword get_n_elem()       const { return Q.n_elem;       }
+  
+  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
+  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
+  arma_inline elem_type at_alt     (const uword i)                                       const { return Q.at_alt(i);           }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Cube<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+template<typename out_eT, typename T1, typename T2, typename glue_type>
+class ProxyCube< mtGlueCube<out_eT, T1, T2, glue_type > >
+  {
+  public:
+  
+  typedef          out_eT                       elem_type;
+  typedef typename get_pod_type<out_eT>::result pod_type;
+  typedef          Cube<out_eT>                 stored_type;
+  typedef          const elem_type*             ea_type;
+  typedef          const Cube<out_eT>&          aligned_ea_type;
+  
+  static const bool prefer_at_accessor = false;
+  static const bool has_subview        = false;
+  
+  arma_aligned const Cube<out_eT> Q;
+  
+  inline explicit ProxyCube(const mtGlueCube<out_eT, T1, T2, glue_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows()       const { return Q.n_rows;       }
+  arma_inline uword get_n_cols()       const { return Q.n_cols;       }
+  arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
+  arma_inline uword get_n_slices()     const { return Q.n_slices;     }
+  arma_inline uword get_n_elem()       const { return Q.n_elem;       }
+  
+  arma_inline elem_type operator[] (const uword i)                                       const { return Q[i];                  }
+  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const { return Q.at(row, col, slice); }
+  arma_inline elem_type at_alt     (const uword i)                                       const { return Q.at_alt(i);           }
+  
+  arma_inline         ea_type         get_ea() const { return Q.memptr(); }
+  arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Cube<eT2>&) const { return false; }
+  
+  arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Row_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,207 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Row
+//! @{
+
+//! Class for row vectors (matrices with only one row)
+
+template<typename eT>
+class Row : public Mat<eT>
+  {
+  public:
+  
+  typedef eT                                elem_type;
+  typedef typename get_pod_type<eT>::result pod_type;
+  
+  static const bool is_col = false;
+  static const bool is_row = true;
+  
+  inline          Row();
+  inline          Row(const Row<eT>& X);
+  inline explicit Row(const uword N);
+  inline          Row(const uword in_rows, const uword in_cols);
+  
+  inline                  Row(const char*        text);
+  inline const Row& operator=(const char*        text);
+  
+  inline                  Row(const std::string& text);
+  inline const Row& operator=(const std::string& text);
+  
+  inline                  Row(const std::vector<eT>& x);
+  inline const Row& operator=(const std::vector<eT>& x);
+  
+  #if defined(ARMA_USE_CXX11)
+  inline                  Row(const std::initializer_list<eT>& list);
+  inline const Row& operator=(const std::initializer_list<eT>& list);
+  #endif
+  
+  inline explicit Row(const SpRow<eT>& X);
+  
+  inline const Row& operator=(const eT val);
+  
+  template<typename T1> inline                   Row(const Base<eT,T1>& X);
+  template<typename T1> inline const Row&  operator=(const Base<eT,T1>& X);
+  
+  inline Row(      eT* aux_mem, const uword aux_length, const bool copy_aux_mem = true, const bool strict = true);
+  inline Row(const eT* aux_mem, const uword aux_length);
+  
+  template<typename T1, typename T2>
+  inline explicit Row(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
+  
+  template<typename T1> inline                  Row(const BaseCube<eT,T1>& X);
+  template<typename T1> inline const Row& operator=(const BaseCube<eT,T1>& X);
+  
+  inline                  Row(const subview_cube<eT>& X);
+  inline const Row& operator=(const subview_cube<eT>& X);
+  
+  inline mat_injector<Row> operator<<(const eT val);
+  
+  arma_inline const Op<Row<eT>,op_htrans>  t() const;
+  arma_inline const Op<Row<eT>,op_htrans> ht() const;
+  arma_inline const Op<Row<eT>,op_strans> st() const;
+  
+  arma_inline eT& col(const uword col_num);
+  arma_inline eT  col(const uword col_num) const;
+  
+  arma_inline       subview_row<eT> cols(const uword in_col1, const uword in_col2);
+  arma_inline const subview_row<eT> cols(const uword in_col1, const uword in_col2) const;
+  
+  arma_inline       subview_row<eT> subvec(const uword in_col1, const uword in_col2);
+  arma_inline const subview_row<eT> subvec(const uword in_col1, const uword in_col2) const;
+  
+  arma_inline       subview_row<eT> subvec(const span& col_span);
+  arma_inline const subview_row<eT> subvec(const span& col_span) const;
+  
+  using Mat<eT>::operator();
+  
+  arma_inline       subview_row<eT> operator()(const span& col_span);
+  arma_inline const subview_row<eT> operator()(const span& col_span) const;
+  
+  
+  inline void shed_col (const uword col_num);
+  inline void shed_cols(const uword in_col1, const uword in_col2);
+  
+                        inline void insert_cols(const uword col_num, const uword N, const bool set_to_zero = true);
+  template<typename T1> inline void insert_cols(const uword col_num, const Base<eT,T1>& X);
+  
+  
+  arma_inline arma_warn_unused       eT& at(const uword i);
+  arma_inline arma_warn_unused const eT& at(const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& at(const uword in_row, const uword in_col);
+  arma_inline arma_warn_unused const eT& at(const uword in_row, const uword in_col) const;
+  
+  
+  typedef       eT*       row_iterator;
+  typedef const eT* const_row_iterator;
+  
+  inline       row_iterator begin_row(const uword row_num);
+  inline const_row_iterator begin_row(const uword row_num) const;
+  
+  inline       row_iterator end_row  (const uword row_num);
+  inline const_row_iterator end_row  (const uword row_num) const;
+  
+  
+  template<uword fixed_n_elem> class fixed;
+  
+  
+  protected:
+  
+  inline Row(const arma_fixed_indicator&, const uword in_n_elem, const eT* in_mem);
+  
+  
+  public:
+  
+  #ifdef ARMA_EXTRA_ROW_PROTO
+    #include ARMA_INCFILE_WRAP(ARMA_EXTRA_ROW_PROTO)
+  #endif
+  };
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+class Row<eT>::fixed : public Row<eT>
+  {
+  private:
+  
+  static const bool use_extra = (fixed_n_elem > arma_config::mat_prealloc);
+  
+  arma_align_mem eT mem_local_extra[ (use_extra) ? fixed_n_elem : 1 ];
+  
+  
+  public:
+  
+  typedef fixed<fixed_n_elem>               Row_fixed_type;
+  
+  typedef eT                                elem_type;
+  typedef typename get_pod_type<eT>::result pod_type;
+  
+  static const bool is_col = false;
+  static const bool is_row = true;
+  
+  static const uword n_rows = 1;
+  static const uword n_cols = fixed_n_elem;
+  static const uword n_elem = fixed_n_elem;
+  
+  arma_inline fixed();
+  arma_inline fixed(const fixed<fixed_n_elem>& X);
+       inline fixed(const subview_cube<eT>& X);
+  
+  template<typename T1>              inline fixed(const Base<eT,T1>& A);
+  template<typename T1, typename T2> inline fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B);
+  
+  inline fixed(const eT* aux_mem);
+  
+  inline fixed(const char*        text);
+  inline fixed(const std::string& text);
+  
+  template<typename T1> inline const Row& operator=(const Base<eT,T1>& A);
+  
+  inline const Row& operator=(const eT val);
+  inline const Row& operator=(const char*        text);
+  inline const Row& operator=(const std::string& text);
+  inline const Row& operator=(const subview_cube<eT>& X);
+  
+  using Row<eT>::operator();
+  
+  #if defined(ARMA_USE_CXX11)
+    inline                fixed(const std::initializer_list<eT>& list);
+    inline const Row& operator=(const std::initializer_list<eT>& list);
+  #endif
+  
+  arma_inline const Op< Row_fixed_type, op_htrans >  t() const;
+  arma_inline const Op< Row_fixed_type, op_htrans > ht() const;
+  arma_inline const Op< Row_fixed_type, op_strans > st() const;
+  
+  arma_inline arma_warn_unused const eT& at_alt     (const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& operator[] (const uword i);
+  arma_inline arma_warn_unused const eT& operator[] (const uword i) const;
+  arma_inline arma_warn_unused       eT& at         (const uword i);
+  arma_inline arma_warn_unused const eT& at         (const uword i) const;
+  arma_inline arma_warn_unused       eT& operator() (const uword i);
+  arma_inline arma_warn_unused const eT& operator() (const uword i) const;
+  
+  arma_inline arma_warn_unused       eT& at         (const uword in_row, const uword in_col);
+  arma_inline arma_warn_unused const eT& at         (const uword in_row, const uword in_col) const;
+  arma_inline arma_warn_unused       eT& operator() (const uword in_row, const uword in_col);
+  arma_inline arma_warn_unused const eT& operator() (const uword in_row, const uword in_col) const;
+  
+  arma_inline arma_warn_unused       eT* memptr();
+  arma_inline arma_warn_unused const eT* memptr() const;
+  
+  arma_hot inline const Row<eT>& fill(const eT val);
+  arma_hot inline const Row<eT>& zeros();
+  arma_hot inline const Row<eT>& ones();
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/Row_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,1241 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup Row
+//! @{
+
+
+//! construct an empty row vector
+template<typename eT>
+inline
+Row<eT>::Row()
+  : Mat<eT>(arma_vec_indicator(), 2)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+Row<eT>::Row(const Row<eT>& X)
+  : Mat<eT>(arma_vec_indicator(), 1, X.n_elem, 2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arrayops::copy((*this).memptr(), X.memptr(), X.n_elem);
+  }
+
+
+
+//! construct a row vector with the specified number of n_elem
+template<typename eT>
+inline
+Row<eT>::Row(const uword in_n_elem)
+  : Mat<eT>(arma_vec_indicator(), 1, in_n_elem, 2)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+Row<eT>::Row(const uword in_n_rows, const uword in_n_cols)
+  : Mat<eT>(arma_vec_indicator(), 2)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::init_warm(in_n_rows, in_n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+Row<eT>::Row(const char* text)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 2;
+  
+  Mat<eT>::operator=(text);
+  }
+  
+
+
+template<typename eT>
+inline
+const Row<eT>&
+Row<eT>::operator=(const char* text)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::operator=(text);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+Row<eT>::Row(const std::string& text)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 2;
+  
+  Mat<eT>::operator=(text);
+  }
+
+
+
+template<typename eT>
+inline
+const Row<eT>&
+Row<eT>::operator=(const std::string& text)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::operator=(text);
+  
+  return *this;
+  }
+
+
+
+//! create a row vector from std::vector
+template<typename eT>
+inline
+Row<eT>::Row(const std::vector<eT>& x)
+  : Mat<eT>(arma_vec_indicator(), 1, uword(x.size()), 2)
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  if(x.size() > 0)
+    {
+    arrayops::copy( Mat<eT>::memptr(), &(x[0]), uword(x.size()) );
+    }
+  }
+  
+  
+  
+//! create a row vector from std::vector
+template<typename eT>
+inline
+const Row<eT>&
+Row<eT>::operator=(const std::vector<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::init_warm(1, uword(x.size()));
+  
+  if(x.size() > 0)
+    {
+    arrayops::copy( Mat<eT>::memptr(), &(x[0]), uword(x.size()) );
+    }
+  
+  return *this;
+  }
+
+
+
+#if defined(ARMA_USE_CXX11)
+  
+  template<typename eT>
+  inline
+  Row<eT>::Row(const std::initializer_list<eT>& list)
+    {
+    arma_extra_debug_sigprint();
+    
+    access::rw(Mat<eT>::vec_state) = 2;
+    
+    Mat<eT>::operator=(list);
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  const Row<eT>&
+  Row<eT>::operator=(const std::initializer_list<eT>& list)
+    {
+    arma_extra_debug_sigprint();
+    
+    Mat<eT>::operator=(list);
+    
+    return *this;
+    }
+  
+#endif
+
+
+
+template<typename eT>
+inline
+Row<eT>::Row(const SpRow<eT>& X)
+  : Mat<eT>(arma_vec_indicator(), 1, X.n_elem, 1)
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  arrayops::inplace_set(Mat<eT>::memptr(), eT(0), X.n_elem);
+
+  for(typename SpRow<eT>::const_iterator it = X.begin(); it != X.end(); ++it)
+    at(it.col()) = (*it);
+  }
+
+
+
+template<typename eT>
+inline
+const Row<eT>&
+Row<eT>::operator=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::operator=(val);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+Row<eT>::Row(const Base<eT,T1>& X)
+  : Mat<eT>(arma_vec_indicator(), 2)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::operator=(X.get_ref());
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Row<eT>&
+Row<eT>::operator=(const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::operator=(X.get_ref());
+  
+  return *this;
+  }
+
+
+
+//! construct a row vector from a given auxiliary array
+template<typename eT>
+inline
+Row<eT>::Row(eT* aux_mem, const uword aux_length, const bool copy_aux_mem, const bool strict)
+  : Mat<eT>(aux_mem, 1, aux_length, copy_aux_mem, strict)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 2;
+  }
+
+
+
+//! construct a row vector from a given auxiliary array
+template<typename eT>
+inline
+Row<eT>::Row(const eT* aux_mem, const uword aux_length)
+  : Mat<eT>(aux_mem, 1, aux_length)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 2;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+inline
+Row<eT>::Row
+  (
+  const Base<typename Row<eT>::pod_type, T1>& A,
+  const Base<typename Row<eT>::pod_type, T2>& B
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 2;
+  
+  Mat<eT>::init(A,B);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+Row<eT>::Row(const BaseCube<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 2;
+  
+  Mat<eT>::operator=(X);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const Row<eT>&
+Row<eT>::operator=(const BaseCube<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::operator=(X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+Row<eT>::Row(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(Mat<eT>::vec_state) = 2;
+  
+  Mat<eT>::operator=(X);
+  }
+
+
+
+template<typename eT>
+inline
+const Row<eT>&
+Row<eT>::operator=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::operator=(X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+mat_injector< Row<eT> >
+Row<eT>::operator<<(const eT val)
+  {
+  return mat_injector< Row<eT> >(*this, val);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<Row<eT>,op_htrans>
+Row<eT>::t() const
+  {
+  return Op<Row<eT>,op_htrans>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<Row<eT>,op_htrans>
+Row<eT>::ht() const
+  {
+  return Op<Row<eT>,op_htrans>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<Row<eT>,op_strans>
+Row<eT>::st() const
+  {
+  return Op<Row<eT>,op_strans>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT&
+Row<eT>::col(const uword col_num)
+  {
+  arma_debug_check( (col_num >= Mat<eT>::n_cols), "Row::col(): index out of bounds" );
+  
+  return access::rw(Mat<eT>::mem[col_num]);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+Row<eT>::col(const uword col_num) const
+  {
+  arma_debug_check( (col_num >= Mat<eT>::n_cols), "Row::col(): index out of bounds" );
+  
+  return Mat<eT>::mem[col_num];
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_row<eT>
+Row<eT>::cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols) ), "Row::cols(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview_row<eT>(*this, 0, in_col1, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_row<eT>
+Row<eT>::cols(const uword in_col1, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols) ), "Row::cols(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview_row<eT>(*this, 0, in_col1, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_row<eT>
+Row<eT>::subvec(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols) ), "Row::subvec(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview_row<eT>(*this, 0, in_col1, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_row<eT>
+Row<eT>::subvec(const uword in_col1, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols) ), "Row::subvec(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview_row<eT>(*this, 0, in_col1, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_row<eT>
+Row<eT>::subvec(const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool col_all = col_span.whole;
+
+  const uword local_n_cols = Mat<eT>::n_cols;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword subvec_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+
+  arma_debug_check( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ), "Row::subvec(): indices out of bounds or incorrectly used");
+  
+  return subview_row<eT>(*this, 0, in_col1, subvec_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_row<eT>
+Row<eT>::subvec(const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool col_all = col_span.whole;
+
+  const uword local_n_cols = Mat<eT>::n_cols;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword subvec_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+
+  arma_debug_check( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ), "Row::subvec(): indices out of bounds or incorrectly used");
+  
+  return subview_row<eT>(*this, 0, in_col1, subvec_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_row<eT>
+Row<eT>::operator()(const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  return subvec(col_span);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_row<eT>
+Row<eT>::operator()(const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return subvec(col_span);
+  }
+
+
+
+//! remove specified columns
+template<typename eT>
+inline
+void
+Row<eT>::shed_col(const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( col_num >= Mat<eT>::n_cols, "Row::shed_col(): index out of bounds");
+  
+  shed_cols(col_num, col_num);
+  }
+
+
+
+//! remove specified columns
+template<typename eT>
+inline
+void
+Row<eT>::shed_cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols),
+    "Row::shed_cols(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword n_keep_front = in_col1;
+  const uword n_keep_back  = Mat<eT>::n_cols - (in_col2 + 1);
+  
+  Row<eT> X(n_keep_front + n_keep_back);
+  
+        eT* X_mem = X.memptr();
+  const eT* t_mem = (*this).memptr();
+  
+  if(n_keep_front > 0)
+    {
+    arrayops::copy( X_mem, t_mem, n_keep_front );
+    }
+  
+  if(n_keep_back > 0)
+    {
+    arrayops::copy( &(X_mem[n_keep_front]), &(t_mem[in_col2+1]), n_keep_back);
+    }
+  
+  Mat<eT>::steal_mem(X);
+  }
+
+
+
+//! insert N cols at the specified col position,
+//! optionally setting the elements of the inserted cols to zero
+template<typename eT>
+inline
+void
+Row<eT>::insert_cols(const uword col_num, const uword N, const bool set_to_zero)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword t_n_cols = Mat<eT>::n_cols;
+  
+  const uword A_n_cols = col_num;
+  const uword B_n_cols = t_n_cols - col_num;
+  
+  // insertion at col_num == n_cols is in effect an append operation
+  arma_debug_check( (col_num > t_n_cols), "Row::insert_cols(): index out of bounds");
+  
+  if(N > 0)
+    {
+    Row<eT> out(t_n_cols + N);
+    
+          eT* out_mem = out.memptr();
+    const eT*   t_mem = (*this).memptr();
+    
+    if(A_n_cols > 0)
+      {
+      arrayops::copy( out_mem, t_mem, A_n_cols );
+      }
+    
+    if(B_n_cols > 0)
+      {
+      arrayops::copy( &(out_mem[col_num + N]), &(t_mem[col_num]), B_n_cols );
+      }
+    
+    if(set_to_zero == true)
+      {
+      arrayops::inplace_set( &(out_mem[col_num]), eT(0), N );
+      }
+    
+    Mat<eT>::steal_mem(out);
+    }
+  }
+
+
+
+//! insert the given object at the specified col position; 
+//! the given object must have one row
+template<typename eT>
+template<typename T1>
+inline
+void
+Row<eT>::insert_cols(const uword col_num, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>::insert_cols(col_num, X);
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Row<eT>::at(const uword i)
+  {
+  return access::rw(Mat<eT>::mem[i]);
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Row<eT>::at(const uword i) const
+  {
+  return Mat<eT>::mem[i];
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT&
+Row<eT>::at(const uword, const uword in_col)
+  {
+  return access::rw( Mat<eT>::mem[in_col] );
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+const eT&
+Row<eT>::at(const uword, const uword in_col) const
+  {
+  return Mat<eT>::mem[in_col];
+  }
+
+
+
+template<typename eT>
+inline
+typename Row<eT>::row_iterator
+Row<eT>::begin_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= Mat<eT>::n_rows), "begin_row(): index out of bounds");
+  
+  return Mat<eT>::memptr();
+  }
+
+
+
+template<typename eT>
+inline
+typename Row<eT>::const_row_iterator
+Row<eT>::begin_row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= Mat<eT>::n_rows), "begin_row(): index out of bounds");
+  
+  return Mat<eT>::memptr();
+  }
+
+
+
+template<typename eT>
+inline
+typename Row<eT>::row_iterator
+Row<eT>::end_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= Mat<eT>::n_rows), "end_row(): index out of bounds");
+  
+  return Mat<eT>::memptr() + Mat<eT>::n_cols;
+  }
+
+
+
+template<typename eT>
+inline
+typename Row<eT>::const_row_iterator
+Row<eT>::end_row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= Mat<eT>::n_rows), "end_row(): index out of bounds");
+  
+  return Mat<eT>::memptr() + Mat<eT>::n_cols;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+inline
+Row<eT>::fixed<fixed_n_elem>::fixed()
+  : Row<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+Row<eT>::fixed<fixed_n_elem>::fixed(const fixed<fixed_n_elem>& X)
+  : Row<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  eT* dest = (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
+  
+  arrayops::copy( dest, X.mem, fixed_n_elem );
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+Row<eT>::fixed<fixed_n_elem>::fixed(const subview_cube<eT>& X)
+  : Row<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  Row<eT>::operator=(X);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+template<typename T1>
+arma_inline
+Row<eT>::fixed<fixed_n_elem>::fixed(const Base<eT,T1>& A)
+  : Row<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  Row<eT>::operator=(A.get_ref());
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+template<typename T1, typename T2>
+arma_inline
+Row<eT>::fixed<fixed_n_elem>::fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B)
+  : Row<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  Row<eT>::init(A,B);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+inline
+Row<eT>::fixed<fixed_n_elem>::fixed(const eT* aux_mem)
+  : Row<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  eT* dest = (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
+  
+  arrayops::copy( dest, aux_mem, fixed_n_elem );
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+inline
+Row<eT>::fixed<fixed_n_elem>::fixed(const char* text)
+  : Row<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  Row<eT>::operator=(text);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+inline
+Row<eT>::fixed<fixed_n_elem>::fixed(const std::string& text)
+  : Row<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  Row<eT>::operator=(text);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+template<typename T1>
+const Row<eT>&
+Row<eT>::fixed<fixed_n_elem>::operator=(const Base<eT,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  Row<eT>::operator=(A.get_ref());
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+const Row<eT>&
+Row<eT>::fixed<fixed_n_elem>::operator=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  Row<eT>::operator=(val);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+const Row<eT>&
+Row<eT>::fixed<fixed_n_elem>::operator=(const char* text)
+  {
+  arma_extra_debug_sigprint();
+  
+  Row<eT>::operator=(text);
+  
+  return *this; 
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+const Row<eT>&
+Row<eT>::fixed<fixed_n_elem>::operator=(const std::string& text)
+  {
+  arma_extra_debug_sigprint();
+  
+  Row<eT>::operator=(text);
+  
+  return *this; 
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+const Row<eT>&
+Row<eT>::fixed<fixed_n_elem>::operator=(const subview_cube<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  Row<eT>::operator=(X);
+  
+  return *this; 
+  }
+
+
+
+#if defined(ARMA_USE_CXX11)
+  
+  template<typename eT>
+  template<uword fixed_n_elem>
+  inline
+  Row<eT>::fixed<fixed_n_elem>::fixed(const std::initializer_list<eT>& list)
+    : Row<eT>( arma_fixed_indicator(), fixed_n_elem, ((use_extra) ? mem_local_extra : Mat<eT>::mem_local) )
+    {
+    arma_extra_debug_sigprint_this(this);
+    
+    (*this).operator=(list);
+    }
+  
+  
+  
+  template<typename eT>
+  template<uword fixed_n_elem>
+  inline
+  const Row<eT>&
+  Row<eT>::fixed<fixed_n_elem>::operator=(const std::initializer_list<eT>& list)
+    {
+    arma_extra_debug_sigprint();
+    
+    const uword N = list.size();
+    
+    arma_debug_check( (N > fixed_n_elem), "Row::fixed: initialiser list is too long" );
+    
+    eT* this_mem = (*this).memptr();
+    
+    arrayops::copy( this_mem, list.begin(), N );
+    
+    for(uword iq=N; iq < fixed_n_elem; ++iq) { this_mem[iq] = eT(0); }
+    
+    return *this;
+    }
+  
+#endif
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+const Op< typename Row<eT>::template fixed<fixed_n_elem>::Row_fixed_type, op_htrans >
+Row<eT>::fixed<fixed_n_elem>::t() const
+  {
+  return Op< typename Row<eT>::template fixed<fixed_n_elem>::Row_fixed_type, op_htrans >(*this);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+const Op< typename Row<eT>::template fixed<fixed_n_elem>::Row_fixed_type, op_htrans >
+Row<eT>::fixed<fixed_n_elem>::ht() const
+  {
+  return Op< typename Row<eT>::template fixed<fixed_n_elem>::Row_fixed_type, op_htrans >(*this);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+const Op< typename Row<eT>::template fixed<fixed_n_elem>::Row_fixed_type, op_strans >
+Row<eT>::fixed<fixed_n_elem>::st() const
+  {
+  return Op< typename Row<eT>::template fixed<fixed_n_elem>::Row_fixed_type, op_strans >(*this);
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT&
+Row<eT>::fixed<fixed_n_elem>::at_alt(const uword ii) const
+  {
+  #if defined(ARMA_HAVE_ALIGNED_ATTRIBUTE)
+  
+    return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+    
+  #else
+    const eT* mem_aligned = (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
+    
+    memory::mark_as_aligned(mem_aligned);
+    
+    return mem_aligned[ii];
+  #endif
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+eT&
+Row<eT>::fixed<fixed_n_elem>::operator[] (const uword ii)
+  {
+  return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT&
+Row<eT>::fixed<fixed_n_elem>::operator[] (const uword ii) const
+  {
+  return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+eT&
+Row<eT>::fixed<fixed_n_elem>::at(const uword ii)
+  {
+  return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT&
+Row<eT>::fixed<fixed_n_elem>::at(const uword ii) const
+  {
+  return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+eT&
+Row<eT>::fixed<fixed_n_elem>::operator() (const uword ii)
+  {
+  arma_debug_check( (ii >= fixed_n_elem), "Row::operator(): index out of bounds");
+  
+  return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT&
+Row<eT>::fixed<fixed_n_elem>::operator() (const uword ii) const
+  {
+  arma_debug_check( (ii >= fixed_n_elem), "Row::operator(): index out of bounds");
+  
+  return (use_extra) ? mem_local_extra[ii] : Mat<eT>::mem_local[ii];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+eT&
+Row<eT>::fixed<fixed_n_elem>::at(const uword, const uword in_col)
+  {
+  return (use_extra) ? mem_local_extra[in_col] : Mat<eT>::mem_local[in_col];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT&
+Row<eT>::fixed<fixed_n_elem>::at(const uword, const uword in_col) const
+  {
+  return (use_extra) ? mem_local_extra[in_col] : Mat<eT>::mem_local[in_col];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+eT&
+Row<eT>::fixed<fixed_n_elem>::operator() (const uword in_row, const uword in_col)
+  {
+  arma_debug_check( ((in_row > 0) || (in_col >= fixed_n_elem)), "Row::operator(): index out of bounds" );
+  
+  return (use_extra) ? mem_local_extra[in_col] : Mat<eT>::mem_local[in_col];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT&
+Row<eT>::fixed<fixed_n_elem>::operator() (const uword in_row, const uword in_col) const
+  {
+  arma_debug_check( ((in_row > 0) || (in_col >= fixed_n_elem)), "Row::operator(): index out of bounds" );
+  
+  return (use_extra) ? mem_local_extra[in_col] : Mat<eT>::mem_local[in_col];
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+eT*
+Row<eT>::fixed<fixed_n_elem>::memptr()
+  {
+  return (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_inline
+arma_warn_unused
+const eT*
+Row<eT>::fixed<fixed_n_elem>::memptr() const
+  {
+  return (use_extra) ? mem_local_extra : Mat<eT>::mem_local;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_hot
+inline
+const Row<eT>&
+Row<eT>::fixed<fixed_n_elem>::fill(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(Mat<eT>::mem_local[0]);
+  
+  arrayops::inplace_set_fixed<eT,fixed_n_elem>( mem_use, val );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_hot
+inline
+const Row<eT>&
+Row<eT>::fixed<fixed_n_elem>::zeros()
+  {
+  arma_extra_debug_sigprint();
+  
+  eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(Mat<eT>::mem_local[0]);
+  
+  arrayops::inplace_set_fixed<eT,fixed_n_elem>( mem_use, eT(0) );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<uword fixed_n_elem>
+arma_hot
+inline
+const Row<eT>&
+Row<eT>::fixed<fixed_n_elem>::ones()
+  {
+  arma_extra_debug_sigprint();
+  
+  eT* mem_use = (use_extra) ? &(mem_local_extra[0]) : &(Mat<eT>::mem_local[0]);
+  
+  arrayops::inplace_set_fixed<eT,fixed_n_elem>( mem_use, eT(1) );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+Row<eT>::Row(const arma_fixed_indicator&, const uword in_n_elem, const eT* in_mem)
+  : Mat<eT>(arma_fixed_indicator(), 1, in_n_elem, 2, in_mem)
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+#ifdef ARMA_EXTRA_ROW_MEAT
+  #include ARMA_INCFILE_WRAP(ARMA_EXTRA_ROW_MEAT)
+#endif
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpBase_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,38 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup SpBase
+//! @{
+
+
+
+template<typename elem_type, typename derived>
+struct SpBase
+  {
+  arma_inline const derived& get_ref() const;
+  
+  inline const SpOp<derived,spop_htrans>  t() const;  //!< Hermitian transpose
+  inline const SpOp<derived,spop_htrans> ht() const;  //!< Hermitian transpose
+  inline const SpOp<derived,spop_strans> st() const;  //!< simple transpose
+  
+  inline void print(const std::string extra_text = "") const;
+  inline void print(std::ostream& user_stream, const std::string extra_text = "") const;
+  
+  inline void raw_print(const std::string extra_text = "") const;
+  inline void raw_print(std::ostream& user_stream, const std::string extra_text = "") const;
+
+  inline void print_dense(const std::string extra_text = "") const;
+  inline void print_dense(std::ostream& user_stream, const std::string extra_text = "") const;
+
+  inline void raw_print_dense(const std::string extra_text = "") const;
+  inline void raw_print_dense(std::ostream& user_stream, const std::string extra_text = "") const;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpBase_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,149 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup SpBase
+//! @{
+
+
+
+template<typename elem_type, typename derived>
+arma_inline
+const derived&
+SpBase<elem_type,derived>::get_ref() const
+  {
+  return static_cast<const derived&>(*this);
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+const SpOp<derived, spop_htrans>
+SpBase<elem_type,derived>::t() const
+  {
+  return SpOp<derived,spop_htrans>( (*this).get_ref() );
+  }
+
+
+template<typename elem_type, typename derived>
+inline
+const SpOp<derived, spop_htrans>
+SpBase<elem_type,derived>::ht() const
+  {
+  return SpOp<derived, spop_htrans>( (*this).get_ref() );
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+const SpOp<derived, spop_strans>
+SpBase<elem_type,derived>::st() const
+  {
+  return SpOp<derived, spop_strans>( (*this).get_ref() );
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+void
+SpBase<elem_type,derived>::print(const std::string extra_text) const
+  {
+  const unwrap_spmat<derived> tmp( (*this).get_ref() );
+  
+  tmp.M.impl_print(extra_text);
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+void
+SpBase<elem_type,derived>::print(std::ostream& user_stream, const std::string extra_text) const
+  {
+  const unwrap_spmat<derived> tmp( (*this).get_ref() );
+  
+  tmp.M.impl_print(user_stream, extra_text);
+  }
+  
+
+
+template<typename elem_type, typename derived>
+inline
+void
+SpBase<elem_type,derived>::raw_print(const std::string extra_text) const
+  {
+  const unwrap_spmat<derived> tmp( (*this).get_ref() );
+  
+  tmp.M.impl_raw_print(extra_text);
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+void
+SpBase<elem_type,derived>::raw_print(std::ostream& user_stream, const std::string extra_text) const
+  {
+  const unwrap_spmat<derived> tmp( (*this).get_ref() );
+  
+  tmp.M.impl_raw_print(user_stream, extra_text);
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+void
+SpBase<elem_type, derived>::print_dense(const std::string extra_text) const
+  {
+  const unwrap_spmat<derived> tmp( (*this).get_ref() );
+
+  tmp.M.impl_print_dense(extra_text);
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+void
+SpBase<elem_type, derived>::print_dense(std::ostream& user_stream, const std::string extra_text) const
+  {
+  const unwrap_spmat<derived> tmp( (*this).get_ref() );
+
+  tmp.M.impl_print_dense(user_stream, extra_text);
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+void
+SpBase<elem_type, derived>::raw_print_dense(const std::string extra_text) const
+  {
+  const unwrap_spmat<derived> tmp( (*this).get_ref() );
+
+  tmp.M.impl_raw_print_dense(extra_text);
+  }
+
+
+
+template<typename elem_type, typename derived>
+inline
+void
+SpBase<elem_type, derived>::raw_print_dense(std::ostream& user_stream, const std::string extra_text) const
+  {
+  const unwrap_spmat<derived> tmp( (*this).get_ref() );
+
+  tmp.M.impl_raw_print_dense(user_stream, extra_text);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpCol_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,79 @@
+// Copyright (C) 2011-2012 Ryan Curtin
+// Copyright (C) 2011 Matthew Amidon
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup SpCol
+//! @{
+
+//! Class for sparse column vectors (matrices with only one column)
+
+template<typename eT>
+class SpCol : public SpMat<eT>
+  {
+  public:
+
+  typedef eT                                elem_type;
+  typedef typename get_pod_type<eT>::result pod_type;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  
+  inline          SpCol();
+  inline explicit SpCol(const uword n_elem);
+  inline          SpCol(const uword in_rows, const uword in_cols);
+
+  inline                  SpCol(const char*        text);
+  inline const SpCol& operator=(const char*        text);
+
+  inline                  SpCol(const std::string& text);
+  inline const SpCol& operator=(const std::string& text);
+
+  inline const SpCol& operator=(const eT val);
+
+  template<typename T1> inline                  SpCol(const Base<eT,T1>& X);
+  template<typename T1> inline const SpCol& operator=(const Base<eT,T1>& X);
+
+  template<typename T1> inline                  SpCol(const SpBase<eT,T1>& X);
+  template<typename T1> inline const SpCol& operator=(const SpBase<eT,T1>& X);
+
+  template<typename T1, typename T2>
+  inline explicit SpCol(const SpBase<pod_type,T1>& A, const SpBase<pod_type,T2>& B);
+
+  inline SpValProxy<SpMat<eT> > row(const uword row_num);
+  inline eT                     row(const uword row_num) const;
+
+//  arma_inline       subview_col<eT> rows(const uword in_row1, const uword in_row2);
+//  arma_inline const subview_col<eT> rows(const uword in_row1, const uword in_row2) const;
+
+//  arma_inline       subview_col<eT> subvec(const uword in_row1, const uword in_row2);
+//  arma_inline const subview_col<eT> subvec(const uword in_row1, const uword in_row2) const;
+
+//  arma_inline       subview_col<eT> subvec(const span& row_span);
+//  arma_inline const subview_col<eT> subvec(const span& row_span) const;
+
+  inline void shed_row (const uword row_num);
+  inline void shed_rows(const uword in_row1, const uword in_row2);
+
+//                         inline void insert_rows(const uword row_num, const uword N, const bool set_to_zero = true);
+//   template<typename T1> inline void insert_rows(const uword row_num, const Base<eT,T1>& X);
+
+
+  typedef typename SpMat<eT>::iterator       row_iterator;
+  typedef typename SpMat<eT>::const_iterator const_row_iterator;
+
+  inline       row_iterator begin_row(const uword row_num = 0);
+  inline const_row_iterator begin_row(const uword row_num = 0) const;
+
+  inline       row_iterator end_row  (const uword row_num = 0);
+  inline const_row_iterator end_row  (const uword row_num = 0) const;
+  
+  
+  #ifdef ARMA_EXTRA_SPCOL_PROTO
+    #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPCOL_PROTO)
+  #endif
+  };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpCol_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,542 @@
+// Copyright (C) 2011-2012 Ryan Curtin
+// Copyright (C) 2011 Matthew Amidon
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup SpCol
+//! @{
+
+
+//! construct an empty column vector
+template<typename eT>
+inline
+SpCol<eT>::SpCol()
+  : SpMat<eT>(0, 1)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 1;
+  }
+
+
+
+//! construct a column vector with the specified number of elements
+template<typename eT>
+inline
+SpCol<eT>::SpCol(const uword in_n_elem)
+  : SpMat<eT>(in_n_elem, 1)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 1;
+  }
+
+
+
+template<typename eT>
+inline
+SpCol<eT>::SpCol(const uword in_n_rows, const uword in_n_cols)
+  : SpMat<eT>(in_n_rows, in_n_cols)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check((in_n_cols != 1), "SpCol::SpCol(): must have only one column");
+
+  access::rw(SpMat<eT>::vec_state) = 1;
+  }
+
+
+
+//! construct a column vector from specified text
+template<typename eT>
+inline
+SpCol<eT>::SpCol(const char* text)
+  : SpMat<eT>(text)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 1;
+
+  arma_debug_check((SpMat<eT>::n_cols != 1), "SpCol::SpCol(): must have only one column");
+  }
+
+
+
+//! construct a column vector from specified text
+template<typename eT>
+inline
+const SpCol<eT>&
+SpCol<eT>::operator=(const char* text)
+  {
+  arma_extra_debug_sigprint();
+
+  SpMat<eT>::init(std::string(text));
+
+  access::rw(SpMat<eT>::vec_state) = 1;
+
+  return *this;
+  }
+
+
+
+//! construct a column vector from specified text
+template<typename eT>
+inline
+SpCol<eT>::SpCol(const std::string& text)
+  : SpMat<eT>(text)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 1;
+
+  arma_debug_check((SpMat<eT>::n_cols != 1), "SpCol::SpCol(): must have only one column");
+  }
+
+
+
+//! construct a column vector from specified text
+template<typename eT>
+inline
+const SpCol<eT>&
+SpCol<eT>::operator=(const std::string& text)
+  {
+  arma_extra_debug_sigprint();
+
+  SpMat<eT>::init(std::string(text));
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpCol<eT>&
+SpCol<eT>::operator=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+
+  SpMat<eT>::operator=(val);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+SpCol<eT>::SpCol(const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 1;
+
+  SpMat<eT>::operator=(X.get_ref());
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpCol<eT>&
+SpCol<eT>::operator=(const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 1;
+
+  SpMat<eT>::operator=(X.get_ref());
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+SpCol<eT>::SpCol(const SpBase<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 1;
+
+  SpMat<eT>::operator=(X.get_ref());
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpCol<eT>&
+SpCol<eT>::operator=(const SpBase<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 1;
+
+  SpMat<eT>::operator=(X.get_ref());
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+inline
+SpCol<eT>::SpCol
+  (
+  const SpBase<typename SpCol<eT>::pod_type, T1>& A,
+  const SpBase<typename SpCol<eT>::pod_type, T2>& B
+  )
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 1;
+
+  SpMat<eT>::init(A,B);
+  }
+
+
+
+template<typename eT>
+inline
+SpValProxy< SpMat<eT> >
+SpCol<eT>::row(const uword row_num)
+  {
+  arma_debug_check( (row_num >= SpMat<eT>::n_rows), "SpCol::row(): out of bounds" );
+
+  return SpMat<eT>::at(row_num, 0);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+SpCol<eT>::row(const uword row_num) const
+  {
+  arma_debug_check( (row_num >= SpMat<eT>::n_rows), "SpCol::row(): out of bounds" );
+  
+  return SpMat<eT>::at(row_num, 0);
+  }
+
+
+/*
+template<typename eT>
+arma_inline
+subview_col<eT>
+SpCol<eT>::rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= SpMat<eT>::n_rows) ), "Col::rows(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  return subview_col<eT>(*this, 0, in_row1, subview_n_rows);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_col<eT>
+SpCol<eT>::rows(const uword in_row1, const uword in_row2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= SpMat<eT>::n_rows) ), "Col::rows(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  return subview_col<eT>(*this, 0, in_row1, subview_n_rows);
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_col<eT>
+SpCol<eT>::subvec(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= SpMat<eT>::n_rows) ), "Col::subvec(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  return subview_col<eT>(*this, 0, in_row1, subview_n_rows);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_col<eT>
+SpCol<eT>::subvec(const uword in_row1, const uword in_row2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= SpMat<eT>::n_rows) ), "Col::subvec(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  return subview_col<eT>(*this, 0, in_row1, subview_n_rows);
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_col<eT>
+SpCol<eT>::subvec(const span& row_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+
+  const uword local_n_rows = SpMat<eT>::n_rows;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword subvec_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+
+  arma_debug_check( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ), "Col::subvec(): indices out of bounds or incorrectly used");
+  
+  return subview_col<eT>(*this, 0, in_row1, subvec_n_rows);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_col<eT>
+SpCol<eT>::subvec(const span& row_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+
+  const uword local_n_rows = SpMat<eT>::n_rows;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword subvec_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+
+  arma_debug_check( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ), "Col::subvec(): indices out of bounds or incorrectly used");
+  
+  return subview_col<eT>(*this, 0, in_row1, subvec_n_rows);
+  }
+*/
+
+
+//! remove specified row
+template<typename eT>
+inline
+void
+SpCol<eT>::shed_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check( row_num >= SpMat<eT>::n_rows, "SpCol::shed_row(): out of bounds");
+  
+  shed_rows(row_num, row_num);
+  }
+
+
+
+//! remove specified rows
+template<typename eT>
+inline
+void
+SpCol<eT>::shed_rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_row2 >= SpMat<eT>::n_rows),
+    "SpCol::shed_rows(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword diff = (in_row2 - in_row1 + 1);
+
+  // This is easy because everything is in one column.
+  uword start = 0, end = 0;
+  bool start_found = false, end_found = false;
+  for(uword i = 0; i < SpMat<eT>::n_nonzero; ++i)
+    {
+    // Start position found?
+    if (SpMat<eT>::row_indices[i] >= in_row1 && !start_found)
+      {
+      start = i;
+      start_found = true;
+      }
+
+    // End position found?
+    if (SpMat<eT>::row_indices[i] > in_row2)
+      {
+      end = i;
+      end_found = true;
+      break;
+      }
+    }
+
+  if (!end_found)
+    {
+    end = SpMat<eT>::n_nonzero;
+    }
+
+  // Now we can make the copy.
+  if (start != end)
+    {
+    const uword elem_diff = end - start;
+
+    eT*    new_values      = memory::acquire_chunked<eT>   (SpMat<eT>::n_nonzero - elem_diff);
+    uword* new_row_indices = memory::acquire_chunked<uword>(SpMat<eT>::n_nonzero - elem_diff);
+
+    // Copy before the section we are dropping (if it exists).
+    if (start > 0)
+      {
+      arrayops::copy(new_values, SpMat<eT>::values, start);
+      arrayops::copy(new_row_indices, SpMat<eT>::row_indices, start);
+      }
+
+    // Copy after the section we are dropping (if it exists).
+    if (end != SpMat<eT>::n_nonzero)
+      {
+      arrayops::copy(new_values + start, SpMat<eT>::values + end, (SpMat<eT>::n_nonzero - end));
+      arrayops::copy(new_row_indices + start, SpMat<eT>::row_indices + end, (SpMat<eT>::n_nonzero - end));
+      arrayops::inplace_minus(new_row_indices + start, diff, (SpMat<eT>::n_nonzero - end));
+      }
+
+    memory::release(SpMat<eT>::values);
+    memory::release(SpMat<eT>::row_indices);
+
+    access::rw(SpMat<eT>::values) = new_values;
+    access::rw(SpMat<eT>::row_indices) = new_row_indices;
+
+    access::rw(SpMat<eT>::n_nonzero) -= elem_diff;
+    access::rw(SpMat<eT>::col_ptrs[1]) -= elem_diff;
+    }
+
+  access::rw(SpMat<eT>::n_rows) -= diff;
+  access::rw(SpMat<eT>::n_elem) -= diff;
+
+  }
+
+
+
+// //! insert N rows at the specified row position,
+// //! optionally setting the elements of the inserted rows to zero
+// template<typename eT>
+// inline
+// void
+// SpCol<eT>::insert_rows(const uword row_num, const uword N, const bool set_to_zero)
+//   {
+//   arma_extra_debug_sigprint();
+// 
+//   arma_debug_check(set_to_zero == false, "SpCol::insert_rows(): cannot set nonzero values");
+// 
+//   arma_debug_check((row_num > SpMat<eT>::n_rows), "SpCol::insert_rows(): out of bounds");
+// 
+//   for(uword row = 0; row < SpMat<eT>::n_rows; ++row)
+//     {
+//     if (SpMat<eT>::row_indices[row] >= row_num)
+//       {
+//       access::rw(SpMat<eT>::row_indices[row]) += N;
+//       }
+//     }
+// 
+//   access::rw(SpMat<eT>::n_rows) += N;
+//   access::rw(SpMat<eT>::n_elem) += N;
+//   }
+// 
+// 
+// 
+// //! insert the given object at the specified row position;
+// //! the given object must have one column
+// template<typename eT>
+// template<typename T1>
+// inline
+// void
+// SpCol<eT>::insert_rows(const uword row_num, const Base<eT,T1>& X)
+//   {
+//   arma_extra_debug_sigprint();
+// 
+//   SpMat<eT>::insert_rows(row_num, X);
+//   }
+
+
+
+template<typename eT>
+inline
+typename SpCol<eT>::row_iterator
+SpCol<eT>::begin_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= SpMat<eT>::n_rows), "begin_row(): index out of bounds");
+  
+  return row_iterator(*this, row_num, 0);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpCol<eT>::const_row_iterator
+SpCol<eT>::begin_row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= SpMat<eT>::n_rows), "begin_row(): index out of bounds");
+  
+  return const_row_iterator(*this, row_num, 0);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpCol<eT>::row_iterator
+SpCol<eT>::end_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= SpMat<eT>::n_rows), "end_row(): index out of bounds");
+  
+  return row_iterator(*this, row_num + 1, 0);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpCol<eT>::const_row_iterator
+SpCol<eT>::end_row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= SpMat<eT>::n_rows), "end_row(): index out of bounds");
+  
+  return const_row_iterator(*this, row_num + 1, 0);
+  }
+
+
+
+#ifdef ARMA_EXTRA_SPCOL_MEAT
+  #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPCOL_MEAT)
+#endif
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpGlue_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup SpGlue
+//! @{
+
+
+
+template<typename T1, typename T2, typename spglue_type>
+class SpGlue : public SpBase<typename T1::elem_type, SpGlue<T1, T2, spglue_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool is_row = ( (T1::is_row || T2::is_row) && is_spglue_elem<spglue_type>::value ) || ( (is_spglue_times<spglue_type>::value || is_spglue_times2<spglue_type>::value) ? T1::is_row : false );
+  static const bool is_col = ( (T1::is_col || T2::is_col) && is_spglue_elem<spglue_type>::value ) || ( (is_spglue_times<spglue_type>::value || is_spglue_times2<spglue_type>::value) ? T2::is_col : false );
+  
+  arma_inline  SpGlue(const T1& in_A, const T2& in_B);
+  arma_inline  SpGlue(const T1& in_A, const T2& in_B, const elem_type in_aux);
+  arma_inline ~SpGlue();
+  
+  const T1&       A;    //!< first operand
+  const T2&       B;    //!< second operand
+        elem_type aux;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpGlue_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,45 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup SpGlue
+//! @{
+
+
+
+template<typename T1, typename T2, typename spglue_type>
+inline
+SpGlue<T1,T2,spglue_type>::SpGlue(const T1& in_A, const T2& in_B)
+  : A(in_A)
+  , B(in_B)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename T2, typename spglue_type>
+inline
+SpGlue<T1,T2,spglue_type>::SpGlue(const T1& in_A, const T2& in_B, const typename T1::elem_type in_aux)
+  : A(in_A)
+  , B(in_B)
+  , aux(in_aux)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename T2, typename spglue_type>
+inline
+SpGlue<T1,T2,spglue_type>::~SpGlue()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpMat_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,584 @@
+// Copyright (C) 2011-2013 Ryan Curtin
+// Copyright (C) 2012-2013 Conrad Sanderson
+// Copyright (C) 2011 Matthew Amidon
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+//! \addtogroup SpMat
+//! @{
+
+//! Sparse matrix class, with data stored in compressed sparse column (CSC) format
+
+template<typename eT>
+class SpMat : public SpBase< eT, SpMat<eT> >
+  {
+  public:
+  
+  typedef eT                                elem_type;  //!< the type of elements stored in the matrix
+  typedef typename get_pod_type<eT>::result pod_type;   //!< if eT is non-complex, pod_type is the same as eT; otherwise, pod_type is the underlying type used by std::complex
+  
+  static const bool is_row = false;
+  static const bool is_col = false;
+  
+  const uword n_rows;    //!< number of rows in the matrix (read-only)
+  const uword n_cols;    //!< number of columns in the matrix (read-only)
+  const uword n_elem;    //!< number of elements in the matrix (read-only)
+  const uword n_nonzero; //!< number of nonzero elements in the matrix (read-only)
+  const uword vec_state; //!< 0: matrix; 1: column vector; 2: row vector
+  
+  // So that SpValProxy can call add_element() and delete_element().
+  friend class SpValProxy<SpMat<eT> >;
+  friend class SpSubview<eT>;
+  
+  /**
+   * The memory used to store the values of the matrix.
+   * In accordance with the CSC format, this stores only the actual values.
+   * The correct locations of the values are assembled from the row indices
+   * and the column pointers.
+   */
+  const eT* const values;
+  
+  /**
+   * The row indices of each value.  row_indices[i] is the row of values[i].
+   * The length of this array is n_nonzero + 1; the final value ensures the
+   * integrity of iterators.
+   */
+  const uword* const row_indices;
+  
+  /**
+   * The column pointers.  This stores the index of the first item in column i.
+   * That is, values[col_ptrs[i]] is the first value in column i, and it is in
+   * row row_indices[col_ptrs[i]].
+   */
+  const uword* const col_ptrs;
+  
+  inline  SpMat();  //! Size will be 0x0 (empty).
+  inline ~SpMat();
+  
+  inline SpMat(const uword in_rows, const uword in_cols);
+  
+  inline                  SpMat(const char*        text);
+  inline const SpMat& operator=(const char*        text);
+  inline                  SpMat(const std::string& text);
+  inline const SpMat& operator=(const std::string& text);
+  inline                  SpMat(const SpMat<eT>&   x);
+
+  template<typename T1, typename T2> inline SpMat(const Base<uword,T1>& locations, const Base<eT,T2>& values, const bool sort_locations = true);
+  template<typename T1, typename T2> inline SpMat(const Base<uword,T1>& locations, const Base<eT,T2>& values, const uword n_rows, const uword n_cols, const bool sort_locations = true);
+  
+  inline const SpMat&  operator=(const eT val); //! Sets size to 1x1.
+  inline const SpMat& operator*=(const eT val);
+  inline const SpMat& operator/=(const eT val);
+  // operator+=(val) and operator-=(val) are not defined as they don't make sense for sparse matrices
+  
+  /**
+   * Operators on other sparse matrices.  These work as though you would expect.
+   */
+  inline const SpMat&  operator=(const SpMat& m);
+  inline const SpMat& operator+=(const SpMat& m);
+  inline const SpMat& operator-=(const SpMat& m);
+  inline const SpMat& operator*=(const SpMat& m);
+  inline const SpMat& operator%=(const SpMat& m);
+  inline const SpMat& operator/=(const SpMat& m);
+  
+  /**
+   * Operators on other regular matrices.  These work as though you would expect.
+   */
+  template<typename T1> inline explicit          SpMat(const Base<eT, T1>& m);
+  template<typename T1> inline const SpMat&  operator=(const Base<eT, T1>& m);
+  template<typename T1> inline const SpMat& operator*=(const Base<eT, T1>& m);
+  template<typename T1> inline const SpMat& operator/=(const Base<eT, T1>& m);
+  template<typename T1> inline const SpMat& operator%=(const Base<eT, T1>& m);
+  
+  
+  //! construction of complex matrix out of two non-complex matrices;
+  template<typename T1, typename T2>
+  inline explicit SpMat(const SpBase<pod_type, T1>& A, const SpBase<pod_type, T2>& B);
+  
+  /**
+   * Operations on sparse subviews.
+   */
+  inline                   SpMat(const SpSubview<eT>& X);
+  inline const SpMat&  operator=(const SpSubview<eT>& X);
+  inline const SpMat& operator+=(const SpSubview<eT>& X);
+  inline const SpMat& operator-=(const SpSubview<eT>& X);
+  inline const SpMat& operator*=(const SpSubview<eT>& X);
+  inline const SpMat& operator%=(const SpSubview<eT>& X);
+  inline const SpMat& operator/=(const SpSubview<eT>& X);
+  
+  /**
+   * Operations on regular subviews.
+   */
+  inline                   SpMat(const subview<eT>& x);
+  inline const SpMat&  operator=(const subview<eT>& x);
+  inline const SpMat& operator+=(const subview<eT>& x);
+  inline const SpMat& operator-=(const subview<eT>& x);
+  inline const SpMat& operator*=(const subview<eT>& x);
+  inline const SpMat& operator%=(const subview<eT>& x);
+  inline const SpMat& operator/=(const subview<eT>& x);
+
+
+  // delayed unary ops
+  template<typename T1, typename spop_type> inline                   SpMat(const SpOp<T1, spop_type>& X);
+  template<typename T1, typename spop_type> inline const SpMat&  operator=(const SpOp<T1, spop_type>& X);
+  template<typename T1, typename spop_type> inline const SpMat& operator+=(const SpOp<T1, spop_type>& X);
+  template<typename T1, typename spop_type> inline const SpMat& operator-=(const SpOp<T1, spop_type>& X);
+  template<typename T1, typename spop_type> inline const SpMat& operator*=(const SpOp<T1, spop_type>& X);
+  template<typename T1, typename spop_type> inline const SpMat& operator%=(const SpOp<T1, spop_type>& X);
+  template<typename T1, typename spop_type> inline const SpMat& operator/=(const SpOp<T1, spop_type>& X);
+  
+  // delayed binary ops
+  template<typename T1, typename T2, typename spglue_type> inline                   SpMat(const SpGlue<T1, T2, spglue_type>& X);
+  template<typename T1, typename T2, typename spglue_type> inline const SpMat&  operator=(const SpGlue<T1, T2, spglue_type>& X);
+  template<typename T1, typename T2, typename spglue_type> inline const SpMat& operator+=(const SpGlue<T1, T2, spglue_type>& X);
+  template<typename T1, typename T2, typename spglue_type> inline const SpMat& operator-=(const SpGlue<T1, T2, spglue_type>& X);
+  template<typename T1, typename T2, typename spglue_type> inline const SpMat& operator*=(const SpGlue<T1, T2, spglue_type>& X);
+  template<typename T1, typename T2, typename spglue_type> inline const SpMat& operator%=(const SpGlue<T1, T2, spglue_type>& X);
+  template<typename T1, typename T2, typename spglue_type> inline const SpMat& operator/=(const SpGlue<T1, T2, spglue_type>& X);
+
+  // delayed mixted-type unary ops
+  template<typename T1, typename spop_type> inline                   SpMat(const mtSpOp<eT, T1, spop_type>& X);
+  template<typename T1, typename spop_type> inline const SpMat&  operator=(const mtSpOp<eT, T1, spop_type>& X);
+  template<typename T1, typename spop_type> inline const SpMat& operator+=(const mtSpOp<eT, T1, spop_type>& X);
+  template<typename T1, typename spop_type> inline const SpMat& operator-=(const mtSpOp<eT, T1, spop_type>& X);
+  template<typename T1, typename spop_type> inline const SpMat& operator*=(const mtSpOp<eT, T1, spop_type>& X);
+  template<typename T1, typename spop_type> inline const SpMat& operator%=(const mtSpOp<eT, T1, spop_type>& X);
+  template<typename T1, typename spop_type> inline const SpMat& operator/=(const mtSpOp<eT, T1, spop_type>& X);
+  
+  /**
+   * Submatrix methods.
+   */
+  arma_inline       SpSubview<eT> row(const uword row_num);
+  arma_inline const SpSubview<eT> row(const uword row_num) const;
+  
+  inline            SpSubview<eT> operator()(const uword row_num, const span& col_span);
+  inline      const SpSubview<eT> operator()(const uword row_num, const span& col_span) const;
+  
+  
+  arma_inline       SpSubview<eT> col(const uword col_num);
+  arma_inline const SpSubview<eT> col(const uword col_num) const;
+  
+  inline            SpSubview<eT> operator()(const span& row_span, const uword col_num);
+  inline      const SpSubview<eT> operator()(const span& row_span, const uword col_num) const;
+  
+  /**
+   * Row- and column-related functions.
+   */
+  inline void swap_rows(const uword in_row1, const uword in_row2);
+  inline void swap_cols(const uword in_col1, const uword in_col2);
+  
+  inline void shed_row(const uword row_num);
+  inline void shed_col(const uword col_num);
+  
+  inline void shed_rows(const uword in_row1, const uword in_row2);
+  inline void shed_cols(const uword in_col1, const uword in_col2);
+  
+  arma_inline       SpSubview<eT> rows(const uword in_row1, const uword in_row2);
+  arma_inline const SpSubview<eT> rows(const uword in_row1, const uword in_row2) const;
+  
+  arma_inline       SpSubview<eT> cols(const uword in_col1, const uword in_col2);
+  arma_inline const SpSubview<eT> cols(const uword in_col1, const uword in_col2) const;
+  
+  arma_inline       SpSubview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2);
+  arma_inline const SpSubview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const;
+  
+  
+  inline            SpSubview<eT> submat    (const span& row_span, const span& col_span);
+  inline      const SpSubview<eT> submat    (const span& row_span, const span& col_span) const;
+  
+  inline            SpSubview<eT> operator()(const span& row_span, const span& col_span);
+  inline      const SpSubview<eT> operator()(const span& row_span, const span& col_span) const;
+  
+  /**
+   * Element access; access the i'th element (works identically to the Mat accessors).
+   * If there is nothing at element i, 0 is returned.
+   *
+   * @param i Element to access.
+   */
+  arma_inline arma_warn_unused SpValProxy<SpMat<eT> > operator[] (const uword i);
+  arma_inline arma_warn_unused eT                     operator[] (const uword i) const;
+  arma_inline arma_warn_unused SpValProxy<SpMat<eT> > at         (const uword i);
+  arma_inline arma_warn_unused eT                     at         (const uword i) const;
+  arma_inline arma_warn_unused SpValProxy<SpMat<eT> > operator() (const uword i);
+  arma_inline arma_warn_unused eT                     operator() (const uword i) const;
+  
+  /**
+   * Element access; access the element at row in_row and column in_col.
+   * If there is nothing at that position, 0 is returned.
+   */
+  arma_inline arma_warn_unused SpValProxy<SpMat<eT> > at         (const uword in_row, const uword in_col);
+  arma_inline arma_warn_unused eT                     at         (const uword in_row, const uword in_col) const;
+  arma_inline arma_warn_unused SpValProxy<SpMat<eT> > operator() (const uword in_row, const uword in_col);
+  arma_inline arma_warn_unused eT                     operator() (const uword in_row, const uword in_col) const;
+  
+  
+  /**
+   * Information boolean checks on matrices.
+   */
+  arma_inline arma_warn_unused bool is_empty()  const;
+  arma_inline arma_warn_unused bool is_vec()    const;
+  arma_inline arma_warn_unused bool is_rowvec() const;
+  arma_inline arma_warn_unused bool is_colvec() const;
+  arma_inline arma_warn_unused bool is_square() const;
+       inline arma_warn_unused bool is_finite() const;
+  
+  arma_inline arma_warn_unused bool in_range(const uword i) const;
+  arma_inline arma_warn_unused bool in_range(const span& x) const;
+  
+  arma_inline arma_warn_unused bool in_range(const uword   in_row, const uword   in_col) const;
+  arma_inline arma_warn_unused bool in_range(const span& row_span, const uword   in_col) const;
+  arma_inline arma_warn_unused bool in_range(const uword   in_row, const span& col_span) const;
+  arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span) const;
+  
+  /**
+   * Printing the matrix.
+   *
+   * @param extra_text Text to prepend to output.
+   */
+  inline void impl_print(const std::string& extra_text) const;
+  inline void impl_print(std::ostream& user_stream, const std::string& extra_text) const;
+
+  inline void impl_raw_print(const std::string& extra_text) const;
+  inline void impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const;
+
+  inline void impl_print_dense(const std::string& extra_text) const;
+  inline void impl_print_dense(std::ostream& user_stream, const std::string& extra_text) const;
+  
+  inline void impl_raw_print_dense(const std::string& extra_text) const;
+  inline void impl_raw_print_dense(std::ostream& user_stream, const std::string& extra_text) const;
+  
+  //! Copy the size of another matrix.
+  template<typename eT2> inline void copy_size(const SpMat<eT2>& m);
+  template<typename eT2> inline void copy_size(const Mat<eT2>& m);
+
+  /**
+   * Resize the matrix to a given size.  The matrix will be resized to be a column vector (i.e. in_elem columns, 1 row).
+   *
+   * @param in_elem Number of elements to allow.
+   */
+  inline void set_size(const uword in_elem);
+
+  /**
+   * Resize the matrix to a given size.
+   *
+   * @param in_rows Number of rows to allow.
+   * @param in_cols Number of columns to allow.
+   */
+  inline void set_size(const uword in_rows, const uword in_cols);
+  
+  inline void  reshape(const uword in_rows, const uword in_cols, const uword dim = 0);
+  
+  inline const SpMat& zeros();
+  inline const SpMat& zeros(const uword in_elem);
+  inline const SpMat& zeros(const uword in_rows, const uword in_cols);
+  
+  inline const SpMat& eye();
+  inline const SpMat& eye(const uword in_rows, const uword in_cols);
+  
+  inline const SpMat& speye();
+  inline const SpMat& speye(const uword in_rows, const uword in_cols);
+  
+  inline const SpMat& sprandu(const uword in_rows, const uword in_cols, const double density);
+  inline const SpMat& sprandn(const uword in_rows, const uword in_cols, const double density);
+  
+  inline void reset();
+  
+  /**
+   * Get the minimum or maximum of the matrix.
+   */
+  inline arma_warn_unused eT min() const;
+  inline                  eT min(uword& index_of_min_val) const;
+  inline                  eT min(uword& row_of_min_val, uword& col_of_min_val) const;
+
+  inline arma_warn_unused eT max() const;
+  inline                  eT max(uword& index_of_max_val) const;
+  inline                  eT max(uword& row_of_min_val, uword& col_of_min_val) const;
+  
+  
+  // saving and loading
+  
+  inline bool save(const std::string   name, const file_type type = arma_binary, const bool print_status = true) const;
+  inline bool save(      std::ostream& os,   const file_type type = arma_binary, const bool print_status = true) const;
+  
+  inline bool load(const std::string   name, const file_type type = arma_binary, const bool print_status = true);
+  inline bool load(      std::istream& is,   const file_type type = arma_binary, const bool print_status = true);
+  
+  inline bool quiet_save(const std::string   name, const file_type type = arma_binary) const;
+  inline bool quiet_save(      std::ostream& os,   const file_type type = arma_binary) const;
+  
+  inline bool quiet_load(const std::string   name, const file_type type = arma_binary);
+  inline bool quiet_load(      std::istream& is,   const file_type type = arma_binary);
+  
+  // TODO: speed up loading of sparse matrices stored as text files (ie. raw_ascii and coord_ascii)
+  // TODO: implement auto_detect for sparse matrices
+  // TODO: modify docs to specify which formats are not applicable to sparse matrices
+  
+  
+  // These forward declarations are necessary.
+  class iterator_base;
+  class iterator;
+  class const_iterator;
+  class row_iterator;
+  class const_row_iterator;
+
+  // Iterator base provides basic operators but not how to compare or how to
+  // iterate.
+  class iterator_base
+    {
+    public:
+
+    inline iterator_base(const SpMat& in_M);
+    inline iterator_base(const SpMat& in_M, const uword col, const uword pos);
+
+    inline arma_hot eT operator*() const;
+    
+    // Don't hold location internally; call "dummy" methods to get that information.
+    arma_inline uword row() const { return M.row_indices[internal_pos]; }
+    arma_inline uword col() const { return internal_col;                }
+    arma_inline uword pos() const { return internal_pos;                }
+
+    arma_aligned const SpMat& M;
+    arma_aligned       uword  internal_col;
+    arma_aligned       uword  internal_pos;
+
+    // So that we satisfy the STL iterator types.
+    typedef std::bidirectional_iterator_tag iterator_category;
+    typedef eT                              value_type;
+    typedef uword                           difference_type; // not certain on this one
+    typedef const eT*                       pointer;
+    typedef const eT&                       reference;
+    };
+
+  class const_iterator : public iterator_base
+    {
+    public:
+    
+    inline const_iterator(const SpMat& in_M, uword initial_pos = 0); // Assumes initial_pos is valid.
+    //! Once initialized, will be at the first nonzero value after the given position (using forward columnwise traversal).
+    inline const_iterator(const SpMat& in_M, uword in_row, uword in_col);
+    //! If you know the exact position of the iterator.  in_row is a dummy argument.
+    inline const_iterator(const SpMat& in_M, uword in_row, uword in_col, uword in_pos);
+    inline const_iterator(const const_iterator& other);
+
+    inline arma_hot const_iterator& operator++();
+    inline arma_hot const_iterator  operator++(int);
+    
+    inline arma_hot const_iterator& operator--();
+    inline arma_hot const_iterator  operator--(int);
+
+    inline arma_hot bool operator==(const const_iterator& rhs) const;
+    inline arma_hot bool operator!=(const const_iterator& rhs) const;
+
+    inline arma_hot bool operator==(const typename SpSubview<eT>::const_iterator& rhs) const;
+    inline arma_hot bool operator!=(const typename SpSubview<eT>::const_iterator& rhs) const;
+
+    inline arma_hot bool operator==(const const_row_iterator& rhs) const;
+    inline arma_hot bool operator!=(const const_row_iterator& rhs) const;
+
+    inline arma_hot bool operator==(const typename SpSubview<eT>::const_row_iterator& rhs) const;
+    inline arma_hot bool operator!=(const typename SpSubview<eT>::const_row_iterator& rhs) const;
+    };
+
+  /**
+   * So that we can iterate over nonzero values, we need an iterator
+   * implementation.  This can't be as simple as Mat's, which is just a pointer
+   * to an eT.  If a value is set to 0 using this iterator, the iterator is no
+   * longer valid!
+   */
+  class iterator : public const_iterator
+    {
+    public:
+
+    inline iterator(SpMat& in_M, uword initial_pos = 0) : const_iterator(in_M, initial_pos) { }
+    inline iterator(SpMat& in_M, uword in_row, uword in_col) : const_iterator(in_M, in_row, in_col) { }
+    inline iterator(SpMat& in_M, uword in_row, uword in_col, uword in_pos) : const_iterator(in_M, in_row, in_col, in_pos) { }
+    inline iterator(const const_iterator& other) : const_iterator(other) { }
+
+    inline arma_hot SpValProxy<SpMat<eT> > operator*();
+
+    // overloads needed for return type correctness
+    inline arma_hot iterator& operator++();
+    inline arma_hot iterator  operator++(int);
+
+    inline arma_hot iterator& operator--();
+    inline arma_hot iterator  operator--(int);
+
+    // This has a different value_type than iterator_base.
+    typedef SpValProxy<SpMat<eT> >         value_type;
+    typedef const SpValProxy<SpMat<eT> >*  pointer;
+    typedef const SpValProxy<SpMat<eT> >&  reference;
+    };
+
+  class const_row_iterator : public iterator_base
+    {
+    public:
+    
+    inline const_row_iterator(const SpMat& in_M, uword initial_pos = 0);
+    //! Once initialized, will be at the first nonzero value after the given position (using forward row-wise traversal).
+    inline const_row_iterator(const SpMat& in_M, uword in_row, uword in_col);
+    inline const_row_iterator(const const_row_iterator& other);
+
+    inline arma_hot const_row_iterator& operator++();
+    inline arma_hot const_row_iterator  operator++(int);
+    
+    inline arma_hot const_row_iterator& operator--();
+    inline arma_hot const_row_iterator  operator--(int);
+
+    uword internal_row; // Hold row internally because we use internal_pos differently.
+    uword actual_pos; // Actual position in matrix.
+
+    arma_inline eT operator*() const { return iterator_base::M.values[actual_pos]; }
+
+    arma_inline uword row() const { return internal_row; }
+
+    inline arma_hot bool operator==(const const_iterator& rhs) const;
+    inline arma_hot bool operator!=(const const_iterator& rhs) const;
+
+    inline arma_hot bool operator==(const typename SpSubview<eT>::const_iterator& rhs) const;
+    inline arma_hot bool operator!=(const typename SpSubview<eT>::const_iterator& rhs) const;
+
+    inline arma_hot bool operator==(const const_row_iterator& rhs) const;
+    inline arma_hot bool operator!=(const const_row_iterator& rhs) const;
+
+    inline arma_hot bool operator==(const typename SpSubview<eT>::const_row_iterator& rhs) const;
+    inline arma_hot bool operator!=(const typename SpSubview<eT>::const_row_iterator& rhs) const;
+    };
+
+  class row_iterator : public const_row_iterator
+    {
+    public:
+    
+    inline row_iterator(SpMat& in_M, uword initial_pos = 0) : const_row_iterator(in_M, initial_pos) { }
+    //! Once initialized, will be at the first nonzero value after the given position (using forward row-wise traversal).
+    inline row_iterator(SpMat& in_M, uword in_row, uword in_col) : const_row_iterator(in_M, in_row, in_col) { }
+    inline row_iterator(const row_iterator& other) : const_row_iterator(other) { }
+    
+    inline arma_hot SpValProxy<SpMat<eT> > operator*();
+
+    // overloads required for return type correctness
+    inline arma_hot row_iterator& operator++();
+    inline arma_hot row_iterator  operator++(int);
+
+    inline arma_hot row_iterator& operator--();
+    inline arma_hot row_iterator  operator--(int);
+    
+    // This has a different value_type than iterator_base.
+    typedef SpValProxy<SpMat<eT> >         value_type;
+    typedef const SpValProxy<SpMat<eT> >*  pointer;
+    typedef const SpValProxy<SpMat<eT> >&  reference;
+    };
+  
+  inline       iterator     begin();
+  inline const_iterator     begin() const;
+  
+  inline       iterator end();
+  inline const_iterator end() const;
+  
+  inline       iterator     begin_col(const uword col_num);
+  inline const_iterator     begin_col(const uword col_num) const;
+  
+  inline       iterator     end_col(const uword col_num);
+  inline const_iterator     end_col(const uword col_num) const;
+  
+  inline       row_iterator begin_row(const uword row_num = 0);
+  inline const_row_iterator begin_row(const uword row_num = 0) const;
+  
+  inline       row_iterator end_row();
+  inline const_row_iterator end_row() const;
+  
+  inline       row_iterator end_row(const uword row_num);
+  inline const_row_iterator end_row(const uword row_num) const;
+  
+  inline void  clear();
+  inline bool  empty() const;
+  inline uword size()  const;
+  
+  /**
+   * Resize memory.  You are responsible for updating the column pointers and
+   * filling the new memory (if the new size is larger).  If the new size is
+   * smaller, the first new_n_nonzero elements will be copied.  n_nonzero is
+   * updated.
+   */
+  inline void mem_resize(const uword new_n_nonzero);
+  
+  //! don't use this unless you're writing internal Armadillo code
+  inline void steal_mem(SpMat& X);
+  
+  //! don't use this unless you're writing internal Armadillo code
+  template<              typename T1, typename Functor> arma_hot inline void init_xform   (const SpBase<eT, T1>& x, const Functor& func);
+  template<typename eT2, typename T1, typename Functor> arma_hot inline void init_xform_mt(const SpBase<eT2,T1>& x, const Functor& func);
+  
+  
+  protected:
+
+  /**
+   * Initialize the matrix to the specified size.  Data is not preserved, so the matrix is assumed to be entirely sparse (empty).
+   */
+  inline void init(uword in_rows, uword in_cols);
+
+  /**
+   * Initialize the matrix from text.  Data is (of course) not preserved, and
+   * the size will be reset.
+   */
+  inline void init(const std::string& text);
+
+  /**
+   * Initialize from another matrix (copy).
+   */
+  inline void init(const SpMat& x);
+  
+  
+  private:
+  
+  /**
+   * Return the given element.
+   */
+  inline arma_hot arma_warn_unused SpValProxy<SpMat<eT> > get_value(const uword i);
+  inline arma_hot arma_warn_unused eT                     get_value(const uword i) const;
+  
+  inline arma_hot arma_warn_unused SpValProxy<SpMat<eT> > get_value(const uword in_row, const uword in_col);
+  inline arma_hot arma_warn_unused eT                     get_value(const uword in_row, const uword in_col) const;
+  
+  /**
+   * Given the index representing which of the nonzero values this is, return
+   * its actual location, either in row/col or just the index.
+   */
+  arma_inline arma_hot arma_warn_unused uword get_position(const uword i) const;
+  arma_inline arma_hot                  void  get_position(const uword i, uword& row_of_i, uword& col_of_i) const;
+  
+  /**
+   * Add an element at the given position, and return a reference to it.  The
+   * element will be set to 0 (unless otherwise specified).  If the element
+   * already exists, its value will be overwritten.
+   *
+   * @param in_row Row of new element.
+   * @param in_col Column of new element.
+   * @param in_val Value to set new element to (default 0.0).
+   */
+  inline arma_hot arma_warn_unused eT& add_element(const uword in_row, const uword in_col, const eT in_val = 0.0);
+  
+  /**
+   * Delete an element at the given position.
+   *
+   * @param in_row Row of element to be deleted.
+   * @param in_col Column of element to be deleted.
+   */
+  inline arma_hot void delete_element(const uword in_row, const uword in_col);
+  
+  
+  public:
+    
+  #ifdef ARMA_EXTRA_SPMAT_PROTO
+    #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPMAT_PROTO)
+  #endif
+  };
+
+
+
+#define ARMA_HAS_SPMAT
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpMat_iterators_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,766 @@
+// Copyright (C) 2011-2012 Ryan Curtin
+// Copyright (C) 2011 Matthew Amidon
+// Copyright (C) 2012 Conrad Sanderson
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+//! \addtogroup SpMat
+//! @{
+
+///////////////////////////////////////////////////////////////////////////////
+// SpMat::iterator_base implementation                                       //
+///////////////////////////////////////////////////////////////////////////////
+
+template<typename eT>
+inline
+SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M)
+  : M(in_M)
+  , internal_col(0)
+  , internal_pos(0)
+  {
+  // Technically this iterator is invalid (it may not point to a real element)
+  }
+
+
+
+template<typename eT>
+inline
+SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M, const uword in_col, const uword in_pos)
+  : M(in_M)
+  , internal_col(in_col)
+  , internal_pos(in_pos)
+  {
+  // Nothing to do.
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+eT
+SpMat<eT>::iterator_base::operator*() const
+  {
+  return M.values[internal_pos];
+  }
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// SpMat::const_iterator implementation                                      //
+///////////////////////////////////////////////////////////////////////////////
+
+template<typename eT>
+inline
+SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, uword initial_pos)
+  : iterator_base(in_M, 0, initial_pos)
+  {
+  // Corner case for empty matrices.
+  if(in_M.n_nonzero == 0)
+    {
+    iterator_base::internal_col = in_M.n_cols;
+    return;
+    }
+
+  // Determine which column we should be in.
+  while(iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos)
+    {
+    iterator_base::internal_col++;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, uword in_row, uword in_col)
+  : iterator_base(in_M, in_col, 0)
+  {
+  // So we have a position we want to be right after.  Skip to the column.
+  iterator_base::internal_pos = iterator_base::M.col_ptrs[iterator_base::internal_col];
+
+  // Now we have to make sure that is the right column.
+  while(iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos)
+    {
+    iterator_base::internal_col++;
+    }
+
+  // Now we have to get to the right row.
+  while((iterator_base::M.row_indices[iterator_base::internal_pos] < in_row) && (iterator_base::internal_col == in_col))
+    {
+    ++(*this); // Increment iterator.
+    }
+  }
+
+
+
+template<typename eT>
+inline
+SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, const uword /* in_row */, const uword in_col, const uword in_pos)
+  : iterator_base(in_M, in_col, in_pos)
+  {
+  // Nothing to do.
+  }
+
+
+
+template<typename eT>
+inline
+SpMat<eT>::const_iterator::const_iterator(const typename SpMat<eT>::const_iterator& other)
+  : iterator_base(other.M, other.internal_col, other.internal_pos)
+  {
+  // Nothing to do.
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::const_iterator&
+SpMat<eT>::const_iterator::operator++()
+  {
+  ++iterator_base::internal_pos;
+
+  if (iterator_base::internal_pos == iterator_base::M.n_nonzero)
+    {
+    iterator_base::internal_col = iterator_base::M.n_cols;
+    return *this;
+    }
+
+  // Check to see if we moved a column.
+  while (iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos)
+    {
+    ++iterator_base::internal_col;
+    }
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::const_iterator
+SpMat<eT>::const_iterator::operator++(int)
+  {
+  typename SpMat<eT>::const_iterator tmp(*this);
+
+  ++(*this);
+
+  return tmp;
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::const_iterator&
+SpMat<eT>::const_iterator::operator--()
+  {
+  //iterator_base::M.print("M");
+  
+  // printf("decrement from %d, %d, %d\n", iterator_base::internal_pos, iterator_base::internal_col, iterator_base::row());
+  
+  --iterator_base::internal_pos;
+  
+  // printf("now pos %d\n", iterator_base::internal_pos);
+
+  // First, see if we moved back a column.
+  while (iterator_base::internal_pos < iterator_base::M.col_ptrs[iterator_base::internal_col])
+    {
+    // printf("colptr %d (col %d)\n", iterator_base::M.col_ptrs[iterator_base::internal_col], iterator_base::internal_col);
+    
+    --iterator_base::internal_col;
+    }
+
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::const_iterator
+SpMat<eT>::const_iterator::operator--(int)
+  {
+  typename SpMat<eT>::const_iterator tmp(*this);
+
+  --(*this);
+
+  return tmp;
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_iterator::operator==(const const_iterator& rhs) const
+  {
+  return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_iterator::operator!=(const const_iterator& rhs) const
+  {
+  return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_iterator::operator==(const typename SpSubview<eT>::const_iterator& rhs) const
+  {
+  return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_iterator::operator!=(const typename SpSubview<eT>::const_iterator& rhs) const
+  {
+  return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_iterator::operator==(const const_row_iterator& rhs) const
+  {
+  return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_iterator::operator!=(const const_row_iterator& rhs) const
+  {
+  return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_iterator::operator==(const typename SpSubview<eT>::const_row_iterator& rhs) const
+  {
+  return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_iterator::operator!=(const typename SpSubview<eT>::const_row_iterator& rhs) const
+  {
+  return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// SpMat::iterator implementation                                            //
+///////////////////////////////////////////////////////////////////////////////
+
+template<typename eT>
+inline
+arma_hot
+SpValProxy<SpMat<eT> >
+SpMat<eT>::iterator::operator*()
+  {
+  return SpValProxy<SpMat<eT> >(
+    iterator_base::M.row_indices[iterator_base::internal_pos],
+    iterator_base::internal_col,
+    access::rw(iterator_base::M),
+    &access::rw(iterator_base::M.values[iterator_base::internal_pos]));
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::iterator&
+SpMat<eT>::iterator::operator++()
+  {
+  const_iterator::operator++();
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::iterator
+SpMat<eT>::iterator::operator++(int)
+  {
+  typename SpMat<eT>::iterator tmp(*this);
+
+  const_iterator::operator++();
+
+  return tmp;
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::iterator&
+SpMat<eT>::iterator::operator--()
+  {
+  const_iterator::operator--();
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::iterator
+SpMat<eT>::iterator::operator--(int)
+  {
+  typename SpMat<eT>::iterator tmp(*this);
+
+  const_iterator::operator--();
+
+  return tmp;
+  }
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// SpMat::const_row_iterator implementation                                  //
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Initialize the const_row_iterator.
+ */
+template<typename eT>
+inline
+SpMat<eT>::const_row_iterator::const_row_iterator(const SpMat<eT>& in_M, uword initial_pos)
+  : iterator_base(in_M, 0, initial_pos)
+  , internal_row(0)
+  , actual_pos(0)
+  {
+  // Corner case for empty matrix.
+  if(in_M.n_nonzero == 0)
+    {
+    iterator_base::internal_col = 0;
+    internal_row = in_M.n_rows;
+    return;
+    }
+
+  // We don't count zeroes in our position count, so we have to find the nonzero
+  // value corresponding to the given initial position.  We assume initial_pos
+  // is valid.
+
+  // This is irritating because we don't know where the elements are in each
+  // row.  What we will do is loop across all columns looking for elements in
+  // row 0 (and add to our sum), then in row 1, and so forth, until we get to
+  // the desired position.
+  uword cur_pos = -1;
+  uword cur_row = 0;
+  uword cur_col = 0;
+
+  while(true) // This loop is terminated from the inside.
+    {
+    // Is there anything in the column we are looking at?
+    for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterator_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] <= cur_row)); ind++)
+      {
+      // There is something in this column.  Is it in the row we are looking at?
+      const uword row_index = iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind];
+      if (row_index == cur_row)
+        {
+        // Yes, it is what we are looking for.  Increment our current position.
+        if (++cur_pos == iterator_base::internal_pos)
+          {
+          actual_pos = iterator_base::M.col_ptrs[cur_col] + ind;
+          internal_row = cur_row;
+          iterator_base::internal_col = cur_col;
+
+          return;
+          }
+
+        // We are done with this column.  Break to the column incrementing code (directly below).
+        break;
+        }
+      else if(row_index > cur_row)
+        {
+        break; // Can't be in this column.
+        }
+      }
+
+    cur_col++; // Done with the column.  Move on.
+    if (cur_col == iterator_base::M.n_cols)
+      {
+      // We are out of columns.  Loop back to the beginning and look on the
+      // next row.
+      cur_col = 0;
+      cur_row++;
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+SpMat<eT>::const_row_iterator::const_row_iterator(const SpMat<eT>& in_M, uword in_row, uword in_col)
+  : iterator_base(in_M, in_col, 0)
+  , internal_row(0)
+  , actual_pos(0)
+  {
+  // This is slow.  It needs to be rewritten.
+  // So we have a destination we want to be just after, but don't know what position that is.  Make another iterator to find out...
+  const_row_iterator it(in_M, 0);
+  while((it.row() < in_row) || ((it.row() == in_row) && (it.col() < in_col)))
+    {
+    it++;
+    }
+
+  // Now that it is at the right place, take its position.
+  iterator_base::internal_col = it.internal_col;
+  iterator_base::internal_pos = it.internal_pos;
+  internal_row = it.internal_row;
+  actual_pos = it.actual_pos;
+  }
+
+
+
+/**
+ * Initialize the const_row_iterator from another const_row_iterator.
+ */
+template<typename eT>
+inline
+SpMat<eT>::const_row_iterator::const_row_iterator(const typename SpMat<eT>::const_row_iterator& other)
+  : iterator_base(other.M, other.internal_col, other.internal_pos)
+  , internal_row(other.internal_row)
+  , actual_pos(other.actual_pos)
+  {
+  // Nothing to do.
+  }
+
+
+
+/**
+ * Increment the row_iterator.
+ */
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::const_row_iterator&
+SpMat<eT>::const_row_iterator::operator++()
+  {
+  // We just need to find the next nonzero element.
+  iterator_base::internal_pos++;
+
+  if(iterator_base::internal_pos == iterator_base::M.n_nonzero)
+    {
+    internal_row = iterator_base::M.n_rows;
+    iterator_base::internal_col = 0;
+    actual_pos = iterator_base::M.n_nonzero;
+
+    return *this;
+    }
+
+  // Otherwise, we need to search.
+  uword cur_col = iterator_base::internal_col;
+  uword cur_row = internal_row;
+
+  while (true) // This loop is terminated from the inside.
+    {
+    // Increment the current column and see if we are now on a new row.
+    if (++cur_col == iterator_base::M.n_cols)
+      {
+      cur_col = 0;
+      cur_row++;
+      }
+
+    // Is there anything in this new column?
+    for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterator_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] <= cur_row)); ind++)
+      {
+      if (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] == cur_row)
+        {
+        // We have successfully incremented.
+        internal_row = cur_row;
+        iterator_base::internal_col = cur_col;
+        actual_pos = iterator_base::M.col_ptrs[cur_col] + ind;
+
+        return *this; // Now we are done.
+        }
+      }
+    }
+  }
+
+
+
+/**
+ * Increment the row_iterator (but do not return anything.
+ */
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::const_row_iterator
+SpMat<eT>::const_row_iterator::operator++(int)
+  {
+  typename SpMat<eT>::const_row_iterator tmp(*this);
+
+  ++(*this);
+
+  return tmp;
+  }
+
+
+
+/**
+ * Decrement the row_iterator.
+ */
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::const_row_iterator&
+SpMat<eT>::const_row_iterator::operator--()
+  {
+  iterator_base::internal_pos--;
+
+  // We have to search backwards.
+  uword cur_col = iterator_base::internal_col;
+  uword cur_row = internal_row;
+
+  while (true) // This loop is terminated from the inside.
+    {
+    // Decrement the current column and see if we are now on a new row.  This is a uword so a negativity check won't work.
+    if (--cur_col > iterator_base::M.n_cols /* this means it underflew */)
+      {
+      cur_col = iterator_base::M.n_cols - 1;
+      cur_row--;
+      }
+
+    // Is there anything in this new column?
+    for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterator_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] <= cur_row)); ind++)
+      {
+      if (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] == cur_row)
+        {
+        // We have successfully decremented.
+        iterator_base::internal_col = cur_col;
+        internal_row = cur_row;
+        actual_pos = iterator_base::M.col_ptrs[cur_col] + ind;
+
+        return *this; // Now we are done.
+        }
+      }
+    }
+  }
+
+
+
+/**
+ * Decrement the row_iterator.
+ */
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::const_row_iterator
+SpMat<eT>::const_row_iterator::operator--(int)
+  {
+  typename SpMat<eT>::const_row_iterator tmp(*this);
+
+  --(*this);
+
+  return tmp;
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_row_iterator::operator==(const const_iterator& rhs) const
+  {
+  return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_row_iterator::operator!=(const const_iterator& rhs) const
+  {
+  return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_row_iterator::operator==(const typename SpSubview<eT>::const_iterator& rhs) const
+  {
+  return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_row_iterator::operator!=(const typename SpSubview<eT>::const_iterator& rhs) const
+  {
+  return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_row_iterator::operator==(const const_row_iterator& rhs) const
+  {
+  return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_row_iterator::operator!=(const const_row_iterator& rhs) const
+  {
+  return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_row_iterator::operator==(const typename SpSubview<eT>::const_row_iterator& rhs) const
+  {
+  return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+bool
+SpMat<eT>::const_row_iterator::operator!=(const typename SpSubview<eT>::const_row_iterator& rhs) const
+  {
+  return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// SpMat::row_iterator implementation                                        //
+///////////////////////////////////////////////////////////////////////////////
+
+template<typename eT>
+inline
+arma_hot
+SpValProxy<SpMat<eT> >
+SpMat<eT>::row_iterator::operator*()
+  {
+  return SpValProxy<SpMat<eT> >(
+    const_row_iterator::internal_row,
+    iterator_base::internal_col,
+    access::rw(iterator_base::M),
+    &access::rw(iterator_base::M.values[const_row_iterator::actual_pos]));
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::row_iterator&
+SpMat<eT>::row_iterator::operator++()
+  {
+  const_row_iterator::operator++();
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::row_iterator
+SpMat<eT>::row_iterator::operator++(int)
+  {
+  typename SpMat<eT>::row_iterator tmp(*this);
+
+  const_row_iterator::operator++();
+
+  return tmp;
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::row_iterator&
+SpMat<eT>::row_iterator::operator--()
+  {
+  const_row_iterator::operator--();
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+typename SpMat<eT>::row_iterator
+SpMat<eT>::row_iterator::operator--(int)
+  {
+  typename SpMat<eT>::row_iterator tmp(*this);
+
+  const_row_iterator::operator--();
+
+  return tmp;
+  }
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpMat_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,4800 @@
+// Copyright (C) 2011-2013 Ryan Curtin
+// Copyright (C) 2012-2013 Conrad Sanderson
+// Copyright (C) 2011 Matthew Amidon
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+//! \addtogroup SpMat
+//! @{
+
+/**
+ * Initialize a sparse matrix with size 0x0 (empty).
+ */
+template<typename eT>
+inline
+SpMat<eT>::SpMat()
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(memory::acquire_chunked<eT>(1))
+  , row_indices(memory::acquire_chunked<uword>(1))
+  , col_ptrs(memory::acquire<uword>(2))
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  access::rw(values[0]) = 0;
+  access::rw(row_indices[0]) = 0;
+  
+  access::rw(col_ptrs[0]) = 0; // No elements.
+  access::rw(col_ptrs[1]) = std::numeric_limits<uword>::max();
+  }
+
+
+
+/**
+ * Clean up the memory of a sparse matrix and destruct it.
+ */
+template<typename eT>
+inline
+SpMat<eT>::~SpMat()
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  // If necessary, release the memory.
+  if (values)
+    {
+    // values being non-NULL implies row_indices is non-NULL.
+    memory::release(access::rw(values));
+    memory::release(access::rw(row_indices));
+    }
+
+  // Column pointers always must be deleted.
+  memory::release(access::rw(col_ptrs));
+  }
+
+
+
+/**
+ * Constructor with size given.
+ */
+template<typename eT>
+inline
+SpMat<eT>::SpMat(const uword in_rows, const uword in_cols)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(NULL)
+  , row_indices(NULL)
+  , col_ptrs(NULL)
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  init(in_rows, in_cols);
+  }
+
+
+
+/**
+ * Assemble from text.
+ */
+template<typename eT>
+inline
+SpMat<eT>::SpMat(const char* text)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(NULL)
+  , row_indices(NULL)
+  , col_ptrs(NULL)
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  init(std::string(text));
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator=(const char* text)
+  {
+  arma_extra_debug_sigprint();
+
+  init(std::string(text));
+  }
+
+
+
+template<typename eT>
+inline
+SpMat<eT>::SpMat(const std::string& text)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(NULL)
+  , row_indices(NULL)
+  , col_ptrs(NULL)
+  {
+  arma_extra_debug_sigprint();
+
+  init(text);
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator=(const std::string& text)
+  {
+  arma_extra_debug_sigprint();
+
+  init(text);
+  }
+
+
+
+template<typename eT>
+inline
+SpMat<eT>::SpMat(const SpMat<eT>& x)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(NULL)
+  , row_indices(NULL)
+  , col_ptrs(NULL)
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  init(x);
+  }
+
+
+
+//! Insert a large number of values at once.
+//! locations.row[0] should be row indices, locations.row[1] should be column indices,
+//! and values should be the corresponding values.
+//! If sort_locations is false, then it is assumed that the locations and values
+//! are already sorted in column-major ordering.
+template<typename eT>
+template<typename T1, typename T2>
+inline
+SpMat<eT>::SpMat(const Base<uword,T1>& locations_expr, const Base<eT,T2>& vals_expr, const bool sort_locations)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(NULL)
+  , row_indices(NULL)
+  , col_ptrs(NULL)
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  const unwrap<T1>         locs_tmp( locations_expr.get_ref() );
+  const Mat<uword>& locs = locs_tmp.M;
+  
+  const unwrap<T2> vals_tmp( vals_expr.get_ref() );
+  const Mat<eT>& vals = vals_tmp.M;
+  
+  arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'values' object is not a vector" );
+  
+  arma_debug_check((locs.n_cols != vals.n_elem), "SpMat::SpMat(): number of locations is different than number of values");
+  
+  // If there are no elements in the list, max() will fail.
+  if (locs.n_cols == 0)
+    {
+    init(0, 0);
+    return;
+    }
+
+  arma_debug_check((locs.n_rows != 2), "SpMat::SpMat(): locations matrix must have two rows");
+
+  // Automatically determine size (and check if it's sorted).
+  uvec bounds = arma::max(locs, 1);
+  init(bounds[0] + 1, bounds[1] + 1);
+
+  // Resize to correct number of elements.
+  mem_resize(vals.n_elem);
+
+  // Reset column pointers to zero.
+  arrayops::inplace_set(access::rwp(col_ptrs), uword(0), n_cols + 1);
+
+  bool actually_sorted = true;
+  if(sort_locations == true)
+    {
+    // sort_index() uses std::sort() which may use quicksort... so we better
+    // make sure it's not already sorted before taking an O(N^2) sort penalty.
+    for (uword i = 1; i < locs.n_cols; ++i)
+      {
+      if ((locs.at(1, i) < locs.at(1, i - 1)) || (locs.at(1, i) == locs.at(1, i - 1) && locs.at(0, i) <= locs.at(0, i - 1)))
+        {
+        actually_sorted = false;
+        break;
+        }
+      }
+    
+    if(actually_sorted == false)
+      {
+      // This may not be the fastest possible implementation but it maximizes code reuse.
+      Col<uword> abslocs(locs.n_cols);
+      
+      for (uword i = 0; i < locs.n_cols; ++i)
+        {
+        abslocs[i] = locs.at(1, i) * n_rows + locs.at(0, i);
+        }
+      
+      // Now we will sort with sort_index().
+      uvec sorted_indices = sort_index(abslocs); // Ascending sort.
+      
+      // Now we add the elements in this sorted order.
+      for (uword i = 0; i < sorted_indices.n_elem; ++i)
+        {
+        arma_debug_check((locs.at(0, sorted_indices[i]) >= n_rows), "SpMat::SpMat(): invalid row index");
+        arma_debug_check((locs.at(1, sorted_indices[i]) >= n_cols), "SpMat::SpMat(): invalid column index");
+        
+        access::rw(values[i])      = vals[sorted_indices[i]];
+        access::rw(row_indices[i]) = locs.at(0, sorted_indices[i]);
+        
+        access::rw(col_ptrs[locs.at(1, sorted_indices[i]) + 1])++;
+        }
+      }
+    }
+  
+  if( (sort_locations == false) || (actually_sorted == true) )
+    {
+    // Now set the values and row indices correctly.
+    // Increment the column pointers in each column (so they are column "counts").
+    for (uword i = 0; i < vals.n_elem; ++i)
+      {
+      arma_debug_check((locs.at(0, i) >= n_rows), "SpMat::SpMat(): invalid row index");
+      arma_debug_check((locs.at(1, i) >= n_cols), "SpMat::SpMat(): invalid column index");
+      
+      // Check ordering in debug mode.
+      if(i > 0)
+        {
+        arma_debug_check
+          (
+          ( (locs.at(1, i) < locs.at(1, i - 1)) || (locs.at(1, i) == locs.at(1, i - 1) && locs.at(0, i) < locs.at(0, i - 1)) ),
+          "SpMat::SpMat(): out of order points; either pass sort_locations = true, or sort points in column-major ordering"
+          );
+        arma_debug_check((locs.at(1, i) == locs.at(1, i - 1) && locs.at(0, i) == locs.at(0, i - 1)), "SpMat::SpMat(): two identical point locations in list");
+        }
+      
+      access::rw(values[i])      = vals[i];
+      access::rw(row_indices[i]) = locs.at(0, i);
+      
+      access::rw(col_ptrs[locs.at(1, i) + 1])++;
+      }
+    }
+  
+  // Now fix the column pointers.
+  for (uword i = 0; i <= n_cols; ++i)
+    {
+    access::rw(col_ptrs[i + 1]) += col_ptrs[i];
+    }
+  }
+
+
+
+//! Insert a large number of values at once.
+//! locations.row[0] should be row indices, locations.row[1] should be column indices,
+//! and values should be the corresponding values.
+//! If sort_locations is false, then it is assumed that the locations and values
+//! are already sorted in column-major ordering.
+//! In this constructor the size is explicitly given.
+template<typename eT>
+template<typename T1, typename T2>
+inline
+SpMat<eT>::SpMat(const Base<uword,T1>& locations_expr, const Base<eT,T2>& vals_expr, const uword in_n_rows, const uword in_n_cols, const bool sort_locations)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(NULL)
+  , row_indices(NULL)
+  , col_ptrs(NULL)
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init(in_n_rows, in_n_cols);
+  
+  const unwrap<T1>         locs_tmp( locations_expr.get_ref() );
+  const Mat<uword>& locs = locs_tmp.M;
+  
+  const unwrap<T2> vals_tmp( vals_expr.get_ref() );
+  const Mat<eT>& vals = vals_tmp.M;
+  
+  arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'values' object is not a vector" );
+  
+  arma_debug_check((locs.n_rows != 2), "SpMat::SpMat(): locations matrix must have two rows");
+  
+  arma_debug_check((locs.n_cols != vals.n_elem), "SpMat::SpMat(): number of locations is different than number of values");
+  
+  // Resize to correct number of elements.
+  mem_resize(vals.n_elem);
+  
+  // Reset column pointers to zero.
+  arrayops::inplace_set(access::rwp(col_ptrs), uword(0), n_cols + 1);
+  
+  bool actually_sorted = true;
+  if(sort_locations == true)
+    {
+    // sort_index() uses std::sort() which may use quicksort... so we better
+    // make sure it's not already sorted before taking an O(N^2) sort penalty.
+    for (uword i = 1; i < locs.n_cols; ++i)
+      {
+      if ((locs.at(1, i) < locs.at(1, i - 1)) || (locs.at(1, i) == locs.at(1, i - 1) && locs.at(0, i) <= locs.at(0, i - 1)))
+        {
+        actually_sorted = false;
+        break;
+        }
+      }
+    
+    if(actually_sorted == false)
+      {
+      // This may not be the fastest possible implementation but it maximizes code reuse.
+      Col<uword> abslocs(locs.n_cols);
+      
+      for (uword i = 0; i < locs.n_cols; ++i)
+        {
+        abslocs[i] = locs.at(1, i) * n_rows + locs.at(0, i);
+        }
+
+      // Now we will sort with sort_index().
+      uvec sorted_indices = sort_index(abslocs); // Ascending sort.
+
+      // Now we add the elements in this sorted order.
+      for (uword i = 0; i < sorted_indices.n_elem; ++i)
+        {
+        arma_debug_check((locs.at(0, sorted_indices[i]) >= n_rows), "SpMat::SpMat(): invalid row index");
+        arma_debug_check((locs.at(1, sorted_indices[i]) >= n_cols), "SpMat::SpMat(): invalid column index");
+
+        access::rw(values[i])      = vals[sorted_indices[i]];
+        access::rw(row_indices[i]) = locs.at(0, sorted_indices[i]);
+
+        access::rw(col_ptrs[locs.at(1, sorted_indices[i]) + 1])++;
+        }
+      }
+    }
+
+  if( (sort_locations == false) || (actually_sorted == true) )
+    {
+    // Now set the values and row indices correctly.
+    // Increment the column pointers in each column (so they are column "counts").
+    for (uword i = 0; i < vals.n_elem; ++i)
+      {
+      arma_debug_check((locs.at(0, i) >= n_rows), "SpMat::SpMat(): invalid row index");
+      arma_debug_check((locs.at(1, i) >= n_cols), "SpMat::SpMat(): invalid column index");
+
+      // Check ordering in debug mode.
+      if(i > 0)
+        {
+        arma_debug_check
+          (
+          ( (locs.at(1, i) < locs.at(1, i - 1)) || (locs.at(1, i) == locs.at(1, i - 1) && locs.at(0, i) < locs.at(0, i - 1)) ),
+          "SpMat::SpMat(): out of order points; either pass sort_locations = true or sort points in column-major ordering"
+          );
+        arma_debug_check((locs.at(1, i) == locs.at(1, i - 1) && locs.at(0, i) == locs.at(0, i - 1)), "SpMat::SpMat(): two identical point locations in list");
+        }
+
+      access::rw(values[i])      = vals[i];
+      access::rw(row_indices[i]) = locs.at(0, i);
+
+      access::rw(col_ptrs[locs.at(1, i) + 1])++;
+      }
+    }
+
+  // Now fix the column pointers.
+  for (uword i = 0; i <= n_cols; ++i)
+    {
+    access::rw(col_ptrs[i + 1]) += col_ptrs[i];
+    }
+  }
+
+
+
+/**
+ * Simple operators with plain values.  These operate on every value in the
+ * matrix, so a sparse matrix += 1 will turn all those zeroes into ones.  Be
+ * careful and make sure that's what you really want!
+ */
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+
+  // Resize to 1x1 then set that to the right value.
+  init(1, 1); // Sets col_ptrs to 0.
+  mem_resize(1); // One element.
+
+  // Manually set element.
+  access::rw(values[0]) = val;
+  access::rw(row_indices[0]) = 0;
+  access::rw(col_ptrs[1]) = 1;
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator*=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(val == eT(0))
+    {
+    // Everything will be zero.
+    init(n_rows, n_cols);
+    return *this;
+    }
+  
+  arrayops::inplace_mul( access::rwp(values), val, n_nonzero );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator/=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (val == eT(0)), "element-wise division: division by zero" );
+  
+  arrayops::inplace_div( access::rwp(values), val, n_nonzero );
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator=(const SpMat<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  init(x);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator+=(const SpMat<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "addition");
+  
+  // Iterate over nonzero values of other matrix.
+  for (const_iterator it = x.begin(); it != x.end(); it++)
+    {
+    get_value(it.row(), it.col()) += *it;
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator-=(const SpMat<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "subtraction");
+  
+  // Iterate over nonzero values of other matrix.
+  for (const_iterator it = x.begin(); it != x.end(); it++)
+    {
+    get_value(it.row(), it.col()) -= *it;
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator*=(const SpMat<eT>& y)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_mul_size(n_rows, n_cols, y.n_rows, y.n_cols, "matrix multiplication");
+  
+  SpMat<eT> z;
+  z = (*this) * y;
+  steal_mem(z);
+  
+  return *this;
+  }
+
+
+
+// This is in-place element-wise matrix multiplication.
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator%=(const SpMat<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-wise multiplication");
+  
+  // We can do this with two iterators rather simply.
+        iterator it    = begin();
+  const_iterator x_it  = x.begin();
+  
+  while (it != end() && x_it != x.end())
+    {
+    // One of these will be further advanced than the other (or they will be at the same place).
+    if ((it.row() == x_it.row()) && (it.col() == x_it.col()))
+      {
+      // There is an element at this place in both matrices.  Multiply.
+      (*it) *= (*x_it);
+
+      // Now move on to the next position.
+      it++;
+      x_it++;
+      }
+
+    else if ((it.col() < x_it.col()) || ((it.col() == x_it.col()) && (it.row() < x_it.row())))
+      {
+      // This case is when our matrix has an element which the other matrix does not.
+      // So we must delete this element.
+      (*it) = 0;
+
+      // Because we have deleted the element, we now have to manually set the position...
+      it.internal_pos--;
+
+      // Now we can increment our iterator.
+      it++;
+      }
+
+    else /* if our iterator is ahead of the other matrix */
+      {
+      // In this case we don't need to set anything to 0; our element is already 0.
+      // We can just increment the iterator of the other matrix.
+      x_it++;
+      }
+
+    }
+
+  // If we are not at the end of our matrix, then we must terminate the remaining elements.
+  while (it != end())
+    {
+    (*it) = 0;
+
+    // Hack to manually set the position right...
+    it.internal_pos--;
+    it++; // ...and then an increment.
+    }
+
+  return *this;
+  }
+
+
+
+// Construct a complex matrix out of two non-complex matrices
+template<typename eT>
+template<typename T1, typename T2>
+inline
+SpMat<eT>::SpMat
+  (
+  const SpBase<typename SpMat<eT>::pod_type, T1>& A,
+  const SpBase<typename SpMat<eT>::pod_type, T2>& B
+  )
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(NULL) // extra element is set when mem_resize is called
+  , row_indices(NULL)
+  , col_ptrs(NULL)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type T;
+  
+  // Make sure eT is complex and T is not (compile-time check).
+  arma_type_check(( is_complex<eT>::value == false ));
+  arma_type_check(( is_complex< T>::value == true  ));
+  
+  // Compile-time abort if types are not compatible.
+  arma_type_check(( is_same_type< std::complex<T>, eT >::value == false ));
+  
+  const unwrap_spmat<T1> tmp1(A.get_ref());
+  const unwrap_spmat<T2> tmp2(B.get_ref());
+  
+  const SpMat<T>& X = tmp1.M;
+  const SpMat<T>& Y = tmp2.M;
+  
+  arma_debug_assert_same_size(X.n_rows, X.n_cols, Y.n_rows, Y.n_cols, "SpMat()");
+  
+  const uword l_n_rows = X.n_rows;
+  const uword l_n_cols = X.n_cols;
+  
+  // Set size of matrix correctly.
+  init(l_n_rows, l_n_cols);
+  mem_resize(n_unique(X, Y, op_n_unique_count()));
+  
+  // Now on a second iteration, fill it.
+  typename SpMat<T>::const_iterator x_it  = X.begin();
+  typename SpMat<T>::const_iterator x_end = X.end();
+  
+  typename SpMat<T>::const_iterator y_it  = Y.begin();
+  typename SpMat<T>::const_iterator y_end = Y.end();
+  
+  uword cur_pos = 0;
+  
+  while ((x_it != x_end) || (y_it != y_end))
+    {
+    if(x_it == y_it) // if we are at the same place
+      {
+      access::rw(values[cur_pos]) = std::complex<T>((T) *x_it, (T) *y_it);
+      access::rw(row_indices[cur_pos]) = x_it.row();
+      ++access::rw(col_ptrs[x_it.col() + 1]);
+      
+      ++x_it;
+      ++y_it;
+      }
+    else
+      {
+      if((x_it.col() < y_it.col()) || ((x_it.col() == y_it.col()) && (x_it.row() < y_it.row()))) // if y is closer to the end
+        {
+        access::rw(values[cur_pos]) = std::complex<T>((T) *x_it, T(0));
+        access::rw(row_indices[cur_pos]) = x_it.row();
+        ++access::rw(col_ptrs[x_it.col() + 1]);
+        
+        ++x_it;
+        }
+      else // x is closer to the end
+        {
+        access::rw(values[cur_pos]) = std::complex<T>(T(0), (T) *y_it);
+        access::rw(row_indices[cur_pos]) = y_it.row();
+        ++access::rw(col_ptrs[y_it.col() + 1]);
+        
+        ++y_it;
+        }
+      }
+    
+    ++cur_pos;
+    }
+  
+  // Now fix the column pointers; they are supposed to be a sum.
+  for (uword c = 1; c <= n_cols; ++c)
+    {
+    access::rw(col_ptrs[c]) += col_ptrs[c - 1];
+    }
+  
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator/=(const SpMat<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-wise division");
+  
+  // If you use this method, you are probably stupid or misguided, but for compatibility with Mat, we have implemented it anyway.
+  // We have to loop over every element, which is not good.  In fact, it makes me physically sad to write this.
+  for(uword c = 0; c < n_cols; ++c)
+    {
+    for(uword r = 0; r < n_rows; ++r)
+      {
+      at(r, c) /= x.at(r, c);
+      }
+    }
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+SpMat<eT>::SpMat(const Base<eT, T1>& x)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(NULL) // extra element is set when mem_resize is called in operator=()
+  , row_indices(NULL)
+  , col_ptrs(NULL)
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  (*this).operator=(x);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator=(const Base<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Proxy<T1> p(x.get_ref());
+  
+  const uword x_n_rows = p.get_n_rows();
+  const uword x_n_cols = p.get_n_cols();
+  const uword x_n_elem = p.get_n_elem();
+
+  init(x_n_rows, x_n_cols);
+
+  // Count number of nonzero elements in base object.
+  uword n = 0;
+  if(Proxy<T1>::prefer_at_accessor == true)
+    {
+    for(uword j = 0; j < x_n_cols; ++j)
+    for(uword i = 0; i < x_n_rows; ++i)
+      {
+      if(p.at(i, j) != eT(0)) { ++n; }
+      }
+    }
+  else
+    {
+    for(uword i = 0; i < x_n_elem; ++i)
+      {
+      if(p[i] != eT(0)) { ++n; }
+      }
+    }
+
+  mem_resize(n);
+
+  // Now the memory is resized correctly; add nonzero elements.
+  n = 0;
+  for(uword j = 0; j < x_n_cols; ++j)
+  for(uword i = 0; i < x_n_rows; ++i)
+    {
+    const eT val = p.at(i, j);
+    
+    if(val != eT(0))
+      {
+      access::rw(values[n])      = val;
+      access::rw(row_indices[n]) = i;
+      access::rw(col_ptrs[j + 1])++;
+      ++n;
+      }
+    }
+
+  // Sum column counts to be column pointers.
+  for(uword c = 1; c <= n_cols; ++c)
+    {
+    access::rw(col_ptrs[c]) += col_ptrs[c - 1];
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator*=(const Base<eT, T1>& y)
+  {
+  arma_extra_debug_sigprint();
+
+  const Proxy<T1> p(y.get_ref());
+
+  arma_debug_assert_mul_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "matrix multiplication");
+
+  // We assume the matrix structure is such that we will end up with a sparse
+  // matrix.  Assuming that every entry in the dense matrix is nonzero (which is
+  // a fairly valid assumption), each row with any nonzero elements in it (in this
+  // matrix) implies an entire nonzero column.  Therefore, we iterate over all
+  // the row_indices and count the number of rows with any elements in them
+  // (using the quasi-linked-list idea from SYMBMM -- see operator_times.hpp).
+  podarray<uword> index(n_rows);
+  index.fill(n_rows); // Fill with invalid links.
+
+  uword last_index = n_rows + 1;
+  for(uword i = 0; i < n_nonzero; ++i)
+    {
+    if(index[row_indices[i]] == n_rows)
+      {
+      index[row_indices[i]] = last_index;
+      last_index = row_indices[i];
+      }
+    }
+
+  // Now count the number of rows which have nonzero elements.
+  uword nonzero_rows = 0;
+  while(last_index != n_rows + 1)
+    {
+    ++nonzero_rows;
+    last_index = index[last_index];
+    }
+
+  SpMat<eT> z(n_rows, p.get_n_cols());
+
+  z.mem_resize(nonzero_rows * p.get_n_cols()); // upper bound on size
+
+  // Now we have to fill all the elements using a modification of the NUMBMM algorithm.
+  uword cur_pos = 0;
+
+  podarray<eT> partial_sums(n_rows);
+  partial_sums.zeros();
+
+  for(uword lcol = 0; lcol < n_cols; ++lcol)
+    {
+    const_iterator it = begin();
+
+    while(it != end())
+      {
+      const eT value = (*it);
+
+      partial_sums[it.row()] += (value * p.at(it.col(), lcol));
+
+      ++it;
+      }
+
+    // Now add all partial sums to the matrix.
+    for(uword i = 0; i < n_rows; ++i)
+      {
+      if(partial_sums[i] != eT(0))
+        {
+        access::rw(z.values[cur_pos]) = partial_sums[i];
+        access::rw(z.row_indices[cur_pos]) = i;
+        ++access::rw(z.col_ptrs[lcol + 1]);
+        //printf("colptr %d now %d\n", lcol + 1, z.col_ptrs[lcol + 1]);
+        ++cur_pos;
+        partial_sums[i] = 0; // Would it be faster to do this in batch later?
+        }
+      }
+    }
+
+  // Now fix the column pointers.
+  for(uword c = 1; c <= z.n_cols; ++c)
+    {
+    access::rw(z.col_ptrs[c]) += z.col_ptrs[c - 1];
+    }
+
+  // Resize to final correct size.
+  z.mem_resize(z.col_ptrs[z.n_cols]);
+  
+  // Now take the memory of the temporary matrix.
+  steal_mem(z);
+  
+  return *this;
+  }
+
+
+
+/**
+ * Don't use this function.  It's not mathematically well-defined and wastes
+ * cycles to trash all your data.  This is dumb.
+ */
+template<typename eT>
+template<typename T1>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator/=(const Base<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+
+  SpMat<eT> tmp = (*this) / x.get_ref();
+  
+  steal_mem(tmp);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator%=(const Base<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+
+  const Proxy<T1> p(x.get_ref());
+  
+  arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise multiplication");
+  
+  // Count the number of elements we will need.
+  SpMat<eT> tmp(n_rows, n_cols);
+  const_iterator it = begin();
+  uword new_n_nonzero = 0;
+
+  while(it != end())
+    {
+    // prefer_at_accessor == false can't save us any work here
+    if(((*it) * p.at(it.row(), it.col())) != eT(0))
+      {
+      ++new_n_nonzero;
+      }
+    ++it;
+    }
+
+  // Resize.
+  tmp.mem_resize(new_n_nonzero);
+
+  const_iterator c_it = begin();
+  uword cur_pos = 0;
+  while(c_it != end())
+    {
+    // prefer_at_accessor == false can't save us any work here
+    const eT val = (*c_it) * p.at(c_it.row(), c_it.col());
+    if(val != eT(0))
+      {
+      access::rw(tmp.values[cur_pos]) = val;
+      access::rw(tmp.row_indices[cur_pos]) = c_it.row();
+      ++access::rw(tmp.col_ptrs[c_it.col() + 1]);
+      ++cur_pos;
+      }
+
+    ++c_it;
+    }
+
+  // Fix column pointers.
+  for(uword c = 1; c <= n_cols; ++c)
+    {
+    access::rw(tmp.col_ptrs[c]) += tmp.col_ptrs[c - 1];
+    }
+
+  steal_mem(tmp);
+
+  return *this;
+  }
+
+
+
+/**
+ * Functions on subviews.
+ */
+template<typename eT>
+inline
+SpMat<eT>::SpMat(const SpSubview<eT>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(NULL) // extra element added when mem_resize is called
+  , row_indices(NULL)
+  , col_ptrs(NULL)
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  (*this).operator=(X);
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator=(const SpSubview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword in_n_cols = X.n_cols;
+  const uword in_n_rows = X.n_rows;
+  
+  const bool alias = (this == &(X.m));
+
+  if(alias == false)
+    {
+    init(in_n_rows, in_n_cols);
+
+    const uword x_n_nonzero = X.n_nonzero;
+
+    mem_resize(x_n_nonzero);
+
+    typename SpSubview<eT>::const_iterator it = X.begin();
+
+    while(it != X.end())
+      {
+      access::rw(row_indices[it.pos()]) = it.row();
+      access::rw(values[it.pos()]) = (*it);
+      ++access::rw(col_ptrs[it.col() + 1]);
+      ++it;
+      }
+
+    // Now sum column pointers.
+    for(uword c = 1; c <= n_cols; ++c)
+      {
+      access::rw(col_ptrs[c]) += col_ptrs[c - 1];
+      }
+    }
+  else
+    {
+    // Create it in a temporary.
+    SpMat<eT> tmp(X);
+
+    steal_mem(tmp);
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator+=(const SpSubview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "addition");
+  
+  typename SpSubview<eT>::const_iterator it = X.begin();
+
+  while(it != X.end())
+    {
+    at(it.row(), it.col()) += (*it);
+    ++it;
+    }
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator-=(const SpSubview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "subtraction");
+  
+  typename SpSubview<eT>::const_iterator it = X.begin();
+  
+  while(it != X.end())
+    {
+    at(it.row(), it.col()) -= (*it);
+    ++it;
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator*=(const SpSubview<eT>& y)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_mul_size(n_rows, n_cols, y.n_rows, y.n_cols, "matrix multiplication");
+  
+  // Cannot be done in-place (easily).
+  SpMat<eT> z = (*this) * y;
+  steal_mem(z);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator%=(const SpSubview<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-wise multiplication");
+
+  iterator it = begin();
+  typename SpSubview<eT>::const_iterator xit = x.begin();
+
+  while((it != end()) || (xit != x.end()))
+    {
+    if((xit.row() == it.row()) && (xit.col() == it.col()))
+      {
+      (*it) *= (*xit);
+      ++it;
+      ++xit;
+      }
+    else
+      {
+      if((xit.col() > it.col()) || ((xit.col() == it.col()) && (xit.row() > it.row())))
+        {
+        // xit is "ahead"
+        (*it) = eT(0); // erase element; x has a zero here
+        it.internal_pos--; // update iterator so it still works
+        ++it;
+        }
+      else
+        {
+        // it is "ahead"
+        ++xit;
+        }
+      }
+    }
+
+  return *this;
+  }
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator/=(const SpSubview<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-wise division");
+  
+  // There is no pretty way to do this.
+  for(uword elem = 0; elem < n_elem; elem++)
+    {
+    at(elem) /= x(elem);
+    }
+  
+  return *this;
+  }
+
+
+
+/**
+ * Operators on regular subviews.
+ */
+template<typename eT>
+inline
+SpMat<eT>::SpMat(const subview<eT>& x)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(NULL) // extra value set in operator=()
+  , row_indices(NULL)
+  , col_ptrs(NULL)
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  (*this).operator=(x);
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator=(const subview<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword x_n_rows = x.n_rows;
+  const uword x_n_cols = x.n_cols;
+  
+  // Set the size correctly.
+  init(x_n_rows, x_n_cols);
+
+  // Count number of nonzero elements.
+  uword n = 0;
+  for(uword c = 0; c < x_n_cols; ++c)
+    {
+    for(uword r = 0; r < x_n_rows; ++r)
+      {
+      if(x.at(r, c) != eT(0))
+        {
+        ++n;
+        }
+      }
+    }
+
+  // Resize memory appropriately.
+  mem_resize(n);
+
+  n = 0;
+  for(uword c = 0; c < x_n_cols; ++c)
+    {
+    for(uword r = 0; r < x_n_rows; ++r)
+      {
+      const eT val = x.at(r, c);
+      
+      if(val != eT(0))
+        {
+        access::rw(values[n]) = val;
+        access::rw(row_indices[n]) = r;
+        ++access::rw(col_ptrs[c + 1]);
+        ++n;
+        }
+      }
+    }
+
+  // Fix column counts into column pointers.
+  for(uword c = 1; c <= n_cols; ++c)
+    {
+    access::rw(col_ptrs[c]) += col_ptrs[c - 1];
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator+=(const subview<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "addition");
+  
+  // Loop over every element.  This could probably be written in a more
+  // efficient way, by calculating the number of nonzero elements the output
+  // matrix will have, allocating the memory correctly, and then filling the
+  // matrix correctly.  However... for now, this works okay.
+  for(uword lcol = 0; lcol < n_cols; ++lcol)
+  for(uword lrow = 0; lrow < n_rows; ++lrow)
+    {
+    at(lrow, lcol) += x.at(lrow, lcol);
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator-=(const subview<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "subtraction");
+  
+  // Loop over every element.
+  for(uword lcol = 0; lcol < n_cols; ++lcol)
+  for(uword lrow = 0; lrow < n_rows; ++lrow)
+    {
+    at(lrow, lcol) -= x.at(lrow, lcol);
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator*=(const subview<eT>& y)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_assert_mul_size(n_rows, n_cols, y.n_rows, y.n_cols, "matrix multiplication");
+
+  SpMat<eT> z(n_rows, y.n_cols);
+
+  // Performed in the same fashion as operator*=(SpMat).
+  for (const_row_iterator x_row_it = begin_row(); x_row_it.pos() < n_nonzero; ++x_row_it)
+    {
+    for (uword lcol = 0; lcol < y.n_cols; ++lcol)
+      {
+      // At this moment in the loop, we are calculating anything that is contributed to by *x_row_it and *y_col_it.
+      // Given that our position is x_ab and y_bc, there will only be a contribution if x.col == y.row, and that
+      // contribution will be in location z_ac.
+      z.at(x_row_it.row, lcol) += (*x_row_it) * y.at(x_row_it.col, lcol);
+      }
+    }
+
+  steal_mem(z);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator%=(const subview<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-wise multiplication");
+  
+  // Loop over every element.
+  for(uword lcol = 0; lcol < n_cols; ++lcol)
+  for(uword lrow = 0; lrow < n_rows; ++lrow)
+    {
+    at(lrow, lcol) *= x.at(lrow, lcol);
+    }
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator/=(const subview<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-wise division");
+  
+  // Loop over every element.
+  for(uword lcol = 0; lcol < n_cols; ++lcol)
+  for(uword lrow = 0; lrow < n_rows; ++lrow)
+    {
+    at(lrow, lcol) /= x.at(lrow, lcol);
+    }
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+SpMat<eT>::SpMat(const SpOp<T1, spop_type>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(NULL) // set in application of sparse operation
+  , row_indices(NULL)
+  , col_ptrs(NULL)
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  spop_type::apply(*this, X);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator=(const SpOp<T1, spop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  spop_type::apply(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator+=(const SpOp<T1, spop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const SpMat<eT> m(X);
+  
+  return (*this).operator+=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator-=(const SpOp<T1, spop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const SpMat<eT> m(X);
+  
+  return (*this).operator-=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator*=(const SpOp<T1, spop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const SpMat<eT> m(X);
+  
+  return (*this).operator*=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator%=(const SpOp<T1, spop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const SpMat<eT> m(X);
+  
+  return (*this).operator%=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator/=(const SpOp<T1, spop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const SpMat<eT> m(X);
+  
+  return (*this).operator/=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2, typename spglue_type>
+inline
+SpMat<eT>::SpMat(const SpGlue<T1, T2, spglue_type>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(NULL) // extra element set in application of sparse glue
+  , row_indices(NULL)
+  , col_ptrs(NULL)
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  spglue_type::apply(*this, X);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+SpMat<eT>::SpMat(const mtSpOp<eT, T1, spop_type>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , n_nonzero(0)
+  , vec_state(0)
+  , values(NULL) // extra element set in application of sparse glue
+  , row_indices(NULL)
+  , col_ptrs(NULL)
+  {
+  arma_extra_debug_sigprint_this(this);
+
+  spop_type::apply(*this, X);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator=(const mtSpOp<eT, T1, spop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  spop_type::apply(*this, X);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator+=(const mtSpOp<eT, T1, spop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  const SpMat<eT> m(X);
+
+  return (*this).operator+=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator-=(const mtSpOp<eT, T1, spop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  const SpMat<eT> m(X);
+
+  return (*this).operator-=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator*=(const mtSpOp<eT, T1, spop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  const SpMat<eT> m(X);
+
+  return (*this).operator*=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator%=(const mtSpOp<eT, T1, spop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  const SpMat<eT> m(X);
+
+  return (*this).operator%=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename spop_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator/=(const mtSpOp<eT, T1, spop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  const SpMat<eT> m(X);
+
+  return (*this).operator/=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2, typename spglue_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator=(const SpGlue<T1, T2, spglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  spglue_type::apply(*this, X);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2, typename spglue_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator+=(const SpGlue<T1, T2, spglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const SpMat<eT> m(X);
+  
+  return (*this).operator+=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2, typename spglue_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator-=(const SpGlue<T1, T2, spglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const SpMat<eT> m(X);
+  
+  return (*this).operator-=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2, typename spglue_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator*=(const SpGlue<T1, T2, spglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const SpMat<eT> m(X);
+  
+  return (*this).operator*=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2, typename spglue_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator%=(const SpGlue<T1, T2, spglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const SpMat<eT> m(X);
+  
+  return (*this).operator%=(m);
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2, typename spglue_type>
+inline
+const SpMat<eT>&
+SpMat<eT>::operator/=(const SpGlue<T1, T2, spglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
+  
+  const SpMat<eT> m(X);
+  
+  return (*this).operator/=(m);
+  }
+
+
+
+template<typename eT>
+arma_inline
+SpSubview<eT>
+SpMat<eT>::row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check(row_num >= n_rows, "SpMat::row(): out of bounds");
+
+  return SpSubview<eT>(*this, row_num, 0, 1, n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const SpSubview<eT>
+SpMat<eT>::row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check(row_num >= n_rows, "SpMat::row(): out of bounds");
+
+  return SpSubview<eT>(*this, row_num, 0, 1, n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>
+SpMat<eT>::operator()(const uword row_num, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_cols = n_cols;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  arma_debug_check
+    (
+    (row_num >= n_rows)
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "SpMat::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return SpSubview<eT>(*this, row_num, in_col1, 1, submat_n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>
+SpMat<eT>::operator()(const uword row_num, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_cols = n_cols;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  arma_debug_check
+    (
+    (row_num >= n_rows)
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "SpMat::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return SpSubview<eT>(*this, row_num, in_col1, 1, submat_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+SpSubview<eT>
+SpMat<eT>::col(const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check(col_num >= n_cols, "SpMat::col(): out of bounds");
+
+  return SpSubview<eT>(*this, 0, col_num, n_rows, 1);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const SpSubview<eT>
+SpMat<eT>::col(const uword col_num) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check(col_num >= n_cols, "SpMat::col(): out of bounds");
+
+  return SpSubview<eT>(*this, 0, col_num, n_rows, 1);
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>
+SpMat<eT>::operator()(const span& row_span, const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  arma_debug_check
+    (
+    (col_num >= n_cols)
+    ||
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ,
+    "SpMat::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return SpSubview<eT>(*this, in_row1, col_num, submat_n_rows, 1);
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>
+SpMat<eT>::operator()(const span& row_span, const uword col_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  arma_debug_check
+    (
+    (col_num >= n_cols)
+    ||
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ,
+    "SpMat::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return SpSubview<eT>(*this, in_row1, col_num, submat_n_rows, 1);
+  }
+
+
+
+/**
+ * Swap in_row1 with in_row2.
+ */
+template<typename eT>
+inline
+void
+SpMat<eT>::swap_rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_row1 >= n_rows) || (in_row2 >= n_rows),
+    "SpMat::swap_rows(): out of bounds"
+    );
+
+  // Sanity check.
+  if (in_row1 == in_row2)
+    {
+    return;
+    }
+
+  // The easier way to do this, instead of collecting all the elements in one row and then swapping with the other, will be
+  // to iterate over each column of the matrix (since we store in column-major format) and then swap the two elements in the two rows at that time.
+  // We will try to avoid using the at() call since it is expensive, instead preferring to use an iterator to track our position.
+  uword col1 = (in_row1 < in_row2) ? in_row1 : in_row2;
+  uword col2 = (in_row1 < in_row2) ? in_row2 : in_row1;
+
+  for (uword lcol = 0; lcol < n_cols; lcol++)
+    {
+    // If there is nothing in this column we can ignore it.
+    if (col_ptrs[lcol] == col_ptrs[lcol + 1])
+      {
+      continue;
+      }
+
+    // These will represent the positions of the items themselves.
+    uword loc1 = n_nonzero + 1;
+    uword loc2 = n_nonzero + 1;
+
+    for (uword search_pos = col_ptrs[lcol]; search_pos < col_ptrs[lcol + 1]; search_pos++)
+      {
+      if (row_indices[search_pos] == col1)
+        {
+        loc1 = search_pos;
+        }
+
+      if (row_indices[search_pos] == col2)
+        {
+        loc2 = search_pos;
+        break; // No need to look any further.
+        }
+      }
+
+    // There are four cases: we found both elements; we found one element (loc1); we found one element (loc2); we found zero elements.
+    // If we found zero elements no work needs to be done and we can continue to the next column.
+    if ((loc1 != (n_nonzero + 1)) && (loc2 != (n_nonzero + 1)))
+      {
+      // This is an easy case: just swap the values.  No index modifying necessary.
+      eT tmp = values[loc1];
+      access::rw(values[loc1]) = values[loc2];
+      access::rw(values[loc2]) = tmp;
+      }
+    else if (loc1 != (n_nonzero + 1)) // We only found loc1 and not loc2.
+      {
+      // We need to find the correct place to move our value to.  It will be forward (not backwards) because in_row2 > in_row1.
+      // Each iteration of the loop swaps the current value (loc1) with (loc1 + 1); in this manner we move our value down to where it should be.
+      while (((loc1 + 1) < col_ptrs[lcol + 1]) && (row_indices[loc1 + 1] < in_row2))
+        {
+        // Swap both the values and the indices.  The column should not change.
+        eT tmp = values[loc1];
+        access::rw(values[loc1]) = values[loc1 + 1];
+        access::rw(values[loc1 + 1]) = tmp;
+
+        uword tmp_index = row_indices[loc1];
+        access::rw(row_indices[loc1]) = row_indices[loc1 + 1];
+        access::rw(row_indices[loc1 + 1]) = tmp_index;
+
+        loc1++; // And increment the counter.
+        }
+
+      // Now set the row index correctly.
+      access::rw(row_indices[loc1]) = in_row2;
+
+      }
+    else if (loc2 != (n_nonzero + 1))
+      {
+      // We need to find the correct place to move our value to.  It will be backwards (not forwards) because in_row1 < in_row2.
+      // Each iteration of the loop swaps the current value (loc2) with (loc2 - 1); in this manner we move our value up to where it should be.
+      while (((loc2 - 1) >= col_ptrs[lcol]) && (row_indices[loc2 - 1] > in_row1))
+        {
+        // Swap both the values and the indices.  The column should not change.
+        eT tmp = values[loc2];
+        access::rw(values[loc2]) = values[loc2 - 1];
+        access::rw(values[loc2 - 1]) = tmp;
+
+        uword tmp_index = row_indices[loc2];
+        access::rw(row_indices[loc2]) = row_indices[loc2 - 1];
+        access::rw(row_indices[loc2 - 1]) = tmp_index;
+
+        loc2--; // And decrement the counter.
+        }
+
+      // Now set the row index correctly.
+      access::rw(row_indices[loc2]) = in_row1;
+
+      }
+    /* else: no need to swap anything; both values are zero */
+    }
+  }
+
+/**
+ * Swap in_col1 with in_col2.
+ */
+template<typename eT>
+inline
+void
+SpMat<eT>::swap_cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+
+  // slow but works
+  for(uword lrow = 0; lrow < n_rows; ++lrow)
+    {
+    eT tmp = at(lrow, in_col1);
+    at(lrow, in_col1) = at(lrow, in_col2);
+    at(lrow, in_col2) = tmp;
+    }
+  }
+
+/**
+ * Remove the row row_num.
+ */
+template<typename eT>
+inline
+void
+SpMat<eT>::shed_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  arma_debug_check (row_num >= n_rows, "SpMat::shed_row(): out of bounds");
+
+  shed_rows (row_num, row_num);
+  }
+
+/**
+ * Remove the column col_num.
+ */
+template<typename eT>
+inline
+void
+SpMat<eT>::shed_col(const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  arma_debug_check (col_num >= n_cols, "SpMat::shed_col(): out of bounds");
+
+  shed_cols(col_num, col_num);
+  }
+
+/**
+ * Remove all rows between (and including) in_row1 and in_row2.
+ */
+template<typename eT>
+inline
+void
+SpMat<eT>::shed_rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_row2 >= n_rows),
+    "SpMat::shed_rows(): indices out of bounds or incorectly used"
+    );
+
+  uword i, j;
+  // Store the length of values
+  uword vlength = n_nonzero;
+  // Store the length of col_ptrs
+  uword clength = n_cols + 1;
+
+  // This is O(n * n_cols) and inplace, there may be a faster way, though.
+  for (i = 0, j = 0; i < vlength; ++i)
+    {
+    // Store the row of the ith element.
+    const uword lrow = row_indices[i];
+    // Is the ith element in the range of rows we want to remove?
+    if (lrow >= in_row1 && lrow <= in_row2)
+      {
+      // Increment our "removed elements" counter.
+      ++j;
+
+      // Adjust the values of col_ptrs each time we remove an element.
+      // Basically, the length of one column reduces by one, and everything to
+      // its right gets reduced by one to represent all the elements being
+      // shifted to the left by one.
+      for(uword k = 0; k < clength; ++k)
+        {
+        if (col_ptrs[k] > (i - j + 1))
+          {
+          --access::rw(col_ptrs[k]);
+          }
+        }
+      }
+    else
+      {
+      // We shift the element we checked to the left by how many elements
+      // we have removed.
+      // j = 0 until we remove the first element.
+      if (j != 0)
+        {
+        access::rw(row_indices[i - j]) = (lrow > in_row2) ? (lrow - (in_row2 - in_row1 + 1)) : lrow;
+        access::rw(values[i - j]) = values[i];
+        }
+      }
+    }
+
+  // j is the number of elements removed.
+
+  // Shrink the vectors.  This will copy the memory.
+  mem_resize(n_nonzero - j);
+
+  // Adjust row and element counts.
+  access::rw(n_rows)    = n_rows - (in_row2 - in_row1) - 1;
+  access::rw(n_elem)    = n_rows * n_cols;
+  }
+
+/**
+ * Remove all columns between (and including) in_col1 and in_col2.
+ */
+template<typename eT>
+inline
+void
+SpMat<eT>::shed_cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_col1 > in_col2) || (in_col2 >= n_cols),
+    "SpMat::shed_cols(): indices out of bounds or incorrectly used"
+    );
+
+  // First we find the locations in values and row_indices for the column entries.
+  uword col_beg = col_ptrs[in_col1];
+  uword col_end = col_ptrs[in_col2 + 1];
+
+  // Then we find the number of entries in the column.
+  uword diff = col_end - col_beg;
+
+  if (diff > 0)
+    {
+    eT*    new_values      = memory::acquire_chunked<eT>   (n_nonzero - diff);
+    uword* new_row_indices = memory::acquire_chunked<uword>(n_nonzero - diff);
+
+    // Copy first part.
+    if (col_beg != 0)
+      {
+      arrayops::copy(new_values, values, col_beg);
+      arrayops::copy(new_row_indices, row_indices, col_beg);
+      }
+
+    // Copy second part.
+    if (col_end != n_nonzero)
+      {
+      arrayops::copy(new_values + col_beg, values + col_end, n_nonzero - col_end);
+      arrayops::copy(new_row_indices + col_beg, row_indices + col_end, n_nonzero - col_end);
+      }
+
+    memory::release(values);
+    memory::release(row_indices);
+
+    access::rw(values)      = new_values;
+    access::rw(row_indices) = new_row_indices;
+
+    // Update counts and such.
+    access::rw(n_nonzero) -= diff;
+    }
+  
+  // Update column pointers.
+  const uword new_n_cols = n_cols - ((in_col2 - in_col1) + 1);
+  
+  uword* new_col_ptrs = memory::acquire<uword>(new_n_cols + 2);
+  new_col_ptrs[new_n_cols + 1] = std::numeric_limits<uword>::max();
+  
+  // Copy first set of columns (no manipulation required).
+  if (in_col1 != 0)
+    {
+    arrayops::copy(new_col_ptrs, col_ptrs, in_col1);
+    }
+  
+  // Copy second set of columns (manipulation required).
+  uword cur_col = in_col1;
+  for (uword i = in_col2 + 1; i <= n_cols; ++i, ++cur_col)
+    {
+    new_col_ptrs[cur_col] = col_ptrs[i] - diff;
+    }
+  
+  memory::release(col_ptrs);
+  access::rw(col_ptrs) = new_col_ptrs;
+  
+  // We update the element and column counts, and we're done.
+  access::rw(n_cols) = new_n_cols;
+  access::rw(n_elem) = n_cols * n_rows;
+  }
+
+
+
+template<typename eT>
+arma_inline
+SpSubview<eT>
+SpMat<eT>::rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_row2 >= n_rows),
+    "SpMat::rows(): indices out of bounds or incorrectly used"
+    );
+
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+
+  return SpSubview<eT>(*this, in_row1, 0, subview_n_rows, n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const SpSubview<eT>
+SpMat<eT>::rows(const uword in_row1, const uword in_row2) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_row2 >= n_rows),
+    "SpMat::rows(): indices out of bounds or incorrectly used"
+    );
+
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+
+  return SpSubview<eT>(*this, in_row1, 0, subview_n_rows, n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+SpSubview<eT>
+SpMat<eT>::cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_col1 > in_col2) || (in_col2 >= n_cols),
+    "SpMat::cols(): indices out of bounds or incorrectly used"
+    );
+
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+
+  return SpSubview<eT>(*this, 0, in_col1, n_rows, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const SpSubview<eT>
+SpMat<eT>::cols(const uword in_col1, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_col1 > in_col2) || (in_col2 >= n_cols),
+    "SpMat::cols(): indices out of bounds or incorrectly used"
+    );
+
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+
+  return SpSubview<eT>(*this, 0, in_col1, n_rows, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+SpSubview<eT>
+SpMat<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
+    "SpMat::submat(): indices out of bounds or incorrectly used"
+    );
+
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+
+  return SpSubview<eT>(*this, in_row1, in_col1, subview_n_rows, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const SpSubview<eT>
+SpMat<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
+    "SpMat::submat(): indices out of bounds or incorrectly used"
+    );
+
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+
+  return SpSubview<eT>(*this, in_row1, in_col1, subview_n_rows, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>
+SpMat<eT>::submat    (const span& row_span, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+
+  const bool row_all = row_span.whole;
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  const uword local_n_cols = n_cols;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; 
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; 
+  
+  arma_debug_check
+    (    
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ||   
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,    
+    "SpMat::submat(): indices out of bounds or incorrectly used"
+    );   
+  
+  return SpSubview<eT>(*this, in_row1, in_col1, submat_n_rows, submat_n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>
+SpMat<eT>::submat    (const span& row_span, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+
+  const bool row_all = row_span.whole;
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  const uword local_n_cols = n_cols;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; 
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; 
+  
+  arma_debug_check
+    (    
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ||   
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,    
+    "SpMat::submat(): indices out of bounds or incorrectly used"
+    );   
+  
+  return SpSubview<eT>(*this, in_row1, in_col1, submat_n_rows, submat_n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>
+SpMat<eT>::operator()(const span& row_span, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+
+  return submat(row_span, col_span);
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>
+SpMat<eT>::operator()(const span& row_span, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+
+  return submat(row_span, col_span);
+  }
+
+
+
+/**
+ * Element access; acces the i'th element (works identically to the Mat accessors).
+ * If there is nothing at element i, 0 is returned.
+ *
+ * @param i Element to access.
+ */
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+SpValProxy<SpMat<eT> >
+SpMat<eT>::operator[](const uword i)
+  {
+  return get_value(i);
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT
+SpMat<eT>::operator[](const uword i) const
+  {
+  return get_value(i);
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+SpValProxy<SpMat<eT> >
+SpMat<eT>::at(const uword i)
+  {
+  return get_value(i);
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT
+SpMat<eT>::at(const uword i) const
+  {
+  return get_value(i);
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+SpValProxy<SpMat<eT> >
+SpMat<eT>::operator()(const uword i)
+  {
+  arma_debug_check( (i >= n_elem), "SpMat::operator(): out of bounds");
+  return get_value(i);
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT
+SpMat<eT>::operator()(const uword i) const
+  {
+  arma_debug_check( (i >= n_elem), "SpMat::operator(): out of bounds");
+  return get_value(i);
+  }
+
+
+
+/**
+ * Element access; access the element at row in_rows and column in_col.
+ * If there is nothing at that position, 0 is returned.
+ */
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+SpValProxy<SpMat<eT> >
+SpMat<eT>::at(const uword in_row, const uword in_col)
+  {
+  return get_value(in_row, in_col);
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT
+SpMat<eT>::at(const uword in_row, const uword in_col) const
+  {
+  return get_value(in_row, in_col);
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+SpValProxy<SpMat<eT> >
+SpMat<eT>::operator()(const uword in_row, const uword in_col)
+  {
+  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "SpMat::operator(): out of bounds");
+  return get_value(in_row, in_col);
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+eT
+SpMat<eT>::operator()(const uword in_row, const uword in_col) const
+  {
+  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "SpMat::operator(): out of bounds");
+  return get_value(in_row, in_col);
+  }
+
+
+
+/**
+ * Check if matrix is empty (no size, no values).
+ */
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+SpMat<eT>::is_empty() const
+  {
+  return(n_elem == 0);
+  }
+
+
+
+//! returns true if the object can be interpreted as a column or row vector
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+SpMat<eT>::is_vec() const
+  {
+  return ( (n_rows == 1) || (n_cols == 1) );
+  }
+
+
+
+//! returns true if the object can be interpreted as a row vector
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+SpMat<eT>::is_rowvec() const
+  {
+  return (n_rows == 1);
+  }
+
+
+
+//! returns true if the object can be interpreted as a column vector
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+SpMat<eT>::is_colvec() const
+  {
+  return (n_cols == 1);
+  }
+
+
+
+//! returns true if the object has the same number of non-zero rows and columnns
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+SpMat<eT>::is_square() const
+  {
+  return (n_rows == n_cols);
+  }
+
+
+
+//! returns true if all of the elements are finite
+template<typename eT>
+inline
+arma_warn_unused
+bool
+SpMat<eT>::is_finite() const
+  {
+  for(uword i = 0; i < n_nonzero; i++)
+    {
+    if(arma_isfinite(values[i]) == false)
+      {
+      return false;
+      }
+    }
+
+  return true; // No infinite values.
+  }
+
+
+
+//! returns true if the given index is currently in range
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+SpMat<eT>::in_range(const uword i) const
+  {
+  return (i < n_elem);
+  }
+
+
+//! returns true if the given start and end indices are currently in range
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+SpMat<eT>::in_range(const span& x) const
+  {
+  arma_extra_debug_sigprint();
+
+  if(x.whole == true)
+    {
+    return true;
+    }
+  else
+    {
+    const uword a = x.a;
+    const uword b = x.b;
+
+    return ( (a <= b) && (b < n_elem) );
+    }
+  }
+
+
+
+//! returns true if the given location is currently in range
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+SpMat<eT>::in_range(const uword in_row, const uword in_col) const
+  {
+  return ( (in_row < n_rows) && (in_col < n_cols) );
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+SpMat<eT>::in_range(const span& row_span, const uword in_col) const
+  {
+  arma_extra_debug_sigprint();
+
+  if(row_span.whole == true)
+    {
+    return (in_col < n_cols);
+    }
+  else
+    {
+    const uword in_row1 = row_span.a;
+    const uword in_row2 = row_span.b;
+
+    return ( (in_row1 <= in_row2) && (in_row2 < n_rows) && (in_col < n_cols) );
+    }
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+SpMat<eT>::in_range(const uword in_row, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+
+  if(col_span.whole == true)
+    {
+    return (in_row < n_rows);
+    }
+  else
+    {
+    const uword in_col1 = col_span.a;
+    const uword in_col2 = col_span.b;
+
+    return ( (in_row < n_rows) && (in_col1 <= in_col2) && (in_col2 < n_cols) );
+    }
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+SpMat<eT>::in_range(const span& row_span, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+
+  const uword in_row1 = row_span.a;
+  const uword in_row2 = row_span.b;
+
+  const uword in_col1 = col_span.a;
+  const uword in_col2 = col_span.b;
+
+  const bool rows_ok = row_span.whole ? true : ( (in_row1 <= in_row2) && (in_row2 < n_rows) );
+  const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2) && (in_col2 < n_cols) );
+
+  return ( (rows_ok == true) && (cols_ok == true) );
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpMat<eT>::impl_print(const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width();
+
+    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
+
+    ARMA_DEFAULT_OSTREAM.width(orig_width);
+    }
+
+  arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, true);
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpMat<eT>::impl_print(std::ostream& user_stream, const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = user_stream.width();
+
+    user_stream << extra_text << '\n';
+
+    user_stream.width(orig_width);
+    }
+
+  arma_ostream::print(user_stream, *this, true);
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpMat<eT>::impl_raw_print(const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width();
+
+    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
+
+    ARMA_DEFAULT_OSTREAM.width(orig_width);
+    }
+
+  arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, false);
+  }
+
+
+template<typename eT>
+inline
+void
+SpMat<eT>::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = user_stream.width();
+
+    user_stream << extra_text << '\n';
+
+    user_stream.width(orig_width);
+    }
+
+  arma_ostream::print(user_stream, *this, false);
+  }
+
+
+
+/**
+ * Matrix printing, prepends supplied text.
+ * Prints 0 wherever no element exists.
+ */
+template<typename eT>
+inline
+void
+SpMat<eT>::impl_print_dense(const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width();
+
+    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
+
+    ARMA_DEFAULT_OSTREAM.width(orig_width);
+    }
+
+  arma_ostream::print_dense(ARMA_DEFAULT_OSTREAM, *this, true);
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpMat<eT>::impl_print_dense(std::ostream& user_stream, const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = user_stream.width();
+
+    user_stream << extra_text << '\n';
+
+    user_stream.width(orig_width);
+    }
+
+  arma_ostream::print_dense(user_stream, *this, true);
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpMat<eT>::impl_raw_print_dense(const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width();
+
+    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
+
+    ARMA_DEFAULT_OSTREAM.width(orig_width);
+    }
+
+  arma_ostream::print_dense(ARMA_DEFAULT_OSTREAM, *this, false);
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpMat<eT>::impl_raw_print_dense(std::ostream& user_stream, const std::string& extra_text) const
+  {
+  arma_extra_debug_sigprint();
+
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = user_stream.width();
+
+    user_stream << extra_text << '\n';
+
+    user_stream.width(orig_width);
+    }
+
+  arma_ostream::print_dense(user_stream, *this, false);
+  }
+
+
+
+//! Set the size to the size of another matrix.
+template<typename eT>
+template<typename eT2>
+inline
+void
+SpMat<eT>::copy_size(const SpMat<eT2>& m)
+  {
+  arma_extra_debug_sigprint();
+
+  init(m.n_rows, m.n_cols);
+  }
+
+
+
+template<typename eT>
+template<typename eT2>
+inline
+void
+SpMat<eT>::copy_size(const Mat<eT2>& m)
+  {
+  arma_extra_debug_sigprint();
+
+  init(m.n_rows, m.n_cols);
+  }
+
+
+
+/**
+ * Resize the matrix to a given size.  The matrix will be resized to be a column vector (i.e. in_elem columns, 1 row).
+ *
+ * @param in_elem Number of elements to allow.
+ */
+template<typename eT>
+inline
+void
+SpMat<eT>::set_size(const uword in_elem)
+  {
+  arma_extra_debug_sigprint();
+
+  // If this is a row vector, we resize to a row vector.
+  if(vec_state == 2)
+    {
+    init(1, in_elem);
+    }
+  else
+    {
+    init(in_elem, 1);
+    }
+  }
+
+
+
+/**
+ * Resize the matrix to a given size.
+ *
+ * @param in_rows Number of rows to allow.
+ * @param in_cols Number of columns to allow.
+ */
+template<typename eT>
+inline
+void
+SpMat<eT>::set_size(const uword in_rows, const uword in_cols)
+  {
+  arma_extra_debug_sigprint();
+
+  init(in_rows, in_cols);
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpMat<eT>::reshape(const uword in_rows, const uword in_cols, const uword dim)
+  {
+  arma_extra_debug_sigprint();
+
+  if (dim == 0)
+    {
+    // We have to modify all of the relevant row indices and the relevant column pointers.
+    // Iterate over all the points to do this.  We won't be deleting any points, but we will be modifying
+    // columns and rows. We'll have to store a new set of column vectors.
+    uword* new_col_ptrs    = memory::acquire<uword>(in_cols + 2);
+    new_col_ptrs[in_cols + 1] = std::numeric_limits<uword>::max();
+    
+    uword* new_row_indices = memory::acquire_chunked<uword>(n_nonzero + 1);
+    access::rw(new_row_indices[n_nonzero]) = 0;
+
+    arrayops::inplace_set(new_col_ptrs, uword(0), in_cols + 1);
+
+    for(const_iterator it = begin(); it != end(); it++)
+      {
+      uword vector_position = (it.col() * n_rows) + it.row();
+      new_row_indices[it.pos()] = vector_position % in_rows;
+      ++new_col_ptrs[vector_position / in_rows + 1];
+      }
+
+    // Now sum the column counts to get the new column pointers.
+    for(uword i = 1; i <= in_cols; i++)
+      {
+      access::rw(new_col_ptrs[i]) += new_col_ptrs[i - 1];
+      }
+
+    // Copy the new row indices.
+    memory::release(row_indices);
+    access::rw(row_indices) = new_row_indices;
+
+    memory::release(col_ptrs);
+    access::rw(col_ptrs) = new_col_ptrs;
+
+    // Now set the size.
+    access::rw(n_rows) = in_rows;
+    access::rw(n_cols) = in_cols;
+    }
+  else
+    {
+    // Row-wise reshaping.  This is more tedious and we will use a separate sparse matrix to do it.
+    SpMat<eT> tmp(in_rows, in_cols);
+
+    for(const_row_iterator it = begin_row(); it.pos() < n_nonzero; it++)
+      {
+      uword vector_position = (it.row() * n_cols) + it.col();
+
+      tmp((vector_position / in_cols), (vector_position % in_cols)) = (*it);
+      }
+
+    (*this).operator=(tmp);
+    }
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::zeros()
+  {
+  arma_extra_debug_sigprint();
+
+  if (n_nonzero > 0)
+    {
+    memory::release(values);
+    memory::release(row_indices);
+
+    access::rw(values)      = memory::acquire_chunked<eT>(1);
+    access::rw(row_indices) = memory::acquire_chunked<uword>(1);
+
+    access::rw(values[0]) = 0;
+    access::rw(row_indices[0]) = 0;
+    }
+
+  access::rw(n_nonzero) = 0;
+  arrayops::inplace_set(access::rwp(col_ptrs), uword(0), n_cols + 1);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::zeros(const uword in_elem)
+  {
+  arma_extra_debug_sigprint();
+
+  if(vec_state == 2)
+    {
+    init(1, in_elem); // Row vector
+    }
+  else
+    {
+    init(in_elem, 1);
+    }
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::zeros(const uword in_rows, const uword in_cols)
+  {
+  arma_extra_debug_sigprint();
+
+  init(in_rows, in_cols);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::eye()
+  {
+  arma_extra_debug_sigprint();
+
+  return (*this).eye(n_rows, n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::eye(const uword in_rows, const uword in_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword N = (std::min)(in_rows, in_cols);
+  
+  init(in_rows, in_cols);
+  
+  mem_resize(N);
+  
+  arrayops::inplace_set(access::rwp(values), eT(1), N);
+  
+  for(uword i = 0; i <  N; ++i) { access::rw(row_indices[i]) = i; }
+  
+  for(uword i = 0; i <= N; ++i) { access::rw(col_ptrs[i])    = i; }
+  
+  access::rw(n_nonzero) = N;
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::speye()
+  {
+  arma_extra_debug_sigprint();
+
+  return (*this).eye(n_rows, n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::speye(const uword in_n_rows, const uword in_n_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).eye(in_n_rows, in_n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::sprandu(const uword in_rows, const uword in_cols, const double density)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (density < double(0)) || (density > double(1)) ), "sprandu(): density must be in the [0,1] interval" );
+  
+  zeros(in_rows, in_cols);
+  
+  mem_resize( uword(density * double(in_rows) * double(in_cols) + 0.5) );
+  
+  if(n_nonzero == 0)
+    {
+    return *this;
+    }
+  
+  eop_aux_randu<eT>::fill( access::rwp(values), n_nonzero );
+  
+  uvec indices = linspace<uvec>( 0u, in_rows*in_cols-1, n_nonzero );
+  
+  // perturb the indices
+  for(uword i=1; i < n_nonzero-1; ++i)
+    {
+    const uword index_left  = indices[i-1];
+    const uword index_right = indices[i+1];
+    
+    const uword center = (index_left + index_right) / 2;
+    
+    const uword delta1 = center      - index_left - 1;
+    const uword delta2 = index_right - center     - 1;
+    
+    const uword min_delta = (std::min)(delta1, delta2);
+    
+    uword index_new = uword( double(center) + double(min_delta) * (2.0*randu()-1.0) );
+    
+    // paranoia, but better be safe than sorry
+    if( (index_left < index_new) && (index_new < index_right) )
+      {
+      indices[i] = index_new;
+      }
+    }
+  
+  uword cur_index = 0;
+  uword count     = 0;  
+  
+  for(uword lcol = 0; lcol < in_cols; ++lcol)
+  for(uword lrow = 0; lrow < in_rows; ++lrow)
+    {
+    if(count == indices[cur_index])
+      {
+      access::rw(row_indices[cur_index]) = lrow;
+      access::rw(col_ptrs[lcol + 1])++;
+      ++cur_index;
+      }
+    
+    ++count;
+    }
+  
+  if(cur_index != n_nonzero)
+    {
+    // Fix size to correct size.
+    mem_resize(cur_index);
+    }
+  
+  // Sum column pointers.
+  for(uword lcol = 1; lcol <= in_cols; ++lcol)
+    {
+    access::rw(col_ptrs[lcol]) += col_ptrs[lcol - 1];
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpMat<eT>&
+SpMat<eT>::sprandn(const uword in_rows, const uword in_cols, const double density)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (density < double(0)) || (density > double(1)) ), "sprandn(): density must be in the [0,1] interval" );
+  
+  zeros(in_rows, in_cols);
+  
+  mem_resize( uword(density * double(in_rows) * double(in_cols) + 0.5) );
+  
+  if(n_nonzero == 0)
+    {
+    return *this;
+    }
+  
+  eop_aux_randn<eT>::fill( access::rwp(values), n_nonzero );
+  
+  uvec indices = linspace<uvec>( 0u, in_rows*in_cols-1, n_nonzero );
+  
+  // perturb the indices
+  for(uword i=1; i < n_nonzero-1; ++i)
+    {
+    const uword index_left  = indices[i-1];
+    const uword index_right = indices[i+1];
+    
+    const uword center = (index_left + index_right) / 2;
+    
+    const uword delta1 = center      - index_left - 1;
+    const uword delta2 = index_right - center     - 1;
+    
+    const uword min_delta = (std::min)(delta1, delta2);
+    
+    uword index_new = uword( double(center) + double(min_delta) * (2.0*randu()-1.0) );
+    
+    // paranoia, but better be safe than sorry
+    if( (index_left < index_new) && (index_new < index_right) )
+      {
+      indices[i] = index_new;
+      }
+    }
+  
+  uword cur_index = 0;
+  uword count     = 0;  
+  
+  for(uword lcol = 0; lcol < in_cols; ++lcol)
+  for(uword lrow = 0; lrow < in_rows; ++lrow)
+    {
+    if(count == indices[cur_index])
+      {
+      access::rw(row_indices[cur_index]) = lrow;
+      access::rw(col_ptrs[lcol + 1])++;
+      ++cur_index;
+      }
+    
+    ++count;
+    }
+  
+  if(cur_index != n_nonzero)
+    {
+    // Fix size to correct size.
+    mem_resize(cur_index);
+    }
+  
+  // Sum column pointers.
+  for(uword lcol = 1; lcol <= in_cols; ++lcol)
+    {
+    access::rw(col_ptrs[lcol]) += col_ptrs[lcol - 1];
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpMat<eT>::reset()
+  {
+  arma_extra_debug_sigprint();
+
+  set_size(0, 0);
+  }
+
+
+
+/**
+ * Get the minimum or the maximum of the matrix.
+ */
+template<typename eT>
+inline
+arma_warn_unused
+eT
+SpMat<eT>::min() const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check((n_elem == 0), "min(): object has no elements");
+
+  if (n_nonzero == 0)
+    {
+    return 0;
+    }
+
+  eT val = op_min::direct_min(values, n_nonzero);
+
+  if ((val > 0) && (n_nonzero < n_elem)) // A sparse 0 is less.
+    {
+    val = 0;
+    }
+
+  return val;
+  }
+
+
+
+template<typename eT>
+inline
+eT
+SpMat<eT>::min(uword& index_of_min_val) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check((n_elem == 0), "min(): object has no elements");
+
+  eT val = 0;
+
+  if (n_nonzero == 0) // There are no other elements.  It must be 0.
+    {
+    index_of_min_val = 0;
+    }
+  else
+    {
+    uword location;
+    val = op_min::direct_min(values, n_nonzero, location);
+
+    if ((val > 0) && (n_nonzero < n_elem)) // A sparse 0 is less.
+      {
+      val = 0;
+
+      // Give back the index to the first zero position.
+      index_of_min_val = 0;
+      while (get_position(index_of_min_val) == index_of_min_val) // An element exists at that position.
+        {
+        index_of_min_val++;
+        }
+
+      }
+    else
+      {
+      index_of_min_val = get_position(location);
+      }
+    }
+
+  return val;
+
+  }
+
+
+
+template<typename eT>
+inline
+eT
+SpMat<eT>::min(uword& row_of_min_val, uword& col_of_min_val) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check((n_elem == 0), "min(): object has no elements");
+
+  eT val = 0;
+
+  if (n_nonzero == 0) // There are no other elements.  It must be 0.
+    {
+    row_of_min_val = 0;
+    col_of_min_val = 0;
+    }
+  else
+    {
+    uword location;
+    val = op_min::direct_min(values, n_nonzero, location);
+
+    if ((val > 0) && (n_nonzero < n_elem)) // A sparse 0 is less.
+      {
+      val = 0;
+
+      location = 0;
+      while (get_position(location) == location) // An element exists at that position.
+        {
+        location++;
+        }
+
+      row_of_min_val = location % n_rows;
+      col_of_min_val = location / n_rows;
+      }
+    else
+      {
+      get_position(location, row_of_min_val, col_of_min_val);
+      }
+    }
+
+  return val;
+
+  }
+
+
+
+template<typename eT>
+inline
+arma_warn_unused
+eT
+SpMat<eT>::max() const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check((n_elem == 0), "max(): object has no elements");
+
+  if (n_nonzero == 0)
+    {
+    return 0;
+    }
+
+  eT val = op_max::direct_max(values, n_nonzero);
+
+  if ((val < 0) && (n_nonzero < n_elem)) // A sparse 0 is more.
+    {
+    return 0;
+    }
+
+  return val;
+
+  }
+
+
+
+template<typename eT>
+inline
+eT
+SpMat<eT>::max(uword& index_of_max_val) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check((n_elem == 0), "max(): object has no elements");
+
+  eT val = 0;
+
+  if (n_nonzero == 0)
+    {
+    index_of_max_val = 0;
+    }
+  else
+    {
+    uword location;
+    val = op_max::direct_max(values, n_nonzero, location);
+
+    if ((val < 0) && (n_nonzero < n_elem)) // A sparse 0 is more.
+      {
+      val = 0;
+
+      location = 0;
+      while (get_position(location) == location) // An element exists at that position.
+        {
+        location++;
+        }
+
+      }
+    else
+      {
+      index_of_max_val = get_position(location);
+      }
+
+    }
+
+  return val;
+
+  }
+
+
+
+template<typename eT>
+inline
+eT
+SpMat<eT>::max(uword& row_of_max_val, uword& col_of_max_val) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check((n_elem == 0), "max(): object has no elements");
+
+  eT val = 0;
+
+  if (n_nonzero == 0)
+    {
+    row_of_max_val = 0;
+    col_of_max_val = 0;
+    }
+  else
+    {
+    uword location;
+    val = op_max::direct_max(values, n_nonzero, location);
+
+    if ((val < 0) && (n_nonzero < n_elem)) // A sparse 0 is more.
+      {
+      val = 0;
+
+      location = 0;
+      while (get_position(location) == location) // An element exists at that position.
+        {
+        location++;
+        }
+
+      row_of_max_val = location % n_rows;
+      col_of_max_val = location / n_rows;
+
+      }
+    else
+      {
+      get_position(location, row_of_max_val, col_of_max_val);
+      }
+
+    }
+
+  return val;
+
+  }
+
+
+
+//! save the matrix to a file
+template<typename eT>
+inline
+bool
+SpMat<eT>::save(const std::string name, const file_type type, const bool print_status) const
+  {
+  arma_extra_debug_sigprint();
+  
+  bool save_okay;
+  
+  switch(type)
+    {
+    // case raw_ascii:
+    //   save_okay = diskio::save_raw_ascii(*this, name);
+    //   break;
+    
+    // case csv_ascii:
+    //   save_okay = diskio::save_csv_ascii(*this, name);
+    //   break;
+    
+    case arma_binary:
+      save_okay = diskio::save_arma_binary(*this, name);
+      break;
+    
+    case coord_ascii:
+      save_okay = diskio::save_coord_ascii(*this, name);
+      break;
+    
+    default:
+      arma_warn(true, "SpMat::save(): unsupported file type");
+      save_okay = false;
+    }
+  
+  arma_warn( (save_okay == false), "SpMat::save(): couldn't write to ", name);
+  
+  return save_okay;
+  }
+
+
+
+//! save the matrix to a stream
+template<typename eT>
+inline
+bool
+SpMat<eT>::save(std::ostream& os, const file_type type, const bool print_status) const
+  {
+  arma_extra_debug_sigprint();
+  
+  bool save_okay;
+  
+  switch(type)
+    {
+    // case raw_ascii:
+    //   save_okay = diskio::save_raw_ascii(*this, os);
+    //   break;
+    
+    // case csv_ascii:
+    //   save_okay = diskio::save_csv_ascii(*this, os);
+    //   break;
+    
+    case arma_binary:
+      save_okay = diskio::save_arma_binary(*this, os);
+      break;
+    
+    case coord_ascii:
+      save_okay = diskio::save_coord_ascii(*this, os);
+      break;
+    
+    default:
+      arma_warn(true, "SpMat::save(): unsupported file type");
+      save_okay = false;
+    }
+  
+  arma_warn( (save_okay == false), "SpMat::save(): couldn't write to the given stream");
+  
+  return save_okay;
+  }
+
+
+
+//! load a matrix from a file
+template<typename eT>
+inline
+bool
+SpMat<eT>::load(const std::string name, const file_type type, const bool print_status)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay;
+  std::string err_msg;
+  
+  switch(type)
+    {
+    // case auto_detect:
+    //   load_okay = diskio::load_auto_detect(*this, name, err_msg);
+    //   break;
+    
+    // case raw_ascii:
+    //   load_okay = diskio::load_raw_ascii(*this, name, err_msg);
+    //   break;
+    
+    // case csv_ascii:
+    //   load_okay = diskio::load_csv_ascii(*this, name, err_msg);
+    //   break;
+    
+    case arma_binary:
+      load_okay = diskio::load_arma_binary(*this, name, err_msg);
+      break;
+    
+    case coord_ascii:
+      load_okay = diskio::load_coord_ascii(*this, name, err_msg);
+      break;
+    
+    default:
+      arma_warn(true, "SpMat::load(): unsupported file type");
+      load_okay = false;
+    }
+  
+  if(load_okay == false)
+    {
+    if(err_msg.length() > 0)
+      {
+      arma_warn(true, "SpMat::load(): ", err_msg, name);
+      }
+    else
+      {
+      arma_warn(true, "SpMat::load(): couldn't read ", name);
+      }
+    }
+  
+  if(load_okay == false)
+    {
+    (*this).reset();
+    }
+    
+  return load_okay;
+  }
+
+
+
+//! load a matrix from a stream
+template<typename eT>
+inline
+bool
+SpMat<eT>::load(std::istream& is, const file_type type, const bool print_status)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay;
+  std::string err_msg;
+  
+  switch(type)
+    {
+    // case auto_detect:
+    //   load_okay = diskio::load_auto_detect(*this, is, err_msg);
+    //   break;
+    
+    // case raw_ascii:
+    //   load_okay = diskio::load_raw_ascii(*this, is, err_msg);
+    //   break;
+    
+    // case csv_ascii:
+    //   load_okay = diskio::load_csv_ascii(*this, is, err_msg);
+    //   break;
+    
+    case arma_binary:
+      load_okay = diskio::load_arma_binary(*this, is, err_msg);
+      break;
+    
+    case coord_ascii:
+      load_okay = diskio::load_coord_ascii(*this, is, err_msg);
+      break;
+    
+    default:
+      arma_warn(true, "SpMat::load(): unsupported file type");
+      load_okay = false;
+    }
+  
+  
+  if(load_okay == false)
+    {
+    if(err_msg.length() > 0)
+      {
+      arma_warn(true, "SpMat::load(): ", err_msg, "the given stream");
+      }
+    else
+      {
+      arma_warn(true, "SpMat::load(): couldn't load from the given stream");
+      }
+    }
+  
+  if(load_okay == false)
+    {
+    (*this).reset();
+    }
+    
+  return load_okay;
+  }
+
+
+
+//! save the matrix to a file, without printing any error messages
+template<typename eT>
+inline
+bool
+SpMat<eT>::quiet_save(const std::string name, const file_type type) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).save(name, type, false);
+  }
+
+
+
+//! save the matrix to a stream, without printing any error messages
+template<typename eT>
+inline
+bool
+SpMat<eT>::quiet_save(std::ostream& os, const file_type type) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).save(os, type, false);
+  }
+
+
+
+//! load a matrix from a file, without printing any error messages
+template<typename eT>
+inline
+bool
+SpMat<eT>::quiet_load(const std::string name, const file_type type)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).load(name, type, false);
+  }
+
+
+
+//! load a matrix from a stream, without printing any error messages
+template<typename eT>
+inline
+bool
+SpMat<eT>::quiet_load(std::istream& is, const file_type type)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).load(is, type, false);
+  }
+
+
+
+/**
+ * Initialize the matrix to the specified size.  Data is not preserved, so the matrix is assumed to be entirely sparse (empty).
+ */
+template<typename eT>
+inline
+void
+SpMat<eT>::init(uword in_rows, uword in_cols)
+  {
+  arma_extra_debug_sigprint();
+
+  // Verify that we are allowed to do this.
+  if(vec_state > 0)
+    {
+    if((in_rows == 0) && (in_cols == 0))
+      {
+      if(vec_state == 1)
+        {
+        in_cols = 1;
+        }
+      else
+      if(vec_state == 2)
+        {
+        in_rows = 1;
+        }
+      }
+    else
+      {
+      arma_debug_check
+        (
+        ( ((vec_state == 1) && (in_cols != 1)) || ((vec_state == 2) && (in_rows != 1)) ),
+        "SpMat::init(): object is a row or column vector; requested size is not compatible"
+        );
+      }
+    }
+
+  // Ensure that n_elem can hold the result of (n_rows * n_cols)
+  arma_debug_check
+    (
+      (
+      ( (in_rows > ARMA_MAX_UHWORD) || (in_cols > ARMA_MAX_UHWORD) )
+        ? ( (float(in_rows) * float(in_cols)) > float(ARMA_MAX_UWORD) )
+        : false
+      ),
+      "SpMat::init(): requested size is too large"
+    );
+
+  // Clean out the existing memory.
+  if (values)
+    {
+    memory::release(values);
+    memory::release(row_indices);
+    }
+
+  access::rw(values)      = memory::acquire_chunked<eT>   (1);
+  access::rw(row_indices) = memory::acquire_chunked<uword>(1);
+
+  access::rw(values[0]) = 0;
+  access::rw(row_indices[0]) = 0;
+
+  memory::release(col_ptrs);
+
+  // Set the new size accordingly.
+  access::rw(n_rows)    = in_rows;
+  access::rw(n_cols)    = in_cols;
+  access::rw(n_elem)    = (in_rows * in_cols);
+  access::rw(n_nonzero) = 0;
+
+  // Try to allocate the column pointers, filling them with 0, except for the
+  // last element which contains the maximum possible element (so iterators
+  // terminate correctly).
+  access::rw(col_ptrs) = memory::acquire<uword>(in_cols + 2);
+  access::rw(col_ptrs[in_cols + 1]) = std::numeric_limits<uword>::max();
+  
+  arrayops::inplace_set(access::rwp(col_ptrs), uword(0), in_cols + 1);
+  }
+
+
+
+/**
+ * Initialize the matrix from a string.
+ */
+template<typename eT>
+inline
+void
+SpMat<eT>::init(const std::string& text)
+  {
+  arma_extra_debug_sigprint();
+
+  // Figure out the size first.
+  uword t_n_rows = 0;
+  uword t_n_cols = 0;
+
+  bool t_n_cols_found = false;
+
+  std::string token;
+
+  std::string::size_type line_start = 0;
+  std::string::size_type   line_end = 0;
+
+  while (line_start < text.length())
+    {
+
+    line_end = text.find(';', line_start);
+
+    if (line_end == std::string::npos)
+      line_end = text.length() - 1;
+
+    std::string::size_type line_len = line_end - line_start + 1;
+    std::stringstream line_stream(text.substr(line_start, line_len));
+
+    // Step through each column.
+    uword line_n_cols = 0;
+
+    while (line_stream >> token)
+      {
+      ++line_n_cols;
+      }
+
+    if (line_n_cols > 0)
+      {
+      if (t_n_cols_found == false)
+        {
+        t_n_cols = line_n_cols;
+        t_n_cols_found = true;
+        }
+      else // Check it each time through, just to make sure.
+        arma_check((line_n_cols != t_n_cols), "SpMat::init(): inconsistent number of columns in given string");
+
+      ++t_n_rows;
+      }
+
+    line_start = line_end + 1;
+
+    }
+
+  set_size(t_n_rows, t_n_cols);
+
+  // Second time through will pick up all the values.
+  line_start = 0;
+  line_end = 0;
+
+  uword lrow = 0;
+
+  while (line_start < text.length())
+    {
+
+    line_end = text.find(';', line_start);
+
+    if (line_end == std::string::npos)
+      line_end = text.length() - 1;
+
+    std::string::size_type line_len = line_end - line_start + 1;
+    std::stringstream line_stream(text.substr(line_start, line_len));
+
+    uword lcol = 0;
+    eT val;
+
+    while (line_stream >> val)
+      {
+      // Only add nonzero elements.
+      if (val != eT(0))
+        {
+        get_value(lrow, lcol) = val;
+        }
+
+      ++lcol;
+      }
+
+    ++lrow;
+    line_start = line_end + 1;
+
+    }
+
+  }
+
+/**
+ * Copy from another matrix.
+ */
+template<typename eT>
+inline
+void
+SpMat<eT>::init(const SpMat<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  // Ensure we are not initializing to ourselves.
+  if (this != &x)
+    {
+    init(x.n_rows, x.n_cols);
+
+    // values and row_indices may not be null.
+    if (values != NULL)
+      {
+      memory::release(values);
+      memory::release(row_indices);
+      }
+
+    access::rw(values)      = memory::acquire_chunked<eT>   (x.n_nonzero + 1);
+    access::rw(row_indices) = memory::acquire_chunked<uword>(x.n_nonzero + 1);
+
+    // Now copy over the elements.
+    arrayops::copy(access::rwp(values),      x.values,      x.n_nonzero + 1);
+    arrayops::copy(access::rwp(row_indices), x.row_indices, x.n_nonzero + 1);
+    arrayops::copy(access::rwp(col_ptrs),    x.col_ptrs,    x.n_cols + 1);
+    
+    access::rw(n_nonzero) = x.n_nonzero;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpMat<eT>::mem_resize(const uword new_n_nonzero)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(n_nonzero != new_n_nonzero)
+    {
+    if(new_n_nonzero == 0)
+      {
+      memory::release(values);
+      memory::release(row_indices);
+      
+      access::rw(values)      = memory::acquire_chunked<eT>   (1);
+      access::rw(row_indices) = memory::acquire_chunked<uword>(1);
+
+      access::rw(values[0]) = 0;
+      access::rw(row_indices[0]) = 0;
+      }
+    else
+      {
+      // Figure out the actual amount of memory currently allocated
+      // NOTE: this relies on memory::acquire_chunked() being used for the 'values' and 'row_indices' arrays
+      const uword n_alloc = memory::enlarge_to_mult_of_chunksize(n_nonzero);
+      
+      if(n_alloc < new_n_nonzero)
+        {
+        eT*    new_values      = memory::acquire_chunked<eT>   (new_n_nonzero + 1);
+        uword* new_row_indices = memory::acquire_chunked<uword>(new_n_nonzero + 1);
+        
+        if(n_nonzero > 0)
+          {
+          // Copy old elements.
+          uword copy_len = std::min(n_nonzero, new_n_nonzero);
+          
+          arrayops::copy(new_values,      values,      copy_len);
+          arrayops::copy(new_row_indices, row_indices, copy_len);
+          }
+        
+        memory::release(values);
+        memory::release(row_indices);
+        
+        access::rw(values)      = new_values;
+        access::rw(row_indices) = new_row_indices;
+        }
+        
+      // Set the "fake end" of the matrix by setting the last value and row
+      // index to 0.  This helps the iterators work correctly.
+      access::rw(values[new_n_nonzero]) = 0;
+      access::rw(row_indices[new_n_nonzero]) = 0;
+      }
+    
+    access::rw(n_nonzero) = new_n_nonzero;
+    }
+  }
+
+
+
+// Steal memory from another matrix.
+template<typename eT>
+inline
+void
+SpMat<eT>::steal_mem(SpMat<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+
+  if(this != &x)
+    {
+    // Release all the memory.
+    memory::release(values);
+    memory::release(row_indices);
+    memory::release(col_ptrs);
+
+    // We'll have to copy everything about the other matrix.
+    const uword x_n_rows    = x.n_rows;
+    const uword x_n_cols    = x.n_cols;
+    const uword x_n_elem    = x.n_elem;
+    const uword x_n_nonzero = x.n_nonzero;
+
+    access::rw(n_rows)    = x_n_rows;
+    access::rw(n_cols)    = x_n_cols;
+    access::rw(n_elem)    = x_n_elem;
+    access::rw(n_nonzero) = x_n_nonzero;
+
+    access::rw(values)      = x.values;
+    access::rw(row_indices) = x.row_indices;
+    access::rw(col_ptrs)    = x.col_ptrs;
+
+    // Set other matrix to empty.
+    access::rw(x.n_rows)    = 0;
+    access::rw(x.n_cols)    = 0;
+    access::rw(x.n_elem)    = 0;
+    access::rw(x.n_nonzero) = 0;
+
+    access::rw(x.values)      = NULL;
+    access::rw(x.row_indices) = NULL;
+    access::rw(x.col_ptrs)    = NULL;
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename Functor>
+arma_hot
+inline
+void
+SpMat<eT>::init_xform(const SpBase<eT,T1>& A, const Functor& func)
+  {
+  arma_extra_debug_sigprint();
+  
+  // if possible, avoid doing a copy and instead apply func to the generated elements
+  if(SpProxy<T1>::Q_created_by_proxy == true)
+    {
+    (*this) = A.get_ref();
+    
+    const uword nnz = n_nonzero;
+    
+    eT* t_values = access::rwp(values);
+    
+    for(uword i=0; i < nnz; ++i)
+      {
+      t_values[i] = func(t_values[i]);
+      }
+    }
+  else
+    {
+    init_xform_mt(A.get_ref(), func);
+    }
+  }
+
+
+
+template<typename eT>
+template<typename eT2, typename T1, typename Functor>
+arma_hot
+inline
+void
+SpMat<eT>::init_xform_mt(const SpBase<eT2,T1>& A, const Functor& func)
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> P(A.get_ref());
+  
+  if( (P.is_alias(*this) == true) || (is_SpMat<typename SpProxy<T1>::stored_type>::value == true) )
+    {
+    // NOTE: unwrap_spmat will convert a submatrix to a matrix, which in effect takes care of aliasing with submatrices;
+    // NOTE: however, when more delayed ops are implemented, more elaborate handling of aliasing will be necessary
+    const unwrap_spmat<typename SpProxy<T1>::stored_type> tmp(P.Q);
+    
+    const SpMat<eT2>& x = tmp.M;
+    
+    if(void_ptr(this) != void_ptr(&x))
+      {
+      init(x.n_rows, x.n_cols);
+      
+      // values and row_indices may not be null.
+      if(values != NULL)
+        {
+        memory::release(values);
+        memory::release(row_indices);
+        }
+      
+      access::rw(values)      = memory::acquire_chunked<eT>   (x.n_nonzero + 1);
+      access::rw(row_indices) = memory::acquire_chunked<uword>(x.n_nonzero + 1);
+      
+      arrayops::copy(access::rwp(row_indices), x.row_indices, x.n_nonzero + 1);
+      arrayops::copy(access::rwp(col_ptrs),    x.col_ptrs,    x.n_cols    + 1);
+      
+      access::rw(n_nonzero) = x.n_nonzero;
+      }
+    
+    
+    // initialise the elements array with a transformed version of the elements from x
+    
+    const uword nnz = n_nonzero;
+    
+    const eT2* x_values = x.values;
+          eT*  t_values = access::rwp(values);
+    
+    for(uword i=0; i < nnz; ++i)
+      {
+      t_values[i] = func(x_values[i]);   // NOTE: func() must produce a value of type eT (ie. act as a convertor between eT2 and eT)
+      }
+    }
+  else
+    {
+    init(P.get_n_rows(), P.get_n_cols());
+    
+    mem_resize(P.get_n_nonzero());
+    
+    typename SpProxy<T1>::const_iterator_type it = P.begin();
+    
+    while(it != P.end())
+      {
+      access::rw(row_indices[it.pos()]) = it.row();
+      access::rw(values[it.pos()]) = func(*it);   // NOTE: func() must produce a value of type eT (ie. act as a convertor between eT2 and eT)
+      ++access::rw(col_ptrs[it.col() + 1]);
+      ++it;
+      }
+    
+    // Now sum column pointers.
+    for(uword c = 1; c <= n_cols; ++c)
+      {
+      access::rw(col_ptrs[c]) += col_ptrs[c - 1];
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::iterator
+SpMat<eT>::begin()
+  {
+  return iterator(*this);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::const_iterator
+SpMat<eT>::begin() const
+  {
+  return const_iterator(*this);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::iterator
+SpMat<eT>::end()
+  {
+  return iterator(*this, 0, n_cols, n_nonzero);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::const_iterator
+SpMat<eT>::end() const
+  {
+  return const_iterator(*this, 0, n_cols, n_nonzero);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::iterator
+SpMat<eT>::begin_col(const uword col_num)
+  {
+  return iterator(*this, 0, col_num);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::const_iterator
+SpMat<eT>::begin_col(const uword col_num) const
+  {
+  return const_iterator(*this, 0, col_num);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::iterator
+SpMat<eT>::end_col(const uword col_num)
+  {
+  return iterator(*this, 0, col_num + 1);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::const_iterator
+SpMat<eT>::end_col(const uword col_num) const
+  {
+  return const_iterator(*this, 0, col_num + 1);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::row_iterator
+SpMat<eT>::begin_row(const uword row_num)
+  {
+  return row_iterator(*this, row_num, 0);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::const_row_iterator
+SpMat<eT>::begin_row(const uword row_num) const
+  {
+  return const_row_iterator(*this, row_num, 0);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::row_iterator
+SpMat<eT>::end_row()
+  {
+  return row_iterator(*this, n_nonzero);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::const_row_iterator
+SpMat<eT>::end_row() const
+  {
+  return const_row_iterator(*this, n_nonzero);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::row_iterator
+SpMat<eT>::end_row(const uword row_num)
+  {
+  return row_iterator(*this, row_num + 1, 0);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpMat<eT>::const_row_iterator
+SpMat<eT>::end_row(const uword row_num) const
+  {
+  return const_row_iterator(*this, row_num + 1, 0);
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpMat<eT>::clear()
+  {
+  if (values)
+    {
+    memory::release(values);
+    memory::release(row_indices);
+    
+    access::rw(values)      = memory::acquire_chunked<eT>   (1);
+    access::rw(row_indices) = memory::acquire_chunked<uword>(1);
+
+    access::rw(values[0]) = 0;
+    access::rw(row_indices[0]) = 0;
+    }
+  
+  memory::release(col_ptrs);
+  
+  access::rw(col_ptrs) = memory::acquire<uword>(n_cols + 2);
+  access::rw(col_ptrs[n_cols + 1]) = std::numeric_limits<uword>::max();
+  
+  arrayops::inplace_set(col_ptrs, eT(0), n_cols + 1);
+  
+  access::rw(n_nonzero) = 0;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpMat<eT>::empty() const
+  {
+  return (n_elem == 0);
+  }
+
+
+
+template<typename eT>
+inline
+uword
+SpMat<eT>::size() const
+  {
+  return n_elem;
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+arma_warn_unused
+SpValProxy<SpMat<eT> >
+SpMat<eT>::get_value(const uword i)
+  {
+  // First convert to the actual location.
+  uword lcol = i / n_rows; // Integer division.
+  uword lrow = i % n_rows;
+
+  return get_value(lrow, lcol);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+arma_warn_unused
+eT
+SpMat<eT>::get_value(const uword i) const
+  {
+  // First convert to the actual location.
+  uword lcol = i / n_rows; // Integer division.
+  uword lrow = i % n_rows;
+
+  return get_value(lrow, lcol);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+arma_warn_unused
+SpValProxy<SpMat<eT> >
+SpMat<eT>::get_value(const uword in_row, const uword in_col)
+  {
+  const uword colptr      = col_ptrs[in_col];
+  const uword next_colptr = col_ptrs[in_col + 1];
+
+  // Step through the row indices to see if our element exists.
+  for (uword i = colptr; i < next_colptr; ++i)
+    {
+    const uword row_index = row_indices[i];
+    
+    // First check that we have not stepped past it.
+    if (in_row < row_index) // If we have, then it doesn't exist: return 0.
+      {
+      return SpValProxy<SpMat<eT> >(in_row, in_col, *this); // Proxy for a zero value.
+      }
+
+    // Now check if we are at the correct place.
+    if (in_row == row_index) // If we are, return a reference to the value.
+      {
+      return SpValProxy<SpMat<eT> >(in_row, in_col, *this, &access::rw(values[i]));
+      }
+
+    }
+
+  // We did not find it, so it does not exist: return 0.
+  return SpValProxy<SpMat<eT> >(in_row, in_col, *this);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+arma_warn_unused
+eT
+SpMat<eT>::get_value(const uword in_row, const uword in_col) const
+  {
+  const uword colptr      = col_ptrs[in_col];
+  const uword next_colptr = col_ptrs[in_col + 1];
+  
+  // Step through the row indices to see if our element exists.
+  for (uword i = colptr; i < next_colptr; ++i)
+    {
+    const uword row_index = row_indices[i];
+    
+    // First check that we have not stepped past it.
+    if (in_row < row_index) // If we have, then it doesn't exist: return 0.
+      {
+      return eT(0);
+      }
+    
+    // Now check if we are at the correct place.
+    if (in_row == row_index) // If we are, return the value.
+      {
+      return values[i];
+      }
+    }
+  
+  // We did not find it, so it does not exist: return 0.
+  return eT(0);
+  }
+
+
+
+/**
+ * Given the index representing which of the nonzero values this is, return its
+ * actual location, either in row/col or just the index.
+ */
+template<typename eT>
+arma_hot
+arma_inline
+arma_warn_unused
+uword
+SpMat<eT>::get_position(const uword i) const
+  {
+  uword lrow, lcol;
+  
+  get_position(i, lrow, lcol);
+  
+  // Assemble the row/col into the element's location in the matrix.
+  return (lrow + n_rows * lcol);
+  }
+
+
+
+template<typename eT>
+arma_hot
+arma_inline
+void
+SpMat<eT>::get_position(const uword i, uword& row_of_i, uword& col_of_i) const
+  {
+  arma_debug_check((i >= n_nonzero), "SpMat::get_position(): index out of bounds");
+  
+  col_of_i = 0;
+  while (col_ptrs[col_of_i + 1] <= i)
+    {
+    col_of_i++;
+    }
+  
+  row_of_i = row_indices[i];
+  
+  return;
+  }
+
+
+
+/**
+ * Add an element at the given position, and return a reference to it.  The
+ * element will be set to 0 (unless otherwise specified).  If the element
+ * already exists, its value will be overwritten.
+ *
+ * @param in_row Row of new element.
+ * @param in_col Column of new element.
+ * @param in_val Value to set new element to (default 0.0).
+ */
+template<typename eT>
+inline
+arma_hot
+arma_warn_unused
+eT&
+SpMat<eT>::add_element(const uword in_row, const uword in_col, const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  // We will assume the new element does not exist and begin the search for
+  // where to insert it.  If we find that it already exists, we will then
+  // overwrite it.
+  uword colptr      = col_ptrs[in_col    ];
+  uword next_colptr = col_ptrs[in_col + 1];
+  
+  uword pos = colptr; // The position in the matrix of this value.
+  
+  if (colptr != next_colptr)
+    {
+    // There are other elements in this column, so we must find where this
+    // element will fit as compared to those.
+    while (pos < next_colptr && in_row > row_indices[pos])
+      {
+      pos++;
+      }
+    
+    // We aren't inserting into the last position, so it is still possible
+    // that the element may exist.
+    if (pos != next_colptr && row_indices[pos] == in_row)
+      {
+      // It already exists.  Then, just overwrite it.
+      access::rw(values[pos]) = val;
+      
+      return access::rw(values[pos]);
+      }
+    }
+  
+  
+  // 
+  // Element doesn't exist, so we have to insert it
+  // 
+  
+  // We have to update the rest of the column pointers.
+  for (uword i = in_col + 1; i < n_cols + 1; i++)
+    {
+    access::rw(col_ptrs[i])++; // We are only inserting one new element.
+    }
+  
+  
+  // Figure out the actual amount of memory currently allocated
+  // NOTE: this relies on memory::acquire_chunked() being used for the 'values' and 'row_indices' arrays
+  const uword n_alloc = memory::enlarge_to_mult_of_chunksize(n_nonzero + 1);
+  
+  // If possible, avoid time-consuming memory allocation 
+  if(n_alloc > (n_nonzero + 1))
+    {
+    arrayops::copy_backwards(access::rwp(values)      + pos + 1, values      + pos, (n_nonzero - pos) + 1);
+    arrayops::copy_backwards(access::rwp(row_indices) + pos + 1, row_indices + pos, (n_nonzero - pos) + 1);
+    
+    // Insert the new element.
+    access::rw(values[pos])      = val;
+    access::rw(row_indices[pos]) = in_row;
+    
+    access::rw(n_nonzero)++;
+    }
+  else
+    {
+    const uword old_n_nonzero = n_nonzero;
+    
+    access::rw(n_nonzero)++; // Add to count of nonzero elements.
+    
+    // Allocate larger memory.
+    eT*    new_values      = memory::acquire_chunked<eT>   (n_nonzero + 1);
+    uword* new_row_indices = memory::acquire_chunked<uword>(n_nonzero + 1);
+    
+    // Copy things over, before the new element.
+    if (pos > 0)
+      {
+      arrayops::copy(new_values,      values,      pos);
+      arrayops::copy(new_row_indices, row_indices, pos);
+      }
+    
+    // Insert the new element.
+    new_values[pos]      = val;
+    new_row_indices[pos] = in_row;
+    
+    // Copy the rest of things over (including the extra element at the end).
+    arrayops::copy(new_values      + pos + 1, values      + pos, (old_n_nonzero - pos) + 1);
+    arrayops::copy(new_row_indices + pos + 1, row_indices + pos, (old_n_nonzero - pos) + 1);
+    
+    // Assign new pointers.
+    memory::release(values);
+    memory::release(row_indices);
+
+    access::rw(values)      = new_values;
+    access::rw(row_indices) = new_row_indices;
+    }
+  
+  return access::rw(values[pos]);
+  }
+
+
+
+/**
+ * Delete an element at the given position.
+ *
+ * @param in_row Row of element to be deleted.
+ * @param in_col Column of element to be deleted.
+ */
+template<typename eT>
+inline
+arma_hot
+void
+SpMat<eT>::delete_element(const uword in_row, const uword in_col)
+  {
+  arma_extra_debug_sigprint();
+  
+  // We assume the element exists (although... it may not) and look for its
+  // exact position.  If it doesn't exist... well, we don't need to do anything.
+  uword colptr      = col_ptrs[in_col];
+  uword next_colptr = col_ptrs[in_col + 1];
+
+  if (colptr != next_colptr)
+    {
+    // There's at least one element in this column.
+    // Let's see if we are one of them.
+    for (uword pos = colptr; pos < next_colptr; pos++)
+      {
+      if (in_row == row_indices[pos])
+        {
+        const uword old_n_nonzero = n_nonzero;
+        
+        --access::rw(n_nonzero); // Remove one from the count of nonzero elements.
+        
+        // Found it.  Now remove it.
+          
+        // Figure out the actual amount of memory currently allocated and the actual amount that will be required
+        // NOTE: this relies on memory::acquire_chunked() being used for the 'values' and 'row_indices' arrays
+          
+        const uword n_alloc     = memory::enlarge_to_mult_of_chunksize(old_n_nonzero + 1);
+        const uword n_alloc_mod = memory::enlarge_to_mult_of_chunksize(n_nonzero + 1);
+          
+        // If possible, avoid time-consuming memory allocation
+        if(n_alloc_mod == n_alloc)
+          {
+          if (pos < n_nonzero)  // remember, we decremented n_nonzero
+            {
+            arrayops::copy_forwards(access::rwp(values)      + pos, values + pos + 1, (n_nonzero - pos) + 1);
+            arrayops::copy_forwards(access::rwp(row_indices) + pos, row_indices + pos + 1, (n_nonzero - pos) + 1);
+            }
+          }
+        else
+          {
+          // Make new arrays.
+          eT*    new_values      = memory::acquire_chunked<eT>   (n_nonzero + 1);
+          uword* new_row_indices = memory::acquire_chunked<uword>(n_nonzero + 1);
+            
+          if (pos > 0)
+            {
+            arrayops::copy(new_values,      values,      pos);
+            arrayops::copy(new_row_indices, row_indices, pos);
+            }
+            
+          arrayops::copy(new_values      + pos, values      + pos + 1, (n_nonzero - pos) + 1);
+          arrayops::copy(new_row_indices + pos, row_indices + pos + 1, (n_nonzero - pos) + 1);
+            
+          memory::release(values);
+          memory::release(row_indices);
+            
+          access::rw(values)      = new_values;
+          access::rw(row_indices) = new_row_indices;
+          }
+        
+        // And lastly, update all the column pointers (decrement by one).
+        for (uword i = in_col + 1; i < n_cols + 1; i++)
+          {
+          --access::rw(col_ptrs[i]); // We only removed one element.
+          }
+        
+        return; // There is nothing left to do.
+        }
+      }
+    }
+  
+  return; // The element does not exist, so there's nothing for us to do.
+  }
+
+
+
+#ifdef ARMA_EXTRA_SPMAT_MEAT
+  #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPMAT_MEAT)
+#endif
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpOp_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,38 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup SpOp
+//! @{
+
+
+
+template<typename T1, typename op_type>
+class SpOp : public SpBase<typename T1::elem_type, SpOp<T1, op_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool is_row = (T1::is_row && is_spop_elem<op_type>::value) || ( T1::is_col && (is_same_type<op_type, spop_strans>::value || is_same_type<op_type, spop_htrans>::value) );
+  static const bool is_col = (T1::is_col && is_spop_elem<op_type>::value) || ( T1::is_row && (is_same_type<op_type, spop_strans>::value || is_same_type<op_type, spop_htrans>::value) );
+  
+  inline explicit SpOp(const T1& in_m);
+  inline          SpOp(const T1& in_m, const elem_type in_aux);
+  inline          SpOp(const T1& in_m, const uword     in_aux_uword_a, const uword in_aux_uword_b);
+  inline         ~SpOp();
+  
+  
+  arma_aligned const T1&       m;            //!< storage of reference to the operand (eg. a matrix)
+  arma_aligned       elem_type aux;          //!< storage of auxiliary data, user defined format
+  arma_aligned       uword     aux_uword_a;  //!< storage of auxiliary data, uword format
+  arma_aligned       uword     aux_uword_b;  //!< storage of auxiliary data, uword format
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpOp_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,55 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup SpOp
+//! @{
+
+
+
+template<typename T1, typename op_type>
+inline
+SpOp<T1, op_type>::SpOp(const T1& in_m)
+  : m(in_m)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename op_type>
+inline
+SpOp<T1, op_type>::SpOp(const T1& in_m, const typename T1::elem_type in_aux)
+  : m(in_m)
+  , aux(in_aux)
+  {
+  arma_extra_debug_sigprint();
+  }
+  
+
+
+template<typename T1, typename op_type>
+inline
+SpOp<T1, op_type>::SpOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b)
+  : m(in_m)
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename op_type>
+inline
+SpOp<T1, op_type>::~SpOp()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpProxy.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,380 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+//! \addtogroup SpProxy
+//! @{
+
+
+
+template<typename eT>
+class SpProxy< SpMat<eT> >
+  {
+  public:
+
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef SpMat<eT>                                stored_type;
+
+  typedef typename SpMat<eT>::const_iterator       const_iterator_type;
+  typedef typename SpMat<eT>::const_row_iterator   const_row_iterator_type;
+
+  static const bool must_use_iterator  = false;
+  static const bool Q_created_by_proxy = false;
+
+  static const bool is_row = false;
+  static const bool is_col = false;
+
+  arma_aligned const SpMat<eT>& Q;
+
+  inline explicit SpProxy(const SpMat<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+
+  arma_inline uword get_n_rows()    const { return Q.n_rows;    }
+  arma_inline uword get_n_cols()    const { return Q.n_cols;    }
+  arma_inline uword get_n_elem()    const { return Q.n_elem;    }
+  arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
+
+  arma_inline elem_type operator[](const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at        (const uword row, const uword col) const { return Q.at(row, col); }
+
+  arma_inline const eT*    get_values()      const { return Q.values;      }
+  arma_inline const uword* get_row_indices() const { return Q.row_indices; }
+  arma_inline const uword* get_col_ptrs()    const { return Q.col_ptrs;    }
+
+  arma_inline const_iterator_type     begin()                            const { return Q.begin();            }
+  arma_inline const_iterator_type     begin_col(const uword col_num)     const { return Q.begin_col(col_num); }
+  arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
+
+  arma_inline const_iterator_type     end()                        const { return Q.end();            }
+  arma_inline const_row_iterator_type end_row()                    const { return Q.end_row();        }
+  arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const SpMat<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
+  };
+
+
+
+template<typename eT>
+class SpProxy< SpCol<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef SpCol<eT>                                stored_type;
+  
+  typedef typename SpCol<eT>::const_iterator       const_iterator_type;
+  typedef typename SpCol<eT>::const_row_iterator   const_row_iterator_type;
+  
+  static const bool must_use_iterator  = false;
+  static const bool Q_created_by_proxy = false;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const SpCol<eT>& Q;
+  
+  inline explicit SpProxy(const SpCol<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows()    const { return Q.n_rows;    }
+  arma_inline uword get_n_cols()    const { return 1;           }
+  arma_inline uword get_n_elem()    const { return Q.n_elem;    }
+  arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
+  
+  arma_inline elem_type operator[](const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at        (const uword row, const uword col) const { return Q.at(row, col); }
+  
+  arma_inline const eT*    get_values()      const { return Q.values;      }
+  arma_inline const uword* get_row_indices() const { return Q.row_indices; }
+  arma_inline const uword* get_col_ptrs()    const { return Q.col_ptrs;    }
+  
+  arma_inline const_iterator_type     begin()                            const { return Q.begin();            }
+  arma_inline const_iterator_type     begin_col(const uword col_num)     const { return Q.begin();            }
+  arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
+  
+  arma_inline const_iterator_type     end()                        const { return Q.end();            }
+  arma_inline const_row_iterator_type end_row()                    const { return Q.end_row();        }
+  arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const SpMat<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
+  };
+
+
+
+template<typename eT>
+class SpProxy< SpRow<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef SpRow<eT>                                stored_type;
+  
+  typedef typename SpRow<eT>::const_iterator       const_iterator_type;
+  typedef typename SpRow<eT>::const_row_iterator   const_row_iterator_type;
+  
+  static const bool must_use_iterator  = false;
+  static const bool Q_created_by_proxy = false;
+  
+  static const bool is_row = true;
+  static const bool is_col = false;
+  
+  arma_aligned const SpRow<eT>& Q;
+  
+  inline explicit SpProxy(const SpRow<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows()    const { return 1;           }
+  arma_inline uword get_n_cols()    const { return Q.n_cols;    }
+  arma_inline uword get_n_elem()    const { return Q.n_elem;    }
+  arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
+  
+  arma_inline elem_type operator[](const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at        (const uword row, const uword col) const { return Q.at(row, col); }
+  
+  arma_inline const eT*    get_values()      const { return Q.values;      }
+  arma_inline const uword* get_row_indices() const { return Q.row_indices; }
+  arma_inline const uword* get_col_ptrs()    const { return Q.col_ptrs;    }
+  
+  arma_inline const_iterator_type     begin()                            const { return Q.begin();            }
+  arma_inline const_iterator_type     begin_col(const uword col_num)     const { return Q.begin_col(col_num); }
+  arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
+  
+  arma_inline const_iterator_type     end()                        const { return Q.end();            }
+  arma_inline const_row_iterator_type end_row()                    const { return Q.end_row();        }
+  arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const SpMat<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
+  };
+
+
+
+template<typename eT>
+class SpProxy< SpSubview<eT> >
+  {
+  public:
+
+  typedef eT                                           elem_type;
+  typedef typename get_pod_type<elem_type>::result     pod_type;
+  typedef SpSubview<eT>                                stored_type;
+
+  typedef typename SpSubview<eT>::const_iterator       const_iterator_type;
+  typedef typename SpSubview<eT>::const_row_iterator   const_row_iterator_type;
+
+  static const bool must_use_iterator  = true;
+  static const bool Q_created_by_proxy = false;
+
+  static const bool is_row = false;
+  static const bool is_col = false;
+
+  arma_aligned const SpSubview<eT>& Q;
+
+  inline explicit SpProxy(const SpSubview<eT>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+
+  arma_inline uword get_n_rows()    const { return Q.n_rows;    }
+  arma_inline uword get_n_cols()    const { return Q.n_cols;    }
+  arma_inline uword get_n_elem()    const { return Q.n_elem;    }
+  arma_inline uword get_n_nonzero() const { return Q.n_nonzero; }
+
+  arma_inline elem_type operator[](const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at        (const uword row, const uword col) const { return Q.at(row, col); }
+
+  arma_inline const eT*    get_values()      const { return Q.m.values;      }
+  arma_inline const uword* get_row_indices() const { return Q.m.row_indices; }
+  arma_inline const uword* get_col_ptrs()    const { return Q.m.col_ptrs;    }
+
+  arma_inline const_iterator_type     begin()                            const { return Q.begin();            }
+  arma_inline const_iterator_type     begin_col(const uword col_num)     const { return Q.begin_col(col_num); }
+  arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
+
+  arma_inline const_iterator_type     end()                        const { return Q.end();            }
+  arma_inline const_row_iterator_type end_row()                    const { return Q.end_row();        }
+  arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const SpMat<eT2>& X) const { return (void_ptr(&Q.m) == void_ptr(&X)); }
+  };
+
+
+
+template<typename T1, typename spop_type>
+class SpProxy< SpOp<T1, spop_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename T1::elem_type                   eT;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef SpMat<eT>                                stored_type;
+  
+  typedef typename SpMat<eT>::const_iterator       const_iterator_type;
+  typedef typename SpMat<eT>::const_row_iterator   const_row_iterator_type;
+  
+  static const bool must_use_iterator  = false;
+  static const bool Q_created_by_proxy = true;
+  
+  static const bool is_row = SpOp<T1, spop_type>::is_row;
+  static const bool is_col = SpOp<T1, spop_type>::is_col;
+  
+  arma_aligned const SpMat<eT> Q;
+  
+  inline explicit SpProxy(const SpOp<T1, spop_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows()    const { return is_row ? 1 : Q.n_rows; }
+  arma_inline uword get_n_cols()    const { return is_col ? 1 : Q.n_cols; }
+  arma_inline uword get_n_elem()    const { return Q.n_elem;              }
+  arma_inline uword get_n_nonzero() const { return Q.n_nonzero;           }
+  
+  arma_inline elem_type operator[](const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at        (const uword row, const uword col) const { return Q.at(row, col); }
+  
+  arma_inline const eT*    get_values()      const { return Q.values;      }
+  arma_inline const uword* get_row_indices() const { return Q.row_indices; }
+  arma_inline const uword* get_col_ptrs()    const { return Q.col_ptrs;    }
+  
+  arma_inline const_iterator_type     begin()                            const { return Q.begin();            }
+  arma_inline const_iterator_type     begin_col(const uword col_num)     const { return Q.begin_col(col_num); }
+  arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
+  
+  arma_inline const_iterator_type     end()                        const { return Q.end();            }
+  arma_inline const_row_iterator_type end_row()                    const { return Q.end_row();        }
+  arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const SpMat<eT2>&) const { return false; }
+  };
+
+
+
+template<typename T1, typename T2, typename spglue_type>
+class SpProxy< SpGlue<T1, T2, spglue_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename T1::elem_type                   eT;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef SpMat<eT>                                stored_type;
+  
+  typedef typename SpMat<eT>::const_iterator       const_iterator_type;
+  typedef typename SpMat<eT>::const_row_iterator   const_row_iterator_type;
+  
+  static const bool must_use_iterator  = false;
+  static const bool Q_created_by_proxy = true;
+  
+  static const bool is_row = SpGlue<T1, T2, spglue_type>::is_row;
+  static const bool is_col = SpGlue<T1, T2, spglue_type>::is_col;
+  
+  arma_aligned const SpMat<eT> Q;
+  
+  inline explicit SpProxy(const SpGlue<T1, T2, spglue_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows()    const { return is_row ? 1 : Q.n_rows; }
+  arma_inline uword get_n_cols()    const { return is_col ? 1 : Q.n_cols; }
+  arma_inline uword get_n_elem()    const { return Q.n_elem;              }
+  arma_inline uword get_n_nonzero() const { return Q.n_nonzero;           }
+  
+  arma_inline elem_type operator[](const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at        (const uword row, const uword col) const { return Q.at(row, col); }
+  
+  arma_inline const eT*    get_values()      const { return Q.values;      }
+  arma_inline const uword* get_row_indices() const { return Q.row_indices; }
+  arma_inline const uword* get_col_ptrs()    const { return Q.col_ptrs;    }
+  
+  arma_inline const_iterator_type     begin()                            const { return Q.begin();            }
+  arma_inline const_iterator_type     begin_col(const uword col_num)     const { return Q.begin_col(col_num); }
+  arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
+  
+  arma_inline const_iterator_type     end()                        const { return Q.end();            }
+  arma_inline const_row_iterator_type end_row()                    const { return Q.end_row();        }
+  arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const SpMat<eT2>&) const { return false; }
+  };
+
+
+
+template<typename out_eT, typename T1, typename spop_type>
+class SpProxy< mtSpOp<out_eT, T1, spop_type> >
+  {
+  public:
+  
+  typedef          out_eT                          elem_type;
+  typedef typename T1::elem_type                   eT;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef SpMat<out_eT>                            stored_type;
+  
+  typedef typename SpMat<out_eT>::const_iterator       const_iterator_type;
+  typedef typename SpMat<out_eT>::const_row_iterator   const_row_iterator_type;
+  
+  static const bool must_use_iterator  = false;
+  static const bool Q_created_by_proxy = true;
+  
+  static const bool is_row = mtSpOp<out_eT, T1, spop_type>::is_row;
+  static const bool is_col = mtSpOp<out_eT, T1, spop_type>::is_col;
+  
+  arma_aligned const SpMat<out_eT> Q;
+  
+  inline explicit SpProxy(const mtSpOp<out_eT, T1, spop_type>& A)
+    : Q(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline uword get_n_rows()    const { return is_row ? 1 : Q.n_rows; }
+  arma_inline uword get_n_cols()    const { return is_col ? 1 : Q.n_cols; }
+  arma_inline uword get_n_elem()    const { return Q.n_elem;              }
+  arma_inline uword get_n_nonzero() const { return Q.n_nonzero;           }
+  
+  arma_inline elem_type operator[](const uword i)                    const { return Q[i];           }
+  arma_inline elem_type at        (const uword row, const uword col) const { return Q.at(row, col); }
+  
+  arma_inline const eT*    get_values()      const { return Q.values;      }
+  arma_inline const uword* get_row_indices() const { return Q.row_indices; }
+  arma_inline const uword* get_col_ptrs()    const { return Q.col_ptrs;    }
+  
+  arma_inline const_iterator_type     begin()                            const { return Q.begin();            }
+  arma_inline const_iterator_type     begin_col(const uword col_num)     const { return Q.begin_col(col_num); }
+  arma_inline const_row_iterator_type begin_row(const uword row_num = 0) const { return Q.begin_row(row_num); }
+  
+  arma_inline const_iterator_type     end()                        const { return Q.end();            }
+  arma_inline const_row_iterator_type end_row()                    const { return Q.end_row();        }
+  arma_inline const_row_iterator_type end_row(const uword row_num) const { return Q.end_row(row_num); }
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const SpMat<eT2>&) const { return false; }
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpRow_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,85 @@
+// Copyright (C) 2011-2012 Ryan Curtin
+// Copyright (C) 2011 Matthew Amidon
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup SpRow
+//! @{
+
+//! Class for sparse row vectors (sparse matrices with only one row)
+
+template<typename eT>
+class SpRow : public SpMat<eT>
+  {
+  public:
+
+  typedef eT                                elem_type;
+  typedef typename get_pod_type<eT>::result pod_type;
+  
+  static const bool is_row = true;
+  static const bool is_col = false;
+  
+  
+  inline          SpRow();
+  inline explicit SpRow(const uword N);
+  inline          SpRow(const uword in_rows, const uword in_cols);
+
+  inline                  SpRow(const char*        text);
+  inline const SpRow& operator=(const char*        text);
+
+  inline                  SpRow(const std::string& text);
+  inline const SpRow& operator=(const std::string& text);
+
+  inline const SpRow& operator=(const eT val);
+
+  template<typename T1> inline                  SpRow(const Base<eT,T1>& X);
+  template<typename T1> inline const SpRow& operator=(const Base<eT,T1>& X);
+
+  template<typename T1> inline                  SpRow(const SpBase<eT,T1>& X);
+  template<typename T1> inline const SpRow& operator=(const SpBase<eT,T1>& X);
+  
+  template<typename T1, typename T2>
+  inline explicit SpRow(const SpBase<pod_type,T1>& A, const SpBase<pod_type,T2>& B);
+
+  inline SpValProxy<SpMat<eT> > col(const uword col_num);
+  inline eT                     col(const uword col_num) const;
+
+//  arma_inline       subview_row<eT> cols(const uword in_col1, const uword in_col2);
+//  arma_inline const subview_row<eT> cols(const uword in_col1, const uword in_col2) const;
+
+//  arma_inline       subview_row<eT> subvec(const uword in_col1, const uword in_col2);
+//  arma_inline const subview_row<eT> subvec(const uword in_col1, const uword in_col2) const;
+
+//  arma_inline       subview_row<eT> subvec(const span& col_span);
+//  arma_inline const subview_row<eT> subvec(const span& col_span) const;
+
+//  arma_inline       subview_row<eT> operator()(const span& col_span);
+//  arma_inline const subview_row<eT> operator()(const span& col_span) const;
+
+  inline void shed_col (const uword col_num);
+  inline void shed_cols(const uword in_col1, const uword in_col2);
+
+//                         inline void insert_cols(const uword col_num, const uword N, const bool set_to_zero = true);
+//   template<typename T1> inline void insert_cols(const uword col_num, const Base<eT,T1>& X);
+
+
+  typedef typename SpMat<eT>::iterator       row_iterator;
+  typedef typename SpMat<eT>::const_iterator const_row_iterator;
+
+  inline       row_iterator begin_row(const uword row_num = 0);
+  inline const_row_iterator begin_row(const uword row_num = 0) const;
+
+  inline       row_iterator end_row(const uword row_num = 0);
+  inline const_row_iterator end_row(const uword row_num = 0) const;
+  
+  #ifdef ARMA_EXTRA_SPROW_PROTO
+    #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPROW_PROTO)
+  #endif
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpRow_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,565 @@
+// Copyright (C) 2011-2012 Ryan Curtin
+// Copyright (C) 2011 Matthew Amidon
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup SpRow
+//! @{
+
+
+
+template<typename eT>
+inline
+SpRow<eT>::SpRow()
+  : SpMat<eT>(1, 0)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 2;
+  }
+
+
+
+template<typename eT>
+inline
+SpRow<eT>::SpRow(const uword in_n_elem)
+  : SpMat<eT>(1, in_n_elem)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 2;
+  }
+
+
+
+template<typename eT>
+inline
+SpRow<eT>::SpRow(const uword in_n_rows, const uword in_n_cols)
+  : SpMat<eT>(in_n_rows, in_n_cols)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check((in_n_rows != 1), "SpRow::SpRow(): must have only one row");
+
+  access::rw(SpMat<eT>::vec_state) = 2;
+  }
+
+
+
+template<typename eT>
+inline
+SpRow<eT>::SpRow(const char* text)
+  : SpMat<eT>(text)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 2;
+
+  arma_debug_check((SpMat<eT>::n_rows != 1), "SpRow::SpRow(): must have only one row");
+  }
+  
+
+
+template<typename eT>
+inline
+const SpRow<eT>&
+SpRow<eT>::operator=(const char* text)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 2;
+  
+  SpMat<eT>::operator=(text);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+SpRow<eT>::SpRow(const std::string& text)
+  : SpMat<eT>(text)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 2;
+  
+  arma_debug_check((SpMat<eT>::n_rows != 1), "SpRow::SpRow(): must have only one row");
+  }
+
+
+
+template<typename eT>
+inline
+const SpRow<eT>&
+SpRow<eT>::operator=(const std::string& text)
+  {
+  arma_extra_debug_sigprint();
+  
+  SpMat<eT>::operator=(text);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpRow<eT>&
+SpRow<eT>::operator=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  SpMat<eT>::operator=(val);
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+SpRow<eT>::SpRow(const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 2;
+  
+  SpMat<eT>::operator=(X.get_ref());
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpRow<eT>&
+SpRow<eT>::operator=(const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  SpMat<eT>::operator=(X.get_ref());
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+SpRow<eT>::SpRow(const SpBase<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 2;
+  
+  SpMat<eT>::operator=(X.get_ref());
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpRow<eT>&
+SpRow<eT>::operator=(const SpBase<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  SpMat<eT>::operator=(X.get_ref());
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1, typename T2>
+inline
+SpRow<eT>::SpRow
+  (
+  const SpBase<typename SpRow<eT>::pod_type, T1>& A,
+  const SpBase<typename SpRow<eT>::pod_type, T2>& B
+  )
+  {
+  arma_extra_debug_sigprint();
+
+  access::rw(SpMat<eT>::vec_state) = 2;
+  
+  SpMat<eT>::init(A,B);
+  }
+
+
+
+template<typename eT>
+inline
+SpValProxy< SpMat<eT> >
+SpRow<eT>::col(const uword col_num)
+  {
+  arma_debug_check( (col_num >= SpMat<eT>::n_cols), "SpRow::col(): out of bounds" );
+  
+  return SpMat<eT>::at(0, col_num);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+SpRow<eT>::col(const uword col_num) const
+  {
+  arma_debug_check( (col_num >= SpMat<eT>::n_cols), "SpRow::col(): out of bounds" );
+  
+  return SpMat<eT>::at(0, col_num);
+  }
+
+
+/*
+template<typename eT>
+arma_inline
+subview_row<eT>
+SpRow<eT>::cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols) ), "SpRow::cols(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview_row<eT>(*this, 0, in_col1, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_row<eT>
+SpRow<eT>::cols(const uword in_col1, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols) ), "SpRow::cols(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview_row<eT>(*this, 0, in_col1, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_row<eT>
+SpRow<eT>::subvec(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols) ), "SpRow::subvec(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview_row<eT>(*this, 0, in_col1, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_row<eT>
+SpRow<eT>::subvec(const uword in_col1, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat<eT>::n_cols) ), "SpRow::subvec(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview_row<eT>(*this, 0, in_col1, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_row<eT>
+SpRow<eT>::subvec(const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool col_all = col_span.whole;
+
+  const uword local_n_cols = Mat<eT>::n_cols;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword subvec_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+
+  arma_debug_check( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ), "SpRow::subvec(): indices out of bounds or incorrectly used");
+  
+  return subview_row<eT>(*this, 0, in_col1, subvec_n_cols);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const subview_row<eT>
+SpRow<eT>::subvec(const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool col_all = col_span.whole;
+
+  const uword local_n_cols = Mat<eT>::n_cols;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword subvec_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+
+  arma_debug_check( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ), "SpRow::subvec(): indices out of bounds or incorrectly used");
+  
+  return subview_row<eT>(*this, 0, in_col1, subvec_n_cols);
+  }
+*/
+
+
+// template<typename eT>
+// arma_inline
+// subview_row<eT>
+// SpRow<eT>::operator()(const span& col_span)
+//   {
+//   arma_extra_debug_sigprint();
+//   
+//   return subvec(col_span);
+//   }
+// 
+// 
+// 
+// template<typename eT>
+// arma_inline
+// const subview_row<eT>
+// SpRow<eT>::operator()(const span& col_span) const
+//   {
+//   arma_extra_debug_sigprint();
+//   
+//   return subvec(col_span);
+//   }
+
+
+
+//! remove specified columns
+template<typename eT>
+inline
+void
+SpRow<eT>::shed_col(const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( col_num >= SpMat<eT>::n_cols, "SpRow::shed_col(): out of bounds");
+  
+  shed_cols(col_num, col_num);
+  }
+
+
+
+//! remove specified columns
+template<typename eT>
+inline
+void
+SpRow<eT>::shed_cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_col1 > in_col2) || (in_col2 >= SpMat<eT>::n_cols),
+    "SpRow::shed_cols(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword diff = (in_col2 - in_col1 + 1);
+
+  // This is doubleplus easy because we have all the column pointers stored.
+  const uword start = SpMat<eT>::col_ptrs[in_col1];
+  const uword end   = SpMat<eT>::col_ptrs[in_col2 + 1];
+
+  if (start != end)
+    {
+    const uword elem_diff = end - start;
+
+    eT*    new_values      = memory::acquire_chunked<eT>   (SpMat<eT>::n_nonzero - elem_diff);
+    uword* new_row_indices = memory::acquire_chunked<uword>(SpMat<eT>::n_nonzero - elem_diff);
+
+    // Copy first set of elements, if necessary.
+    if (start > 0)
+      {
+      arrayops::copy(new_values, SpMat<eT>::values, start);
+      arrayops::copy(new_row_indices, SpMat<eT>::row_indices, start);
+      }
+
+    // Copy last set of elements, if necessary.
+    if (end != SpMat<eT>::n_nonzero)
+      {
+      arrayops::copy(new_values + start, SpMat<eT>::values + end, (SpMat<eT>::n_nonzero - end));
+      arrayops::copy(new_row_indices + start, SpMat<eT>::row_indices + end, (SpMat<eT>::n_nonzero - end));
+      }
+
+    memory::release(SpMat<eT>::values);
+    memory::release(SpMat<eT>::row_indices);
+
+    access::rw(SpMat<eT>::values) = new_values;
+    access::rw(SpMat<eT>::row_indices) = new_row_indices;
+
+    access::rw(SpMat<eT>::n_nonzero) -= elem_diff;
+    }
+
+  // Update column pointers.
+  uword* new_col_ptrs = memory::acquire<uword>(SpMat<eT>::n_cols - diff + 1);
+
+  // Copy first part of column pointers.
+  if (in_col1 > 0)
+    {
+    arrayops::copy(new_col_ptrs, SpMat<eT>::col_ptrs, in_col1);
+    }
+
+  // Copy last part of column pointers (and adjust their values as necessary).
+  if (in_col2 < SpMat<eT>::n_cols - 1)
+    {
+    arrayops::copy(new_col_ptrs + in_col1, SpMat<eT>::col_ptrs + in_col2 + 1, SpMat<eT>::n_cols - in_col2);
+    // Modify their values.
+    arrayops::inplace_minus(new_col_ptrs + in_col1, (end - start), SpMat<eT>::n_cols - in_col2);
+    }
+
+  memory::release(SpMat<eT>::col_ptrs);
+
+  access::rw(SpMat<eT>::col_ptrs) = new_col_ptrs;
+
+  access::rw(SpMat<eT>::n_cols) -= diff;
+  access::rw(SpMat<eT>::n_elem) -= diff;
+  }
+
+
+
+// //! insert N cols at the specified col position,
+// //! optionally setting the elements of the inserted cols to zero
+// template<typename eT>
+// inline
+// void
+// SpRow<eT>::insert_cols(const uword col_num, const uword N, const bool set_to_zero)
+//   {
+//   arma_extra_debug_sigprint();
+// 
+//   // insertion at col_num == n_cols is in effect an append operation
+//   arma_debug_check( (col_num > SpMat<eT>::n_cols), "SpRow::insert_cols(): out of bounds");
+// 
+//   arma_debug_check( (set_to_zero == false), "SpRow::insert_cols(): cannot set elements to nonzero values");
+// 
+//   uword newVal = (col_num == 0) ? 0 : SpMat<eT>::col_ptrs[col_num];
+//   SpMat<eT>::col_ptrs.insert(col_num, N, newVal);
+//   uword* new_col_ptrs = memory::acquire<uword>(SpMat<eT>::n_cols + N);
+// 
+//   arrayops::copy(new_col_ptrs, SpMat<eT>::col_ptrs, col_num);
+// 
+//   uword fill_value = (col_num == 0) ? 0 : SpMat<eT>::col_ptrs[col_num - 1];
+//   arrayops::inplace_set(new_col_ptrs + col_num, fill_value, N);
+// 
+//   arrayops::copy(new_col_ptrs + col_num + N, SpMat<eT>::col_ptrs + col_num, SpMat<eT>::n_cols - col_num);
+// 
+//   access::rw(SpMat<eT>::n_cols) += N;
+//   access::rw(SpMat<eT>::n_elem) += N;
+//   }
+// 
+// 
+// 
+// //! insert the given object at the specified col position; 
+// //! the given object must have one row
+// template<typename eT>
+// template<typename T1>
+// inline
+// void
+// SpRow<eT>::insert_cols(const uword col_num, const Base<eT,T1>& X)
+//   {
+//   arma_extra_debug_sigprint();
+//   
+//   SpMat<eT>::insert_cols(col_num, X);
+//   }
+
+
+
+template<typename eT>
+inline
+typename SpRow<eT>::row_iterator
+SpRow<eT>::begin_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+
+  // Since this is a row, row_num can only be 0.  But the option is provided for
+  // compatibility.
+  arma_debug_check((row_num >= 1), "SpRow::row(): invalid row index");
+  
+  return SpMat<eT>::begin();
+  }
+
+
+
+template<typename eT>
+inline
+typename SpRow<eT>::const_row_iterator
+SpRow<eT>::begin_row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  // Since this is a row, row_num can only be 0.  But the option is provided for
+  // compatibility.
+  arma_debug_check((row_num >= 1), "SpRow::row(): invalid row index");
+  
+  return SpMat<eT>::begin();
+  }
+
+
+
+template<typename eT>
+inline
+typename SpRow<eT>::row_iterator
+SpRow<eT>::end_row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  // Since this is a row, row_num can only be 0.  But the option is provided for
+  // compatibility.
+  arma_debug_check((row_num >= 1), "SpRow::row(): invalid row index");
+  
+  return SpMat<eT>::end();
+  }
+
+
+
+template<typename eT>
+inline
+typename SpRow<eT>::const_row_iterator
+SpRow<eT>::end_row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  // Since this is a row, row_num can only be 0.  But the option is provided for
+  // compatibility.
+  arma_debug_check((row_num >= 1), "SpRow::row(): invalid row index");
+  
+  return SpMat<eT>::end();
+  }
+
+
+
+  
+#ifdef ARMA_EXTRA_SPROW_MEAT
+  #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPROW_MEAT)
+#endif
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpSubview_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,416 @@
+// Copyright (C) 2011-2012 Ryan Curtin
+// Copyright (C) 2011 Matthew Amidon
+// Copyright (C) 2012 Conrad Sanderson
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+//! \addtogroup SpSubview
+//! @{
+
+template<typename eT>
+class SpSubview : public SpBase<eT, SpSubview<eT> >
+  {
+  public:
+  
+  const SpMat<eT>& m;
+  
+  typedef eT elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool is_row = false;
+  static const bool is_col = false;
+  
+  const uword aux_row1;
+  const uword aux_col1;
+  const uword n_rows;
+  const uword n_cols;
+  const uword n_elem;
+  const uword n_nonzero;
+
+  // So that SpValProxy can call add_element() and delete_element().
+  friend class SpValProxy<SpSubview<eT> >;
+
+  protected:
+
+  arma_inline SpSubview(const SpMat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols);
+  arma_inline SpSubview(      SpMat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols);
+
+  public:
+
+  inline ~SpSubview();
+
+  inline const SpSubview& operator+= (const eT val);
+  inline const SpSubview& operator-= (const eT val);
+  inline const SpSubview& operator*= (const eT val);
+  inline const SpSubview& operator/= (const eT val);
+
+  inline const SpSubview& operator=(const SpSubview& x);
+
+  template<typename T1> inline const SpSubview& operator= (const Base<eT, T1>& x);
+  template<typename T1> inline const SpSubview& operator+=(const Base<eT, T1>& x);
+  template<typename T1> inline const SpSubview& operator-=(const Base<eT, T1>& x);
+  template<typename T1> inline const SpSubview& operator*=(const Base<eT, T1>& x);
+  template<typename T1> inline const SpSubview& operator%=(const Base<eT, T1>& x);
+  template<typename T1> inline const SpSubview& operator/=(const Base<eT, T1>& x);
+
+  template<typename T1> inline const SpSubview& operator= (const SpBase<eT, T1>& x);
+  template<typename T1> inline const SpSubview& operator+=(const SpBase<eT, T1>& x);
+  template<typename T1> inline const SpSubview& operator-=(const SpBase<eT, T1>& x);
+  template<typename T1> inline const SpSubview& operator*=(const SpBase<eT, T1>& x);
+  template<typename T1> inline const SpSubview& operator%=(const SpBase<eT, T1>& x);
+  template<typename T1> inline const SpSubview& operator/=(const SpBase<eT, T1>& x);
+
+  /*
+  inline static void extract(SpMat<eT>& out, const SpSubview& in);
+
+  inline static void  plus_inplace(Mat<eT>& out, const subview& in);
+  inline static void minus_inplace(Mat<eT>& out, const subview& in);
+  inline static void schur_inplace(Mat<eT>& out, const subview& in);
+  inline static void   div_inplace(Mat<eT>& out, const subview& in);
+  */
+
+  inline void fill(const eT val);
+  inline void zeros();
+  inline void ones();
+  inline void eye();
+
+  arma_hot inline SpValProxy<SpSubview<eT> > operator[](const uword i);
+  arma_hot inline eT                         operator[](const uword i) const;
+
+  arma_hot inline SpValProxy<SpSubview<eT> > operator()(const uword i);
+  arma_hot inline eT                         operator()(const uword i) const;
+
+  arma_hot inline SpValProxy<SpSubview<eT> > operator()(const uword in_row, const uword in_col);
+  arma_hot inline eT                         operator()(const uword in_row, const uword in_col) const;
+
+  arma_hot inline SpValProxy<SpSubview<eT> > at(const uword i);
+  arma_hot inline eT                         at(const uword i) const;
+
+  arma_hot inline SpValProxy<SpSubview<eT> > at(const uword in_row, const uword in_col);
+  arma_hot inline eT                         at(const uword in_row, const uword in_col) const;
+
+  inline bool check_overlap(const SpSubview& x) const;
+
+  inline bool is_vec() const;
+
+  inline       SpSubview row(const uword row_num);
+  inline const SpSubview row(const uword row_num) const;
+
+  inline       SpSubview col(const uword col_num);
+  inline const SpSubview col(const uword col_num) const;
+
+  inline       SpSubview rows(const uword in_row1, const uword in_row2);
+  inline const SpSubview rows(const uword in_row1, const uword in_row2) const;
+
+  inline       SpSubview cols(const uword in_col1, const uword in_col2);
+  inline const SpSubview cols(const uword in_col1, const uword in_col2) const;
+
+  inline       SpSubview submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2);
+  inline const SpSubview submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const;
+
+  inline       SpSubview submat(const span& row_span, const span& col_span);
+  inline const SpSubview submat(const span& row_span, const span& col_span) const;
+
+  inline       SpSubview operator()(const uword row_num, const span& col_span);
+  inline const SpSubview operator()(const uword row_num, const span& col_span) const;
+
+  inline       SpSubview operator()(const span& row_span, const uword col_num);
+  inline const SpSubview operator()(const span& row_span, const uword col_num) const;
+
+  inline       SpSubview operator()(const span& row_span, const span& col_span);
+  inline const SpSubview operator()(const span& row_span, const span& col_span) const;
+
+/* not yet
+  inline       SpSubview_row<eT> row(const uword row_num);
+  inline const SpSubview_row<eT> row(const uword row_num) const;
+
+  inline            SpSubview_row<eT> operator()(const uword row_num, const span& col_span);
+  inline      const SpSubview_row<eT> operator()(const uword row_num, const span& col_span) const;
+
+  inline       SpSubview_col<eT> col(const uword col_num);
+  inline const SpSubview_col<eT> col(const uword col_num) const;
+
+  inline            SpSubview_col<eT> operator()(const span& row_span, const uword col_num);
+  inline      const SpSubview_col<eT> operator()(const span& row_span, const uword col_num) const;
+
+  inline            Col<eT>  unsafe_col(const uword col_num);
+  inline      const Col<eT>  unsafe_col(const uword col_num) const;
+
+  inline       SpSubview<eT> rows(const uword in_row1, const uword in_row2);
+  inline const SpSubview<eT> rows(const uword in_row1, const uword in_row2) const;
+
+  inline       SpSubview<eT> cols(const uword in_col1, const uword in_col2);
+  inline const SpSubview<eT> cols(const uword in_col1, const uword in_col2) const;
+
+  inline       SpSubview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2);
+  inline const SpSubview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const;
+
+  inline            SpSubview<eT> submat    (const span& row_span, const span& col_span);
+  inline      const SpSubview<eT> submat    (const span& row_span, const span& col_span) const;
+
+  inline            SpSubview<eT> operator()(const span& row_span, const span& col_span);
+  inline      const SpSubview<eT> operator()(const span& row_span, const span& col_span) const;
+
+  inline       diagview<eT> diag(const s32 in_id = 0);
+  inline const diagview<eT> diag(const s32 in_id = 0) const;
+*/
+
+  inline void swap_rows(const uword in_row1, const uword in_row2);
+  inline void swap_cols(const uword in_col1, const uword in_col2);
+
+  // Forward declarations.
+  class iterator_base;
+  class const_iterator;
+  class iterator;
+  class const_row_iterator;
+  class row_iterator;
+
+  // Similar to SpMat iterators but automatically iterates past and ignores values not in the subview.
+  class iterator_base
+    {
+    public:
+
+    inline iterator_base(const SpSubview& in_M);
+    inline iterator_base(const SpSubview& in_M, const uword col, const uword pos, const uword skip_pos);
+
+    inline eT operator*() const;
+
+    // Don't hold location internally; call "dummy" methods to get that information.
+    arma_inline uword row() const { return M.m.row_indices[internal_pos + skip_pos] - M.aux_row1; }
+    arma_inline uword col() const { return internal_col;                                          }
+    arma_inline uword pos() const { return internal_pos;                                          }
+
+    arma_aligned const SpSubview& M;
+    arma_aligned       uword      internal_col;
+    arma_aligned       uword      internal_pos;
+    arma_aligned       uword      skip_pos; // not used in row_iterator or const_row_iterator
+
+    // So that we satisfy the STL iterator types.
+    typedef std::bidirectional_iterator_tag iterator_category;
+    typedef eT                              value_type;
+    typedef uword                           difference_type; // not certain on this one
+    typedef const eT*                       pointer;
+    typedef const eT&                       reference;
+    };
+
+  class const_iterator : public iterator_base
+    {
+    public:
+
+    inline const_iterator(const SpSubview& in_M, uword initial_pos = 0);
+    inline const_iterator(const SpSubview& in_M, uword in_row, uword in_col);
+    inline const_iterator(const SpSubview& in_M, uword in_row, uword in_col, uword in_pos, uword skip_pos);
+    inline const_iterator(const const_iterator& other);
+
+    inline const_iterator& operator++();
+    inline const_iterator  operator++(int);
+
+    inline const_iterator& operator--();
+    inline const_iterator  operator--(int);
+
+    inline bool operator!=(const const_iterator& rhs) const;
+    inline bool operator==(const const_iterator& rhs) const;
+
+    inline bool operator!=(const typename SpMat<eT>::const_iterator& rhs) const;
+    inline bool operator==(const typename SpMat<eT>::const_iterator& rhs) const;
+
+    inline bool operator!=(const const_row_iterator& rhs) const;
+    inline bool operator==(const const_row_iterator& rhs) const;
+
+    inline bool operator!=(const typename SpMat<eT>::const_row_iterator& rhs) const;
+    inline bool operator==(const typename SpMat<eT>::const_row_iterator& rhs) const;
+    };
+
+  class iterator : public const_iterator
+    {
+    public:
+
+    inline iterator(SpSubview& in_M, const uword initial_pos = 0) : const_iterator(in_M, initial_pos) { }
+    inline iterator(SpSubview& in_M, const uword in_row, const uword in_col) : const_iterator(in_M, in_row, in_col) { }
+    inline iterator(SpSubview& in_M, const uword in_row, const uword in_col, const uword in_pos, const uword in_skip_pos) : const_iterator(in_M, in_row, in_col, in_pos, in_skip_pos) { }
+    inline iterator(const iterator& other) : const_iterator(other) { }
+
+    inline SpValProxy<SpSubview<eT> > operator*();
+
+    // overloads needed for return type correctness
+    inline iterator& operator++();
+    inline iterator  operator++(int);
+
+    inline iterator& operator--();
+    inline iterator  operator--(int);
+
+    // This has a different value_type than iterator_base.
+    typedef SpValProxy<SpSubview<eT> >        value_type;
+    typedef const SpValProxy<SpSubview<eT> >* pointer;
+    typedef const SpValProxy<SpSubview<eT> >& reference;
+    };
+
+  class const_row_iterator : public iterator_base
+    {
+    public:
+
+    inline const_row_iterator(const SpSubview& in_M, uword initial_pos = 0);
+    inline const_row_iterator(const SpSubview& in_M, uword in_row, uword in_col);
+    inline const_row_iterator(const const_row_iterator& other);
+
+    inline const_row_iterator& operator++();
+    inline const_row_iterator  operator++(int);
+
+    inline const_row_iterator& operator--();
+    inline const_row_iterator  operator--(int);
+
+    uword internal_row; // Hold row internally because we use internal_pos differently.
+    uword actual_pos; // Actual position in subview's parent matrix.
+
+    arma_inline eT operator*() const { return iterator_base::M.m.values[actual_pos]; }
+
+    arma_inline uword row() const { return internal_row; }
+
+    inline bool operator!=(const const_iterator& rhs) const;
+    inline bool operator==(const const_iterator& rhs) const;
+
+    inline bool operator!=(const typename SpMat<eT>::const_iterator& rhs) const;
+    inline bool operator==(const typename SpMat<eT>::const_iterator& rhs) const;
+
+    inline bool operator!=(const const_row_iterator& rhs) const;
+    inline bool operator==(const const_row_iterator& rhs) const;
+
+    inline bool operator!=(const typename SpMat<eT>::const_row_iterator& rhs) const;
+    inline bool operator==(const typename SpMat<eT>::const_row_iterator& rhs) const;
+    };
+
+  class row_iterator : public const_row_iterator
+    {
+    public:
+
+    inline row_iterator(SpSubview& in_M, uword initial_pos = 0) : const_row_iterator(in_M, initial_pos) { }
+    inline row_iterator(SpSubview& in_M, uword in_row, uword in_col) : const_row_iterator(in_M, in_row, in_col) { }
+    inline row_iterator(const row_iterator& other) : const_row_iterator(other) { }
+
+    inline SpValProxy<SpSubview<eT> > operator*();
+
+    // overloads needed for return type correctness
+    inline row_iterator& operator++();
+    inline row_iterator  operator++(int);
+
+    inline row_iterator& operator--();
+    inline row_iterator  operator--(int);
+
+    // This has a different value_type than iterator_base.
+    typedef SpValProxy<SpSubview<eT> >        value_type;
+    typedef const SpValProxy<SpSubview<eT> >* pointer;
+    typedef const SpValProxy<SpSubview<eT> >& reference;
+    };
+
+  inline iterator           begin();
+  inline const_iterator     begin() const;
+
+  inline iterator           begin_col(const uword col_num);
+  inline const_iterator     begin_col(const uword col_num) const;
+
+  inline row_iterator       begin_row(const uword row_num = 0);
+  inline const_row_iterator begin_row(const uword row_num = 0) const;
+
+  inline iterator           end();
+  inline const_iterator     end() const;
+
+  inline row_iterator       end_row();
+  inline const_row_iterator end_row() const;
+
+  inline row_iterator       end_row(const uword row_num = 0);
+  inline const_row_iterator end_row(const uword row_num = 0) const;
+
+
+  private:
+  friend class SpMat<eT>;
+  SpSubview();
+
+  // For use by SpValProxy.  We just update n_nonzero and pass the call on to the matrix.
+  inline arma_hot arma_warn_unused eT&  add_element(const uword in_row, const uword in_col, const eT in_val = 0.0);
+  inline arma_hot                  void delete_element(const uword in_row, const uword in_col);
+
+  };
+
+/*
+template<typename eT>
+class SpSubview_col : public SpSubview<eT>
+  {
+  public:
+
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+
+  inline void operator= (const SpSubview<eT>& x);
+  inline void operator= (const SpSubview_col& x);
+
+  template<typename T1>
+  inline void operator= (const Base<eT,T1>& x);
+
+  inline       SpSubview_col<eT> rows(const uword in_row1, const uword in_row2);
+  inline const SpSubview_col<eT> rows(const uword in_row1, const uword in_row2) const;
+
+  inline       SpSubview_col<eT> subvec(const uword in_row1, const uword in_row2);
+  inline const SpSubview_col<eT> subvec(const uword in_row1, const uword in_row2) const;
+
+
+  protected:
+
+  inline SpSubview_col(const Mat<eT>& in_m, const uword in_col);
+  inline SpSubview_col(      Mat<eT>& in_m, const uword in_col);
+
+  inline SpSubview_col(const Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows);
+  inline SpSubview_col(      Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows);
+
+
+  private:
+
+  friend class Mat<eT>;
+  friend class Col<eT>;
+  friend class SpSubview<eT>;
+
+  SpSubview_col();
+  };
+
+template<typename eT>
+class SpSubview_row : public SpSubview<eT>
+  {
+  public:
+
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+
+  inline void operator= (const SpSubview<eT>& x);
+  inline void operator= (const SpSubview_row& x);
+
+  template<typename T1>
+  inline void operator= (const Base<eT,T1>& x);
+
+  inline       SpSubview_row<eT> cols(const uword in_col1, const uword in_col2);
+  inline const SpSubview_row<eT> cols(const uword in_col1, const uword in_col2) const;
+
+  inline       SpSubview_row<eT> subvec(const uword in_col1, const uword in_col2);
+  inline const SpSubview_row<eT> subvec(const uword in_col1, const uword in_col2) const;
+
+
+  protected:
+
+  inline SpSubview_row(const Mat<eT>& in_m, const uword in_row);
+  inline SpSubview_row(      Mat<eT>& in_m, const uword in_row);
+
+  inline SpSubview_row(const Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols);
+  inline SpSubview_row(      Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols);
+
+
+  private:
+
+  friend class Mat<eT>;
+  friend class Row<eT>;
+  friend class SpSubview<eT>;
+
+  SpSubview_row();
+  };
+*/
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpSubview_iterators_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,962 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+//! \addtogroup SpSubview
+//! @{
+
+///////////////////////////////////////////////////////////////////////////////
+// SpSubview::iterator_base implementation                                   //
+///////////////////////////////////////////////////////////////////////////////
+
+template<typename eT>
+inline
+SpSubview<eT>::iterator_base::iterator_base(const SpSubview<eT>& in_M)
+  : M(in_M)
+  , internal_col(0)
+  , internal_pos(0)
+  , skip_pos(0)
+  {
+  // Technically this iterator is invalid (it may not point to a real element).
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>::iterator_base::iterator_base(const SpSubview<eT>& in_M, const uword in_col, const uword in_pos, const uword in_skip_pos)
+  : M(in_M)
+  , internal_col(in_col)
+  , internal_pos(in_pos)
+  , skip_pos    (in_skip_pos)
+  {
+  // Nothing to do.
+  }
+
+
+
+template<typename eT>
+inline
+eT
+SpSubview<eT>::iterator_base::operator*() const
+  {
+  return M.m.values[internal_pos + skip_pos];
+  }
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// SpSubview::const_iterator implementation                                  //
+///////////////////////////////////////////////////////////////////////////////
+
+template<typename eT>
+inline
+SpSubview<eT>::const_iterator::const_iterator(const SpSubview<eT>& in_M, const uword initial_pos)
+  : iterator_base(in_M, 0, initial_pos, 0)
+  {
+  // Corner case for empty subviews.
+  if(in_M.n_nonzero == 0)
+    {
+    iterator_base::internal_col = in_M.n_cols;
+    iterator_base::skip_pos     = in_M.m.n_nonzero;
+    return;
+    }
+
+  // Figure out the row and column of the position.
+  // lskip_pos holds the number of values which aren't part of this subview.
+  const uword aux_col = iterator_base::M.aux_col1;
+  const uword aux_row = iterator_base::M.aux_row1;
+  const uword ln_rows = iterator_base::M.n_rows;
+  const uword ln_cols = iterator_base::M.n_cols;
+
+  uword cur_pos   = 0; // off by one because we might be searching for pos 0
+  uword lskip_pos = iterator_base::M.m.col_ptrs[aux_col];
+  uword cur_col   = 0;
+
+  while(cur_pos < (iterator_base::internal_pos + 1))
+    {
+    // Have we stepped forward a column (or multiple columns)?
+    while(((lskip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]) && (cur_col < ln_cols))
+      {
+      ++cur_col;
+      }
+
+    // See if the current position is in the subview.
+    const uword row_index = iterator_base::M.m.row_indices[cur_pos + lskip_pos];
+    if(row_index < aux_row)
+      {
+      ++lskip_pos; // not valid
+      }
+    else if(row_index < (aux_row + ln_rows))
+      {
+      ++cur_pos; // valid, in the subview
+      }
+    else
+      {
+      // skip to end of column
+      const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1];
+      lskip_pos += (next_colptr - (cur_pos + lskip_pos));
+      }
+    }
+
+  iterator_base::internal_col = cur_col;
+  iterator_base::skip_pos     = lskip_pos;
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>::const_iterator::const_iterator(const SpSubview<eT>& in_M, const uword in_row, const uword in_col)
+  : iterator_base(in_M, in_col, 0, 0)
+  {
+  // Corner case for empty subviews.
+  if(in_M.n_nonzero == 0)
+    {
+    // We must be at the last position.
+    iterator_base::internal_col = in_M.n_cols;
+    iterator_base::skip_pos = in_M.m.n_nonzero;
+    return;
+    }
+
+  // We have a destination we want to be just after, but don't know what position that is.
+  // Because we have to count the points in this subview and not in this subview, this becomes a little difficult and slow.
+  const uword aux_col = iterator_base::M.aux_col1;
+  const uword aux_row = iterator_base::M.aux_row1;
+  const uword ln_rows = iterator_base::M.n_rows;
+  const uword ln_cols = iterator_base::M.n_cols;
+
+  uword cur_pos = 0;
+  uword skip_pos = iterator_base::M.m.col_ptrs[aux_col];
+  uword cur_col = 0;
+
+  while(cur_col < in_col)
+    {
+    // See if the current position is in the subview.
+    const uword row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos];
+    if(row_index < aux_row)
+      {
+      ++skip_pos;
+      }
+    else if(row_index < (aux_row + ln_rows))
+      {
+      ++cur_pos;
+      }
+    else
+      {
+      // skip to end of column
+      const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1];
+      skip_pos += (next_colptr - (cur_pos + skip_pos));
+      }
+
+    // Have we stepped forward a column (or multiple columns)?
+    while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]) && (cur_col < ln_cols))
+      {
+      ++cur_col;
+      }
+    }
+
+  // Now we are either on the right column or ahead of it.
+  if(cur_col == in_col)
+    {
+    // We have to find the right row index.
+    uword row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos];
+    while((row_index < (in_row + aux_row)))
+      {
+      if(row_index < aux_row)
+        {
+        ++skip_pos;
+        }
+      else
+        {
+        ++cur_pos;
+        }
+
+      // Ensure we didn't step forward a column; if we did, we need to stop.
+      while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]) && (cur_col < ln_cols))
+        {
+        ++cur_col;
+        }
+
+      if(cur_col != in_col)
+        {
+        break;
+        }
+
+      row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos];
+      }
+    }
+
+  // Now we need to find the next valid position in the subview.
+  uword row_index;
+  while(true)
+    {
+    const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1];
+    row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos];
+
+    // Are we at the last position?
+    if(cur_col >= ln_cols)
+      {
+      cur_col = ln_cols;
+      // Make sure we will be pointing at the last element in the parent matrix.
+      skip_pos = iterator_base::M.m.n_nonzero - iterator_base::M.n_nonzero;
+      break;
+      }
+
+    if(row_index < aux_row)
+      {
+      ++skip_pos;
+      }
+    else if(row_index < (aux_row + ln_rows))
+      {
+      break; // found
+      }
+    else
+      {
+      skip_pos += (next_colptr - (cur_pos + skip_pos));
+      }
+
+    // Did we move any columns?
+    while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]) && (cur_col < ln_cols))
+      {
+      ++cur_col;
+      }
+    }
+
+  // It is possible we have moved another column.
+  while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]) && (cur_col < ln_cols))
+    {
+    ++cur_col;
+    }
+
+  iterator_base::internal_pos = cur_pos;
+  iterator_base::skip_pos     = skip_pos;
+  iterator_base::internal_col = cur_col;
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>::const_iterator::const_iterator(const SpSubview<eT>& in_M, uword in_row, uword in_col, uword in_pos, uword in_skip_pos)
+  : iterator_base(in_M, in_col, in_pos, in_skip_pos)
+  {
+  // Nothing to do.
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>::const_iterator::const_iterator(const const_iterator& other)
+  : iterator_base(other.M, other.internal_col, other.internal_pos, other.skip_pos)
+  {
+  // Nothing to do.
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_iterator&
+SpSubview<eT>::const_iterator::operator++()
+  {
+  const uword aux_col = iterator_base::M.aux_col1;
+  const uword aux_row = iterator_base::M.aux_row1;
+  const uword ln_rows = iterator_base::M.n_rows;
+  const uword ln_cols = iterator_base::M.n_cols;
+
+  uword cur_col   = iterator_base::internal_col;
+  uword cur_pos   = iterator_base::internal_pos + 1;
+  uword lskip_pos = iterator_base::skip_pos;
+  uword row_index;
+
+  while(true)
+    {
+    const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1];
+    row_index = iterator_base::M.m.row_indices[cur_pos + lskip_pos];
+
+    // Did we move any columns?
+    while((cur_col < ln_cols) && ((lskip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]))
+      {
+      ++cur_col;
+      }
+
+    // Are we at the last position?
+    if(cur_col >= ln_cols)
+      {
+      cur_col = ln_cols;
+      // Make sure we will be pointing at the last element in the parent matrix.
+      lskip_pos = iterator_base::M.m.n_nonzero - iterator_base::M.n_nonzero;
+      break;
+      }
+
+    if(row_index < aux_row)
+      {
+      ++lskip_pos;
+      }
+    else if(row_index < (aux_row + ln_rows))
+      {
+      break; // found
+      }
+    else
+      {
+      lskip_pos += (next_colptr - (cur_pos + lskip_pos));
+      }
+    }
+
+  iterator_base::internal_pos = cur_pos;
+  iterator_base::internal_col = cur_col;
+  iterator_base::skip_pos     = lskip_pos;
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_iterator
+SpSubview<eT>::const_iterator::operator++(int)
+  {
+  typename SpSubview<eT>::const_iterator tmp(*this);
+
+  ++(*this);
+
+  return tmp;
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_iterator&
+SpSubview<eT>::const_iterator::operator--()
+  {
+  const uword aux_col = iterator_base::M.aux_col1;
+  const uword aux_row = iterator_base::M.aux_row1;
+  const uword ln_rows = iterator_base::M.n_rows;
+
+  uword cur_col  = iterator_base::internal_col;
+  uword cur_pos  = iterator_base::internal_pos - 1;
+  uword skip_pos = iterator_base::skip_pos;
+
+  // Special condition for end of iterator.
+  if((skip_pos + cur_pos + 1) == iterator_base::M.m.n_nonzero)
+    {
+    // We are at the last element.  So we need to set skip_pos back to what it
+    // would be if we didn't manually modify it back in operator++().
+    skip_pos = iterator_base::M.m.col_ptrs[cur_col + aux_col] - iterator_base::internal_pos;
+    }
+
+  uword row_index;
+
+  while(true)
+    {
+    const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col];
+    row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos];
+
+    // Did we move back any columns?
+    while((skip_pos + cur_pos) < iterator_base::M.m.col_ptrs[cur_col + aux_col])
+      {
+      --cur_col;
+      }
+
+    if(row_index < aux_row)
+      {
+      skip_pos -= (colptr - (cur_pos + skip_pos) + 1);
+      }
+    else if(row_index < (aux_row + ln_rows))
+      {
+      break; // found
+      }
+    else
+      {
+      --skip_pos;
+      }
+    }
+
+  iterator_base::internal_pos = cur_pos;
+  iterator_base::skip_pos     = skip_pos;
+  iterator_base::internal_col = cur_col;
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_iterator
+SpSubview<eT>::const_iterator::operator--(int)
+  {
+  typename SpSubview<eT>::const_iterator tmp(*this);
+
+  --(*this);
+
+  return tmp;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_iterator::operator==(const const_iterator& rhs) const
+  {
+  return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_iterator::operator!=(const const_iterator& rhs) const
+  {
+  return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_iterator::operator==(const typename SpMat<eT>::const_iterator& rhs) const
+  {
+  return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_iterator::operator!=(const typename SpMat<eT>::const_iterator& rhs) const
+  {
+  return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_iterator::operator==(const const_row_iterator& rhs) const
+  {
+  return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_iterator::operator!=(const const_row_iterator& rhs) const
+  {
+  return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_iterator::operator==(const typename SpMat<eT>::const_row_iterator& rhs) const
+  {
+  return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_iterator::operator!=(const typename SpMat<eT>::const_row_iterator& rhs) const
+  {
+  return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// SpSubview<eT>::iterator implementation                                    //
+///////////////////////////////////////////////////////////////////////////////
+
+template<typename eT>
+inline
+SpValProxy<SpSubview<eT> >
+SpSubview<eT>::iterator::operator*()
+  {
+  return SpValProxy<SpSubview<eT> >(
+    iterator_base::row(),
+    iterator_base::col(),
+    access::rw(iterator_base::M),
+    &(access::rw(iterator_base::M.m.values[iterator_base::internal_pos + iterator_base::skip_pos])));
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::iterator&
+SpSubview<eT>::iterator::operator++()
+  {
+  const_iterator::operator++();
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::iterator
+SpSubview<eT>::iterator::operator++(int)
+  {
+  typename SpSubview<eT>::iterator tmp(*this);
+
+  const_iterator::operator++();
+
+  return tmp;
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::iterator&
+SpSubview<eT>::iterator::operator--()
+  {
+  const_iterator::operator--();
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::iterator
+SpSubview<eT>::iterator::operator--(int)
+  {
+  typename SpSubview<eT>::iterator tmp(*this);
+
+  const_iterator::operator--();
+
+  return tmp;
+  }
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// SpSubview<eT>::const_row_iterator implementation                          //
+///////////////////////////////////////////////////////////////////////////////
+
+template<typename eT>
+inline
+SpSubview<eT>::const_row_iterator::const_row_iterator(const SpSubview<eT>& in_M, uword initial_pos)
+  : iterator_base(in_M, 0, initial_pos, 0)
+  , internal_row(0)
+  , actual_pos(0)
+  {
+  // Corner case for empty subviews.
+  if(in_M.n_nonzero == 0)
+    {
+    iterator_base::internal_col = 0;
+    internal_row = in_M.n_rows;
+    iterator_base::skip_pos = in_M.m.n_nonzero;
+    return;
+    }
+
+  const uword aux_col = iterator_base::M.aux_col1;
+  const uword aux_row = iterator_base::M.aux_row1;
+  const uword ln_cols = iterator_base::M.n_cols;
+
+  // We don't know where the elements are in each row.  What we will do is
+  // loop across all valid columns looking for elements in row 0 (and add to
+  // our sum), then in row 1, and so forth, until we get to the desired
+  // position.
+  uword cur_pos = -1;
+  uword cur_row = 0;
+  uword cur_col = 0;
+
+  while(true)
+    {
+    // Is there anything in the column we are looking at?
+    const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col];
+    const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1];
+
+    for(uword ind = colptr; (ind < next_colptr) && (iterator_base::M.m.row_indices[ind] <= (cur_row + aux_row)); ++ind)
+      {
+      // There is something in this column.  Is it in the row we are looking at?
+      const uword row_index = iterator_base::M.m.row_indices[ind];
+      if(row_index == (cur_row + aux_row))
+        {
+        // Yes, it is in the right row.
+        if(++cur_pos == iterator_base::internal_pos)
+          {
+          iterator_base::internal_col = cur_col;
+          internal_row = cur_row;
+          actual_pos = ind;
+
+          return;
+          }
+
+        // We are done with this column.  Break to the column incrementing code (directly below).
+        break;
+        }
+      else if(row_index > (cur_row + aux_row))
+        {
+        break; // Can't be in this column.
+        }
+      }
+
+    cur_col++; // Done with the column.  Move on.
+    if(cur_col == ln_cols)
+      {
+      // Out of columns.  Loop back to the beginning and look on the next row.
+      cur_col = 0;
+      cur_row++;
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>::const_row_iterator::const_row_iterator(const SpSubview<eT>& in_M, uword in_row, uword in_col)
+  : iterator_base(in_M, in_col, 0, 0)
+  , internal_row(0)
+  , actual_pos(0)
+  {
+  // We have a destination we want to be just after, but don't know what that
+  // position is.  Because we will have to loop over everything anyway, create
+  // another iterator and loop it until it is at the right place, then take its
+  // information.
+  const_row_iterator it(in_M, 0);
+  while((it.row() < in_row) || ((it.row() == in_row) && (it.col() < in_col)))
+    {
+    ++it;
+    }
+
+  iterator_base::internal_col = it.col();
+  iterator_base::internal_pos = it.pos();
+  iterator_base::skip_pos = it.skip_pos;
+  internal_row = it.internal_row;
+  actual_pos = it.actual_pos;
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>::const_row_iterator::const_row_iterator(const const_row_iterator& other)
+  : iterator_base(other.M, other.internal_col, other.internal_pos, other.skip_pos)
+  , internal_row(other.internal_row)
+  , actual_pos(other.actual_pos)
+  {
+  // Nothing to do.
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_row_iterator&
+SpSubview<eT>::const_row_iterator::operator++()
+  {
+  // We just need to find the next nonzero element.
+  ++iterator_base::internal_pos;
+
+  // If we have exceeded the bounds, update accordingly.
+  if(iterator_base::internal_pos >= iterator_base::M.n_nonzero)
+    {
+    internal_row = iterator_base::M.n_rows;
+    iterator_base::internal_col = 0;
+    actual_pos = iterator_base::M.m.n_nonzero;
+
+    return *this;
+    }
+
+  // Otherwise, we need to search.
+  uword cur_col = iterator_base::internal_col;
+  uword cur_row = internal_row;
+
+  const uword aux_col = iterator_base::M.aux_col1;
+  const uword aux_row = iterator_base::M.aux_row1;
+  const uword ln_cols = iterator_base::M.n_cols;
+
+  while(true)
+    {
+    // Increment the current column and see if we are on a new row.
+    if(++cur_col == ln_cols)
+      {
+      cur_col = 0;
+      ++cur_row;
+      }
+
+    // Is there anything in this new column?
+    const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col];
+    const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1];
+
+    for(uword ind = colptr; (ind < next_colptr) && (iterator_base::M.m.row_indices[ind] <= (cur_row + aux_row)); ++ind)
+      {
+      const uword row_index = iterator_base::M.m.row_indices[ind];
+
+      if((row_index - aux_row) == cur_row)
+        {
+        // We have successfully incremented.
+        internal_row = cur_row;
+        actual_pos = ind;
+        iterator_base::internal_col = cur_col;
+
+        return *this;
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_row_iterator
+SpSubview<eT>::const_row_iterator::operator++(int)
+  {
+  typename SpSubview<eT>::const_row_iterator tmp(*this);
+
+  ++(*this);
+
+  return tmp;
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_row_iterator&
+SpSubview<eT>::const_row_iterator::operator--()
+  {
+  // We just need to find the previous element.
+//  if(iterator_base::pos == 0)
+//    {
+//    // We cannot decrement.
+//    return *this;
+//    }
+//  else if(iterator_base::pos == iterator_base::M.n_nonzero)
+//    {
+//    // We will be coming off the last element.  We need to reset the row correctly, because we set row = 0 in the last matrix position.
+//    iterator_base::row = iterator_base::M.n_rows - 1;
+//    }
+//  else if(iterator_base::pos > iterator_base::M.n_nonzero)
+//    {
+//    // This shouldn't happen...
+//    iterator_base::pos--;
+//    return *this;
+//    }
+
+  iterator_base::internal_pos--;
+
+  // We have to search backwards.
+  uword cur_col = iterator_base::internal_col;
+  uword cur_row = internal_row;
+
+  const uword aux_col = iterator_base::M.aux_col1;
+  const uword aux_row = iterator_base::M.aux_row1;
+  const uword ln_cols = iterator_base::M.n_cols;
+
+  while(true)
+    {
+    // Decrement the current column and see if we are on a new row.
+    if(--cur_col > ln_cols)
+      {
+      cur_col = ln_cols - 1;
+      cur_row--;
+      }
+
+    // Is there anything in this new column?
+    const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col];
+    const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1];
+
+    for(uword ind = colptr; (ind < next_colptr) && (iterator_base::M.m.row_indices[ind] <= (cur_row + aux_row)); ++ind)
+      {
+      const uword row_index = iterator_base::M.m.row_indices[ind];
+
+      if((row_index - aux_row) == cur_row)
+        {
+        iterator_base::internal_col = cur_col;
+        internal_row = cur_row;
+        actual_pos = ind;
+
+        return *this;
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_row_iterator
+SpSubview<eT>::const_row_iterator::operator--(int)
+  {
+  typename SpSubview<eT>::const_row_iterator tmp(*this);
+
+  --(*this);
+
+  return tmp;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_row_iterator::operator==(const const_iterator& rhs) const
+  {
+  return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_row_iterator::operator!=(const const_iterator& rhs) const
+  {
+  return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_row_iterator::operator==(const typename SpMat<eT>::const_iterator& rhs) const
+  {
+  return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_row_iterator::operator!=(const typename SpMat<eT>::const_iterator& rhs) const
+  {
+  return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_row_iterator::operator==(const const_row_iterator& rhs) const
+  {
+  return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_row_iterator::operator!=(const const_row_iterator& rhs) const
+  {
+  return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_row_iterator::operator==(const typename SpMat<eT>::const_row_iterator& rhs) const
+  {
+  return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::const_row_iterator::operator!=(const typename SpMat<eT>::const_row_iterator& rhs) const
+  {
+  return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col);
+  }
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// SpSubview<eT>::row_iterator implementation                                //
+///////////////////////////////////////////////////////////////////////////////
+
+template<typename eT>
+inline
+SpValProxy<SpSubview<eT> >
+SpSubview<eT>::row_iterator::operator*()
+  {
+  return SpValProxy<SpSubview<eT> >(
+    const_row_iterator::internal_row,
+    iterator_base::internal_col,
+    access::rw(iterator_base::M),
+    &access::rw(iterator_base::M.m.values[const_row_iterator::actual_pos]));
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::row_iterator&
+SpSubview<eT>::row_iterator::operator++()
+  {
+  const_row_iterator::operator++();
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::row_iterator
+SpSubview<eT>::row_iterator::operator++(int)
+  {
+  typename SpSubview<eT>::row_iterator tmp(*this);
+
+  ++(*this);
+
+  return tmp;
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::row_iterator&
+SpSubview<eT>::row_iterator::operator--()
+  {
+  const_row_iterator::operator--();
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::row_iterator
+SpSubview<eT>::row_iterator::operator--(int)
+  {
+  typename SpSubview<eT>::row_iterator tmp(*this);
+
+  --(*this);
+
+  return tmp;
+  }
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpSubview_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,1550 @@
+// Copyright (C) 2011-2012 Ryan Curtin
+// Copyright (C) 2011 Matthew Amidon
+// Copyright (C) 2012 Conrad Sanderson
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup SpSubview
+//! @{
+
+template<typename eT>
+arma_inline
+SpSubview<eT>::SpSubview(const SpMat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols)
+  : m(in_m)
+  , aux_row1(in_row1)
+  , aux_col1(in_col1)
+  , n_rows(in_n_rows)
+  , n_cols(in_n_cols)
+  , n_elem(in_n_rows * in_n_cols)
+  , n_nonzero(0)
+  {
+  arma_extra_debug_sigprint();
+
+  // There must be a O(1) way to do this
+  uword lend     = m.col_ptrs[in_col1 + in_n_cols];
+  uword lend_row = in_row1 + in_n_rows;
+  uword count   = 0;
+
+  for(uword i = m.col_ptrs[in_col1]; i < lend; ++i)
+    {
+    if(m.row_indices[i] >= in_row1 && m.row_indices[i] < lend_row)
+      {
+      ++count;
+      }
+    }
+
+  access::rw(n_nonzero) = count;
+  }
+
+
+
+template<typename eT>
+arma_inline
+SpSubview<eT>::SpSubview(SpMat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols)
+  : m(in_m)
+  , aux_row1(in_row1)
+  , aux_col1(in_col1)
+  , n_rows(in_n_rows)
+  , n_cols(in_n_cols)
+  , n_elem(in_n_rows * in_n_cols)
+  , n_nonzero(0)
+  {
+  arma_extra_debug_sigprint();
+
+  // There must be a O(1) way to do this
+  uword lend     = m.col_ptrs[in_col1 + in_n_cols];
+  uword lend_row = in_row1 + in_n_rows;
+  uword count    = 0;
+
+  for(uword i = m.col_ptrs[in_col1]; i < lend; ++i)
+    {
+    if(m.row_indices[i] >= in_row1 && m.row_indices[i] < lend_row)
+      {
+      ++count;
+      }
+    }
+
+  access::rw(n_nonzero) = count;
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>::~SpSubview()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator+=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+
+  if(val == eT(0))
+    {
+    return *this;
+    }
+
+  const uword lstart_row = aux_row1;
+  const uword lend_row   = aux_row1 + n_rows;
+  
+  const uword lstart_col = aux_col1;
+  const uword lend_col   = aux_col1 + n_cols;
+
+  const uword old_n_nonzero = m.n_nonzero;
+
+  // iterate over our part of the sparse matrix
+  for(uword lcol = lstart_col; lcol < lend_col; ++lcol)
+  for(uword lrow = lstart_row; lrow < lend_row; ++lrow)
+    {
+    access::rw(m).at(lrow, lcol) += val;
+    }
+
+  const uword new_n_nonzero = m.n_nonzero;
+
+  access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator-=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+
+  if(val == eT(0))
+    {
+    return *this;
+    }
+
+  const uword lstart_row = aux_row1;
+  const uword lend_row   = aux_row1 + n_rows;
+  
+  const uword lstart_col = aux_col1;
+  const uword lend_col   = aux_col1 + n_cols;
+
+  const uword old_n_nonzero = m.n_nonzero;
+
+  for(uword lcol = lstart_col; lcol < lend_col; ++lcol)
+  for(uword lrow = lstart_row; lrow < lend_row; ++lrow)
+    {
+    access::rw(m).at(lrow, lcol) -= val;
+    }
+
+  const uword new_n_nonzero = m.n_nonzero;
+
+  access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator*=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+
+  if(val == eT(0))
+    {
+    // Turn it all into zeros.
+    for(iterator it(*this); it != end(); ++it)
+      {
+      (*it) = eT(0); // zero out the value.
+      it.internal_pos--;
+      }
+
+    return *this;
+    }
+
+  const uword lstart_row = aux_row1;
+  const uword lend_row   = aux_row1 + n_rows;
+  
+  const uword lstart_col = aux_col1;
+  const uword lend_col   = aux_col1 + n_cols;
+
+  for(uword c = lstart_col; c < lend_col; ++c)
+    {
+    for(uword r = m.col_ptrs[c]; r < m.col_ptrs[c + 1]; ++r)
+      {
+      if(m.row_indices[r] >= lstart_row && m.row_indices[r] < lend_row)
+        {
+        access::rw(m.values[r]) *= val;
+        }
+      }
+    }
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator/=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+
+  const uword lstart_col = aux_col1;
+  const uword lend_col   = aux_col1 + n_cols;
+  
+  const uword lstart_row = aux_row1;
+  const uword lend_row   = aux_row1 + n_rows;
+
+  const uword old_n_nonzero = m.n_nonzero;
+
+  for(uword c = lstart_col; c < lend_col; ++c)
+  for(uword r = lstart_row; r < lend_row; ++r)
+    {
+    access::rw(m).at(r, c) /= val;
+    }
+
+  const uword new_n_nonzero = m.n_nonzero;
+
+  access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator=(const Base<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+
+  const Proxy<T1> P(x.get_ref());
+
+  arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "insert into sparse submatrix");
+
+  const uword old_n_nonzero = m.n_nonzero;
+
+  for(uword c = 0; c < n_cols; ++c)
+    {
+    for(uword r = 0; r < n_rows; ++r)
+      {
+      at(r, c) = P.at(r, c);
+      }
+    }
+
+  const uword new_n_nonzero = m.n_nonzero;
+
+  access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator+=(const Base<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+
+  const Proxy<T1> P(x.get_ref());
+
+  arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "addition");
+
+  const uword old_n_nonzero = m.n_nonzero;
+
+  for(uword c = 0; c < n_cols; ++c)
+    {
+    for(uword r = 0; r < n_rows; ++r)
+      {
+      at(r, c) += P.at(r, c);
+      }
+    }
+
+  const uword new_n_nonzero = m.n_nonzero;
+
+  access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator-=(const Base<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+
+  const Proxy<T1> P(x.get_ref());
+
+  arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "subtraction");
+
+  const uword old_n_nonzero = m.n_nonzero;
+
+  for(uword c = 0; c < n_cols; ++c)
+    {
+    for(uword r = 0; r < n_rows; ++r)
+      {
+      at(r, c) -= P.at(r, c);
+      }
+    }
+
+  const uword new_n_nonzero = m.n_nonzero;
+
+  access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator*=(const Base<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+
+  const Proxy<T1> P(x.get_ref());
+
+  // Must be exactly the same size for this (we can't modify our own size).
+  arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "matrix multiplication");
+
+  SpMat<eT> tmp(*this);
+  Mat<eT> other_tmp(x.get_ref());
+  tmp *= other_tmp;
+  operator=(tmp);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator%=(const Base<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+
+  const Proxy<T1> P(x.get_ref());
+
+  arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "element-wise multiplication");
+
+  const uword old_n_nonzero = m.n_nonzero;
+
+  for(iterator it(*this); it != end(); ++it)
+    {
+    (*it) *= P.at(it.row(), it.col());
+    if(P.at(it.row(), it.col()) == eT(0))
+      {
+      it.internal_pos--;
+      }
+    }
+
+  const uword new_n_nonzero = m.n_nonzero;
+
+  access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator/=(const Base<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+
+  const Proxy<T1> P(x.get_ref());
+
+  arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "element-wise division");
+
+  const uword old_n_nonzero = m.n_nonzero;
+
+  for(uword c = 0; c < n_cols; ++c)
+    {
+    for(uword r = 0; r < n_rows; ++r)
+      {
+      at(r, c) /= P.at(r, c);
+      }
+    }
+
+  const uword new_n_nonzero = m.n_nonzero;
+
+  access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
+
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator=(const SpSubview<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "insertion into sparse submatrix");
+  
+  const bool alias = ( &m == &(x.m) );
+  
+  if(alias == false)
+    {
+    const_iterator cit = x.begin();
+    iterator        it = begin();
+    
+    while((cit != x.end()) || (it != end()))
+      {
+      if((cit.row() == it.row()) && (cit.col() == it.col()))
+        {
+        (*it) = (*cit);
+        ++it;
+        ++cit;
+        }
+      else
+        {
+        if((cit.col() > it.col()) || ((cit.col() == it.col()) && (cit.row() > it.row())))
+          {
+          // cit is "ahead"
+          (*it) = eT(0); // erase element
+          it.internal_pos--; // update iterator so it still works
+          ++it;
+          }
+        else
+          {
+          // it is "ahead"
+          at(cit.row(), cit.col()) = (*cit);
+          it.internal_pos++; // update iterator so it still works
+          ++cit;
+          }
+        }
+      }
+    
+    access::rw(n_nonzero) = x.n_nonzero;
+    }
+  else
+    {
+    const SpMat<eT> tmp(x);
+    
+    (*this).operator=(tmp);
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator=(const SpBase<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> p(x.get_ref());
+  
+  arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "insertion into sparse submatrix");
+  
+  if(p.is_alias(m) == false)
+    {
+    typename SpProxy<T1>::const_iterator_type cit = p.begin();
+    iterator it(*this);
+
+    while((cit != p.end()) || (it != end()))
+      {
+      if(cit == it) // at the same location
+        {
+        (*it) = (*cit);
+        ++it;
+        ++cit;
+        }
+      else
+        {
+        if((cit.col() > it.col()) || ((cit.col() == it.col()) && (cit.row() > it.row())))
+          {
+          // cit is "ahead"
+          (*it) = eT(0); // erase element
+          it.internal_pos--; // update iterator so it still works
+          ++it;
+          }
+        else
+          {
+          // it is "ahead"
+          at(cit.row(), cit.col()) = (*cit);
+          it.internal_pos++; // update iterator so it still works
+          ++cit;
+          }
+        }
+      }
+    }
+  else
+    {
+    const SpMat<eT> tmp(p.Q);
+    
+    (*this).operator=(tmp);
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator+=(const SpBase<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> p(x.get_ref());
+  
+  arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "addition");
+  
+  if(p.is_alias(m) == false)
+    {
+    typename SpProxy<T1>::const_iterator_type cit = p.begin();
+
+    while(cit != p.end())
+      {
+      at(cit.row(), cit.col()) += (*cit);
+      ++cit;
+      }
+    }
+  else
+    {
+    const SpMat<eT> tmp(p.Q);
+    
+    (*this).operator+=(tmp);
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator-=(const SpBase<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> p(x.get_ref());
+  
+  arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "subtraction");
+  
+  if(p.is_alias(m) == false)
+    {
+    typename SpProxy<T1>::const_iterator_type cit = p.begin();
+    
+    while(cit != p.end())
+      {
+      at(cit.row(), cit.col()) -= (*cit);
+      ++cit;
+      }
+    }
+  else
+    {
+    const SpMat<eT> tmp(p.Q);
+    
+    (*this).operator-=(tmp);
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator*=(const SpBase<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+
+  const SpProxy<T1> p(x.get_ref());
+
+  arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "matrix multiplication");
+
+  // Because we have to use a temporary anyway, it doesn't make sense to
+  // reimplement this here.
+  return operator=((*this) * x.get_ref());
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator%=(const SpBase<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> p(x.get_ref());
+  
+  arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise multiplication");
+  
+  if(p.is_alias(m) == false)
+    {
+    typename SpProxy<T1>::const_iterator_type cit = p.begin();
+    iterator it(*this);
+
+    while((it != end()) || (cit != p.end()))
+      {
+      if((cit.row() == it.row()) && (cit.col() == it.col()))
+        {
+        (*it) *= (*cit);
+        ++it;
+        ++cit;
+        }
+      else
+        {
+        if((cit.col() > it.col()) || ((cit.col() == it.col()) && (cit.row() > it.row())))
+          {
+          // cit is "ahead"
+          (*it) = eT(0); // erase element -- x has a zero here
+          it.internal_pos--; // update iterator so it still works
+          ++it;
+          }
+        else
+          {
+          // it is "ahead"
+          ++cit;
+          }
+        }
+      }
+    }
+  else
+    {
+    const SpMat<eT> tmp(p.Q);
+    
+    (*this).operator%=(tmp);
+    }
+  
+  return *this;
+  }
+
+
+
+//! If you are using this function, you are probably misguided.
+template<typename eT>
+template<typename T1>
+inline
+const SpSubview<eT>&
+SpSubview<eT>::operator/=(const SpBase<eT, T1>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  SpProxy<T1> p(x.get_ref());
+  
+  arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise division");
+  
+  if(p.is_alias(m) == false)
+    {
+    for(uword lcol = 0; lcol < n_cols; ++lcol)
+    for(uword lrow = 0; lrow < n_rows; ++lrow)
+      {
+      at(lrow,lcol) /= p.at(lrow,lcol);
+      }
+    }
+  else
+    {
+    const SpMat<eT> tmp(p.Q);
+    
+    (*this).operator/=(tmp);
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpSubview<eT>::fill(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(val != eT(0))
+    {
+    // TODO: implement a faster version; the code below is slow
+    
+    const uword lstart_row = aux_row1;
+    const uword lend_row   = aux_row1 + n_rows;
+    
+    const uword lstart_col = aux_col1;
+    const uword lend_col   = aux_col1 + n_cols;
+
+    const uword orig_nonzero = m.n_nonzero;
+    
+    // iterate over our part of the sparse matrix
+    for(uword lcol = lstart_col; lcol < lend_col; ++lcol)
+    for(uword lrow = lstart_row; lrow < lend_row; ++lrow)
+      {
+      access::rw(m).at(lrow, lcol) = val;
+      }
+
+    access::rw(n_nonzero) += (m.n_nonzero - orig_nonzero);
+
+    }
+  else
+    {
+    (*this).zeros();
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpSubview<eT>::zeros()
+  {
+  arma_extra_debug_sigprint();
+  
+  // we can be a little smarter here
+  iterator it(*this);
+
+  while(it != end())
+    {
+    (*it) = eT(0);
+    it.internal_pos--; // hack to update iterator without requiring a new one
+    ++it;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpSubview<eT>::ones()
+  {
+  arma_extra_debug_sigprint();
+
+  (*this).fill(eT(1));
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpSubview<eT>::eye()
+  {
+  arma_extra_debug_sigprint();
+  
+  // clear other things
+  (*this).zeros();
+  
+  const uword orig_nonzero = m.n_nonzero;
+  
+  // now the diagonal ones
+  const uword end_index = std::min(n_rows, n_cols);
+  
+  for(uword ind = 0; ind < end_index; ++ind)
+    {
+    access::rw(m).at(ind + aux_row1, ind + aux_col1) = eT(1);
+    }
+  
+  access::rw(n_nonzero) += (m.n_nonzero - orig_nonzero);
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+SpValProxy<SpSubview<eT> >
+SpSubview<eT>::operator[](const uword i)
+  {
+  const uword lrow = i % n_rows;
+  const uword lcol = i / n_rows;
+
+  return (*this).at(lrow, lcol);
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+eT
+SpSubview<eT>::operator[](const uword i) const
+  {
+  const uword lrow = i % n_rows;
+  const uword lcol = i / n_rows;
+
+  return (*this).at(lrow, lcol);
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+SpValProxy< SpSubview<eT> >
+SpSubview<eT>::operator()(const uword i)
+  {
+  arma_debug_check( (i >= n_elem), "SpSubview::operator(): index out of bounds");
+
+  const uword lrow = i % n_rows;
+  const uword lcol = i / n_rows;
+
+  return (*this).at(lrow, lcol);
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+eT
+SpSubview<eT>::operator()(const uword i) const
+  {
+  arma_debug_check( (i >= n_elem), "SpSubview::operator(): index out of bounds");
+
+  const uword lrow = i % n_rows;
+  const uword lcol = i / n_rows;
+
+  return (*this).at(lrow, lcol);
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+SpValProxy< SpSubview<eT> >
+SpSubview<eT>::operator()(const uword in_row, const uword in_col)
+  {
+  arma_debug_check( (in_row >= n_rows) || (in_col >= n_cols), "SpSubview::operator(): index out of bounds");
+
+  return (*this).at(in_row, in_col);
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+eT
+SpSubview<eT>::operator()(const uword in_row, const uword in_col) const
+  {
+  arma_debug_check( (in_row >= n_rows) || (in_col >= n_cols), "SpSubview::operator(): index out of bounds");
+
+  return (*this).at(in_row, in_col);
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+SpValProxy< SpSubview<eT> >
+SpSubview<eT>::at(const uword i)
+  {
+  const uword lrow = i % n_rows;
+  const uword lcol = i / n_cols;
+
+  return (*this).at(lrow, lcol);
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+eT
+SpSubview<eT>::at(const uword i) const
+  {
+  const uword lrow = i % n_rows;
+  const uword lcol = i / n_cols;
+
+  return (*this).at(lrow, lcol);
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+SpValProxy< SpSubview<eT> >
+SpSubview<eT>::at(const uword in_row, const uword in_col)
+  {
+  const uword colptr      = m.col_ptrs[in_col + aux_col1];
+  const uword next_colptr = m.col_ptrs[in_col + aux_col1 + 1];
+
+  // Step through the row indices to see if our element exists.
+  for(uword i = colptr; i < next_colptr; ++i)
+    {
+    // First check that we have not stepped past it.
+    if((in_row + aux_row1) < m.row_indices[i])
+      {
+      return SpValProxy<SpSubview<eT> >(in_row, in_col, *this); // Proxy for a zero value.
+      }
+
+    // Now check if we are at the correct place.
+    if((in_row + aux_row1) == m.row_indices[i]) // If we are, return a reference to the value.
+      {
+      return SpValProxy<SpSubview<eT> >(in_row, in_col, *this, &access::rw(m.values[i]));
+      }
+    }
+
+  // We did not find it, so it does not exist.
+  return SpValProxy<SpSubview<eT> >(in_row, in_col, *this);
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+eT
+SpSubview<eT>::at(const uword in_row, const uword in_col) const
+  {
+  return m.at(aux_row1 + in_row, aux_col1 + in_col);
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::check_overlap(const SpSubview<eT>& x) const
+  {
+  const subview<eT>& t = *this;
+
+  if(&t.m != &x.m)
+    {
+    return false;
+    }
+  else
+    {
+    if( (t.n_elem == 0) || (x.n_elem == 0) )
+      {
+      return false;
+      }
+    else
+      {
+      const uword t_row_start  = t.aux_row1;
+      const uword t_row_end_p1 = t_row_start + t.n_rows;
+
+      const uword t_col_start  = t.aux_col1;
+      const uword t_col_end_p1 = t_col_start + t.n_cols;
+
+      const uword x_row_start  = x.aux_row1;
+      const uword x_row_end_p1 = x_row_start + x.n_rows;
+
+      const uword x_col_start  = x.aux_col1;
+      const uword x_col_end_p1 = x_col_start + x.n_cols;
+
+      const bool outside_rows = ( (x_row_start >= t_row_end_p1) || (t_row_start >= x_row_end_p1) );
+      const bool outside_cols = ( (x_col_start >= t_col_end_p1) || (t_col_start >= x_col_end_p1) );
+
+      return ( (outside_rows == false) && (outside_cols == false) );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+SpSubview<eT>::is_vec() const
+  {
+  return ( (n_rows == 1) || (n_cols == 1) );
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>
+SpSubview<eT>::row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check(row_num >= n_rows, "SpSubview::row(): out of bounds");
+
+  return submat(row_num, 0, row_num, n_cols - 1);
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>
+SpSubview<eT>::row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check(row_num >= n_rows, "SpSubview::row(): out of bounds");
+
+  return submat(row_num, 0, row_num, n_cols - 1);
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>
+SpSubview<eT>::col(const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check(col_num >= n_cols, "SpSubview::col(): out of bounds");
+
+  return submat(0, col_num, n_rows - 1, col_num);
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>
+SpSubview<eT>::col(const uword col_num) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check(col_num >= n_cols, "SpSubview::col(): out of bounds");
+
+  return submat(0, col_num, n_rows - 1, col_num);
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>
+SpSubview<eT>::rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_row2 >= n_rows),
+    "SpSubview::rows(): indices out of bounds or incorrectly used"
+    );
+
+  return submat(in_row1, 0, in_row2, n_cols - 1);
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>
+SpSubview<eT>::rows(const uword in_row1, const uword in_row2) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_row2 >= n_rows),
+    "SpSubview::rows(): indices out of bounds or incorrectly used"
+    );
+
+  return submat(in_row1, 0, in_row2, n_cols - 1);
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>
+SpSubview<eT>::cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_col1 > in_col2) || (in_col2 >= n_cols),
+    "SpSubview::cols(): indices out of bounds or incorrectly used"
+    );
+
+  return submat(0, in_col1, n_rows - 1, in_col2);
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>
+SpSubview<eT>::cols(const uword in_col1, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_col1 > in_col2) || (in_col2 >= n_cols),
+    "SpSubview::cols(): indices out of bounds or incorrectly used"
+    );
+
+  return submat(0, in_col1, n_rows - 1, in_col2);
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>
+SpSubview<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
+    "SpSubview::submat(): indices out of bounds or incorrectly used"
+    );
+
+  return access::rw(m).submat(in_row1 + aux_row1, in_col1 + aux_col1, in_row2 + aux_row1, in_col2 + aux_col1);
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>
+SpSubview<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
+    "SpSubview::submat(): indices out of bounds or incorrectly used"
+    );
+
+  return m.submat(in_row1 + aux_row1, in_col1 + aux_col1, in_row2 + aux_row1, in_col2 + aux_col1);
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>
+SpSubview<eT>::submat(const span& row_span, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+
+  const bool row_all = row_span.whole;
+  const bool col_all = row_span.whole;
+
+  const uword in_row1 = row_all ? 0      : row_span.a;
+  const uword in_row2 = row_all ? n_rows : row_span.b;
+
+  const uword in_col1 = col_all ? 0      : col_span.a;
+  const uword in_col2 = col_all ? n_cols : col_span.b;
+
+  arma_debug_check
+    (
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= n_rows)))
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= n_cols))),
+    "SpSubview::submat(): indices out of bounds or incorrectly used"
+    );
+
+  return submat(in_row1, in_col1, in_row2, in_col2);
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>
+SpSubview<eT>::submat(const span& row_span, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+
+  const bool row_all = row_span.whole;
+  const bool col_all = row_span.whole;
+
+  const uword in_row1 = row_all ? 0          : row_span.a;
+  const uword in_row2 = row_all ? n_rows - 1 : row_span.b;
+
+  const uword in_col1 = col_all ? 0          : col_span.a;
+  const uword in_col2 = col_all ? n_cols - 1 : col_span.b;
+
+  arma_debug_check
+    (
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= n_rows)))
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= n_cols))),
+    "SpSubview::submat(): indices out of bounds or incorrectly used"
+    );
+
+  return submat(in_row1, in_col1, in_row2, in_col2);
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>
+SpSubview<eT>::operator()(const uword row_num, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+
+  return submat(span(row_num, row_num), col_span);
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>
+SpSubview<eT>::operator()(const uword row_num, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+
+  return submat(span(row_num, row_num), col_span);
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>
+SpSubview<eT>::operator()(const span& row_span, const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+
+  return submat(row_span, span(col_num, col_num));
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>
+SpSubview<eT>::operator()(const span& row_span, const uword col_num) const
+  {
+  arma_extra_debug_sigprint();
+
+  return submat(row_span, span(col_num, col_num));
+  }
+
+
+
+template<typename eT>
+inline
+SpSubview<eT>
+SpSubview<eT>::operator()(const span& row_span, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+
+  return submat(row_span, col_span);
+  }
+
+
+
+template<typename eT>
+inline
+const SpSubview<eT>
+SpSubview<eT>::operator()(const span& row_span, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+
+  return submat(row_span, col_span);
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpSubview<eT>::swap_rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check((in_row1 >= n_rows) || (in_row2 >= n_rows), "SpSubview::swap_rows(): invalid row index");
+
+  const uword lstart_col = aux_col1;
+  const uword lend_col   = aux_col1 + n_cols;
+
+  for(uword c = lstart_col; c < lend_col; ++c)
+    {
+    eT val = m.at(in_row1 + aux_row1, c);
+    access::rw(m).at(in_row2 + aux_row1, c) = m.at(in_row1 + aux_row1, c);
+    access::rw(m).at(in_row1 + aux_row1, c) = val;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpSubview<eT>::swap_cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+
+  arma_debug_check((in_col1 >= n_cols) || (in_col2 >= n_cols), "SpSubview::swap_cols(): invalid column index");
+
+  const uword lstart_row = aux_row1;
+  const uword lend_row   = aux_row1 + n_rows;
+
+  for(uword r = lstart_row; r < lend_row; ++r)
+    {
+    eT val = m.at(r, in_col1 + aux_col1);
+    access::rw(m).at(r, in_col1 + aux_col1) = m.at(r, in_col2 + aux_col1);
+    access::rw(m).at(r, in_col2 + aux_col1) = val;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::iterator
+SpSubview<eT>::begin()
+  {
+  return iterator(*this);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_iterator
+SpSubview<eT>::begin() const
+  {
+  return const_iterator(*this);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::iterator
+SpSubview<eT>::begin_col(const uword col_num)
+  {
+  return iterator(*this, 0, col_num);
+  }
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_iterator
+SpSubview<eT>::begin_col(const uword col_num) const
+  {
+  return const_iterator(*this, 0, col_num);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::row_iterator
+SpSubview<eT>::begin_row(const uword row_num)
+  {
+  return row_iterator(*this, row_num, 0);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_row_iterator
+SpSubview<eT>::begin_row(const uword row_num) const
+  {
+  return const_row_iterator(*this, row_num, 0);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::iterator
+SpSubview<eT>::end()
+  {
+  return iterator(*this, 0, n_cols, n_nonzero, m.n_nonzero - n_nonzero);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_iterator
+SpSubview<eT>::end() const
+  {
+  return const_iterator(*this, 0, n_cols, n_nonzero, m.n_nonzero - n_nonzero);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::row_iterator
+SpSubview<eT>::end_row()
+  {
+  return row_iterator(*this, n_nonzero);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_row_iterator
+SpSubview<eT>::end_row() const
+  {
+  return const_row_iterator(*this, n_nonzero);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::row_iterator
+SpSubview<eT>::end_row(const uword row_num)
+  {
+  return row_iterator(*this, row_num + 1, 0);
+  }
+
+
+
+template<typename eT>
+inline
+typename SpSubview<eT>::const_row_iterator
+SpSubview<eT>::end_row(const uword row_num) const
+  {
+  return const_row_iterator(*this, row_num + 1, 0);
+  }
+
+
+
+template<typename eT>
+inline
+arma_hot
+arma_warn_unused
+eT&
+SpSubview<eT>::add_element(const uword in_row, const uword in_col, const eT in_val)
+  {
+  arma_extra_debug_sigprint();
+
+  // This may not actually add an element.
+  const uword old_n_nonzero = m.n_nonzero;
+  eT& retval = access::rw(m).add_element(in_row + aux_row1, in_col + aux_col1, in_val);
+  // Update n_nonzero (if necessary).
+  access::rw(n_nonzero) += (m.n_nonzero - old_n_nonzero);
+
+  return retval;
+  }
+
+
+
+template<typename eT>
+inline
+void
+SpSubview<eT>::delete_element(const uword in_row, const uword in_col)
+  {
+  arma_extra_debug_sigprint();
+
+  // This may not actually delete an element.
+  const uword old_n_nonzero = m.n_nonzero;
+  access::rw(m).delete_element(in_row + aux_row1, in_col + aux_col1);
+  access::rw(n_nonzero) -= (old_n_nonzero - m.n_nonzero);
+  }
+
+
+
+/**
+ * Sparse subview col
+ *
+template<typename eT>
+inline
+SpSubview_col<eT>::SpSubview_col(const Mat<eT>& in_m, const uword in_col)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+template<typename eT>
+inline
+SpSubview_col<eT>::SpSubview_col(Mat<eT>& in_m, const uword in_col)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+template<typename eT>
+inline
+SpSubview_col<eT>::SpSubview_col(const Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+template<typename eT>
+inline
+SpSubview_col<eT>::SpSubview_col(Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows)
+  {
+  arma_extra_debug_sigprint();
+  }
+*/
+
+/**
+ * Sparse subview row
+ *
+template<typename eT>
+inline
+SpSubview_row<eT>::SpSubview_row(const Mat<eT>& in_m, const uword in_row)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+template<typename eT>
+inline
+SpSubview_row<eT>::SpSubview_row(Mat<eT>& in_m, const uword in_row)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+template<typename eT>
+inline
+SpSubview_row<eT>::SpSubview_row(const Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+template<typename eT>
+inline
+SpSubview_row<eT>::SpSubview_row(Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols)
+  {
+  arma_extra_debug_sigprint();
+  }
+*/
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpValProxy_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,70 @@
+// Copyright (C) 2011-2012 Ryan Curtin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+//! \addtogroup SpValProxy
+//! @{
+
+/**
+ * Sparse value proxy class, meant to prevent 0s from being added to sparse
+ * matrices.  T1 should be either SpMat or SpSubview, and if it's not, bad news
+ * is probably coming.  This class only uses T1::add_element() and
+ * T1::delete_element().
+ */
+template<typename T1>
+class SpValProxy
+  {
+  public:
+
+  typedef typename T1::elem_type eT; // Convenience typedef
+
+  friend class SpMat<eT>;
+  friend class SpSubview<eT>;
+  
+  /**
+   * Create the sparse value proxy.
+   * Otherwise, pass a pointer to a reference of the value.
+   */
+  arma_inline SpValProxy(uword row, uword col, T1& in_parent, eT* in_val_ptr = NULL);
+  
+  //! For swapping operations.
+  arma_inline SpValProxy& operator=(const SpValProxy& rhs);
+  template<typename T2>
+  arma_inline SpValProxy& operator=(const SpValProxy<T2>& rhs);
+  
+  //! Overload all of the potential operators.
+  
+  //! First, the ones that could modify a value.
+  arma_inline SpValProxy& operator=(const eT rhs);
+  arma_inline SpValProxy& operator+=(const eT rhs);
+  arma_inline SpValProxy& operator-=(const eT rhs);
+  arma_inline SpValProxy& operator*=(const eT rhs);
+  arma_inline SpValProxy& operator/=(const eT rhs);
+  
+  arma_inline SpValProxy& operator++();
+  arma_inline SpValProxy& operator--();
+  arma_inline eT operator++(const int);
+  arma_inline eT operator--(const int);
+  
+  //! This will work for any other operations that do not modify a value.
+  arma_inline operator eT() const;
+  
+  
+  private:
+  
+  // Deletes the element if it is zero.  Does not check if val_ptr == NULL!
+  arma_inline arma_hot void check_zero();
+  
+  uword row;
+  uword col;
+  
+  eT* val_ptr;
+  
+  T1& parent; // We will call this object if we need to insert or delete an element.
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/SpValProxy_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,345 @@
+// Copyright (C) 2011-2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+//! \addtogroup SpValProxy
+//! @{
+
+//! SpValProxy implementation.
+template<typename T1>
+arma_inline
+SpValProxy<T1>::SpValProxy(uword in_row, uword in_col, T1& in_parent, eT* in_val_ptr)
+  : row(in_row)
+  , col(in_col)
+  , val_ptr(in_val_ptr)
+  , parent(in_parent)
+  {
+  // Nothing to do.
+  }
+
+
+
+template<typename T1>
+arma_inline
+SpValProxy<T1>&
+SpValProxy<T1>::operator=(const SpValProxy<T1>& rhs)
+  {
+  return (*this).operator=(eT(rhs));
+  }
+
+
+
+template<typename T1>
+template<typename T2>
+arma_inline
+SpValProxy<T1>&
+SpValProxy<T1>::operator=(const SpValProxy<T2>& rhs)
+  {
+  return (*this).operator=(eT(rhs));
+  }
+
+
+
+template<typename T1>
+arma_inline
+SpValProxy<T1>&
+SpValProxy<T1>::operator=(const eT rhs)
+  {
+  if (rhs != eT(0)) // A nonzero element is being assigned.
+    {
+
+    if (val_ptr)
+      {
+      // The value exists and merely needs to be updated.
+      *val_ptr = rhs;
+      }
+
+    else
+      {
+      // The value is nonzero and must be added.
+      val_ptr = &parent.add_element(row, col, rhs);
+      }
+
+    }
+  else // A zero is being assigned.~
+    {
+
+    if (val_ptr)
+      {
+      // The element exists, but we need to remove it, because it is being set to 0.
+      parent.delete_element(row, col);
+      val_ptr = NULL;
+      }
+
+    // If the element does not exist, we do not need to do anything at all.
+
+    }
+
+  return *this;
+  }
+
+
+
+template<typename T1>
+arma_inline
+SpValProxy<T1>&
+SpValProxy<T1>::operator+=(const eT rhs)
+  {
+  if (val_ptr)
+    {
+    // The value already exists and merely needs to be updated.
+    *val_ptr += rhs;
+    check_zero();
+    }
+  else
+    {
+    if (rhs != eT(0))
+      {
+      // The value does not exist and must be added.
+      val_ptr = &parent.add_element(row, col, rhs);
+      }
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename T1>
+arma_inline
+SpValProxy<T1>&
+SpValProxy<T1>::operator-=(const eT rhs)
+  {
+  if (val_ptr)
+    {
+    // The value already exists and merely needs to be updated.
+    *val_ptr -= rhs;
+    check_zero();
+    }
+  else
+    {
+    if (rhs != eT(0))
+      {
+      // The value does not exist and must be added.
+      val_ptr = &parent.add_element(row, col, -rhs);
+      }
+    }
+
+  return *this;
+  }
+
+
+
+template<typename T1>
+arma_inline
+SpValProxy<T1>&
+SpValProxy<T1>::operator*=(const eT rhs)
+  {
+  if (rhs != eT(0))
+    {
+
+    if (val_ptr)
+      {
+      // The value already exists and merely needs to be updated.
+      *val_ptr *= rhs;
+      check_zero();
+      }
+
+    }
+  else
+    {
+
+    if (val_ptr)
+      {
+      // Since we are multiplying by zero, the value can be deleted.
+      parent.delete_element(row, col);
+      val_ptr = NULL;
+      }
+
+    }
+
+  return *this;
+  }
+
+
+
+template<typename T1>
+arma_inline
+SpValProxy<T1>&
+SpValProxy<T1>::operator/=(const eT rhs)
+  {
+  if (rhs != eT(0)) // I hope this is true!
+    {
+
+    if (val_ptr)
+      {
+      *val_ptr /= rhs;
+      check_zero();
+      }
+
+    }
+  else
+    {
+
+    if (val_ptr)
+      {
+      *val_ptr /= rhs; // That is where it gets ugly.
+      // Now check if it's 0.
+      if (*val_ptr == eT(0))
+        {
+        parent.delete_element(row, col);
+        val_ptr = NULL;
+        }
+      }
+
+    else
+      {
+      eT val = eT(0) / rhs; // This may vary depending on type and implementation.
+
+      if (val != eT(0))
+        {
+        // Ok, now we have to add it.
+        val_ptr = &parent.add_element(row, col, val);
+        }
+
+      }
+    }
+
+  return *this;
+  }
+
+
+
+template<typename T1>
+arma_inline
+SpValProxy<T1>&
+SpValProxy<T1>::operator++()
+  {
+  if (val_ptr)
+    {
+    (*val_ptr) += eT(1);
+    check_zero();
+    }
+
+  else
+    {
+    val_ptr = &parent.add_element(row, col, eT(1));
+    }
+
+  return *this;
+  }
+
+
+
+template<typename T1>
+arma_inline
+SpValProxy<T1>&
+SpValProxy<T1>::operator--()
+  {
+  if (val_ptr)
+    {
+    (*val_ptr) -= eT(1);
+    check_zero();
+    }
+
+  else
+    {
+    val_ptr = &parent.add_element(row, col, eT(-1));
+    }
+
+  return *this;
+  }
+
+
+
+template<typename T1>
+arma_inline
+typename T1::elem_type
+SpValProxy<T1>::operator++(const int)
+  {
+  if (val_ptr)
+    {
+    (*val_ptr) += eT(1);
+    check_zero();
+    }
+
+  else
+    {
+    val_ptr = &parent.add_element(row, col, eT(1));
+    }
+
+  if (val_ptr) // It may have changed to now be 0.
+    {
+    return *(val_ptr) - eT(1);
+    }
+  else
+    {
+    return eT(0);
+    }
+  }
+
+
+
+template<typename T1>
+arma_inline
+typename T1::elem_type
+SpValProxy<T1>::operator--(const int)
+  {
+  if (val_ptr)
+    {
+    (*val_ptr) -= eT(1);
+    check_zero();
+    }
+
+  else
+    {
+    val_ptr = &parent.add_element(row, col, eT(-1));
+    }
+
+  if (val_ptr) // It may have changed to now be 0.
+    {
+    return *(val_ptr) + eT(1);
+    }
+  else
+    {
+    return eT(0);
+    }
+  }
+
+
+
+template<typename T1>
+arma_inline
+SpValProxy<T1>::operator eT() const
+  {
+  if (val_ptr)
+    {
+    return *val_ptr;
+    }
+  else
+    {
+    return eT(0);
+    }
+  }
+
+
+
+template<typename T1>
+arma_inline
+arma_hot
+void
+SpValProxy<T1>::check_zero()
+  {
+  if (*val_ptr == eT(0))
+    {
+    parent.delete_element(row, col);
+    val_ptr = NULL;
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/access.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,31 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup access
+//! @{
+
+
+class access
+  {
+  public:
+  
+  //! internal function to allow modification of data declared as read-only (use with caution)
+  template<typename T1> arma_inline static T1&  rw (const T1& x)        { return const_cast<T1& >(x); }
+  template<typename T1> arma_inline static T1*& rwp(const T1* const& x) { return const_cast<T1*&>(x); }
+  
+  //! internal function to obtain the real part of either a plain number or a complex number
+  template<typename eT> arma_inline static const eT& tmp_real(const eT&              X) { return X;        }
+  template<typename  T> arma_inline static const   T tmp_real(const std::complex<T>& X) { return X.real(); }
+  
+  //! internal function to work around braindead compilers
+  template<typename eT> arma_inline static const typename enable_if2<is_not_complex<eT>::value, const eT&>::result alt_conj(const eT& X) { return X;            }
+  template<typename eT> arma_inline static const typename enable_if2<    is_complex<eT>::value, const eT >::result alt_conj(const eT& X) { return std::conj(X); }
+  };
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/arma_config.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,104 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup arma_config
+//! @{
+
+
+
+struct arma_config
+  {
+  #if defined(ARMA_MAT_PREALLOC)
+    static const uword mat_prealloc = (sword(ARMA_MAT_PREALLOC) > 0) ? uword(ARMA_MAT_PREALLOC) : 1;
+  #else
+    static const uword mat_prealloc = 16;
+  #endif
+  
+  
+  #if defined(ARMA_SPMAT_CHUNKSIZE)
+    static const uword spmat_chunksize = (sword(ARMA_SPMAT_CHUNKSIZE) > 0) ? uword(ARMA_SPMAT_CHUNKSIZE) : 256;
+  #else
+    static const uword spmat_chunksize = 256;
+  #endif
+  
+  
+  #if defined(ARMA_USE_ATLAS)
+    static const bool atlas = true;
+  #else
+    static const bool atlas = false;
+  #endif
+  
+  
+  #if defined(ARMA_USE_LAPACK)
+    static const bool lapack = true;
+  #else
+    static const bool lapack = false;
+  #endif
+  
+  
+  #if defined(ARMA_USE_BLAS)
+    static const bool blas = true;
+  #else
+    static const bool blas = false;
+  #endif
+
+
+  #if defined(ARMA_USE_BOOST)
+    static const bool boost = true;
+  #else
+    static const bool boost = false;
+  #endif
+  
+
+  #if defined(ARMA_USE_BOOST_DATE)
+    static const bool boost_date = true;
+  #else
+    static const bool boost_date = false;
+  #endif
+
+
+  #if !defined(ARMA_NO_DEBUG) && !defined(NDEBUG)
+    static const bool debug = true;
+  #else
+    static const bool debug = false;
+  #endif
+  
+  
+  #if defined(ARMA_EXTRA_DEBUG)
+    static const bool extra_debug = true;
+  #else
+    static const bool extra_debug = false;
+  #endif
+  
+  
+  #if defined(ARMA_GOOD_COMPILER)
+    static const bool good_comp = true;
+  #else
+    static const bool good_comp = false;
+  #endif
+  
+  
+  #if (  \
+         defined(ARMA_EXTRA_MAT_PROTO)   || defined(ARMA_EXTRA_MAT_MEAT)   \
+      || defined(ARMA_EXTRA_COL_PROTO)   || defined(ARMA_EXTRA_COL_MEAT)   \
+      || defined(ARMA_EXTRA_ROW_PROTO)   || defined(ARMA_EXTRA_ROW_MEAT)   \
+      || defined(ARMA_EXTRA_CUBE_PROTO)  || defined(ARMA_EXTRA_CUBE_MEAT)  \
+      || defined(ARMA_EXTRA_FIELD_PROTO) || defined(ARMA_EXTRA_FIELD_MEAT) \
+      || defined(ARMA_EXTRA_SPMAT_PROTO) || defined(ARMA_EXTRA_SPMAT_MEAT) \
+      || defined(ARMA_EXTRA_SPCOL_PROTO) || defined(ARMA_EXTRA_SPCOL_MEAT) \
+      || defined(ARMA_EXTRA_SPROW_PROTO) || defined(ARMA_EXTRA_SPROW_MEAT) \
+      )
+    static const bool extra_code = true;
+  #else
+    static const bool extra_code = false;
+  #endif
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/arma_ostream_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,60 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup arma_ostream
+//! @{
+
+
+
+class arma_ostream_state
+  {
+  private:
+
+  const ios::fmtflags   orig_flags;
+  const std::streamsize orig_precision;
+  const std::streamsize orig_width;
+  const char            orig_fill;
+
+
+  public:
+
+  inline arma_ostream_state(const std::ostream& o);
+  
+  inline void restore(std::ostream& o) const;
+  };
+
+
+
+class arma_ostream
+  {
+  public:
+  
+  template<typename eT> inline static std::streamsize modify_stream(std::ostream& o, const eT*              data, const uword n_elem);
+  template<typename  T> inline static std::streamsize modify_stream(std::ostream& o, const std::complex<T>* data, const uword n_elem);
+  template<typename eT> inline static std::streamsize modify_stream(std::ostream& o, typename SpMat<eT>::const_iterator begin, const uword n_elem, const typename arma_not_cx<eT>::result* junk = 0);
+  template<typename  T> inline static std::streamsize modify_stream(std::ostream& o, typename SpMat<T>::const_iterator begin, const uword n_elem, const typename arma_cx_only<T>::result* junk = 0);
+  
+  template<typename eT> inline static void print_elem_zero(std::ostream& o, const bool modify);
+  
+  template<typename eT> arma_inline static void print_elem(std::ostream& o, const eT&              x, const bool modify);
+  template<typename  T>      inline static void print_elem(std::ostream& o, const std::complex<T>& x, const bool modify);
+
+  template<typename eT> inline static void print(std::ostream& o, const  Mat<eT>& m, const bool modify);
+  template<typename eT> inline static void print(std::ostream& o, const Cube<eT>& m, const bool modify);
+  
+  template<typename oT> inline static void print(std::ostream& o, const field<oT>&         m);
+  template<typename oT> inline static void print(std::ostream& o, const subview_field<oT>& m);
+
+
+  template<typename eT> inline static void print_dense(std::ostream& o, const SpMat<eT>& m, const bool modify);
+  template<typename eT> inline static void print(std::ostream& o, const SpMat<eT>& m, const bool modify);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/arma_ostream_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,669 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup arma_ostream
+//! @{
+
+
+
+inline
+arma_ostream_state::arma_ostream_state(const std::ostream& o)
+  : orig_flags    (o.flags())
+  , orig_precision(o.precision())
+  , orig_width    (o.width())
+  , orig_fill     (o.fill())
+  {
+  }
+
+
+
+inline
+void
+arma_ostream_state::restore(std::ostream& o) const
+  {
+  o.flags    (orig_flags);
+  o.precision(orig_precision);
+  o.width    (orig_width);
+  o.fill     (orig_fill);
+  }
+
+
+
+//
+//
+
+
+
+template<typename eT>
+inline
+std::streamsize
+arma_ostream::modify_stream(std::ostream& o, const eT* data, const uword n_elem)
+  {
+  o.unsetf(ios::showbase);
+  o.unsetf(ios::uppercase);
+  o.unsetf(ios::showpos);
+  
+  o.fill(' ');
+  
+  std::streamsize cell_width;
+  
+  bool use_layout_B = false;
+  bool use_layout_C = false;
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    const eT val = data[i];
+    
+    if(
+      ( val >= eT(+100) )
+      ||
+      //( (is_signed<eT>::value == true) && (val <= eT(-100)) ) ||
+      //( (is_non_integral<eT>::value == true) && (val > eT(0)) && (val <= eT(+1e-4)) ) ||
+      //( (is_non_integral<eT>::value == true) && (is_signed<eT>::value == true) && (val < eT(0)) && (val >= eT(-1e-4)) ) 
+        (
+        cond_rel< is_signed<eT>::value >::leq(val, eT(-100))
+        )
+      ||
+        (
+        cond_rel< is_non_integral<eT>::value >::gt(val,  eT(0))
+        &&
+        cond_rel< is_non_integral<eT>::value >::leq(val, eT(+1e-4))
+        )
+      ||
+        (
+        cond_rel< is_non_integral<eT>::value && is_signed<eT>::value >::lt(val, eT(0))
+        &&
+        cond_rel< is_non_integral<eT>::value && is_signed<eT>::value >::geq(val, eT(-1e-4))
+        )
+      )
+      {
+      use_layout_C = true;
+      break;
+      }
+      
+    if(
+      // (val >= eT(+10)) || ( (is_signed<eT>::value == true) && (val <= eT(-10)) )
+      (val >= eT(+10)) || ( cond_rel< is_signed<eT>::value >::leq(val, eT(-10)) )
+      )
+      {
+      use_layout_B = true;
+      }
+    }
+  
+  if(use_layout_C == true)
+    {
+    o.setf(ios::scientific);
+    o.setf(ios::right);
+    o.unsetf(ios::fixed);
+    o.precision(4);
+    cell_width = 13;
+    }
+  else
+  if(use_layout_B == true)
+    {
+    o.unsetf(ios::scientific);
+    o.setf(ios::right);
+    o.setf(ios::fixed);
+    o.precision(4);
+    cell_width = 10;
+    }
+  else
+    {
+    o.unsetf(ios::scientific);
+    o.setf(ios::right);
+    o.setf(ios::fixed);
+    o.precision(4);
+    cell_width = 9;
+    }
+  
+  return cell_width;
+  }
+
+
+
+//! "better than nothing" settings for complex numbers
+template<typename T>
+inline
+std::streamsize
+arma_ostream::modify_stream(std::ostream& o, const std::complex<T>* data, const uword n_elem)
+  {
+  arma_ignore(data);
+  arma_ignore(n_elem);
+  
+  o.unsetf(ios::showbase);
+  o.unsetf(ios::uppercase);
+  o.fill(' ');
+  
+  o.setf(ios::scientific);
+  o.setf(ios::showpos);
+  o.setf(ios::right);
+  o.unsetf(ios::fixed);
+  
+  std::streamsize cell_width;
+  
+  o.precision(3);
+  cell_width = 2 + 2*(1 + 3 + o.precision() + 5) + 1;
+  
+  return cell_width;
+  }
+
+
+template<typename eT>
+inline
+std::streamsize
+arma_ostream::modify_stream(std::ostream& o, typename SpMat<eT>::const_iterator begin, const uword n_elem, const typename arma_not_cx<eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+
+  o.unsetf(ios::showbase);
+  o.unsetf(ios::uppercase);
+  o.unsetf(ios::showpos);
+
+  o.fill(' ');
+
+  std::streamsize cell_width;
+
+  bool use_layout_B  = false;
+  bool use_layout_C  = false;
+
+  for(typename SpMat<eT>::const_iterator it = begin; it.pos() < n_elem; ++it)
+    {
+    const eT val = *it;
+
+    if(
+      val >= eT(+100) ||
+      ( (is_signed<eT>::value == true) && (val <= eT(-100)) ) ||
+      ( (is_non_integral<eT>::value == true) && (val > eT(0)) && (val <= eT(+1e-4)) ) ||
+      ( (is_non_integral<eT>::value == true) && (is_signed<eT>::value == true) && (val < eT(0)) && (val >= eT(-1e-4)) )
+      )
+      {
+      use_layout_C = true;
+      break;
+      }
+
+    if(
+      (val >= eT(+10)) || ( (is_signed<eT>::value == true) && (val <= eT(-10)) )
+      )
+      {
+      use_layout_B = true;
+      }
+    }
+
+  if(use_layout_C == true)
+    {
+    o.setf(ios::scientific);
+    o.setf(ios::right);
+    o.unsetf(ios::fixed);
+    o.precision(4);
+    cell_width = 13;
+    }
+  else
+  if(use_layout_B == true)
+    {
+    o.unsetf(ios::scientific);
+    o.setf(ios::right);
+    o.setf(ios::fixed);
+    o.precision(4);
+    cell_width = 10;
+    }
+  else
+    {
+    o.unsetf(ios::scientific);
+    o.setf(ios::right);
+    o.setf(ios::fixed);
+    o.precision(4);
+    cell_width = 9;
+    }
+  
+  return cell_width;
+  }
+
+
+
+//! "better than nothing" settings for complex numbers
+template<typename T>
+inline
+std::streamsize
+arma_ostream::modify_stream(std::ostream& o, typename SpMat<T>::const_iterator begin, const uword n_elem, const typename arma_cx_only<T>::result* junk)
+  {
+  arma_ignore(begin);
+  arma_ignore(n_elem);
+  arma_ignore(junk);
+  
+  o.unsetf(ios::showbase);
+  o.unsetf(ios::uppercase);
+  o.fill(' ');
+  
+  o.setf(ios::scientific);
+  o.setf(ios::showpos);
+  o.setf(ios::right);
+  o.unsetf(ios::fixed);
+  
+  std::streamsize cell_width;
+  
+  o.precision(3);
+  cell_width = 2 + 2*(1 + 3 + o.precision() + 5) + 1;
+  
+  return cell_width;
+  }
+
+
+
+template<typename eT>
+inline
+void
+arma_ostream::print_elem_zero(std::ostream& o, const bool modify)
+  {
+  if(modify == true)
+    {
+    const std::streamsize orig_precision = o.precision();
+    
+    o.precision(0);
+    
+    o << eT(0);
+    
+    o.precision(orig_precision);
+    }
+  else
+    {
+    o << eT(0);
+    }
+  }
+
+
+
+//! Print an element to the specified stream
+template<typename eT>
+arma_inline
+void
+arma_ostream::print_elem(std::ostream& o, const eT& x, const bool modify)
+  {
+  if(x != eT(0))
+    {
+    o << x;
+    }
+  else
+    {
+    arma_ostream::print_elem_zero<eT>(o, modify);
+    }
+  }
+
+
+
+//! Print a complex element to the specified stream
+template<typename T>
+inline
+void
+arma_ostream::print_elem(std::ostream& o, const std::complex<T>& x, const bool modify)
+  {
+  if( (x.real() != T(0)) || (x.imag() != T(0)) || (modify == false) )
+    {
+    std::ostringstream ss;
+    ss.flags(o.flags());
+    //ss.imbue(o.getloc());
+    ss.precision(o.precision());
+  
+    ss << '(' << x.real() << ',' << x.imag() << ')';
+    o << ss.str();
+    }
+  else
+    {
+    o << "(0,0)";
+    }
+  }
+
+
+
+//! Print a matrix to the specified stream
+template<typename eT>
+inline
+void
+arma_ostream::print(std::ostream& o, const Mat<eT>& m, const bool modify)
+  {
+  arma_extra_debug_sigprint();
+  
+  const arma_ostream_state stream_state(o);
+  
+  const std::streamsize cell_width = modify ? arma_ostream::modify_stream(o, m.memptr(), m.n_elem) : o.width();
+  
+  const uword m_n_rows = m.n_rows;
+  const uword m_n_cols = m.n_cols;
+  
+  if(m.is_empty() == false)
+    {
+    if(m_n_cols > 0)
+      {
+      if(cell_width > 0)
+        {
+        for(uword row=0; row < m_n_rows; ++row)
+          {
+          for(uword col=0; col < m_n_cols; ++col)
+            {
+            // the cell width appears to be reset after each element is printed,
+            // hence we need to restore it
+            o.width(cell_width);
+            arma_ostream::print_elem(o, m.at(row,col), modify);
+            }
+        
+          o << '\n';
+          }
+        }
+      else
+        {
+        for(uword row=0; row < m_n_rows; ++row)
+          {
+          for(uword col=0; col < m_n_cols-1; ++col)
+            {
+            arma_ostream::print_elem(o, m.at(row,col), modify);
+            o << ' ';
+            }
+        
+          arma_ostream::print_elem(o, m.at(row, m_n_cols-1), modify);
+          o << '\n';
+          }
+        }
+      }
+    }
+  else
+    {
+    o << "[matrix size: " << m_n_rows << 'x' << m_n_cols << "]\n";
+    }
+  
+  o.flush();
+  stream_state.restore(o);
+  }
+
+
+
+//! Print a cube to the specified stream
+template<typename eT>
+inline
+void
+arma_ostream::print(std::ostream& o, const Cube<eT>& x, const bool modify)
+  {
+  arma_extra_debug_sigprint();
+  
+  const arma_ostream_state stream_state(o);
+  
+  const std::streamsize cell_width = modify ? arma_ostream::modify_stream(o, x.memptr(), x.n_elem) : o.width();
+  
+  if(x.is_empty() == false)
+    {
+    for(uword slice=0; slice < x.n_slices; ++slice)
+      {
+      o << "[cube slice " << slice << ']' << '\n';
+      o.width(cell_width);
+      arma_ostream::print(o, x.slice(slice), false);
+      o << '\n';
+      }
+    }
+  else
+    {
+    o << "[cube size: " << x.n_rows << 'x' << x.n_cols << 'x' << x.n_slices <<  "]\n";
+    }
+
+  stream_state.restore(o);
+  }
+
+
+
+
+//! Print a field to the specified stream
+//! Assumes type oT can be printed, i.e. oT has std::ostream& operator<< (std::ostream&, const oT&) 
+template<typename oT>
+inline
+void
+arma_ostream::print(std::ostream& o, const field<oT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const arma_ostream_state stream_state(o);
+  
+  const std::streamsize cell_width = o.width();
+  
+  const uword x_n_rows = x.n_rows;
+  const uword x_n_cols = x.n_cols;
+  
+  if(x.is_empty() == false)
+    {
+    for(uword col=0; col<x_n_cols; ++col)
+      {
+      o << "[field column " << col << ']' << '\n'; 
+      
+      for(uword row=0; row<x_n_rows; ++row)
+        {
+        o.width(cell_width);
+        o << x.at(row,col) << '\n';
+        }
+      
+      o << '\n';
+      }
+    }
+  else
+    {
+    o << "[field size: " << x_n_rows << 'x' << x_n_cols <<  "]\n";
+    }
+  
+  o.flush();
+  stream_state.restore(o);
+  }
+
+
+
+//! Print a subfield to the specified stream
+//! Assumes type oT can be printed, i.e. oT has std::ostream& operator<< (std::ostream&, const oT&) 
+template<typename oT>
+inline
+void
+arma_ostream::print(std::ostream& o, const subview_field<oT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const arma_ostream_state stream_state(o);
+  
+  const std::streamsize cell_width = o.width();
+  
+  const uword x_n_rows = x.n_rows;
+  const uword x_n_cols = x.n_cols;
+  
+  for(uword col=0; col<x_n_cols; ++col)
+    {
+    o << "[field column " << col << ']' << '\n'; 
+    for(uword row=0; row<x_n_rows; ++row)
+      {
+      o.width(cell_width);
+      o << x.at(row,col) << '\n';
+      }
+    
+    o << '\n';
+    }
+  
+  o.flush();
+  stream_state.restore(o);
+  }
+
+
+
+template<typename eT>
+inline
+void
+arma_ostream::print_dense(std::ostream& o, const SpMat<eT>& m, const bool modify)
+  {
+  arma_extra_debug_sigprint();
+  
+  const arma_ostream_state stream_state(o);
+  
+  const uword m_n_rows = m.n_rows;
+  const uword m_n_cols = m.n_cols;
+    
+  if(m.n_nonzero > 0)
+    {
+    const std::streamsize cell_width = modify ? modify_stream<eT>(o, m.begin(), m.n_nonzero) : o.width();
+    
+    typename SpMat<eT>::const_iterator begin = m.begin();
+    
+    if(m_n_cols > 0)
+      {
+      if(cell_width > 0)
+        {
+        // An efficient row_iterator would make this simpler and faster
+        for(uword row=0; row < m_n_rows; ++row)
+          {
+          for(uword col=0; col < m_n_cols; ++col)
+            {
+            // the cell width appears to be reset after each element is printed,
+            // hence we need to restore it
+            o.width(cell_width);
+            eT val = eT(0);
+            for(typename SpMat<eT>::const_iterator it = begin; it.pos() < m.n_nonzero; ++it)
+              {
+              if(it.row() == row && it.col() == col)
+                {
+                val = *it;
+                break;
+                }
+              }
+            arma_ostream::print_elem(o,eT(val), modify);
+            }
+
+          o << '\n';
+          }
+        }
+      else
+        {
+        // An efficient row_iterator would make this simpler and faster
+        for(uword row=0; row < m_n_rows; ++row)
+          {
+          for(uword col=0; col < m_n_cols; ++col)
+            {
+            eT val = eT(0);
+            for(typename SpMat<eT>::const_iterator it = begin; it.pos() < m.n_nonzero; ++it)
+              {
+              if(it.row() == row && it.col() == col)
+                {
+                val = *it;
+                break;
+                }
+              }
+            arma_ostream::print_elem(o,eT(val), modify);
+            o << ' ';
+            }
+
+          o << '\n';
+          }
+        }
+      }
+    }
+  else
+    {
+    if(m.n_elem == 0)
+      {
+      o << "[matrix size: " << m_n_rows << 'x' << m_n_cols << "]\n";
+      }
+    else
+      {
+      eT tmp[1];
+      tmp[0] = eT(0);
+      
+      const std::streamsize cell_width = modify ? arma_ostream::modify_stream(o, &tmp[0], 1) : o.width();
+      
+      for(uword row=0; row < m_n_rows; ++row)
+        {
+        for(uword col=0; col < m_n_cols; ++col)
+          {
+          o.width(cell_width);
+          
+          arma_ostream::print_elem_zero<eT>(o, modify);
+          
+          o << ' ';
+          }
+        
+        o << '\n';
+        }
+      }
+    }
+  
+  o.flush();
+  stream_state.restore(o);
+  }
+
+
+
+template<typename eT>
+inline
+void
+arma_ostream::print(std::ostream& o, const SpMat<eT>& m, const bool modify)
+  {
+  arma_extra_debug_sigprint();
+  
+  const arma_ostream_state stream_state(o);
+  
+  o.unsetf(ios::showbase);
+  o.unsetf(ios::uppercase);
+  o.unsetf(ios::showpos);
+  o.unsetf(ios::scientific);
+  o.setf(ios::right);
+  o.setf(ios::fixed);
+  o.precision(2);
+  
+  const uword m_n_nonzero = m.n_nonzero;
+  
+  o << "[matrix size: " << m.n_rows << 'x' << m.n_cols << "; n_nonzero: " << m_n_nonzero
+    << "; density: " << ((m.n_elem > 0) ? (double(m_n_nonzero) / double(m.n_elem) * double(100)) : double(0))
+    << "%]\n\n";
+  
+  if(modify == false) { stream_state.restore(o); }
+  
+  if(m_n_nonzero > 0)
+    {
+    const std::streamsize cell_width = modify ? modify_stream<eT>(o, m.begin(), m_n_nonzero) : o.width();
+    
+    typename SpMat<eT>::const_iterator begin = m.begin();
+    
+    while(begin != m.end())
+      {
+      const uword row = begin.row();
+      
+      // TODO: change the maximum number of spaces before and after each location to be dependent on n_rows and n_cols
+      
+           if(row < 10)      { o << "     "; }
+      else if(row < 100)     { o << "    ";  }
+      else if(row < 1000)    { o << "   ";   }
+      else if(row < 10000)   { o << "  ";    }
+      else if(row < 100000)  { o << ' ';     }
+      
+      const uword col = begin.col();
+      
+      o << '(' << row << ", " << col << ") ";
+      
+           if(col < 10)      { o << "     "; }
+      else if(col < 100)     { o << "    ";  }
+      else if(col < 1000)    { o << "   ";   }
+      else if(col < 10000)   { o << "  ";    }
+      else if(col < 100000)  { o << ' ';     }
+      
+      if(cell_width > 0) { o.width(cell_width); }
+        
+      arma_ostream::print_elem(o, eT(*begin), modify);
+      o << '\n';
+      
+      ++begin;
+      }
+    
+    o << '\n';
+    }
+  
+  o.flush();
+  stream_state.restore(o);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/arma_static_check.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,58 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup arma_static_check
+//! @{
+
+
+
+template<bool ERROR___INCORRECT_OR_UNSUPPORTED_TYPE>
+struct arma_type_check_cxx1998
+  {
+  arma_inline
+  static
+  void
+  apply()
+    {
+    static const char
+    junk[ ERROR___INCORRECT_OR_UNSUPPORTED_TYPE ? -1 : +1 ];
+    }
+  };
+
+
+
+template<>
+struct arma_type_check_cxx1998<false>
+  {
+  arma_inline
+  static
+  void
+  apply()
+    {
+    }
+  };
+
+
+
+#if !defined(ARMA_USE_CXX11)
+
+  #define arma_static_check(condition, message)  static const char message[ (condition) ? -1 : +1 ]
+  
+  #define arma_type_check(condition)  arma_type_check_cxx1998<condition>::apply()
+
+#else
+
+  #define arma_static_check(condition, message)  static_assert( !(condition), #message )
+  
+  #define arma_type_check(condition)  static_assert( !(condition), "error: incorrect or unsupported type" )
+
+#endif
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/arma_version.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,50 @@
+// Copyright (C) 2009-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup arma_version
+//! @{
+
+
+
+#define ARMA_VERSION_MAJOR 3
+#define ARMA_VERSION_MINOR 900
+#define ARMA_VERSION_PATCH 4
+#define ARMA_VERSION_NAME  "Bavarian Sunflower"
+
+
+
+struct arma_version
+  {
+  static const unsigned int major = ARMA_VERSION_MAJOR;
+  static const unsigned int minor = ARMA_VERSION_MINOR;
+  static const unsigned int patch = ARMA_VERSION_PATCH;
+  
+  static
+  inline
+  std::string
+  as_string()
+    {
+    const char* nickname = ARMA_VERSION_NAME;
+    
+    std::stringstream ss;
+    ss << arma_version::major
+       << '.'
+       << arma_version::minor
+       << '.'
+       << arma_version::patch
+       << " ("
+       << nickname
+       << ')';
+    
+    return ss.str();
+    }
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/arrayops_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,191 @@
+// Copyright (C) 2011-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2011-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup arrayops
+//! @{
+
+
+class arrayops
+  {
+  public:
+  
+  template<typename eT>
+  arma_hot arma_inline static void
+  copy(eT* dest, const eT* src, const uword n_elem);
+  
+  
+  template<typename eT>
+  static inline void
+  copy_big(eT* dest, const eT* src, const uword n_elem);
+  
+  
+  template<typename eT>
+  arma_hot inline static void
+  copy_forwards(eT* dest, const eT* src, const uword n_elem);
+  
+  
+  template<typename eT>
+  arma_hot inline static void
+  copy_backwards(eT* dest, const eT* src, const uword n_elem);
+  
+  
+  // 
+  // array = convert(array)
+  
+  template<typename out_eT, typename in_eT>
+  arma_hot arma_inline static void
+  convert_cx_scalar(out_eT& out, const in_eT&  in, const typename arma_not_cx<out_eT>::result* junk1 = 0, const typename arma_not_cx< in_eT>::result* junk2 = 0);
+  
+  template<typename out_eT, typename in_T>
+  arma_hot arma_inline static void
+  convert_cx_scalar(out_eT& out, const std::complex<in_T>& in, const typename arma_not_cx<out_eT>::result* junk = 0);
+  
+  template<typename out_T, typename in_T>
+  arma_hot arma_inline static void
+  convert_cx_scalar(std::complex<out_T>& out, const std::complex< in_T>& in);
+  
+  template<typename out_eT, typename in_eT>
+  arma_hot inline static void
+  convert(out_eT* dest, const in_eT* src, const uword n_elem);
+  
+  template<typename out_eT, typename in_eT>
+  arma_hot inline static void
+  convert_cx(out_eT* dest, const in_eT* src, const uword n_elem);
+  
+  
+  // 
+  // array op= array
+  
+  template<typename eT>
+  arma_hot inline static
+  void
+  inplace_plus(eT* dest, const eT* src, const uword n_elem);
+  
+  template<typename eT>
+  arma_hot inline static
+  void
+  inplace_minus(eT* dest, const eT* src, const uword n_elem);
+  
+  template<typename eT>
+  arma_hot inline static
+  void
+  inplace_mul(eT* dest, const eT* src, const uword n_elem);
+   
+  template<typename eT>
+  arma_hot inline static
+  void
+  inplace_div(eT* dest, const eT* src, const uword n_elem);
+  
+  
+  template<typename eT>
+  arma_hot inline static
+  void
+  inplace_plus_base(eT* dest, const eT* src, const uword n_elem);
+  
+  template<typename eT>
+  arma_hot inline static
+  void
+  inplace_minus_base(eT* dest, const eT* src, const uword n_elem);
+  
+  template<typename eT>
+  arma_hot inline static
+  void
+  inplace_mul_base(eT* dest, const eT* src, const uword n_elem);
+   
+  template<typename eT>
+  arma_hot inline static
+  void
+  inplace_div_base(eT* dest, const eT* src, const uword n_elem);
+  
+  
+  // 
+  // array op= scalar
+  
+  template<typename eT>
+  arma_hot inline static
+  void
+  inplace_set(eT* dest, const eT val, const uword n_elem);
+  
+  template<typename eT, const uword n_elem>
+  arma_hot inline static
+  void
+  inplace_set_fixed(eT* dest, const eT val);
+  
+  template<typename eT>
+  arma_hot inline static
+  void
+  inplace_plus(eT* dest, const eT val, const uword n_elem);
+  
+  template<typename eT>
+  arma_hot inline static
+  void
+  inplace_minus(eT* dest, const eT val, const uword n_elem);
+  
+  template<typename eT>
+  arma_hot inline static void
+  inplace_mul(eT* dest, const eT val, const uword n_elem);
+  
+  template<typename eT>
+  arma_hot inline static
+  void
+  inplace_div(eT* dest, const eT val, const uword n_elem);
+  
+  
+  // 
+  // scalar = op(array)
+  
+  template<typename eT>
+  arma_hot arma_pure inline static
+  eT
+  accumulate(const eT* src, const uword n_elem);
+  
+  template<typename eT>
+  arma_hot arma_pure inline static
+  eT
+  product(const eT* src, const uword n_elem);
+  
+  template<typename eT>
+  arma_hot arma_pure inline static
+  bool
+  is_finite(const eT* src, const uword n_elem);
+  
+  template<typename eT>
+  arma_hot arma_pure inline static
+  typename get_pod_type<eT>::result
+  norm_1(const eT* src, const uword n_elem);
+  
+  template<typename eT>
+  arma_hot arma_pure inline static
+  eT
+  norm_2(const eT* src, const uword n_elem, const typename arma_not_cx<eT>::result* junk = 0);
+  
+  template<typename T>
+  arma_hot arma_pure inline static
+  T
+  norm_2(const std::complex<T>* src, const uword n_elem);
+  
+  template<typename eT>
+  arma_hot arma_pure inline static
+  typename get_pod_type<eT>::result
+  norm_k(const eT* src, const uword n_elem, const int k);
+  
+  template<typename eT>
+  arma_hot arma_pure inline static
+  typename get_pod_type<eT>::result
+  norm_max(const eT* src, const uword n_elem);
+  
+  template<typename eT>
+  arma_hot arma_pure inline static
+  typename get_pod_type<eT>::result
+  norm_min(const eT* src, const uword n_elem);
+  
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/arrayops_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,1091 @@
+// Copyright (C) 2011-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2011-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup arrayops
+//! @{
+
+
+
+template<typename eT>
+arma_hot
+arma_inline
+void
+arrayops::copy(eT* dest, const eT* src, const uword n_elem)
+  {
+  switch(n_elem)
+    {
+    default:
+      arrayops::copy_big(dest, src, n_elem);
+      break;
+    case 8:
+      dest[7] = src[7];
+    case 7:
+      dest[6] = src[6];
+    case 6:
+      dest[5] = src[5];
+    case 5:
+      dest[4] = src[4];
+    case 4:
+      dest[3] = src[3];
+    case 3:
+      dest[2] = src[2];
+    case 2:
+      dest[1] = src[1];
+    case 1:
+      dest[0] = src[0];
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+arrayops::copy_big(eT* dest, const eT* src, const uword n_elem)
+  {
+  switch(n_elem)
+    {
+    default:
+      std::memcpy(dest, src, n_elem*sizeof(eT));
+      break;
+    case 32:
+      dest[31] = src[31];
+    case 31:
+      dest[30] = src[30];
+    case 30:
+      dest[29] = src[29];
+    case 29:
+      dest[28] = src[28];
+    case 28:
+      dest[27] = src[27];
+    case 27:
+      dest[26] = src[26];
+    case 26:
+      dest[25] = src[25];
+    case 25:
+      dest[24] = src[24];
+    case 24:
+      dest[23] = src[23];
+    case 23:
+      dest[22] = src[22];
+    case 22:
+      dest[21] = src[21];
+    case 21:
+      dest[20] = src[20];
+    case 20:
+      dest[19] = src[19];
+    case 19:
+      dest[18] = src[18];
+    case 18:
+      dest[17] = src[17];
+    case 17:
+      dest[16] = src[16];
+    case 16:
+      dest[15] = src[15];
+    case 15:
+      dest[14] = src[14];
+    case 14:
+      dest[13] = src[13];
+    case 13:
+      dest[12] = src[12];
+    case 12:
+      dest[11] = src[11];
+    case 11:
+      dest[10] = src[10];
+    case 10:
+      dest[9] = src[9];
+    case 9:
+      dest[8] = src[8];
+    case 8:
+      dest[7] = src[7];
+    case 7:
+      dest[6] = src[6];
+    case 6:
+      dest[5] = src[5];
+    case 5:
+      dest[4] = src[4];
+    case 4:
+      dest[3] = src[3];
+    case 3:
+      dest[2] = src[2];
+    case 2:
+      dest[1] = src[1];
+    case 1:
+      dest[0] = src[0];
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::copy_forwards(eT* dest, const eT* src, const uword n_elem)
+  {
+  // can't use std::memcpy(), as we don't know how it copies data
+  uword i,j;
+  
+  for(i=0, j=1; j < n_elem; i+=2, j+=2)
+    {
+    dest[i] = src[i];
+    dest[j] = src[j];
+    }
+  
+  if(i < n_elem)
+    {
+    dest[i] = src[i];
+    }
+  }
+
+
+
+// template<typename eT>
+// arma_hot
+// inline
+// void
+// arrayops::copy_backwards(eT* dest, const eT* src, const uword n_elem)
+//   {
+//   // can't use std::memcpy(), as we don't know how it copies data
+//   
+//   switch(n_elem)
+//     {
+//     default:
+//       for(uword i = (n_elem-1); i >= 1; --i) { dest[i] = src[i]; }
+//       // NOTE: the 'break' statement has been deliberately omitted
+//     case 1:
+//       dest[0] = src[0];
+//     case 0:
+//       ;
+//     }
+//   }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::copy_backwards(eT* dest, const eT* src, const uword n_elem)
+  {
+  // can't use std::memcpy(), as we don't know how it copies data
+  
+  switch(n_elem)
+    {
+    default:
+      {
+      uword i, j;
+      for(i = (n_elem-1), j = (n_elem-2); j >= 2; i-=2, j-=2)
+        {
+        const eT tmp_i = src[i];
+        const eT tmp_j = src[j];
+        
+        dest[i] = tmp_i;
+        dest[j] = tmp_j;
+        }
+      
+      // j is less than 2:  it can be 1 or 0
+      // i is j+1, ie. less than 3: it can be 2 or 1
+      
+      if(i == 2)
+        {
+        dest[2] = src[2];
+        }
+      }
+      // NOTE: the 'break' statement has been deliberately omitted
+    case 2:
+      dest[1] = src[1];
+    case 1:
+      dest[0] = src[0];
+    case 0:
+      ;
+    }
+  }
+
+
+
+template<typename out_eT, typename in_eT>
+arma_hot
+arma_inline
+void
+arrayops::convert_cx_scalar
+  (
+        out_eT& out,
+  const in_eT&  in,
+  const typename arma_not_cx<out_eT>::result* junk1,
+  const typename arma_not_cx< in_eT>::result* junk2
+  )
+  {
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  out = out_eT(in);
+  }
+
+
+
+template<typename out_eT, typename in_T>
+arma_hot
+arma_inline
+void
+arrayops::convert_cx_scalar
+  (
+        out_eT&             out,
+  const std::complex<in_T>& in,
+  const typename arma_not_cx<out_eT>::result* junk
+  )
+  {
+  arma_ignore(junk);
+  
+  out = out_eT( in.real() );
+  }
+
+
+
+template<typename out_T, typename in_T>
+arma_hot
+arma_inline
+void
+arrayops::convert_cx_scalar
+  (
+        std::complex<out_T>& out,
+  const std::complex< in_T>& in
+  )
+  {
+  typedef std::complex<out_T> out_eT;
+  
+  out = out_eT(in);
+  }
+
+
+
+template<typename out_eT, typename in_eT>
+arma_hot
+inline
+void
+arrayops::convert(out_eT* dest, const in_eT* src, const uword n_elem)
+  {
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const in_eT tmp_i = src[i];
+    const in_eT tmp_j = src[j];
+    
+    // dest[i] = out_eT( tmp_i );
+    // dest[j] = out_eT( tmp_j );
+    
+    dest[i] = (is_signed<out_eT>::value)
+              ? out_eT( tmp_i )
+              : ( cond_rel< is_signed<in_eT>::value >::lt(tmp_i, in_eT(0)) ? out_eT(0) : out_eT(tmp_i) );
+              
+    dest[j] = (is_signed<out_eT>::value)
+              ? out_eT( tmp_j )
+              : ( cond_rel< is_signed<in_eT>::value >::lt(tmp_j, in_eT(0)) ? out_eT(0) : out_eT(tmp_j) );
+    }
+  
+  if(i < n_elem)
+    {
+    const in_eT tmp_i = src[i];
+    
+    // dest[i] = out_eT( tmp_i );
+    
+    dest[i] = (is_signed<out_eT>::value)
+              ? out_eT( tmp_i )
+              : ( cond_rel< is_signed<in_eT>::value >::lt(tmp_i, in_eT(0)) ? out_eT(0) : out_eT(tmp_i) );
+    }
+  }
+
+
+
+template<typename out_eT, typename in_eT>
+arma_hot
+inline
+void
+arrayops::convert_cx(out_eT* dest, const in_eT* src, const uword n_elem)
+  {
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    arrayops::convert_cx_scalar( dest[i], src[i] );
+    arrayops::convert_cx_scalar( dest[j], src[j] );
+    }
+  
+  if(i < n_elem)
+    {
+    arrayops::convert_cx_scalar( dest[i], src[i] );
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::inplace_plus(eT* dest, const eT* src, const uword n_elem)
+  {
+  if(memory::is_aligned(dest))
+    {
+    memory::mark_as_aligned(dest);
+    
+    if(memory::is_aligned(src))
+      {
+      memory::mark_as_aligned(src);
+      
+      arrayops::inplace_plus_base(dest, src, n_elem);
+      }
+    else
+      {
+      arrayops::inplace_plus_base(dest, src, n_elem);
+      }
+    }
+  else
+    {
+    if(memory::is_aligned(src))
+      {
+      memory::mark_as_aligned(src);
+      
+      arrayops::inplace_plus_base(dest, src, n_elem);
+      }
+    else
+      {
+      arrayops::inplace_plus_base(dest, src, n_elem);
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::inplace_minus(eT* dest, const eT* src, const uword n_elem)
+  {
+  if(memory::is_aligned(dest))
+    {
+    memory::mark_as_aligned(dest);
+    
+    if(memory::is_aligned(src))
+      {
+      memory::mark_as_aligned(src);
+      
+      arrayops::inplace_minus_base(dest, src, n_elem);
+      }
+    else
+      {
+      arrayops::inplace_minus_base(dest, src, n_elem);
+      }
+    }
+  else
+    {
+    if(memory::is_aligned(src))
+      {
+      memory::mark_as_aligned(src);
+      
+      arrayops::inplace_minus_base(dest, src, n_elem);
+      }
+    else
+      {
+      arrayops::inplace_minus_base(dest, src, n_elem);
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::inplace_mul(eT* dest, const eT* src, const uword n_elem)
+  {
+  if(memory::is_aligned(dest))
+    {
+    memory::mark_as_aligned(dest);
+    
+    if(memory::is_aligned(src))
+      {
+      memory::mark_as_aligned(src);
+      
+      arrayops::inplace_mul_base(dest, src, n_elem);
+      }
+    else
+      {
+      arrayops::inplace_mul_base(dest, src, n_elem);
+      }
+    }
+  else
+    {
+    if(memory::is_aligned(src))
+      {
+      memory::mark_as_aligned(src);
+      
+      arrayops::inplace_mul_base(dest, src, n_elem);
+      }
+    else
+      {
+      arrayops::inplace_mul_base(dest, src, n_elem);
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::inplace_div(eT* dest, const eT* src, const uword n_elem)
+  {
+  if(memory::is_aligned(dest))
+    {
+    memory::mark_as_aligned(dest);
+    
+    if(memory::is_aligned(src))
+      {
+      memory::mark_as_aligned(src);
+      
+      arrayops::inplace_div_base(dest, src, n_elem);
+      }
+    else
+      {
+      arrayops::inplace_div_base(dest, src, n_elem);
+      }
+    }
+  else
+    {
+    if(memory::is_aligned(src))
+      {
+      memory::mark_as_aligned(src);
+      
+      arrayops::inplace_div_base(dest, src, n_elem);
+      }
+    else
+      {
+      arrayops::inplace_div_base(dest, src, n_elem);
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::inplace_plus_base(eT* dest, const eT* src, const uword n_elem)
+  {
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = src[i];
+    const eT tmp_j = src[j];
+    
+    dest[i] += tmp_i;
+    dest[j] += tmp_j;
+    }
+  
+  if(i < n_elem)
+    {
+    dest[i] += src[i];
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::inplace_minus_base(eT* dest, const eT* src, const uword n_elem)
+  {
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = src[i];
+    const eT tmp_j = src[j];
+    
+    dest[i] -= tmp_i;
+    dest[j] -= tmp_j;
+    }
+  
+  if(i < n_elem)
+    {
+    dest[i] -= src[i];
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::inplace_mul_base(eT* dest, const eT* src, const uword n_elem)
+  {
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = src[i];
+    const eT tmp_j = src[j];
+    
+    dest[i] *= tmp_i;
+    dest[j] *= tmp_j;
+    }
+  
+  if(i < n_elem)
+    {
+    dest[i] *= src[i];
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::inplace_div_base(eT* dest, const eT* src, const uword n_elem)
+  {
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = src[i];
+    const eT tmp_j = src[j];
+    
+    dest[i] /= tmp_i;
+    dest[j] /= tmp_j;
+    }
+  
+  if(i < n_elem)
+    {
+    dest[i] /= src[i];
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::inplace_set(eT* dest, const eT val, const uword n_elem)
+  {
+  if(memory::is_aligned(dest))
+    {
+    memory::mark_as_aligned(dest);
+    
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      dest[i] = val;
+      dest[j] = val;
+      }
+    
+    if(i < n_elem)
+      {
+      dest[i] = val;
+      }
+    }
+  else
+    {
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      dest[i] = val;
+      dest[j] = val;
+      }
+    
+    if(i < n_elem)
+      {
+      dest[i] = val;
+      }
+    } 
+  }
+
+
+
+template<typename eT, const uword n_elem>
+arma_hot
+inline
+void
+arrayops::inplace_set_fixed(eT* dest, const eT val)
+  {
+  for(uword i=0; i<n_elem; ++i)
+    {
+    dest[i] = val;
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::inplace_plus(eT* dest, const eT val, const uword n_elem)
+  {
+  if(memory::is_aligned(dest))
+    {
+    memory::mark_as_aligned(dest);
+    
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      dest[i] += val;
+      dest[j] += val;
+      }
+    
+    if(i < n_elem)
+      {
+      dest[i] += val;
+      }
+    }
+  else
+    {
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      dest[i] += val;
+      dest[j] += val;
+      }
+    
+    if(i < n_elem)
+      {
+      dest[i] += val;
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::inplace_minus(eT* dest, const eT val, const uword n_elem)
+  {
+  if(memory::is_aligned(dest))
+    {
+    memory::mark_as_aligned(dest);
+    
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      dest[i] -= val;
+      dest[j] -= val;
+      }
+    
+    if(i < n_elem)
+      {
+      dest[i] -= val;
+      }
+    }
+  else
+    {
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      dest[i] -= val;
+      dest[j] -= val;
+      }
+    
+    if(i < n_elem)
+      {
+      dest[i] -= val;
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::inplace_mul(eT* dest, const eT val, const uword n_elem)
+  {
+  if(memory::is_aligned(dest))
+    {
+    memory::mark_as_aligned(dest);
+    
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      dest[i] *= val;
+      dest[j] *= val;
+      }
+    
+    if(i < n_elem)
+      {
+      dest[i] *= val;
+      }
+    }
+  else
+    {
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      dest[i] *= val;
+      dest[j] *= val;
+      }
+    
+    if(i < n_elem)
+      {
+      dest[i] *= val;
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+arrayops::inplace_div(eT* dest, const eT val, const uword n_elem)
+  {
+  if(memory::is_aligned(dest))
+    {
+    memory::mark_as_aligned(dest);
+    
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      dest[i] /= val;
+      dest[j] /= val;
+      }
+    
+    if(i < n_elem)
+      {
+      dest[i] /= val;
+      }
+    }
+  else
+    {
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      dest[i] /= val;
+      dest[j] /= val;
+      }
+    
+    if(i < n_elem)
+      {
+      dest[i] /= val;
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+arma_pure
+inline
+eT
+arrayops::accumulate(const eT* src, const uword n_elem)
+  {
+  uword i,j;
+  
+  eT acc1 = eT(0);
+  eT acc2 = eT(0);
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    acc1 += src[i];
+    acc2 += src[j];
+    }
+  
+  if(i < n_elem)
+    {
+    acc1 += src[i];
+    }
+  
+  return acc1 + acc2;
+  }
+
+
+
+template<typename eT>
+arma_hot
+arma_pure
+inline
+eT
+arrayops::product(const eT* src, const uword n_elem)
+  {
+  eT val1 = eT(1);
+  eT val2 = eT(1);
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    val1 *= src[i];
+    val2 *= src[j];
+    }
+  
+  if(i < n_elem)
+    {
+    val1 *= src[i];
+    }
+  
+  return val1 * val2;
+  }
+
+
+
+template<typename eT>
+arma_hot
+arma_pure
+inline
+bool
+arrayops::is_finite(const eT* src, const uword n_elem)
+  {
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT val_i = src[i];
+    const eT val_j = src[j];
+    
+    if( (arma_isfinite(val_i) == false) || (arma_isfinite(val_j) == false) )
+      {
+      return false;
+      }
+    }
+  
+  if(i < n_elem)
+    {
+    if(arma_isfinite(src[i]) == false)
+      {
+      return false;
+      }
+    }
+  
+  return true;
+  }
+
+
+
+// TODO: this function is currently not used
+template<typename eT>
+arma_hot
+arma_pure
+inline
+typename get_pod_type<eT>::result
+arrayops::norm_1(const eT* src, const uword n_elem)
+  {
+  typedef typename get_pod_type<eT>::result T;
+  
+  T acc = T(0);
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    acc += std::abs(src[i]);
+    acc += std::abs(src[j]);
+    }
+  
+  if(i < n_elem)
+    {
+    acc += std::abs(src[i]);
+    }
+  
+  return acc;
+  }
+
+
+
+// TODO: this function is currently not used
+template<typename eT>
+arma_hot
+arma_pure
+inline
+eT
+arrayops::norm_2(const eT* src, const uword n_elem, const typename arma_not_cx<eT>::result* junk)
+  {
+  arma_ignore(junk);
+  
+  eT acc = eT(0);
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = src[i];
+    const eT tmp_j = src[j];
+    
+    acc += tmp_i * tmp_i;
+    acc += tmp_j * tmp_j;
+    }
+  
+  if(i < n_elem)
+    {
+    const eT tmp_i = src[i];
+    
+    acc += tmp_i * tmp_i;
+    }
+  
+  return std::sqrt(acc);
+  }
+
+
+
+// TODO: this function is currently not used
+template<typename T>
+arma_hot
+arma_pure
+inline
+T
+arrayops::norm_2(const std::complex<T>* src, const uword n_elem)
+  {
+  T acc = T(0);
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const T tmp_i = std::abs(src[i]);
+    const T tmp_j = std::abs(src[j]);
+    
+    acc += tmp_i * tmp_i;
+    acc += tmp_j * tmp_j;
+    }
+  
+  if(i < n_elem)
+    {
+    const T tmp_i = std::abs(src[i]);
+    
+    acc += tmp_i * tmp_i;
+    }
+  
+  return std::sqrt(acc);
+  }
+
+
+
+// TODO: this function is currently not used
+template<typename eT>
+arma_hot
+arma_pure
+inline
+typename get_pod_type<eT>::result
+arrayops::norm_k(const eT* src, const uword n_elem, const int k)
+  {
+  typedef typename get_pod_type<eT>::result T;
+  
+  T acc = T(0);
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    acc += std::pow(std::abs(src[i]), k);
+    acc += std::pow(std::abs(src[j]), k);
+    }
+  
+  if(i < n_elem)
+    {
+    acc += std::pow(std::abs(src[i]), k);
+    }
+  
+  return std::pow(acc, T(1)/T(k));
+  }
+
+
+
+// TODO: this function is currently not used
+template<typename eT>
+arma_hot
+arma_pure
+inline
+typename get_pod_type<eT>::result
+arrayops::norm_max(const eT* src, const uword n_elem)
+  {
+  typedef typename get_pod_type<eT>::result T;
+  
+  T max_val = std::abs(src[0]);
+  
+  uword i,j;
+  
+  for(i=1, j=2; j<n_elem; i+=2, j+=2)
+    {
+    const T tmp_i = std::abs(src[i]);
+    const T tmp_j = std::abs(src[j]);
+    
+    if(max_val < tmp_i) { max_val = tmp_i; }
+    if(max_val < tmp_j) { max_val = tmp_j; }
+    }
+  
+  if(i < n_elem)
+    {
+    const T tmp_i = std::abs(src[i]);
+    
+    if(max_val < tmp_i) { max_val = tmp_i; }
+    }
+  
+  return max_val;
+  }
+
+
+
+// TODO: this function is currently not used
+template<typename eT>
+arma_hot
+arma_pure
+inline
+typename get_pod_type<eT>::result
+arrayops::norm_min(const eT* src, const uword n_elem)
+  {
+  typedef typename get_pod_type<eT>::result T;
+  
+  T min_val = std::abs(src[0]);
+  
+  uword i,j;
+  
+  for(i=1, j=2; j<n_elem; i+=2, j+=2)
+    {
+    const T tmp_i = std::abs(src[i]);
+    const T tmp_j = std::abs(src[j]);
+    
+    if(min_val > tmp_i) { min_val = tmp_i; }
+    if(min_val > tmp_j) { min_val = tmp_j; }
+    }
+  
+  if(i < n_elem)
+    {
+    const T tmp_i = std::abs(src[i]);
+    
+    if(min_val > tmp_i) { min_val = tmp_i; }
+    }
+  
+  return min_val;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/atlas_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,84 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+#ifdef ARMA_USE_ATLAS
+
+
+//! \namespace atlas namespace for ATLAS functions (imported from the global namespace)
+namespace atlas
+  {
+  
+  using ::CblasColMajor;
+  using ::CblasNoTrans;
+  using ::CblasTrans;
+  using ::CblasConjTrans;
+  
+  #if defined(ARMA_USE_WRAPPER)
+  extern "C"
+    {
+    
+    float  wrapper_cblas_sdot(const int N, const float  *X, const int incX, const float  *Y, const int incY);
+    double wrapper_cblas_ddot(const int N, const double *X, const int incX, const double *Y, const int incY);
+    
+    void wrapper_cblas_cdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu);
+    void wrapper_cblas_zdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu);
+    
+    
+    void wrapper_cblas_sgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const float alpha,
+                             const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY);
+    
+    void wrapper_cblas_dgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const double alpha,
+                             const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY);
+    
+    void wrapper_cblas_cgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha,
+                             const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY);
+    
+    void wrapper_cblas_zgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha,
+                             const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY);
+    
+    
+    
+    void wrapper_cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
+                             const int M, const int N, const int K, const float alpha,
+                             const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc);
+    
+    void wrapper_cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
+                             const int M, const int N, const int K, const double alpha,
+                             const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc);
+    
+    void wrapper_cblas_cgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
+                             const int M, const int N, const int K, const void *alpha,
+                             const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc);
+    
+    void wrapper_cblas_zgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
+                             const int M, const int N, const int K, const void *alpha,
+                             const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc);
+    
+    
+    int wrapper_clapack_sgetrf(const enum CBLAS_ORDER Order, const int M, const int N, float  *A, const int lda, int *ipiv);
+    int wrapper_clapack_dgetrf(const enum CBLAS_ORDER Order, const int M, const int N, double *A, const int lda, int *ipiv);
+    int wrapper_clapack_cgetrf(const enum CBLAS_ORDER Order, const int M, const int N, void   *A, const int lda, int *ipiv);
+    int wrapper_clapack_zgetrf(const enum CBLAS_ORDER Order, const int M, const int N, void   *A, const int lda, int *ipiv);
+    
+    int wrapper_clapack_sgetri(const enum CBLAS_ORDER Order, const int N, float  *A, const int lda, const int *ipiv);
+    int wrapper_clapack_dgetri(const enum CBLAS_ORDER Order, const int N, double *A, const int lda, const int *ipiv);
+    int wrapper_clapack_cgetri(const enum CBLAS_ORDER Order, const int N, void   *A, const int lda, const int *ipiv);
+    int wrapper_clapack_zgetri(const enum CBLAS_ORDER Order, const int N, void   *A, const int lda, const int *ipiv);
+
+    int wrapper_clapack_sgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, float  *A, const int lda, int *ipiv, float  *B, const int ldb);
+    int wrapper_clapack_dgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, double *A, const int lda, int *ipiv, double *B, const int ldb);
+    int wrapper_clapack_cgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, void   *A, const int lda, int *ipiv, void   *B, const int ldb);
+    int wrapper_clapack_zgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, void   *A, const int lda, int *ipiv, void   *B, const int ldb);
+    
+    }
+  #endif
+  
+  }
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/atlas_wrapper.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,298 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+#ifdef ARMA_USE_ATLAS
+
+
+//! \namespace atlas namespace for ATLAS functions (imported from the global namespace)
+namespace atlas
+  {
+  
+  template<typename eT>
+  inline static const eT& tmp_real(const eT& X)              { return X; }
+  
+  template<typename T>
+  inline static const  T  tmp_real(const std::complex<T>& X) { return X.real(); }
+  
+  
+  
+  template<typename eT>
+  arma_inline
+  eT
+  cblas_dot(const int N, const eT* X, const eT* Y)
+    {
+    arma_type_check((is_supported_blas_type<eT>::value == false));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      return eT( arma_atlas(cblas_sdot)(N, (const T*)X, 1, (const T*)Y, 1) );
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      return eT( arma_atlas(cblas_ddot)(N, (const T*)X, 1, (const T*)Y, 1) );
+      }
+    else
+      {
+      return eT(0);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  arma_inline
+  eT
+  cx_cblas_dot(const int N, const eT* X, const eT* Y)
+    {
+    arma_type_check((is_supported_blas_type<eT>::value == false));
+    
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef typename std::complex<float> T;
+      
+      T out;    
+      arma_atlas(cblas_cdotu_sub)(N, (const T*)X, 1, (const T*)Y, 1, &out);
+      
+      return eT(out);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef typename std::complex<double> T;
+      
+      T out;
+      arma_atlas(cblas_zdotu_sub)(N, (const T*)X, 1, (const T*)Y, 1, &out);
+      
+      return eT(out);
+      }
+    else
+      {
+      return eT(0);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  cblas_gemv
+    (
+    const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
+    const int M, const int N,
+    const eT alpha,
+    const eT *A, const int lda,
+    const eT *X, const int incX,
+    const eT beta,
+    eT *Y, const int incY
+    )
+    {
+    arma_type_check((is_supported_blas_type<eT>::value == false));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_atlas(cblas_sgemv)(Order, TransA, M, N, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)X, incX, (const T)tmp_real(beta), (T*)Y, incY);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_atlas(cblas_dgemv)(Order, TransA, M, N, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)X, incX, (const T)tmp_real(beta), (T*)Y, incY);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_atlas(cblas_cgemv)(Order, TransA, M, N, (const T*)&alpha, (const T*)A, lda, (const T*)X, incX, (const T*)&beta, (T*)Y, incY);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_atlas(cblas_zgemv)(Order, TransA, M, N, (const T*)&alpha, (const T*)A, lda, (const T*)X, incX, (const T*)&beta, (T*)Y, incY);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  cblas_gemm
+    (
+    const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
+    const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
+    const int K, const eT alpha, const eT *A,
+    const int lda, const eT *B, const int ldb,
+    const eT beta, eT *C, const int ldc
+    )
+    {
+    arma_type_check((is_supported_blas_type<eT>::value == false));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_atlas(cblas_sgemm)(Order, TransA, TransB, M, N, K, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)B, ldb, (const T)tmp_real(beta), (T*)C, ldc);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_atlas(cblas_dgemm)(Order, TransA, TransB, M, N, K, (const T)tmp_real(alpha), (const T*)A, lda, (const T*)B, ldb, (const T)tmp_real(beta), (T*)C, ldc);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_atlas(cblas_cgemm)(Order, TransA, TransB, M, N, K, (const T*)&alpha, (const T*)A, lda, (const T*)B, ldb, (const T*)&beta, (T*)C, ldc);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_atlas(cblas_zgemm)(Order, TransA, TransB, M, N, K, (const T*)&alpha, (const T*)A, lda, (const T*)B, ldb, (const T*)&beta, (T*)C, ldc);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  int
+  clapack_getrf
+    (
+    const enum CBLAS_ORDER Order, const int M, const int N,
+    eT *A, const int lda, int *ipiv
+    )
+    {
+    arma_type_check((is_supported_blas_type<eT>::value == false));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      return arma_atlas(clapack_sgetrf)(Order, M, N, (T*)A, lda, ipiv);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      return arma_atlas(clapack_dgetrf)(Order, M, N, (T*)A, lda, ipiv);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      return arma_atlas(clapack_cgetrf)(Order, M, N, (T*)A, lda, ipiv);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      return arma_atlas(clapack_zgetrf)(Order, M, N, (T*)A, lda, ipiv);
+      }
+    else
+      {
+      return -1;
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  int
+  clapack_getri
+    (
+    const enum CBLAS_ORDER Order, const int N, eT *A,
+    const int lda, const int *ipiv
+    )
+    {
+    arma_type_check((is_supported_blas_type<eT>::value == false));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      return arma_atlas(clapack_sgetri)(Order, N, (T*)A, lda, ipiv);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      return arma_atlas(clapack_dgetri)(Order, N, (T*)A, lda, ipiv);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      return arma_atlas(clapack_cgetri)(Order, N, (T*)A, lda, ipiv);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      return arma_atlas(clapack_zgetri)(Order, N, (T*)A, lda, ipiv);
+      }
+    else
+      {
+      return -1;
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  int
+  clapack_gesv
+    (
+    const enum CBLAS_ORDER Order,
+    const int N, const int NRHS,
+    eT* A, const int lda, int* ipiv,
+    eT* B, const int ldb
+    )
+    {
+    arma_type_check((is_supported_blas_type<eT>::value == false));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      return arma_atlas(clapack_sgesv)(Order, N, NRHS, (T*)A, lda, ipiv, (T*)B, ldb);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      return arma_atlas(clapack_dgesv)(Order, N, NRHS, (T*)A, lda, ipiv, (T*)B, ldb);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      return arma_atlas(clapack_cgesv)(Order, N, NRHS, (T*)A, lda, ipiv, (T*)B, ldb);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      return arma_atlas(clapack_zgesv)(Order, N, NRHS, (T*)A, lda, ipiv, (T*)B, ldb);
+      }
+    else
+      {
+      return -1;
+      }
+    }
+
+
+
+  }
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/auxlib_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,235 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2009 Edmund Highcock
+// Copyright (C) 2011 James Sanders
+// Copyright (C) 2012 Eric Jon Sundstrom
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup auxlib
+//! @{
+
+
+//! wrapper for accessing external functions defined in ATLAS, LAPACK or BLAS libraries
+class auxlib
+  {
+  public:
+  
+  
+  template<const uword row, const uword col>
+  struct pos
+    {
+    static const uword n2 = row + col*2;
+    static const uword n3 = row + col*3;
+    static const uword n4 = row + col*4;
+    };
+  
+  
+  //
+  // inv
+  
+  template<typename eT, typename T1>
+  inline static bool inv(Mat<eT>& out, const Base<eT,T1>& X, const bool slow = false);
+  
+  template<typename eT>
+  inline static bool inv(Mat<eT>& out, const Mat<eT>& A, const bool slow = false);
+  
+  template<typename eT>
+  inline static bool inv_noalias_tinymat(Mat<eT>& out, const Mat<eT>& X, const uword N);
+  
+  template<typename eT>
+  inline static bool inv_inplace_tinymat(Mat<eT>& out, const uword N);
+  
+  template<typename eT>
+  inline static bool inv_inplace_lapack(Mat<eT>& out);
+  
+  
+  //
+  // inv_tr
+  
+  template<typename eT, typename T1>
+  inline static bool inv_tr(Mat<eT>& out, const Base<eT,T1>& X, const uword layout);
+  
+  
+  //
+  // inv_sym
+  
+  template<typename eT, typename T1>
+  inline static bool inv_sym(Mat<eT>& out, const Base<eT,T1>& X, const uword layout);
+  
+  
+  //
+  // inv_sympd
+  
+  template<typename eT, typename T1>
+  inline static bool inv_sympd(Mat<eT>& out, const Base<eT,T1>& X, const uword layout);
+  
+  
+  //
+  // det
+  
+  template<typename eT, typename T1>
+  inline static eT det(const Base<eT,T1>& X, const bool slow = false);
+  
+  template<typename eT>
+  inline static eT det_tinymat(const Mat<eT>& X, const uword N);
+  
+  template<typename eT>
+  inline static eT det_lapack(const Mat<eT>& X, const bool make_copy);
+  
+  
+  //
+  // log_det
+  
+  template<typename eT, typename T1>
+  inline static bool log_det(eT& out_val, typename get_pod_type<eT>::result& out_sign, const Base<eT,T1>& X);
+  
+  
+  //
+  // lu
+  
+  template<typename eT, typename T1>
+  inline static bool lu(Mat<eT>& L, Mat<eT>& U, podarray<blas_int>& ipiv, const Base<eT,T1>& X);
+  
+  template<typename eT, typename T1>
+  inline static bool lu(Mat<eT>& L, Mat<eT>& U, Mat<eT>& P, const Base<eT,T1>& X);
+  
+  template<typename eT, typename T1>
+  inline static bool lu(Mat<eT>& L, Mat<eT>& U, const Base<eT,T1>& X);
+  
+  
+  //
+  // eig
+  
+  template<typename eT, typename T1> 
+  inline static bool eig_sym(Col<eT>& eigval, const Base<eT,T1>& X);
+  
+  template<typename T, typename T1> 
+  inline static bool eig_sym(Col<T>& eigval, const Base<std::complex<T>,T1>& X);
+  
+  template<typename eT, typename T1>
+  inline static bool eig_sym(Col<eT>& eigval, Mat<eT>& eigvec, const Base<eT,T1>& X);
+  
+  template<typename T, typename T1>
+  inline static bool eig_sym(Col<T>& eigval, Mat< std::complex<T> >& eigvec, const Base<std::complex<T>,T1>& X);
+  
+  template<typename eT, typename T1>
+  inline static bool eig_sym_dc(Col<eT>& eigval, Mat<eT>& eigvec, const Base<eT,T1>& X);
+  
+  template<typename T, typename T1>
+  inline static bool eig_sym_dc(Col<T>& eigval, Mat< std::complex<T> >& eigvec, const Base<std::complex<T>,T1>& X);
+  
+  template<typename T, typename T1>
+  inline static bool eig_gen(Col< std::complex<T> >& eigval, Mat<T>& l_eigvec, Mat<T>& r_eigvec, const Base<T,T1>& X, const char side);
+  
+  template<typename T, typename T1>
+  inline static bool eig_gen(Col< std::complex<T> >& eigval, Mat< std::complex<T> >& l_eigvec, Mat< std::complex<T> >& r_eigvec, const Base< std::complex<T>, T1 >& X, const char side);
+  
+  
+  //
+  // chol
+  
+  template<typename eT, typename T1>
+  inline static bool chol(Mat<eT>& out, const Base<eT,T1>& X);
+  
+  
+  //
+  // qr
+  
+  template<typename eT, typename T1>
+  inline static bool qr(Mat<eT>& Q, Mat<eT>& R, const Base<eT,T1>& X);
+  
+  template<typename eT, typename T1>
+  inline static bool qr_econ(Mat<eT>& Q, Mat<eT>& R, const Base<eT,T1>& X);
+  
+  
+  //
+  // svd
+  
+  template<typename eT, typename T1>
+  inline static bool svd(Col<eT>& S, const Base<eT,T1>& X, uword& n_rows, uword& n_cols);
+  
+  template<typename T, typename T1>
+  inline static bool svd(Col<T>& S, const Base<std::complex<T>, T1>& X, uword& n_rows, uword& n_cols);
+  
+  template<typename eT, typename T1>
+  inline static bool svd(Col<eT>& S, const Base<eT,T1>& X);
+  
+  template<typename T, typename T1>
+  inline static bool svd(Col<T>& S, const Base<std::complex<T>, T1>& X);
+  
+  template<typename eT, typename T1>
+  inline static bool svd(Mat<eT>& U, Col<eT>& S, Mat<eT>& V, const Base<eT,T1>& X);
+  
+  template<typename T, typename T1>
+  inline static bool svd(Mat< std::complex<T> >& U, Col<T>& S, Mat< std::complex<T> >& V, const Base< std::complex<T>, T1>& X);
+  
+  template<typename eT, typename T1>
+  inline static bool svd_econ(Mat<eT>& U, Col<eT>& S, Mat<eT>& V, const Base<eT,T1>& X, const char mode);
+  
+  template<typename T, typename T1>
+  inline static bool svd_econ(Mat< std::complex<T> >& U, Col<T>& S, Mat< std::complex<T> >& V, const Base< std::complex<T>, T1>& X, const char mode);
+  
+  template<typename eT, typename T1>
+  inline static bool svd_dc(Mat<eT>& U, Col<eT>& S, Mat<eT>& V, const Base<eT,T1>& X);
+  
+  template<typename T, typename T1>
+  inline static bool svd_dc(Mat< std::complex<T> >& U, Col<T>& S, Mat< std::complex<T> >& V, const Base< std::complex<T>, T1>& X);
+  
+  
+  //
+  // solve
+  
+  template<typename eT, typename T1>
+  inline static bool solve   (Mat<eT>& out, Mat<eT>& A, const Base<eT,T1>& X, const bool slow = false);
+  
+  template<typename eT, typename T1>
+  inline static bool solve_od(Mat<eT>& out, Mat<eT>& A, const Base<eT,T1>& X);
+  
+  template<typename eT, typename T1>
+  inline static bool solve_ud(Mat<eT>& out, Mat<eT>& A, const Base<eT,T1>& X);
+  
+  
+  //
+  // solve_tr
+  
+  template<typename eT>
+  inline static bool solve_tr(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const uword layout);
+
+
+  //
+  // Schur decomposition
+  
+  template<typename eT>
+  inline static bool schur_dec(Mat<eT>& Z, Mat<eT>& T, const Mat<eT>& A);
+  
+  template<typename cT>
+  inline static bool schur_dec(Mat<std::complex<cT> >& Z, Mat<std::complex<cT> >& T, const Mat<std::complex<cT> >& A);
+  
+  
+  //
+  // syl (solution of the Sylvester equation AX + XB = C)
+  
+  template<typename eT>
+  inline static bool syl(Mat<eT>& X, const Mat<eT>& A, const Mat<eT>& B, const Mat<eT>& C);
+  
+  
+  //
+  // lyap (solution of the continuous Lyapunov equation AX + XA^H + Q = 0)
+  
+  template<typename eT>
+  inline static bool lyap(Mat<eT>& X, const Mat<eT>& A, const Mat<eT>& Q);
+  
+  
+  //
+  // dlyap (solution of the discrete Lyapunov equation AXA^H - X + Q = 0)
+  
+  template<typename eT>
+  inline static bool dlyap(Mat<eT>& X, const Mat<eT>& A, const Mat<eT>& Q);
+  };
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/auxlib_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,3249 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// Copyright (C) 2009 Edmund Highcock
+// Copyright (C) 2011 James Sanders
+// Copyright (C) 2011 Stanislav Funiak
+// Copyright (C) 2012 Eric Jon Sundstrom
+// Copyright (C) 2012 Michael McNeil Forbes
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup auxlib
+//! @{
+
+
+
+//! immediate matrix inverse
+template<typename eT, typename T1>
+inline
+bool
+auxlib::inv(Mat<eT>& out, const Base<eT,T1>& X, const bool slow)
+  {
+  arma_extra_debug_sigprint();
+  
+  out = X.get_ref();
+  
+  arma_debug_check( (out.is_square() == false), "inv(): given matrix is not square" );
+  
+  bool status = false;
+  
+  const uword N = out.n_rows;
+  
+  if( (N <= 4) && (slow == false) )
+    {
+    status = auxlib::inv_inplace_tinymat(out, N);
+    }
+    
+  if( (N > 4) || (status == false) )
+    {
+    status = auxlib::inv_inplace_lapack(out);
+    }
+  
+  return status;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+auxlib::inv(Mat<eT>& out, const Mat<eT>& X, const bool slow)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (X.is_square() == false), "inv(): given matrix is not square" );
+  
+  bool status = false;
+  
+  const uword N = X.n_rows;
+  
+  if( (N <= 4) && (slow == false) )
+    {
+    status = (&out != &X) ? auxlib::inv_noalias_tinymat(out, X, N) : auxlib::inv_inplace_tinymat(out, N);
+    }
+  
+  if( (N > 4) || (status == false) )
+    {
+    out = X;
+    status = auxlib::inv_inplace_lapack(out);
+    }
+  
+  return status;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+auxlib::inv_noalias_tinymat(Mat<eT>& out, const Mat<eT>& X, const uword N)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool det_ok = true;
+  
+  out.set_size(N,N);
+  
+  switch(N)
+    {
+    case 1:
+      {
+      out[0] = eT(1) / X[0];
+      };
+      break;
+      
+    case 2:
+      {
+      const eT* Xm = X.memptr();
+      
+      const eT a = Xm[pos<0,0>::n2];
+      const eT b = Xm[pos<0,1>::n2];
+      const eT c = Xm[pos<1,0>::n2];
+      const eT d = Xm[pos<1,1>::n2];
+      
+      const eT tmp_det = (a*d - b*c);
+      
+      if(tmp_det != eT(0))
+        {
+        eT* outm = out.memptr();
+        
+        outm[pos<0,0>::n2] =  d / tmp_det;
+        outm[pos<0,1>::n2] = -b / tmp_det;
+        outm[pos<1,0>::n2] = -c / tmp_det;
+        outm[pos<1,1>::n2] =  a / tmp_det;
+        }
+      else
+        {
+        det_ok = false;
+        }
+      };
+      break;
+    
+    case 3:
+      {
+      const eT* X_col0 = X.colptr(0);
+      const eT a11 = X_col0[0];
+      const eT a21 = X_col0[1];
+      const eT a31 = X_col0[2];
+      
+      const eT* X_col1 = X.colptr(1);
+      const eT a12 = X_col1[0];
+      const eT a22 = X_col1[1];
+      const eT a32 = X_col1[2];
+      
+      const eT* X_col2 = X.colptr(2);
+      const eT a13 = X_col2[0];
+      const eT a23 = X_col2[1];
+      const eT a33 = X_col2[2];
+      
+      const eT tmp_det = a11*(a33*a22 - a32*a23) - a21*(a33*a12-a32*a13) + a31*(a23*a12 - a22*a13);
+      
+      if(tmp_det != eT(0))
+        {
+        eT* out_col0 = out.colptr(0);
+        out_col0[0] =  (a33*a22 - a32*a23) / tmp_det;
+        out_col0[1] = -(a33*a21 - a31*a23) / tmp_det;
+        out_col0[2] =  (a32*a21 - a31*a22) / tmp_det;
+        
+        eT* out_col1 = out.colptr(1);
+        out_col1[0] = -(a33*a12 - a32*a13) / tmp_det;
+        out_col1[1] =  (a33*a11 - a31*a13) / tmp_det;
+        out_col1[2] = -(a32*a11 - a31*a12) / tmp_det;
+        
+        eT* out_col2 = out.colptr(2);
+        out_col2[0] =  (a23*a12 - a22*a13) / tmp_det;
+        out_col2[1] = -(a23*a11 - a21*a13) / tmp_det;
+        out_col2[2] =  (a22*a11 - a21*a12) / tmp_det;
+        }
+      else
+        {
+        det_ok = false;
+        }
+      };
+      break;
+      
+    case 4:
+      {
+      const eT tmp_det = det(X);
+      
+      if(tmp_det != eT(0))
+        {
+        const eT* Xm   = X.memptr();
+              eT* outm = out.memptr();
+        
+        outm[pos<0,0>::n4] = ( Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] - Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] - Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] + Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
+        outm[pos<1,0>::n4] = ( Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] + Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] + Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] - Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
+        outm[pos<2,0>::n4] = ( Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] + Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] - Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] + Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
+        outm[pos<3,0>::n4] = ( Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] + Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] - Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] ) / tmp_det;
+        
+        outm[pos<0,1>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] - Xm[pos<0,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
+        outm[pos<1,1>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] + Xm[pos<0,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] + Xm[pos<0,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
+        outm[pos<2,1>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,1>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,0>::n4]*Xm[pos<2,3>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,3>::n4] - Xm[pos<0,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
+        outm[pos<3,1>::n4] = ( Xm[pos<0,1>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,0>::n4] + Xm[pos<0,2>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,0>::n4]*Xm[pos<2,2>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,1>::n4]*Xm[pos<2,0>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,0>::n4]*Xm[pos<2,1>::n4]*Xm[pos<3,2>::n4] ) / tmp_det;
+        
+        outm[pos<0,2>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,3>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
+        outm[pos<1,2>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,2>::n4] + Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,3>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
+        outm[pos<2,2>::n4] = ( Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,0>::n4] + Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<3,1>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,3>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,3>::n4] ) / tmp_det;
+        outm[pos<3,2>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<3,1>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<3,2>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<3,2>::n4] ) / tmp_det;
+        
+        outm[pos<0,3>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4] + Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4] ) / tmp_det;
+        outm[pos<1,3>::n4] = ( Xm[pos<0,2>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4] + Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,2>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,3>::n4] ) / tmp_det;
+        outm[pos<2,3>::n4] = ( Xm[pos<0,3>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,3>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,3>::n4]*Xm[pos<2,1>::n4] + Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,3>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,3>::n4] ) / tmp_det;
+        outm[pos<3,3>::n4] = ( Xm[pos<0,1>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,0>::n4] - Xm[pos<0,2>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,0>::n4] + Xm[pos<0,2>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,0>::n4]*Xm[pos<1,2>::n4]*Xm[pos<2,1>::n4] - Xm[pos<0,1>::n4]*Xm[pos<1,0>::n4]*Xm[pos<2,2>::n4] + Xm[pos<0,0>::n4]*Xm[pos<1,1>::n4]*Xm[pos<2,2>::n4] ) / tmp_det;
+        }
+      else
+        {
+        det_ok = false;
+        }
+      };
+      break;
+    
+    default:
+      ;
+    }
+  
+  return det_ok;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+auxlib::inv_inplace_tinymat(Mat<eT>& X, const uword N)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool det_ok = true;
+  
+  // for more info, see:
+  // http://www.dr-lex.34sp.com/random/matrix_inv.html
+  // http://www.cvl.iis.u-tokyo.ac.jp/~miyazaki/tech/teche23.html
+  // http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
+  // http://www.geometrictools.com//LibFoundation/Mathematics/Wm4Matrix4.inl
+  
+  switch(N)
+    {
+    case 1:
+      {
+      X[0] = eT(1) / X[0];
+      };
+      break;
+      
+    case 2:
+      {
+      const eT a = X[pos<0,0>::n2];
+      const eT b = X[pos<0,1>::n2];
+      const eT c = X[pos<1,0>::n2];
+      const eT d = X[pos<1,1>::n2];
+      
+      const eT tmp_det = (a*d - b*c);
+      
+      if(tmp_det != eT(0))
+        {
+        X[pos<0,0>::n2] =  d / tmp_det;
+        X[pos<0,1>::n2] = -b / tmp_det;
+        X[pos<1,0>::n2] = -c / tmp_det;
+        X[pos<1,1>::n2] =  a / tmp_det;
+        }
+      else
+        {
+        det_ok = false;
+        }
+      };
+      break;
+    
+    case 3:
+      {
+      eT* X_col0 = X.colptr(0);
+      eT* X_col1 = X.colptr(1);
+      eT* X_col2 = X.colptr(2);
+      
+      const eT a11 = X_col0[0];
+      const eT a21 = X_col0[1];
+      const eT a31 = X_col0[2];
+      
+      const eT a12 = X_col1[0];
+      const eT a22 = X_col1[1];
+      const eT a32 = X_col1[2];
+      
+      const eT a13 = X_col2[0];
+      const eT a23 = X_col2[1];
+      const eT a33 = X_col2[2];
+      
+      const eT tmp_det = a11*(a33*a22 - a32*a23) - a21*(a33*a12-a32*a13) + a31*(a23*a12 - a22*a13);
+      
+      if(tmp_det != eT(0))
+        {
+        X_col0[0] =  (a33*a22 - a32*a23) / tmp_det;
+        X_col0[1] = -(a33*a21 - a31*a23) / tmp_det;
+        X_col0[2] =  (a32*a21 - a31*a22) / tmp_det;
+        
+        X_col1[0] = -(a33*a12 - a32*a13) / tmp_det;
+        X_col1[1] =  (a33*a11 - a31*a13) / tmp_det;
+        X_col1[2] = -(a32*a11 - a31*a12) / tmp_det;
+        
+        X_col2[0] =  (a23*a12 - a22*a13) / tmp_det;
+        X_col2[1] = -(a23*a11 - a21*a13) / tmp_det;
+        X_col2[2] =  (a22*a11 - a21*a12) / tmp_det;
+        }
+      else
+        {
+        det_ok = false;
+        }
+      };
+      break;
+      
+    case 4:
+      {
+      const eT tmp_det = det(X);
+      
+      if(tmp_det != eT(0))
+        {
+        const Mat<eT> A(X);
+        
+        const eT* Am = A.memptr();
+              eT* Xm = X.memptr();
+        
+        Xm[pos<0,0>::n4] = ( Am[pos<1,2>::n4]*Am[pos<2,3>::n4]*Am[pos<3,1>::n4] - Am[pos<1,3>::n4]*Am[pos<2,2>::n4]*Am[pos<3,1>::n4] + Am[pos<1,3>::n4]*Am[pos<2,1>::n4]*Am[pos<3,2>::n4] - Am[pos<1,1>::n4]*Am[pos<2,3>::n4]*Am[pos<3,2>::n4] - Am[pos<1,2>::n4]*Am[pos<2,1>::n4]*Am[pos<3,3>::n4] + Am[pos<1,1>::n4]*Am[pos<2,2>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
+        Xm[pos<1,0>::n4] = ( Am[pos<1,3>::n4]*Am[pos<2,2>::n4]*Am[pos<3,0>::n4] - Am[pos<1,2>::n4]*Am[pos<2,3>::n4]*Am[pos<3,0>::n4] - Am[pos<1,3>::n4]*Am[pos<2,0>::n4]*Am[pos<3,2>::n4] + Am[pos<1,0>::n4]*Am[pos<2,3>::n4]*Am[pos<3,2>::n4] + Am[pos<1,2>::n4]*Am[pos<2,0>::n4]*Am[pos<3,3>::n4] - Am[pos<1,0>::n4]*Am[pos<2,2>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
+        Xm[pos<2,0>::n4] = ( Am[pos<1,1>::n4]*Am[pos<2,3>::n4]*Am[pos<3,0>::n4] - Am[pos<1,3>::n4]*Am[pos<2,1>::n4]*Am[pos<3,0>::n4] + Am[pos<1,3>::n4]*Am[pos<2,0>::n4]*Am[pos<3,1>::n4] - Am[pos<1,0>::n4]*Am[pos<2,3>::n4]*Am[pos<3,1>::n4] - Am[pos<1,1>::n4]*Am[pos<2,0>::n4]*Am[pos<3,3>::n4] + Am[pos<1,0>::n4]*Am[pos<2,1>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
+        Xm[pos<3,0>::n4] = ( Am[pos<1,2>::n4]*Am[pos<2,1>::n4]*Am[pos<3,0>::n4] - Am[pos<1,1>::n4]*Am[pos<2,2>::n4]*Am[pos<3,0>::n4] - Am[pos<1,2>::n4]*Am[pos<2,0>::n4]*Am[pos<3,1>::n4] + Am[pos<1,0>::n4]*Am[pos<2,2>::n4]*Am[pos<3,1>::n4] + Am[pos<1,1>::n4]*Am[pos<2,0>::n4]*Am[pos<3,2>::n4] - Am[pos<1,0>::n4]*Am[pos<2,1>::n4]*Am[pos<3,2>::n4] ) / tmp_det;
+        
+        Xm[pos<0,1>::n4] = ( Am[pos<0,3>::n4]*Am[pos<2,2>::n4]*Am[pos<3,1>::n4] - Am[pos<0,2>::n4]*Am[pos<2,3>::n4]*Am[pos<3,1>::n4] - Am[pos<0,3>::n4]*Am[pos<2,1>::n4]*Am[pos<3,2>::n4] + Am[pos<0,1>::n4]*Am[pos<2,3>::n4]*Am[pos<3,2>::n4] + Am[pos<0,2>::n4]*Am[pos<2,1>::n4]*Am[pos<3,3>::n4] - Am[pos<0,1>::n4]*Am[pos<2,2>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
+        Xm[pos<1,1>::n4] = ( Am[pos<0,2>::n4]*Am[pos<2,3>::n4]*Am[pos<3,0>::n4] - Am[pos<0,3>::n4]*Am[pos<2,2>::n4]*Am[pos<3,0>::n4] + Am[pos<0,3>::n4]*Am[pos<2,0>::n4]*Am[pos<3,2>::n4] - Am[pos<0,0>::n4]*Am[pos<2,3>::n4]*Am[pos<3,2>::n4] - Am[pos<0,2>::n4]*Am[pos<2,0>::n4]*Am[pos<3,3>::n4] + Am[pos<0,0>::n4]*Am[pos<2,2>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
+        Xm[pos<2,1>::n4] = ( Am[pos<0,3>::n4]*Am[pos<2,1>::n4]*Am[pos<3,0>::n4] - Am[pos<0,1>::n4]*Am[pos<2,3>::n4]*Am[pos<3,0>::n4] - Am[pos<0,3>::n4]*Am[pos<2,0>::n4]*Am[pos<3,1>::n4] + Am[pos<0,0>::n4]*Am[pos<2,3>::n4]*Am[pos<3,1>::n4] + Am[pos<0,1>::n4]*Am[pos<2,0>::n4]*Am[pos<3,3>::n4] - Am[pos<0,0>::n4]*Am[pos<2,1>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
+        Xm[pos<3,1>::n4] = ( Am[pos<0,1>::n4]*Am[pos<2,2>::n4]*Am[pos<3,0>::n4] - Am[pos<0,2>::n4]*Am[pos<2,1>::n4]*Am[pos<3,0>::n4] + Am[pos<0,2>::n4]*Am[pos<2,0>::n4]*Am[pos<3,1>::n4] - Am[pos<0,0>::n4]*Am[pos<2,2>::n4]*Am[pos<3,1>::n4] - Am[pos<0,1>::n4]*Am[pos<2,0>::n4]*Am[pos<3,2>::n4] + Am[pos<0,0>::n4]*Am[pos<2,1>::n4]*Am[pos<3,2>::n4] ) / tmp_det;
+        
+        Xm[pos<0,2>::n4] = ( Am[pos<0,2>::n4]*Am[pos<1,3>::n4]*Am[pos<3,1>::n4] - Am[pos<0,3>::n4]*Am[pos<1,2>::n4]*Am[pos<3,1>::n4] + Am[pos<0,3>::n4]*Am[pos<1,1>::n4]*Am[pos<3,2>::n4] - Am[pos<0,1>::n4]*Am[pos<1,3>::n4]*Am[pos<3,2>::n4] - Am[pos<0,2>::n4]*Am[pos<1,1>::n4]*Am[pos<3,3>::n4] + Am[pos<0,1>::n4]*Am[pos<1,2>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
+        Xm[pos<1,2>::n4] = ( Am[pos<0,3>::n4]*Am[pos<1,2>::n4]*Am[pos<3,0>::n4] - Am[pos<0,2>::n4]*Am[pos<1,3>::n4]*Am[pos<3,0>::n4] - Am[pos<0,3>::n4]*Am[pos<1,0>::n4]*Am[pos<3,2>::n4] + Am[pos<0,0>::n4]*Am[pos<1,3>::n4]*Am[pos<3,2>::n4] + Am[pos<0,2>::n4]*Am[pos<1,0>::n4]*Am[pos<3,3>::n4] - Am[pos<0,0>::n4]*Am[pos<1,2>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
+        Xm[pos<2,2>::n4] = ( Am[pos<0,1>::n4]*Am[pos<1,3>::n4]*Am[pos<3,0>::n4] - Am[pos<0,3>::n4]*Am[pos<1,1>::n4]*Am[pos<3,0>::n4] + Am[pos<0,3>::n4]*Am[pos<1,0>::n4]*Am[pos<3,1>::n4] - Am[pos<0,0>::n4]*Am[pos<1,3>::n4]*Am[pos<3,1>::n4] - Am[pos<0,1>::n4]*Am[pos<1,0>::n4]*Am[pos<3,3>::n4] + Am[pos<0,0>::n4]*Am[pos<1,1>::n4]*Am[pos<3,3>::n4] ) / tmp_det;
+        Xm[pos<3,2>::n4] = ( Am[pos<0,2>::n4]*Am[pos<1,1>::n4]*Am[pos<3,0>::n4] - Am[pos<0,1>::n4]*Am[pos<1,2>::n4]*Am[pos<3,0>::n4] - Am[pos<0,2>::n4]*Am[pos<1,0>::n4]*Am[pos<3,1>::n4] + Am[pos<0,0>::n4]*Am[pos<1,2>::n4]*Am[pos<3,1>::n4] + Am[pos<0,1>::n4]*Am[pos<1,0>::n4]*Am[pos<3,2>::n4] - Am[pos<0,0>::n4]*Am[pos<1,1>::n4]*Am[pos<3,2>::n4] ) / tmp_det;
+        
+        Xm[pos<0,3>::n4] = ( Am[pos<0,3>::n4]*Am[pos<1,2>::n4]*Am[pos<2,1>::n4] - Am[pos<0,2>::n4]*Am[pos<1,3>::n4]*Am[pos<2,1>::n4] - Am[pos<0,3>::n4]*Am[pos<1,1>::n4]*Am[pos<2,2>::n4] + Am[pos<0,1>::n4]*Am[pos<1,3>::n4]*Am[pos<2,2>::n4] + Am[pos<0,2>::n4]*Am[pos<1,1>::n4]*Am[pos<2,3>::n4] - Am[pos<0,1>::n4]*Am[pos<1,2>::n4]*Am[pos<2,3>::n4] ) / tmp_det;
+        Xm[pos<1,3>::n4] = ( Am[pos<0,2>::n4]*Am[pos<1,3>::n4]*Am[pos<2,0>::n4] - Am[pos<0,3>::n4]*Am[pos<1,2>::n4]*Am[pos<2,0>::n4] + Am[pos<0,3>::n4]*Am[pos<1,0>::n4]*Am[pos<2,2>::n4] - Am[pos<0,0>::n4]*Am[pos<1,3>::n4]*Am[pos<2,2>::n4] - Am[pos<0,2>::n4]*Am[pos<1,0>::n4]*Am[pos<2,3>::n4] + Am[pos<0,0>::n4]*Am[pos<1,2>::n4]*Am[pos<2,3>::n4] ) / tmp_det;
+        Xm[pos<2,3>::n4] = ( Am[pos<0,3>::n4]*Am[pos<1,1>::n4]*Am[pos<2,0>::n4] - Am[pos<0,1>::n4]*Am[pos<1,3>::n4]*Am[pos<2,0>::n4] - Am[pos<0,3>::n4]*Am[pos<1,0>::n4]*Am[pos<2,1>::n4] + Am[pos<0,0>::n4]*Am[pos<1,3>::n4]*Am[pos<2,1>::n4] + Am[pos<0,1>::n4]*Am[pos<1,0>::n4]*Am[pos<2,3>::n4] - Am[pos<0,0>::n4]*Am[pos<1,1>::n4]*Am[pos<2,3>::n4] ) / tmp_det;
+        Xm[pos<3,3>::n4] = ( Am[pos<0,1>::n4]*Am[pos<1,2>::n4]*Am[pos<2,0>::n4] - Am[pos<0,2>::n4]*Am[pos<1,1>::n4]*Am[pos<2,0>::n4] + Am[pos<0,2>::n4]*Am[pos<1,0>::n4]*Am[pos<2,1>::n4] - Am[pos<0,0>::n4]*Am[pos<1,2>::n4]*Am[pos<2,1>::n4] - Am[pos<0,1>::n4]*Am[pos<1,0>::n4]*Am[pos<2,2>::n4] + Am[pos<0,0>::n4]*Am[pos<1,1>::n4]*Am[pos<2,2>::n4] ) / tmp_det;
+        }
+      else
+        {
+        det_ok = false;
+        }
+      };
+      break;
+      
+    default:
+      ;
+    }
+  
+  return det_ok;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+auxlib::inv_inplace_lapack(Mat<eT>& out)
+  {
+  arma_extra_debug_sigprint();
+
+  if(out.is_empty())
+    {
+    return true;
+    }
+  
+  #if defined(ARMA_USE_ATLAS)
+    {
+    podarray<int> ipiv(out.n_rows);
+    
+    int info = atlas::clapack_getrf(atlas::CblasColMajor, out.n_rows, out.n_cols, out.memptr(), out.n_rows, ipiv.memptr());
+    
+    if(info == 0)
+      {
+      info = atlas::clapack_getri(atlas::CblasColMajor, out.n_rows, out.memptr(), out.n_rows, ipiv.memptr());
+      }
+    
+    return (info == 0);
+    }
+  #elif defined(ARMA_USE_LAPACK)
+    {
+    blas_int n_rows    = out.n_rows;
+    blas_int n_cols    = out.n_cols;
+    blas_int lwork     = 0;
+    blas_int lwork_min = (std::max)(blas_int(1), n_rows);
+    blas_int info      = 0;
+    
+    podarray<blas_int> ipiv(out.n_rows);
+    
+    eT        work_query[2];
+    blas_int lwork_query = -1;
+    
+    lapack::getri(&n_rows, out.memptr(), &n_rows, ipiv.memptr(), &work_query[0], &lwork_query, &info);
+    
+    if(info == 0)
+      {
+      const blas_int lwork_proposed = static_cast<blas_int>( access::tmp_real(work_query[0]) );
+      
+      lwork = (lwork_proposed > lwork_min) ? lwork_proposed : lwork_min;
+      }
+    else
+      {
+      return false;
+      }
+    
+    podarray<eT> work( static_cast<uword>(lwork) );
+    
+    lapack::getrf(&n_rows, &n_cols, out.memptr(), &n_rows, ipiv.memptr(), &info);
+    
+    if(info == 0)
+      {
+      lapack::getri(&n_rows, out.memptr(), &n_rows, ipiv.memptr(), work.memptr(), &lwork, &info);
+      }
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_stop("inv(): use of ATLAS or LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+bool
+auxlib::inv_tr(Mat<eT>& out, const Base<eT,T1>& X, const uword layout)
+  {
+  arma_extra_debug_sigprint();
+  
+  out = X.get_ref();
+  
+  arma_debug_check( (out.is_square() == false), "inv(): given matrix is not square" );
+  
+  if(out.is_empty())
+    {
+    return true;
+    }
+  
+  bool status;
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    char     uplo = (layout == 0) ? 'U' : 'L';
+    char     diag = 'N';
+    blas_int n    = blas_int(out.n_rows);
+    blas_int info = 0;
+    
+    lapack::trtri(&uplo, &diag, &n, out.memptr(), &n, &info);
+    
+    status = (info == 0);
+    }
+  #else
+    {
+    arma_ignore(layout);
+    arma_stop("inv(): use of LAPACK needs to be enabled");
+    status = false;
+    }
+  #endif
+  
+  
+  if(status == true)
+    {
+    if(layout == 0)
+      {
+      // upper triangular
+      out = trimatu(out);
+      }
+    else
+      {
+      // lower triangular      
+      out = trimatl(out);
+      }
+    }
+  
+  return status;
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+bool
+auxlib::inv_sym(Mat<eT>& out, const Base<eT,T1>& X, const uword layout)
+  {
+  arma_extra_debug_sigprint();
+  
+  out = X.get_ref();
+  
+  arma_debug_check( (out.is_square() == false), "inv(): given matrix is not square" );
+  
+  if(out.is_empty())
+    {
+    return true;
+    }
+  
+  bool status;
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    char     uplo  = (layout == 0) ? 'U' : 'L';
+    blas_int n     = blas_int(out.n_rows);
+    blas_int lwork = 3 * (n*n); // TODO: use lwork = -1 to determine optimal size
+    blas_int info  = 0;
+    
+    podarray<blas_int> ipiv;
+    ipiv.set_size(out.n_rows);
+    
+    podarray<eT> work;
+    work.set_size( uword(lwork) );
+    
+    lapack::sytrf(&uplo, &n, out.memptr(), &n, ipiv.memptr(), work.memptr(), &lwork, &info);
+    
+    status = (info == 0);
+    
+    if(status == true)
+      {
+      lapack::sytri(&uplo, &n, out.memptr(), &n, ipiv.memptr(), work.memptr(), &info);
+      
+      out = (layout == 0) ? symmatu(out) : symmatl(out);
+      
+      status = (info == 0);
+      }
+    }
+  #else
+    {
+    arma_ignore(layout);
+    arma_stop("inv(): use of LAPACK needs to be enabled");
+    status = false;
+    }
+  #endif
+  
+  return status;
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+bool
+auxlib::inv_sympd(Mat<eT>& out, const Base<eT,T1>& X, const uword layout)
+  {
+  arma_extra_debug_sigprint();
+  
+  out = X.get_ref();
+  
+  arma_debug_check( (out.is_square() == false), "inv(): given matrix is not square" );
+  
+  if(out.is_empty())
+    {
+    return true;
+    }
+  
+  bool status;
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    char     uplo = (layout == 0) ? 'U' : 'L';
+    blas_int n    = blas_int(out.n_rows);
+    blas_int info = 0;
+    
+    lapack::potrf(&uplo, &n, out.memptr(), &n, &info);
+    
+    status = (info == 0);
+    
+    if(status == true)
+      {
+      lapack::potri(&uplo, &n, out.memptr(), &n, &info);
+    
+      out = (layout == 0) ? symmatu(out) : symmatl(out);
+    
+      status = (info == 0);
+      }
+    }
+  #else
+    {
+    arma_ignore(layout);
+    arma_stop("inv(): use of LAPACK needs to be enabled");
+    status = false;
+    }
+  #endif
+  
+  return status;
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+eT
+auxlib::det(const Base<eT,T1>& X, const bool slow)
+  {
+  const unwrap<T1>   tmp(X.get_ref());
+  const Mat<eT>& A = tmp.M;
+  
+  arma_debug_check( (A.is_square() == false), "det(): matrix is not square" );
+  
+  const bool make_copy = (is_Mat<T1>::value == true) ? true : false;
+  
+  if(slow == false)
+    {
+    const uword N = A.n_rows;
+    
+    switch(N)
+      {
+      case 0:
+      case 1:
+      case 2:
+        return auxlib::det_tinymat(A, N);
+        break;
+      
+      case 3:
+      case 4:
+        {
+        const eT tmp_det = auxlib::det_tinymat(A, N);
+        return (tmp_det != eT(0)) ? tmp_det : auxlib::det_lapack(A, make_copy);
+        }
+        break;
+      
+      default:
+        return auxlib::det_lapack(A, make_copy);
+      }
+    }
+  
+  return auxlib::det_lapack(A, make_copy);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+auxlib::det_tinymat(const Mat<eT>& X, const uword N)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(N)
+    {
+    case 0:
+      return eT(1);
+      break;
+    
+    case 1:
+      return X[0];
+      break;
+    
+    case 2:
+      {
+      const eT* Xm = X.memptr();
+      
+      return ( Xm[pos<0,0>::n2]*Xm[pos<1,1>::n2] - Xm[pos<0,1>::n2]*Xm[pos<1,0>::n2] );
+      }
+      break;
+    
+    case 3:
+      {
+      // const double tmp1 = X.at(0,0) * X.at(1,1) * X.at(2,2);
+      // const double tmp2 = X.at(0,1) * X.at(1,2) * X.at(2,0);
+      // const double tmp3 = X.at(0,2) * X.at(1,0) * X.at(2,1);
+      // const double tmp4 = X.at(2,0) * X.at(1,1) * X.at(0,2);
+      // const double tmp5 = X.at(2,1) * X.at(1,2) * X.at(0,0);
+      // const double tmp6 = X.at(2,2) * X.at(1,0) * X.at(0,1);
+      // return (tmp1+tmp2+tmp3) - (tmp4+tmp5+tmp6);
+      
+      const eT* a_col0 = X.colptr(0);
+      const eT  a11    = a_col0[0];
+      const eT  a21    = a_col0[1];
+      const eT  a31    = a_col0[2];
+      
+      const eT* a_col1 = X.colptr(1);
+      const eT  a12    = a_col1[0];
+      const eT  a22    = a_col1[1];
+      const eT  a32    = a_col1[2];
+      
+      const eT* a_col2 = X.colptr(2);
+      const eT  a13    = a_col2[0];
+      const eT  a23    = a_col2[1];
+      const eT  a33    = a_col2[2];
+      
+      return ( a11*(a33*a22 - a32*a23) - a21*(a33*a12-a32*a13) + a31*(a23*a12 - a22*a13) );
+      }
+      break;
+      
+    case 4:
+      {
+      const eT* Xm = X.memptr();
+      
+      const eT val = \
+          Xm[pos<0,3>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,0>::n4] \
+        - Xm[pos<0,2>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,0>::n4] \
+        - Xm[pos<0,3>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,0>::n4] \
+        + Xm[pos<0,1>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,0>::n4] \
+        + Xm[pos<0,2>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,0>::n4] \
+        - Xm[pos<0,1>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,0>::n4] \
+        - Xm[pos<0,3>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,1>::n4] \
+        + Xm[pos<0,2>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,1>::n4] \
+        + Xm[pos<0,3>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,1>::n4] \
+        - Xm[pos<0,0>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,1>::n4] \
+        - Xm[pos<0,2>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,1>::n4] \
+        + Xm[pos<0,0>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,1>::n4] \
+        + Xm[pos<0,3>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,2>::n4] \
+        - Xm[pos<0,1>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,2>::n4] \
+        - Xm[pos<0,3>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,2>::n4] \
+        + Xm[pos<0,0>::n4] * Xm[pos<1,3>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,2>::n4] \
+        + Xm[pos<0,1>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,2>::n4] \
+        - Xm[pos<0,0>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,3>::n4] * Xm[pos<3,2>::n4] \
+        - Xm[pos<0,2>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,3>::n4] \
+        + Xm[pos<0,1>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,0>::n4] * Xm[pos<3,3>::n4] \
+        + Xm[pos<0,2>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,3>::n4] \
+        - Xm[pos<0,0>::n4] * Xm[pos<1,2>::n4] * Xm[pos<2,1>::n4] * Xm[pos<3,3>::n4] \
+        - Xm[pos<0,1>::n4] * Xm[pos<1,0>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,3>::n4] \
+        + Xm[pos<0,0>::n4] * Xm[pos<1,1>::n4] * Xm[pos<2,2>::n4] * Xm[pos<3,3>::n4] \
+        ;
+      
+      return val;
+      }
+      break;
+    
+    default:
+      return eT(0);
+      ;
+    }
+  }
+
+
+
+//! immediate determinant of a matrix using ATLAS or LAPACK
+template<typename eT>
+inline
+eT
+auxlib::det_lapack(const Mat<eT>& X, const bool make_copy)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT> X_copy;
+  
+  if(make_copy == true)
+    {
+    X_copy = X;
+    }
+  
+  Mat<eT>& tmp = (make_copy == true) ? X_copy : const_cast< Mat<eT>& >(X);
+  
+  if(tmp.is_empty())
+    {
+    return eT(1);
+    }
+  
+  
+  #if defined(ARMA_USE_ATLAS)
+    {
+    podarray<int> ipiv(tmp.n_rows);
+    
+    //const int info =
+    atlas::clapack_getrf(atlas::CblasColMajor, tmp.n_rows, tmp.n_cols, tmp.memptr(), tmp.n_rows, ipiv.memptr());
+    
+    // on output tmp appears to be L+U_alt, where U_alt is U with the main diagonal set to zero
+    eT val = tmp.at(0,0);
+    for(uword i=1; i < tmp.n_rows; ++i)
+      {
+      val *= tmp.at(i,i);
+      }
+    
+    int sign = +1;
+    for(uword i=0; i < tmp.n_rows; ++i)
+      {
+      if( int(i) != ipiv.mem[i] )  // NOTE: no adjustment required, as the clapack version of getrf() assumes counting from 0
+        {
+        sign *= -1;
+        }
+      }
+    
+    return ( (sign < 0) ? -val : val );
+    }
+  #elif defined(ARMA_USE_LAPACK)
+    {
+    podarray<blas_int> ipiv(tmp.n_rows);
+    
+    blas_int info   = 0;
+    blas_int n_rows = blas_int(tmp.n_rows);
+    blas_int n_cols = blas_int(tmp.n_cols);
+    
+    lapack::getrf(&n_rows, &n_cols, tmp.memptr(), &n_rows, ipiv.memptr(), &info);
+    
+    // on output tmp appears to be L+U_alt, where U_alt is U with the main diagonal set to zero
+    eT val = tmp.at(0,0);
+    for(uword i=1; i < tmp.n_rows; ++i)
+      {
+      val *= tmp.at(i,i);
+      }
+    
+    blas_int sign = +1;
+    for(uword i=0; i < tmp.n_rows; ++i)
+      {
+      if( blas_int(i) != (ipiv.mem[i] - 1) )  // NOTE: adjustment of -1 is required as Fortran counts from 1
+        {
+        sign *= -1;
+        }
+      }
+    
+    return ( (sign < 0) ? -val : val );
+    }
+  #else
+    {
+    arma_ignore(X);
+    arma_ignore(make_copy);
+    arma_ignore(tmp);
+    arma_stop("det(): use of ATLAS or LAPACK needs to be enabled");
+    return eT(0);
+    }
+  #endif
+  }
+
+
+
+//! immediate log determinant of a matrix using ATLAS or LAPACK
+template<typename eT, typename T1>
+inline
+bool
+auxlib::log_det(eT& out_val, typename get_pod_type<eT>::result& out_sign, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  #if defined(ARMA_USE_ATLAS)
+    {
+    Mat<eT> tmp(X.get_ref());
+    arma_debug_check( (tmp.is_square() == false), "log_det(): given matrix is not square" );
+    
+    if(tmp.is_empty())
+      {
+      out_val  = eT(0);
+      out_sign =  T(1);
+      return true;
+      }
+    
+    podarray<int> ipiv(tmp.n_rows);
+    
+    const int info = atlas::clapack_getrf(atlas::CblasColMajor, tmp.n_rows, tmp.n_cols, tmp.memptr(), tmp.n_rows, ipiv.memptr());
+    
+    // on output tmp appears to be L+U_alt, where U_alt is U with the main diagonal set to zero
+    
+    sword sign = (is_complex<eT>::value == false) ? ( (access::tmp_real( tmp.at(0,0) ) < T(0)) ? -1 : +1 ) : +1;
+    eT   val = (is_complex<eT>::value == false) ? std::log( (access::tmp_real( tmp.at(0,0) ) < T(0)) ? tmp.at(0,0)*T(-1) : tmp.at(0,0) ) : std::log( tmp.at(0,0) );
+    
+    for(uword i=1; i < tmp.n_rows; ++i)
+      {
+      const eT x = tmp.at(i,i);
+      
+      sign *= (is_complex<eT>::value == false) ? ( (access::tmp_real(x) < T(0)) ? -1 : +1 ) : +1;
+      val  += (is_complex<eT>::value == false) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x);
+      }
+    
+    for(uword i=0; i < tmp.n_rows; ++i)
+      {
+      if( int(i) != ipiv.mem[i] )  // NOTE: no adjustment required, as the clapack version of getrf() assumes counting from 0
+        {
+        sign *= -1;
+        }
+      }
+    
+    out_val  = val;
+    out_sign = T(sign);
+    
+    return (info == 0);
+    }
+  #elif defined(ARMA_USE_LAPACK)
+    {
+    Mat<eT> tmp(X.get_ref());
+    arma_debug_check( (tmp.is_square() == false), "log_det(): given matrix is not square" );
+    
+    if(tmp.is_empty())
+      {
+      out_val  = eT(0);
+      out_sign =  T(1);
+      return true;
+      }
+    
+    podarray<blas_int> ipiv(tmp.n_rows);
+    
+    blas_int info   = 0;
+    blas_int n_rows = blas_int(tmp.n_rows);
+    blas_int n_cols = blas_int(tmp.n_cols);
+    
+    lapack::getrf(&n_rows, &n_cols, tmp.memptr(), &n_rows, ipiv.memptr(), &info);
+    
+    // on output tmp appears to be L+U_alt, where U_alt is U with the main diagonal set to zero
+    
+    sword sign = (is_complex<eT>::value == false) ? ( (access::tmp_real( tmp.at(0,0) ) < T(0)) ? -1 : +1 ) : +1;
+    eT   val = (is_complex<eT>::value == false) ? std::log( (access::tmp_real( tmp.at(0,0) ) < T(0)) ? tmp.at(0,0)*T(-1) : tmp.at(0,0) ) : std::log( tmp.at(0,0) );
+    
+    for(uword i=1; i < tmp.n_rows; ++i)
+      {
+      const eT x = tmp.at(i,i);
+      
+      sign *= (is_complex<eT>::value == false) ? ( (access::tmp_real(x) < T(0)) ? -1 : +1 ) : +1;
+      val  += (is_complex<eT>::value == false) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x);
+      }
+    
+    for(uword i=0; i < tmp.n_rows; ++i)
+      {
+      if( blas_int(i) != (ipiv.mem[i] - 1) )  // NOTE: adjustment of -1 is required as Fortran counts from 1
+        {
+        sign *= -1;
+        }
+      }
+    
+    out_val  = val;
+    out_sign = T(sign);
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(X);
+    
+    out_val  = eT(0);
+    out_sign =  T(0);
+    
+    arma_stop("log_det(): use of ATLAS or LAPACK needs to be enabled");
+    
+    return false;
+    }
+  #endif
+  }
+
+
+
+//! immediate LU decomposition of a matrix using ATLAS or LAPACK
+template<typename eT, typename T1>
+inline
+bool
+auxlib::lu(Mat<eT>& L, Mat<eT>& U, podarray<blas_int>& ipiv, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  U = X.get_ref();
+  
+  const uword U_n_rows = U.n_rows;
+  const uword U_n_cols = U.n_cols;
+  
+  if(U.is_empty())
+    {
+    L.set_size(U_n_rows, 0);
+    U.set_size(0, U_n_cols);
+    ipiv.reset();
+    return true;
+    }
+  
+  #if defined(ARMA_USE_ATLAS) || defined(ARMA_USE_LAPACK)
+    {
+    bool status;
+    
+    #if defined(ARMA_USE_ATLAS)
+      {
+      ipiv.set_size( (std::min)(U_n_rows, U_n_cols) );
+      
+      int info = atlas::clapack_getrf(atlas::CblasColMajor, U_n_rows, U_n_cols, U.memptr(), U_n_rows, ipiv.memptr());
+      
+      status = (info == 0);
+      }
+    #elif defined(ARMA_USE_LAPACK)
+      {
+      ipiv.set_size( (std::min)(U_n_rows, U_n_cols) );
+      
+      blas_int info = 0;
+      
+      blas_int n_rows = U_n_rows;
+      blas_int n_cols = U_n_cols;
+      
+      
+      lapack::getrf(&n_rows, &n_cols, U.memptr(), &n_rows, ipiv.memptr(), &info);
+      
+      // take into account that Fortran counts from 1
+      arrayops::inplace_minus(ipiv.memptr(), blas_int(1), ipiv.n_elem);
+      
+      status = (info == 0);
+      }
+    #endif
+    
+    L.copy_size(U);
+    
+    for(uword col=0; col < U_n_cols; ++col)
+      {
+      for(uword row=0; (row < col) && (row < U_n_rows); ++row)
+        {
+        L.at(row,col) = eT(0);
+        }
+      
+      if( L.in_range(col,col) == true )
+        {
+        L.at(col,col) = eT(1);
+        }
+      
+      for(uword row = (col+1); row < U_n_rows; ++row)
+        {
+        L.at(row,col) = U.at(row,col);
+        U.at(row,col) = eT(0);
+        }
+      }
+    
+    return status;
+    }
+  #else
+    {
+    arma_stop("lu(): use of ATLAS or LAPACK needs to be enabled");
+    
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+bool
+auxlib::lu(Mat<eT>& L, Mat<eT>& U, Mat<eT>& P, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  podarray<blas_int> ipiv1;
+  const bool status = auxlib::lu(L, U, ipiv1, X);
+  
+  if(status == true)
+    {
+    if(U.is_empty())
+      {
+      // L and U have been already set to the correct empty matrices
+      P.eye(L.n_rows, L.n_rows);
+      return true;
+      }
+    
+    const uword n      = ipiv1.n_elem;
+    const uword P_rows = U.n_rows;
+    
+    podarray<blas_int> ipiv2(P_rows);
+    
+    const blas_int* ipiv1_mem = ipiv1.memptr();
+          blas_int* ipiv2_mem = ipiv2.memptr();
+    
+    for(uword i=0; i<P_rows; ++i)
+      {
+      ipiv2_mem[i] = blas_int(i);
+      }
+    
+    for(uword i=0; i<n; ++i)
+      {
+      const uword k = static_cast<uword>(ipiv1_mem[i]);
+      
+      if( ipiv2_mem[i] != ipiv2_mem[k] )
+        {
+        std::swap( ipiv2_mem[i], ipiv2_mem[k] );
+        }
+      }
+    
+    P.zeros(P_rows, P_rows);
+    
+    for(uword row=0; row<P_rows; ++row)
+      {
+      P.at(row, static_cast<uword>(ipiv2_mem[row])) = eT(1);
+      }
+    
+    if(L.n_cols > U.n_rows)
+      {
+      L.shed_cols(U.n_rows, L.n_cols-1);
+      }
+      
+    if(U.n_rows > L.n_cols)
+      {
+      U.shed_rows(L.n_cols, U.n_rows-1);
+      }
+    }
+  
+  return status;
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+bool
+auxlib::lu(Mat<eT>& L, Mat<eT>& U, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  podarray<blas_int> ipiv1;
+  const bool status = auxlib::lu(L, U, ipiv1, X);
+  
+  if(status == true)
+    {
+    if(U.is_empty())
+      {
+      // L and U have been already set to the correct empty matrices
+      return true;
+      }
+    
+    const uword n      = ipiv1.n_elem;
+    const uword P_rows = U.n_rows;
+    
+    podarray<blas_int> ipiv2(P_rows);
+    
+    const blas_int* ipiv1_mem = ipiv1.memptr();
+          blas_int* ipiv2_mem = ipiv2.memptr();
+    
+    for(uword i=0; i<P_rows; ++i)
+      {
+      ipiv2_mem[i] = blas_int(i);
+      }
+    
+    for(uword i=0; i<n; ++i)
+      {
+      const uword k = static_cast<uword>(ipiv1_mem[i]);
+      
+      if( ipiv2_mem[i] != ipiv2_mem[k] )
+        {
+        std::swap( ipiv2_mem[i], ipiv2_mem[k] );
+        L.swap_rows( static_cast<uword>(ipiv2_mem[i]), static_cast<uword>(ipiv2_mem[k]) );
+        }
+      }
+    
+    if(L.n_cols > U.n_rows)
+      {
+      L.shed_cols(U.n_rows, L.n_cols-1);
+      }
+      
+    if(U.n_rows > L.n_cols)
+      {
+      U.shed_rows(L.n_cols, U.n_rows-1);
+      }
+    }
+  
+  return status;
+  }
+
+
+
+//! immediate eigenvalues of a symmetric real matrix using LAPACK
+template<typename eT, typename T1>
+inline
+bool
+auxlib::eig_sym(Col<eT>& eigval, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    Mat<eT> A(X.get_ref());
+    
+    arma_debug_check( (A.is_square() == false), "eig_sym(): given matrix is not square");
+    
+    if(A.is_empty())
+      {
+      eigval.reset();
+      return true;
+      }
+    
+    eigval.set_size(A.n_rows);
+    
+    char jobz  = 'N';
+    char uplo  = 'U';
+    
+    blas_int N     = blas_int(A.n_rows);
+    blas_int lwork = 3 * ( (std::max)(blas_int(1), 3*N-1) );
+    blas_int info  = 0;
+    
+    podarray<eT> work( static_cast<uword>(lwork) );
+    
+    lapack::syev(&jobz, &uplo, &N, A.memptr(), &N, eigval.memptr(), work.memptr(), &lwork, &info);
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(eigval);
+    arma_ignore(X);
+    arma_stop("eig_sym(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+//! immediate eigenvalues of a hermitian complex matrix using LAPACK
+template<typename T, typename T1>
+inline
+bool
+auxlib::eig_sym(Col<T>& eigval, const Base<std::complex<T>,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    typedef typename std::complex<T> eT;
+    
+    Mat<eT> A(X.get_ref());
+    
+    arma_debug_check( (A.is_square() == false), "eig_sym(): given matrix is not square");
+    
+    if(A.is_empty())
+      {
+      eigval.reset();
+      return true;
+      }
+    
+    eigval.set_size(A.n_rows);
+    
+    char jobz  = 'N'; 
+    char uplo  = 'U';
+    
+    blas_int N     = blas_int(A.n_rows);
+    blas_int lwork = 3 * ( (std::max)(blas_int(1), 2*N-1) );
+    blas_int info  = 0;
+    
+    podarray<eT>  work( static_cast<uword>(lwork) );
+    podarray<T>  rwork( static_cast<uword>( (std::max)(blas_int(1), 3*N-2) ) );
+    
+    arma_extra_debug_print("lapack::heev()");
+    lapack::heev(&jobz, &uplo, &N, A.memptr(), &N, eigval.memptr(), work.memptr(), &lwork, rwork.memptr(), &info);
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(eigval);
+    arma_ignore(X);
+    arma_stop("eig_sym(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+//! immediate eigenvalues and eigenvectors of a symmetric real matrix using LAPACK
+template<typename eT, typename T1>
+inline
+bool
+auxlib::eig_sym(Col<eT>& eigval, Mat<eT>& eigvec, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    eigvec = X.get_ref();
+    
+    arma_debug_check( (eigvec.is_square() == false), "eig_sym(): given matrix is not square" );
+    
+    if(eigvec.is_empty())
+      {
+      eigval.reset();
+      eigvec.reset();
+      return true;
+      }
+    
+    eigval.set_size(eigvec.n_rows);
+    
+    char jobz  = 'V';
+    char uplo  = 'U';
+    
+    blas_int N     = blas_int(eigvec.n_rows);
+    blas_int lwork = 3 * ( (std::max)(blas_int(1), 3*N-1) );
+    blas_int info  = 0;
+    
+    podarray<eT> work( static_cast<uword>(lwork) );
+    
+    lapack::syev(&jobz, &uplo, &N, eigvec.memptr(), &N, eigval.memptr(), work.memptr(), &lwork, &info);
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(eigval);
+    arma_ignore(eigvec);
+    arma_ignore(X);
+    arma_stop("eig_sym(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+//! immediate eigenvalues and eigenvectors of a hermitian complex matrix using LAPACK
+template<typename T, typename T1>
+inline
+bool
+auxlib::eig_sym(Col<T>& eigval, Mat< std::complex<T> >& eigvec, const Base<std::complex<T>,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    typedef typename std::complex<T> eT;
+    
+    eigvec = X.get_ref();
+    
+    arma_debug_check( (eigvec.is_square() == false), "eig_sym(): given matrix is not square" );
+    
+    if(eigvec.is_empty())
+      {
+      eigval.reset();
+      eigvec.reset();
+      return true;
+      }
+    
+    eigval.set_size(eigvec.n_rows);
+    
+    char jobz  = 'V';
+    char uplo  = 'U';
+    
+    blas_int N     = blas_int(eigvec.n_rows);
+    blas_int lwork = 3 * ( (std::max)(blas_int(1), 2*N-1) );
+    blas_int info  = 0;
+    
+    podarray<eT>  work( static_cast<uword>(lwork) );
+    podarray<T>  rwork( static_cast<uword>((std::max)(blas_int(1), 3*N-2)) );
+    
+    arma_extra_debug_print("lapack::heev()");
+    lapack::heev(&jobz, &uplo, &N, eigvec.memptr(), &N, eigval.memptr(), work.memptr(), &lwork, rwork.memptr(), &info);
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(eigval);
+    arma_ignore(eigvec);
+    arma_ignore(X);
+    arma_stop("eig_sym(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+//! immediate eigenvalues and eigenvectors of a symmetric real matrix using LAPACK (divide and conquer algorithm)
+template<typename eT, typename T1>
+inline
+bool
+auxlib::eig_sym_dc(Col<eT>& eigval, Mat<eT>& eigvec, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    eigvec = X.get_ref();
+    
+    arma_debug_check( (eigvec.is_square() == false), "eig_sym(): given matrix is not square" );
+    
+    if(eigvec.is_empty())
+      {
+      eigval.reset();
+      eigvec.reset();
+      return true;
+      }
+    
+    eigval.set_size(eigvec.n_rows);
+    
+    char jobz = 'V';
+    char uplo = 'U';
+    
+    blas_int N      = blas_int(eigvec.n_rows);
+    blas_int lwork  = 3 * (1 + 6*N + 2*(N*N));
+    blas_int liwork = 3 * (3 + 5*N + 2);
+    blas_int info   = 0;
+    
+    podarray<eT>        work( static_cast<uword>( lwork) );
+    podarray<blas_int> iwork( static_cast<uword>(liwork) ); 
+    
+    arma_extra_debug_print("lapack::syevd()");
+    lapack::syevd(&jobz, &uplo, &N, eigvec.memptr(), &N, eigval.memptr(), work.memptr(), &lwork, iwork.memptr(), &liwork, &info);
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(eigval);
+    arma_ignore(eigvec);
+    arma_ignore(X);
+    arma_stop("eig_sym(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+//! immediate eigenvalues and eigenvectors of a hermitian complex matrix using LAPACK (divide and conquer algorithm)
+template<typename T, typename T1>
+inline
+bool
+auxlib::eig_sym_dc(Col<T>& eigval, Mat< std::complex<T> >& eigvec, const Base<std::complex<T>,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    typedef typename std::complex<T> eT;
+    
+    eigvec = X.get_ref();
+    
+    arma_debug_check( (eigvec.is_square() == false), "eig_sym(): given matrix is not square" );
+    
+    if(eigvec.is_empty())
+      {
+      eigval.reset();
+      eigvec.reset();
+      return true;
+      }
+    
+    eigval.set_size(eigvec.n_rows);
+    
+    char jobz  = 'V';
+    char uplo  = 'U';
+    
+    blas_int N      = blas_int(eigvec.n_rows);
+    blas_int lwork  = 3 * (2*N + N*N);
+    blas_int lrwork = 3 * (1 + 5*N + 2*(N*N));
+    blas_int liwork = 3 * (3 + 5*N);
+    blas_int info   = 0;
+    
+    podarray<eT>        work( static_cast<uword>(lwork)  );
+    podarray<T>        rwork( static_cast<uword>(lrwork) );
+    podarray<blas_int> iwork( static_cast<uword>(liwork) ); 
+    
+    arma_extra_debug_print("lapack::heevd()");
+    lapack::heevd(&jobz, &uplo, &N, eigvec.memptr(), &N, eigval.memptr(), work.memptr(), &lwork, rwork.memptr(), &lrwork, iwork.memptr(), &liwork, &info);
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(eigval);
+    arma_ignore(eigvec);
+    arma_ignore(X);
+    arma_stop("eig_sym(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+//! Eigenvalues and eigenvectors of a general square real matrix using LAPACK.
+//! The argument 'side' specifies which eigenvectors should be calculated
+//! (see code for mode details).
+template<typename T, typename T1>
+inline
+bool
+auxlib::eig_gen
+  (
+  Col< std::complex<T> >&   eigval,
+  Mat<T>&                 l_eigvec,
+  Mat<T>&                 r_eigvec,
+  const Base<T,T1>&       X,
+  const char              side
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    char jobvl;
+    char jobvr;
+    
+    switch(side)
+      {
+      case 'l':  // left
+        jobvl = 'V';
+        jobvr = 'N';
+        break;
+        
+      case 'r':  // right
+        jobvl = 'N';
+        jobvr = 'V';
+        break;
+        
+      case 'b':  // both
+        jobvl = 'V';
+        jobvr = 'V';
+        break;
+        
+      case 'n':  // neither
+        jobvl = 'N';
+        jobvr = 'N';
+        break;
+      
+      default:
+        arma_stop("eig_gen(): parameter 'side' is invalid");
+        return false;
+      }
+    
+    Mat<T> A(X.get_ref());
+    arma_debug_check( (A.is_square() == false), "eig_gen(): given matrix is not square" );
+    
+    if(A.is_empty())
+      {
+      eigval.reset();
+      l_eigvec.reset();
+      r_eigvec.reset();
+      return true;
+      }
+    
+    const uword A_n_rows = A.n_rows;
+    
+    eigval.set_size(A_n_rows);
+    
+    l_eigvec.set_size(A_n_rows, A_n_rows);
+    r_eigvec.set_size(A_n_rows, A_n_rows);
+    
+    blas_int N     = blas_int(A_n_rows);
+    blas_int lwork = 3 * ( (std::max)(blas_int(1), 4*N) );
+    blas_int info  = 0;
+    
+    podarray<T> work( static_cast<uword>(lwork) );
+    
+    podarray<T> wr(A_n_rows);
+    podarray<T> wi(A_n_rows);
+    
+    arma_extra_debug_print("lapack::geev()");
+    lapack::geev(&jobvl, &jobvr, &N, A.memptr(), &N, wr.memptr(), wi.memptr(), l_eigvec.memptr(), &N, r_eigvec.memptr(), &N, work.memptr(), &lwork, &info);
+    
+    eigval.set_size(A_n_rows);
+    for(uword i=0; i<A_n_rows; ++i)
+      {
+      eigval[i] = std::complex<T>(wr[i], wi[i]);
+      }
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(eigval);
+    arma_ignore(l_eigvec);
+    arma_ignore(r_eigvec);
+    arma_ignore(X);
+    arma_ignore(side);
+    arma_stop("eig_gen(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+
+
+//! Eigenvalues and eigenvectors of a general square complex matrix using LAPACK
+//! The argument 'side' specifies which eigenvectors should be calculated
+//! (see code for mode details).
+template<typename T, typename T1>
+inline
+bool
+auxlib::eig_gen
+  (
+  Col< std::complex<T> >&              eigval,
+  Mat< std::complex<T> >&            l_eigvec, 
+  Mat< std::complex<T> >&            r_eigvec, 
+  const Base< std::complex<T>, T1 >& X, 
+  const char                         side
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    typedef typename std::complex<T> eT;
+    
+    char jobvl;
+    char jobvr;
+    
+    switch(side)
+      {
+      case 'l':  // left
+        jobvl = 'V';
+        jobvr = 'N';
+        break;
+        
+      case 'r':  // right
+        jobvl = 'N';
+        jobvr = 'V';
+        break;
+        
+      case 'b':  // both
+        jobvl = 'V';
+        jobvr = 'V';
+        break;
+        
+      case 'n':  // neither
+        jobvl = 'N';
+        jobvr = 'N';
+        break;
+      
+      default:
+        arma_stop("eig_gen(): parameter 'side' is invalid");
+        return false;
+      }
+    
+    Mat<eT> A(X.get_ref());
+    arma_debug_check( (A.is_square() == false), "eig_gen(): given matrix is not square" );
+    
+    if(A.is_empty())
+      {
+      eigval.reset();
+      l_eigvec.reset();
+      r_eigvec.reset();
+      return true;
+      }
+    
+    const uword A_n_rows = A.n_rows;
+    
+    eigval.set_size(A_n_rows);
+    
+    l_eigvec.set_size(A_n_rows, A_n_rows);
+    r_eigvec.set_size(A_n_rows, A_n_rows);
+    
+    blas_int N     = blas_int(A_n_rows);
+    blas_int lwork = 3 * ( (std::max)(blas_int(1), 2*N) );
+    blas_int info  = 0;
+    
+    podarray<eT>  work( static_cast<uword>(lwork) );
+    podarray<T>  rwork( static_cast<uword>(2*N)   );
+    
+    arma_extra_debug_print("lapack::cx_geev()");
+    lapack::cx_geev(&jobvl, &jobvr, &N, A.memptr(), &N, eigval.memptr(), l_eigvec.memptr(), &N, r_eigvec.memptr(), &N, work.memptr(), &lwork, rwork.memptr(), &info);
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(eigval);
+    arma_ignore(l_eigvec);
+    arma_ignore(r_eigvec);
+    arma_ignore(X);
+    arma_ignore(side);
+    arma_stop("eig_gen(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+bool
+auxlib::chol(Mat<eT>& out, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    out = X.get_ref();
+    
+    arma_debug_check( (out.is_square() == false), "chol(): given matrix is not square" );
+    
+    if(out.is_empty())
+      {
+      return true;
+      }
+    
+    const uword out_n_rows = out.n_rows;
+    
+    char      uplo = 'U';
+    blas_int  n    = out_n_rows;
+    blas_int  info = 0;
+    
+    lapack::potrf(&uplo, &n, out.memptr(), &n, &info);
+    
+    for(uword col=0; col<out_n_rows; ++col)
+      {
+      eT* colptr = out.colptr(col);
+      
+      for(uword row=(col+1); row < out_n_rows; ++row)
+        {
+        colptr[row] = eT(0);
+        }
+      }
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(out);
+    arma_ignore(X);
+    
+    arma_stop("chol(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+bool
+auxlib::qr(Mat<eT>& Q, Mat<eT>& R, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    R = X.get_ref();
+    
+    const uword R_n_rows = R.n_rows;
+    const uword R_n_cols = R.n_cols;
+    
+    if(R.is_empty())
+      {
+      Q.eye(R_n_rows, R_n_rows);
+      return true;
+      }
+    
+    blas_int m         = static_cast<blas_int>(R_n_rows);
+    blas_int n         = static_cast<blas_int>(R_n_cols);
+    blas_int lwork     = 0;
+    blas_int lwork_min = (std::max)(blas_int(1), (std::max)(m,n));  // take into account requirements of geqrf() _and_ orgqr()/ungqr()
+    blas_int k         = (std::min)(m,n);
+    blas_int info      = 0;
+    
+    podarray<eT> tau( static_cast<uword>(k) );
+    
+    eT        work_query[2];
+    blas_int lwork_query = -1;
+    
+    lapack::geqrf(&m, &n, R.memptr(), &m, tau.memptr(), &work_query[0], &lwork_query, &info);
+    
+    if(info == 0)
+      {
+      const blas_int lwork_proposed = static_cast<blas_int>( access::tmp_real(work_query[0]) );
+      
+      lwork = (lwork_proposed > lwork_min) ? lwork_proposed : lwork_min;
+      }
+    else
+      {
+      return false;
+      }
+    
+    podarray<eT> work( static_cast<uword>(lwork) );
+    
+    lapack::geqrf(&m, &n, R.memptr(), &m, tau.memptr(), work.memptr(), &lwork, &info);
+    
+    Q.set_size(R_n_rows, R_n_rows);
+    
+    arrayops::copy( Q.memptr(), R.memptr(), (std::min)(Q.n_elem, R.n_elem) );
+    
+    //
+    // construct R
+    
+    for(uword col=0; col < R_n_cols; ++col)
+      {
+      for(uword row=(col+1); row < R_n_rows; ++row)
+        {
+        R.at(row,col) = eT(0);
+        }
+      }
+    
+    
+    if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
+      {
+      lapack::orgqr(&m, &m, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork, &info);
+      }
+    else
+    if( (is_supported_complex_float<eT>::value == true) || (is_supported_complex_double<eT>::value == true) )
+      {
+      lapack::ungqr(&m, &m, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork, &info);
+      }
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(Q);
+    arma_ignore(R);
+    arma_ignore(X);
+    arma_stop("qr(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+bool 
+auxlib::qr_econ(Mat<eT>& Q, Mat<eT>& R, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  // This function implements a memory-efficient QR for a non-square X that has dimensions m x n.
+  // This basically discards the basis for the null-space.
+  // 
+  // if m <= n: (use standard routine)
+  //     Q[m,m]*R[m,n] = X[m,n]
+  //     geqrf Needs A[m,n]: Uses R
+  //     orgqr Needs A[m,m]: Uses Q
+  // otherwise: (memory-efficient routine)
+  //     Q[m,n]*R[n,n] = X[m,n]
+  //     geqrf Needs A[m,n]: Uses Q
+  //     geqrf Needs A[m,n]: Uses Q
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    if(is_Mat<T1>::value == true)
+      {
+      const unwrap<T1>   tmp(X.get_ref());
+      const Mat<eT>& M = tmp.M;
+      
+      if(M.n_rows < M.n_cols)
+        {
+        return auxlib::qr(Q, R, X);
+        }
+      }
+    
+    Q = X.get_ref();
+    
+    const uword Q_n_rows = Q.n_rows;
+    const uword Q_n_cols = Q.n_cols;
+    
+    if( Q_n_rows <= Q_n_cols )
+      {
+      return auxlib::qr(Q, R, Q);
+      }
+    
+    if(Q.is_empty())
+      {
+      Q.set_size(Q_n_rows, 0       );
+      R.set_size(0,        Q_n_cols);
+      return true;
+      }
+    
+    blas_int m         = static_cast<blas_int>(Q_n_rows);
+    blas_int n         = static_cast<blas_int>(Q_n_cols);
+    blas_int lwork     = 0;
+    blas_int lwork_min = (std::max)(blas_int(1), (std::max)(m,n));  // take into account requirements of geqrf() _and_ orgqr()/ungqr()
+    blas_int k         = (std::min)(m,n);
+    blas_int info      = 0;
+    
+    podarray<eT> tau( static_cast<uword>(k) );
+    
+    eT        work_query[2];
+    blas_int lwork_query = -1;
+    
+    lapack::geqrf(&m, &n, Q.memptr(), &m, tau.memptr(), &work_query[0], &lwork_query, &info);
+    
+    if(info == 0)
+      {
+      const blas_int lwork_proposed = static_cast<blas_int>( access::tmp_real(work_query[0]) );
+      
+      lwork = (lwork_proposed > lwork_min) ? lwork_proposed : lwork_min;
+      }
+    else
+      {
+      return false;
+      }
+    
+    podarray<eT> work( static_cast<uword>(lwork) );
+    
+    lapack::geqrf(&m, &n, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork, &info);
+    
+    // Q now has the elements on and above the diagonal of the array
+    // contain the min(M,N)-by-N upper trapezoidal matrix Q
+    // (Q is upper triangular if m >= n);
+    // the elements below the diagonal, with the array TAU,
+    // represent the orthogonal matrix Q as a product of min(m,n) elementary reflectors.
+    
+    R.set_size(Q_n_cols, Q_n_cols);
+    
+    //
+    // construct R
+    
+    for(uword col=0; col < Q_n_cols; ++col)
+      {
+      for(uword row=0; row <= col; ++row)
+        {
+        R.at(row,col) = Q.at(row,col);
+        }
+      
+      for(uword row=(col+1); row < Q_n_cols; ++row)
+        {
+        R.at(row,col) = eT(0);
+        }
+      }
+    
+    if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
+      {
+      lapack::orgqr(&m, &n, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork, &info);
+      }
+    else
+    if( (is_supported_complex_float<eT>::value == true) || (is_supported_complex_double<eT>::value == true) )
+      {
+      lapack::ungqr(&m, &n, &k, Q.memptr(), &m, tau.memptr(), work.memptr(), &lwork, &info);
+      }
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(Q);
+    arma_ignore(R);
+    arma_ignore(X);
+    arma_stop("qr_econ(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+bool
+auxlib::svd(Col<eT>& S, const Base<eT,T1>& X, uword& X_n_rows, uword& X_n_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    Mat<eT> A(X.get_ref());
+    
+    X_n_rows = A.n_rows;
+    X_n_cols = A.n_cols;
+    
+    if(A.is_empty())
+      {
+      S.reset();
+      return true;
+      }
+    
+    Mat<eT> U(1, 1);
+    Mat<eT> V(1, A.n_cols);
+    
+    char jobu  = 'N';
+    char jobvt = 'N';
+    
+    blas_int m          = A.n_rows;
+    blas_int n          = A.n_cols;
+    blas_int min_mn     = (std::min)(m,n);
+    blas_int lda        = A.n_rows;
+    blas_int ldu        = U.n_rows;
+    blas_int ldvt       = V.n_rows;
+    blas_int lwork      = 0;
+    blas_int lwork_min  = (std::max)( blas_int(1), (std::max)( (3*min_mn + (std::max)(m,n)), 5*min_mn ) );
+    blas_int info   = 0;
+    
+    S.set_size( static_cast<uword>(min_mn) );
+    
+    eT        work_query[2];
+    blas_int lwork_query = -1;
+    
+    lapack::gesvd<eT>
+      (
+      &jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, &info
+      );
+    
+    if(info == 0)
+      {
+      const blas_int lwork_proposed = static_cast<blas_int>( work_query[0] );
+      
+      lwork = (lwork_proposed > lwork_min) ? lwork_proposed : lwork_min;
+      
+      podarray<eT> work( static_cast<uword>(lwork) );
+      
+      lapack::gesvd<eT>
+        (
+        &jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, &info
+        );
+      }
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(S);
+    arma_ignore(X);
+    arma_ignore(X_n_rows);
+    arma_ignore(X_n_cols);
+    arma_stop("svd(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename T, typename T1>
+inline
+bool
+auxlib::svd(Col<T>& S, const Base<std::complex<T>, T1>& X, uword& X_n_rows, uword& X_n_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    typedef std::complex<T> eT;
+    
+    Mat<eT> A(X.get_ref());
+    
+    X_n_rows = A.n_rows;
+    X_n_cols = A.n_cols;
+    
+    if(A.is_empty())
+      {
+      S.reset();
+      return true;
+      }
+    
+    Mat<eT> U(1, 1);
+    Mat<eT> V(1, A.n_cols);
+    
+    char jobu  = 'N';
+    char jobvt = 'N';
+    
+    blas_int  m      = A.n_rows;
+    blas_int  n      = A.n_cols;
+    blas_int  min_mn = (std::min)(m,n);
+    blas_int  lda    = A.n_rows;
+    blas_int  ldu    = U.n_rows;
+    blas_int  ldvt   = V.n_rows;
+    blas_int  lwork  = 3 * ( (std::max)(blas_int(1), 2*min_mn+(std::max)(m,n) ) );
+    blas_int  info   = 0;
+    
+    S.set_size( static_cast<uword>(min_mn) );
+    
+    podarray<eT>   work( static_cast<uword>(lwork   ) );
+    podarray< T>  rwork( static_cast<uword>(5*min_mn) );
+    
+    // let gesvd_() calculate the optimum size of the workspace
+    blas_int lwork_tmp = -1;
+    
+    lapack::cx_gesvd<T>
+      (
+      &jobu, &jobvt,
+      &m, &n,
+      A.memptr(), &lda,
+      S.memptr(),
+      U.memptr(), &ldu,
+      V.memptr(), &ldvt,
+      work.memptr(), &lwork_tmp,
+      rwork.memptr(),
+      &info
+      );
+    
+    if(info == 0)
+      {
+      blas_int proposed_lwork = static_cast<blas_int>(real(work[0]));
+      if(proposed_lwork > lwork)
+        {
+        lwork = proposed_lwork;
+        work.set_size( static_cast<uword>(lwork) );
+        }
+      
+      lapack::cx_gesvd<T>
+        (
+        &jobu, &jobvt,
+        &m, &n,
+        A.memptr(), &lda,
+        S.memptr(),
+        U.memptr(), &ldu,
+        V.memptr(), &ldvt,
+        work.memptr(), &lwork,
+        rwork.memptr(),
+        &info
+        );
+      }
+        
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(S);
+    arma_ignore(X);
+    arma_ignore(X_n_rows);
+    arma_ignore(X_n_cols);
+
+    arma_stop("svd(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+bool
+auxlib::svd(Col<eT>& S, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  uword junk;
+  return auxlib::svd(S, X, junk, junk);
+  }
+
+
+
+template<typename T, typename T1>
+inline
+bool
+auxlib::svd(Col<T>& S, const Base<std::complex<T>, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  uword junk;
+  return auxlib::svd(S, X, junk, junk);
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+bool
+auxlib::svd(Mat<eT>& U, Col<eT>& S, Mat<eT>& V, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    Mat<eT> A(X.get_ref());
+    
+    if(A.is_empty())
+      {
+      U.eye(A.n_rows, A.n_rows);
+      S.reset();
+      V.eye(A.n_cols, A.n_cols);
+      return true;
+      }
+    
+    U.set_size(A.n_rows, A.n_rows);
+    V.set_size(A.n_cols, A.n_cols);
+    
+    char jobu  = 'A';
+    char jobvt = 'A';
+    
+    blas_int  m          = blas_int(A.n_rows);
+    blas_int  n          = blas_int(A.n_cols);
+    blas_int  min_mn     = (std::min)(m,n);
+    blas_int  lda        = blas_int(A.n_rows);
+    blas_int  ldu        = blas_int(U.n_rows);
+    blas_int  ldvt       = blas_int(V.n_rows);
+    blas_int  lwork_min  = (std::max)( blas_int(1), (std::max)( (3*min_mn + (std::max)(m,n)), 5*min_mn ) );
+    blas_int  lwork      = 0;
+    blas_int  info       = 0;
+    
+    S.set_size( static_cast<uword>(min_mn) );
+    
+    // let gesvd_() calculate the optimum size of the workspace
+    eT        work_query[2];
+    blas_int lwork_query = -1;
+    
+    lapack::gesvd<eT>
+      (
+      &jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, &work_query[0], &lwork_query, &info
+      );
+    
+    if(info == 0)
+      {
+      const blas_int lwork_proposed = static_cast<blas_int>( work_query[0] );
+      
+      lwork = (lwork_proposed > lwork_min) ? lwork_proposed : lwork_min;
+      
+      podarray<eT> work( static_cast<uword>(lwork) );
+      
+      lapack::gesvd<eT>
+        (
+        &jobu, &jobvt, &m, &n, A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt, work.memptr(), &lwork, &info
+        );
+      
+      op_strans::apply(V,V);  // op_strans will work out that an in-place transpose can be done
+      }
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(U);
+    arma_ignore(S);
+    arma_ignore(V);
+    arma_ignore(X);
+    arma_stop("svd(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename T, typename T1>
+inline
+bool
+auxlib::svd(Mat< std::complex<T> >& U, Col<T>& S, Mat< std::complex<T> >& V, const Base< std::complex<T>, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    typedef std::complex<T> eT;
+    
+    Mat<eT> A(X.get_ref());
+    
+    if(A.is_empty())
+      {
+      U.eye(A.n_rows, A.n_rows);
+      S.reset();
+      V.eye(A.n_cols, A.n_cols);
+      return true;
+      }
+    
+    U.set_size(A.n_rows, A.n_rows);
+    V.set_size(A.n_cols, A.n_cols);
+    
+    char jobu  = 'A';
+    char jobvt = 'A';
+    
+    blas_int  m      = blas_int(A.n_rows);
+    blas_int  n      = blas_int(A.n_cols);
+    blas_int  min_mn = (std::min)(m,n);
+    blas_int  lda    = blas_int(A.n_rows);
+    blas_int  ldu    = blas_int(U.n_rows);
+    blas_int  ldvt   = blas_int(V.n_rows);
+    blas_int  lwork  = 3 * ( (std::max)(blas_int(1), 2*min_mn + (std::max)(m,n) ) );
+    blas_int  info   = 0;
+    
+    S.set_size( static_cast<uword>(min_mn) );
+    
+    podarray<eT>  work( static_cast<uword>(lwork   ) );
+    podarray<T>  rwork( static_cast<uword>(5*min_mn) );
+    
+    // let gesvd_() calculate the optimum size of the workspace
+    blas_int lwork_tmp = -1;
+    lapack::cx_gesvd<T>
+     (
+     &jobu, &jobvt,
+     &m, &n,
+     A.memptr(), &lda,
+     S.memptr(),
+     U.memptr(), &ldu,
+     V.memptr(), &ldvt,
+     work.memptr(), &lwork_tmp,
+     rwork.memptr(),
+     &info
+     );
+    
+    if(info == 0)
+      {
+      blas_int proposed_lwork = static_cast<blas_int>(real(work[0]));
+      
+      if(proposed_lwork > lwork)
+        {
+        lwork = proposed_lwork;
+        work.set_size( static_cast<uword>(lwork) );
+        }
+      
+      lapack::cx_gesvd<T>
+        (
+        &jobu, &jobvt,
+        &m, &n,
+        A.memptr(), &lda,
+        S.memptr(),
+        U.memptr(), &ldu,
+        V.memptr(), &ldvt,
+        work.memptr(), &lwork,
+        rwork.memptr(),
+        &info
+        );
+      
+      op_htrans::apply(V,V);  // op_htrans will work out that an in-place transpose can be done
+      }
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(U);
+    arma_ignore(S);
+    arma_ignore(V);
+    arma_ignore(X);
+    arma_stop("svd(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+bool
+auxlib::svd_econ(Mat<eT>& U, Col<eT>& S, Mat<eT>& V, const Base<eT,T1>& X, const char mode)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    Mat<eT> A(X.get_ref());
+    
+    blas_int m      = blas_int(A.n_rows);
+    blas_int n      = blas_int(A.n_cols);
+    blas_int min_mn = (std::min)(m,n);
+    blas_int lda    = blas_int(A.n_rows);
+    
+    S.set_size( static_cast<uword>(min_mn) );
+    
+    blas_int ldu  = 0;
+    blas_int ldvt = 0;
+    
+    char jobu;
+    char jobvt;
+    
+    switch(mode)
+      {
+      case 'l':
+        jobu  = 'S';
+        jobvt = 'N';
+        
+        ldu  = m;
+        ldvt = 1;
+        
+        U.set_size( static_cast<uword>(ldu), static_cast<uword>(min_mn) );
+        V.reset();
+        
+        break;
+      
+      
+      case 'r':
+        jobu  = 'N';
+        jobvt = 'S';
+        
+        ldu = 1;
+        ldvt = (std::min)(m,n);
+        
+        U.reset();
+        V.set_size( static_cast<uword>(ldvt), static_cast<uword>(n) );
+        
+        break;
+      
+      
+      case 'b':
+        jobu  = 'S';
+        jobvt = 'S';
+        
+        ldu  = m;
+        ldvt = (std::min)(m,n);
+        
+        U.set_size( static_cast<uword>(ldu),  static_cast<uword>(min_mn) );
+        V.set_size( static_cast<uword>(ldvt), static_cast<uword>(n     ) );
+        
+        break;
+      
+      
+      default:
+        U.reset();
+        S.reset();
+        V.reset();
+        return false;
+      }
+    
+    
+    if(A.is_empty())
+      {
+      U.eye();
+      S.reset();
+      V.eye();
+      return true;
+      }
+    
+    
+    blas_int lwork = 3 * ( (std::max)(blas_int(1), (std::max)( (3*min_mn + (std::max)(m,n)), 5*min_mn ) ) );
+    blas_int info  = 0;
+    
+    
+    podarray<eT> work( static_cast<uword>(lwork) );
+    
+    // let gesvd_() calculate the optimum size of the workspace
+    blas_int lwork_tmp = -1;
+    
+    lapack::gesvd<eT>
+      (
+      &jobu, &jobvt,
+      &m, &n,
+      A.memptr(), &lda,
+      S.memptr(),
+      U.memptr(), &ldu,
+      V.memptr(), &ldvt,
+      work.memptr(), &lwork_tmp,
+      &info
+      );
+    
+    if(info == 0)
+      {
+      blas_int proposed_lwork = static_cast<blas_int>(work[0]);
+      if(proposed_lwork > lwork)
+        {
+        lwork = proposed_lwork;
+        work.set_size( static_cast<uword>(lwork) );
+        }
+      
+      lapack::gesvd<eT>
+        (
+        &jobu, &jobvt,
+        &m, &n,
+        A.memptr(), &lda,
+        S.memptr(),
+        U.memptr(), &ldu,
+        V.memptr(), &ldvt,
+        work.memptr(), &lwork,
+        &info
+        );
+      
+      op_strans::apply(V,V);  // op_strans will work out that an in-place transpose can be done
+      }
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(U);
+    arma_ignore(S);
+    arma_ignore(V);
+    arma_ignore(X);
+    arma_ignore(mode);
+    arma_stop("svd(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename T, typename T1>
+inline
+bool
+auxlib::svd_econ(Mat< std::complex<T> >& U, Col<T>& S, Mat< std::complex<T> >& V, const Base< std::complex<T>, T1>& X, const char mode)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    typedef std::complex<T> eT;
+    
+    Mat<eT> A(X.get_ref());
+    
+    blas_int m      = blas_int(A.n_rows);
+    blas_int n      = blas_int(A.n_cols);
+    blas_int min_mn = (std::min)(m,n);
+    blas_int lda    = blas_int(A.n_rows);
+    
+    S.set_size( static_cast<uword>(min_mn) );
+    
+    blas_int ldu  = 0;
+    blas_int ldvt = 0;
+    
+    char jobu;
+    char jobvt;
+    
+    switch(mode)
+      {
+      case 'l':
+        jobu  = 'S';
+        jobvt = 'N';
+        
+        ldu  = m;
+        ldvt = 1;
+        
+        U.set_size( static_cast<uword>(ldu), static_cast<uword>(min_mn) );
+        V.reset();
+        
+        break;
+      
+      
+      case 'r':
+        jobu  = 'N';
+        jobvt = 'S';
+        
+        ldu  = 1;
+        ldvt = (std::min)(m,n);
+        
+        U.reset();
+        V.set_size( static_cast<uword>(ldvt), static_cast<uword>(n) );
+        
+        break;
+      
+      
+      case 'b':
+        jobu  = 'S';
+        jobvt = 'S';
+        
+        ldu  = m;
+        ldvt = (std::min)(m,n);
+        
+        U.set_size( static_cast<uword>(ldu),  static_cast<uword>(min_mn) );
+        V.set_size( static_cast<uword>(ldvt), static_cast<uword>(n)      );
+        
+        break;
+      
+      
+      default:
+        U.reset();
+        S.reset();
+        V.reset();
+        return false;
+      }
+    
+    
+    if(A.is_empty())
+      {
+      U.eye();
+      S.reset();
+      V.eye();
+      return true;
+      }
+    
+    
+    blas_int lwork = 3 * ( (std::max)(blas_int(1), (std::max)( (3*min_mn + (std::max)(m,n)), 5*min_mn ) ) );
+    blas_int info  = 0;
+    
+    
+    podarray<eT>  work( static_cast<uword>(lwork   ) );
+    podarray<T>  rwork( static_cast<uword>(5*min_mn) );
+    
+    // let gesvd_() calculate the optimum size of the workspace
+    blas_int lwork_tmp = -1;
+    
+    lapack::cx_gesvd<T>
+      (
+      &jobu, &jobvt,
+      &m, &n,
+      A.memptr(), &lda,
+      S.memptr(),
+      U.memptr(), &ldu,
+      V.memptr(), &ldvt,
+      work.memptr(), &lwork_tmp,
+      rwork.memptr(),
+      &info
+      );
+    
+    if(info == 0)
+      {
+      blas_int proposed_lwork = static_cast<blas_int>(real(work[0]));
+      if(proposed_lwork > lwork)
+        {
+        lwork = proposed_lwork;
+        work.set_size( static_cast<uword>(lwork) );
+        }
+      
+      lapack::cx_gesvd<T>
+        (
+        &jobu, &jobvt,
+        &m, &n,
+        A.memptr(), &lda,
+        S.memptr(),
+        U.memptr(), &ldu,
+        V.memptr(), &ldvt,
+        work.memptr(), &lwork,
+        rwork.memptr(),
+        &info
+        );
+      
+      op_htrans::apply(V,V);  // op_strans will work out that an in-place transpose can be done
+      }
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(U);
+    arma_ignore(S);
+    arma_ignore(V);
+    arma_ignore(X);
+    arma_ignore(mode);
+    arma_stop("svd(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+bool
+auxlib::svd_dc(Mat<eT>& U, Col<eT>& S, Mat<eT>& V, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    Mat<eT> A(X.get_ref());
+    
+    if(A.is_empty())
+      {
+      U.eye(A.n_rows, A.n_rows);
+      S.reset();
+      V.eye(A.n_cols, A.n_cols);
+      return true;
+      }
+    
+    U.set_size(A.n_rows, A.n_rows);
+    V.set_size(A.n_cols, A.n_cols);
+    
+    char jobz = 'A';
+    
+    blas_int  m      = blas_int(A.n_rows);
+    blas_int  n      = blas_int(A.n_cols);
+    blas_int  min_mn = (std::min)(m,n);
+    blas_int  lda    = blas_int(A.n_rows);
+    blas_int  ldu    = blas_int(U.n_rows);
+    blas_int  ldvt   = blas_int(V.n_rows);
+    blas_int  lwork  = 3 * ( 3*min_mn*min_mn + (std::max)( (std::max)(m,n), 4*min_mn*min_mn + 4*min_mn ) );
+    blas_int  info   = 0;
+    
+    S.set_size( static_cast<uword>(min_mn) );
+    
+    podarray<eT>        work( static_cast<uword>(lwork   ) );
+    podarray<blas_int> iwork( static_cast<uword>(8*min_mn) );
+    
+    lapack::gesdd<eT>
+      (
+      &jobz, &m, &n,
+      A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt,
+      work.memptr(), &lwork, iwork.memptr(), &info
+      );
+    
+    op_strans::apply(V,V);  // op_strans will work out that an in-place transpose can be done
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(U);
+    arma_ignore(S);
+    arma_ignore(V);
+    arma_ignore(X);
+    arma_stop("svd(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename T, typename T1>
+inline
+bool
+auxlib::svd_dc(Mat< std::complex<T> >& U, Col<T>& S, Mat< std::complex<T> >& V, const Base< std::complex<T>, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    typedef std::complex<T> eT;
+    
+    Mat<eT> A(X.get_ref());
+    
+    if(A.is_empty())
+      {
+      U.eye(A.n_rows, A.n_rows);
+      S.reset();
+      V.eye(A.n_cols, A.n_cols);
+      return true;
+      }
+    
+    U.set_size(A.n_rows, A.n_rows);
+    V.set_size(A.n_cols, A.n_cols);
+    
+    char jobz = 'A';
+    
+    blas_int  m      = blas_int(A.n_rows);
+    blas_int  n      = blas_int(A.n_cols);
+    blas_int  min_mn = (std::min)(m,n);
+    blas_int  lda    = blas_int(A.n_rows);
+    blas_int  ldu    = blas_int(U.n_rows);
+    blas_int  ldvt   = blas_int(V.n_rows);
+    blas_int  lwork  = 3 * (min_mn*min_mn + 2*min_mn + (std::max)(m,n));
+    blas_int  info   = 0;
+    
+    S.set_size( static_cast<uword>(min_mn) );
+    
+    podarray<eT>        work( static_cast<uword>(lwork                     ) );
+    podarray<T>        rwork( static_cast<uword>(5*min_mn*min_mn + 7*min_mn) );
+    podarray<blas_int> iwork( static_cast<uword>(8*min_mn                  ) );
+    
+    lapack::cx_gesdd<T>
+      (
+      &jobz, &m, &n,
+      A.memptr(), &lda, S.memptr(), U.memptr(), &ldu, V.memptr(), &ldvt,
+      work.memptr(), &lwork, rwork.memptr(), iwork.memptr(), &info
+      );
+    
+    op_htrans::apply(V,V);  // op_htrans will work out that an in-place transpose can be done
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(U);
+    arma_ignore(S);
+    arma_ignore(V);
+    arma_ignore(X);
+    arma_stop("svd(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+//! Solve a system of linear equations.
+//! Assumes that A.n_rows = A.n_cols and B.n_rows = A.n_rows
+template<typename eT, typename T1>
+inline
+bool
+auxlib::solve(Mat<eT>& out, Mat<eT>& A, const Base<eT,T1>& X, const bool slow)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool status = false;
+  
+  const uword A_n_rows = A.n_rows;
+  
+  if( (A_n_rows <= 4) && (slow == false) )
+    {
+    Mat<eT> A_inv;
+    
+    status = auxlib::inv_noalias_tinymat(A_inv, A, A_n_rows);
+    
+    if(status == true)
+      {
+      const unwrap_check<T1> Y( X.get_ref(), out );
+      const Mat<eT>& B     = Y.M;
+      
+      const uword B_n_rows = B.n_rows;
+      const uword B_n_cols = B.n_cols;
+      
+      arma_debug_check( (A_n_rows != B_n_rows), "solve(): number of rows in the given objects must be the same" );
+      
+      if(A.is_empty() || B.is_empty())
+        {
+        out.zeros(A.n_cols, B_n_cols);
+        return true;
+        }
+      
+      out.set_size(A_n_rows, B_n_cols);
+      
+      gemm_emul<false,false,false,false>::apply(out, A_inv, B);
+      
+      return true;
+      }
+    }
+  
+  if( (A_n_rows > 4) || (status == false) )
+    {
+    out = X.get_ref();
+    
+    const uword B_n_rows = out.n_rows;
+    const uword B_n_cols = out.n_cols;
+      
+    arma_debug_check( (A_n_rows != B_n_rows), "solve(): number of rows in the given objects must be the same" );
+      
+    if(A.is_empty() || out.is_empty())
+      {
+      out.zeros(A.n_cols, B_n_cols);
+      return true;
+      }
+    
+    #if defined(ARMA_USE_ATLAS)
+      {
+      podarray<int> ipiv(A_n_rows + 2);  // +2 for paranoia: old versions of Atlas might be trashing memory
+      
+      int info = atlas::clapack_gesv<eT>(atlas::CblasColMajor, A_n_rows, B_n_cols, A.memptr(), A_n_rows, ipiv.memptr(), out.memptr(), A_n_rows);
+      
+      return (info == 0);
+      }
+    #elif defined(ARMA_USE_LAPACK)
+      {
+      blas_int n    = blas_int(A_n_rows);  // assuming A is square
+      blas_int lda  = blas_int(A_n_rows);
+      blas_int ldb  = blas_int(A_n_rows);
+      blas_int nrhs = blas_int(B_n_cols);
+      blas_int info = 0;
+      
+      podarray<blas_int> ipiv(A_n_rows + 2);  // +2 for paranoia: some versions of Lapack might be trashing memory
+      
+      arma_extra_debug_print("lapack::gesv()");
+      lapack::gesv<eT>(&n, &nrhs, A.memptr(), &lda, ipiv.memptr(), out.memptr(), &ldb, &info);
+      
+      arma_extra_debug_print("lapack::gesv() -- finished");
+      
+      return (info == 0);
+      }
+    #else
+      {
+      arma_stop("solve(): use of ATLAS or LAPACK needs to be enabled");
+      return false;
+      }
+    #endif
+    }
+  
+  return true;
+  }
+
+
+
+//! Solve an over-determined system.
+//! Assumes that A.n_rows > A.n_cols and B.n_rows = A.n_rows
+template<typename eT, typename T1>
+inline
+bool
+auxlib::solve_od(Mat<eT>& out, Mat<eT>& A, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    Mat<eT> tmp = X.get_ref();
+    
+    const uword A_n_rows = A.n_rows;
+    const uword A_n_cols = A.n_cols;
+    
+    const uword B_n_rows = tmp.n_rows;
+    const uword B_n_cols = tmp.n_cols;
+      
+    arma_debug_check( (A_n_rows != B_n_rows), "solve(): number of rows in the given objects must be the same" );
+    
+    out.set_size(A_n_cols, B_n_cols);
+    
+    if(A.is_empty() || tmp.is_empty())
+      {
+      out.zeros();
+      return true;
+      }
+    
+    char trans = 'N';
+    
+    blas_int  m     = blas_int(A_n_rows);
+    blas_int  n     = blas_int(A_n_cols);
+    blas_int  lda   = blas_int(A_n_rows);
+    blas_int  ldb   = blas_int(A_n_rows);
+    blas_int  nrhs  = blas_int(B_n_cols);
+    blas_int  lwork = 3 * ( (std::max)(blas_int(1), n + (std::max)(n, nrhs)) );
+    blas_int  info  = 0;
+    
+    podarray<eT> work( static_cast<uword>(lwork) );
+    
+    // NOTE: the dgels() function in the lapack library supplied by ATLAS 3.6 seems to have problems
+    arma_extra_debug_print("lapack::gels()");
+    lapack::gels<eT>( &trans, &m, &n, &nrhs, A.memptr(), &lda, tmp.memptr(), &ldb, work.memptr(), &lwork, &info );
+    
+    arma_extra_debug_print("lapack::gels() -- finished");
+    
+    for(uword col=0; col<B_n_cols; ++col)
+      {
+      arrayops::copy( out.colptr(col), tmp.colptr(col), A_n_cols );
+      }
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(out);
+    arma_ignore(A);
+    arma_ignore(X);
+    arma_stop("solve(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+//! Solve an under-determined system.
+//! Assumes that A.n_rows < A.n_cols and B.n_rows = A.n_rows
+template<typename eT, typename T1>
+inline
+bool
+auxlib::solve_ud(Mat<eT>& out, Mat<eT>& A, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  // TODO: this function provides the same results as Octave 3.4.2.
+  // TODO: however, these results are different than Matlab 7.12.0.635.
+  // TODO: figure out whether both Octave and Matlab are correct, or only one of them
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    const unwrap<T1>   Y( X.get_ref() );
+    const Mat<eT>& B = Y.M;
+    
+    const uword A_n_rows = A.n_rows;
+    const uword A_n_cols = A.n_cols;
+    
+    const uword B_n_rows = B.n_rows;
+    const uword B_n_cols = B.n_cols;
+    
+    arma_debug_check( (A_n_rows != B_n_rows), "solve(): number of rows in the given objects must be the same" );
+    
+    // B could be an alias of "out", hence we need to check whether B is empty before setting the size of "out"
+    if(A.is_empty() || B.is_empty())
+      {
+      out.zeros(A_n_cols, B_n_cols);
+      return true;
+      }
+    
+    char trans = 'N';
+    
+    blas_int  m     = blas_int(A_n_rows);
+    blas_int  n     = blas_int(A_n_cols);
+    blas_int  lda   = blas_int(A_n_rows);
+    blas_int  ldb   = blas_int(A_n_cols);
+    blas_int  nrhs  = blas_int(B_n_cols);
+    blas_int  lwork = 3 * ( (std::max)(blas_int(1), m + (std::max)(m,nrhs)) );
+    blas_int  info  = 0;
+    
+    Mat<eT> tmp(A_n_cols, B_n_cols);
+    tmp.zeros();
+    
+    for(uword col=0; col<B_n_cols; ++col)
+      {
+      eT* tmp_colmem = tmp.colptr(col);
+      
+      arrayops::copy( tmp_colmem, B.colptr(col), B_n_rows );
+      
+      for(uword row=B_n_rows; row<A_n_cols; ++row)
+        {
+        tmp_colmem[row] = eT(0);
+        }
+      }
+    
+    podarray<eT> work( static_cast<uword>(lwork) );
+    
+    // NOTE: the dgels() function in the lapack library supplied by ATLAS 3.6 seems to have problems
+    arma_extra_debug_print("lapack::gels()");
+    lapack::gels<eT>( &trans, &m, &n, &nrhs, A.memptr(), &lda, tmp.memptr(), &ldb, work.memptr(), &lwork, &info );
+    
+    arma_extra_debug_print("lapack::gels() -- finished");
+    
+    out.set_size(A_n_cols, B_n_cols);
+    
+    for(uword col=0; col<B_n_cols; ++col)
+      {
+      arrayops::copy( out.colptr(col), tmp.colptr(col), A_n_cols );
+      }
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(out);
+    arma_ignore(A);
+    arma_ignore(X);
+    arma_stop("solve(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+//
+// solve_tr
+
+template<typename eT>
+inline
+bool
+auxlib::solve_tr(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const uword layout)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    if(A.is_empty() || B.is_empty())
+      {
+      out.zeros(A.n_cols, B.n_cols);
+      return true;
+      }
+    
+    out = B;
+    
+    char     uplo  = (layout == 0) ? 'U' : 'L';
+    char     trans = 'N';
+    char     diag  = 'N';
+    blas_int n     = blas_int(A.n_rows);
+    blas_int nrhs  = blas_int(B.n_cols);
+    blas_int info  = 0;
+    
+    lapack::trtrs<eT>(&uplo, &trans, &diag, &n, &nrhs, A.memptr(), &n, out.memptr(), &n, &info);
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(out);
+    arma_ignore(A);
+    arma_ignore(B);
+    arma_ignore(layout);
+    arma_stop("solve(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+//
+// Schur decomposition
+
+template<typename eT>
+inline
+bool
+auxlib::schur_dec(Mat<eT>& Z, Mat<eT>& T, const Mat<eT>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    arma_debug_check( (A.is_square() == false), "schur_dec(): given matrix is not square" );
+    
+    if(A.is_empty())
+      {
+      Z.reset();
+      T.reset();
+      return true;
+      }
+    
+    const uword A_n_rows = A.n_rows;
+    
+    Z.set_size(A_n_rows, A_n_rows);
+    T = A;
+    
+    char    jobvs    = 'V';                // get Schur vectors (Z)
+    char     sort    = 'N';                // do not sort eigenvalues/vectors
+    blas_int* select = 0;                  // pointer to sorting function
+    blas_int    n    = blas_int(A_n_rows);
+    blas_int sdim    = 0;                  // output for sorting
+    blas_int lwork   = 3 * ( (std::max)(blas_int(1), 3*n) );
+    blas_int info    = 0;
+    
+    podarray<eT>       work( static_cast<uword>(lwork) );
+    podarray<blas_int> bwork(A_n_rows);
+    
+    podarray<eT> wr(A_n_rows);             // output for eigenvalues
+    podarray<eT> wi(A_n_rows);             // output for eigenvalues
+    
+    lapack::gees(&jobvs, &sort, select, &n, T.memptr(), &n, &sdim, wr.memptr(), wi.memptr(), Z.memptr(), &n, work.memptr(), &lwork, bwork.memptr(), &info);
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(Z);
+    arma_ignore(T);
+    arma_ignore(A);
+    
+    arma_stop("schur_dec(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename cT>
+inline
+bool
+auxlib::schur_dec(Mat<std::complex<cT> >& Z, Mat<std::complex<cT> >& T, const Mat<std::complex<cT> >& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    arma_debug_check( (A.is_square() == false), "schur_dec(): matrix A is not square" );
+    
+    if(A.is_empty())
+      {
+      Z.reset();
+      T.reset();
+      return true;
+      }
+    
+    typedef std::complex<cT> eT;
+    
+    const uword A_n_rows = A.n_rows;
+    
+    Z.set_size(A_n_rows, A_n_rows);
+    T = A;
+    
+    char        jobvs = 'V';                // get Schur vectors (Z)
+    char         sort = 'N';                // do not sort eigenvalues/vectors
+    blas_int*  select = 0;                  // pointer to sorting function
+    blas_int        n = blas_int(A_n_rows);
+    blas_int     sdim = 0;                  // output for sorting
+    blas_int lwork    = 3 * ( (std::max)(blas_int(1), 2*n) );
+    blas_int info     = 0;
+    
+    podarray<eT>       work( static_cast<uword>(lwork) );
+    podarray<blas_int> bwork(A_n_rows);
+    
+    podarray<eT>     w(A_n_rows);           // output for eigenvalues
+    podarray<cT> rwork(A_n_rows);
+    
+    lapack::cx_gees(&jobvs, &sort, select, &n, T.memptr(), &n, &sdim, w.memptr(), Z.memptr(), &n, work.memptr(), &lwork, rwork.memptr(), bwork.memptr(), &info);
+    
+    return (info == 0);
+    }
+  #else
+    {
+    arma_ignore(Z);
+    arma_ignore(T);
+    arma_ignore(A);
+    
+    arma_stop("schur_dec(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+
+
+
+//
+// syl (solution of the Sylvester equation AX + XB = C)
+
+template<typename eT>
+inline
+bool
+auxlib::syl(Mat<eT>& X, const Mat<eT>& A, const Mat<eT>& B, const Mat<eT>& C)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (A.is_square() == false) || (B.is_square() == false),
+    "syl(): given matrix is not square"
+    );
+    
+  arma_debug_check
+    (
+    (C.n_rows != A.n_rows) || (C.n_cols != B.n_cols),
+    "syl(): matrices are not conformant"
+    );
+  
+  if(A.is_empty() || B.is_empty() || C.is_empty())
+    {
+    X.reset();
+    return true;
+    }
+  
+  #if defined(ARMA_USE_LAPACK)
+    {
+    Mat<eT> Z1, Z2, T1, T2;
+    
+    const bool status_sd1 = auxlib::schur_dec(Z1, T1, A);
+    const bool status_sd2 = auxlib::schur_dec(Z2, T2, B);
+    
+    if( (status_sd1 == false) || (status_sd2 == false) )
+      {
+      return false;
+      }
+    
+    char     trana = 'N';
+    char     tranb = 'N';
+    blas_int  isgn = +1;
+    blas_int     m = blas_int(T1.n_rows);
+    blas_int     n = blas_int(T2.n_cols);
+    
+    eT       scale = eT(0);
+    blas_int  info = 0;
+    
+    Mat<eT> Y = trans(Z1) * C * Z2;
+    
+    lapack::trsyl<eT>(&trana, &tranb, &isgn, &m, &n, T1.memptr(), &m, T2.memptr(), &n, Y.memptr(), &m, &scale, &info);
+    
+    //Y /= scale;
+    Y /= (-scale);
+    
+    X = Z1 * Y * trans(Z2);
+    
+    return (info >= 0);
+    }
+  #else
+    {
+    arma_stop("syl(): use of LAPACK needs to be enabled");
+    return false;
+    }
+  #endif
+  }
+  
+  
+  
+//
+// lyap (solution of the continuous Lyapunov equation AX + XA^H + Q = 0)
+
+template<typename eT>
+inline
+bool
+auxlib::lyap(Mat<eT>& X, const Mat<eT>& A, const Mat<eT>& Q)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (A.is_square() == false), "lyap(): matrix A is not square");
+  arma_debug_check( (Q.is_square() == false), "lyap(): matrix Q is not square");
+  arma_debug_check( (A.n_rows != Q.n_rows),   "lyap(): matrices A and Q have different dimensions");
+  
+  Mat<eT> htransA;
+  op_htrans::apply_noalias(htransA, A);
+  
+  const Mat<eT> mQ = -Q;
+  
+  return auxlib::syl(X, A, htransA, mQ);
+  }
+
+
+
+//
+// dlyap (solution of the discrete Lyapunov equation AXA^H - X + Q = 0)
+
+template<typename eT>
+inline
+bool
+auxlib::dlyap(Mat<eT>& X, const Mat<eT>& A, const Mat<eT>& Q)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (A.is_square() == false), "dlyap(): matrix A is not square");
+  arma_debug_check( (Q.is_square() == false), "dlyap(): matrix Q is not square");
+  arma_debug_check( (A.n_rows != Q.n_rows),   "dlyap(): matrices A and Q have different dimensions");
+  
+  const Col<eT> vecQ = reshape(Q, Q.n_elem, 1);
+  
+  const Mat<eT> M = eye< Mat<eT> >(Q.n_elem, Q.n_elem) - kron(conj(A), A);
+  
+  Col<eT> vecX;
+  
+  const bool status = solve(vecX, M, vecQ);
+  
+  if(status == true)
+    {
+    X = reshape(vecX, Q.n_rows, Q.n_cols);
+    return true;
+    }
+  else
+    {
+    X.reset();
+    return false;
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/blas_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,70 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+#ifdef ARMA_USE_BLAS
+
+
+#if !defined(ARMA_BLAS_CAPITALS)
+  
+  #define arma_sdot  sdot
+  #define arma_ddot  ddot
+  
+  #define arma_sgemv sgemv
+  #define arma_dgemv dgemv
+  #define arma_cgemv cgemv
+  #define arma_zgemv zgemv
+  
+  #define arma_sgemm sgemm
+  #define arma_dgemm dgemm
+  #define arma_cgemm cgemm
+  #define arma_zgemm zgemm
+  
+#else
+  
+  #define arma_sdot  SDOT
+  #define arma_ddot  DDOT
+  
+  #define arma_sgemv SGEMV
+  #define arma_dgemv DGEMV
+  #define arma_cgemv CGEMV
+  #define arma_zgemv ZGEMV
+  
+  #define arma_sgemm SGEMM
+  #define arma_dgemm DGEMM
+  #define arma_cgemm CGEMM
+  #define arma_zgemm ZGEMM
+  
+#endif
+
+
+
+extern "C"
+  {
+  float  arma_fortran(arma_sdot)(blas_int* n, const float*  x, blas_int* incx, const float*  y, blas_int* incy);
+  double arma_fortran(arma_ddot)(blas_int* n, const double* x, blas_int* incx, const double* y, blas_int* incy);
+  
+  void arma_fortran(arma_sgemv)(const char* transA, const blas_int* m, const blas_int* n, const float*  alpha, const float*  A, const blas_int* ldA, const float*  x, const blas_int* incx, const float*  beta, float*  y, const blas_int* incy);
+  void arma_fortran(arma_dgemv)(const char* transA, const blas_int* m, const blas_int* n, const double* alpha, const double* A, const blas_int* ldA, const double* x, const blas_int* incx, const double* beta, double* y, const blas_int* incy);
+  void arma_fortran(arma_cgemv)(const char* transA, const blas_int* m, const blas_int* n, const void*   alpha, const void*   A, const blas_int* ldA, const void*   x, const blas_int* incx, const void*   beta, void*   y, const blas_int* incy);
+  void arma_fortran(arma_zgemv)(const char* transA, const blas_int* m, const blas_int* n, const void*   alpha, const void*   A, const blas_int* ldA, const void*   x, const blas_int* incx, const void*   beta, void*   y, const blas_int* incy);
+  
+  void arma_fortran(arma_sgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const float*  alpha, const float*  A, const blas_int* ldA, const float*  B, const blas_int* ldB, const float*  beta, float*  C, const blas_int* ldC);
+  void arma_fortran(arma_dgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const double* alpha, const double* A, const blas_int* ldA, const double* B, const blas_int* ldB, const double* beta, double* C, const blas_int* ldC);
+  void arma_fortran(arma_cgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const void*   alpha, const void*   A, const blas_int* ldA, const void*   B, const blas_int* ldB, const void*   beta, void*   C, const blas_int* ldC);
+  void arma_fortran(arma_zgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const void*   alpha, const void*   A, const blas_int* ldA, const void*   B, const blas_int* ldB, const void*   beta, void*   C, const blas_int* ldC);
+  
+  // void   arma_fortran(arma_dswap)(const blas_int* n, double* x, const blas_int* incx, double* y, const blas_int* incy);
+  // void   arma_fortran(arma_dscal)(const blas_int* n, const double* alpha, double* x, const blas_int* incx);
+  // void   arma_fortran(arma_dcopy)(const blas_int* n, const double* x, const blas_int* incx, double* y, const blas_int* incy);
+  // void   arma_fortran(arma_daxpy)(const blas_int* n, const double* alpha, const double* x, const blas_int* incx, double* y, const blas_int* incy);
+  // void   arma_fortran(arma_dger )(const blas_int* m, const blas_int* n, const double* alpha, const double* x, const blas_int* incx, const double* y, const blas_int* incy, double* A, const blas_int* ldA);
+  }
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/blas_wrapper.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,169 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+#ifdef ARMA_USE_BLAS
+
+
+//! \namespace blas namespace for BLAS functions
+namespace blas
+  {
+  
+  
+  template<typename eT>
+  inline
+  void
+  gemv(const char* transA, const blas_int* m, const blas_int* n, const eT* alpha, const eT* A, const blas_int* ldA, const eT* x, const blas_int* incx, const eT* beta, eT* y, const blas_int* incy)
+    {
+    arma_type_check((is_supported_blas_type<eT>::value == false));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_sgemv)(transA, m, n, (const T*)alpha, (const T*)A, ldA, (const T*)x, incx, (const T*)beta, (T*)y, incy);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dgemv)(transA, m, n, (const T*)alpha, (const T*)A, ldA, (const T*)x, incx, (const T*)beta, (T*)y, incy);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_cgemv)(transA, m, n, (const T*)alpha, (const T*)A, ldA, (const T*)x, incx, (const T*)beta, (T*)y, incy);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_zgemv)(transA, m, n, (const T*)alpha, (const T*)A, ldA, (const T*)x, incx, (const T*)beta, (T*)y, incy);
+      }
+    
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  gemm(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const eT* alpha, const eT* A, const blas_int* ldA, const eT* B, const blas_int* ldB, const eT* beta, eT* C, const blas_int* ldC)
+    {
+    arma_type_check((is_supported_blas_type<eT>::value == false));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_sgemm)(transA, transB, m, n, k, (const T*)alpha, (const T*)A, ldA, (const T*)B, ldB, (const T*)beta, (T*)C, ldC);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dgemm)(transA, transB, m, n, k, (const T*)alpha, (const T*)A, ldA, (const T*)B, ldB, (const T*)beta, (T*)C, ldC);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_cgemm)(transA, transB, m, n, k, (const T*)alpha, (const T*)A, ldA, (const T*)B, ldB, (const T*)beta, (T*)C, ldC);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_zgemm)(transA, transB, m, n, k, (const T*)alpha, (const T*)A, ldA, (const T*)B, ldB, (const T*)beta, (T*)C, ldC);
+      }
+    
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  eT
+  dot(const uword n_elem, const eT* x, const eT* y)
+    {
+    arma_type_check((is_supported_blas_type<eT>::value == false));
+    
+    if(is_float<eT>::value == true)
+      {
+      #if defined(ARMA_BLAS_SDOT_BUG)
+        {
+        if(n_elem == 0)  { return eT(0); }
+        
+        const char trans   = 'T';
+        
+        const blas_int m   = blas_int(n_elem);
+        const blas_int n   = 1;
+        //const blas_int lda = (n_elem > 0) ? blas_int(n_elem) : blas_int(1);
+        const blas_int inc = 1;
+        
+        const eT alpha     = eT(1);
+        const eT beta      = eT(0);
+        
+        eT result[2];  // paranoia: using two elements instead of one
+        
+        //blas::gemv(&trans, &m, &n, &alpha, x, &lda, y, &inc, &beta, &result[0], &inc);
+        blas::gemv(&trans, &m, &n, &alpha, x, &m, y, &inc, &beta, &result[0], &inc);
+        
+        return result[0];
+        }
+      #else
+        {
+        blas_int n   = blas_int(n_elem);
+        blas_int inc = 1;
+        
+        typedef float T;
+        return arma_fortran(arma_sdot)(&n, (const T*)x, &inc, (const T*)y, &inc);
+        }
+      #endif
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      blas_int n   = blas_int(n_elem);
+      blas_int inc = 1;
+      
+      typedef double T;
+      return arma_fortran(arma_ddot)(&n, (const T*)x, &inc, (const T*)y, &inc);
+      }
+    else
+    if( (is_supported_complex_float<eT>::value == true) || (is_supported_complex_double<eT>::value == true) )
+      {
+      if(n_elem == 0)  { return eT(0); }
+      
+      // using gemv() workaround due to compatibility issues with cdotu() and zdotu()
+      
+      const char trans   = 'T';
+      
+      const blas_int m   = blas_int(n_elem);
+      const blas_int n   = 1;
+      //const blas_int lda = (n_elem > 0) ? blas_int(n_elem) : blas_int(1);
+      const blas_int inc = 1;
+      
+      const eT alpha     = eT(1);
+      const eT beta      = eT(0);
+      
+      eT result[2];  // paranoia: using two elements instead of one
+      
+      //blas::gemv(&trans, &m, &n, &alpha, x, &lda, y, &inc, &beta, &result[0], &inc);
+      blas::gemv(&trans, &m, &n, &alpha, x, &m, y, &inc, &beta, &result[0], &inc);
+      
+      return result[0];
+      }
+    else
+      {
+      return eT(0);
+      }
+    }
+  }
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/cmath_wrap.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,339 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup cmath_wrap
+//! @{
+
+
+
+//
+// wrappers for isfinite
+//
+
+
+
+template<typename eT>
+arma_inline
+bool
+arma_isfinite(eT val)
+  {
+  arma_ignore(val);
+    
+  return true;
+  }
+
+
+
+template<>
+arma_inline
+bool
+arma_isfinite(float x)
+  {
+  #if defined(ARMA_HAVE_STD_ISFINITE)
+    {
+    return (std::isfinite(x) != 0);
+    }
+  #else
+    {
+    const bool x_is_inf = ( (x == x) && ((x - x) != float(0)) );
+    const bool x_is_nan = (x != x);
+
+    return ( (x_is_inf == false) && (x_is_nan == false) );
+    }
+  #endif
+  }
+
+
+
+template<>
+arma_inline
+bool
+arma_isfinite(double x)
+  {
+  #if defined(ARMA_HAVE_STD_ISFINITE)
+    {
+    return (std::isfinite(x) != 0);
+    }
+  #else
+    {
+    const bool x_is_inf = ( (x == x) && ((x - x) != double(0)) );
+    const bool x_is_nan = (x != x);
+
+    return ( (x_is_inf == false) && (x_is_nan == false) );
+    }
+  #endif
+  }
+
+
+
+template<typename T>
+arma_inline
+bool
+arma_isfinite(const std::complex<T>& x)
+  {
+  if( (arma_isfinite(x.real()) == false) || (arma_isfinite(x.imag()) == false) )
+    {
+    return false;
+    }
+  else
+    {
+    return true;
+    }
+  }
+
+
+
+//
+// wrappers for trigonometric functions
+//
+
+
+
+// Wherever possible, try to use TR1 versions of the functions below,
+// otherwise fall back to Boost Math.
+//
+// complex acos
+// complex asin
+// complex atan
+//
+// real    acosh
+// real    asinh
+// real    atanh
+//
+// complex acosh
+// complex asinh
+// complex atanh
+// 
+// 
+// If TR1 not present and Boost math not present,
+// we have our own rudimentary versions of:
+// 
+// real    acosh
+// real    asinh
+// real    atanh
+
+
+
+#if defined(ARMA_USE_BOOST)
+  #define arma_boost_wrap(trig_fn, val) ( (boost::math::trig_fn)(val) )
+#else
+  #define arma_boost_wrap(trig_fn, val) ( arma_stop( #trig_fn "(): need Boost libraries" ), val )
+#endif
+
+
+template<typename T>
+arma_inline
+std::complex<T>
+arma_acos(const std::complex<T>& x)
+  {
+  #if defined(ARMA_HAVE_STD_TR1)
+    {
+    return std::tr1::acos(x);
+    }
+  #else
+    {
+    return arma_boost_wrap(acos, x);
+    }
+  #endif
+  }
+
+
+
+template<typename T>
+arma_inline
+std::complex<T>
+arma_asin(const std::complex<T>& x)
+  {
+  #if defined(ARMA_HAVE_STD_TR1)
+    {
+    return std::tr1::asin(x);
+    }
+  #else
+    {
+    return arma_boost_wrap(asin, x);
+    }
+  #endif
+  }
+
+
+
+template<typename T>
+arma_inline
+std::complex<T>
+arma_atan(const std::complex<T>& x)
+  {
+  #if defined(ARMA_HAVE_STD_TR1)
+    {
+    return std::tr1::atan(x);
+    }
+  #else
+    {
+    return arma_boost_wrap(atan, x);
+    }
+  #endif
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+arma_acosh(const eT x)
+  {
+  #if defined(ARMA_HAVE_STD_TR1)
+    {
+    return std::tr1::acosh(x);
+    }
+  #elif defined(ARMA_USE_BOOST)
+    {
+    return boost::math::acosh(x);
+    }
+  #else
+    {
+    if(x >= eT(1))
+      {
+      // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/02/
+      return std::log( x + std::sqrt(x*x - eT(1)) );
+      }
+    else
+      {
+      if(std::numeric_limits<eT>::has_quiet_NaN == true)
+        {
+        return -(std::numeric_limits<eT>::quiet_NaN());
+        }
+      else
+        {
+        return eT(0);
+        }
+      }
+    }
+  #endif
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+arma_asinh(const eT x)
+  {
+  #if defined(ARMA_HAVE_STD_TR1)
+    {
+    return std::tr1::asinh(x);
+    }
+  #elif defined(ARMA_USE_BOOST)
+    {
+    return boost::math::asinh(x);
+    }
+  #else
+    {
+    // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/02/
+    return std::log( x + std::sqrt(x*x + eT(1)) );
+    }
+  #endif
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+arma_atanh(const eT x)
+  {
+  #if defined(ARMA_HAVE_STD_TR1)
+    {
+    return std::tr1::atanh(x);
+    }
+  #elif defined(ARMA_USE_BOOST)
+    {
+    return boost::math::atanh(x);
+    }
+  #else
+    {
+    if( (x >= eT(-1)) && (x <= eT(+1)) )
+      {
+      // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/02/
+      return std::log( ( eT(1)+x ) / ( eT(1)-x ) ) / eT(2);
+      }
+    else
+      {
+      if(std::numeric_limits<eT>::has_quiet_NaN == true)
+        {
+        return -(std::numeric_limits<eT>::quiet_NaN());
+        }
+      else
+        {
+        return eT(0);
+        }
+      }
+    }
+  #endif
+  }
+
+
+
+template<typename T>
+arma_inline
+std::complex<T>
+arma_acosh(const std::complex<T>& x)
+  {
+  #if defined(ARMA_HAVE_STD_TR1)
+    {
+    return std::tr1::acosh(x);
+    }
+  #else
+    {
+    return arma_boost_wrap(acosh, x);
+    }
+  #endif
+  }
+
+
+
+template<typename T>
+arma_inline
+std::complex<T>
+arma_asinh(const std::complex<T>& x)
+  {
+  #if defined(ARMA_HAVE_STD_TR1)
+    {
+    return std::tr1::asinh(x);
+    }
+  #else
+    {
+    return arma_boost_wrap(asinh, x);
+    }
+  #endif
+  }
+
+
+
+template<typename T>
+arma_inline
+std::complex<T>
+arma_atanh(const std::complex<T>& x)
+  {
+  #if defined(ARMA_HAVE_STD_TR1)
+    {
+    return std::tr1::atanh(x);
+    }
+  #else
+    {
+    return arma_boost_wrap(atanh, x);
+    }
+  #endif
+  }
+
+
+
+#undef arma_boost_wrap
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/compiler_setup.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,252 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+#define arma_hot
+#define arma_cold
+#define arma_pure
+#define arma_const
+#define arma_aligned
+#define arma_align_mem
+#define arma_warn_unused
+#define arma_deprecated
+#define arma_malloc
+#define arma_inline            inline
+#define arma_noinline
+#define arma_ignore(variable)  ((void)(variable))
+
+
+#if defined(ARMA_BLAS_UNDERSCORE)
+  #define arma_fortran2_noprefix(function) function##_
+  #define arma_fortran2_prefix(function)   wrapper_##function##_
+#else
+  #define arma_fortran2_noprefix(function) function
+  #define arma_fortran2_prefix(function)   wrapper_##function
+#endif
+
+#if defined(ARMA_USE_WRAPPER)
+  #define arma_fortran(function) arma_fortran2_prefix(function)
+  #define arma_atlas(function)   wrapper_##function
+#else
+  #define arma_fortran(function) arma_fortran2_noprefix(function)
+  #define arma_atlas(function)   function
+#endif
+
+#define arma_fortran_prefix(function)   arma_fortran2_prefix(function)
+#define arma_fortran_noprefix(function) arma_fortran2_noprefix(function)
+
+
+#define ARMA_INCFILE_WRAP(x) <x>
+
+
+#if ( ((_POSIX_C_SOURCE >= 200112L) || (_XOPEN_SOURCE >= 600)) && !defined(__MINGW32__) && !defined(__APPLE__) )
+  #define ARMA_HAVE_POSIX_MEMALIGN
+#endif
+
+
+#if (__cplusplus >= 201103L)
+  #if !defined(ARMA_USE_CXX11)
+    #define ARMA_USE_CXX11
+  #endif
+#endif
+
+
+#if defined(ARMA_USE_CXX11)
+  #if !defined(ARMA_USE_U64S64)
+    #define ARMA_USE_U64S64
+  #endif
+#endif
+
+
+#if defined(ARMA_64BIT_WORD)
+  #if !defined(ARMA_USE_U64S64)
+    #define ARMA_USE_U64S64
+  #endif
+#endif
+
+
+#if defined(__INTEL_COMPILER)
+  
+  #if (__INTEL_COMPILER < 1000)
+    #error "*** Need a newer compiler ***"
+  #endif
+  
+  #define ARMA_GOOD_COMPILER
+  #undef  ARMA_HAVE_STD_TR1
+  
+  #if (__INTEL_COMPILER <= 1110)
+    #undef ARMA_HAVE_STD_ISFINITE
+  #endif
+  
+  // #undef  arma_aligned
+  // #define arma_aligned __attribute__((aligned(16)))
+  
+  #if defined(_MSC_VER)
+    #undef  arma_align_mem
+    #define arma_align_mem __declspec(align(16))
+  #else
+    #undef  arma_align_mem
+    #define arma_align_mem __attribute__((aligned(16)))
+  #endif
+  
+  #define ARMA_HAVE_ALIGNED_ATTRIBUTE
+  #define ARMA_HAVE_ICC_ASSUME_ALIGNED
+  
+#elif defined(__GNUG__)
+  
+  #if (__GNUC__ < 4)
+    #error "*** Need a newer compiler ***"
+  #endif
+  
+  #define ARMA_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+  
+  #define ARMA_GOOD_COMPILER
+  #undef  ARMA_HAVE_STD_TR1
+  
+  #undef  arma_pure
+  #undef  arma_const
+  #undef  arma_aligned
+  #undef  arma_align_mem
+  #undef  arma_warn_unused
+  #undef  arma_deprecated
+  #undef  arma_malloc
+  #undef  arma_inline
+  #undef  arma_noinline
+  
+  #define arma_pure               __attribute__((__pure__))
+  #define arma_const              __attribute__((__const__))
+  #define arma_aligned            __attribute__((__aligned__))
+  #define arma_align_mem          __attribute__((__aligned__(16)))
+  #define arma_warn_unused        __attribute__((__warn_unused_result__))
+  #define arma_deprecated         __attribute__((__deprecated__))
+  #define arma_malloc             __attribute__((__malloc__))
+  #define arma_inline      inline __attribute__((__always_inline__))
+  #define arma_noinline           __attribute__((__noinline__))
+  
+  #define ARMA_HAVE_ALIGNED_ATTRIBUTE
+  
+  #if (ARMA_GCC_VERSION >= 40300)
+    #undef  arma_hot
+    #undef  arma_cold
+    
+    #define arma_hot  __attribute__((__hot__))
+    #define arma_cold __attribute__((__cold__))
+  #endif
+  
+  #if (ARMA_GCC_VERSION >= 40200)
+    #if defined(_GLIBCXX_USE_C99_MATH_TR1) && defined(_GLIBCXX_USE_C99_COMPLEX_TR1)
+      #define ARMA_HAVE_STD_TR1
+    #endif
+  #endif
+  
+  #if defined(__GXX_EXPERIMENTAL_CXX0X__)
+    #undef ARMA_HAVE_STD_TR1
+    
+    #if !defined(ARMA_USE_CXX11)
+      #define ARMA_USE_CXX11
+    #endif
+  #endif
+  
+  #if defined(__clang__)
+    #undef ARMA_HAVE_STD_TR1
+    //#undef ARMA_GOOD_COMPILER
+  #endif
+  
+  #if ( (ARMA_GCC_VERSION >= 40700) && (ARMA_GCC_VERSION <= 40701) )
+    #error "gcc versions 4.7.0 and 4.7.1 are unsupported; use 4.7.2 or later"
+    // due to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53549
+  #endif
+  
+  #if (ARMA_GCC_VERSION >= 40700)
+    #define ARMA_HAVE_GCC_ASSUME_ALIGNED
+    // TODO: future versions of clang may also have __builtin_assume_aligned
+  #endif
+  
+  #undef ARMA_GCC_VERSION
+  
+#endif
+
+
+#if defined(__APPLE__)
+  #define ARMA_BLAS_SDOT_BUG
+#endif
+
+
+#if defined(_MSC_VER)
+  
+  #if (_MSC_VER < 1500)
+    #error "*** Need a newer compiler ***"
+  #endif
+  
+  #undef ARMA_GOOD_COMPILER
+  #undef ARMA_HAVE_STD_ISFINITE
+  #undef ARMA_HAVE_STD_SNPRINTF
+  #undef ARMA_HAVE_LOG1P
+  #undef ARMA_HAVE_STD_ISINF
+  #undef ARMA_HAVE_STD_ISNAN
+  #undef ARMA_HAVE_STD_TR1
+  
+  // #undef  arma_inline
+  // #define arma_inline inline __forceinline
+  
+  #pragma warning(push)
+  
+  #pragma warning(disable: 4127)  // conditional expression is constant
+  #pragma warning(disable: 4510)  // default constructor could not be generated
+  #pragma warning(disable: 4511)  // copy constructor can't be generated
+  #pragma warning(disable: 4512)  // assignment operator can't be generated
+  #pragma warning(disable: 4513)  // destructor can't be generated
+  #pragma warning(disable: 4514)  // unreferenced inline function has been removed
+  #pragma warning(disable: 4522)  // multiple assignment operators specified
+  #pragma warning(disable: 4623)  // default constructor can't be generated
+  #pragma warning(disable: 4624)  // destructor can't be generated
+  #pragma warning(disable: 4625)  // copy constructor can't be generated
+  #pragma warning(disable: 4626)  // assignment operator can't be generated
+  #pragma warning(disable: 4710)  // function not inlined
+  #pragma warning(disable: 4711)  // call was inlined
+  #pragma warning(disable: 4714)  // __forceinline can't be inlined
+  
+  #if (_MANAGED == 1) || (_M_CEE == 1)
+    
+    // don't do any alignment when compiling in "managed code" mode 
+    
+  #else
+    // #undef  arma_aligned
+    // #define arma_aligned __declspec(align(16))
+    
+    #undef  arma_align_mem
+    #define arma_align_mem __declspec(align(16))
+    
+    #define ARMA_HAVE_ALIGNED_ATTRIBUTE
+    
+    // disable warnings: "structure was padded due to __declspec(align(16))"
+    #pragma warning(disable: 4324)
+    
+  #endif
+  
+#endif
+
+
+#if defined(__CUDACC__)
+  #undef ARMA_HAVE_STD_ISFINITE
+  #undef ARMA_HAVE_STD_SNPRINTF
+  #undef ARMA_HAVE_LOG1P
+  #undef ARMA_HAVE_STD_ISINF
+  #undef ARMA_HAVE_STD_ISNAN
+  #undef ARMA_HAVE_STD_TR1
+#endif
+
+
+#if defined(__SUNPRO_CC)
+  #undef ARMA_HAVE_STD_ISFINITE
+  #undef ARMA_HAVE_STD_SNPRINTF
+  #undef ARMA_HAVE_LOG1P
+  #undef ARMA_HAVE_STD_ISINF
+  #undef ARMA_HAVE_STD_ISNAN
+  #undef ARMA_HAVE_STD_TR1
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/compiler_setup_post.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,14 @@
+// Copyright (C) 2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+#if defined(_MSC_VER)
+  
+  #pragma warning(pop)
+  
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/cond_rel_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,30 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup cond_rel
+//! @{
+
+
+//
+// for preventing pedantic compiler warnings
+
+template<const bool do_eval>
+class cond_rel
+  {
+  public:
+  
+  template<typename eT> arma_inline static bool lt(const eT A, const eT B);
+  template<typename eT> arma_inline static bool gt(const eT A, const eT B);
+
+  template<typename eT> arma_inline static bool leq(const eT A, const eT B);
+  template<typename eT> arma_inline static bool geq(const eT A, const eT B);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/cond_rel_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,102 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup cond_rel
+//! @{
+
+
+
+template<>
+template<typename eT>
+arma_inline
+bool
+cond_rel<true>::lt(const eT A, const eT B)
+  {
+  return (A < B);
+  }
+  
+
+
+template<>
+template<typename eT>
+arma_inline
+bool
+cond_rel<false>::lt(const eT, const eT)
+  {
+  return false;
+  }
+  
+
+
+template<>
+template<typename eT>
+arma_inline
+bool
+cond_rel<true>::gt(const eT A, const eT B)
+  {
+  return (A > B);
+  }
+  
+
+
+template<>
+template<typename eT>
+arma_inline
+bool
+cond_rel<false>::gt(const eT, const eT)
+  {
+  return false;
+  }
+  
+
+
+template<>
+template<typename eT>
+arma_inline
+bool
+cond_rel<true>::leq(const eT A, const eT B)
+  {
+  return (A <= B);
+  }
+  
+
+
+template<>
+template<typename eT>
+arma_inline
+bool
+cond_rel<false>::leq(const eT, const eT)
+  {
+  return false;
+  }
+  
+
+
+template<>
+template<typename eT>
+arma_inline
+bool
+cond_rel<true>::geq(const eT A, const eT B)
+  {
+  return (A >= B);
+  }
+  
+
+
+template<>
+template<typename eT>
+arma_inline
+bool
+cond_rel<false>::geq(const eT, const eT)
+  {
+  return false;
+  }
+  
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/config.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,165 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+#if !defined(ARMA_USE_LAPACK)
+// #define ARMA_USE_LAPACK
+//// Uncomment the above line if you have LAPACK or a high-speed replacement for LAPACK,
+//// such as Intel MKL, AMD ACML, or the Accelerate framework.
+//// LAPACK is required for matrix decompositions (eg. SVD) and matrix inverse.
+#endif
+
+#if !defined(ARMA_USE_BLAS)
+// #define ARMA_USE_BLAS
+//// Uncomment the above line if you have BLAS or a high-speed replacement for BLAS,
+//// such as OpenBLAS, GotoBLAS, Intel MKL, AMD ACML, or the Accelerate framework.
+//// BLAS is used for matrix multiplication.
+//// Without BLAS, matrix multiplication will still work, but might be slower.
+#endif
+
+// #define ARMA_USE_WRAPPER
+//// Comment out the above line if you're getting linking errors when compiling your programs,
+//// or if you prefer to directly link with LAPACK and/or BLAS.
+//// You will then need to link your programs directly with -llapack -lblas instead of -larmadillo
+
+// #define ARMA_BLAS_CAPITALS
+//// Uncomment the above line if your BLAS and LAPACK libraries have capitalised function names (eg. ACML on 64-bit Windows)
+
+#define ARMA_BLAS_UNDERSCORE
+//// Uncomment the above line if your BLAS and LAPACK libraries have function names with a trailing underscore.
+//// Conversely, comment it out if the function names don't have a trailing underscore.
+
+// #define ARMA_BLAS_LONG
+//// Uncomment the above line if your BLAS and LAPACK libraries use "long" instead of "int"
+
+// #define ARMA_BLAS_LONG_LONG
+//// Uncomment the above line if your BLAS and LAPACK libraries use "long long" instead of "int"
+
+// #define ARMA_USE_TBB_ALLOC
+//// Uncomment the above line if you want to use Intel TBB scalable_malloc() and scalable_free() instead of standard malloc() and free()
+
+// #define ARMA_USE_MKL_ALLOC
+//// Uncomment the above line if you want to use Intel MKL mkl_malloc() and mkl_free() instead of standard malloc() and free()
+
+// #define ARMA_USE_ATLAS
+// #define ARMA_ATLAS_INCLUDE_DIR /usr/include/
+//// If you're using ATLAS and the compiler can't find cblas.h and/or clapack.h
+//// uncomment the above define and specify the appropriate include directory.
+//// Make sure the directory has a trailing /
+
+#if !defined(ARMA_64BIT_WORD)
+// #define ARMA_64BIT_WORD
+//// Uncomment the above line if you require matrices/vectors capable of holding more than 4 billion elements.
+//// Your machine and compiler must have support for 64 bit integers (eg. via "long" or "long long")
+#endif
+
+#if !defined(ARMA_USE_CXX11)
+// #define ARMA_USE_CXX11
+//// Uncomment the above line if you have a C++ compiler that supports the C++11 standard
+//// This will enable additional features, such as use of initialiser lists
+#endif
+
+#if !defined(ARMA_USE_U64S64)
+// #define ARMA_USE_U64S64
+//// Uncomment the above line if you require u64 and s64 integer types.
+//// Your machine and compiler must have support for 64 bit integers (eg. via "long" or "long long").
+//// Note that ARMA_USE_U64S64 is automatically enabled when ARMA_64BIT_WORD or ARMA_USE_CXX11 are enabled
+#endif
+
+#if !defined(ARMA_USE_HDF5)
+// #define ARMA_USE_HDF5
+//// Uncomment the above line if you want the ability to save and load matrices stored in the HDF5 format;
+//// the hdf5.h header file must be available on your system and you will need to link with the hdf5 library (eg. -lhdf5)
+#endif
+
+#if !defined(ARMA_MAT_PREALLOC)
+  #define ARMA_MAT_PREALLOC 16
+#endif
+//// This is the number of preallocated elements used by matrices and vectors;
+//// it must be an integer that is at least 1.
+//// If you mainly use lots of very small vectors (eg. <= 4 elements),
+//// change the number to the size of your vectors.
+
+#if !defined(ARMA_SPMAT_CHUNKSIZE)
+  #define ARMA_SPMAT_CHUNKSIZE 256
+#endif
+//// This is the minimum increase in the amount of memory (in terms of elements) allocated by a sparse matrix;
+//// it must be an integer that is at least 1.
+//// The minimum recommended size is 16.
+
+// #define ARMA_NO_DEBUG
+//// Uncomment the above line if you want to disable all run-time checks.
+//// This will result in faster code, but you first need to make sure that your code runs correctly!
+//// We strongly recommend to have the run-time checks enabled during development,
+//// as this greatly aids in finding mistakes in your code, and hence speeds up development.
+//// We recommend that run-time checks be disabled _only_ for the shipped version of your program.
+
+// #define ARMA_EXTRA_DEBUG
+//// Uncomment the above line if you want to see the function traces of how Armadillo evaluates expressions.
+//// This is mainly useful for debugging of the library.
+
+
+// #define ARMA_USE_BOOST
+// #define ARMA_USE_BOOST_DATE
+
+
+#if !defined(ARMA_DEFAULT_OSTREAM)
+  #define ARMA_DEFAULT_OSTREAM std::cout
+#endif
+
+#define ARMA_PRINT_LOGIC_ERRORS
+#define ARMA_PRINT_RUNTIME_ERRORS
+//#define ARMA_PRINT_HDF5_ERRORS
+
+// #define ARMA_HAVE_STD_ISFINITE
+// #define ARMA_HAVE_STD_ISINF
+// #define ARMA_HAVE_STD_ISNAN
+// #define ARMA_HAVE_STD_SNPRINTF
+
+// #define ARMA_HAVE_LOG1P
+// #define ARMA_HAVE_GETTIMEOFDAY
+
+
+
+#if defined(ARMA_DONT_USE_LAPACK)
+  #undef ARMA_USE_LAPACK
+#endif
+
+#if defined(ARMA_DONT_USE_BLAS)
+  #undef ARMA_USE_BLAS
+#endif
+
+#if defined(ARMA_DONT_USE_WRAPPER)
+  #undef ARMA_USE_WRAPPER
+#endif
+
+#if defined(ARMA_DONT_USE_ATLAS)
+  #undef ARMA_USE_ATLAS
+  #undef ARMA_ATLAS_INCLUDE_DIR
+#endif
+
+#if defined(ARMA_DONT_USE_CXX11)
+  #undef ARMA_USE_CXX11
+#endif
+
+#if defined(ARMA_DONT_USE_HDF5)
+  #undef ARMA_USE_HDF5
+#endif
+
+#if defined(ARMA_DONT_USE_BOOST)
+  #undef ARMA_USE_BOOST
+  #undef ARMA_USE_BOOST_DATE
+#endif
+
+#if defined(ARMA_DONT_PRINT_LOGIC_ERRORS)
+  #undef ARMA_PRINT_LOGIC_ERRORS
+#endif
+
+#if defined(ARMA_DONT_PRINT_RUNTIME_ERRORS)
+  #undef ARMA_PRINT_RUNTIME_ERRORS
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/config.hpp.cmake	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,165 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+#if !defined(ARMA_USE_LAPACK)
+#cmakedefine ARMA_USE_LAPACK
+//// Uncomment the above line if you have LAPACK or a high-speed replacement for LAPACK,
+//// such as Intel MKL, AMD ACML, or the Accelerate framework.
+//// LAPACK is required for matrix decompositions (eg. SVD) and matrix inverse.
+#endif
+
+#if !defined(ARMA_USE_BLAS)
+#cmakedefine ARMA_USE_BLAS
+//// Uncomment the above line if you have BLAS or a high-speed replacement for BLAS,
+//// such as OpenBLAS, GotoBLAS, Intel MKL, AMD ACML, or the Accelerate framework.
+//// BLAS is used for matrix multiplication.
+//// Without BLAS, matrix multiplication will still work, but might be slower.
+#endif
+
+#cmakedefine ARMA_USE_WRAPPER
+//// Comment out the above line if you're getting linking errors when compiling your programs,
+//// or if you prefer to directly link with LAPACK and/or BLAS.
+//// You will then need to link your programs directly with -llapack -lblas instead of -larmadillo
+
+// #define ARMA_BLAS_CAPITALS
+//// Uncomment the above line if your BLAS and LAPACK libraries have capitalised function names (eg. ACML on 64-bit Windows)
+
+#define ARMA_BLAS_UNDERSCORE
+//// Uncomment the above line if your BLAS and LAPACK libraries have function names with a trailing underscore.
+//// Conversely, comment it out if the function names don't have a trailing underscore.
+
+// #define ARMA_BLAS_LONG
+//// Uncomment the above line if your BLAS and LAPACK libraries use "long" instead of "int"
+
+// #define ARMA_BLAS_LONG_LONG
+//// Uncomment the above line if your BLAS and LAPACK libraries use "long long" instead of "int"
+
+// #define ARMA_USE_TBB_ALLOC
+//// Uncomment the above line if you want to use Intel TBB scalable_malloc() and scalable_free() instead of standard malloc() and free()
+
+// #define ARMA_USE_MKL_ALLOC
+//// Uncomment the above line if you want to use Intel MKL mkl_malloc() and mkl_free() instead of standard malloc() and free()
+
+#cmakedefine ARMA_USE_ATLAS
+#define ARMA_ATLAS_INCLUDE_DIR ${ARMA_ATLAS_INCLUDE_DIR}/
+//// If you're using ATLAS and the compiler can't find cblas.h and/or clapack.h
+//// uncomment the above define and specify the appropriate include directory.
+//// Make sure the directory has a trailing /
+
+#if !defined(ARMA_64BIT_WORD)
+// #define ARMA_64BIT_WORD
+//// Uncomment the above line if you require matrices/vectors capable of holding more than 4 billion elements.
+//// Your machine and compiler must have support for 64 bit integers (eg. via "long" or "long long")
+#endif
+
+#if !defined(ARMA_USE_CXX11)
+// #define ARMA_USE_CXX11
+//// Uncomment the above line if you have a C++ compiler that supports the C++11 standard
+//// This will enable additional features, such as use of initialiser lists
+#endif
+
+#if !defined(ARMA_USE_U64S64)
+// #define ARMA_USE_U64S64
+//// Uncomment the above line if you require u64 and s64 integer types.
+//// Your machine and compiler must have support for 64 bit integers (eg. via "long" or "long long").
+//// Note that ARMA_USE_U64S64 is automatically enabled when ARMA_64BIT_WORD or ARMA_USE_CXX11 are enabled
+#endif
+
+#if !defined(ARMA_USE_HDF5)
+#cmakedefine ARMA_USE_HDF5
+//// Uncomment the above line if you want the ability to save and load matrices stored in the HDF5 format;
+//// the hdf5.h header file must be available on your system and you will need to link with the hdf5 library (eg. -lhdf5)
+#endif
+
+#if !defined(ARMA_MAT_PREALLOC)
+  #define ARMA_MAT_PREALLOC 16
+#endif
+//// This is the number of preallocated elements used by matrices and vectors;
+//// it must be an integer that is at least 1.
+//// If you mainly use lots of very small vectors (eg. <= 4 elements),
+//// change the number to the size of your vectors.
+
+#if !defined(ARMA_SPMAT_CHUNKSIZE)
+  #define ARMA_SPMAT_CHUNKSIZE 256
+#endif
+//// This is the minimum increase in the amount of memory (in terms of elements) allocated by a sparse matrix;
+//// it must be an integer that is at least 1.
+//// The minimum recommended size is 16.
+
+// #define ARMA_NO_DEBUG
+//// Uncomment the above line if you want to disable all run-time checks.
+//// This will result in faster code, but you first need to make sure that your code runs correctly!
+//// We strongly recommend to have the run-time checks enabled during development,
+//// as this greatly aids in finding mistakes in your code, and hence speeds up development.
+//// We recommend that run-time checks be disabled _only_ for the shipped version of your program.
+
+// #define ARMA_EXTRA_DEBUG
+//// Uncomment the above line if you want to see the function traces of how Armadillo evaluates expressions.
+//// This is mainly useful for debugging of the library.
+
+
+// #define ARMA_USE_BOOST
+// #define ARMA_USE_BOOST_DATE
+
+
+#if !defined(ARMA_DEFAULT_OSTREAM)
+  #define ARMA_DEFAULT_OSTREAM std::cout
+#endif
+
+#define ARMA_PRINT_LOGIC_ERRORS
+#define ARMA_PRINT_RUNTIME_ERRORS
+//#define ARMA_PRINT_HDF5_ERRORS
+
+#cmakedefine ARMA_HAVE_STD_ISFINITE
+#cmakedefine ARMA_HAVE_STD_ISINF
+#cmakedefine ARMA_HAVE_STD_ISNAN
+#cmakedefine ARMA_HAVE_STD_SNPRINTF
+
+#cmakedefine ARMA_HAVE_LOG1P
+#cmakedefine ARMA_HAVE_GETTIMEOFDAY
+
+
+
+#if defined(ARMA_DONT_USE_LAPACK)
+  #undef ARMA_USE_LAPACK
+#endif
+
+#if defined(ARMA_DONT_USE_BLAS)
+  #undef ARMA_USE_BLAS
+#endif
+
+#if defined(ARMA_DONT_USE_WRAPPER)
+  #undef ARMA_USE_WRAPPER
+#endif
+
+#if defined(ARMA_DONT_USE_ATLAS)
+  #undef ARMA_USE_ATLAS
+  #undef ARMA_ATLAS_INCLUDE_DIR
+#endif
+
+#if defined(ARMA_DONT_USE_CXX11)
+  #undef ARMA_USE_CXX11
+#endif
+
+#if defined(ARMA_DONT_USE_HDF5)
+  #undef ARMA_USE_HDF5
+#endif
+
+#if defined(ARMA_DONT_USE_BOOST)
+  #undef ARMA_USE_BOOST
+  #undef ARMA_USE_BOOST_DATE
+#endif
+
+#if defined(ARMA_DONT_PRINT_LOGIC_ERRORS)
+  #undef ARMA_PRINT_LOGIC_ERRORS
+#endif
+
+#if defined(ARMA_DONT_PRINT_RUNTIME_ERRORS)
+  #undef ARMA_PRINT_RUNTIME_ERRORS
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/constants.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,288 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup constants
+//! @{
+
+
+namespace priv
+  {
+  class Datum_helper
+    {
+    public:
+    
+    template<typename eT>
+    static
+    typename arma_real_only<eT>::result
+    nan(typename arma_real_only<eT>::result* junk = 0)
+      {
+      arma_ignore(junk);
+      
+      if(std::numeric_limits<eT>::has_quiet_NaN == true)
+        {
+        return std::numeric_limits<eT>::quiet_NaN();
+        }
+      else
+        {
+        return eT(0);
+        }
+      }
+    
+    
+    template<typename eT>
+    static
+    typename arma_cx_only<eT>::result
+    nan(typename arma_cx_only<eT>::result* junk = 0)
+      {
+      arma_ignore(junk);
+      
+      typedef typename get_pod_type<eT>::result T;
+      
+      return eT( Datum_helper::nan<T>(), Datum_helper::nan<T>() );
+      }
+    
+    
+    template<typename eT>
+    static
+    typename arma_integral_only<eT>::result
+    nan(typename arma_integral_only<eT>::result* junk = 0)
+      {
+      arma_ignore(junk);
+      
+      return eT(0);
+      }
+    
+    
+    template<typename eT>
+    static
+    typename arma_real_only<eT>::result
+    inf(typename arma_real_only<eT>::result* junk = 0)
+      {
+      arma_ignore(junk);
+      
+      if(std::numeric_limits<eT>::has_infinity == true)
+        {
+        return std::numeric_limits<eT>::infinity();
+        }
+      else
+        {
+        return std::numeric_limits<eT>::max();
+        }
+      }
+    
+    
+    template<typename eT>
+    static
+    typename arma_cx_only<eT>::result
+    inf(typename arma_cx_only<eT>::result* junk = 0)
+      {
+      arma_ignore(junk);
+      
+      typedef typename get_pod_type<eT>::result T;
+      
+      return eT( Datum_helper::inf<T>(), Datum_helper::inf<T>() );
+      }
+    
+
+    template<typename eT>
+    static
+    typename arma_integral_only<eT>::result
+    inf(typename arma_integral_only<eT>::result* junk = 0)
+      {
+      arma_ignore(junk);
+      
+      return std::numeric_limits<eT>::max();
+      }
+    
+    };
+  }
+
+
+
+//! various constants.
+//! Physical constants taken from NIST and WolframAlpha on 2009-06-23
+//! http://physics.nist.gov/cuu/Constants
+//! http://www.wolframalpha.com
+//! See also http://en.wikipedia.org/wiki/Physical_constant
+
+
+template<typename eT>
+class Datum
+  {
+  public:
+  
+  static const eT pi;       //!< ratio of any circle's circumference to its diameter
+  static const eT e;        //!< base of the natural logarithm
+  static const eT euler;    //!< Euler's constant, aka Euler-Mascheroni constant
+  static const eT gratio;   //!< golden ratio
+  static const eT sqrt2;    //!< square root of 2
+  static const eT eps;      //!< the difference between 1 and the least value greater than 1 that is representable
+  static const eT log_min;  //!< log of the minimum representable value
+  static const eT log_max;  //!< log of the maximum representable value
+  static const eT nan;      //!< "not a number"
+  static const eT inf;      //!< infinity 
+
+  // 
+  
+  static const eT m_u;       //!< atomic mass constant (in kg)
+  static const eT N_A;       //!< Avogadro constant
+  static const eT k;         //!< Boltzmann constant (in joules per kelvin)
+  static const eT k_evk;     //!< Boltzmann constant (in eV/K)
+  static const eT a_0;       //!< Bohr radius (in meters)
+  static const eT mu_B;      //!< Bohr magneton
+  static const eT Z_0;       //!< characteristic impedance of vacuum (in ohms)
+  static const eT G_0;       //!< conductance quantum (in siemens)
+  static const eT k_e;       //!< Coulomb's constant (in meters per farad)
+  static const eT eps_0;     //!< electric constant (in farads per meter)
+  static const eT m_e;       //!< electron mass (in kg)
+  static const eT eV;        //!< electron volt (in joules)
+  static const eT ec;        //!< elementary charge (in coulombs)
+  static const eT F;         //!< Faraday constant (in coulombs)
+  static const eT alpha;     //!< fine-structure constant
+  static const eT alpha_inv; //!< inverse fine-structure constant
+  static const eT K_J;       //!< Josephson constant
+  static const eT mu_0;      //!< magnetic constant (in henries per meter)
+  static const eT phi_0;     //!< magnetic flux quantum (in webers)
+  static const eT R;         //!< molar gas constant (in joules per mole kelvin)
+  static const eT G;         //!< Newtonian constant of gravitation (in newton square meters per kilogram squared)
+  static const eT h;         //!< Planck constant (in joule seconds)
+  static const eT h_bar;     //!< Planck constant over 2 pi, aka reduced Planck constant (in joule seconds)
+  static const eT m_p;       //!< proton mass (in kg)
+  static const eT R_inf;     //!< Rydberg constant (in reciprocal meters)
+  static const eT c_0;       //!< speed of light in vacuum (in meters per second)
+  static const eT sigma;     //!< Stefan-Boltzmann constant
+  static const eT R_k;       //!< von Klitzing constant (in ohms)
+  static const eT b;         //!< Wien wavelength displacement law constant
+  };
+
+
+// the long lengths of the constants are for future support of "long double"
+// and any smart compiler that does high-precision computation at compile-time
+  
+template<typename eT> const eT Datum<eT>::pi        = eT(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679);
+template<typename eT> const eT Datum<eT>::e         = eT(2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274);
+template<typename eT> const eT Datum<eT>::euler     = eT(0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495);
+template<typename eT> const eT Datum<eT>::gratio    = eT(1.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374);
+template<typename eT> const eT Datum<eT>::sqrt2     = eT(1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727);
+template<typename eT> const eT Datum<eT>::eps       = std::numeric_limits<eT>::epsilon();
+template<typename eT> const eT Datum<eT>::log_min   = std::log(std::numeric_limits<eT>::min());
+template<typename eT> const eT Datum<eT>::log_max   = std::log(std::numeric_limits<eT>::max());
+template<typename eT> const eT Datum<eT>::nan       = priv::Datum_helper::nan<eT>();
+template<typename eT> const eT Datum<eT>::inf       = priv::Datum_helper::inf<eT>();
+
+template<typename eT> const eT Datum<eT>::m_u       = eT(1.660538782e-27);
+template<typename eT> const eT Datum<eT>::N_A       = eT(6.02214179e23);
+template<typename eT> const eT Datum<eT>::k         = eT(1.3806504e-23);
+template<typename eT> const eT Datum<eT>::k_evk     = eT(8.617343e-5);
+template<typename eT> const eT Datum<eT>::a_0       = eT(0.52917720859e-10);
+template<typename eT> const eT Datum<eT>::mu_B      = eT(927.400915e-26);
+template<typename eT> const eT Datum<eT>::Z_0       = eT(3.76730313461771e-2);
+template<typename eT> const eT Datum<eT>::G_0       = eT(7.7480917004e-5);
+template<typename eT> const eT Datum<eT>::k_e       = eT(8.9875517873681764e9);
+template<typename eT> const eT Datum<eT>::eps_0     = eT(8.85418781762039e-12);
+template<typename eT> const eT Datum<eT>::m_e       = eT(9.10938215e-31);
+template<typename eT> const eT Datum<eT>::eV        = eT(1.602176487e-19);
+template<typename eT> const eT Datum<eT>::ec        = eT(1.602176487e-19);
+template<typename eT> const eT Datum<eT>::F         = eT(96485.3399);
+template<typename eT> const eT Datum<eT>::alpha     = eT(7.2973525376e-3);
+template<typename eT> const eT Datum<eT>::alpha_inv = eT(137.035999679);
+template<typename eT> const eT Datum<eT>::K_J       = eT(483597.891e9);
+template<typename eT> const eT Datum<eT>::mu_0      = eT(1.25663706143592e-06);
+template<typename eT> const eT Datum<eT>::phi_0     = eT(2.067833667e-15);
+template<typename eT> const eT Datum<eT>::R         = eT(8.314472);
+template<typename eT> const eT Datum<eT>::G         = eT(6.67428e-11);
+template<typename eT> const eT Datum<eT>::h         = eT(6.62606896e-34);
+template<typename eT> const eT Datum<eT>::h_bar     = eT(1.054571628e-34);
+template<typename eT> const eT Datum<eT>::m_p       = eT(1.672621637e-27);
+template<typename eT> const eT Datum<eT>::R_inf     = eT(10973731.568527);
+template<typename eT> const eT Datum<eT>::c_0       = eT(299792458.0);
+template<typename eT> const eT Datum<eT>::sigma     = eT(5.670400e-8);
+template<typename eT> const eT Datum<eT>::R_k       = eT(25812.807557);
+template<typename eT> const eT Datum<eT>::b         = eT(2.8977685e-3);
+
+
+
+typedef Datum<float>  fdatum;
+typedef Datum<double> datum;
+
+
+
+
+namespace priv
+  {
+  
+  template<typename eT>
+  static
+  arma_inline
+  arma_hot
+  typename arma_real_only<eT>::result
+  most_neg(typename arma_real_only<eT>::result* junk = 0)
+    {
+    arma_ignore(junk);
+    
+    if(std::numeric_limits<eT>::has_infinity == true)
+      {
+      return -(std::numeric_limits<eT>::infinity());
+      }
+    else
+      {
+      return -(std::numeric_limits<eT>::max());
+      }
+    }
+  
+  
+  template<typename eT>
+  static
+  arma_inline
+  arma_hot
+  typename arma_integral_only<eT>::result
+  most_neg(typename arma_integral_only<eT>::result* junk = 0)
+    {
+    arma_ignore(junk);
+    
+    return std::numeric_limits<eT>::min();
+    }
+  
+  
+  template<typename eT>
+  static
+  arma_inline
+  arma_hot
+  typename arma_real_only<eT>::result
+  most_pos(typename arma_real_only<eT>::result* junk = 0)
+    {
+    arma_ignore(junk);
+    
+    if(std::numeric_limits<eT>::has_infinity == true)
+      {
+      return std::numeric_limits<eT>::infinity();
+      }
+    else
+      {
+      return std::numeric_limits<eT>::max();
+      }
+    }
+  
+  
+  template<typename eT>
+  static
+  arma_inline
+  arma_hot
+  typename arma_integral_only<eT>::result
+  most_pos(typename arma_integral_only<eT>::result* junk = 0)
+    {
+    arma_ignore(junk);
+    
+    return std::numeric_limits<eT>::max();
+    }
+
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/constants_compat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,166 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup constants_compat
+//! @{
+
+
+// the Math and Phy classes are kept for compatibility with old code;
+// for new code, use the Datum class instead
+// eg. instead of math::pi(), use datum::pi
+
+
+template<typename eT>
+class Math
+  {
+  public:
+  
+  // the long lengths of the constants are for future support of "long double"
+  // and any smart compiler that does high-precision computation at compile-time
+  
+  //! ratio of any circle's circumference to its diameter
+  static eT pi()        { return eT(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679); }
+  
+  //! base of the natural logarithm
+  static eT e()         { return eT(2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274); }
+  
+  //! Euler's constant, aka Euler-Mascheroni constant
+  static eT euler()     { return eT(0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495); }
+  
+  //! golden ratio
+  static eT gratio()    { return eT(1.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374); }
+  
+  //! square root of 2
+  static eT sqrt2()     { return eT(1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727); }
+  
+  //! the difference between 1 and the least value greater than 1 that is representable
+  static eT eps()       { return std::numeric_limits<eT>::epsilon(); }
+  
+  //! log of the minimum representable value
+  static eT log_min()   { static const eT out = std::log(std::numeric_limits<eT>::min()); return out; }
+    
+  //! log of the maximum representable value
+  static eT log_max()   { static const eT out = std::log(std::numeric_limits<eT>::max()); return out; }
+  
+  //! "not a number"
+  static eT nan()       { return priv::Datum_helper::nan<eT>(); }
+  
+  //! infinity 
+  static eT inf()       { return priv::Datum_helper::inf<eT>(); }
+  };
+
+
+
+//! Physical constants taken from NIST and WolframAlpha on 2009-06-23
+//! http://physics.nist.gov/cuu/Constants
+//! http://www.wolframalpha.com
+//! See also http://en.wikipedia.org/wiki/Physical_constant
+template<typename eT>
+class Phy
+  {
+  public:
+  
+  //! atomic mass constant (in kg)
+  static eT m_u()       {  return eT(1.660538782e-27); }
+  
+  //! Avogadro constant
+  static eT N_A()       {  return eT(6.02214179e23); }
+  
+  //! Boltzmann constant (in joules per kelvin)
+  static eT k()         {  return eT(1.3806504e-23); }
+  
+  //! Boltzmann constant (in eV/K)
+  static eT k_evk()     {  return eT(8.617343e-5); }
+  
+  //! Bohr radius (in meters)
+  static eT a_0()       { return eT(0.52917720859e-10); }
+  
+  //! Bohr magneton
+  static eT mu_B()      { return eT(927.400915e-26); }
+  
+  //! characteristic impedance of vacuum (in ohms)
+  static eT Z_0()       { return eT(3.76730313461771e-2); }
+  
+  //! conductance quantum (in siemens)
+  static eT G_0()       { return eT(7.7480917004e-5); }
+  
+  //! Coulomb's constant (in meters per farad)
+  static eT k_e()       { return eT(8.9875517873681764e9); }
+  
+  //! electric constant (in farads per meter)
+  static eT eps_0()     { return eT(8.85418781762039e-12); }
+  
+  //! electron mass (in kg)
+  static eT m_e()       { return eT(9.10938215e-31); }
+  
+  //! electron volt (in joules)
+  static eT eV()        { return eT(1.602176487e-19); }
+  
+  //! elementary charge (in coulombs)
+  static eT e()         { return eT(1.602176487e-19); }
+  
+  //! Faraday constant (in coulombs)
+  static eT F()         { return eT(96485.3399); }
+  
+  //! fine-structure constant
+  static eT alpha()     { return eT(7.2973525376e-3); }
+  
+  //! inverse fine-structure constant
+  static eT alpha_inv() { return eT(137.035999679); }
+  
+  //! Josephson constant
+  static eT K_J()       { return eT(483597.891e9); }
+  
+  //! magnetic constant (in henries per meter)
+  static eT mu_0()      { return eT(1.25663706143592e-06); }
+  
+  //! magnetic flux quantum (in webers)
+  static eT phi_0()     { return eT(2.067833667e-15); }
+  
+  //! molar gas constant (in joules per mole kelvin)
+  static eT R()         { return eT(8.314472); }
+  
+  //! Newtonian constant of gravitation (in newton square meters per kilogram squared)
+  static eT G()         { return eT(6.67428e-11); }
+  
+  //! Planck constant (in joule seconds)
+  static eT h()         { return eT(6.62606896e-34); }
+  
+  //! Planck constant over 2 pi, aka reduced Planck constant (in joule seconds)
+  static eT h_bar()     { return eT(1.054571628e-34); }
+  
+  //! proton mass (in kg)
+  static eT m_p()       { return eT(1.672621637e-27); }
+  
+  //! Rydberg constant (in reciprocal meters)
+  static eT R_inf()     { return eT(10973731.568527); }
+  
+  //! speed of light in vacuum (in meters per second)
+  static eT c_0()       { return eT(299792458.0); }
+  
+  //! Stefan-Boltzmann constant
+  static eT sigma()     { return eT(5.670400e-8); }
+  
+  //! von Klitzing constant (in ohms)
+  static eT R_k()       { return eT(25812.807557); }
+  
+  //! Wien wavelength displacement law constant
+  static eT b()         { return eT(2.8977685e-3); }
+  };
+
+
+
+typedef Math<float>  fmath;
+typedef Math<double> math;
+
+typedef Phy<float>   fphy;
+typedef Phy<double>  phy;
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/debug.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,1213 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// Copyright (C) 2011 Stanislav Funiak
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup debug
+//! @{
+
+
+
+template<typename T>
+inline
+std::ostream&
+arma_stream_err1(std::ostream* user_stream)
+  {
+  static std::ostream* stream_err1 = &(ARMA_DEFAULT_OSTREAM);
+  
+  if(user_stream != NULL)
+    {
+    stream_err1 = user_stream;
+    }
+  
+  return *stream_err1;
+  }
+
+
+
+template<typename T>
+inline
+std::ostream&
+arma_stream_err2(std::ostream* user_stream)
+  {
+  static std::ostream* stream_err2 = &(ARMA_DEFAULT_OSTREAM);
+  
+  if(user_stream != NULL)
+    {
+    stream_err2 = user_stream;
+    }
+  
+  return *stream_err2;
+  }
+
+
+
+inline
+void
+set_stream_err1(std::ostream& user_stream)
+  {
+  arma_stream_err1<char>(&user_stream);
+  }
+
+
+
+inline
+void
+set_stream_err2(std::ostream& user_stream)
+  {
+  arma_stream_err2<char>(&user_stream);
+  }
+
+
+
+inline
+std::ostream&
+get_stream_err1()
+  {
+  return arma_stream_err1<char>(NULL);
+  }
+
+
+
+inline
+std::ostream&
+get_stream_err2()
+  {
+  return arma_stream_err2<char>(NULL);
+  }
+
+
+
+//
+// arma_stop
+
+//! print a message to get_stream_err1() and/or throw a logic_error exception
+template<typename T1>
+arma_cold
+arma_noinline
+static
+void
+arma_stop(const T1& x)
+  {
+  #if defined(ARMA_PRINT_LOGIC_ERRORS)
+    {
+    std::ostream& out = get_stream_err1();
+    
+    out.flush();
+    
+    out << '\n';
+    out << "error: " << x << '\n';
+    out << '\n';
+    out.flush();
+    }
+  #else
+    {
+    arma_ignore(x);
+    }
+  #endif
+  
+  throw std::logic_error("");
+  }
+
+
+
+template<typename T1>
+arma_cold
+arma_noinline
+static
+void
+arma_stop_bad_alloc(const T1& x)
+  {
+  std::ostream& out = get_stream_err1();
+  
+  out.flush();
+  
+  out << '\n';
+  out << "error: " << x << '\n';
+  out << '\n';
+  out.flush();
+  
+  throw std::bad_alloc();
+  }
+
+
+
+//
+// arma_bad
+
+//! print a message to get_stream_err2() and/or throw a run-time error exception
+template<typename T1>
+arma_cold
+arma_noinline
+static
+void
+arma_bad(const T1& x, const bool hurl = true)
+  {
+  #if defined(ARMA_PRINT_RUNTIME_ERRORS)
+    {
+    std::ostream& out = get_stream_err2();
+    
+    out.flush();
+    
+    out << '\n';
+    out << "error: " << x << '\n';
+    out << '\n';
+    out.flush();
+    }
+  #else
+    {
+    arma_ignore(x);
+    }
+  #endif
+  
+  if(hurl == true)
+    {
+    throw std::runtime_error("");
+    }
+  }
+
+
+
+//
+// arma_print
+
+
+arma_cold
+inline
+void
+arma_print()
+  {
+  get_stream_err1() << std::endl;
+  }
+
+
+template<typename T1>
+arma_cold
+arma_noinline
+static
+void
+arma_print(const T1& x)
+  {
+  get_stream_err1() << x << std::endl;
+  }
+
+
+
+template<typename T1, typename T2>
+arma_cold
+arma_noinline
+static
+void
+arma_print(const T1& x, const T2& y)
+  {
+  get_stream_err1() << x << y << std::endl;
+  }
+
+
+
+template<typename T1, typename T2, typename T3>
+arma_cold
+arma_noinline
+static
+void
+arma_print(const T1& x, const T2& y, const T3& z)
+  {
+  get_stream_err1() << x << y << z << std::endl;
+  }
+
+
+
+
+
+
+//
+// arma_sigprint
+
+//! print a message the the log stream with a preceding @ character.
+//! by default the log stream is cout.
+//! used for printing the signature of a function
+//! (see the arma_extra_debug_sigprint macro) 
+inline
+void
+arma_sigprint(const char* x)
+  {
+  get_stream_err1() << "@ " << x;
+  }
+
+
+
+//
+// arma_bktprint
+
+
+inline
+void
+arma_bktprint()
+  {
+  get_stream_err1() << std::endl;
+  }
+
+
+template<typename T1>
+inline
+void
+arma_bktprint(const T1& x)
+  {
+  get_stream_err1() << " [" << x << ']' << std::endl;
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+arma_bktprint(const T1& x, const T2& y)
+  {
+  get_stream_err1() << " [" << x << y << ']' << std::endl;
+  }
+
+
+
+
+
+
+//
+// arma_thisprint
+
+inline
+void
+arma_thisprint(const void* this_ptr)
+  {
+  get_stream_err1() << " [this = " << this_ptr << ']' << std::endl;
+  }
+
+
+
+//
+// arma_warn
+
+
+//! print a message to the warn stream
+template<typename T1>
+arma_cold
+arma_noinline
+static
+void
+arma_warn(const bool state, const T1& x)
+  {
+  if(state==true)
+    {
+    get_stream_err2() << x << std::endl;
+    }
+  }
+
+
+template<typename T1, typename T2>
+arma_cold
+arma_noinline
+static
+void
+arma_warn(const bool state, const T1& x, const T2& y)
+  {
+  if(state==true)
+    {
+    get_stream_err2() << x << y << std::endl;
+    }
+  }
+
+
+template<typename T1, typename T2, typename T3>
+arma_cold
+arma_noinline
+static
+void
+arma_warn(const bool state, const T1& x, const T2& y, const T3& z)
+  {
+  if(state==true)
+    {
+    get_stream_err2() << x << y << z << std::endl;
+    }
+  }
+
+
+
+//
+// arma_check
+
+//! if state is true, abort program
+template<typename T1>
+arma_hot
+inline
+void
+arma_check(const bool state, const T1& x)
+  {
+  if(state==true)
+    {
+    arma_stop(arma_boost::str_wrapper(x));
+    }
+  }
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+arma_check(const bool state, const T1& x, const T2& y)
+  {
+  if(state==true)
+    {
+    arma_stop( std::string(x) + std::string(y) );
+    }
+  }
+
+
+template<typename T1>
+arma_hot
+inline
+void
+arma_check_bad_alloc(const bool state, const T1& x)
+  {
+  if(state==true)
+    {
+    arma_stop_bad_alloc(x);
+    }
+  }
+
+
+
+//
+// arma_set_error
+
+
+arma_hot
+arma_inline
+void
+arma_set_error(bool& err_state, char*& err_msg, const bool expression, const char* message)
+  {
+  if(expression == true)
+    {
+    err_state = true;
+    err_msg   = const_cast<char*>(message);
+    }
+  }
+
+
+
+
+//
+// functions for generating strings indicating size errors
+
+arma_cold
+arma_noinline
+static
+std::string
+arma_incompat_size_string(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x)
+  {
+  std::stringstream tmp;
+  
+  tmp << x << ": incompatible matrix dimensions: " << A_n_rows << 'x' << A_n_cols << " and " << B_n_rows << 'x' << B_n_cols;
+  
+  return tmp.str();
+  }
+
+
+
+arma_cold
+arma_noinline
+static
+std::string
+arma_incompat_size_string(const uword A_n_rows, const uword A_n_cols, const uword A_n_slices, const uword B_n_rows, const uword B_n_cols, const uword B_n_slices, const char* x)
+  {
+  std::stringstream tmp;
+  
+  tmp << x << ": incompatible cube dimensions: " << A_n_rows << 'x' << A_n_cols << 'x' << A_n_slices << " and " << B_n_rows << 'x' << B_n_cols << 'x' << B_n_slices;
+  
+  return tmp.str();
+  }
+
+
+
+template<typename eT>
+arma_cold
+arma_noinline
+static
+std::string
+arma_incompat_size_string(const subview_cube<eT>& Q, const Mat<eT>& A, const char* x)
+  {
+  std::stringstream tmp;
+  
+  tmp << x
+      << ": interpreting matrix as cube with dimenensions: "
+      << A.n_rows << 'x' << A.n_cols << 'x' << 1
+      << " or "
+      << A.n_rows << 'x' << 1        << 'x' << A.n_cols
+      << " or "
+      << 1        << 'x' << A.n_rows << 'x' << A.n_cols
+      << " is incompatible with cube dimensions: "
+      << Q.n_rows << 'x' << Q.n_cols << 'x' << Q.n_slices;
+      
+  return tmp.str();
+  }
+
+
+
+//
+// functions for checking whether two matrices have the same dimensions
+
+
+
+arma_inline
+arma_hot
+void
+arma_assert_same_size(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x)
+  {
+  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
+    {
+    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
+    }
+  }
+
+
+
+//! stop if given matrices have different sizes
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const Mat<eT1>& A, const Mat<eT2>& B, const char* x)
+  {
+  const uword A_n_rows = A.n_rows;
+  const uword A_n_cols = A.n_cols;
+  
+  const uword B_n_rows = B.n_rows;
+  const uword B_n_cols = B.n_cols;
+  
+  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
+    {
+    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
+    }
+  }
+
+
+
+//! stop if given proxies have different sizes
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const Proxy<eT1>& A, const Proxy<eT2>& B, const char* x)
+  {
+  const uword A_n_rows = A.get_n_rows();
+  const uword A_n_cols = A.get_n_cols();
+  
+  const uword B_n_rows = B.get_n_rows();
+  const uword B_n_cols = B.get_n_cols();
+  
+  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
+    {
+    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const subview<eT1>& A, const subview<eT2>& B, const char* x)
+  {
+  const uword A_n_rows = A.n_rows;
+  const uword A_n_cols = A.n_cols;
+  
+  const uword B_n_rows = B.n_rows;
+  const uword B_n_cols = B.n_cols;
+  
+  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
+    {
+    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const Mat<eT1>& A, const subview<eT2>& B, const char* x)
+  {
+  const uword A_n_rows = A.n_rows;
+  const uword A_n_cols = A.n_cols;
+  
+  const uword B_n_rows = B.n_rows;
+  const uword B_n_cols = B.n_cols;
+  
+  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
+    {
+    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const subview<eT1>& A, const Mat<eT2>& B, const char* x)
+  {
+  const uword A_n_rows = A.n_rows;
+  const uword A_n_cols = A.n_cols;
+  
+  const uword B_n_rows = B.n_rows;
+  const uword B_n_cols = B.n_cols;
+  
+  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
+    {
+    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const Mat<eT1>& A, const Proxy<eT2>& B, const char* x)
+  {
+  const uword A_n_rows = A.n_rows;
+  const uword A_n_cols = A.n_cols;
+  
+  const uword B_n_rows = B.get_n_rows();
+  const uword B_n_cols = B.get_n_cols();
+  
+  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
+    {
+    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const Proxy<eT1>& A, const Mat<eT2>& B, const char* x)
+  {
+  const uword A_n_rows = A.get_n_rows();
+  const uword A_n_cols = A.get_n_cols();
+  
+  const uword B_n_rows = B.n_rows;
+  const uword B_n_cols = B.n_cols;
+  
+  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
+    {
+    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const Proxy<eT1>& A, const subview<eT2>& B, const char* x)
+  {
+  const uword A_n_rows = A.get_n_rows();
+  const uword A_n_cols = A.get_n_cols();
+  
+  const uword B_n_rows = B.n_rows;
+  const uword B_n_cols = B.n_cols;
+  
+  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
+    {
+    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const subview<eT1>& A, const Proxy<eT2>& B, const char* x)
+  {
+  const uword A_n_rows = A.n_rows;
+  const uword A_n_cols = A.n_cols;
+  
+  const uword B_n_rows = B.get_n_rows();
+  const uword B_n_cols = B.get_n_cols();
+  
+  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
+    {
+    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
+    }
+  }
+
+
+
+//
+// functions for checking whether two cubes have the same dimensions
+
+
+
+arma_hot
+inline
+void
+arma_assert_same_size(const uword A_n_rows, const uword A_n_cols, const uword A_n_slices, const uword B_n_rows, const uword B_n_cols, const uword B_n_slices, const char* x)
+  {
+  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) || (A_n_slices != B_n_slices) )
+    {
+    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, A_n_slices, B_n_rows, B_n_cols, B_n_slices, x) );
+    }
+  }
+
+
+
+//! stop if given cubes have different sizes
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const Cube<eT1>& A, const Cube<eT2>& B, const char* x)
+  {
+  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
+    {
+    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const Cube<eT1>& A, const subview_cube<eT2>& B, const char* x)
+  {
+  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
+    {
+    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const subview_cube<eT1>& A, const Cube<eT2>& B, const char* x)
+  {
+  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
+    {
+    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const subview_cube<eT1>& A, const subview_cube<eT2>& B, const char* x)
+  {
+  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices))
+    {
+    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
+    }
+  }
+
+
+
+//! stop if given cube proxies have different sizes
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const ProxyCube<eT1>& A, const ProxyCube<eT2>& B, const char* x)
+  {
+  const uword A_n_rows   = A.get_n_rows();
+  const uword A_n_cols   = A.get_n_cols();
+  const uword A_n_slices = A.get_n_slices();
+  
+  const uword B_n_rows   = B.get_n_rows();
+  const uword B_n_cols   = B.get_n_cols();
+  const uword B_n_slices = B.get_n_slices();
+  
+  if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) || (A_n_slices != B_n_slices))
+    {
+    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, A_n_slices, B_n_rows, B_n_cols, B_n_slices, x) );
+    }
+  }
+
+
+
+//
+// functions for checking whether a cube or subcube can be interpreted as a matrix (i.e. single slice)
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const Cube<eT1>& A, const Mat<eT2>& B, const char* x)
+  {
+  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != 1) )
+    {
+    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, 1, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const Mat<eT1>& A, const Cube<eT2>& B, const char* x)
+  {
+  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (1 != B.n_slices) )
+    {
+    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, 1, B.n_rows, B.n_cols, B.n_slices, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const subview_cube<eT1>& A, const Mat<eT2>& B, const char* x)
+  {
+  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != 1) )
+    {
+    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, 1, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_same_size(const Mat<eT1>& A, const subview_cube<eT2>& B, const char* x)
+  {
+  if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (1 != B.n_slices) )
+    {
+    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, 1, B.n_rows, B.n_cols, B.n_slices, x) );
+    }
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+arma_assert_cube_as_mat(const Mat<eT>& M, const T1& Q, const char* x, const bool check_compat_size)
+  {
+  const uword Q_n_rows   = Q.n_rows;
+  const uword Q_n_cols   = Q.n_cols;
+  const uword Q_n_slices = Q.n_slices;
+  
+  const uword M_vec_state = M.vec_state;
+  
+  if(M_vec_state == 0)
+    {
+    if( ( (Q_n_rows == 1) || (Q_n_cols == 1) || (Q_n_slices == 1) ) == false )
+      {
+      std::stringstream tmp;
+        
+      tmp << x
+          << ": can't interpret cube with dimensions "
+          << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices 
+          << " as a matrix; one of the dimensions must be 1";
+      
+      arma_stop( tmp.str() );
+      }
+    }
+  else
+    {
+    if(Q_n_slices == 1)
+      {
+      if( (M_vec_state == 1) && (Q_n_cols != 1) )
+        {
+        std::stringstream tmp;
+        
+        tmp << x
+            << ": can't interpret cube with dimensions "
+            << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
+            << " as a column vector";
+        
+        arma_stop( tmp.str() );
+        }
+      
+      if( (M_vec_state == 2) && (Q_n_rows != 1) )
+        {
+        std::stringstream tmp;
+        
+        tmp << x
+            << ": can't interpret cube with dimensions "
+            << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
+            << " as a row vector";
+        
+        arma_stop( tmp.str() );
+        }
+      }
+    else
+      {
+      if( (Q_n_cols != 1) && (Q_n_rows != 1) )
+        {
+        std::stringstream tmp;
+        
+        tmp << x
+            << ": can't interpret cube with dimensions "
+            << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
+            << " as a vector";
+        
+        arma_stop( tmp.str() );
+        }
+      }
+    }
+  
+  
+  if(check_compat_size == true)
+    {
+    const uword M_n_rows = M.n_rows;
+    const uword M_n_cols = M.n_cols;
+    
+    if(M_vec_state == 0)
+      {
+      if(
+          (
+          ( (Q_n_rows == M_n_rows) && (Q_n_cols   == M_n_cols) )
+          ||
+          ( (Q_n_rows == M_n_rows) && (Q_n_slices == M_n_cols) )
+          ||
+          ( (Q_n_cols == M_n_rows) && (Q_n_slices == M_n_cols) )
+          )
+          == false
+        )
+        {
+        std::stringstream tmp;
+        
+        tmp << x
+            << ": can't interpret cube with dimenensions "
+            << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
+            << " as a matrix with dimensions "
+            << M_n_rows << 'x' << M_n_cols;
+        
+        arma_stop( tmp.str() );
+        }
+      }
+    else
+      {
+      if(Q_n_slices == 1)
+        {
+        if( (M_vec_state == 1) && (Q_n_rows != M_n_rows) )
+          {
+          std::stringstream tmp;
+          
+          tmp << x
+              << ": can't interpret cube with dimensions "
+              << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
+              << " as a column vector with dimensions "
+              << M_n_rows << 'x' << M_n_cols;
+          
+          arma_stop( tmp.str() );
+          }
+        
+        if( (M_vec_state == 2) && (Q_n_cols != M_n_cols) )
+          {
+          std::stringstream tmp;
+          
+          tmp << x
+              << ": can't interpret cube with dimensions "
+              << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
+              << " as a row vector with dimensions "
+              << M_n_rows << 'x' << M_n_cols;
+          
+          arma_stop( tmp.str() );
+          }
+        }
+      else
+        {
+        if( ( (M_n_cols == Q_n_slices) || (M_n_rows == Q_n_slices) ) == false )
+          {
+          std::stringstream tmp;
+          
+          tmp << x
+              << ": can't interpret cube with dimensions "
+              << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
+              << " as a vector with dimensions "
+              << M_n_rows << 'x' << M_n_cols;
+          
+          arma_stop( tmp.str() );
+          }
+        }
+      }
+    }
+  }
+
+
+
+//
+// functions for checking whether two matrices have dimensions that are compatible with the matrix multiply operation
+
+
+
+arma_hot
+inline
+void
+arma_assert_mul_size(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x)
+  {
+  if(A_n_cols != B_n_rows)
+    {
+    arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
+    }
+  }
+
+
+
+//! stop if given matrices are incompatible for multiplication
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_mul_size(const Mat<eT1>& A, const Mat<eT2>& B, const char* x)
+  {
+  const uword A_n_cols = A.n_cols;
+  const uword B_n_rows = B.n_rows;
+  
+  if(A_n_cols != B_n_rows)
+    {
+    arma_stop( arma_incompat_size_string(A.n_rows, A_n_cols, B_n_rows, B.n_cols, x) );
+    }
+  }
+
+
+
+//! stop if given matrices are incompatible for multiplication
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_mul_size(const Mat<eT1>& A, const Mat<eT2>& B, const bool do_trans_A, const bool do_trans_B, const char* x)
+  {
+  const uword final_A_n_cols = (do_trans_A == false) ? A.n_cols : A.n_rows;
+  const uword final_B_n_rows = (do_trans_B == false) ? B.n_rows : B.n_cols;
+    
+  if(final_A_n_cols != final_B_n_rows)
+    {
+    const uword final_A_n_rows = (do_trans_A == false) ? A.n_rows : A.n_cols;
+    const uword final_B_n_cols = (do_trans_B == false) ? B.n_cols : B.n_rows;
+    
+    arma_stop( arma_incompat_size_string(final_A_n_rows, final_A_n_cols, final_B_n_rows, final_B_n_cols, x) );
+    }
+  }
+
+
+
+template<const bool do_trans_A, const bool do_trans_B>
+arma_hot
+inline
+void
+arma_assert_trans_mul_size(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x)
+  {
+  const uword final_A_n_cols = (do_trans_A == false) ? A_n_cols : A_n_rows;
+  const uword final_B_n_rows = (do_trans_B == false) ? B_n_rows : B_n_cols;
+    
+  if(final_A_n_cols != final_B_n_rows)
+    {
+    const uword final_A_n_rows = (do_trans_A == false) ? A_n_rows : A_n_cols;
+    const uword final_B_n_cols = (do_trans_B == false) ? B_n_cols : B_n_rows;
+    
+    arma_stop( arma_incompat_size_string(final_A_n_rows, final_A_n_cols, final_B_n_rows, final_B_n_cols, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_mul_size(const Mat<eT1>& A, const subview<eT2>& B, const char* x)
+  {
+  if(A.n_cols != B.n_rows)
+    {
+    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_mul_size(const subview<eT1>& A, const Mat<eT2>& B, const char* x)
+  {
+  if(A.n_cols != B.n_rows)
+    {
+    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
+    }
+  }
+
+
+
+template<typename eT1, typename eT2>
+arma_hot
+inline
+void
+arma_assert_mul_size(const subview<eT1>& A, const subview<eT2>& B, const char* x)
+  {
+  if(A.n_cols != B.n_rows)
+    {
+    arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
+    }
+  }
+
+
+
+//
+// macros
+
+
+#define ARMA_STRING1(x) #x
+#define ARMA_STRING2(x) ARMA_STRING1(x)
+#define ARMA_FILELINE  __FILE__ ": " ARMA_STRING2(__LINE__)
+
+
+#if defined (__GNUG__)
+  #define ARMA_FNSIG  __PRETTY_FUNCTION__
+#elif defined (_MSC_VER)
+  #define ARMA_FNSIG  __FUNCSIG__ 
+#elif defined (ARMA_USE_BOOST)
+  #define ARMA_FNSIG  BOOST_CURRENT_FUNCTION  
+#elif defined (ARMA_USE_CXX11)
+  #define ARMA_FNSIG  __func__
+#else 
+  #define ARMA_FNSIG  "(unknown)"
+#endif
+
+
+
+#if !defined(ARMA_NO_DEBUG) && !defined(NDEBUG)
+  
+  #define arma_debug_print                 arma_print
+  #define arma_debug_warn                  arma_warn
+  #define arma_debug_check                 arma_check
+  #define arma_debug_set_error             arma_set_error
+  #define arma_debug_assert_same_size      arma_assert_same_size
+  #define arma_debug_assert_mul_size       arma_assert_mul_size
+  #define arma_debug_assert_trans_mul_size arma_assert_trans_mul_size
+  #define arma_debug_assert_cube_as_mat    arma_assert_cube_as_mat
+  
+#else
+  
+  #undef ARMA_EXTRA_DEBUG
+  
+  #define arma_debug_print                 true ? (void)0 : arma_print
+  #define arma_debug_warn                  true ? (void)0 : arma_warn
+  #define arma_debug_check                 true ? (void)0 : arma_check
+  #define arma_debug_set_error             true ? (void)0 : arma_set_error
+  #define arma_debug_assert_same_size      true ? (void)0 : arma_assert_same_size
+  #define arma_debug_assert_mul_size       true ? (void)0 : arma_assert_mul_size
+  #define arma_debug_assert_trans_mul_size true ? (void)0 : arma_assert_trans_mul_size
+  #define arma_debug_assert_cube_as_mat    true ? (void)0 : arma_assert_cube_as_mat
+
+#endif
+
+
+
+#if defined(ARMA_EXTRA_DEBUG)
+  
+  #define arma_extra_debug_sigprint       arma_sigprint(ARMA_FNSIG); arma_bktprint
+  #define arma_extra_debug_sigprint_this  arma_sigprint(ARMA_FNSIG); arma_thisprint
+  #define arma_extra_debug_print          arma_print
+  #define arma_extra_debug_warn           arma_warn
+  #define arma_extra_debug_check          arma_check
+
+#else
+  
+  #define arma_extra_debug_sigprint        true ? (void)0 : arma_bktprint
+  #define arma_extra_debug_sigprint_this   true ? (void)0 : arma_thisprint
+  #define arma_extra_debug_print           true ? (void)0 : arma_print
+  #define arma_extra_debug_warn            true ? (void)0 : arma_warn
+  #define arma_extra_debug_check           true ? (void)0 : arma_check
+ 
+#endif
+
+
+
+
+#if defined(ARMA_EXTRA_DEBUG)
+
+  namespace junk
+    {
+    class arma_first_extra_debug_message
+      {
+      public:
+      
+      inline
+      arma_first_extra_debug_message()
+        {
+        union
+          {
+          unsigned short a;
+          unsigned char  b[sizeof(unsigned short)];
+          } endian_test;
+          
+        endian_test.a = 1;
+        
+        const bool  little_endian = (endian_test.b[0] == 1);
+        const char* nickname      = ARMA_VERSION_NAME;
+        
+        std::ostream& out = get_stream_err1();
+        
+        out << "@ ---" << '\n';
+        out << "@ Armadillo "
+            << arma_version::major << '.' << arma_version::minor << '.' << arma_version::patch
+            << " (" << nickname << ")\n";
+        
+        out << "@ arma_config::mat_prealloc   = " << arma_config::mat_prealloc   << " element(s)\n";
+        out << "@ arma_config::atlas          = " << arma_config::atlas          << '\n';
+        out << "@ arma_config::lapack         = " << arma_config::lapack         << '\n';
+        out << "@ arma_config::blas           = " << arma_config::blas           << '\n';
+        out << "@ arma_config::boost          = " << arma_config::boost          << '\n';
+        out << "@ arma_config::boost_date     = " << arma_config::boost_date     << '\n';
+        out << "@ arma_config::good_comp      = " << arma_config::good_comp      << '\n';
+        out << "@ arma_config::extra_code     = " << arma_config::extra_code     << '\n';
+        out << "@ sizeof(void*)    = " << sizeof(void*)    << '\n';
+        out << "@ sizeof(uword)    = " << sizeof(uword)    << '\n';
+        out << "@ sizeof(int)      = " << sizeof(int)      << '\n';
+        out << "@ sizeof(long)     = " << sizeof(long)     << '\n';
+        out << "@ sizeof(blas_int) = " << sizeof(blas_int) << '\n';
+        out << "@ little_endian    = " << little_endian    << '\n';
+        out << "@ ---" << std::endl;
+        }
+      
+      };
+    
+    static arma_first_extra_debug_message arma_first_extra_debug_message_run;
+    }
+
+#endif
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/diagmat_proxy.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,578 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup diagmat_proxy
+//! @{
+
+
+
+template<typename T1>
+class diagmat_proxy_default
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  inline
+  diagmat_proxy_default(const T1& X)
+    : P       ( X )
+    , P_is_vec( (resolves_to_vector<T1>::value) || (P.get_n_rows() == 1) || (P.get_n_cols() == 1) )
+    , P_is_col( T1::is_col || (P.get_n_cols() == 1) )
+    , n_elem  ( P_is_vec ? P.get_n_elem() : (std::min)(P.get_n_elem(), P.get_n_rows()) )
+    {
+    arma_extra_debug_sigprint();
+    
+    arma_debug_check
+      (
+      (P_is_vec == false) && (P.get_n_rows() != P.get_n_cols()),
+      "diagmat(): only vectors and square matrices are accepted"
+      );
+    }
+  
+  
+  arma_inline
+  elem_type
+  operator[](const uword i) const
+    {
+    if(Proxy<T1>::prefer_at_accessor == false)
+      {
+      return P_is_vec ? P[i] : P.at(i,i);
+      }
+    else
+      {
+      if(P_is_vec)
+        {
+        return (P_is_col) ? P.at(i,0) : P.at(0,i);
+        }
+      else
+        {
+        return P.at(i,i);
+        }
+      }
+    }
+  
+  
+  arma_inline
+  elem_type
+  at(const uword row, const uword col) const
+    {
+    if(row == col)
+      {
+      if(Proxy<T1>::prefer_at_accessor == false)
+        {
+        return (P_is_vec) ? P[row] : P.at(row,row);
+        }
+      else
+        {
+        if(P_is_vec)
+          {
+          return (P_is_col) ? P.at(row,0) : P.at(0,row);
+          }
+        else
+          {
+          return P.at(row,row);
+          }
+        }
+      }
+    else
+      {
+      return elem_type(0);
+      }
+    }
+  
+  
+  const Proxy<T1> P;
+  const bool      P_is_vec;
+  const bool      P_is_col;
+  const uword     n_elem;
+  };
+
+
+
+template<typename T1>
+class diagmat_proxy_fixed
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  inline
+  diagmat_proxy_fixed(const T1& X)
+    : P(X)
+    {
+    arma_extra_debug_sigprint();
+    
+    arma_debug_check
+      (
+      (P_is_vec == false) && (T1::n_rows != T1::n_cols),
+      "diagmat(): only vectors and square matrices are accepted"
+      );
+    }
+  
+  
+  arma_inline
+  elem_type
+  operator[](const uword i) const
+    {
+    return (P_is_vec) ? P[i] : P.at(i,i);
+    }
+  
+  
+  arma_inline
+  elem_type
+  at(const uword row, const uword col) const
+    {
+    if(row == col)
+      {
+      return (P_is_vec) ? P[row] : P.at(row,row);
+      }
+    else
+      {
+      return elem_type(0);
+      }
+    }
+  
+  const T1& P;
+  
+  static const bool  P_is_vec = (T1::n_rows == 1) || (T1::n_cols == 1);
+  static const uword n_elem   = P_is_vec ? T1::n_elem : ( (T1::n_elem < T1::n_rows) ? T1::n_elem : T1::n_rows );
+  };
+
+
+
+template<typename T1, bool condition>
+struct diagmat_proxy_redirect {};
+
+template<typename T1>
+struct diagmat_proxy_redirect<T1, false> { typedef diagmat_proxy_default<T1> result; };
+
+template<typename T1>
+struct diagmat_proxy_redirect<T1, true>  { typedef diagmat_proxy_fixed<T1>   result; };
+
+
+template<typename T1>
+class diagmat_proxy : public diagmat_proxy_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  public:
+  inline diagmat_proxy(const T1& X)
+    : diagmat_proxy_redirect< T1, is_Mat_fixed<T1>::value >::result(X)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+class diagmat_proxy< Mat<eT> >
+  {
+  public:
+  
+  typedef          eT                              elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  inline
+  diagmat_proxy(const Mat<eT>& X)
+    : P       ( X )
+    , P_is_vec( (X.n_rows == 1) || (X.n_cols == 1) )
+    , n_elem  ( P_is_vec ? X.n_elem : (std::min)(X.n_elem, X.n_rows) )
+    {
+    arma_extra_debug_sigprint();
+    
+    arma_debug_check
+      (
+      (P_is_vec == false) && (P.n_rows != P.n_cols),
+      "diagmat(): only vectors and square matrices are accepted"
+      );
+    }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return P_is_vec ? P[i] : P.at(i,i);                                         }
+  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? ( P_is_vec ? P[row] : P.at(row,row) ) : elem_type(0); }
+  
+  const Mat<eT>& P;
+  const bool     P_is_vec;
+  const uword    n_elem;
+  };
+
+
+
+template<typename eT>
+class diagmat_proxy< Row<eT> >
+  {
+  public:
+  
+  typedef          eT                              elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  
+  inline
+  diagmat_proxy(const Row<eT>& X)
+    : P(X)
+    , n_elem(X.n_elem)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return P[i];                                                                }
+  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); }
+  
+  static const bool P_is_vec = true;
+  
+  const Row<eT>& P;
+  const uword    n_elem;
+  };
+
+
+
+template<typename eT>
+class diagmat_proxy< Col<eT> >
+  {
+  public:
+  
+  typedef          eT                              elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  
+  inline
+  diagmat_proxy(const Col<eT>& X)
+    : P(X)
+    , n_elem(X.n_elem)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return P[i];                                 }
+  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); }
+  
+  static const bool P_is_vec = true;
+  
+  const Col<eT>& P;
+  const uword    n_elem;
+  };
+
+
+
+template<typename eT>
+class diagmat_proxy< subview_row<eT> >
+  {
+  public:
+  
+  typedef          eT                              elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  
+  inline
+  diagmat_proxy(const subview_row<eT>& X)
+    : P(X)
+    , n_elem(X.n_elem)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return P[i];                                 }
+  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); }
+  
+  static const bool P_is_vec = true;
+  
+  const subview_row<eT>& P;
+  const uword            n_elem;
+  };
+
+
+
+template<typename eT>
+class diagmat_proxy< subview_col<eT> >
+  {
+  public:
+  
+  typedef          eT                              elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  
+  inline
+  diagmat_proxy(const subview_col<eT>& X)
+    : P(X)
+    , n_elem(X.n_elem)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return P[i];                                 }
+  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); }
+  
+  static const bool P_is_vec = true;
+  
+  const subview_col<eT>& P;
+  const uword            n_elem;
+  };
+
+
+
+//
+//
+//
+
+
+
+template<typename T1>
+class diagmat_proxy_check_default
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  inline
+  diagmat_proxy_check_default(const T1& X, const Mat<typename T1::elem_type>&)
+    : P(X)
+    , P_is_vec( (resolves_to_vector<T1>::value) || (P.n_rows == 1) || (P.n_cols == 1) )
+    , n_elem( P_is_vec ? P.n_elem : (std::min)(P.n_elem, P.n_rows) )
+    {
+    arma_extra_debug_sigprint();
+    
+    arma_debug_check
+      (
+      (P_is_vec == false) && (P.n_rows != P.n_cols),
+      "diagmat(): only vectors and square matrices are accepted"
+      );
+    }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return P_is_vec ? P[i] : P.at(i,i);                                         }
+  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? ( P_is_vec ? P[row] : P.at(row,row) ) : elem_type(0); }
+  
+  const Mat<elem_type> P;
+  const bool           P_is_vec;
+  const uword          n_elem;
+  };
+
+
+
+template<typename T1>
+class diagmat_proxy_check_fixed
+  {
+  public:
+  
+  typedef typename T1::elem_type                   eT;
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  inline
+  diagmat_proxy_check_fixed(const T1& X, const Mat<eT>& out)
+    : P( const_cast<eT*>(X.memptr()), T1::n_rows, T1::n_cols, (&X == &out), false )
+    {
+    arma_extra_debug_sigprint();
+    
+    arma_debug_check
+      (
+      (P_is_vec == false) && (T1::n_rows != T1::n_cols),
+      "diagmat(): only vectors and square matrices are accepted"
+      );
+    }
+  
+  
+  arma_inline eT operator[] (const uword i)                    const { return P_is_vec ? P[i] : P.at(i,i);                                         }
+  arma_inline eT at         (const uword row, const uword col) const { return (row == col) ? ( P_is_vec ? P[row] : P.at(row,row) ) : elem_type(0); }
+  
+  const Mat<eT> P;  // TODO: why not just store X directly as T1& ?  test with fixed size vectors and matrices
+  
+  static const bool  P_is_vec = (T1::n_rows == 1) || (T1::n_cols == 1);
+  static const uword n_elem   = P_is_vec ? T1::n_elem : ( (T1::n_elem < T1::n_rows) ? T1::n_elem : T1::n_rows );
+  };
+
+
+
+template<typename T1, bool condition>
+struct diagmat_proxy_check_redirect {};
+
+template<typename T1>
+struct diagmat_proxy_check_redirect<T1, false> { typedef diagmat_proxy_check_default<T1> result; };
+
+template<typename T1>
+struct diagmat_proxy_check_redirect<T1, true>  { typedef diagmat_proxy_check_fixed<T1>   result; };
+
+
+template<typename T1>
+class diagmat_proxy_check : public diagmat_proxy_check_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  public:
+  inline diagmat_proxy_check(const T1& X, const Mat<typename T1::elem_type>& out)
+    : diagmat_proxy_check_redirect< T1, is_Mat_fixed<T1>::value >::result(X, out)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+class diagmat_proxy_check< Mat<eT> >
+  {
+  public:
+  
+  typedef          eT                              elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  
+  inline
+  diagmat_proxy_check(const Mat<eT>& X, const Mat<eT>& out)
+    : P_local ( (&X == &out) ? new Mat<eT>(X) : 0  )
+    , P       ( (&X == &out) ? (*P_local)     : X  )
+    , P_is_vec( (P.n_rows == 1) || (P.n_cols == 1) )
+    , n_elem  ( P_is_vec ? P.n_elem : (std::min)(P.n_elem, P.n_rows) )
+    {
+    arma_extra_debug_sigprint();
+    
+    arma_debug_check
+      (
+      (P_is_vec == false) && (P.n_rows != P.n_cols),
+      "diagmat(): only vectors and square matrices are accepted"
+      );
+    }
+  
+  inline ~diagmat_proxy_check()
+    {
+    if(P_local) { delete P_local; }
+    }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return P_is_vec ? P[i] : P.at(i,i);                                         }
+  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? ( P_is_vec ? P[row] : P.at(row,row) ) : elem_type(0); }
+  
+  const Mat<eT>* P_local;
+  const Mat<eT>& P;
+  const bool     P_is_vec;
+  const uword    n_elem;
+  };
+
+
+
+template<typename eT>
+class diagmat_proxy_check< Row<eT> >
+  {
+  public:
+  
+  typedef          eT                              elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  inline
+  diagmat_proxy_check(const Row<eT>& X, const Mat<eT>& out)
+    : P_local ( (&X == reinterpret_cast<const Row<eT>*>(&out)) ? new Row<eT>(X) : 0 )
+    , P       ( (&X == reinterpret_cast<const Row<eT>*>(&out)) ? (*P_local)     : X )
+    , n_elem  (X.n_elem)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline ~diagmat_proxy_check()
+    {
+    if(P_local) { delete P_local; }
+    }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return P[i];                                 }
+  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); }
+  
+  static const bool P_is_vec = true;
+  
+  const Row<eT>* P_local;
+  const Row<eT>& P;
+  const uword    n_elem;
+  };
+
+
+
+template<typename eT>
+class diagmat_proxy_check< Col<eT> >
+  {
+  public:
+  
+  typedef          eT                              elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  inline
+  diagmat_proxy_check(const Col<eT>& X, const Mat<eT>& out)
+    : P_local ( (&X == reinterpret_cast<const Col<eT>*>(&out)) ? new Col<eT>(X) : 0 )
+    , P       ( (&X == reinterpret_cast<const Col<eT>*>(&out)) ? (*P_local)     : X )
+    , n_elem  (X.n_elem)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline ~diagmat_proxy_check()
+    {
+    if(P_local) { delete P_local; }
+    }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return P[i];                                 }
+  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); }
+  
+  static const bool P_is_vec = true;
+  
+  const Col<eT>* P_local;
+  const Col<eT>& P;
+  const uword    n_elem;
+  };
+
+
+
+template<typename eT>
+class diagmat_proxy_check< subview_row<eT> >
+  {
+  public:
+  
+  typedef          eT                              elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  inline
+  diagmat_proxy_check(const subview_row<eT>& X, const Mat<eT>&)
+    : P       ( X )
+    , n_elem  ( X.n_elem )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return P[i];                                 }
+  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); }
+  
+  static const bool P_is_vec = true;
+  
+  const Row<eT> P;
+  const uword   n_elem;
+  };
+
+
+
+template<typename eT>
+class diagmat_proxy_check< subview_col<eT> >
+  {
+  public:
+  
+  typedef          eT                              elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  inline
+  diagmat_proxy_check(const subview_col<eT>& X, const Mat<eT>& out)
+    : P     ( const_cast<eT*>(X.colptr(0)), X.n_rows, (&(X.m) == &out), false )
+    , n_elem( X.n_elem )
+    //, X_ref ( X )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline elem_type operator[] (const uword i)                    const { return P[i];                                 }
+  arma_inline elem_type at         (const uword row, const uword col) const { return (row == col) ? P[row] : elem_type(0); }
+  
+  static const bool P_is_vec = true;
+  
+  const Col<eT> P;
+  const uword   n_elem;
+  
+  //const subview_col<eT>& X_ref;   // prevents the compiler from potentially deleting X before we're done with it
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/diagview_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,103 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup diagview
+//! @{
+
+
+//! Class for storing data required to extract and set the diagonals of a matrix
+template<typename eT>
+class diagview : public Base<eT, diagview<eT> >
+  {
+  public:
+  
+  typedef eT                                elem_type;
+  typedef typename get_pod_type<eT>::result pod_type;
+  
+  arma_aligned const Mat<eT>& m;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  const uword row_offset;
+  const uword col_offset;
+  
+  const uword n_rows;     // equal to n_elem
+  const uword n_elem;
+  
+  static const uword n_cols = 1;
+  
+  
+  protected:
+  
+  arma_inline diagview(const Mat<eT>& in_m, const uword in_row_offset, const uword in_col_offset, const uword len);
+  
+  
+  public:
+  
+  inline ~diagview();
+  
+  inline void operator=(const diagview& x);
+  
+  inline void operator+=(const eT val);
+  inline void operator-=(const eT val);
+  inline void operator*=(const eT val);
+  inline void operator/=(const eT val);
+  
+  template<typename T1> inline void operator= (const Base<eT,T1>& x);
+  template<typename T1> inline void operator+=(const Base<eT,T1>& x);
+  template<typename T1> inline void operator-=(const Base<eT,T1>& x);
+  template<typename T1> inline void operator%=(const Base<eT,T1>& x);
+  template<typename T1> inline void operator/=(const Base<eT,T1>& x);
+  
+  
+  arma_inline eT  at_alt    (const uword ii) const;
+  
+  arma_inline eT& operator[](const uword ii);
+  arma_inline eT  operator[](const uword ii) const;
+  
+  arma_inline eT&         at(const uword ii);
+  arma_inline eT          at(const uword ii) const;
+  
+  arma_inline eT& operator()(const uword ii);
+  arma_inline eT  operator()(const uword ii) const;
+  
+  arma_inline eT&         at(const uword in_n_row, const uword);
+  arma_inline eT          at(const uword in_n_row, const uword) const;
+   
+  arma_inline eT& operator()(const uword in_n_row, const uword in_n_col);
+  arma_inline eT  operator()(const uword in_n_row, const uword in_n_col) const;
+  
+  
+  arma_inline const Op<diagview<eT>,op_htrans>  t() const;
+  arma_inline const Op<diagview<eT>,op_htrans> ht() const;
+  arma_inline const Op<diagview<eT>,op_strans> st() const;
+  
+  inline void fill(const eT val);
+  inline void zeros();
+  inline void ones();
+  
+  inline static void extract(Mat<eT>& out, const diagview& in);
+  
+  inline static void  plus_inplace(Mat<eT>& out, const diagview& in);
+  inline static void minus_inplace(Mat<eT>& out, const diagview& in);
+  inline static void schur_inplace(Mat<eT>& out, const diagview& in);
+  inline static void   div_inplace(Mat<eT>& out, const diagview& in);
+  
+  
+  private:
+  
+  friend class Mat<eT>;
+  friend class subview<eT>;
+  
+  diagview();
+  //diagview(const diagview&);  // making this private causes an error under gcc 4.1/4.2, but not 4.3
+  };
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/diagview_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,904 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup diagview
+//! @{
+
+
+template<typename eT>
+inline
+diagview<eT>::~diagview()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+template<typename eT>
+arma_inline
+diagview<eT>::diagview(const Mat<eT>& in_m, const uword in_row_offset, const uword in_col_offset, const uword in_len)
+  : m(in_m)
+  , row_offset(in_row_offset)
+  , col_offset(in_col_offset)
+  , n_rows(in_len)
+  , n_elem(in_len)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+//! set a diagonal of our matrix using a diagonal from a foreign matrix
+template<typename eT>
+inline
+void
+diagview<eT>::operator= (const diagview<eT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  diagview<eT>& d = *this;
+  
+  arma_debug_check( (d.n_elem != x.n_elem), "diagview: diagonals have incompatible lengths");
+  
+        Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
+  const Mat<eT>& x_m = x.m;
+  
+  if(&d_m != &x_m)
+    {
+    const uword d_n_elem     = d.n_elem;
+    const uword d_row_offset = d.row_offset;
+    const uword d_col_offset = d.col_offset;
+    
+    const uword x_row_offset = x.row_offset;
+    const uword x_col_offset = x.col_offset;
+    
+    uword ii,jj;
+    for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
+      {
+      const eT tmp_i = x_m.at(ii + x_row_offset, ii + x_col_offset);
+      const eT tmp_j = x_m.at(jj + x_row_offset, jj + x_col_offset);
+      
+      d_m.at(ii + d_row_offset, ii + d_col_offset) = tmp_i;
+      d_m.at(jj + d_row_offset, jj + d_col_offset) = tmp_j;
+      }
+    
+    if(ii < d_n_elem)
+      {
+      d_m.at(ii + d_row_offset, ii + d_col_offset) = x_m.at(ii + x_row_offset, ii + x_col_offset);
+      }
+    }
+  else
+    {
+    const Mat<eT> tmp = x;
+    
+    (*this).operator=(tmp);
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+diagview<eT>::operator+=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& t_m = const_cast< Mat<eT>& >(m);
+  
+  const uword t_n_elem     = n_elem;
+  const uword t_row_offset = row_offset;
+  const uword t_col_offset = col_offset;
+  
+  for(uword ii=0; ii < t_n_elem; ++ii)
+    {
+    t_m.at( ii + t_row_offset,  ii + t_col_offset) += val;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+diagview<eT>::operator-=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& t_m = const_cast< Mat<eT>& >(m);
+  
+  const uword t_n_elem     = n_elem;
+  const uword t_row_offset = row_offset;
+  const uword t_col_offset = col_offset;
+  
+  for(uword ii=0; ii < t_n_elem; ++ii)
+    {
+    t_m.at( ii + t_row_offset,  ii + t_col_offset) -= val;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+diagview<eT>::operator*=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& t_m = const_cast< Mat<eT>& >(m);
+  
+  const uword t_n_elem     = n_elem;
+  const uword t_row_offset = row_offset;
+  const uword t_col_offset = col_offset;
+  
+  for(uword ii=0; ii < t_n_elem; ++ii)
+    {
+    t_m.at( ii + t_row_offset,  ii + t_col_offset) *= val;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+diagview<eT>::operator/=(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& t_m = const_cast< Mat<eT>& >(m);
+  
+  const uword t_n_elem     = n_elem;
+  const uword t_row_offset = row_offset;
+  const uword t_col_offset = col_offset;
+  
+  for(uword ii=0; ii < t_n_elem; ++ii)
+    {
+    t_m.at( ii + t_row_offset,  ii + t_col_offset) /= val;
+    }
+  }
+
+
+
+//! set a diagonal of our matrix using data from a foreign object
+template<typename eT>
+template<typename T1>
+inline
+void
+diagview<eT>::operator= (const Base<eT,T1>& o)
+  {
+  arma_extra_debug_sigprint();
+  
+  diagview<eT>& d = *this;
+  
+  Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
+  
+  const uword d_n_elem     = d.n_elem;
+  const uword d_row_offset = d.row_offset;
+  const uword d_col_offset = d.col_offset;
+    
+  const Proxy<T1> P( o.get_ref() );
+  
+  arma_debug_check
+    (
+    ( (d.n_elem != P.get_n_elem()) || ((P.get_n_rows() != 1) && (P.get_n_cols() != 1)) ),
+    "diagview: given object has incompatible size"
+    );
+  
+  const bool is_alias = P.is_alias(d_m);
+  
+  arma_extra_debug_warn(is_alias, "aliasing detected");
+  
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) || (Proxy<T1>::prefer_at_accessor == true) || (is_alias == true) )
+    {
+    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
+    const Mat<eT>& x = tmp.M;
+    
+    const eT* x_mem = x.memptr();
+    
+    uword ii,jj;
+    for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
+      {
+      const eT tmp_i = x_mem[ii];
+      const eT tmp_j = x_mem[jj];
+      
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) = tmp_i;
+      d_m.at( jj + d_row_offset,  jj + d_col_offset) = tmp_j;
+      }
+    
+    if(ii < d_n_elem)
+      {
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) = x_mem[ii];
+      }
+    }
+  else
+    {
+    typename Proxy<T1>::ea_type Pea = P.get_ea();
+      
+    uword ii,jj;
+    for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
+      {
+      const eT tmp_i = Pea[ii];
+      const eT tmp_j = Pea[jj];
+      
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) = tmp_i;
+      d_m.at( jj + d_row_offset,  jj + d_col_offset) = tmp_j;
+      }
+    
+    if(ii < d_n_elem)
+      {
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) = Pea[ii];
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+diagview<eT>::operator+=(const Base<eT,T1>& o)
+  {
+  arma_extra_debug_sigprint();
+  
+  diagview<eT>& d = *this;
+  
+  Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
+  
+  const uword d_n_elem     = d.n_elem;
+  const uword d_row_offset = d.row_offset;
+  const uword d_col_offset = d.col_offset;
+    
+  const Proxy<T1> P( o.get_ref() );
+  
+  arma_debug_check
+    (
+    ( (d.n_elem != P.get_n_elem()) || ((P.get_n_rows() != 1) && (P.get_n_cols() != 1)) ),
+    "diagview: given object has incompatible size"
+    );
+  
+  const bool is_alias = P.is_alias(d_m);
+  
+  arma_extra_debug_warn(is_alias, "aliasing detected");
+  
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) || (Proxy<T1>::prefer_at_accessor == true) || (is_alias == true) )
+    {
+    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
+    const Mat<eT>& x = tmp.M;
+    
+    const eT* x_mem = x.memptr();
+    
+    uword ii,jj;
+    for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
+      {
+      const eT tmp_i = x_mem[ii];
+      const eT tmp_j = x_mem[jj];
+      
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) += tmp_i;
+      d_m.at( jj + d_row_offset,  jj + d_col_offset) += tmp_j;
+      }
+    
+    if(ii < d_n_elem)
+      {
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) += x_mem[ii];
+      }
+    }
+  else
+    {
+    typename Proxy<T1>::ea_type Pea = P.get_ea();
+      
+    uword ii,jj;
+    for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
+      {
+      const eT tmp_i = Pea[ii];
+      const eT tmp_j = Pea[jj];
+      
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) += tmp_i;
+      d_m.at( jj + d_row_offset,  jj + d_col_offset) += tmp_j;
+      }
+    
+    if(ii < d_n_elem)
+      {
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) += Pea[ii];
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+diagview<eT>::operator-=(const Base<eT,T1>& o)
+  {
+  arma_extra_debug_sigprint();
+  
+  diagview<eT>& d = *this;
+  
+  Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
+  
+  const uword d_n_elem     = d.n_elem;
+  const uword d_row_offset = d.row_offset;
+  const uword d_col_offset = d.col_offset;
+    
+  const Proxy<T1> P( o.get_ref() );
+  
+  arma_debug_check
+    (
+    ( (d.n_elem != P.get_n_elem()) || ((P.get_n_rows() != 1) && (P.get_n_cols() != 1)) ),
+    "diagview: given object has incompatible size"
+    );
+  
+  const bool is_alias = P.is_alias(d_m);
+  
+  arma_extra_debug_warn(is_alias, "aliasing detected");
+  
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) || (Proxy<T1>::prefer_at_accessor == true) || (is_alias == true) )
+    {
+    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
+    const Mat<eT>& x = tmp.M;
+    
+    const eT* x_mem = x.memptr();
+    
+    uword ii,jj;
+    for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
+      {
+      const eT tmp_i = x_mem[ii];
+      const eT tmp_j = x_mem[jj];
+      
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) -= tmp_i;
+      d_m.at( jj + d_row_offset,  jj + d_col_offset) -= tmp_j;
+      }
+    
+    if(ii < d_n_elem)
+      {
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) -= x_mem[ii];
+      }
+    }
+  else
+    {
+    typename Proxy<T1>::ea_type Pea = P.get_ea();
+      
+    uword ii,jj;
+    for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
+      {
+      const eT tmp_i = Pea[ii];
+      const eT tmp_j = Pea[jj];
+      
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) -= tmp_i;
+      d_m.at( jj + d_row_offset,  jj + d_col_offset) -= tmp_j;
+      }
+    
+    if(ii < d_n_elem)
+      {
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) -= Pea[ii];
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+diagview<eT>::operator%=(const Base<eT,T1>& o)
+  {
+  arma_extra_debug_sigprint();
+  
+  diagview<eT>& d = *this;
+  
+  Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
+  
+  const uword d_n_elem     = d.n_elem;
+  const uword d_row_offset = d.row_offset;
+  const uword d_col_offset = d.col_offset;
+    
+  const Proxy<T1> P( o.get_ref() );
+  
+  arma_debug_check
+    (
+    ( (d.n_elem != P.get_n_elem()) || ((P.get_n_rows() != 1) && (P.get_n_cols() != 1)) ),
+    "diagview: given object has incompatible size"
+    );
+  
+  const bool is_alias = P.is_alias(d_m);
+  
+  arma_extra_debug_warn(is_alias, "aliasing detected");
+  
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) || (Proxy<T1>::prefer_at_accessor == true) || (is_alias == true) )
+    {
+    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
+    const Mat<eT>& x = tmp.M;
+    
+    const eT* x_mem = x.memptr();
+    
+    uword ii,jj;
+    for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
+      {
+      const eT tmp_i = x_mem[ii];
+      const eT tmp_j = x_mem[jj];
+      
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) *= tmp_i;
+      d_m.at( jj + d_row_offset,  jj + d_col_offset) *= tmp_j;
+      }
+    
+    if(ii < d_n_elem)
+      {
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) *= x_mem[ii];
+      }
+    }
+  else
+    {
+    typename Proxy<T1>::ea_type Pea = P.get_ea();
+      
+    uword ii,jj;
+    for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
+      {
+      const eT tmp_i = Pea[ii];
+      const eT tmp_j = Pea[jj];
+      
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) *= tmp_i;
+      d_m.at( jj + d_row_offset,  jj + d_col_offset) *= tmp_j;
+      }
+    
+    if(ii < d_n_elem)
+      {
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) *= Pea[ii];
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+diagview<eT>::operator/=(const Base<eT,T1>& o)
+  {
+  arma_extra_debug_sigprint();
+  
+  diagview<eT>& d = *this;
+  
+  Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
+  
+  const uword d_n_elem     = d.n_elem;
+  const uword d_row_offset = d.row_offset;
+  const uword d_col_offset = d.col_offset;
+    
+  const Proxy<T1> P( o.get_ref() );
+  
+  arma_debug_check
+    (
+    ( (d.n_elem != P.get_n_elem()) || ((P.get_n_rows() != 1) && (P.get_n_cols() != 1)) ),
+    "diagview: given object has incompatible size"
+    );
+  
+  const bool is_alias = P.is_alias(d_m);
+  
+  arma_extra_debug_warn(is_alias, "aliasing detected");
+  
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) || (Proxy<T1>::prefer_at_accessor == true) || (is_alias == true) )
+    {
+    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
+    const Mat<eT>& x = tmp.M;
+    
+    const eT* x_mem = x.memptr();
+    
+    uword ii,jj;
+    for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
+      {
+      const eT tmp_i = x_mem[ii];
+      const eT tmp_j = x_mem[jj];
+      
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) /= tmp_i;
+      d_m.at( jj + d_row_offset,  jj + d_col_offset) /= tmp_j;
+      }
+    
+    if(ii < d_n_elem)
+      {
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) /= x_mem[ii];
+      }
+    }
+  else
+    {
+    typename Proxy<T1>::ea_type Pea = P.get_ea();
+      
+    uword ii,jj;
+    for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
+      {
+      const eT tmp_i = Pea[ii];
+      const eT tmp_j = Pea[jj];
+      
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) /= tmp_i;
+      d_m.at( jj + d_row_offset,  jj + d_col_offset) /= tmp_j;
+      }
+    
+    if(ii < d_n_elem)
+      {
+      d_m.at( ii + d_row_offset,  ii + d_col_offset) /= Pea[ii];
+      }
+    }
+  }
+
+
+
+//! extract a diagonal and store it as a column vector
+template<typename eT>
+inline
+void
+diagview<eT>::extract(Mat<eT>& out, const diagview<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing;
+  // size setting and alias checking is done by either the Mat contructor or operator=()
+  
+  const Mat<eT>& in_m = in.m;
+  
+  const uword in_n_elem     = in.n_elem;
+  const uword in_row_offset = in.row_offset;
+  const uword in_col_offset = in.col_offset;
+  
+  eT* out_mem = out.memptr();
+  
+  uword i,j;
+  for(i=0, j=1; j < in_n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset );
+    const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset );
+    
+    out_mem[i] = tmp_i;
+    out_mem[j] = tmp_j;
+    }
+  
+  if(i < in_n_elem)
+    {
+    out_mem[i] = in_m.at( i + in_row_offset, i + in_col_offset );
+    }
+  }
+
+
+
+//! X += Y.diag()
+template<typename eT>
+inline
+void
+diagview<eT>::plus_inplace(Mat<eT>& out, const diagview<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, in.n_rows, in.n_cols, "addition");
+  
+  const Mat<eT>& in_m = in.m;
+  
+  const uword in_n_elem     = in.n_elem;
+  const uword in_row_offset = in.row_offset;
+  const uword in_col_offset = in.col_offset;
+  
+  eT* out_mem = out.memptr();
+  
+  uword i,j;
+  for(i=0, j=1; j < in_n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset );
+    const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset );
+    
+    out_mem[i] += tmp_i;
+    out_mem[j] += tmp_j;
+    }
+  
+  if(i < in_n_elem)
+    {
+    out_mem[i] += in_m.at( i + in_row_offset, i + in_col_offset );
+    }
+  }
+
+
+
+//! X -= Y.diag()
+template<typename eT>
+inline
+void
+diagview<eT>::minus_inplace(Mat<eT>& out, const diagview<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, in.n_rows, in.n_cols, "subtraction");
+  
+  const Mat<eT>& in_m = in.m;
+  
+  const uword in_n_elem     = in.n_elem;
+  const uword in_row_offset = in.row_offset;
+  const uword in_col_offset = in.col_offset;
+  
+  eT* out_mem = out.memptr();
+  
+  uword i,j;
+  for(i=0, j=1; j < in_n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset );
+    const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset );
+    
+    out_mem[i] -= tmp_i;
+    out_mem[j] -= tmp_j;
+    }
+  
+  if(i < in_n_elem)
+    {
+    out_mem[i] -= in_m.at( i + in_row_offset, i + in_col_offset );
+    }
+  }
+
+
+
+//! X %= Y.diag()
+template<typename eT>
+inline
+void
+diagview<eT>::schur_inplace(Mat<eT>& out, const diagview<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, in.n_rows, in.n_cols, "element-wise multiplication");
+  
+  const Mat<eT>& in_m = in.m;
+  
+  const uword in_n_elem     = in.n_elem;
+  const uword in_row_offset = in.row_offset;
+  const uword in_col_offset = in.col_offset;
+  
+  eT* out_mem = out.memptr();
+  
+  uword i,j;
+  for(i=0, j=1; j < in_n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset );
+    const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset );
+    
+    out_mem[i] *= tmp_i;
+    out_mem[j] *= tmp_j;
+    }
+  
+  if(i < in_n_elem)
+    {
+    out_mem[i] *= in_m.at( i + in_row_offset, i + in_col_offset );
+    }
+  }
+
+
+
+//! X /= Y.diag()
+template<typename eT>
+inline
+void
+diagview<eT>::div_inplace(Mat<eT>& out, const diagview<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, in.n_rows, in.n_cols, "element-wise division");
+  
+  const Mat<eT>& in_m = in.m;
+  
+  const uword in_n_elem     = in.n_elem;
+  const uword in_row_offset = in.row_offset;
+  const uword in_col_offset = in.col_offset;
+  
+  eT* out_mem = out.memptr();
+  
+  uword i,j;
+  for(i=0, j=1; j < in_n_elem; i+=2, j+=2)
+    {
+    const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset );
+    const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset );
+    
+    out_mem[i] /= tmp_i;
+    out_mem[j] /= tmp_j;
+    }
+  
+  if(i < in_n_elem)
+    {
+    out_mem[i] /= in_m.at( i + in_row_offset, i + in_col_offset );
+    }
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+diagview<eT>::at_alt(const uword ii) const
+  {
+  return m.at(ii+row_offset, ii+col_offset);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT&
+diagview<eT>::operator[](const uword ii)
+  {
+  return (const_cast< Mat<eT>& >(m)).at(ii+row_offset, ii+col_offset);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+diagview<eT>::operator[](const uword ii) const
+  {
+  return m.at(ii+row_offset, ii+col_offset);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT&
+diagview<eT>::at(const uword ii)
+  {
+  return (const_cast< Mat<eT>& >(m)).at(ii+row_offset, ii+col_offset);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+diagview<eT>::at(const uword ii) const
+  {
+  return m.at(ii+row_offset, ii+col_offset);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT&
+diagview<eT>::operator()(const uword ii)
+  {
+  arma_debug_check( (ii >= n_elem), "diagview::operator(): out of bounds" );
+  
+  return (const_cast< Mat<eT>& >(m)).at(ii+row_offset, ii+col_offset);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+diagview<eT>::operator()(const uword ii) const
+  {
+  arma_debug_check( (ii >= n_elem), "diagview::operator(): out of bounds" );
+  
+  return m.at(ii+row_offset, ii+col_offset);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT&
+diagview<eT>::at(const uword row, const uword)
+  {
+  return (const_cast< Mat<eT>& >(m)).at(row+row_offset, row+col_offset);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+diagview<eT>::at(const uword row, const uword) const
+  {
+  return m.at(row+row_offset, row+col_offset);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT&
+diagview<eT>::operator()(const uword row, const uword col)
+  {
+  arma_debug_check( ((row >= n_elem) || (col > 0)), "diagview::operator(): out of bounds" );
+  
+  return (const_cast< Mat<eT>& >(m)).at(row+row_offset, row+col_offset);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+diagview<eT>::operator()(const uword row, const uword col) const
+  {
+  arma_debug_check( ((row >= n_elem) || (col > 0)), "diagview::operator(): out of bounds" );
+  
+  return m.at(row+row_offset, row+col_offset);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<diagview<eT>,op_htrans>
+diagview<eT>::t() const
+  {
+  return Op<diagview<eT>,op_htrans>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<diagview<eT>,op_htrans>
+diagview<eT>::ht() const
+  {
+  return Op<diagview<eT>,op_htrans>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<diagview<eT>,op_strans>
+diagview<eT>::st() const
+  {
+  return Op<diagview<eT>,op_strans>(*this);
+  }
+
+
+
+template<typename eT>
+inline
+void
+diagview<eT>::fill(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& x = const_cast< Mat<eT>& >(m);
+  
+  for(uword ii=0; ii < n_elem; ++ii)
+    {
+    x.at(ii+row_offset, ii+col_offset) = val;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+diagview<eT>::zeros()
+  {
+  arma_extra_debug_sigprint();
+  
+  (*this).fill(eT(0));
+  }
+
+
+
+template<typename eT>
+inline
+void
+diagview<eT>::ones()
+  {
+  arma_extra_debug_sigprint();
+  
+  (*this).fill(eT(1));
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/diskio_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,187 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2009-2010 Ian Cullinan
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2013 Szabolcs Horvat
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup diskio
+//! @{
+
+
+//! class for saving and loading matrices and fields
+class diskio
+  {
+  public:
+  
+  template<typename eT> inline static std::string gen_txt_header(const Mat<eT>& x);
+  template<typename eT> inline static std::string gen_bin_header(const Mat<eT>& x);
+  
+  template<typename eT> inline static std::string gen_bin_header(const SpMat<eT>& x);
+
+  template<typename eT> inline static std::string gen_txt_header(const Cube<eT>& x);
+  template<typename eT> inline static std::string gen_bin_header(const Cube<eT>& x);
+  
+  inline static file_type guess_file_type(std::istream& f);
+  
+  inline static char conv_to_hex_char(const u8 x);
+  inline static void conv_to_hex(char* out, const u8 x);
+  
+  inline static std::string gen_tmp_name(const std::string& x);
+  
+  inline static bool safe_rename(const std::string& old_name, const std::string& new_name);
+  
+  template<typename eT> inline static bool convert_naninf(eT&              val, const std::string& token);
+  template<typename  T> inline static bool convert_naninf(std::complex<T>& val, const std::string& token);
+  
+  //
+  // matrix saving
+  
+  template<typename eT> inline static bool save_raw_ascii  (const Mat<eT>&                x, const std::string& final_name);
+  template<typename eT> inline static bool save_raw_binary (const Mat<eT>&                x, const std::string& final_name);
+  template<typename eT> inline static bool save_arma_ascii (const Mat<eT>&                x, const std::string& final_name);
+  template<typename eT> inline static bool save_csv_ascii  (const Mat<eT>&                x, const std::string& final_name);
+  template<typename eT> inline static bool save_arma_binary(const Mat<eT>&                x, const std::string& final_name);
+  template<typename eT> inline static bool save_pgm_binary (const Mat<eT>&                x, const std::string& final_name);
+  template<typename  T> inline static bool save_pgm_binary (const Mat< std::complex<T> >& x, const std::string& final_name);
+  template<typename eT> inline static bool save_hdf5_binary(const Mat<eT>&                x, const std::string& final_name);
+  
+  template<typename eT> inline static bool save_raw_ascii  (const Mat<eT>&                x, std::ostream& f);
+  template<typename eT> inline static bool save_raw_binary (const Mat<eT>&                x, std::ostream& f);
+  template<typename eT> inline static bool save_arma_ascii (const Mat<eT>&                x, std::ostream& f);
+  template<typename eT> inline static bool save_csv_ascii  (const Mat<eT>&                x, std::ostream& f);
+  template<typename eT> inline static bool save_arma_binary(const Mat<eT>&                x, std::ostream& f);
+  template<typename eT> inline static bool save_pgm_binary (const Mat<eT>&                x, std::ostream& f);
+  template<typename  T> inline static bool save_pgm_binary (const Mat< std::complex<T> >& x, std::ostream& f);
+  
+  
+  //
+  // matrix loading
+  
+  template<typename eT> inline static bool load_raw_ascii  (Mat<eT>&                x, const std::string& name, std::string& err_msg);
+  template<typename eT> inline static bool load_raw_binary (Mat<eT>&                x, const std::string& name, std::string& err_msg);
+  template<typename eT> inline static bool load_arma_ascii (Mat<eT>&                x, const std::string& name, std::string& err_msg);
+  template<typename eT> inline static bool load_csv_ascii  (Mat<eT>&                x, const std::string& name, std::string& err_msg);
+  template<typename eT> inline static bool load_arma_binary(Mat<eT>&                x, const std::string& name, std::string& err_msg);
+  template<typename eT> inline static bool load_pgm_binary (Mat<eT>&                x, const std::string& name, std::string& err_msg);
+  template<typename  T> inline static bool load_pgm_binary (Mat< std::complex<T> >& x, const std::string& name, std::string& err_msg);
+  template<typename eT> inline static bool load_hdf5_binary(Mat<eT>&                x, const std::string& name, std::string& err_msg);
+  template<typename eT> inline static bool load_auto_detect(Mat<eT>&                x, const std::string& name, std::string& err_msg);
+  
+  template<typename eT> inline static bool load_raw_ascii  (Mat<eT>&                x, std::istream& f,  std::string& err_msg);
+  template<typename eT> inline static bool load_raw_binary (Mat<eT>&                x, std::istream& f,  std::string& err_msg);
+  template<typename eT> inline static bool load_arma_ascii (Mat<eT>&                x, std::istream& f,  std::string& err_msg);
+  template<typename eT> inline static bool load_csv_ascii  (Mat<eT>&                x, std::istream& f,  std::string& err_msg);
+  template<typename eT> inline static bool load_arma_binary(Mat<eT>&                x, std::istream& f,  std::string& err_msg);
+  template<typename eT> inline static bool load_pgm_binary (Mat<eT>&                x, std::istream& is, std::string& err_msg);
+  template<typename  T> inline static bool load_pgm_binary (Mat< std::complex<T> >& x, std::istream& is, std::string& err_msg);
+  template<typename eT> inline static bool load_auto_detect(Mat<eT>&                x, std::istream& f,  std::string& err_msg);
+  
+  inline static void pnm_skip_comments(std::istream& f);
+  
+  
+  //
+  // sparse matrix saving
+  
+  template<typename eT> inline static bool save_coord_ascii(const SpMat<eT>& x, const std::string& final_name);
+  template<typename eT> inline static bool save_arma_binary(const SpMat<eT>& x, const std::string& final_name);
+  
+  template<typename eT> inline static bool save_coord_ascii(const SpMat<eT>& x,                std::ostream& f);
+  template<typename  T> inline static bool save_coord_ascii(const SpMat< std::complex<T> >& x, std::ostream& f);
+  template<typename eT> inline static bool save_arma_binary(const SpMat<eT>& x,                std::ostream& f);
+  
+  
+  //
+  // sparse matrix loading
+  
+  template<typename eT> inline static bool load_coord_ascii(SpMat<eT>& x, const std::string& name, std::string& err_msg);
+  template<typename eT> inline static bool load_arma_binary(SpMat<eT>& x, const std::string& name, std::string& err_msg);
+  
+  template<typename eT> inline static bool load_coord_ascii(SpMat<eT>& x,                std::istream& f, std::string& err_msg);
+  template<typename  T> inline static bool load_coord_ascii(SpMat< std::complex<T> >& x, std::istream& f, std::string& err_msg);
+  template<typename eT> inline static bool load_arma_binary(SpMat<eT>& x,                std::istream& f, std::string& err_msg);
+  
+  
+  
+  //
+  // cube saving
+  
+  template<typename eT> inline static bool save_raw_ascii  (const Cube<eT>& x, const std::string& name);
+  template<typename eT> inline static bool save_raw_binary (const Cube<eT>& x, const std::string& name);
+  template<typename eT> inline static bool save_arma_ascii (const Cube<eT>& x, const std::string& name);
+  template<typename eT> inline static bool save_arma_binary(const Cube<eT>& x, const std::string& name);
+  template<typename eT> inline static bool save_hdf5_binary(const Cube<eT>& x, const std::string& name);
+  
+  template<typename eT> inline static bool save_raw_ascii  (const Cube<eT>& x, std::ostream& f);
+  template<typename eT> inline static bool save_raw_binary (const Cube<eT>& x, std::ostream& f);
+  template<typename eT> inline static bool save_arma_ascii (const Cube<eT>& x, std::ostream& f);
+  template<typename eT> inline static bool save_arma_binary(const Cube<eT>& x, std::ostream& f);
+  
+  
+  //
+  // cube loading
+  
+  template<typename eT> inline static bool load_raw_ascii  (Cube<eT>& x, const std::string& name, std::string& err_msg);
+  template<typename eT> inline static bool load_raw_binary (Cube<eT>& x, const std::string& name, std::string& err_msg);
+  template<typename eT> inline static bool load_arma_ascii (Cube<eT>& x, const std::string& name, std::string& err_msg);
+  template<typename eT> inline static bool load_arma_binary(Cube<eT>& x, const std::string& name, std::string& err_msg);
+  template<typename eT> inline static bool load_hdf5_binary(Cube<eT>& x, const std::string& name, std::string& err_msg);
+  template<typename eT> inline static bool load_auto_detect(Cube<eT>& x, const std::string& name, std::string& err_msg);
+  
+  template<typename eT> inline static bool load_raw_ascii  (Cube<eT>& x, std::istream& f, std::string& err_msg);
+  template<typename eT> inline static bool load_raw_binary (Cube<eT>& x, std::istream& f, std::string& err_msg);
+  template<typename eT> inline static bool load_arma_ascii (Cube<eT>& x, std::istream& f, std::string& err_msg);
+  template<typename eT> inline static bool load_arma_binary(Cube<eT>& x, std::istream& f, std::string& err_msg);
+  template<typename eT> inline static bool load_auto_detect(Cube<eT>& x, std::istream& f, std::string& err_msg);
+  
+  
+  //
+  // field saving and loading
+  
+  template<typename T1> inline static bool save_arma_binary(const field<T1>& x, const std::string&  name);
+  template<typename T1> inline static bool save_arma_binary(const field<T1>& x,       std::ostream& f);
+  
+  template<typename T1> inline static bool load_arma_binary(      field<T1>& x, const std::string&  name, std::string& err_msg);
+  template<typename T1> inline static bool load_arma_binary(      field<T1>& x,       std::istream& f,    std::string& err_msg);
+  
+  template<typename T1> inline static bool load_auto_detect(      field<T1>& x, const std::string&  name, std::string& err_msg);
+  template<typename T1> inline static bool load_auto_detect(      field<T1>& x,       std::istream& f,    std::string& err_msg);
+  
+  inline static bool save_std_string(const field<std::string>& x, const std::string&  name);
+  inline static bool save_std_string(const field<std::string>& x,       std::ostream& f);
+  
+  inline static bool load_std_string(      field<std::string>& x, const std::string&  name, std::string& err_msg);
+  inline static bool load_std_string(      field<std::string>& x,       std::istream& f,    std::string& err_msg);
+  
+
+
+  //
+  // handling of PPM images by cubes
+
+  template<typename T1> inline static bool save_ppm_binary(const Cube<T1>& x, const std::string&  final_name);
+  template<typename T1> inline static bool save_ppm_binary(const Cube<T1>& x,       std::ostream& f);
+  
+  template<typename T1> inline static bool load_ppm_binary(      Cube<T1>& x, const std::string&  final_name, std::string& err_msg);
+  template<typename T1> inline static bool load_ppm_binary(      Cube<T1>& x,       std::istream& f,          std::string& err_msg);
+
+
+  //
+  // handling of PPM images by fields
+
+  template<typename T1> inline static bool save_ppm_binary(const field<T1>& x, const std::string&  final_name);
+  template<typename T1> inline static bool save_ppm_binary(const field<T1>& x,       std::ostream& f);
+  
+  template<typename T1> inline static bool load_ppm_binary(      field<T1>& x, const std::string&  final_name, std::string& err_msg);
+  template<typename T1> inline static bool load_ppm_binary(      field<T1>& x,       std::istream& f,          std::string& err_msg);
+  
+
+
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/diskio_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,4662 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2009-2010 Ian Cullinan
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2013 Szabolcs Horvat
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup diskio
+//! @{
+
+
+//! Generate the first line of the header used for saving matrices in text format.
+//! Format: "ARMA_MAT_TXT_ABXYZ".
+//! A is one of: I (for integral types) or F (for floating point types).
+//! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
+//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
+template<typename eT>
+inline
+std::string
+diskio::gen_txt_header(const Mat<eT>& x)
+  {
+  arma_type_check(( is_supported_elem_type<eT>::value == false ));
+
+  arma_ignore(x);
+  
+  if(is_u8<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_IU001");
+    }
+  else
+  if(is_s8<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_IS001");
+    }
+  else
+  if(is_u16<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_IU002");
+    }
+  else
+  if(is_s16<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_IS002");
+    }
+  else
+  if(is_u32<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_IU004");
+    }
+  else
+  if(is_s32<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_IS004");
+    }
+#if defined(ARMA_USE_U64S64)
+  else
+  if(is_u64<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_IU008");
+    }
+  else
+  if(is_s64<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_IS008");
+    }
+#endif
+#if defined(ARMA_ALLOW_LONG)
+  else
+  if(is_ulng_t_32<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_IU004");
+    }
+  else
+  if(is_slng_t_32<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_IS004");
+    }
+  else
+  if(is_ulng_t_64<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_IU008");
+    }
+  else
+  if(is_slng_t_64<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_IS008");
+    }
+#endif
+  else
+  if(is_float<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_FN004");
+    }
+  else
+  if(is_double<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_FN008");
+    }
+  else
+  if(is_complex_float<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_FC008");
+    }
+  else
+  if(is_complex_double<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_TXT_FC016");
+    }
+  else
+    {
+    return std::string();
+    }
+  
+  }
+
+
+
+//! Generate the first line of the header used for saving matrices in binary format.
+//! Format: "ARMA_MAT_BIN_ABXYZ".
+//! A is one of: I (for integral types) or F (for floating point types).
+//! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
+//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
+template<typename eT>
+inline
+std::string
+diskio::gen_bin_header(const Mat<eT>& x)
+  {
+  arma_type_check(( is_supported_elem_type<eT>::value == false ));
+  
+  arma_ignore(x);
+  
+  if(is_u8<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_IU001");
+    }
+  else
+  if(is_s8<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_IS001");
+    }
+  else
+  if(is_u16<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_IU002");
+    }
+  else
+  if(is_s16<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_IS002");
+    }
+  else
+  if(is_u32<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_IU004");
+    }
+  else
+  if(is_s32<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_IS004");
+    }
+#if defined(ARMA_USE_U64S64)
+  else
+  if(is_u64<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_IU008");
+    }
+  else
+  if(is_s64<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_IS008");
+    }
+#endif
+#if defined(ARMA_ALLOW_LONG)
+  else
+  if(is_ulng_t_32<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_IU004");
+    }
+  else
+  if(is_slng_t_32<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_IS004");
+    }
+  else
+  if(is_ulng_t_64<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_IU008");
+    }
+  else
+  if(is_slng_t_64<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_IS008");
+    }
+#endif
+  else
+  if(is_float<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_FN004");
+    }
+  else
+  if(is_double<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_FN008");
+    }
+  else
+  if(is_complex_float<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_FC008");
+    }
+  else
+  if(is_complex_double<eT>::value == true)
+    {
+    return std::string("ARMA_MAT_BIN_FC016");
+    }
+  else
+    {
+    return std::string();
+    }
+  
+  }
+
+
+
+//! Generate the first line of the header used for saving matrices in binary format.
+//! Format: "ARMA_SPM_BIN_ABXYZ".
+//! A is one of: I (for integral types) or F (for floating point types).
+//! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
+//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
+template<typename eT>
+inline
+std::string
+diskio::gen_bin_header(const SpMat<eT>& x)
+  {
+  arma_type_check(( is_supported_elem_type<eT>::value == false ));
+
+  arma_ignore(x);
+
+  if(is_u8<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_IU001");
+    }
+  else
+  if(is_s8<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_IS001");
+    }
+  else
+  if(is_u16<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_IU002");
+    }
+  else
+  if(is_s16<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_IS002");
+    }
+  else
+  if(is_u32<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_IU004");
+    }
+  else
+  if(is_s32<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_IS004");
+    }
+#if defined(ARMA_USE_U64S64)
+  else
+  if(is_u64<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_IU008");
+    }
+  else
+  if(is_s64<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_IS008");
+    }
+#endif
+#if defined(ARMA_ALLOW_LONG)
+  else
+  if(is_ulng_t_32<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_IU004");
+    }
+  else
+  if(is_slng_t_32<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_IS004");
+    }
+  else
+  if(is_ulng_t_64<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_IU008");
+    }
+  else
+  if(is_slng_t_64<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_IS008");
+    }
+#endif
+  else
+  if(is_float<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_FN004");
+    }
+  else
+  if(is_double<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_FN008");
+    }
+  else
+  if(is_complex_float<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_FC008");
+    }
+  else
+  if(is_complex_double<eT>::value == true)
+    {
+    return std::string("ARMA_SPM_BIN_FC016");
+    }
+  else
+    {
+    return std::string();
+    }
+
+  }
+
+
+//! Generate the first line of the header used for saving cubes in text format.
+//! Format: "ARMA_CUB_TXT_ABXYZ".
+//! A is one of: I (for integral types) or F (for floating point types).
+//! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
+//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
+template<typename eT>
+inline
+std::string
+diskio::gen_txt_header(const Cube<eT>& x)
+  {
+  arma_type_check(( is_supported_elem_type<eT>::value == false ));
+  
+  arma_ignore(x);
+
+  if(is_u8<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_IU001");
+    }
+  else
+  if(is_s8<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_IS001");
+    }
+  else
+  if(is_u16<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_IU002");
+    }
+  else
+  if(is_s16<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_IS002");
+    }
+  else
+  if(is_u32<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_IU004");
+    }
+  else
+  if(is_s32<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_IS004");
+    }
+#if defined(ARMA_USE_U64S64)
+  else
+  if(is_u64<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_IU008");
+    }
+  else
+  if(is_s64<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_IS008");
+    }
+#endif
+#if defined(ARMA_ALLOW_LONG)
+  else
+  if(is_ulng_t_32<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_IU004");
+    }
+  else
+  if(is_slng_t_32<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_IS004");
+    }
+  else
+  if(is_ulng_t_64<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_IU008");
+    }
+  else
+  if(is_slng_t_64<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_IS008");
+    }
+#endif
+  else
+  if(is_float<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_FN004");
+    }
+  else
+  if(is_double<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_FN008");
+    }
+  else
+  if(is_complex_float<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_FC008");
+    }
+  else
+  if(is_complex_double<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_TXT_FC016");
+    }
+  else
+    {
+    return std::string();
+    }
+  
+  }
+
+
+
+//! Generate the first line of the header used for saving cubes in binary format.
+//! Format: "ARMA_CUB_BIN_ABXYZ".
+//! A is one of: I (for integral types) or F (for floating point types).
+//! B is one of: U (for unsigned types), S (for signed types), N (for not appliable) or C (for complex types).
+//! XYZ specifies the width of each element in terms of bytes, e.g. "008" indicates eight bytes.
+template<typename eT>
+inline
+std::string
+diskio::gen_bin_header(const Cube<eT>& x)
+  {
+  arma_type_check(( is_supported_elem_type<eT>::value == false ));
+  
+  arma_ignore(x);
+  
+  if(is_u8<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_IU001");
+    }
+  else
+  if(is_s8<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_IS001");
+    }
+  else
+  if(is_u16<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_IU002");
+    }
+  else
+  if(is_s16<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_IS002");
+    }
+  else
+  if(is_u32<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_IU004");
+    }
+  else
+  if(is_s32<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_IS004");
+    }
+#if defined(ARMA_USE_U64S64)
+  else
+  if(is_u64<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_IU008");
+    }
+  else
+  if(is_s64<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_IS008");
+    }
+#endif
+#if defined(ARMA_ALLOW_LONG)
+  else
+  if(is_ulng_t_32<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_IU004");
+    }
+  else
+  if(is_slng_t_32<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_IS004");
+    }
+  else
+  if(is_ulng_t_64<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_IU008");
+    }
+  else
+  if(is_slng_t_64<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_IS008");
+    }
+#endif
+  else
+  if(is_float<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_FN004");
+    }
+  else
+  if(is_double<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_FN008");
+    }
+  else
+  if(is_complex_float<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_FC008");
+    }
+  else
+  if(is_complex_double<eT>::value == true)
+    {
+    return std::string("ARMA_CUB_BIN_FC016");
+    }
+  else
+    {
+    return std::string();
+    }
+  
+  }
+
+
+
+inline
+file_type
+diskio::guess_file_type(std::istream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  f.clear();
+  const std::fstream::pos_type pos1 = f.tellg();
+  
+  f.clear();
+  f.seekg(0, ios::end);
+  
+  f.clear();
+  const std::fstream::pos_type pos2 = f.tellg();
+  
+  const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
+  
+  f.clear();
+  f.seekg(pos1);
+  
+  podarray<unsigned char> data(N);
+  
+  unsigned char* ptr = data.memptr();
+  
+  f.clear();
+  f.read( reinterpret_cast<char*>(ptr), std::streamsize(N) );
+  
+  const bool load_okay = f.good();
+  
+  f.clear();
+  f.seekg(pos1);
+  
+  bool has_binary  = false;
+  bool has_comma   = false;
+  bool has_bracket = false;
+  
+  if(load_okay == true)
+    {
+    uword i = 0;
+    uword j = (N >= 2) ? 1 : 0;
+    
+    for(; j<N; i+=2, j+=2)
+      {
+      const unsigned char val_i = ptr[i];
+      const unsigned char val_j = ptr[j];
+      
+      // the range checking can be made more elaborate
+      if( ((val_i <= 8) || (val_i >= 123)) || ((val_j <= 8) || (val_j >= 123)) )
+        {
+        has_binary = true;
+        break;
+        }
+      
+      if( (val_i == ',') || (val_j == ',') )
+        {
+        has_comma = true;
+        }
+      
+      if( (val_i == '(') || (val_j == '(') || (val_i == ')') || (val_j == ')') )
+        {
+        has_bracket = true;
+        }
+      }
+    }
+  else
+    {
+    return file_type_unknown;
+    }
+  
+  if(has_binary)
+    {
+    return raw_binary;
+    }
+  
+  if(has_comma && (has_bracket == false))
+    {
+    return csv_ascii;
+    }
+  
+  return raw_ascii;
+  }
+
+
+
+inline
+char
+diskio::conv_to_hex_char(const u8 x)
+  {
+  char out;
+
+  switch(x)
+    {
+    case  0: out = '0'; break;
+    case  1: out = '1'; break;
+    case  2: out = '2'; break;
+    case  3: out = '3'; break;
+    case  4: out = '4'; break;
+    case  5: out = '5'; break;
+    case  6: out = '6'; break;
+    case  7: out = '7'; break;
+    case  8: out = '8'; break;
+    case  9: out = '9'; break;
+    case 10: out = 'a'; break;
+    case 11: out = 'b'; break;
+    case 12: out = 'c'; break;
+    case 13: out = 'd'; break;
+    case 14: out = 'e'; break;
+    case 15: out = 'f'; break;
+    default: out = '-'; break;
+    }
+
+  return out;  
+  }
+
+
+
+inline
+void
+diskio::conv_to_hex(char* out, const u8 x)
+  {
+  const u8 a = x / 16;
+  const u8 b = x - 16*a;
+
+  out[0] = conv_to_hex_char(a);
+  out[1] = conv_to_hex_char(b);
+  }
+
+
+
+//! Append a quasi-random string to the given filename.
+//! The rand() function is deliberately not used,
+//! as rand() has an internal state that changes
+//! from call to call. Such states should not be
+//! modified in scientific applications, where the
+//! results should be reproducable and not affected 
+//! by saving data.
+inline
+std::string
+diskio::gen_tmp_name(const std::string& x)
+  {
+  const std::string* ptr_x     = &x;
+  const u8*          ptr_ptr_x = reinterpret_cast<const u8*>(&ptr_x);
+  
+  const char* extra      = ".tmp_";
+  const uword extra_size = 5;
+  
+  const uword tmp_size   = 2*sizeof(u8*) + 2*2;
+        char  tmp[tmp_size];
+  
+  uword char_count = 0;
+  
+  for(uword i=0; i<sizeof(u8*); ++i)
+    {
+    conv_to_hex(&tmp[char_count], ptr_ptr_x[i]);
+    char_count += 2;
+    }
+  
+  const uword x_size = static_cast<uword>(x.size());
+  u8 sum = 0;
+  
+  for(uword i=0; i<x_size; ++i)
+    {
+    sum += u8(x[i]);
+    }
+  
+  conv_to_hex(&tmp[char_count], sum);
+  char_count += 2;
+  
+  conv_to_hex(&tmp[char_count], u8(x_size));
+  
+  
+  std::string out;
+  out.resize(x_size + extra_size + tmp_size);
+  
+  
+  for(uword i=0; i<x_size; ++i)
+    {
+    out[i] = x[i];
+    }
+  
+  for(uword i=0; i<extra_size; ++i)
+    {
+    out[x_size + i] = extra[i];
+    }
+  
+  for(uword i=0; i<tmp_size; ++i)
+    {
+    out[x_size + extra_size + i] = tmp[i];
+    }
+  
+  return out;
+  }
+
+
+
+//! Safely rename a file.
+//! Before renaming, test if we can write to the final file.
+//! This should prevent:
+//! (i)  overwriting files that are write protected,
+//! (ii) overwriting directories.
+inline
+bool
+diskio::safe_rename(const std::string& old_name, const std::string& new_name)
+  {
+  std::fstream f(new_name.c_str(), std::fstream::out | std::fstream::app);
+  f.put(' ');
+  
+  bool save_okay = f.good();
+  f.close();
+  
+  if(save_okay == true)
+    {
+    std::remove(new_name.c_str());
+    
+    const int mv_result = std::rename(old_name.c_str(), new_name.c_str());
+    
+    save_okay = (mv_result == 0);
+    }
+  
+  return save_okay;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+diskio::convert_naninf(eT& val, const std::string& token)
+  {
+  // see if the token represents a NaN or Inf
+  
+  if( (token.length() == 3) || (token.length() == 4) )
+    {
+    const bool neg = (token[0] == '-');
+    const bool pos = (token[0] == '+');
+    
+    const size_t offset = ( (neg || pos) && (token.length() == 4) ) ? 1 : 0;
+    
+    const std::string token2 = token.substr(offset, 3);
+    
+    if( (token2 == "inf") || (token2 == "Inf") || (token2 == "INF") )
+      {
+      val = neg ? -(Datum<eT>::inf) : Datum<eT>::inf;
+      
+      return true;
+      }
+    else
+    if( (token2 == "nan") || (token2 == "Nan") || (token2 == "NaN") || (token2 == "NAN") )
+      {
+      val = neg ? -(Datum<eT>::nan) : Datum<eT>::nan;
+      
+      return true;
+      }
+    }
+    
+  return false;
+  }
+
+
+
+template<typename T>
+inline
+bool
+diskio::convert_naninf(std::complex<T>& val, const std::string& token)
+  {
+  if( token.length() >= 5 )
+    {
+    std::stringstream ss( token.substr(1, token.length()-2) );  // strip '(' at the start and ')' at the end
+    
+    std::string token_real;
+    std::string token_imag;
+    
+    std::getline(ss, token_real, ',');
+    std::getline(ss, token_imag);
+    
+    std::stringstream ss_real(token_real);
+    std::stringstream ss_imag(token_imag);
+    
+    T val_real = T(0);
+    T val_imag = T(0);
+    
+    ss_real >> val_real;
+    ss_imag >> val_imag;
+    
+    bool success_real = true;
+    bool success_imag = true;
+    
+    if(ss_real.fail() == true)
+      {
+      success_real = diskio::convert_naninf( val_real, token_real );
+      }
+    
+    if(ss_imag.fail() == true)
+      {
+      success_imag = diskio::convert_naninf( val_imag, token_imag );
+      }
+    
+    val = std::complex<T>(val_real, val_imag);
+    
+    return (success_real && success_imag);
+    }
+  
+  return false;
+  }
+
+
+
+//! Save a matrix as raw text (no header, human readable).
+//! Matrices can be loaded in Matlab and Octave, as long as they don't have complex elements.
+template<typename eT>
+inline
+bool
+diskio::save_raw_ascii(const Mat<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  
+  std::fstream f(tmp_name.c_str(), std::fstream::out);
+  
+  bool save_okay = f.is_open();
+  
+  if(save_okay == true)
+    {
+    save_okay = diskio::save_raw_ascii(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+//! Save a matrix as raw text (no header, human readable).
+//! Matrices can be loaded in Matlab and Octave, as long as they don't have complex elements.
+template<typename eT>
+inline
+bool
+diskio::save_raw_ascii(const Mat<eT>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  uword cell_width;
+  
+  // TODO: need sane values for complex numbers
+  
+  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
+    {
+    f.setf(ios::scientific);
+    f.precision(12);
+    cell_width = 20;
+    }
+  
+  for(uword row=0; row < x.n_rows; ++row)
+    {
+    for(uword col=0; col < x.n_cols; ++col)
+      {
+      f.put(' ');
+      
+      if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
+        {
+        f.width(cell_width);
+        }
+      
+      f << x.at(row,col);
+      }
+      
+    f.put('\n');
+    }
+  
+  return f.good();
+  }
+
+
+
+//! Save a matrix as raw binary (no header)
+template<typename eT>
+inline
+bool
+diskio::save_raw_binary(const Mat<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  
+  std::ofstream f(tmp_name.c_str(), std::fstream::binary);
+  
+  bool save_okay = f.is_open();
+  
+  if(save_okay == true)
+    {
+    save_okay = diskio::save_raw_binary(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+diskio::save_raw_binary(const Mat<eT>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
+  
+  return f.good();
+  }
+
+
+
+//! Save a matrix in text format (human readable),
+//! with a header that indicates the matrix type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::save_arma_ascii(const Mat<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  
+  std::ofstream f(tmp_name.c_str());
+  
+  bool save_okay = f.is_open();
+
+  if(save_okay == true)  
+    {
+    save_okay = diskio::save_arma_ascii(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+//! Save a matrix in text format (human readable),
+//! with a header that indicates the matrix type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::save_arma_ascii(const Mat<eT>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  const ios::fmtflags orig_flags = f.flags();
+  
+  f << diskio::gen_txt_header(x) << '\n';
+  f << x.n_rows << ' ' << x.n_cols << '\n';
+  
+  uword cell_width;
+  
+  // TODO: need sane values for complex numbers
+  
+  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
+    {
+    f.setf(ios::scientific);
+    f.precision(12);
+    cell_width = 20;
+    }
+    
+  for(uword row=0; row < x.n_rows; ++row)
+    {
+    for(uword col=0; col < x.n_cols; ++col)
+      {
+      f.put(' ');
+      
+      if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )        
+        {
+        f.width(cell_width);
+        }
+      
+      f << x.at(row,col);
+      }
+    
+    f.put('\n');
+    }
+  
+  const bool save_okay = f.good();
+  
+  f.flags(orig_flags);
+  
+  return save_okay;
+  }
+
+
+
+//! Save a matrix in CSV text format (human readable)
+template<typename eT>
+inline
+bool
+diskio::save_csv_ascii(const Mat<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  
+  std::ofstream f(tmp_name.c_str());
+  
+  bool save_okay = f.is_open();
+  
+  if(save_okay == true)  
+    {
+    save_okay = diskio::save_csv_ascii(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+//! Save a matrix in CSV text format (human readable)
+template<typename eT>
+inline
+bool
+diskio::save_csv_ascii(const Mat<eT>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  const ios::fmtflags orig_flags = f.flags();
+  
+  // TODO: need sane values for complex numbers
+  
+  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
+    {
+    f.setf(ios::scientific);
+    f.precision(12);
+    }
+  
+  uword x_n_rows = x.n_rows;
+  uword x_n_cols = x.n_cols;
+  
+  for(uword row=0; row < x_n_rows; ++row)
+    {
+    for(uword col=0; col < x_n_cols; ++col)
+      {
+      f << x.at(row,col);
+      
+      if( col < (x_n_cols-1) )
+        {
+        f.put(',');
+        }
+      }
+    
+    f.put('\n');
+    }
+  
+  const bool save_okay = f.good();
+  
+  f.flags(orig_flags);
+  
+  return save_okay;
+  }
+
+
+
+//! Save a matrix in binary format,
+//! with a header that stores the matrix type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::save_arma_binary(const Mat<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  
+  std::ofstream f(tmp_name.c_str(), std::fstream::binary);
+  
+  bool save_okay = f.is_open();
+  
+  if(save_okay == true)
+    {
+    save_okay = diskio::save_arma_binary(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+//! Save a matrix in binary format,
+//! with a header that stores the matrix type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::save_arma_binary(const Mat<eT>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+
+  f << diskio::gen_bin_header(x) << '\n';
+  f << x.n_rows << ' ' << x.n_cols << '\n';
+  
+  f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
+  
+  return f.good();
+  }
+
+
+
+//! Save a matrix as a PGM greyscale image
+template<typename eT>
+inline
+bool
+diskio::save_pgm_binary(const Mat<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  
+  std::fstream f(tmp_name.c_str(), std::fstream::out | std::fstream::binary);
+  
+  bool save_okay = f.is_open();
+  
+  if(save_okay == true)
+    {
+    save_okay = diskio::save_pgm_binary(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+//
+// TODO:
+// add functionality to save the image in a normalised format,
+// i.e. scaled so that every value falls in the [0,255] range.
+
+//! Save a matrix as a PGM greyscale image
+template<typename eT>
+inline
+bool
+diskio::save_pgm_binary(const Mat<eT>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  f << "P5" << '\n';
+  f << x.n_cols << ' ' << x.n_rows << '\n';
+  f << 255 << '\n';
+  
+  const uword n_elem = x.n_rows * x.n_cols;
+  podarray<u8> tmp(n_elem);
+  
+  uword i = 0;
+  
+  for(uword row=0; row < x.n_rows; ++row)
+    {
+    for(uword col=0; col < x.n_cols; ++col)
+      {
+      tmp[i] = u8( x.at(row,col) );  // TODO: add round() ?
+      ++i;
+      }
+    }
+  
+  f.write(reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
+  
+  return f.good();
+  }
+
+
+
+//! Save a matrix as a PGM greyscale image
+template<typename T>
+inline
+bool
+diskio::save_pgm_binary(const Mat< std::complex<T> >& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uchar_mat tmp = conv_to<uchar_mat>::from(x);
+  
+  return diskio::save_pgm_binary(tmp, final_name);
+  }
+
+
+
+//! Save a matrix as a PGM greyscale image
+template<typename T>
+inline
+bool
+diskio::save_pgm_binary(const Mat< std::complex<T> >& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uchar_mat tmp = conv_to<uchar_mat>::from(x);
+  
+  return diskio::save_pgm_binary(tmp, f);
+  }
+
+
+
+//! Save a matrix as part of a HDF5 file
+template<typename eT>
+inline 
+bool 
+diskio::save_hdf5_binary(const Mat<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_HDF5)
+    {
+    #if !defined(ARMA_PRINT_HDF5_ERRORS)
+      {
+      // Disable annoying HDF5 error messages.
+      H5Eset_auto(H5E_DEFAULT, NULL, NULL);
+      }
+    #endif
+
+    bool save_okay = false;
+    
+    const std::string tmp_name = diskio::gen_tmp_name(final_name);
+    
+    // Set up the file according to HDF5's preferences  
+    hid_t file = H5Fcreate(tmp_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+    
+    // We need to create a dataset, datatype, and dataspace
+    hsize_t dims[2];
+    dims[1] = x.n_rows;
+    dims[0] = x.n_cols;
+    
+    hid_t dataspace = H5Screate_simple(2, dims, NULL);   // treat the matrix as a 2d array dataspace
+    hid_t datatype  = hdf5_misc::get_hdf5_type<eT>();
+
+    // If this returned something invalid, well, it's time to crash.
+    arma_check(datatype == -1, "Mat::save(): unknown datatype for HDF5");
+
+    // MATLAB forces the users to specify a name at save time for HDF5; Octave
+    // will use the default of 'dataset' unless otherwise specified, so we will
+    // use that.
+    hid_t dataset = H5Dcreate(file, "dataset", datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+    
+    // H5Dwrite does not make a distinction between row-major and column-major;
+    // it just writes the memory.  MATLAB and Octave store HDF5 matrices as
+    // column-major, though, so we can save ours like that too and not need to
+    // transpose.
+    herr_t status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, x.mem);
+    save_okay = (status >= 0);
+    
+    H5Dclose(dataset);
+    H5Tclose(datatype);
+    H5Sclose(dataspace);
+    H5Fclose(file);
+    
+    if(save_okay == true) { save_okay = diskio::safe_rename(tmp_name, final_name); }
+    
+    return save_okay;
+    }
+  #else
+    {
+    arma_ignore(x);
+    arma_ignore(final_name);
+    
+    arma_stop("Mat::save(): use of HDF5 needs to be enabled");
+    
+    return false;
+    }
+  #endif
+  }
+
+
+
+//! Load a matrix as raw text (no header, human readable).
+//! Can read matrices saved as text in Matlab and Octave.
+//! NOTE: this is much slower than reading a file with a header.
+template<typename eT>
+inline
+bool
+diskio::load_raw_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+
+  std::fstream f;
+  f.open(name.c_str(), std::fstream::in);
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_raw_ascii(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Load a matrix as raw text (no header, human readable).
+//! Can read matrices saved as text in Matlab and Octave.
+//! NOTE: this is much slower than reading a file with a header.
+template<typename eT>
+inline
+bool
+diskio::load_raw_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay = f.good();
+  
+  f.clear();
+  const std::fstream::pos_type pos1 = f.tellg();
+  
+  //
+  // work out the size
+  
+  uword f_n_rows = 0;
+  uword f_n_cols = 0;
+  
+  bool f_n_cols_found = false;
+  
+  std::string line_string;
+  std::string token;
+  
+  std::stringstream line_stream;
+  
+  while( (f.good() == true) && (load_okay == true) )
+    {
+    std::getline(f, line_string);
+    
+    if(line_string.size() == 0)
+      {
+      break;
+      }
+    
+    line_stream.clear();
+    line_stream.str(line_string);
+    
+    uword line_n_cols = 0;
+    
+    while (line_stream >> token)
+      {
+      ++line_n_cols;
+      }
+    
+    if(f_n_cols_found == false)
+      {
+      f_n_cols = line_n_cols;
+      f_n_cols_found = true;
+      }
+    else
+      {
+      if(line_n_cols != f_n_cols)
+        {
+        err_msg = "inconsistent number of columns in ";
+        load_okay = false;
+        }
+      }
+    
+    ++f_n_rows;
+    }
+    
+  if(load_okay == true)
+    {
+    f.clear();
+    f.seekg(pos1);
+    
+    x.set_size(f_n_rows, f_n_cols);
+    
+    std::stringstream ss;
+    
+    for(uword row=0; (row < x.n_rows) && (load_okay == true); ++row)
+      {
+      for(uword col=0; (col < x.n_cols) && (load_okay == true); ++col)
+        {
+        f >> token;
+        
+        ss.clear();
+        ss.str(token);
+        
+        eT val = eT(0);
+        ss >> val;
+        
+        if(ss.fail() == false)
+          {
+          x.at(row,col) = val;
+          }
+        else
+          {
+          const bool success = diskio::convert_naninf( x.at(row,col), token );
+          
+          if(success == false)
+            {
+            load_okay = false;
+            err_msg = "couldn't interpret data in ";
+            }
+          }
+        }
+      }
+    }
+  
+  
+  // an empty file indicates an empty matrix
+  if( (f_n_cols_found == false) && (load_okay == true) )
+    {
+    x.reset();
+    }
+  
+  
+  return load_okay;
+  }
+
+
+
+//! Load a matrix in binary format (no header);
+//! the matrix is assumed to have one column
+template<typename eT>
+inline
+bool
+diskio::load_raw_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::ifstream f;
+  f.open(name.c_str(), std::fstream::binary);
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_raw_binary(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+diskio::load_raw_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(err_msg);
+  
+  f.clear();
+  const std::streampos pos1 = f.tellg();
+  
+  f.clear();
+  f.seekg(0, ios::end);
+
+  f.clear();
+  const std::streampos pos2 = f.tellg();
+  
+  const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
+  
+  f.clear();
+  //f.seekg(0, ios::beg);
+  f.seekg(pos1);
+  
+  x.set_size(N / sizeof(eT), 1);
+  
+  f.clear();
+  f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(N) );
+  
+  return f.good();
+  }
+
+
+
+//! Load a matrix in text format (human readable),
+//! with a header that indicates the matrix type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::load_arma_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::ifstream f(name.c_str());
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_arma_ascii(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Load a matrix in text format (human readable),
+//! with a header that indicates the matrix type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::load_arma_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay = true;
+  
+  std::string f_header;
+  uword f_n_rows;
+  uword f_n_cols;
+  
+  f >> f_header;
+  f >> f_n_rows;
+  f >> f_n_cols;
+  
+  if(f_header == diskio::gen_txt_header(x))
+    {
+    x.zeros(f_n_rows, f_n_cols);
+    
+    std::string       token;
+    std::stringstream ss;
+    
+    for(uword row=0; row < x.n_rows; ++row)
+      {
+      for(uword col=0; col < x.n_cols; ++col)
+        {
+        f >> token;
+        
+        ss.clear();
+        ss.str(token);
+        
+        eT val = eT(0);
+        ss >> val;
+        
+        if(ss.fail() == false)
+          {
+          x.at(row,col) = val;
+          }
+        else
+          {
+          diskio::convert_naninf( x.at(row,col), token );
+          }
+        }
+      }
+    
+    load_okay = f.good();
+    }
+  else
+    {
+    load_okay = false;
+    err_msg = "incorrect header in ";
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Load a matrix in CSV text format (human readable)
+template<typename eT>
+inline
+bool
+diskio::load_csv_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::fstream f;
+  f.open(name.c_str(), std::fstream::in);
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_csv_ascii(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Load a matrix in CSV text format (human readable)
+template<typename eT>
+inline
+bool
+diskio::load_csv_ascii(Mat<eT>& x, std::istream& f, std::string&)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay = f.good();
+  
+  f.clear();
+  const std::fstream::pos_type pos1 = f.tellg();
+  
+  //
+  // work out the size
+  
+  uword f_n_rows = 0;
+  uword f_n_cols = 0;
+  
+  std::string line_string;
+  std::string token;
+  
+  std::stringstream line_stream;
+  
+  while( (f.good() == true) && (load_okay == true) )
+    {
+    std::getline(f, line_string);
+    
+    if(line_string.size() == 0)
+      {
+      break;
+      }
+    
+    line_stream.clear();
+    line_stream.str(line_string);
+    
+    uword line_n_cols = 0;
+    
+    while(line_stream.good() == true)
+      {
+      std::getline(line_stream, token, ',');
+      ++line_n_cols;
+      }
+    
+    if(f_n_cols < line_n_cols)
+      {
+      f_n_cols = line_n_cols;
+      }
+    
+    ++f_n_rows;
+    }
+  
+  f.clear();
+  f.seekg(pos1);
+  
+  x.zeros(f_n_rows, f_n_cols);
+  
+  uword row = 0;
+  
+  std::stringstream ss;
+  
+  while(f.good() == true)
+    {
+    std::getline(f, line_string);
+    
+    if(line_string.size() == 0)
+      {
+      break;
+      }
+    
+    line_stream.clear();
+    line_stream.str(line_string);
+    
+    uword col = 0;
+    
+    while(line_stream.good() == true)
+      {
+      std::getline(line_stream, token, ',');
+      
+      ss.clear();
+      ss.str(token);
+      
+      eT val = eT(0);
+      ss >> val;
+      
+      if(ss.fail() == false)
+        {
+        x.at(row,col) = val;
+        }
+      else
+        {
+        diskio::convert_naninf( x.at(row,col), token );
+        }
+      
+      ++col;
+      }
+    
+    ++row;
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Load a matrix in binary format,
+//! with a header that indicates the matrix type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::load_arma_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::ifstream f;
+  f.open(name.c_str(), std::fstream::binary);
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_arma_binary(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+diskio::load_arma_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay = true;
+  
+  std::string f_header;
+  uword f_n_rows;
+  uword f_n_cols;
+  
+  f >> f_header;
+  f >> f_n_rows;
+  f >> f_n_cols;
+  
+  if(f_header == diskio::gen_bin_header(x))
+    {
+    //f.seekg(1, ios::cur);  // NOTE: this may not be portable, as on a Windows machine a newline could be two characters
+    f.get();
+    
+    x.set_size(f_n_rows,f_n_cols);
+    f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(x.n_elem*sizeof(eT)) );
+    
+    load_okay = f.good();
+    }
+  else
+    {
+    load_okay = false;
+    err_msg = "incorrect header in ";
+    }
+  
+  return load_okay;
+  }
+
+
+
+inline
+void
+diskio::pnm_skip_comments(std::istream& f)
+  {
+  while( isspace(f.peek()) )
+    {
+    while( isspace(f.peek()) )
+      {
+      f.get();
+      }
+  
+    if(f.peek() == '#')
+      {
+      while( (f.peek() != '\r') && (f.peek()!='\n') )
+        {
+        f.get();
+        }
+      }
+    }
+  }
+
+
+
+//! Load a PGM greyscale image as a matrix
+template<typename eT>
+inline
+bool
+diskio::load_pgm_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::fstream f;
+  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_pgm_binary(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Load a PGM greyscale image as a matrix
+template<typename eT>
+inline
+bool
+diskio::load_pgm_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  bool load_okay = true;
+  
+  std::string f_header;
+  f >> f_header;
+  
+  if(f_header == "P5")
+    {
+    uword f_n_rows = 0;
+    uword f_n_cols = 0;
+    int f_maxval = 0;
+  
+    diskio::pnm_skip_comments(f);
+  
+    f >> f_n_cols;
+    diskio::pnm_skip_comments(f);
+  
+    f >> f_n_rows;
+    diskio::pnm_skip_comments(f);
+  
+    f >> f_maxval;
+    f.get();
+    
+    if( (f_maxval > 0) || (f_maxval <= 65535) )
+      {
+      x.set_size(f_n_rows,f_n_cols);
+      
+      if(f_maxval <= 255)
+        {
+        const uword n_elem = f_n_cols*f_n_rows;
+        podarray<u8> tmp(n_elem);
+        
+        f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
+        
+        uword i = 0;
+        
+        //cout << "f_n_cols = " << f_n_cols << endl;
+        //cout << "f_n_rows = " << f_n_rows << endl;
+        
+        
+        for(uword row=0; row < f_n_rows; ++row)
+          {
+          for(uword col=0; col < f_n_cols; ++col)
+            {
+            x.at(row,col) = eT(tmp[i]);
+            ++i;
+            }
+          }
+          
+        }
+      else
+        {
+        const uword n_elem = f_n_cols*f_n_rows;
+        podarray<u16> tmp(n_elem);
+        
+        f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(n_elem*2) );
+        
+        uword i = 0;
+        
+        for(uword row=0; row < f_n_rows; ++row)
+          {
+          for(uword col=0; col < f_n_cols; ++col)
+            {
+            x.at(row,col) = eT(tmp[i]);
+            ++i;
+            }
+          }
+        
+        }
+      
+      }
+    else
+      {
+      load_okay = false;
+      err_msg = "currently no code available to handle loading ";
+      }
+    
+    if(f.good() == false)
+      {
+      load_okay = false;
+      }
+    }
+  else
+    {
+    load_okay = false;
+    err_msg = "unsupported header in ";
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Load a PGM greyscale image as a matrix
+template<typename T>
+inline
+bool
+diskio::load_pgm_binary(Mat< std::complex<T> >& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  uchar_mat tmp;
+  const bool load_okay = diskio::load_pgm_binary(tmp, name, err_msg);
+  
+  x = conv_to< Mat< std::complex<T> > >::from(tmp);
+  
+  return load_okay;
+  }
+
+
+
+//! Load a PGM greyscale image as a matrix
+template<typename T>
+inline
+bool
+diskio::load_pgm_binary(Mat< std::complex<T> >& x, std::istream& is, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  uchar_mat tmp;
+  const bool load_okay = diskio::load_pgm_binary(tmp, is, err_msg);
+  
+  x = conv_to< Mat< std::complex<T> > >::from(tmp);
+  
+  return load_okay;
+  }
+
+
+
+//! Load a HDF5 file as a matrix
+template<typename eT>
+inline
+bool
+diskio::load_hdf5_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_HDF5)
+    {
+
+    // These may be necessary to store the error handler (if we need to).
+    herr_t (*old_func)(hid_t, void*);
+    void *old_client_data;
+
+    #if !defined(ARMA_PRINT_HDF5_ERRORS)
+      {
+      // Save old error handler.
+      H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data);
+
+      // Disable annoying HDF5 error messages.
+      H5Eset_auto(H5E_DEFAULT, NULL, NULL);
+      }
+    #endif
+
+    bool load_okay = false;
+    
+    hid_t fid = H5Fopen(name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
+    
+    if(fid >= 0)
+      {
+      // MATLAB HDF5 dataset names are user-specified;
+      // Octave tends to store the datasets in a group, with the actual dataset being referred to as "value".
+      // So we will search for "dataset" and "value", and if those are not found we will take the first dataset we do find.
+      std::vector<std::string> searchNames;
+      searchNames.push_back("dataset");
+      searchNames.push_back("value");
+      
+      hid_t dataset = hdf5_misc::search_hdf5_file(searchNames, fid, 2, false);
+
+      if(dataset >= 0)
+        {
+        hid_t filespace = H5Dget_space(dataset);
+        
+        // This must be <= 2 due to our search rules.
+        const int ndims = H5Sget_simple_extent_ndims(filespace);
+        
+        hsize_t dims[2];
+        const herr_t query_status = H5Sget_simple_extent_dims(filespace, dims, NULL);
+        
+        // arma_check(query_status < 0, "Mat::load(): cannot get size of HDF5 dataset");
+        if(query_status < 0)
+          {
+          err_msg = "cannot get size of HDF5 dataset in ";
+          
+          H5Sclose(filespace);
+          H5Dclose(dataset);
+          H5Fclose(fid);
+    
+          #if !defined(ARMA_PRINT_HDF5_ERRORS)
+            {
+            // Restore HDF5 error handler.
+            H5Eset_auto(H5E_DEFAULT, old_func, old_client_data);
+            }
+          #endif
+          
+          return false;
+          }
+        
+        if(ndims == 1) { dims[1] = 1; }  // Vector case; fake second dimension (one column).
+        
+        x.set_size(dims[1], dims[0]);
+        
+        // Now we have to see what type is stored to figure out how to load it.
+        hid_t datatype = H5Dget_type(dataset);
+        hid_t mat_type = hdf5_misc::get_hdf5_type<eT>();
+        
+        // If these are the same type, it is simple.
+        if(H5Tequal(datatype, mat_type) > 0)
+          {
+          // Load directly; H5S_ALL used so that we load the entire dataset.
+          hid_t read_status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(x.memptr()));
+          
+          if(read_status >= 0) { load_okay = true; }
+          }
+        else
+          {
+          // Load into another array and convert its type accordingly.
+          hid_t read_status = hdf5_misc::load_and_convert_hdf5(x.memptr(), dataset, datatype, x.n_elem);
+          
+          if(read_status >= 0) { load_okay = true; }
+          }
+        
+        // Now clean up.
+        H5Tclose(datatype);
+        H5Tclose(mat_type);
+        H5Sclose(filespace);
+        }
+      
+      H5Dclose(dataset);
+    
+      H5Fclose(fid);
+
+      if(load_okay == false)
+        {
+        err_msg = "unsupported or incorrect HDF5 data in ";
+        }
+      }
+    else
+      {
+      err_msg = "cannot open file ";
+      }
+
+    #if !defined(ARMA_PRINT_HDF5_ERRORS)
+      {
+      // Restore HDF5 error handler.
+      H5Eset_auto(H5E_DEFAULT, old_func, old_client_data);
+      }
+    #endif
+
+    return load_okay;
+    }
+  #else
+    {
+    arma_ignore(x);
+    arma_ignore(name);
+    arma_ignore(err_msg);
+
+    arma_stop("Mat::load(): use of HDF5 needs to be enabled");
+
+    return false;
+    }
+  #endif
+  }
+
+
+
+//! Try to load a matrix by automatically determining its type
+template<typename eT>
+inline
+bool
+diskio::load_auto_detect(Mat<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_HDF5)
+    // We're currently using the C bindings for the HDF5 library, which don't support C++ streams
+    if( H5Fis_hdf5(name.c_str()) ) { return load_hdf5_binary(x, name, err_msg); }
+  #endif
+
+  std::fstream f;
+  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_auto_detect(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Try to load a matrix by automatically determining its type
+template<typename eT>
+inline
+bool
+diskio::load_auto_detect(Mat<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  static const std::string ARMA_MAT_TXT = "ARMA_MAT_TXT";
+  static const std::string ARMA_MAT_BIN = "ARMA_MAT_BIN";
+  static const std::string           P5 = "P5";
+  
+  podarray<char> raw_header(ARMA_MAT_TXT.length() + 1);
+  
+  std::streampos pos = f.tellg();
+    
+  f.read( raw_header.memptr(), std::streamsize(ARMA_MAT_TXT.length()) );
+  raw_header[ARMA_MAT_TXT.length()] = '\0';
+  
+  f.clear();
+  f.seekg(pos);
+  
+  const std::string header = raw_header.mem;
+  
+  if(ARMA_MAT_TXT == header.substr(0,ARMA_MAT_TXT.length()))
+    {
+    return load_arma_ascii(x, f, err_msg);
+    }
+  else
+  if(ARMA_MAT_BIN == header.substr(0,ARMA_MAT_BIN.length()))
+    {
+    return load_arma_binary(x, f, err_msg);
+    }
+  else
+  if(P5 == header.substr(0,P5.length()))
+    {
+    return load_pgm_binary(x, f, err_msg);
+    }
+  else
+    {
+    const file_type ft = guess_file_type(f);
+    
+    switch(ft)
+      {
+      case csv_ascii:
+        return load_csv_ascii(x, f, err_msg);
+        break;
+      
+      case raw_binary:
+        return load_raw_binary(x, f, err_msg);
+        break;
+        
+      case raw_ascii:
+        return load_raw_ascii(x, f, err_msg);
+        break;
+      
+      default:
+        err_msg = "unknown data in ";
+        return false;
+      }
+    }
+  
+  return false;
+  }
+
+
+
+//
+// sparse matrices
+//
+
+
+
+//! Save a matrix in ASCII coord format
+template<typename eT>
+inline
+bool
+diskio::save_coord_ascii(const SpMat<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+
+  std::ofstream f(tmp_name.c_str());
+
+  bool save_okay = f.is_open();
+
+  if(save_okay == true)
+    {
+    save_okay = diskio::save_coord_ascii(x, f);
+
+    f.flush();
+    f.close();
+
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+
+  return save_okay;
+  }
+
+
+
+//! Save a matrix in ASCII coord format
+template<typename eT>
+inline
+bool
+diskio::save_coord_ascii(const SpMat<eT>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  const ios::fmtflags orig_flags = f.flags();
+  
+  typename SpMat<eT>::const_iterator iter     = x.begin();
+  typename SpMat<eT>::const_iterator iter_end = x.end();
+  
+  for(; iter != iter_end; ++iter)
+    {
+    f.setf(ios::fixed);
+    
+    f << iter.row() << ' ' << iter.col() << ' ';
+    
+    if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
+      {
+      f.setf(ios::scientific);
+      f.precision(12);
+      }
+    
+    f << (*iter) << '\n';
+    }
+  
+  
+  // make sure it's possible to figure out the matrix size later
+  if( (x.n_rows > 0) && (x.n_cols > 0) )
+    {
+    const uword max_row = (x.n_rows > 0) ? x.n_rows-1 : 0;
+    const uword max_col = (x.n_cols > 0) ? x.n_cols-1 : 0;
+    
+    if( x.at(max_row, max_col) == eT(0) )
+      {
+      f.setf(ios::fixed);
+      
+      f << max_row << ' ' << max_col << " 0\n";
+      }
+    }
+  
+  const bool save_okay = f.good();
+  
+  f.flags(orig_flags);
+  
+  return save_okay;
+  }
+
+
+
+//! Save a matrix in ASCII coord format (complex numbers)
+template<typename T>
+inline
+bool
+diskio::save_coord_ascii(const SpMat< std::complex<T> >& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  const ios::fmtflags orig_flags = f.flags();
+  
+  typedef typename std::complex<T> eT;
+  
+  typename SpMat<eT>::const_iterator iter     = x.begin();
+  typename SpMat<eT>::const_iterator iter_end = x.end();
+  
+  for(; iter != iter_end; ++iter)
+    {
+    f.setf(ios::fixed);
+    
+    f << iter.row() << ' ' << iter.col() << ' ';
+    
+    if( (is_float<T>::value == true) || (is_double<T>::value == true) )
+      {
+      f.setf(ios::scientific);
+      f.precision(12);
+      }
+    
+    const eT val = (*iter);
+    
+    f << val.real() << ' ' << val.imag() << '\n';
+    }
+  
+  // make sure it's possible to figure out the matrix size later
+  if( (x.n_rows > 0) && (x.n_cols > 0) )
+    {
+    const uword max_row = (x.n_rows > 0) ? x.n_rows-1 : 0;
+    const uword max_col = (x.n_cols > 0) ? x.n_cols-1 : 0;
+    
+    if( x.at(max_row, max_col) == eT(0) )
+      {
+      f.setf(ios::fixed);
+      
+      f << max_row << ' ' << max_col << " 0 0\n";
+      }
+    }
+  
+  const bool save_okay = f.good();
+  
+  f.flags(orig_flags);
+  
+  return save_okay;
+  }
+
+
+
+//! Save a matrix in binary format,
+//! with a header that stores the matrix type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::save_arma_binary(const SpMat<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+
+  std::ofstream f(tmp_name.c_str(), std::fstream::binary);
+
+  bool save_okay = f.is_open();
+
+  if(save_okay == true)
+    {
+    save_okay = diskio::save_arma_binary(x, f);
+
+    f.flush();
+    f.close();
+
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+
+  return save_okay;
+  }
+
+
+
+//! Save a matrix in binary format,
+//! with a header that stores the matrix type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::save_arma_binary(const SpMat<eT>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  f << diskio::gen_bin_header(x) << '\n';
+  f << x.n_rows << ' ' << x.n_cols << ' ' << x.n_nonzero << '\n';
+  
+  f.write( reinterpret_cast<const char*>(x.values),      std::streamsize(x.n_nonzero*sizeof(eT))     );
+  f.write( reinterpret_cast<const char*>(x.row_indices), std::streamsize(x.n_nonzero*sizeof(uword))  );
+  f.write( reinterpret_cast<const char*>(x.col_ptrs),    std::streamsize((x.n_cols+1)*sizeof(uword)) );
+  
+  return f.good();
+  }
+
+
+
+template<typename eT>
+inline
+bool
+diskio::load_coord_ascii(SpMat<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::fstream f;
+  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_coord_ascii(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+diskio::load_coord_ascii(SpMat<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  bool load_okay = f.good();
+  
+  f.clear();
+  const std::fstream::pos_type pos1 = f.tellg();
+  
+  //
+  // work out the size
+  
+  uword f_n_rows = 0;
+  uword f_n_cols = 0;
+  uword f_n_nz   = 0;
+  
+  bool size_found = false;
+  
+  std::string       line_string;
+  std::string       token;
+  
+  std::stringstream line_stream;
+  std::stringstream ss;
+  
+  uword last_line_row = 0;
+  uword last_line_col = 0;
+  
+  bool first_line   = true;
+  bool weird_format = false;
+  
+  
+  while( (f.good() == true) && (load_okay == true) )
+    {
+    std::getline(f, line_string);
+    
+    if(line_string.size() == 0)
+      {
+      break;
+      }
+    
+    line_stream.clear();
+    line_stream.str(line_string);
+    
+    uword line_row = 0;
+    uword line_col = 0;
+    
+    // a valid line in co-ord format has at least 2 entries
+    
+    line_stream >> line_row;
+    
+    if(line_stream.good() == false)
+      {
+      load_okay = false;
+      break;
+      }
+    
+    line_stream >> line_col;
+    
+    size_found = true;
+    
+    if(f_n_rows < line_row)  f_n_rows = line_row;
+    if(f_n_cols < line_col)  f_n_cols = line_col;
+    
+    if(first_line == true)
+      {
+      first_line = false;
+      }
+    else
+      {
+      if( (line_col < last_line_col) || ((line_row <= last_line_row) && (line_col <= last_line_col)) )
+        {
+        weird_format = true;
+        }
+      }
+    
+    last_line_row = line_row;
+    last_line_col = line_col;
+    
+    
+    if(line_stream.good() == true)
+      {
+      eT final_val = eT(0);
+      
+      line_stream >> token;
+      
+      if(line_stream.fail() == false)
+        {
+        eT val = eT(0);
+        
+        ss.clear();
+        ss.str(token);
+        
+        ss >> val;
+        
+        if(ss.fail() == false)
+          {
+          final_val = val;
+          }
+        else
+          {
+          val = eT(0);
+          
+          const bool success = diskio::convert_naninf( val, token );
+          
+          if(success == true)
+            {
+            final_val = val;
+            }
+          }
+        }
+      
+      if(final_val != eT(0))
+        {
+        ++f_n_nz;
+        }
+      }
+    }
+  
+  
+  if(size_found == true)
+    {
+    // take into account that indices start at 0
+    f_n_rows++;
+    f_n_cols++;
+    }
+  
+  
+  if(load_okay == true)
+    {
+    f.clear();
+    f.seekg(pos1);
+    
+    x.set_size(f_n_rows, f_n_cols);
+    
+    if(weird_format == false)
+      {
+      x.mem_resize(f_n_nz);
+      }
+    
+    uword pos = 0;
+    
+    while(f.good() == true)
+      {
+      std::getline(f, line_string);
+      
+      if(line_string.size() == 0)
+        {
+        break;
+        }
+      
+      line_stream.clear();
+      line_stream.str(line_string);
+      
+      uword line_row = 0;
+      uword line_col = 0;
+      
+      line_stream >> line_row;
+      line_stream >> line_col;
+      
+      eT final_val = eT(0);
+      
+      line_stream >> token;
+      
+      if(line_stream.fail() == false)
+        {
+        eT val = eT(0);
+        
+        ss.clear();
+        ss.str(token);
+        
+        ss >> val;
+        
+        if(ss.fail() == false)
+          {
+          final_val = val;
+          }
+        else
+          {
+          val = eT(0);
+          
+          const bool success = diskio::convert_naninf( val, token );
+          
+          if(success == true)
+            {
+            final_val = val;
+            }
+          }
+        }
+      
+      
+      if(final_val != eT(0))
+        {
+        if(weird_format == false)
+          {
+          access::rw(x.row_indices[pos]) = line_row;
+          access::rw(x.values[pos])      = final_val;
+          ++access::rw(x.col_ptrs[line_col + 1]);
+          
+          ++pos;
+          }
+        else
+          {
+          x.at(line_row,line_col) = final_val;
+          }
+        }
+      }
+    
+    if(weird_format == false)
+      {
+      for(uword c = 1; c <= f_n_cols; ++c)
+        {
+        access::rw(x.col_ptrs[c]) += x.col_ptrs[c - 1];
+        }
+      }
+    }
+  
+  return load_okay;
+  }
+
+
+
+template<typename T>
+inline
+bool
+diskio::load_coord_ascii(SpMat< std::complex<T> >& x, std::istream& f, std::string& err_msg)
+  {
+  bool load_okay = f.good();
+  
+  f.clear();
+  const std::fstream::pos_type pos1 = f.tellg();
+  
+  //
+  // work out the size
+  
+  uword f_n_rows = 0;
+  uword f_n_cols = 0;
+  uword f_n_nz   = 0;
+  
+  bool size_found = false;
+  
+  std::string line_string;
+  std::string token_real;
+  std::string token_imag;
+  
+  std::stringstream line_stream;
+  std::stringstream ss;
+  
+  uword last_line_row = 0;
+  uword last_line_col = 0;
+  
+  bool first_line   = true;
+  bool weird_format = false;
+  
+  while( (f.good() == true) && (load_okay == true) )
+    {
+    std::getline(f, line_string);
+    
+    if(line_string.size() == 0)
+      {
+      break;
+      }
+    
+    line_stream.clear();
+    line_stream.str(line_string);
+    
+    uword line_row = 0;
+    uword line_col = 0;
+    
+    // a valid line in co-ord format has at least 2 entries
+    
+    line_stream >> line_row;
+    
+    if(line_stream.good() == false)
+      {
+      load_okay = false;
+      break;
+      }
+    
+    line_stream >> line_col;
+    
+    size_found = true;
+    
+    if(f_n_rows < line_row)  f_n_rows = line_row;
+    if(f_n_cols < line_col)  f_n_cols = line_col;
+    
+    
+    if(first_line == true)
+      {
+      first_line = false;
+      }
+    else
+      {
+      if( (line_col < last_line_col) || ((line_row <= last_line_row) && (line_col <= last_line_col)) )
+        {
+        weird_format = true;
+        }
+      }
+    
+    last_line_row = line_row;
+    last_line_col = line_col;
+    
+    
+    if(line_stream.good() == true)
+      {
+      T final_val_real = T(0);
+      T final_val_imag = T(0);
+      
+      
+      line_stream >> token_real;
+      
+      if(line_stream.fail() == false)
+        {
+        T val_real = T(0);
+        
+        ss.clear();
+        ss.str(token_real);
+        
+        ss >> val_real;
+        
+        if(ss.fail() == false)
+          {
+          final_val_real = val_real;
+          }
+        else
+          {
+          val_real = T(0);
+          
+          const bool success = diskio::convert_naninf( val_real, token_real );
+          
+          if(success == true)
+            {
+            final_val_real = val_real;
+            }
+          }
+        }
+      
+      
+      line_stream >> token_imag;
+      
+      if(line_stream.fail() == false)
+        {
+        T val_imag = T(0);
+        
+        ss.clear();
+        ss.str(token_imag);
+        
+        ss >> val_imag;
+        
+        if(ss.fail() == false)
+          {
+          final_val_imag = val_imag;
+          }
+        else
+          {
+          val_imag = T(0);
+          
+          const bool success = diskio::convert_naninf( val_imag, token_imag );
+          
+          if(success == true)
+            {
+            final_val_imag = val_imag;
+            }
+          }
+        }
+      
+      
+      if( (final_val_real != T(0)) || (final_val_imag != T(0)) )
+        {
+        ++f_n_nz;
+        }
+      }
+    }
+  
+  
+  if(size_found == true)
+    {
+    // take into account that indices start at 0
+    f_n_rows++;
+    f_n_cols++;
+    }
+  
+  
+  if(load_okay == true)
+    {
+    f.clear();
+    f.seekg(pos1);
+    
+    x.set_size(f_n_rows, f_n_cols);
+    
+    if(weird_format == false)
+      {
+      x.mem_resize(f_n_nz);
+      }
+    
+    uword pos = 0;
+    
+    while(f.good() == true)
+      {
+      std::getline(f, line_string);
+      
+      if(line_string.size() == 0)
+        {
+        break;
+        }
+      
+      line_stream.clear();
+      line_stream.str(line_string);
+      
+      uword line_row = 0;
+      uword line_col = 0;
+      
+      line_stream >> line_row;
+      line_stream >> line_col;
+      
+      T final_val_real = T(0);
+      T final_val_imag = T(0);
+      
+      
+      line_stream >> token_real;
+      
+      if(line_stream.fail() == false)
+        {
+        T val_real = T(0);
+        
+        ss.clear();
+        ss.str(token_real);
+        
+        ss >> val_real;
+        
+        if(ss.fail() == false)
+          {
+          final_val_real = val_real;
+          }
+        else
+          {
+          val_real = T(0);
+          
+          const bool success = diskio::convert_naninf( val_real, token_real );
+          
+          if(success == true)
+            {
+            final_val_real = val_real;
+            }
+          }
+        }
+      
+      
+      line_stream >> token_imag;
+      
+      if(line_stream.fail() == false)
+        {
+        T val_imag = T(0);
+        
+        ss.clear();
+        ss.str(token_imag);
+        
+        ss >> val_imag;
+        
+        if(ss.fail() == false)
+          {
+          final_val_imag = val_imag;
+          }
+        else
+          {
+          val_imag = T(0);
+          
+          const bool success = diskio::convert_naninf( val_imag, token_imag );
+          
+          if(success == true)
+            {
+            final_val_imag = val_imag;
+            }
+          }
+        }
+      
+      
+      if( (final_val_real != T(0)) || (final_val_imag != T(0)) )
+        {
+        if(weird_format == false)
+          {
+          access::rw(x.row_indices[pos]) = line_row;
+          access::rw(x.values[pos])      = std::complex<T>(final_val_real, final_val_imag);
+          ++access::rw(x.col_ptrs[line_col + 1]);
+          
+          ++pos;
+          }
+        else
+          {
+          x.at(line_row,line_col) = std::complex<T>(final_val_real, final_val_imag);
+          }
+        }
+      }
+    
+    
+    if(weird_format == false)
+      {
+      for(uword c = 1; c <= f_n_cols; ++c)
+        {
+        access::rw(x.col_ptrs[c]) += x.col_ptrs[c - 1];
+        }
+      }
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Load a matrix in binary format,
+//! with a header that indicates the matrix type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::load_arma_binary(SpMat<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+
+  std::ifstream f;
+  f.open(name.c_str(), std::fstream::binary);
+
+  bool load_okay = f.is_open();
+
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_arma_binary(x, f, err_msg);
+    f.close();
+    }
+
+  return load_okay;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+diskio::load_arma_binary(SpMat<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay = true;
+  
+  std::string f_header;
+  
+  f >> f_header;
+  
+  if(f_header == diskio::gen_bin_header(x))
+    {
+    uword f_n_rows;
+    uword f_n_cols;
+    uword f_n_nz;
+    
+    f >> f_n_rows;
+    f >> f_n_cols;
+    f >> f_n_nz;
+    
+    //f.seekg(1, ios::cur);  // NOTE: this may not be portable, as on a Windows machine a newline could be two characters
+    f.get();
+    
+    x.set_size(f_n_rows, f_n_cols);
+    
+    x.mem_resize(f_n_nz);
+    
+    f.read( reinterpret_cast<char*>(access::rwp(x.values)),      std::streamsize(x.n_nonzero*sizeof(eT))     );
+    f.read( reinterpret_cast<char*>(access::rwp(x.row_indices)), std::streamsize(x.n_nonzero*sizeof(uword))  );
+    f.read( reinterpret_cast<char*>(access::rwp(x.col_ptrs)),    std::streamsize((x.n_cols+1)*sizeof(uword)) );
+    
+    load_okay = f.good();
+    }
+  else
+    {
+    load_okay = false;
+    err_msg = "incorrect header in ";
+    }
+
+  return load_okay;
+  }
+
+
+
+// cubes
+
+
+
+//! Save a cube as raw text (no header, human readable).
+template<typename eT>
+inline
+bool
+diskio::save_raw_ascii(const Cube<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  
+  std::fstream f(tmp_name.c_str(), std::fstream::out);
+  
+  bool save_okay = f.is_open();
+  
+  if(save_okay == true)
+    {
+    save_okay = save_raw_ascii(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+//! Save a cube as raw text (no header, human readable).
+template<typename eT>
+inline
+bool
+diskio::save_raw_ascii(const Cube<eT>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  uword cell_width;
+  
+  // TODO: need sane values for complex numbers
+  
+  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
+    {
+    f.setf(ios::scientific);
+    f.precision(12);
+    cell_width = 20;
+    }
+  
+  for(uword slice=0; slice < x.n_slices; ++slice)
+    {
+    for(uword row=0; row < x.n_rows; ++row)
+      {
+      for(uword col=0; col < x.n_cols; ++col)
+        {
+        f.put(' ');
+        
+        if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
+          {
+          f.width(cell_width);
+          }
+        
+        f << x.at(row,col,slice);
+        }
+        
+      f.put('\n');
+      }
+    }
+  
+  return f.good();
+  }
+
+
+
+//! Save a cube as raw binary (no header)
+template<typename eT>
+inline
+bool
+diskio::save_raw_binary(const Cube<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  
+  std::ofstream f(tmp_name.c_str(), std::fstream::binary);
+  
+  bool save_okay = f.is_open();
+  
+  if(save_okay == true)
+    {
+    save_okay = diskio::save_raw_binary(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+diskio::save_raw_binary(const Cube<eT>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
+  
+  return f.good();
+  }
+
+
+
+//! Save a cube in text format (human readable),
+//! with a header that indicates the cube type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::save_arma_ascii(const Cube<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  
+  std::ofstream f(tmp_name.c_str());
+  
+  bool save_okay = f.is_open();
+  
+  if(save_okay == true)
+    {
+    save_okay = diskio::save_arma_ascii(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+//! Save a cube in text format (human readable),
+//! with a header that indicates the cube type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::save_arma_ascii(const Cube<eT>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  const ios::fmtflags orig_flags = f.flags();
+  
+  f << diskio::gen_txt_header(x) << '\n';
+  f << x.n_rows << ' ' << x.n_cols << ' ' << x.n_slices << '\n';
+  
+  uword cell_width;
+  
+  // TODO: need sane values for complex numbers
+  
+  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
+    {
+    f.setf(ios::scientific);
+    f.precision(12);
+    cell_width = 20;
+    }
+    
+  for(uword slice=0; slice < x.n_slices; ++slice)
+    {
+    for(uword row=0; row < x.n_rows; ++row)
+      {
+      for(uword col=0; col < x.n_cols; ++col)
+        {
+        f.put(' ');
+        
+        if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )        
+          {
+          f.width(cell_width);
+          }
+        
+        f << x.at(row,col,slice);
+        }
+      
+      f.put('\n');
+      }
+    }
+  
+  const bool save_okay = f.good();
+  
+  f.flags(orig_flags);
+  
+  return save_okay;
+  }
+
+
+
+//! Save a cube in binary format,
+//! with a header that stores the cube type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::save_arma_binary(const Cube<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  
+  std::ofstream f(tmp_name.c_str(), std::fstream::binary);
+  
+  bool save_okay = f.is_open();
+  
+  if(save_okay == true)
+    {
+    save_okay = diskio::save_arma_binary(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+//! Save a cube in binary format,
+//! with a header that stores the cube type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::save_arma_binary(const Cube<eT>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  f << diskio::gen_bin_header(x) << '\n';
+  f << x.n_rows << ' ' << x.n_cols << ' ' << x.n_slices << '\n';
+  
+  f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
+  
+  return f.good();
+  }
+
+
+
+//! Save a cube as part of a HDF5 file
+template<typename eT>
+inline
+bool
+diskio::save_hdf5_binary(const Cube<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+
+  #if defined(ARMA_USE_HDF5)
+    {
+    #if !defined(ARMA_PRINT_HDF5_ERRORS)
+      {
+      // Disable annoying HDF5 error messages.
+      H5Eset_auto(H5E_DEFAULT, NULL, NULL);
+      }
+    #endif
+
+    bool save_okay = false;
+
+    const std::string tmp_name = diskio::gen_tmp_name(final_name);
+
+    // Set up the file according to HDF5's preferences
+    hid_t file = H5Fcreate(tmp_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+
+    // We need to create a dataset, datatype, and dataspace
+    hsize_t dims[3];
+    dims[2] = x.n_rows;
+    dims[1] = x.n_cols;
+    dims[0] = x.n_slices;
+
+    hid_t dataspace = H5Screate_simple(3, dims, NULL);   // treat the cube as a 3d array dataspace
+    hid_t datatype  = hdf5_misc::get_hdf5_type<eT>();
+
+    // If this returned something invalid, well, it's time to crash.
+    arma_check(datatype == -1, "Cube::save(): unknown datatype for HDF5");
+
+    // MATLAB forces the users to specify a name at save time for HDF5; Octave
+    // will use the default of 'dataset' unless otherwise specified, so we will
+    // use that.
+    hid_t dataset = H5Dcreate(file, "dataset", datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+
+    herr_t status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, x.mem);
+    save_okay = (status >= 0);
+
+    H5Dclose(dataset);
+    H5Tclose(datatype);
+    H5Sclose(dataspace);
+    H5Fclose(file);
+
+    if(save_okay == true) { save_okay = diskio::safe_rename(tmp_name, final_name); }
+
+    return save_okay;
+    }
+  #else
+    {
+    arma_ignore(x);
+    arma_ignore(final_name);
+
+    arma_stop("Cube::save(): use of HDF5 needs to be enabled");
+
+    return false;
+    }
+  #endif
+  }
+
+
+
+//! Load a cube as raw text (no header, human readable).
+//! NOTE: this is much slower than reading a file with a header.
+template<typename eT>
+inline
+bool
+diskio::load_raw_ascii(Cube<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT> tmp;
+  const bool load_okay = diskio::load_raw_ascii(tmp, name, err_msg);
+  
+  if(load_okay == true)
+    {
+    if(tmp.is_empty() == false)
+      {
+      x.set_size(tmp.n_rows, tmp.n_cols, 1);
+      
+      x.slice(0) = tmp;
+      }
+    else
+      {
+      x.reset();
+      }
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Load a cube as raw text (no header, human readable).
+//! NOTE: this is much slower than reading a file with a header.
+template<typename eT>
+inline
+bool
+diskio::load_raw_ascii(Cube<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT> tmp;
+  const bool load_okay = diskio::load_raw_ascii(tmp, f, err_msg);
+  
+  if(load_okay == true)
+    {
+    if(tmp.is_empty() == false)
+      {
+      x.set_size(tmp.n_rows, tmp.n_cols, 1);
+      
+      x.slice(0) = tmp;
+      }
+    else
+      {
+      x.reset();
+      }
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Load a cube in binary format (no header);
+//! the cube is assumed to have one slice with one column
+template<typename eT>
+inline
+bool
+diskio::load_raw_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::ifstream f;
+  f.open(name.c_str(), std::fstream::binary);
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_raw_binary(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+diskio::load_raw_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(err_msg);
+  
+  f.clear();
+  const std::streampos pos1 = f.tellg();
+  
+  f.clear();
+  f.seekg(0, ios::end);
+  
+  f.clear();
+  const std::streampos pos2 = f.tellg();
+  
+  const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
+  
+  f.clear();
+  //f.seekg(0, ios::beg);
+  f.seekg(pos1);
+  
+  x.set_size(N / sizeof(eT), 1, 1);
+  
+  f.clear();
+  f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(N) );
+  
+  return f.good();
+  }
+
+
+
+//! Load a cube in text format (human readable),
+//! with a header that indicates the cube type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::load_arma_ascii(Cube<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::ifstream f(name.c_str());
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_arma_ascii(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+  
+
+
+//! Load a cube in text format (human readable),
+//! with a header that indicates the cube type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::load_arma_ascii(Cube<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay = true;
+  
+  std::string f_header;
+  uword f_n_rows;
+  uword f_n_cols;
+  uword f_n_slices;
+  
+  f >> f_header;
+  f >> f_n_rows;
+  f >> f_n_cols;
+  f >> f_n_slices;
+  
+  if(f_header == diskio::gen_txt_header(x))
+    {
+    x.set_size(f_n_rows, f_n_cols, f_n_slices);
+
+    for(uword slice=0; slice < x.n_slices; ++slice)
+      {
+      for(uword row=0; row < x.n_rows; ++row)
+        {
+        for(uword col=0; col < x.n_cols; ++col)
+          {
+          f >> x.at(row,col,slice);
+          }
+        }
+      }
+    
+    load_okay = f.good();
+    }
+  else
+    {
+    load_okay = false;
+    err_msg = "incorrect header in ";
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Load a cube in binary format,
+//! with a header that indicates the cube type as well as its dimensions
+template<typename eT>
+inline
+bool
+diskio::load_arma_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::ifstream f;
+  f.open(name.c_str(), std::fstream::binary);
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_arma_binary(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+diskio::load_arma_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay = true;
+  
+  std::string f_header;
+  uword f_n_rows;
+  uword f_n_cols;
+  uword f_n_slices;
+  
+  f >> f_header;
+  f >> f_n_rows;
+  f >> f_n_cols;
+  f >> f_n_slices;
+  
+  if(f_header == diskio::gen_bin_header(x))
+    {
+    //f.seekg(1, ios::cur);  // NOTE: this may not be portable, as on a Windows machine a newline could be two characters
+    f.get();
+    
+    x.set_size(f_n_rows, f_n_cols, f_n_slices);
+    f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(x.n_elem*sizeof(eT)) );
+    
+    load_okay = f.good();
+    }
+  else
+    {
+    load_okay = false;
+    err_msg = "incorrect header in ";
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Load a HDF5 file as a cube
+template<typename eT>
+inline
+bool
+diskio::load_hdf5_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+
+  #if defined(ARMA_USE_HDF5)
+    {
+
+    // These may be necessary to store the error handler (if we need to).
+    herr_t (*old_func)(hid_t, void*);
+    void *old_client_data;
+
+    #if !defined(ARMA_PRINT_HDF5_ERRORS)
+      {
+      // Save old error handler.
+      H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data);
+
+      // Disable annoying HDF5 error messages.
+      H5Eset_auto(H5E_DEFAULT, NULL, NULL);
+      }
+    #endif
+
+    bool load_okay = false;
+
+    hid_t fid = H5Fopen(name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
+
+    if(fid >= 0)
+      {
+      // MATLAB HDF5 dataset names are user-specified;
+      // Octave tends to store the datasets in a group, with the actual dataset being referred to as "value".
+      // So we will search for "dataset" and "value", and if those are not found we will take the first dataset we do find.
+      std::vector<std::string> searchNames;
+      searchNames.push_back("dataset");
+      searchNames.push_back("value");
+
+      hid_t dataset = hdf5_misc::search_hdf5_file(searchNames, fid, 3, false);
+
+      if(dataset >= 0)
+        {
+        hid_t filespace = H5Dget_space(dataset);
+
+        // This must be <= 3 due to our search rules.
+        const int ndims = H5Sget_simple_extent_ndims(filespace);
+
+        hsize_t dims[3];
+        const herr_t query_status = H5Sget_simple_extent_dims(filespace, dims, NULL);
+
+        // arma_check(query_status < 0, "Cube::load(): cannot get size of HDF5 dataset");
+        if(query_status < 0)
+          {
+          err_msg = "cannot get size of HDF5 dataset in ";
+
+          H5Sclose(filespace);
+          H5Dclose(dataset);
+          H5Fclose(fid);
+
+          #if !defined(ARMA_PRINT_HDF5_ERRORS)
+            {
+            // Restore HDF5 error handler.
+            H5Eset_auto(H5E_DEFAULT, old_func, old_client_data);
+            }
+          #endif
+
+          return false;
+          }
+
+        if (ndims == 1) { dims[1] = 1; dims[2] = 1; }  // Vector case; one row/colum, several slices
+        if (ndims == 2) { dims[2] = 1; } // Matrix case; one column, several rows/slices
+
+        x.set_size(dims[2], dims[1], dims[0]);
+
+        // Now we have to see what type is stored to figure out how to load it.
+        hid_t datatype = H5Dget_type(dataset);
+        hid_t mat_type = hdf5_misc::get_hdf5_type<eT>();
+
+        // If these are the same type, it is simple.
+        if(H5Tequal(datatype, mat_type) > 0)
+          {
+          // Load directly; H5S_ALL used so that we load the entire dataset.
+          hid_t read_status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(x.memptr()));
+
+          if(read_status >= 0) { load_okay = true; }
+          }
+        else
+          {
+          // Load into another array and convert its type accordingly.
+          hid_t read_status = hdf5_misc::load_and_convert_hdf5(x.memptr(), dataset, datatype, x.n_elem);
+
+          if(read_status >= 0) { load_okay = true; }
+          }
+
+        // Now clean up.
+        H5Tclose(datatype);
+        H5Tclose(mat_type);
+        H5Sclose(filespace);
+        }
+
+      H5Dclose(dataset);
+
+      H5Fclose(fid);
+
+      if(load_okay == false)
+        {
+        err_msg = "unsupported or incorrect HDF5 data in ";
+        }
+      }
+    else
+      {
+      err_msg = "cannot open file ";
+      }
+
+    #if !defined(ARMA_PRINT_HDF5_ERRORS)
+      {
+      // Restore HDF5 error handler.
+      H5Eset_auto(H5E_DEFAULT, old_func, old_client_data);
+      }
+    #endif
+
+    return load_okay;
+    }
+  #else
+    {
+    arma_ignore(x);
+    arma_ignore(name);
+    arma_ignore(err_msg);
+
+    arma_stop("Cube::load(): use of HDF5 needs to be enabled");
+
+    return false;
+    }
+  #endif
+  }
+
+
+
+//! Try to load a cube by automatically determining its type
+template<typename eT>
+inline
+bool
+diskio::load_auto_detect(Cube<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_HDF5)
+    // We're currently using the C bindings for the HDF5 library, which don't support C++ streams
+    if( H5Fis_hdf5(name.c_str()) ) { return load_hdf5_binary(x, name, err_msg); }
+  #endif
+
+  std::fstream f;
+  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_auto_detect(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Try to load a cube by automatically determining its type
+template<typename eT>
+inline
+bool
+diskio::load_auto_detect(Cube<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  static const std::string ARMA_CUB_TXT = "ARMA_CUB_TXT";
+  static const std::string ARMA_CUB_BIN = "ARMA_CUB_BIN";
+  static const std::string           P6 = "P6";
+  
+  podarray<char> raw_header(ARMA_CUB_TXT.length() + 1);
+  
+  std::streampos pos = f.tellg();
+  
+  f.read( raw_header.memptr(), std::streamsize(ARMA_CUB_TXT.length()) );
+  raw_header[ARMA_CUB_TXT.length()] = '\0';
+  
+  f.clear();
+  f.seekg(pos);
+  
+  const std::string header = raw_header.mem;
+  
+  if(ARMA_CUB_TXT == header.substr(0, ARMA_CUB_TXT.length()))
+    {
+    return load_arma_ascii(x, f, err_msg);
+    }
+  else
+  if(ARMA_CUB_BIN == header.substr(0, ARMA_CUB_BIN.length()))
+    {
+    return load_arma_binary(x, f, err_msg);
+    }
+  else
+  if(P6 == header.substr(0, P6.length()))
+    {
+    return load_ppm_binary(x, f, err_msg);
+    }
+  else
+    {
+    const file_type ft = guess_file_type(f);
+    
+    switch(ft)
+      {
+      // case csv_ascii:
+      //   return load_csv_ascii(x, f, err_msg);
+      //   break;
+      
+      case raw_binary:
+        return load_raw_binary(x, f, err_msg);
+        break;
+        
+      case raw_ascii:
+        return load_raw_ascii(x, f, err_msg);
+        break;
+        
+      default:
+        err_msg = "unknown data in ";
+        return false;
+      }
+    }
+  
+  return false;
+  }
+
+
+
+
+
+// fields
+
+
+
+template<typename T1>
+inline
+bool
+diskio::save_arma_binary(const field<T1>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  
+  std::ofstream f( tmp_name.c_str(), std::fstream::binary );
+  
+  bool save_okay = f.is_open();
+  
+  if(save_okay == true)
+    {
+    save_okay = diskio::save_arma_binary(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+template<typename T1>
+inline
+bool
+diskio::save_arma_binary(const field<T1>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( (is_Mat<T1>::value == false) && (is_Cube<T1>::value == false) ));
+  
+  f << "ARMA_FLD_BIN" << '\n';
+  f << x.n_rows << '\n';
+  f << x.n_cols << '\n';
+  
+  bool save_okay = true;
+  
+  for(uword i=0; i<x.n_elem; ++i)
+    {
+    save_okay = diskio::save_arma_binary(x[i], f);
+    
+    if(save_okay == false)
+      {
+      break;
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+template<typename T1>
+inline
+bool
+diskio::load_arma_binary(field<T1>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::ifstream f( name.c_str(), std::fstream::binary );
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_arma_binary(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+template<typename T1>
+inline
+bool
+diskio::load_arma_binary(field<T1>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( (is_Mat<T1>::value == false) && (is_Cube<T1>::value == false) ));
+  
+  bool load_okay = true;
+  
+  std::string f_type;
+  f >> f_type;
+  
+  if(f_type != "ARMA_FLD_BIN")
+    {
+    load_okay = false;
+    err_msg = "unsupported field type in ";
+    }
+  else
+    {
+    uword f_n_rows;
+    uword f_n_cols;
+  
+    f >> f_n_rows;
+    f >> f_n_cols;
+    
+    x.set_size(f_n_rows, f_n_cols);
+    
+    f.get();      
+    
+    for(uword i=0; i<x.n_elem; ++i)
+      {
+      load_okay = diskio::load_arma_binary(x[i], f, err_msg);
+      
+      if(load_okay == false)
+        {
+        break;
+        }
+      }
+    }
+  
+  return load_okay;
+  }
+
+
+
+inline
+bool
+diskio::save_std_string(const field<std::string>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  
+  std::ofstream f( tmp_name.c_str(), std::fstream::binary );
+  
+  bool save_okay = f.is_open();
+  
+  if(save_okay == true)
+    {
+    save_okay = diskio::save_std_string(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+inline
+bool
+diskio::save_std_string(const field<std::string>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  for(uword row=0; row<x.n_rows; ++row)
+  for(uword col=0; col<x.n_cols; ++col)
+    {
+    f << x.at(row,col);
+    
+    if(col < x.n_cols-1)
+      {
+      f << ' ';
+      }
+    else
+      {
+      f << '\n';
+      }
+    }
+  
+  return f.good();
+  }
+
+
+
+inline
+bool
+diskio::load_std_string(field<std::string>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::ifstream f( name.c_str() );
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_std_string(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+inline
+bool
+diskio::load_std_string(field<std::string>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay = true;
+  
+  //
+  // work out the size
+  
+  uword f_n_rows = 0;
+  uword f_n_cols = 0;
+  
+  bool f_n_cols_found = false;
+  
+  std::string line_string;
+  std::string token;
+  
+  while( (f.good() == true) && (load_okay == true) )
+    {
+    std::getline(f, line_string);
+    if(line_string.size() == 0)
+      break;
+    
+    std::stringstream line_stream(line_string);
+    
+    uword line_n_cols = 0;
+    while (line_stream >> token)
+      line_n_cols++;
+    
+    if(f_n_cols_found == false)
+      {
+      f_n_cols = line_n_cols;
+      f_n_cols_found = true;
+      }
+    else
+      {
+      if(line_n_cols != f_n_cols)
+        {
+        load_okay = false;
+        err_msg = "inconsistent number of columns in ";
+        }
+      }
+    
+    ++f_n_rows;
+    }
+    
+  if(load_okay == true)
+    {
+    f.clear();
+    f.seekg(0, ios::beg);
+    //f.seekg(start);
+    
+    x.set_size(f_n_rows, f_n_cols);
+  
+    for(uword row=0; row < x.n_rows; ++row)
+      {
+      for(uword col=0; col < x.n_cols; ++col)
+        {
+        f >> x.at(row,col);
+        }
+      }
+    }
+  
+  if(f.good() == false)
+    {
+    load_okay = false; 
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Try to load a field by automatically determining its type
+template<typename T1>
+inline
+bool
+diskio::load_auto_detect(field<T1>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::fstream f;
+  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_auto_detect(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+//! Try to load a field by automatically determining its type
+template<typename T1>
+inline
+bool
+diskio::load_auto_detect(field<T1>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_Mat<T1>::value == false ));
+  
+  static const std::string ARMA_FLD_BIN = "ARMA_FLD_BIN";
+  static const std::string           P6 = "P6";
+  
+  podarray<char> raw_header(ARMA_FLD_BIN.length() + 1);
+  
+  std::streampos pos = f.tellg();
+  
+  f.read( raw_header.memptr(), std::streamsize(ARMA_FLD_BIN.length()) );
+  
+  f.clear();
+  f.seekg(pos);
+  
+  raw_header[ARMA_FLD_BIN.length()] = '\0';
+  
+  const std::string header = raw_header.mem;
+  
+  if(ARMA_FLD_BIN == header.substr(0, ARMA_FLD_BIN.length()))
+    {
+    return load_arma_binary(x, f, err_msg);
+    }
+  else
+  if(P6 == header.substr(0, P6.length()))
+    {
+    return load_ppm_binary(x, f, err_msg);
+    }
+  else
+    {
+    err_msg = "unsupported header in ";
+    return false;
+    }
+  }
+
+
+
+//
+// handling of PPM images by cubes
+
+
+template<typename eT>
+inline
+bool
+diskio::load_ppm_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::fstream f;
+  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_ppm_binary(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+diskio::load_ppm_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  bool load_okay = true;
+  
+  std::string f_header;
+  f >> f_header;
+  
+  if(f_header == "P6")
+    {
+    uword f_n_rows = 0;
+    uword f_n_cols = 0;
+    int f_maxval = 0;
+  
+    diskio::pnm_skip_comments(f);
+  
+    f >> f_n_cols;
+    diskio::pnm_skip_comments(f);
+  
+    f >> f_n_rows;
+    diskio::pnm_skip_comments(f);
+  
+    f >> f_maxval;
+    f.get();
+    
+    if( (f_maxval > 0) || (f_maxval <= 65535) )
+      {
+      x.set_size(f_n_rows, f_n_cols, 3);
+      
+      if(f_maxval <= 255)
+        {
+        const uword n_elem = 3*f_n_cols*f_n_rows;
+        podarray<u8> tmp(n_elem);
+        
+        f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
+        
+        uword i = 0;
+        
+        //cout << "f_n_cols = " << f_n_cols << endl;
+        //cout << "f_n_rows = " << f_n_rows << endl;
+        
+        
+        for(uword row=0; row < f_n_rows; ++row)
+          {
+          for(uword col=0; col < f_n_cols; ++col)
+            {
+            x.at(row,col,0) = eT(tmp[i+0]);
+            x.at(row,col,1) = eT(tmp[i+1]);
+            x.at(row,col,2) = eT(tmp[i+2]);
+            i+=3;
+            }
+          
+          }
+        }
+      else
+        {
+        const uword n_elem = 3*f_n_cols*f_n_rows;
+        podarray<u16> tmp(n_elem);
+        
+        f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(2*n_elem) );
+        
+        uword i = 0;
+        
+        for(uword row=0; row < f_n_rows; ++row)
+          {
+          for(uword col=0; col < f_n_cols; ++col)
+            {
+            x.at(row,col,0) = eT(tmp[i+0]);
+            x.at(row,col,1) = eT(tmp[i+1]);
+            x.at(row,col,2) = eT(tmp[i+2]);
+            i+=3;
+            }
+          
+          }
+        
+        }
+      
+      }
+    else
+      {
+      load_okay = false;
+      err_msg = "currently no code available to handle loading ";
+      }
+      
+    if(f.good() == false)
+      {
+      load_okay = false;
+      }
+    
+    }
+  else
+    {
+    load_okay = false;
+    err_msg = "unsupported header in ";
+    }
+  
+  return load_okay;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+diskio::save_ppm_binary(const Cube<eT>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  
+  std::ofstream f( tmp_name.c_str(), std::fstream::binary );
+  
+  bool save_okay = f.is_open();
+  
+  if(save_okay == true)
+    {
+    save_okay = diskio::save_ppm_binary(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+diskio::save_ppm_binary(const Cube<eT>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (x.n_slices != 3), "diskio::save_ppm_binary(): given cube must have exactly 3 slices" );
+  
+  const uword n_elem = 3 * x.n_rows * x.n_cols;
+  podarray<u8> tmp(n_elem);
+  
+  uword i = 0;
+  for(uword row=0; row < x.n_rows; ++row)
+    {
+    for(uword col=0; col < x.n_cols; ++col)
+      {
+      tmp[i+0] = u8( access::tmp_real( x.at(row,col,0) ) );
+      tmp[i+1] = u8( access::tmp_real( x.at(row,col,1) ) );
+      tmp[i+2] = u8( access::tmp_real( x.at(row,col,2) ) );
+      
+      i+=3;
+      }
+    }
+  
+  f << "P6" << '\n';
+  f << x.n_cols << '\n';
+  f << x.n_rows << '\n';
+  f << 255 << '\n';
+  
+  f.write( reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
+  
+  return f.good();
+  }
+
+
+
+//
+// handling of PPM images by fields
+
+
+
+template<typename T1>
+inline
+bool
+diskio::load_ppm_binary(field<T1>& x, const std::string& name, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::fstream f;
+  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
+  
+  bool load_okay = f.is_open();
+  
+  if(load_okay == true)
+    {
+    load_okay = diskio::load_ppm_binary(x, f, err_msg);
+    f.close();
+    }
+  
+  return load_okay;
+  }
+
+
+
+template<typename T1>
+inline
+bool
+diskio::load_ppm_binary(field<T1>& x, std::istream& f, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_Mat<T1>::value == false ));
+  typedef typename T1::elem_type eT;
+  
+  bool load_okay = true;
+  
+  std::string f_header;
+  f >> f_header;
+  
+  if(f_header == "P6")
+    {
+    uword f_n_rows = 0;
+    uword f_n_cols = 0;
+    int f_maxval = 0;
+  
+    diskio::pnm_skip_comments(f);
+  
+    f >> f_n_cols;
+    diskio::pnm_skip_comments(f);
+  
+    f >> f_n_rows;
+    diskio::pnm_skip_comments(f);
+  
+    f >> f_maxval;
+    f.get();
+    
+    if( (f_maxval > 0) || (f_maxval <= 65535) )
+      {
+      x.set_size(3);
+      Mat<eT>& R = x(0);
+      Mat<eT>& G = x(1);
+      Mat<eT>& B = x(2);
+      
+      R.set_size(f_n_rows,f_n_cols);
+      G.set_size(f_n_rows,f_n_cols);
+      B.set_size(f_n_rows,f_n_cols);
+      
+      if(f_maxval <= 255)
+        {
+        const uword n_elem = 3*f_n_cols*f_n_rows;
+        podarray<u8> tmp(n_elem);
+        
+        f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
+        
+        uword i = 0;
+        
+        //cout << "f_n_cols = " << f_n_cols << endl;
+        //cout << "f_n_rows = " << f_n_rows << endl;
+        
+        
+        for(uword row=0; row < f_n_rows; ++row)
+          {
+          for(uword col=0; col < f_n_cols; ++col)
+            {
+            R.at(row,col) = eT(tmp[i+0]);
+            G.at(row,col) = eT(tmp[i+1]);
+            B.at(row,col) = eT(tmp[i+2]);
+            i+=3;
+            }
+          
+          }
+        }
+      else
+        {
+        const uword n_elem = 3*f_n_cols*f_n_rows;
+        podarray<u16> tmp(n_elem);
+        
+        f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(2*n_elem) );
+        
+        uword i = 0;
+        
+        for(uword row=0; row < f_n_rows; ++row)
+          {
+          for(uword col=0; col < f_n_cols; ++col)
+            {
+            R.at(row,col) = eT(tmp[i+0]);
+            G.at(row,col) = eT(tmp[i+1]);
+            B.at(row,col) = eT(tmp[i+2]);
+            i+=3;
+            }
+          
+          }
+        
+        }
+      
+      }
+    else
+      {
+      load_okay = false;
+      err_msg = "currently no code available to handle loading ";
+      }
+    
+    if(f.good() == false)
+      {
+      load_okay = false;
+      }
+    
+    }
+  else
+    {
+    load_okay = false;
+    err_msg = "unsupported header in ";
+    }
+  
+  return load_okay;
+  }
+
+
+
+template<typename T1>
+inline
+bool
+diskio::save_ppm_binary(const field<T1>& x, const std::string& final_name)
+  {
+  arma_extra_debug_sigprint();
+  
+  const std::string tmp_name = diskio::gen_tmp_name(final_name);
+  std::ofstream f( tmp_name.c_str(), std::fstream::binary );
+  
+  bool save_okay = f.is_open();
+  
+  if(save_okay == true)
+    {
+    save_okay = diskio::save_ppm_binary(x, f);
+    
+    f.flush();
+    f.close();
+    
+    if(save_okay == true)
+      {
+      save_okay = diskio::safe_rename(tmp_name, final_name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+template<typename T1>
+inline
+bool
+diskio::save_ppm_binary(const field<T1>& x, std::ostream& f)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_Mat<T1>::value == false ));
+  
+  typedef typename T1::elem_type eT;
+  
+  arma_debug_check( (x.n_elem != 3), "diskio::save_ppm_binary(): given field must have exactly 3 matrices of equal size" );
+  
+  bool same_size = true;
+  for(uword i=1; i<3; ++i)
+    {
+    if( (x(0).n_rows != x(i).n_rows) || (x(0).n_cols != x(i).n_cols) )
+      {
+      same_size = false;
+      break;
+      }
+    }
+  
+  arma_debug_check( (same_size != true), "diskio::save_ppm_binary(): given field must have exactly 3 matrices of equal size" );
+  
+  const Mat<eT>& R = x(0);
+  const Mat<eT>& G = x(1);
+  const Mat<eT>& B = x(2);
+  
+  f << "P6" << '\n';
+  f << R.n_cols << '\n';
+  f << R.n_rows << '\n';
+  f << 255 << '\n';
+
+  const uword n_elem = 3 * R.n_rows * R.n_cols;
+  podarray<u8> tmp(n_elem);
+
+  uword i = 0;
+  for(uword row=0; row < R.n_rows; ++row)
+    {
+    for(uword col=0; col < R.n_cols; ++col)
+      {
+      tmp[i+0] = u8( access::tmp_real( R.at(row,col) ) );
+      tmp[i+1] = u8( access::tmp_real( G.at(row,col) ) );
+      tmp[i+2] = u8( access::tmp_real( B.at(row,col) ) );
+      
+      i+=3;
+      }
+    }
+  
+  f.write( reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
+  
+  return f.good();
+  }
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/eGlueCube_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,43 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup eGlueCube
+//! @{
+
+
+template<typename T1, typename T2, typename eglue_type>
+class eGlueCube : public BaseCube<typename T1::elem_type, eGlueCube<T1, T2, eglue_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
+  static const bool has_subview        = (ProxyCube<T1>::has_subview        || ProxyCube<T2>::has_subview       );
+  
+  arma_aligned const ProxyCube<T1> P1;
+  arma_aligned const ProxyCube<T2> P2;
+  
+  arma_inline ~eGlueCube();
+  arma_inline  eGlueCube(const T1& in_A, const T2& in_B);
+  
+  arma_inline uword get_n_rows()       const;
+  arma_inline uword get_n_cols()       const;
+  arma_inline uword get_n_elem_slice() const;
+  arma_inline uword get_n_slices()     const;
+  arma_inline uword get_n_elem()       const;
+  
+  arma_inline elem_type operator[] (const uword i)                                       const;
+  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const;
+  arma_inline elem_type at_alt     (const uword i)                                       const;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/eGlueCube_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,143 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup eGlueCube
+//! @{
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+eGlueCube<T1,T2,eglue_type>::~eGlueCube()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+eGlueCube<T1,T2,eglue_type>::eGlueCube(const T1& in_A, const T2& in_B)
+  : P1(in_A)
+  , P2(in_B)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size
+    (
+    P1.get_n_rows(), P1.get_n_cols(), P1.get_n_slices(),
+    P2.get_n_rows(), P2.get_n_cols(), P2.get_n_slices(), 
+    eglue_type::text()
+    );
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+uword
+eGlueCube<T1,T2,eglue_type>::get_n_rows() const
+  {
+  return P1.get_n_rows();
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+uword
+eGlueCube<T1,T2,eglue_type>::get_n_cols() const
+  {
+  return P1.get_n_cols();
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+uword
+eGlueCube<T1,T2,eglue_type>::get_n_slices() const
+  {
+  return P1.get_n_slices();
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+uword
+eGlueCube<T1,T2,eglue_type>::get_n_elem_slice() const
+  {
+  return P1.get_n_elem_slice();
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+uword
+eGlueCube<T1,T2,eglue_type>::get_n_elem() const
+  {
+  return P1.get_n_elem();
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+typename T1::elem_type
+eGlueCube<T1,T2,eglue_type>::operator[] (const uword i) const
+  {
+  // the optimiser will keep only one return statement
+  
+  typedef typename T1::elem_type eT;
+  
+       if(is_same_type<eglue_type, eglue_plus >::value == true) { return P1[i] + P2[i]; }
+  else if(is_same_type<eglue_type, eglue_minus>::value == true) { return P1[i] - P2[i]; }
+  else if(is_same_type<eglue_type, eglue_div  >::value == true) { return P1[i] / P2[i]; }
+  else if(is_same_type<eglue_type, eglue_schur>::value == true) { return P1[i] * P2[i]; }
+  else return eT(0);
+  }
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+typename T1::elem_type
+eGlueCube<T1,T2,eglue_type>::at(const uword row, const uword col, const uword slice) const
+  {
+  // the optimiser will keep only one return statement
+  
+  typedef typename T1::elem_type eT;
+  
+       if(is_same_type<eglue_type, eglue_plus >::value == true) { return P1.at(row,col,slice) + P2.at(row,col,slice); }
+  else if(is_same_type<eglue_type, eglue_minus>::value == true) { return P1.at(row,col,slice) - P2.at(row,col,slice); }
+  else if(is_same_type<eglue_type, eglue_div  >::value == true) { return P1.at(row,col,slice) / P2.at(row,col,slice); }
+  else if(is_same_type<eglue_type, eglue_schur>::value == true) { return P1.at(row,col,slice) * P2.at(row,col,slice); }
+  else return eT(0);
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+typename T1::elem_type
+eGlueCube<T1,T2,eglue_type>::at_alt(const uword i) const
+  {
+  // the optimiser will keep only one return statement
+  
+  typedef typename T1::elem_type eT;
+  
+       if(is_same_type<eglue_type, eglue_plus >::value == true) { return P1.at_alt(i) + P2.at_alt(i); }
+  else if(is_same_type<eglue_type, eglue_minus>::value == true) { return P1.at_alt(i) - P2.at_alt(i); }
+  else if(is_same_type<eglue_type, eglue_div  >::value == true) { return P1.at_alt(i) / P2.at_alt(i); }
+  else if(is_same_type<eglue_type, eglue_schur>::value == true) { return P1.at_alt(i) * P2.at_alt(i); }
+  else return eT(0);
+  }
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/eGlue_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,48 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup eGlue
+//! @{
+
+
+template<typename T1, typename T2, typename eglue_type>
+class eGlue : public Base<typename T1::elem_type, eGlue<T1, T2, eglue_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef          Proxy<T1>                       proxy1_type;
+  typedef          Proxy<T2>                       proxy2_type;
+  
+  static const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
+  static const bool has_subview        = (Proxy<T1>::has_subview        || Proxy<T2>::has_subview       );
+  static const bool is_fixed           = (Proxy<T1>::is_fixed           || Proxy<T2>::is_fixed          );
+  static const bool fake_mat           = (Proxy<T1>::fake_mat           || Proxy<T2>::fake_mat          );
+  
+  static const bool is_col = (Proxy<T1>::is_col || Proxy<T2>::is_col);
+  static const bool is_row = (Proxy<T1>::is_row || Proxy<T2>::is_row);
+  
+  arma_aligned const Proxy<T1> P1;
+  arma_aligned const Proxy<T2> P2;
+  
+  arma_inline ~eGlue();
+  arma_inline  eGlue(const T1& in_A, const T2& in_B);
+  
+  arma_inline uword get_n_rows() const;
+  arma_inline uword get_n_cols() const;
+  arma_inline uword get_n_elem() const;
+  
+  arma_inline elem_type operator[] (const uword ii)                   const;
+  arma_inline elem_type at         (const uword row, const uword col) const;
+  arma_inline elem_type at_alt     (const uword ii)                   const;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/eGlue_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,126 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup eGlue
+//! @{
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+eGlue<T1,T2,eglue_type>::~eGlue()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+eGlue<T1,T2,eglue_type>::eGlue(const T1& in_A, const T2& in_B)
+  : P1(in_A)
+  , P2(in_B)
+  {
+  arma_extra_debug_sigprint();
+  
+  // arma_debug_assert_same_size( P1, P2, eglue_type::text() );
+  arma_debug_assert_same_size
+    (
+    P1.get_n_rows(), P1.get_n_cols(),
+    P2.get_n_rows(), P2.get_n_cols(),
+    eglue_type::text()
+    );
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+uword
+eGlue<T1,T2,eglue_type>::get_n_rows() const
+  {
+  return is_row ? 1 : ( Proxy<T1>::is_fixed ? P1.get_n_rows() : ( Proxy<T2>::is_fixed ? P2.get_n_rows() : P1.get_n_rows() ) );
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+uword
+eGlue<T1,T2,eglue_type>::get_n_cols() const
+  {
+  return is_col ? 1 : ( Proxy<T1>::is_fixed ? P1.get_n_cols() : ( Proxy<T2>::is_fixed ? P2.get_n_cols() : P1.get_n_cols() ) );
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+uword
+eGlue<T1,T2,eglue_type>::get_n_elem() const
+  {
+  return Proxy<T1>::is_fixed ? P1.get_n_elem() : ( Proxy<T2>::is_fixed ? P2.get_n_elem() : P1.get_n_elem() ) ;
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+typename T1::elem_type
+eGlue<T1,T2,eglue_type>::operator[] (const uword ii) const
+  {
+  // the optimiser will keep only one return statement
+  
+  typedef typename T1::elem_type eT;
+  
+       if(is_same_type<eglue_type, eglue_plus >::value == true) { return P1[ii] + P2[ii]; }
+  else if(is_same_type<eglue_type, eglue_minus>::value == true) { return P1[ii] - P2[ii]; }
+  else if(is_same_type<eglue_type, eglue_div  >::value == true) { return P1[ii] / P2[ii]; }
+  else if(is_same_type<eglue_type, eglue_schur>::value == true) { return P1[ii] * P2[ii]; }
+  else return eT(0);
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+typename T1::elem_type
+eGlue<T1,T2,eglue_type>::at(const uword row, const uword col) const
+  {
+  // the optimiser will keep only one return statement
+  
+  typedef typename T1::elem_type eT;
+  
+       if(is_same_type<eglue_type, eglue_plus >::value == true) { return P1.at(row,col) + P2.at(row,col); }
+  else if(is_same_type<eglue_type, eglue_minus>::value == true) { return P1.at(row,col) - P2.at(row,col); }
+  else if(is_same_type<eglue_type, eglue_div  >::value == true) { return P1.at(row,col) / P2.at(row,col); }
+  else if(is_same_type<eglue_type, eglue_schur>::value == true) { return P1.at(row,col) * P2.at(row,col); }
+  else return eT(0);
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+arma_inline
+typename T1::elem_type
+eGlue<T1,T2,eglue_type>::at_alt(const uword ii) const
+  {
+  // the optimiser will keep only one return statement
+  
+  typedef typename T1::elem_type eT;
+  
+       if(is_same_type<eglue_type, eglue_plus >::value == true) { return P1.at_alt(ii) + P2.at_alt(ii); }
+  else if(is_same_type<eglue_type, eglue_minus>::value == true) { return P1.at_alt(ii) - P2.at_alt(ii); }
+  else if(is_same_type<eglue_type, eglue_div  >::value == true) { return P1.at_alt(ii) / P2.at_alt(ii); }
+  else if(is_same_type<eglue_type, eglue_schur>::value == true) { return P1.at_alt(ii) * P2.at_alt(ii); }
+  else return eT(0);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/eOpCube_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,51 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup eOpCube
+//! @{
+
+
+
+template<typename T1, typename eop_type>
+class eOpCube : public BaseCube<typename T1::elem_type, eOpCube<T1, eop_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool prefer_at_accessor = ProxyCube<T1>::prefer_at_accessor;
+  static const bool has_subview        = ProxyCube<T1>::has_subview;
+  
+  arma_aligned const ProxyCube<T1> P;
+  arma_aligned       elem_type     aux;          //!< storage of auxiliary data, user defined format
+  arma_aligned       uword         aux_uword_a;  //!< storage of auxiliary data, uword format
+  arma_aligned       uword         aux_uword_b;  //!< storage of auxiliary data, uword format
+  arma_aligned       uword         aux_uword_c;  //!< storage of auxiliary data, uword format
+  
+  inline         ~eOpCube();
+  inline explicit eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m);
+  inline          eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const elem_type in_aux);
+  inline          eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
+  inline          eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
+  inline          eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
+  
+  arma_inline uword get_n_rows()       const;
+  arma_inline uword get_n_cols()       const;
+  arma_inline uword get_n_elem_slice() const;
+  arma_inline uword get_n_slices()     const;
+  arma_inline uword get_n_elem()       const;
+  
+  arma_inline elem_type operator[] (const uword i)                                       const;
+  arma_inline elem_type at         (const uword row, const uword col, const uword slice) const;
+  arma_inline elem_type at_alt     (const uword i)                                       const;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/eOpCube_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,157 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup eOpCube
+//! @{
+
+
+
+template<typename T1, typename eop_type>
+eOpCube<T1, eop_type>::eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m)
+  : P (in_m.get_ref())
+  {
+  arma_extra_debug_sigprint();
+  }
+  
+
+
+template<typename T1, typename eop_type>
+eOpCube<T1, eop_type>::eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const typename T1::elem_type in_aux)
+  : P   (in_m.get_ref())
+  , aux (in_aux)
+  {
+  arma_extra_debug_sigprint();
+  }
+  
+
+
+template<typename T1, typename eop_type>
+eOpCube<T1, eop_type>::eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b)
+  : P           (in_m.get_ref())
+  , aux_uword_a (in_aux_uword_a)
+  , aux_uword_b (in_aux_uword_b)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename eop_type>
+eOpCube<T1, eop_type>::eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c)
+  : P           (in_m.get_ref())
+  , aux_uword_a (in_aux_uword_a)
+  , aux_uword_b (in_aux_uword_b)
+  , aux_uword_c (in_aux_uword_c)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename eop_type>
+eOpCube<T1, eop_type>::eOpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const typename T1::elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c)
+  : P           (in_m.get_ref())
+  , aux         (in_aux)
+  , aux_uword_a (in_aux_uword_a)
+  , aux_uword_b (in_aux_uword_b)
+  , aux_uword_c (in_aux_uword_c)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename eop_type>
+eOpCube<T1, eop_type>::~eOpCube()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename eop_type>
+arma_inline
+uword
+eOpCube<T1, eop_type>::get_n_rows() const
+  {
+  return P.get_n_rows();
+  }
+  
+
+
+template<typename T1, typename eop_type>
+arma_inline
+uword
+eOpCube<T1, eop_type>::get_n_cols() const
+  {
+  return P.get_n_cols();
+  }
+
+
+
+template<typename T1, typename eop_type>
+arma_inline
+uword
+eOpCube<T1, eop_type>::get_n_elem_slice() const
+  {
+  return P.get_n_elem_slice();
+  }
+
+
+
+template<typename T1, typename eop_type>
+arma_inline
+uword
+eOpCube<T1, eop_type>::get_n_slices() const
+  {
+  return P.get_n_slices();
+  }
+
+
+
+template<typename T1, typename eop_type>
+arma_inline
+uword
+eOpCube<T1, eop_type>::get_n_elem() const
+  {
+  return P.get_n_elem();
+  }
+
+
+
+template<typename T1, typename eop_type>
+arma_inline
+typename T1::elem_type
+eOpCube<T1, eop_type>::operator[] (const uword i) const
+  {
+  return eop_core<eop_type>::process(P[i], aux);
+  }
+
+
+
+template<typename T1, typename eop_type>
+arma_inline
+typename T1::elem_type
+eOpCube<T1, eop_type>::at(const uword row, const uword col, const uword slice) const
+  {
+  return eop_core<eop_type>::process(P.at(row, col, slice), aux);
+  }
+
+
+
+template<typename T1, typename eop_type>
+arma_inline
+typename T1::elem_type
+eOpCube<T1, eop_type>::at_alt(const uword i) const
+  {
+  return eop_core<eop_type>::process(P.at_alt(i), aux);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/eOp_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,54 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup eOp
+//! @{
+
+
+
+template<typename T1, typename eop_type>
+class eOp : public Base<typename T1::elem_type, eOp<T1, eop_type> >
+  {
+  public:
+  
+  typedef typename T1::elem_type                   elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  typedef          Proxy<T1>                       proxy_type;
+  
+  static const bool prefer_at_accessor = Proxy<T1>::prefer_at_accessor;
+  static const bool has_subview        = Proxy<T1>::has_subview;
+  static const bool is_fixed           = Proxy<T1>::is_fixed;
+  static const bool fake_mat           = Proxy<T1>::fake_mat;
+  
+  static const bool is_row = Proxy<T1>::is_row;
+  static const bool is_col = Proxy<T1>::is_col;
+  
+  arma_aligned const Proxy<T1> P;
+  
+  arma_aligned       elem_type aux;          //!< storage of auxiliary data, user defined format
+  arma_aligned       uword     aux_uword_a;  //!< storage of auxiliary data, uword format
+  arma_aligned       uword     aux_uword_b;  //!< storage of auxiliary data, uword format
+  
+  inline         ~eOp();
+  inline explicit eOp(const T1& in_m);
+  inline          eOp(const T1& in_m, const elem_type in_aux);
+  inline          eOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
+  inline          eOp(const T1& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b);
+  
+  arma_inline uword get_n_rows() const;
+  arma_inline uword get_n_cols() const;
+  arma_inline uword get_n_elem() const;
+  
+  arma_inline elem_type operator[] (const uword ii)                   const;
+  arma_inline elem_type at         (const uword row, const uword col) const;
+  arma_inline elem_type at_alt     (const uword ii)                   const;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/eOp_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,136 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup eOp
+//! @{
+
+
+
+template<typename T1, typename eop_type>
+eOp<T1, eop_type>::eOp(const T1& in_m)
+  : P(in_m)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename eop_type>
+eOp<T1, eop_type>::eOp(const T1& in_m, const typename T1::elem_type in_aux)
+  : P(in_m)
+  , aux(in_aux)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename eop_type>
+eOp<T1, eop_type>::eOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b)
+  : P(in_m)
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename eop_type>
+eOp<T1, eop_type>::eOp(const T1& in_m, const typename T1::elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b)
+  : P(in_m)
+  , aux(in_aux)
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename T1, typename eop_type>
+eOp<T1, eop_type>::~eOp()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+  
+
+template<typename T1, typename eop_type>
+arma_inline
+uword
+eOp<T1, eop_type>::get_n_rows() const
+  {
+  return is_row ? 1 : P.get_n_rows();
+  }
+  
+
+
+template<typename T1, typename eop_type>
+arma_inline
+uword
+eOp<T1, eop_type>::get_n_cols() const
+  {
+  return is_col ? 1 : P.get_n_cols();
+  }
+
+
+
+template<typename T1, typename eop_type>
+arma_inline
+uword
+eOp<T1, eop_type>::get_n_elem() const
+  {
+  return P.get_n_elem();
+  }
+
+
+
+template<typename T1, typename eop_type>
+arma_inline
+typename T1::elem_type
+eOp<T1, eop_type>::operator[] (const uword ii) const
+  {
+  return eop_core<eop_type>::process(P[ii], aux);
+  }
+
+
+
+template<typename T1, typename eop_type>
+arma_inline
+typename T1::elem_type
+eOp<T1, eop_type>::at(const uword row, const uword col) const
+  {
+  if(is_row)
+    {
+    return eop_core<eop_type>::process(P.at(0, col), aux);
+    }
+  else
+  if(is_col)
+    {
+    return eop_core<eop_type>::process(P.at(row, 0), aux);
+    }
+  else
+    {
+    return eop_core<eop_type>::process(P.at(row, col), aux);
+    }
+  }
+
+
+
+template<typename T1, typename eop_type>
+arma_inline
+typename T1::elem_type
+eOp<T1, eop_type>::at_alt(const uword ii) const
+  {
+  return eop_core<eop_type>::process(P.at_alt(ii), aux);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/eglue_core_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,76 @@
+// Copyright (C) 2010-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup eglue_core
+//! @{
+
+
+
+template<typename eglue_type>
+struct eglue_core
+  {
+  
+  // matrices
+  
+  template<typename T1, typename T2> arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x);
+  
+  template<typename T1, typename T2> arma_hot inline static void apply_inplace_plus (Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x);
+  template<typename T1, typename T2> arma_hot inline static void apply_inplace_minus(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x);
+  template<typename T1, typename T2> arma_hot inline static void apply_inplace_schur(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x);
+  template<typename T1, typename T2> arma_hot inline static void apply_inplace_div  (Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x);
+  
+  
+  // cubes
+  
+  template<typename T1, typename T2> arma_hot inline static void apply(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x);
+  
+  template<typename T1, typename T2> arma_hot inline static void apply_inplace_plus (Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x);
+  template<typename T1, typename T2> arma_hot inline static void apply_inplace_minus(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x);
+  template<typename T1, typename T2> arma_hot inline static void apply_inplace_schur(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x);
+  template<typename T1, typename T2> arma_hot inline static void apply_inplace_div  (Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x);
+  };
+
+
+
+class eglue_plus : public eglue_core<eglue_plus>
+  {
+  public:
+  
+  inline static const char* text() { return "addition"; }
+  };
+
+
+
+class eglue_minus : public eglue_core<eglue_minus>
+  {
+  public:
+  
+  inline static const char* text() { return "subtraction"; }
+  };
+
+
+
+class eglue_div : public eglue_core<eglue_div>
+  {
+  public:
+  
+  inline static const char* text() { return "element-wise division"; }
+  };
+
+
+
+class eglue_schur : public eglue_core<eglue_schur>
+  {
+  public:
+  
+  inline static const char* text() { return "element-wise multiplication"; }
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/eglue_core_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,916 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup eglue_core
+//! @{
+
+
+
+#undef arma_applier_1u
+#undef arma_applier_1a
+#undef arma_applier_2
+#undef arma_applier_3
+#undef operatorA
+#undef operatorB
+
+#define arma_applier_1u(operatorA, operatorB) \
+  {\
+  uword i,j;\
+  \
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)\
+    {\
+    eT tmp_i = P1[i];\
+    eT tmp_j = P1[j];\
+    \
+    tmp_i operatorB##= P2[i];\
+    tmp_j operatorB##= P2[j];\
+    \
+    out_mem[i] operatorA tmp_i;\
+    out_mem[j] operatorA tmp_j;\
+    }\
+  \
+  if(i < n_elem)\
+    {\
+    out_mem[i] operatorA P1[i] operatorB P2[i];\
+    }\
+  }
+  
+
+
+#define arma_applier_1a(operatorA, operatorB) \
+  {\
+  uword i,j;\
+  \
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)\
+    {\
+    eT tmp_i = P1.at_alt(i);\
+    eT tmp_j = P1.at_alt(j);\
+    \
+    tmp_i operatorB##= P2.at_alt(i);\
+    tmp_j operatorB##= P2.at_alt(j);\
+    \
+    out_mem[i] operatorA tmp_i;\
+    out_mem[j] operatorA tmp_j;\
+    }\
+  \
+  if(i < n_elem)\
+    {\
+    out_mem[i] operatorA P1.at_alt(i) operatorB P2.at_alt(i);\
+    }\
+  }
+  
+
+
+#define arma_applier_2(operatorA, operatorB) \
+  {\
+  if(n_rows != 1)\
+    {\
+    for(uword col=0; col<n_cols; ++col)\
+      {\
+      uword i,j;\
+      \
+      for(i=0, j=1; j<n_rows; i+=2, j+=2)\
+        {\
+        eT tmp_i = P1.at(i,col);\
+        eT tmp_j = P1.at(j,col);\
+        \
+        tmp_i operatorB##= P2.at(i,col);\
+        tmp_j operatorB##= P2.at(j,col);\
+        \
+        *out_mem operatorA tmp_i; out_mem++; \
+        *out_mem operatorA tmp_j; out_mem++; \
+        }\
+      \
+      if(i < n_rows)\
+        {\
+        *out_mem operatorA P1.at(i,col) operatorB P2.at(i,col); out_mem++; \
+        }\
+      }\
+    }\
+  else\
+    {\
+    uword i,j;\
+    for(i=0, j=1; j < n_cols; i+=2, j+=2)\
+      {\
+      eT tmp_i = P1.at(0,i);\
+      eT tmp_j = P1.at(0,j);\
+      \
+      tmp_i operatorB##= P2.at(0,i);\
+      tmp_j operatorB##= P2.at(0,j);\
+      \
+      out_mem[i] operatorA tmp_i;\
+      out_mem[j] operatorA tmp_j;\
+      }\
+    \
+    if(i < n_cols)\
+      {\
+      out_mem[i] operatorA P1.at(0,i) operatorB P2.at(0,i);\
+      }\
+    }\
+  }
+
+
+
+#define arma_applier_3(operatorA, operatorB) \
+  {\
+  for(uword slice=0; slice<n_slices; ++slice)\
+    {\
+    for(uword col=0; col<n_cols; ++col)\
+      {\
+      uword i,j;\
+      \
+      for(i=0, j=1; j<n_rows; i+=2, j+=2)\
+        {\
+        eT tmp_i = P1.at(i,col,slice);\
+        eT tmp_j = P1.at(j,col,slice);\
+        \
+        tmp_i operatorB##= P2.at(i,col,slice);\
+        tmp_j operatorB##= P2.at(j,col,slice);\
+        \
+        *out_mem operatorA tmp_i; out_mem++; \
+        *out_mem operatorA tmp_j; out_mem++; \
+        }\
+      \
+      if(i < n_rows)\
+        {\
+        *out_mem operatorA P1.at(i,col,slice) operatorB P2.at(i,col,slice); out_mem++; \
+        }\
+      }\
+    }\
+  }
+
+
+
+//
+// matrices
+
+
+
+template<typename eglue_type>
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+eglue_core<eglue_type>::apply(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
+  
+  // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing;
+  // size setting and alias checking is done by either the Mat contructor or operator=()
+  
+  
+  eT* out_mem = out.memptr();
+  
+  if(prefer_at_accessor == false)
+    {
+    const uword n_elem = (Proxy<T1>::is_fixed || Proxy<T2>::is_fixed) ? x.get_n_elem() : out.n_elem;
+    
+    //if( memory::is_aligned(out_mem) )
+    if( memory::is_aligned(out_mem) && ((Proxy<T1>::is_fixed && Proxy<T2>::is_fixed) ? (x.get_n_elem() >= 32) : true) )
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P1.is_aligned() && x.P2.is_aligned())
+        {
+        typename Proxy<T1>::aligned_ea_type P1 = x.P1.get_aligned_ea();
+        typename Proxy<T2>::aligned_ea_type P2 = x.P2.get_aligned_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1a(=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1a(=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1a(=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1a(=, *); }
+        }
+      else
+        {
+        typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
+        typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(=, *); }
+        }
+      }
+    else
+      {
+      typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
+      typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
+    
+           if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(=, +); }
+      else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(=, -); }
+      else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(=, /); }
+      else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(=, *); }
+      }
+    }
+  else
+    {
+    const uword n_rows = x.get_n_rows();
+    const uword n_cols = x.get_n_cols();
+    
+    const Proxy<T1>& P1 = x.P1;
+    const Proxy<T2>& P2 = x.P2;
+    
+         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_2(=, +); }
+    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_2(=, -); }
+    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_2(=, /); }
+    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_2(=, *); }
+    }
+  }
+
+
+
+template<typename eglue_type>
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+eglue_core<eglue_type>::apply_inplace_plus(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword n_rows = x.get_n_rows();
+  const uword n_cols = x.get_n_cols();
+    
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "addition");
+  
+  typedef typename T1::elem_type eT;
+  
+  eT* out_mem = out.memptr();
+  
+  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    const uword n_elem = (Proxy<T1>::is_fixed || Proxy<T2>::is_fixed) ? x.get_n_elem() : out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P1.is_aligned() && x.P2.is_aligned())
+        {
+        typename Proxy<T1>::aligned_ea_type P1 = x.P1.get_aligned_ea();
+        typename Proxy<T2>::aligned_ea_type P2 = x.P2.get_aligned_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1a(+=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1a(+=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1a(+=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1a(+=, *); }
+        }
+      else
+        {
+        typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
+        typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
+    
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(+=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(+=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(+=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(+=, *); }
+        }
+      }
+    else
+      {
+      typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
+      typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
+    
+           if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(+=, +); }
+      else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(+=, -); }
+      else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(+=, /); }
+      else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(+=, *); }
+      }
+    }
+  else
+    {
+    const Proxy<T1>& P1 = x.P1;
+    const Proxy<T2>& P2 = x.P2;
+    
+         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_2(+=, +); }
+    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_2(+=, -); }
+    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_2(+=, /); }
+    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_2(+=, *); }
+    }
+  }
+
+
+
+template<typename eglue_type>
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+eglue_core<eglue_type>::apply_inplace_minus(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword n_rows = x.get_n_rows();
+  const uword n_cols = x.get_n_cols();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "subtraction");
+  
+  typedef typename T1::elem_type eT;
+  
+  eT* out_mem = out.memptr();
+  
+  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    const uword n_elem = (Proxy<T1>::is_fixed || Proxy<T2>::is_fixed) ? x.get_n_elem() : out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P1.is_aligned() && x.P2.is_aligned())
+        {
+        typename Proxy<T1>::aligned_ea_type P1 = x.P1.get_aligned_ea();
+        typename Proxy<T2>::aligned_ea_type P2 = x.P2.get_aligned_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1a(-=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1a(-=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1a(-=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1a(-=, *); }
+        }
+      else
+        {
+        typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
+        typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
+    
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(-=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(-=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(-=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(-=, *); }
+        }
+      }
+    else
+      {
+      typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
+      typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
+    
+           if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(-=, +); }
+      else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(-=, -); }
+      else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(-=, /); }
+      else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(-=, *); }
+      }
+    }
+  else
+    {
+    const Proxy<T1>& P1 = x.P1;
+    const Proxy<T2>& P2 = x.P2;
+    
+         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_2(-=, +); }
+    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_2(-=, -); }
+    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_2(-=, /); }
+    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_2(-=, *); }
+    }
+  }
+
+
+
+template<typename eglue_type>
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+eglue_core<eglue_type>::apply_inplace_schur(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword n_rows = x.get_n_rows();
+  const uword n_cols = x.get_n_cols();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise multiplication");
+  
+  typedef typename T1::elem_type eT;
+  
+  eT* out_mem = out.memptr();
+  
+  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    const uword n_elem = (Proxy<T1>::is_fixed || Proxy<T2>::is_fixed) ? x.get_n_elem() : out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P1.is_aligned() && x.P2.is_aligned())
+        {
+        typename Proxy<T1>::aligned_ea_type P1 = x.P1.get_aligned_ea();
+        typename Proxy<T2>::aligned_ea_type P2 = x.P2.get_aligned_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1a(*=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1a(*=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1a(*=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1a(*=, *); }
+        }
+      else
+        {
+        typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
+        typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
+    
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(*=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(*=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(*=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(*=, *); }
+        }
+      }
+    else
+      {
+      typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
+      typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
+    
+           if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(*=, +); }
+      else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(*=, -); }
+      else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(*=, /); }
+      else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(*=, *); }
+      }
+    }
+  else
+    {
+    const Proxy<T1>& P1 = x.P1;
+    const Proxy<T2>& P2 = x.P2;
+    
+         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_2(*=, +); }
+    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_2(*=, -); }
+    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_2(*=, /); }
+    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_2(*=, *); }
+    }
+  }
+
+
+
+template<typename eglue_type>
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+eglue_core<eglue_type>::apply_inplace_div(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword n_rows = x.get_n_rows();
+  const uword n_cols = x.get_n_cols();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise division");
+  
+  typedef typename T1::elem_type eT;
+  
+  eT* out_mem = out.memptr();
+  
+  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    const uword n_elem = (Proxy<T1>::is_fixed || Proxy<T2>::is_fixed) ? x.get_n_elem() : out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P1.is_aligned() && x.P2.is_aligned())
+        {
+        typename Proxy<T1>::aligned_ea_type P1 = x.P1.get_aligned_ea();
+        typename Proxy<T2>::aligned_ea_type P2 = x.P2.get_aligned_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1a(/=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1a(/=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1a(/=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1a(/=, *); }
+        }
+      else
+        {
+        typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
+        typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
+    
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(/=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(/=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(/=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(/=, *); }
+        }
+      }
+    else
+      {
+      typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
+      typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
+    
+           if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(/=, +); }
+      else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(/=, -); }
+      else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(/=, /); }
+      else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(/=, *); }
+      }
+    }
+  else
+    {
+    const Proxy<T1>& P1 = x.P1;
+    const Proxy<T2>& P2 = x.P2;
+    
+         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_2(/=, +); }
+    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_2(/=, -); }
+    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_2(/=, /); }
+    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_2(/=, *); }
+    }
+  }
+
+
+
+//
+// cubes
+
+
+
+template<typename eglue_type>
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+eglue_core<eglue_type>::apply(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
+  
+  // NOTE: we're assuming that the cube has already been set to the correct size and there is no aliasing;
+  // size setting and alias checking is done by either the Cube contructor or operator=()
+  
+  
+  eT* out_mem = out.memptr();
+  
+  if(prefer_at_accessor == false)
+    {
+    const uword n_elem = out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P1.is_aligned() && x.P2.is_aligned())
+        {
+        typename ProxyCube<T1>::aligned_ea_type P1 = x.P1.get_aligned_ea();
+        typename ProxyCube<T2>::aligned_ea_type P2 = x.P2.get_aligned_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1a(=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1a(=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1a(=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1a(=, *); }
+        }
+      else
+        {
+        typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
+        typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(=, *); }
+        }
+      }
+    else
+      {
+      typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
+      typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
+      
+           if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(=, +); }
+      else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(=, -); }
+      else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(=, /); }
+      else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(=, *); }
+      }
+    }
+  else
+    {
+    const uword n_rows   = x.get_n_rows();
+    const uword n_cols   = x.get_n_cols();
+    const uword n_slices = x.get_n_slices();
+  
+    const ProxyCube<T1>& P1 = x.P1;
+    const ProxyCube<T2>& P2 = x.P2;
+    
+         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_3(=, +); }
+    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_3(=, -); }
+    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_3(=, /); }
+    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_3(=, *); }
+    }
+  }
+
+
+
+template<typename eglue_type>
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+eglue_core<eglue_type>::apply_inplace_plus(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword n_rows   = x.get_n_rows();
+  const uword n_cols   = x.get_n_cols();
+  const uword n_slices = x.get_n_slices();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "addition");
+  
+  typedef typename T1::elem_type eT;
+  
+  eT* out_mem = out.memptr();
+  
+  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    const uword n_elem = out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P1.is_aligned() && x.P2.is_aligned())
+        {
+        typename ProxyCube<T1>::aligned_ea_type P1 = x.P1.get_aligned_ea();
+        typename ProxyCube<T2>::aligned_ea_type P2 = x.P2.get_aligned_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1a(+=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1a(+=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1a(+=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1a(+=, *); }
+        }
+      else
+        {
+        typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
+        typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(+=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(+=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(+=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(+=, *); }
+        }
+      }
+    else
+      {
+      typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
+      typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
+      
+           if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(+=, +); }
+      else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(+=, -); }
+      else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(+=, /); }
+      else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(+=, *); }
+      }
+    }
+  else
+    {
+    const ProxyCube<T1>& P1 = x.P1;
+    const ProxyCube<T2>& P2 = x.P2;
+    
+         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_3(+=, +); }
+    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_3(+=, -); }
+    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_3(+=, /); }
+    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_3(+=, *); }
+    }
+  }
+
+
+
+template<typename eglue_type>
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+eglue_core<eglue_type>::apply_inplace_minus(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword n_rows   = x.get_n_rows();
+  const uword n_cols   = x.get_n_cols();
+  const uword n_slices = x.get_n_slices();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "subtraction");
+  
+  typedef typename T1::elem_type eT;
+  
+  eT* out_mem = out.memptr();
+  
+  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    const uword n_elem = out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P1.is_aligned() && x.P2.is_aligned())
+        {
+        typename ProxyCube<T1>::aligned_ea_type P1 = x.P1.get_aligned_ea();
+        typename ProxyCube<T2>::aligned_ea_type P2 = x.P2.get_aligned_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1a(-=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1a(-=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1a(-=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1a(-=, *); }
+        }
+      else
+        {
+        typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
+        typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(-=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(-=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(-=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(-=, *); }
+        }
+      }
+    else
+      {
+      typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
+      typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
+      
+           if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(-=, +); }
+      else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(-=, -); }
+      else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(-=, /); }
+      else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(-=, *); }
+      }
+    }
+  else
+    {
+    const ProxyCube<T1>& P1 = x.P1;
+    const ProxyCube<T2>& P2 = x.P2;
+    
+         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_3(-=, +); }
+    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_3(-=, -); }
+    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_3(-=, /); }
+    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_3(-=, *); }
+    }
+  }
+
+
+
+template<typename eglue_type>
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+eglue_core<eglue_type>::apply_inplace_schur(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword n_rows   = x.get_n_rows();
+  const uword n_cols   = x.get_n_cols();
+  const uword n_slices = x.get_n_slices();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise multiplication");
+  
+  typedef typename T1::elem_type eT;
+  
+  eT* out_mem = out.memptr();
+  
+  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    const uword n_elem = out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P1.is_aligned() && x.P2.is_aligned())
+        {
+        typename ProxyCube<T1>::aligned_ea_type P1 = x.P1.get_aligned_ea();
+        typename ProxyCube<T2>::aligned_ea_type P2 = x.P2.get_aligned_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1a(*=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1a(*=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1a(*=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1a(*=, *); }
+        }
+      else
+        {
+        typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
+        typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(*=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(*=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(*=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(*=, *); }
+        }
+      }
+    else
+      {
+      typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
+      typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
+      
+           if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(*=, +); }
+      else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(*=, -); }
+      else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(*=, /); }
+      else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(*=, *); }
+      }
+    }
+  else
+    {
+    const ProxyCube<T1>& P1 = x.P1;
+    const ProxyCube<T2>& P2 = x.P2;
+    
+         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_3(*=, +); }
+    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_3(*=, -); }
+    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_3(*=, /); }
+    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_3(*=, *); }
+    }
+  }
+
+
+
+template<typename eglue_type>
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+eglue_core<eglue_type>::apply_inplace_div(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword n_rows   = x.get_n_rows();
+  const uword n_cols   = x.get_n_cols();
+  const uword n_slices = x.get_n_slices();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise division");
+  
+  typedef typename T1::elem_type eT;
+  
+  eT* out_mem = out.memptr();
+  
+  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    const uword n_elem = out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P1.is_aligned() && x.P2.is_aligned())
+        {
+        typename ProxyCube<T1>::aligned_ea_type P1 = x.P1.get_aligned_ea();
+        typename ProxyCube<T2>::aligned_ea_type P2 = x.P2.get_aligned_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1a(/=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1a(/=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1a(/=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1a(/=, *); }
+        }
+      else
+        {
+        typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
+        typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
+        
+             if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(/=, +); }
+        else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(/=, -); }
+        else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(/=, /); }
+        else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(/=, *); }
+        }
+      }
+    else
+      {
+      typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
+      typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
+      
+           if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_1u(/=, +); }
+      else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_1u(/=, -); }
+      else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_1u(/=, /); }
+      else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_1u(/=, *); }
+      }
+    }
+  else
+    {
+    const ProxyCube<T1>& P1 = x.P1;
+    const ProxyCube<T2>& P2 = x.P2;
+    
+         if(is_same_type<eglue_type, eglue_plus >::value == true) { arma_applier_3(/=, +); }
+    else if(is_same_type<eglue_type, eglue_minus>::value == true) { arma_applier_3(/=, -); }
+    else if(is_same_type<eglue_type, eglue_div  >::value == true) { arma_applier_3(/=, /); }
+    else if(is_same_type<eglue_type, eglue_schur>::value == true) { arma_applier_3(/=, *); }
+    }
+  }
+
+
+
+#undef arma_applier_1u
+#undef arma_applier_1a
+#undef arma_applier_2
+#undef arma_applier_3
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/eop_aux.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,424 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup eop_aux
+//! @{
+
+
+
+template<typename eT>
+struct eop_aux_randu
+  {
+  arma_inline
+  operator eT ()
+    {
+    // make sure we are internally using at least floats
+    typedef typename promote_type<eT,float>::result eTp;
+    
+    return eT( eTp(std::rand()) * ( eTp(1) / eTp(RAND_MAX) ) );
+    }
+  
+  
+  inline
+  static
+  void
+  fill(eT* mem, const uword N)
+    {
+    uword i,j;
+    
+    for(i=0, j=1; j < N; i+=2, j+=2)
+      {
+      const eT tmp_i = eT(eop_aux_randu<eT>());
+      const eT tmp_j = eT(eop_aux_randu<eT>());
+      
+      mem[i] = tmp_i;
+      mem[j] = tmp_j;
+      }
+    
+    if(i < N)
+      {
+      mem[i] = eT(eop_aux_randu<eT>());
+      }
+    }
+  };
+
+
+  
+template<typename T>
+struct eop_aux_randu< std::complex<T> >
+  {
+  arma_inline
+  operator std::complex<T> ()
+    {
+    return std::complex<T>( T(eop_aux_randu<T>()), T(eop_aux_randu<T>()) );
+    }
+  
+  
+  inline
+  static
+  void
+  fill(std::complex<T>* mem, const uword N)
+    {
+    for(uword i=0; i < N; ++i)
+      {
+      mem[i] = std::complex<T>( eop_aux_randu< std::complex<T> >() );
+      }
+    }
+  };
+
+
+
+template<typename eT>
+struct eop_aux_randn
+  {
+  // rudimentary method, based on the central limit theorem:
+  // http://en.wikipedia.org/wiki/Central_limit_theorem
+  
+  // polar form of the Box-Muller transformation:
+  // http://en.wikipedia.org/wiki/Box-Muller_transformation
+  // http://en.wikipedia.org/wiki/Marsaglia_polar_method
+  
+  // other methods:
+  // http://en.wikipedia.org/wiki/Ziggurat_algorithm
+  //
+  // Marsaglia and Tsang Ziggurat technique to transform from a uniform to a normal distribution.
+  // G. Marsaglia, W.W. Tsang.
+  // "Ziggurat method for generating random variables",
+  // J. Statistical Software, vol 5, 2000.
+  // http://www.jstatsoft.org/v05/i08/
+  
+  
+  // currently using polar form of the Box-Muller transformation
+  inline
+  operator eT () const
+    {
+    // make sure we are internally using at least floats
+    typedef typename promote_type<eT,float>::result eTp;
+    
+    eTp tmp1;
+    eTp tmp2;
+    eTp w;
+    
+    do
+      {
+      tmp1 = eTp(2) * eTp(std::rand()) * (eTp(1) / eTp(RAND_MAX)) - eTp(1);
+      tmp2 = eTp(2) * eTp(std::rand()) * (eTp(1) / eTp(RAND_MAX)) - eTp(1);
+      
+      w = tmp1*tmp1 + tmp2*tmp2;
+      }
+    while ( w >= eTp(1) );
+    
+    return eT( tmp1 * std::sqrt( (eTp(-2) * std::log(w)) / w) );
+    }
+  
+  
+  
+  inline
+  static
+  void
+  generate(eT& out1, eT& out2)
+    {
+    // make sure we are internally using at least floats
+    typedef typename promote_type<eT,float>::result eTp;
+    
+    eTp tmp1;
+    eTp tmp2;
+    eTp w;
+    
+    do
+      {
+      tmp1 = eTp(2) * eTp(std::rand()) * (eTp(1) / eTp(RAND_MAX)) - eTp(1);
+      tmp2 = eTp(2) * eTp(std::rand()) * (eTp(1) / eTp(RAND_MAX)) - eTp(1);
+      
+      w = tmp1*tmp1 + tmp2*tmp2;
+      }
+    while ( w >= eTp(1) );
+    
+    const eTp k = std::sqrt( (eTp(-2) * std::log(w)) / w);
+    
+    out1 = eT(tmp1*k);
+    out2 = eT(tmp2*k);
+    }
+  
+  
+  
+  inline
+  static
+  void
+  fill(eT* mem, const uword N)
+    {
+    uword i, j;
+    
+    for(i=0, j=1; j < N; i+=2, j+=2)
+      {
+      eop_aux_randn<eT>::generate( mem[i], mem[j] );
+      }
+    
+    if(i < N)
+      {
+      mem[i] = eT(eop_aux_randn<eT>());
+      }
+    }
+  
+  };
+
+
+
+template<typename T>
+struct eop_aux_randn< std::complex<T> >
+  {
+  inline
+  operator std::complex<T> () const
+    {
+    T a, b;
+    
+    eop_aux_randn<T>::generate(a, b);
+    
+    return std::complex<T>(a, b);
+    }
+  
+  
+  inline
+  static
+  void
+  fill(std::complex<T>* mem, const uword N)
+    {
+    for(uword i=0; i < N; ++i)
+      {
+      mem[i] = std::complex<T>( eop_aux_randn< std::complex<T> >() );
+      }
+    }
+  
+  };
+
+
+
+//! use of the SFINAE approach to work around compiler limitations
+//! http://en.wikipedia.org/wiki/SFINAE
+
+class eop_aux
+  {
+  public:
+  
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result    acos  (const eT x) { return eT( std::acos(double(x)) ); }
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result    asin  (const eT x) { return eT( std::asin(double(x)) ); }
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result    atan  (const eT x) { return eT( std::atan(double(x)) ); }
+  
+  template<typename eT> arma_inline static typename arma_real_only<eT>::result        acos  (const eT x) { return std::acos(x); }
+  template<typename eT> arma_inline static typename arma_real_only<eT>::result        asin  (const eT x) { return std::asin(x); }
+  template<typename eT> arma_inline static typename arma_real_only<eT>::result        atan  (const eT x) { return std::atan(x); }
+  
+  template<typename eT> arma_inline static typename arma_cx_only<eT>::result          acos  (const eT x) { return arma_acos(x); }
+  template<typename eT> arma_inline static typename arma_cx_only<eT>::result          asin  (const eT x) { return arma_asin(x); }
+  template<typename eT> arma_inline static typename arma_cx_only<eT>::result          atan  (const eT x) { return arma_atan(x); }
+  
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result    acosh (const eT x) { return eT( arma_acosh(double(x)) ); }
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result    asinh (const eT x) { return eT( arma_asinh(double(x)) ); }
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result    atanh (const eT x) { return eT( arma_atanh(double(x)) ); }
+  
+  template<typename eT> arma_inline static typename arma_real_or_cx_only<eT>::result acosh (const eT x) { return arma_acosh(x); }
+  template<typename eT> arma_inline static typename arma_real_or_cx_only<eT>::result asinh (const eT x) { return arma_asinh(x); }
+  template<typename eT> arma_inline static typename arma_real_or_cx_only<eT>::result atanh (const eT x) { return arma_atanh(x); }
+  
+  template<typename eT> arma_inline static typename arma_not_cx<eT>::result conj(const eT               x) { return x;            }
+  template<typename  T> arma_inline static          std::complex<T>         conj(const std::complex<T>& x) { return std::conj(x); }
+  
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result sqrt  (const eT x) { return eT( std::sqrt (double(x)) ); }
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result log10 (const eT x) { return eT( std::log10(double(x)) ); }
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result log   (const eT x) { return eT( std::log  (double(x)) ); }
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result exp   (const eT x) { return eT( std::exp  (double(x)) ); }
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result cos   (const eT x) { return eT( std::cos  (double(x)) ); }
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result sin   (const eT x) { return eT( std::sin  (double(x)) ); }
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result tan   (const eT x) { return eT( std::tan  (double(x)) ); }
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result cosh  (const eT x) { return eT( std::cosh (double(x)) ); }
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result sinh  (const eT x) { return eT( std::sinh (double(x)) ); }
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result tanh  (const eT x) { return eT( std::tanh (double(x)) ); }
+  
+  template<typename eT> arma_inline static typename arma_real_or_cx_only<eT>::result sqrt  (const eT x) { return std::sqrt (x); }
+  template<typename eT> arma_inline static typename arma_real_or_cx_only<eT>::result log10 (const eT x) { return std::log10(x); }
+  template<typename eT> arma_inline static typename arma_real_or_cx_only<eT>::result log   (const eT x) { return std::log  (x); }
+  template<typename eT> arma_inline static typename arma_real_or_cx_only<eT>::result exp   (const eT x) { return std::exp  (x); }
+  template<typename eT> arma_inline static typename arma_real_or_cx_only<eT>::result cos   (const eT x) { return std::cos  (x); }
+  template<typename eT> arma_inline static typename arma_real_or_cx_only<eT>::result sin   (const eT x) { return std::sin  (x); }
+  template<typename eT> arma_inline static typename arma_real_or_cx_only<eT>::result tan   (const eT x) { return std::tan  (x); }
+  template<typename eT> arma_inline static typename arma_real_or_cx_only<eT>::result cosh  (const eT x) { return std::cosh (x); }
+  template<typename eT> arma_inline static typename arma_real_or_cx_only<eT>::result sinh  (const eT x) { return std::sinh (x); }
+  template<typename eT> arma_inline static typename arma_real_or_cx_only<eT>::result tanh  (const eT x) { return std::tanh (x); }
+  
+  template<typename eT> arma_inline static typename arma_unsigned_integral_only<eT>::result neg (const eT x) { return  x; }
+  template<typename eT> arma_inline static typename arma_signed_only<eT>::result            neg (const eT x) { return -x; }
+  
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result floor(const eT  x) { return x;                                                }
+  template<typename eT> arma_inline static typename arma_real_only<eT>::result     floor(const eT  x) { return std::floor(x);                                    }
+  template<typename eT> arma_inline static typename arma_cx_only<eT>::result       floor(const eT& x) { return eT( std::floor(x.real()), std::floor(x.imag()) ); }
+  
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result  ceil(const eT  x) { return x;                                                }
+  template<typename eT> arma_inline static typename arma_real_only<eT>::result      ceil(const eT  x) { return std::ceil(x);                                     }
+  template<typename eT> arma_inline static typename arma_cx_only<eT>::result        ceil(const eT& x) { return eT( std::ceil(x.real()), std::ceil(x.imag()) );   }
+  
+  template<typename eT> arma_inline static typename arma_integral_only<eT>::result round(const eT  x) { return x;                                                        }
+  template<typename eT> arma_inline static typename arma_real_only<eT>::result     round(const eT  x) { return (x >= eT(0)) ? std::floor(x+0.5) : std::ceil(x-0.5);      }
+  template<typename eT> arma_inline static typename arma_cx_only<eT>::result       round(const eT& x) { return eT( eop_aux::round(x.real()), eop_aux::round(x.imag()) ); }
+  
+  template<typename eT>
+  arma_inline
+  static
+  typename arma_integral_only<eT>::result
+  log2 (const eT x)
+    {
+    return eT( std::log(double(x))/ double(0.69314718055994530942) );
+    }
+  
+  
+  template<typename eT>
+  arma_inline
+  static
+  typename arma_real_or_cx_only<eT>::result
+  log2 (const eT x)
+    {
+    typedef typename get_pod_type<eT>::result T;
+    return std::log(x) / T(0.69314718055994530942);
+    }
+  
+  
+  template<typename eT>
+  arma_inline
+  static
+  typename arma_integral_only<eT>::result
+  exp10 (const eT x)
+    {
+    return eT( std::pow(double(10), double(x)) );
+    }
+  
+  
+  template<typename eT>
+  arma_inline
+  static
+  typename
+  arma_real_or_cx_only<eT>::result
+  exp10 (const eT x)
+    {
+    typedef typename get_pod_type<eT>::result T;
+    return std::pow( T(10), x);
+    }
+  
+  
+  template<typename eT>
+  arma_inline
+  static
+  typename arma_integral_only<eT>::result
+  exp2 (const eT x)
+    {
+    return eT( std::pow(double(2), double(x)) );
+    }
+  
+  
+  template<typename eT>
+  arma_inline
+  static
+  typename arma_real_or_cx_only<eT>::result
+  exp2 (const eT x)
+    {
+    typedef typename get_pod_type<eT>::result T;
+    return std::pow( T(2), x);
+    }
+  
+  
+  template<typename T1, typename T2>
+  arma_inline
+  static
+  typename arma_real_or_cx_only<T1>::result
+  pow(const T1 base, const T2 exponent)
+    {
+    return std::pow(base, exponent);
+    }
+  
+  
+  
+  template<typename T1, typename T2>
+  arma_inline
+  static
+  typename arma_integral_only<T1>::result
+  pow(const T1 base, const T2 exponent)
+    {
+    return T1( std::pow( double(base), double(exponent) ) );
+    }
+  
+  
+  
+  template<typename eT>
+  arma_inline
+  static
+  typename arma_integral_only<eT>::result
+  direct_eps(const eT)
+    {
+    return eT(0);
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  static
+  typename arma_real_only<eT>::result
+  direct_eps(const eT x)
+    {
+    //arma_extra_debug_sigprint();
+    
+    // acording to IEEE Standard for Floating-Point Arithmetic (IEEE 754)
+    // the mantissa length for double is 53 bits = std::numeric_limits<double>::digits
+    // the mantissa length for float  is 24 bits = std::numeric_limits<float >::digits
+    
+    //return std::pow( std::numeric_limits<eT>::radix, (std::floor(std::log10(std::abs(x))/std::log10(std::numeric_limits<eT>::radix))-(std::numeric_limits<eT>::digits-1)) );
+    
+    const eT radix_eT     = eT(std::numeric_limits<eT>::radix);
+    const eT digits_m1_eT = eT(std::numeric_limits<eT>::digits - 1);
+    
+    // return std::pow( radix_eT, eT(std::floor(std::log10(std::abs(x))/std::log10(radix_eT)) - digits_m1_eT) );
+    return eop_aux::pow( radix_eT, eT(std::floor(std::log10(std::abs(x))/std::log10(radix_eT)) - digits_m1_eT) );
+    }
+  
+  
+  
+  template<typename T>
+  inline
+  static
+  typename arma_real_only<T>::result
+  direct_eps(const std::complex<T> x)
+    {
+    //arma_extra_debug_sigprint();
+    
+    //return std::pow( std::numeric_limits<T>::radix, (std::floor(std::log10(std::abs(x))/std::log10(std::numeric_limits<T>::radix))-(std::numeric_limits<T>::digits-1)) );
+    
+    const T radix_T     = T(std::numeric_limits<T>::radix);
+    const T digits_m1_T = T(std::numeric_limits<T>::digits - 1);
+    
+    return std::pow( radix_T, T(std::floor(std::log10(std::abs(x))/std::log10(radix_T)) - digits_m1_T) );
+    }
+  
+  
+  
+  //! work around a bug in GCC 4.4
+  template<typename eT> arma_inline static
+  typename arma_unsigned_integral_only<eT>::result arma_abs(const eT x)              { return x;           }
+  
+  template<typename eT> arma_inline static
+  typename arma_signed_integral_only<eT>::result   arma_abs(const eT x)              { return std::abs(x); }
+  
+  template<typename eT> arma_inline static
+  typename arma_real_only<eT>::result              arma_abs(const eT x)              { return std::abs(x); }
+  
+  template<typename T> arma_inline static
+  typename arma_real_only<T>::result               arma_abs(const std::complex<T> x) { return std::abs(x); }
+  
+  };
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/eop_core_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,85 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup eop_core
+//! @{
+
+
+
+template<typename eop_type>
+class eop_core
+  {
+  public:
+  
+  // matrices
+  
+  template<typename T1> arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x);
+  
+  template<typename T1> arma_hot inline static void apply_inplace_plus (Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x);
+  template<typename T1> arma_hot inline static void apply_inplace_minus(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x);
+  template<typename T1> arma_hot inline static void apply_inplace_schur(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x);
+  template<typename T1> arma_hot inline static void apply_inplace_div  (Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x);
+  
+  
+  // cubes
+  
+  template<typename T1> arma_hot inline static void apply(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x);
+  
+  template<typename T1> arma_hot inline static void apply_inplace_plus (Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x);
+  template<typename T1> arma_hot inline static void apply_inplace_minus(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x);
+  template<typename T1> arma_hot inline static void apply_inplace_schur(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x);
+  template<typename T1> arma_hot inline static void apply_inplace_div  (Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x);
+  
+  
+  // common
+  
+  template<typename eT> arma_hot arma_pure arma_inline static eT process(const eT val, const eT k);
+  };
+
+
+
+class eop_neg               : public eop_core<eop_neg>               {};
+class eop_scalar_plus       : public eop_core<eop_scalar_plus>       {};
+class eop_scalar_minus_pre  : public eop_core<eop_scalar_minus_pre>  {};
+class eop_scalar_minus_post : public eop_core<eop_scalar_minus_post> {};
+class eop_scalar_times      : public eop_core<eop_scalar_times>      {};
+class eop_scalar_div_pre    : public eop_core<eop_scalar_div_pre>    {};
+class eop_scalar_div_post   : public eop_core<eop_scalar_div_post>   {};
+class eop_square            : public eop_core<eop_square>            {};
+class eop_sqrt              : public eop_core<eop_sqrt>              {};
+class eop_log               : public eop_core<eop_log>               {};
+class eop_log2              : public eop_core<eop_log2>              {};
+class eop_log10             : public eop_core<eop_log10>             {};
+class eop_trunc_log         : public eop_core<eop_trunc_log>         {};
+class eop_exp               : public eop_core<eop_exp>               {};
+class eop_exp2              : public eop_core<eop_exp2>              {};
+class eop_exp10             : public eop_core<eop_exp10>             {};
+class eop_trunc_exp         : public eop_core<eop_trunc_exp>         {};
+class eop_cos               : public eop_core<eop_cos>               {};
+class eop_sin               : public eop_core<eop_sin>               {};
+class eop_tan               : public eop_core<eop_tan>               {};
+class eop_acos              : public eop_core<eop_acos>              {};
+class eop_asin              : public eop_core<eop_asin>              {};
+class eop_atan              : public eop_core<eop_atan>              {};
+class eop_cosh              : public eop_core<eop_cosh>              {};
+class eop_sinh              : public eop_core<eop_sinh>              {};
+class eop_tanh              : public eop_core<eop_tanh>              {};
+class eop_acosh             : public eop_core<eop_acosh>             {};
+class eop_asinh             : public eop_core<eop_asinh>             {};
+class eop_atanh             : public eop_core<eop_atanh>             {};
+class eop_eps               : public eop_core<eop_eps>               {};
+class eop_abs               : public eop_core<eop_abs>               {};
+class eop_conj              : public eop_core<eop_conj>              {};
+class eop_pow               : public eop_core<eop_pow>               {};
+class eop_floor             : public eop_core<eop_floor>             {};
+class eop_ceil              : public eop_core<eop_ceil>              {};
+class eop_round             : public eop_core<eop_round>             {};
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/eop_core_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,855 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup eop_core
+//! @{
+
+
+#undef arma_applier_1u
+#undef arma_applier_1a
+#undef arma_applier_2
+#undef arma_applier_3
+#undef operatorA
+
+#define arma_applier_1u(operatorA) \
+  {\
+  uword i,j;\
+  \
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)\
+    {\
+    eT tmp_i = P[i];\
+    eT tmp_j = P[j];\
+    \
+    tmp_i = eop_core<eop_type>::process(tmp_i, k);\
+    tmp_j = eop_core<eop_type>::process(tmp_j, k);\
+    \
+    out_mem[i] operatorA tmp_i;\
+    out_mem[j] operatorA tmp_j;\
+    }\
+  \
+  if(i < n_elem)\
+    {\
+    out_mem[i] operatorA eop_core<eop_type>::process(P[i], k);\
+    }\
+  }
+
+
+#define arma_applier_1a(operatorA) \
+  {\
+  uword i,j;\
+  \
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)\
+    {\
+    eT tmp_i = P.at_alt(i);\
+    eT tmp_j = P.at_alt(j);\
+    \
+    tmp_i = eop_core<eop_type>::process(tmp_i, k);\
+    tmp_j = eop_core<eop_type>::process(tmp_j, k);\
+    \
+    out_mem[i] operatorA tmp_i;\
+    out_mem[j] operatorA tmp_j;\
+    }\
+  \
+  if(i < n_elem)\
+    {\
+    out_mem[i] operatorA eop_core<eop_type>::process(P.at_alt(i), k);\
+    }\
+  }
+
+
+#define arma_applier_2(operatorA) \
+  {\
+  if(n_rows != 1)\
+    {\
+    for(uword col=0; col<n_cols; ++col)\
+      {\
+      uword i,j;\
+      \
+      for(i=0, j=1; j<n_rows; i+=2, j+=2)\
+        {\
+        eT tmp_i = P.at(i,col);\
+        eT tmp_j = P.at(j,col);\
+        \
+        tmp_i = eop_core<eop_type>::process(tmp_i, k);\
+        tmp_j = eop_core<eop_type>::process(tmp_j, k);\
+        \
+        *out_mem operatorA tmp_i;  out_mem++;\
+        *out_mem operatorA tmp_j;  out_mem++;\
+        }\
+      \
+      if(i < n_rows)\
+        {\
+        *out_mem operatorA eop_core<eop_type>::process(P.at(i,col), k);  out_mem++;\
+        }\
+      }\
+    }\
+  else\
+    {\
+    for(uword count=0; count < n_cols; ++count)\
+      {\
+      out_mem[count] operatorA eop_core<eop_type>::process(P.at(0,count), k);\
+      }\
+    }\
+  }
+
+
+
+#define arma_applier_3(operatorA) \
+  {\
+  for(uword slice=0; slice<n_slices; ++slice)\
+    {\
+    for(uword col=0; col<n_cols; ++col)\
+      {\
+      uword i,j;\
+      \
+      for(i=0, j=1; j<n_rows; i+=2, j+=2)\
+        {\
+        eT tmp_i = P.at(i,col,slice);\
+        eT tmp_j = P.at(j,col,slice);\
+        \
+        tmp_i = eop_core<eop_type>::process(tmp_i, k);\
+        tmp_j = eop_core<eop_type>::process(tmp_j, k);\
+        \
+        *out_mem operatorA tmp_i; out_mem++; \
+        *out_mem operatorA tmp_j; out_mem++; \
+        }\
+      \
+      if(i < n_rows)\
+        {\
+        *out_mem operatorA eop_core<eop_type>::process(P.at(i,col,slice), k); out_mem++; \
+        }\
+      }\
+    }\
+  }
+
+
+
+//
+// matrices
+
+
+
+template<typename eop_type>
+template<typename T1>
+arma_hot
+inline
+void
+eop_core<eop_type>::apply(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing;
+  // size setting and alias checking is done by either the Mat contructor or operator=()
+  
+  const eT  k       = x.aux;
+        eT* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = (Proxy<T1>::is_fixed) ? x.get_n_elem() : out.n_elem;
+    
+    //if(memory::is_aligned(out_mem))
+    if( memory::is_aligned(out_mem) && ((Proxy<T1>::is_fixed) ? (x.get_n_elem() >= 32) : true) )
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P.is_aligned())
+        {
+        typename Proxy<T1>::aligned_ea_type P = x.P.get_aligned_ea();
+        
+        arma_applier_1a(=);
+        }
+      else
+        {
+        typename Proxy<T1>::ea_type P = x.P.get_ea();
+        
+        arma_applier_1u(=);
+        }
+      }
+    else
+      {
+      typename Proxy<T1>::ea_type P = x.P.get_ea();
+      
+      arma_applier_1u(=);
+      }
+    }
+  else
+    {
+    const uword n_rows = x.get_n_rows();
+    const uword n_cols = x.get_n_cols();
+    
+    const Proxy<T1>& P = x.P;
+    
+    arma_applier_2(=);
+    }
+  }
+
+
+
+template<typename eop_type>
+template<typename T1>
+arma_hot
+inline
+void
+eop_core<eop_type>::apply_inplace_plus(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword n_rows = x.get_n_rows();
+  const uword n_cols = x.get_n_cols();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "addition");
+  
+  const eT  k       = x.aux;
+        eT* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = (Proxy<T1>::is_fixed) ? x.get_n_elem() : out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P.is_aligned())
+        {
+        typename Proxy<T1>::aligned_ea_type P = x.P.get_aligned_ea();
+        
+        arma_applier_1a(+=);
+        }
+      else
+        {
+        typename Proxy<T1>::ea_type P = x.P.get_ea();
+        
+        arma_applier_1u(+=);
+        }
+      }
+    else
+      {
+      typename Proxy<T1>::ea_type P = x.P.get_ea();
+      
+      arma_applier_1u(+=);
+      }
+    }
+  else
+    {
+    const Proxy<T1>& P = x.P;
+    
+    arma_applier_2(+=);
+    }
+  }
+
+
+
+template<typename eop_type>
+template<typename T1>
+arma_hot
+inline
+void
+eop_core<eop_type>::apply_inplace_minus(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword n_rows = x.get_n_rows();
+  const uword n_cols = x.get_n_cols();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "subtraction");
+  
+  const eT  k       = x.aux;
+        eT* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = (Proxy<T1>::is_fixed) ? x.get_n_elem() : out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P.is_aligned())
+        {
+        typename Proxy<T1>::aligned_ea_type P = x.P.get_aligned_ea();
+        
+        arma_applier_1a(-=);
+        }
+      else
+        {
+        typename Proxy<T1>::ea_type P = x.P.get_ea();
+        
+        arma_applier_1u(-=);
+        }
+      }
+    else
+      {
+      typename Proxy<T1>::ea_type P = x.P.get_ea();
+      
+      arma_applier_1u(-=);
+      }
+    }
+  else
+    {
+    const Proxy<T1>& P = x.P;
+    
+    arma_applier_2(-=);
+    }
+  }
+
+
+
+template<typename eop_type>
+template<typename T1>
+arma_hot
+inline
+void
+eop_core<eop_type>::apply_inplace_schur(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword n_rows = x.get_n_rows();
+  const uword n_cols = x.get_n_cols();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise multiplication");
+  
+  const eT  k       = x.aux;
+        eT* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = (Proxy<T1>::is_fixed) ? x.get_n_elem() : out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P.is_aligned())
+        {
+        typename Proxy<T1>::aligned_ea_type P = x.P.get_aligned_ea();
+        
+        arma_applier_1a(*=);
+        }
+      else
+        {
+        typename Proxy<T1>::ea_type P = x.P.get_ea();
+        
+        arma_applier_1u(*=);
+        }
+      }
+    else
+      {
+      typename Proxy<T1>::ea_type P = x.P.get_ea();
+      
+      arma_applier_1u(*=);
+      }
+    }
+  else
+    {
+    const Proxy<T1>& P = x.P;
+    
+    arma_applier_2(*=);
+    }
+  }
+
+
+
+template<typename eop_type>
+template<typename T1>
+arma_hot
+inline
+void
+eop_core<eop_type>::apply_inplace_div(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword n_rows = x.get_n_rows();
+  const uword n_cols = x.get_n_cols();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise division");
+  
+  const eT  k       = x.aux;
+        eT* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = (Proxy<T1>::is_fixed) ? x.get_n_elem() : out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P.is_aligned())
+        {
+        typename Proxy<T1>::aligned_ea_type P = x.P.get_aligned_ea();
+        
+        arma_applier_1a(/=);
+        }
+      else
+        {
+        typename Proxy<T1>::ea_type P = x.P.get_ea();
+        
+        arma_applier_1u(/=);
+        }
+      }
+    else
+      {
+      typename Proxy<T1>::ea_type P = x.P.get_ea();
+      
+      arma_applier_1u(/=);
+      }
+    }
+  else
+    {
+    const Proxy<T1>& P = x.P;
+    
+    arma_applier_2(/=);
+    }
+  }
+
+
+
+//
+// cubes
+
+
+
+template<typename eop_type>
+template<typename T1>
+arma_hot
+inline
+void
+eop_core<eop_type>::apply(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing;
+  // size setting and alias checking is done by either the Mat contructor or operator=()
+  
+  const eT  k       = x.aux;
+        eT* out_mem = out.memptr();
+  
+  if(ProxyCube<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P.is_aligned())
+        {
+        typename ProxyCube<T1>::aligned_ea_type P = x.P.get_aligned_ea();
+        
+        arma_applier_1a(=);
+        }
+      else
+        {
+        typename ProxyCube<T1>::ea_type P = x.P.get_ea();
+        
+        arma_applier_1u(=);
+        }
+      }
+    else
+      {
+      typename ProxyCube<T1>::ea_type P = x.P.get_ea();
+      
+      arma_applier_1u(=);
+      }
+    }
+  else
+    {
+    const uword n_rows   = x.get_n_rows();
+    const uword n_cols   = x.get_n_cols();
+    const uword n_slices = x.get_n_slices();
+    
+    const ProxyCube<T1>& P = x.P;
+    
+    arma_applier_3(=);
+    }
+  }
+
+
+
+template<typename eop_type>
+template<typename T1>
+arma_hot
+inline
+void
+eop_core<eop_type>::apply_inplace_plus(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword n_rows   = x.get_n_rows();
+  const uword n_cols   = x.get_n_cols();
+  const uword n_slices = x.get_n_slices();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "addition");
+  
+  const eT  k       = x.aux;
+        eT* out_mem = out.memptr();
+  
+  if(ProxyCube<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P.is_aligned())
+        {
+        typename ProxyCube<T1>::aligned_ea_type P = x.P.get_aligned_ea();
+        
+        arma_applier_1a(+=);
+        }
+      else
+        {
+        typename ProxyCube<T1>::ea_type P = x.P.get_ea();
+        
+        arma_applier_1u(+=);
+        }
+      }
+    else
+      {
+      typename ProxyCube<T1>::ea_type P = x.P.get_ea();
+      
+      arma_applier_1u(+=);
+      }
+    }
+  else
+    {
+    const ProxyCube<T1>& P = x.P;
+    
+    arma_applier_3(+=);
+    }
+  }
+
+
+
+template<typename eop_type>
+template<typename T1>
+arma_hot
+inline
+void
+eop_core<eop_type>::apply_inplace_minus(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword n_rows   = x.get_n_rows();
+  const uword n_cols   = x.get_n_cols();
+  const uword n_slices = x.get_n_slices();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "subtraction");
+  
+  const eT  k       = x.aux;
+        eT* out_mem = out.memptr();
+  
+  if(ProxyCube<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P.is_aligned())
+        {
+        typename ProxyCube<T1>::aligned_ea_type P = x.P.get_aligned_ea();
+        
+        arma_applier_1a(-=);
+        }
+      else
+        {
+        typename ProxyCube<T1>::ea_type P = x.P.get_ea();
+        
+        arma_applier_1u(-=);
+        }
+      }
+    else
+      {
+      typename ProxyCube<T1>::ea_type P = x.P.get_ea();
+      
+      arma_applier_1u(-=);
+      }
+    }
+  else
+    {
+    const ProxyCube<T1>& P = x.P;
+    
+    arma_applier_3(-=);
+    }
+  }
+
+
+
+template<typename eop_type>
+template<typename T1>
+arma_hot
+inline
+void
+eop_core<eop_type>::apply_inplace_schur(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword n_rows   = x.get_n_rows();
+  const uword n_cols   = x.get_n_cols();
+  const uword n_slices = x.get_n_slices();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise multiplication");
+  
+  const eT  k       = x.aux;
+        eT* out_mem = out.memptr();
+  
+  if(ProxyCube<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P.is_aligned())
+        {
+        typename ProxyCube<T1>::aligned_ea_type P = x.P.get_aligned_ea();
+        
+        arma_applier_1a(*=);
+        }
+      else
+        {
+        typename ProxyCube<T1>::ea_type P = x.P.get_ea();
+        
+        arma_applier_1u(*=);
+        }
+      }
+    else
+      {
+      typename ProxyCube<T1>::ea_type P = x.P.get_ea();
+      
+      arma_applier_1u(*=);
+      }
+    }
+  else
+    {
+    const ProxyCube<T1>& P = x.P;
+    
+    arma_applier_3(*=);
+    }
+  }
+
+
+
+template<typename eop_type>
+template<typename T1>
+arma_hot
+inline
+void
+eop_core<eop_type>::apply_inplace_div(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword n_rows   = x.get_n_rows();
+  const uword n_cols   = x.get_n_cols();
+  const uword n_slices = x.get_n_slices();
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise division");
+  
+  const eT  k       = x.aux;
+        eT* out_mem = out.memptr();
+  
+  if(ProxyCube<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = out.n_elem;
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      if(x.P.is_aligned())
+        {
+        typename ProxyCube<T1>::aligned_ea_type P = x.P.get_aligned_ea();
+        
+        arma_applier_1a(/=);
+        }
+      else
+        {
+        typename ProxyCube<T1>::ea_type P = x.P.get_ea();
+        
+        arma_applier_1u(/=);
+        }
+      }
+    else
+      {
+      typename ProxyCube<T1>::ea_type P = x.P.get_ea();
+      
+      arma_applier_1u(/=);
+      }
+    }
+  else
+    {
+    const ProxyCube<T1>& P = x.P;
+    
+    arma_applier_3(/=);
+    }
+  }
+
+
+
+//
+// common
+
+
+
+template<typename eop_type>
+template<typename eT>
+arma_hot
+arma_pure
+arma_inline
+eT
+eop_core<eop_type>::process(const eT, const eT)
+  {
+  arma_stop("eop_core::process(): unhandled eop_type");
+  return eT(0);
+  }
+
+
+
+template<> template<typename eT> arma_hot arma_const arma_inline eT
+eop_core<eop_scalar_plus      >::process(const eT val, const eT k) { return val + k;                  }
+
+template<> template<typename eT> arma_hot arma_const arma_inline eT
+eop_core<eop_scalar_minus_pre >::process(const eT val, const eT k) { return k - val;                  }
+
+template<> template<typename eT> arma_hot arma_const arma_inline eT
+eop_core<eop_scalar_minus_post>::process(const eT val, const eT k) { return val - k;                  }
+
+template<> template<typename eT> arma_hot arma_const arma_inline eT
+eop_core<eop_scalar_times     >::process(const eT val, const eT k) { return val * k;                  }
+
+template<> template<typename eT> arma_hot arma_const arma_inline eT
+eop_core<eop_scalar_div_pre   >::process(const eT val, const eT k) { return k / val;                  }
+
+template<> template<typename eT> arma_hot arma_const arma_inline eT
+eop_core<eop_scalar_div_post  >::process(const eT val, const eT k) { return val / k;                  }
+
+template<> template<typename eT> arma_hot arma_const arma_inline eT
+eop_core<eop_square           >::process(const eT val, const eT  ) { return val*val;                  }
+
+template<> template<typename eT> arma_hot arma_const arma_inline eT
+eop_core<eop_neg              >::process(const eT val, const eT  ) { return eop_aux::neg(val);        }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_sqrt             >::process(const eT val, const eT  ) { return eop_aux::sqrt(val);       }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_log              >::process(const eT val, const eT  ) { return eop_aux::log(val);        }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_log2             >::process(const eT val, const eT  ) { return eop_aux::log2(val);       }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_log10            >::process(const eT val, const eT  ) { return eop_aux::log10(val);      }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_trunc_log        >::process(const eT val, const eT  ) { return    arma::trunc_log(val);  }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_exp              >::process(const eT val, const eT  ) { return eop_aux::exp(val);        }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_exp2             >::process(const eT val, const eT  ) { return eop_aux::exp2(val);       }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_exp10            >::process(const eT val, const eT  ) { return eop_aux::exp10(val);      }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_trunc_exp        >::process(const eT val, const eT  ) { return    arma::trunc_exp(val);  }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_cos              >::process(const eT val, const eT  ) { return eop_aux::cos(val);        }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_sin              >::process(const eT val, const eT  ) { return eop_aux::sin(val);        }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_tan              >::process(const eT val, const eT  ) { return eop_aux::tan(val);        }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_acos             >::process(const eT val, const eT  ) { return eop_aux::acos(val);       }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_asin             >::process(const eT val, const eT  ) { return eop_aux::asin(val);       }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_atan             >::process(const eT val, const eT  ) { return eop_aux::atan(val);       }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_cosh             >::process(const eT val, const eT  ) { return eop_aux::cosh(val);       }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_sinh             >::process(const eT val, const eT  ) { return eop_aux::sinh(val);       }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_tanh             >::process(const eT val, const eT  ) { return eop_aux::tanh(val);       }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_acosh            >::process(const eT val, const eT  ) { return eop_aux::acosh(val);      }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_asinh            >::process(const eT val, const eT  ) { return eop_aux::asinh(val);      }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_atanh            >::process(const eT val, const eT  ) { return eop_aux::atanh(val);      }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_eps              >::process(const eT val, const eT  ) { return eop_aux::direct_eps(val); }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_abs              >::process(const eT val, const eT  ) { return eop_aux::arma_abs(val);   }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_conj             >::process(const eT val, const eT  ) { return eop_aux::conj(val);       }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_pow              >::process(const eT val, const eT k) { return eop_aux::pow(val, k);     }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_floor            >::process(const eT val, const eT  ) { return eop_aux::floor(val);      }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_ceil             >::process(const eT val, const eT  ) { return eop_aux::ceil(val);       }
+
+template<> template<typename eT> arma_hot arma_pure arma_inline eT
+eop_core<eop_round            >::process(const eT val, const eT  ) { return eop_aux::round(val);      }
+
+
+#undef arma_applier_1u
+#undef arma_applier_1a
+#undef arma_applier_2
+#undef arma_applier_3
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fft_engine.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,409 @@
+// This Source Code Form is a compilation of:
+// (1) source code written by Conrad Sanderson, and
+// (2) a modified form of source code referred to as "kissfft.hh".
+// 
+// This compilation is Copyright (C) 2013 Conrad Sanderson
+// and is subject to the terms of the Mozilla Public License, v. 2.0.
+// 
+// The source code that is distinct and separate from "kissfft.hh"
+// is Copyright (C) 2013 Conrad Sanderson and is subject to the
+// terms of the Mozilla Public License, v. 2.0.
+// 
+// If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+// 
+// The original "kissfft.hh" source code is licensed under a 3-clause BSD license,
+// as follows:
+// 
+// Copyright (c) 2003-2010 Mark Borgerding
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+// 
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// 
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// 
+// * Neither the author nor the names of any contributors may be used to endorse or promote
+//   products derived from this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+template<typename cx_type, uword fixed_N, bool> struct store {};
+
+template<typename cx_type, uword fixed_N>
+struct store<cx_type, fixed_N, true>
+  {
+  static const uword N = fixed_N;
+  
+  arma_aligned cx_type coeffs_array[fixed_N];
+  
+  inline store()      {}
+  inline store(uword) {}
+  
+  arma_inline       cx_type* coeffs_ptr()       { return &coeffs_array[0]; }
+  arma_inline const cx_type* coeffs_ptr() const { return &coeffs_array[0]; }
+  };
+
+
+
+template<typename cx_type, uword fixed_N>
+struct store<cx_type, fixed_N, false>
+  {
+  const uword N;
+  
+  podarray<cx_type> coeffs_array;
+  
+  inline store()           : N(0)    {}
+  inline store(uword in_N) : N(in_N) { coeffs_array.set_size(N); }
+  
+  arma_inline       cx_type* coeffs_ptr()       { return coeffs_array.memptr(); }
+  arma_inline const cx_type* coeffs_ptr() const { return coeffs_array.memptr(); }
+  };
+
+
+
+template<typename cx_type, bool inverse, uword fixed_N = 0>
+class fft_engine : public store<cx_type, fixed_N, (fixed_N > 0)>
+  {
+  public:
+  
+  typedef typename get_pod_type<cx_type>::result T;
+  
+  using store<cx_type, fixed_N, (fixed_N > 0)>::N;
+  using store<cx_type, fixed_N, (fixed_N > 0)>::coeffs_ptr;
+  
+  podarray<uword>   residue;
+  podarray<uword>   radix;
+  
+  podarray<cx_type> tmp_array;
+  
+  
+  template<bool fill>
+  inline
+  uword
+  calc_radix()
+    {
+    uword i = 0;
+    
+    for(uword n = N, r=4; n >= 2; ++i)
+      {
+      while( (n % r) > 0 )
+        {
+        switch(r)
+          {
+          case 2:  r  = 3; break;
+          case 4:  r  = 2; break;
+          default: r += 2; break;
+          }
+        
+        if(r*r > n) { r = n; }
+        }
+      
+      n /= r;
+      
+      if(fill)
+        {
+        residue[i] = n;
+          radix[i] = r;
+        }
+      }
+    
+    return i;
+    }
+  
+  
+  
+  inline
+  fft_engine(const uword in_N)
+    : store< cx_type, fixed_N, (fixed_N > 0) >(in_N)
+    {
+    arma_extra_debug_sigprint();
+    
+    const uword len = calc_radix<false>();
+    
+    residue.set_size(len);
+      radix.set_size(len);
+    
+    calc_radix<true>();
+    
+    
+    // calculate the constant coefficients
+    
+    cx_type* coeffs = coeffs_ptr();
+    
+    const T k = T( (inverse) ? +2 : -2 ) * std::acos( T(-1) ) / T(N);
+    
+    for(uword i=0; i < N; ++i)  { coeffs[i] = std::exp( cx_type(T(0), i*k) ); }
+    }
+  
+  
+  
+  arma_hot
+  inline
+  void
+  butterfly_2(cx_type* Y, const uword stride, const uword m)
+    {
+    arma_extra_debug_sigprint();
+    
+    const cx_type* coeffs = coeffs_ptr();
+    
+    for(uword i=0; i < m; ++i)
+      {
+      const cx_type t = Y[i+m] * coeffs[i*stride];
+      
+      Y[i+m] =  Y[i] - t;
+      Y[i  ] += t;
+      }
+    }
+  
+  
+  
+  arma_hot
+  inline
+  void
+  butterfly_3(cx_type* Y, const uword stride, const uword m)
+    {
+    arma_extra_debug_sigprint();
+    
+    arma_aligned cx_type tmp[5];
+    
+    cx_type* coeffs1 = coeffs_ptr();
+    cx_type* coeffs2 = coeffs1;
+    
+    const T coeff_sm_imag = coeffs1[stride*m].imag();
+    
+    const uword n = m*2;
+    
+    // TODO: rearrange the indices within tmp[] into a more sane order
+    
+    for(uword i = m; i > 0; --i)
+      {
+      tmp[1] = Y[m] * (*coeffs1);
+      tmp[2] = Y[n] * (*coeffs2);
+      
+      tmp[0]  = tmp[1] - tmp[2];
+      tmp[0] *= coeff_sm_imag;
+      
+      tmp[3] = tmp[1] + tmp[2];
+      
+      Y[m] = cx_type( (Y[0].real() - (0.5*tmp[3].real())), (Y[0].imag() - (0.5*tmp[3].imag())) );
+      
+      Y[0] += tmp[3];
+      
+      
+      Y[n] = cx_type( (Y[m].real() + tmp[0].imag()), (Y[m].imag() - tmp[0].real()) );
+      
+      Y[m] += cx_type( -tmp[0].imag(), tmp[0].real() );
+      
+      Y++;
+      
+      coeffs1 += stride;
+      coeffs2 += stride*2;
+      }
+    }
+  
+  
+  
+  arma_hot
+  inline
+  void
+  butterfly_4(cx_type* Y, const uword stride, const uword m)
+    {
+    arma_extra_debug_sigprint();
+    
+    arma_aligned cx_type tmp[7];
+    
+    const cx_type* coeffs = coeffs_ptr();
+    
+    const uword m2 = m*2;
+    const uword m3 = m*3;
+    
+    // TODO: rearrange the indices within tmp[] into a more sane order
+    
+    for(uword i=0; i < m; ++i)
+      {
+      tmp[0] = Y[i + m ] * coeffs[i*stride  ];
+      tmp[2] = Y[i + m3] * coeffs[i*stride*3];
+      tmp[3] = tmp[0] + tmp[2];
+      
+      //tmp[4] = tmp[0] - tmp[2];
+      //tmp[4] = (inverse) ? cx_type( -(tmp[4].imag()), tmp[4].real() ) : cx_type( tmp[4].imag(), -tmp[4].real() );
+      
+      tmp[4] = (inverse)
+                 ? cx_type( (tmp[2].imag() - tmp[0].imag()), (tmp[0].real() - tmp[2].real()) )
+                 : cx_type( (tmp[0].imag() - tmp[2].imag()), (tmp[2].real() - tmp[0].real()) );
+      
+      tmp[1] = Y[i + m2] * coeffs[i*stride*2];
+      tmp[5] = Y[i] - tmp[1];
+      
+      
+      Y[i     ] += tmp[1];
+      Y[i + m2]  = Y[i] - tmp[3];
+      Y[i     ] += tmp[3];
+      Y[i + m ]  = tmp[5] + tmp[4];
+      Y[i + m3]  = tmp[5] - tmp[4];
+      }
+    }
+  
+  
+  
+  inline
+  arma_hot
+  void
+  butterfly_5(cx_type* Y, const uword stride, const uword m)
+    {
+    arma_extra_debug_sigprint();
+    
+    arma_aligned cx_type tmp[13];
+    
+    const cx_type* coeffs = coeffs_ptr();
+    
+    const T a_real = coeffs[stride*1*m].real();
+    const T a_imag = coeffs[stride*1*m].imag();
+    
+    const T b_real = coeffs[stride*2*m].real();
+    const T b_imag = coeffs[stride*2*m].imag();
+    
+    cx_type* Y0 = Y;
+    cx_type* Y1 = Y + 1*m;
+    cx_type* Y2 = Y + 2*m;
+    cx_type* Y3 = Y + 3*m;
+    cx_type* Y4 = Y + 4*m;
+    
+    for(uword i=0; i < m; ++i)
+      {
+      tmp[0] = (*Y0);
+      
+      tmp[1] = (*Y1) * coeffs[stride*1*i];
+      tmp[2] = (*Y2) * coeffs[stride*2*i];
+      tmp[3] = (*Y3) * coeffs[stride*3*i];
+      tmp[4] = (*Y4) * coeffs[stride*4*i];
+      
+      tmp[7]  = tmp[1] + tmp[4];
+      tmp[8]  = tmp[2] + tmp[3];
+      tmp[9]  = tmp[2] - tmp[3];
+      tmp[10] = tmp[1] - tmp[4];
+      
+      (*Y0) += tmp[7];
+      (*Y0) += tmp[8];
+      
+      tmp[5] = tmp[0] + cx_type( ( (tmp[7].real() * a_real) + (tmp[8].real() * b_real) ), ( (tmp[7].imag() * a_real) + (tmp[8].imag() * b_real) ) );
+      
+      tmp[6] =  cx_type( ( (tmp[10].imag() * a_imag) + (tmp[9].imag() * b_imag) ), ( -(tmp[10].real() * a_imag) - (tmp[9].real() * b_imag) ) );
+      
+      (*Y1) = tmp[5] - tmp[6];
+      (*Y4) = tmp[5] + tmp[6];
+      
+      tmp[11] = tmp[0] +  cx_type( ( (tmp[7].real() * b_real) + (tmp[8].real() * a_real) ), ( (tmp[7].imag() * b_real) + (tmp[8].imag() * a_real) ) );
+      
+      tmp[12] = cx_type( ( -(tmp[10].imag() * b_imag) + (tmp[9].imag() * a_imag) ), (  (tmp[10].real() * b_imag) - (tmp[9].real() * a_imag) ) );
+      
+      (*Y2) = tmp[11] + tmp[12];
+      (*Y3) = tmp[11] - tmp[12];
+      
+      Y0++;
+      Y1++;
+      Y2++;
+      Y3++;
+      Y4++;
+      }
+    }
+  
+  
+  
+  arma_hot
+  inline
+  void
+  butterfly_N(cx_type* Y, const uword stride, const uword m, const uword r)
+    {
+    arma_extra_debug_sigprint();
+    
+    const cx_type* coeffs = coeffs_ptr();
+    
+    tmp_array.set_min_size(r);
+    cx_type* tmp = tmp_array.memptr();
+    
+    for(uword u=0; u < m; ++u)
+      {
+      uword k = u;
+      
+      for(uword v=0; v < r; ++v)
+        {
+        tmp[v] = Y[k];
+        k += m;
+        }
+      
+      k = u;
+      
+      for(uword v=0; v < r; ++v)
+        {
+        Y[k] = tmp[0];
+        
+        uword j = 0;
+        
+        for(uword w=1; w < r; ++w)
+          {
+          j += stride * k;
+          
+          if(j >= N) { j -= N; }
+          
+          Y[k] += tmp[w] * coeffs[j];
+          }
+        
+        k += m;
+        }
+      }
+    }
+  
+  
+  
+  inline
+  void
+  run(cx_type* Y, const cx_type* X, const uword stage = 0, const uword stride = 1)
+    {
+    arma_extra_debug_sigprint();
+    
+    const uword m = residue[stage];
+    const uword r =   radix[stage];
+    
+    const cx_type *Y_end = Y + r*m;
+    
+    if(m == 1)
+      {
+      for(cx_type* Yi = Y; Yi != Y_end; Yi++, X += stride)  {  (*Yi) = (*X);  }
+      }
+    else
+      {
+      const uword next_stage  = stage + 1;
+      const uword next_stride = stride * r;
+      
+      for(cx_type* Yi = Y; Yi != Y_end; Yi += m, X += stride)  { run(Yi, X, next_stage, next_stride); }
+      }
+    
+    switch(r)
+      {
+      case 2:  butterfly_2(Y, stride, m   );  break;
+      case 3:  butterfly_3(Y, stride, m   );  break;
+      case 4:  butterfly_4(Y, stride, m   );  break;
+      case 5:  butterfly_5(Y, stride, m   );  break;
+      default: butterfly_N(Y, stride, m, r);  break;
+      }
+    }
+
+
+  };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/field_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,265 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// Copyright (C) 2009-2010 Ian Cullinan
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup field
+//! @{
+
+
+
+struct field_prealloc_n_elem
+  {
+  static const uword val = 16;
+  };
+
+
+
+//! A lightweight 2D container for abitrary objects
+//! (the objects must have a copy constructor)
+
+template<typename oT>
+class field
+  {
+  public:
+  
+  typedef oT object_type;
+  
+  const uword n_rows;     //!< number of rows in the field (read-only)
+  const uword n_cols;     //!< number of columns in the field (read-only)
+  const uword n_elem;     //!< number of elements in the field (read-only)
+  
+  
+  private:
+  
+  arma_aligned oT** mem;                                     //!< pointer to memory used by the object
+  arma_aligned oT*  mem_local[ field_prealloc_n_elem::val ]; //!< Internal memory, to avoid calling the 'new' operator for small amounts of memory
+  
+  
+  public:
+  
+  inline ~field();
+  inline  field();
+  
+  inline                  field(const field& x);
+  inline const field& operator=(const field& x);
+  
+  inline                  field(const subview_field<oT>& x);
+  inline const field& operator=(const subview_field<oT>& x);
+  
+  inline explicit field(const uword n_elem_in);
+  inline          field(const uword n_rows_in, const uword n_cols_in);
+  
+  inline void  set_size(const uword n_obj_in);
+  inline void  set_size(const uword n_rows_in, const uword n_cols_in);
+  
+  template<typename oT2>
+  inline void copy_size(const field<oT2>& x);
+  
+  arma_inline       oT& operator[](const uword i);
+  arma_inline const oT& operator[](const uword i) const;
+  
+  arma_inline       oT&         at(const uword i);
+  arma_inline const oT&         at(const uword i) const;
+  
+  arma_inline       oT& operator()(const uword i);
+  arma_inline const oT& operator()(const uword i) const;
+  
+  arma_inline       oT&         at(const uword row, const uword col);
+  arma_inline const oT&         at(const uword row, const uword col) const;
+  
+  arma_inline       oT& operator()(const uword row, const uword col);
+  arma_inline const oT& operator()(const uword row, const uword col) const;
+  
+  inline field_injector<field> operator<<(const oT& val);
+  inline field_injector<field> operator<<(const injector_end_of_row<>& x);
+  
+  
+  inline       subview_field<oT> row(const uword row_num);
+  inline const subview_field<oT> row(const uword row_num) const;
+  
+  inline       subview_field<oT> col(const uword col_num);
+  inline const subview_field<oT> col(const uword col_num) const;
+  
+  inline       subview_field<oT> rows(const uword in_row1, const uword in_row2);
+  inline const subview_field<oT> rows(const uword in_row1, const uword in_row2) const;
+  
+  inline       subview_field<oT> cols(const uword in_col1, const uword in_col2);
+  inline const subview_field<oT> cols(const uword in_col1, const uword in_col2) const;
+  
+  inline       subview_field<oT> subfield(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2);
+  inline const subview_field<oT> subfield(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const;
+  
+  inline       subview_field<oT> subfield  (const span& row_span, const span& col_span);
+  inline const subview_field<oT> subfield  (const span& row_span, const span& col_span) const;
+  
+  inline       subview_field<oT> operator()(const span& row_span, const span& col_span);
+  inline const subview_field<oT> operator()(const span& row_span, const span& col_span) const;
+  
+  
+  inline void print(const std::string extra_text = "") const;
+  inline void print(std::ostream& user_stream, const std::string extra_text = "") const;
+  
+  inline void fill(const oT& x);
+  
+  inline void reset();
+  inline void reset_objects();
+  
+  arma_inline bool is_empty() const;
+  
+  arma_inline arma_warn_unused bool in_range(const uword i) const;
+  arma_inline arma_warn_unused bool in_range(const span& x) const;
+  
+  arma_inline arma_warn_unused bool in_range(const uword   in_row, const uword   in_col) const;
+  arma_inline arma_warn_unused bool in_range(const span& row_span, const uword   in_col) const;
+  arma_inline arma_warn_unused bool in_range(const uword   in_row, const span& col_span) const;
+  arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span) const;
+  
+  inline bool save(const std::string   name, const file_type type = arma_binary, const bool print_status = true) const;
+  inline bool save(      std::ostream& os,   const file_type type = arma_binary, const bool print_status = true) const;
+  
+  inline bool load(const std::string   name, const file_type type = auto_detect, const bool print_status = true);
+  inline bool load(      std::istream& is,   const file_type type = auto_detect, const bool print_status = true);
+  
+  
+  inline bool quiet_save(const std::string   name, const file_type type = arma_binary) const;
+  inline bool quiet_save(      std::ostream& os,   const file_type type = arma_binary) const;
+  
+  inline bool quiet_load(const std::string   name, const file_type type = auto_detect);
+  inline bool quiet_load(      std::istream& is,   const file_type type = auto_detect);
+  
+  
+  // for container-like functionality
+  
+  typedef oT    value_type;
+  typedef uword size_type;
+    
+  
+  class iterator
+    {
+    public:
+    
+    inline iterator(field<oT>& in_M, const bool at_end = false);
+    
+    inline oT& operator* ();
+    
+    inline iterator& operator++();
+    inline void      operator++(int);
+    
+    inline iterator& operator--();
+    inline void      operator--(int);
+    
+    inline bool operator!=(const iterator& X) const;
+    inline bool operator==(const iterator& X) const;
+    
+    arma_aligned field<oT>& M;
+    arma_aligned uword      i;
+    };
+  
+  
+  class const_iterator
+    {
+    public:
+    
+    const_iterator(const field<oT>& in_M, const bool at_end = false);
+    const_iterator(const iterator& X);
+    
+    inline const oT& operator*() const;
+    
+    inline const_iterator& operator++();
+    inline void            operator++(int);
+    
+    inline const_iterator& operator--();
+    inline void            operator--(int);
+    
+    inline bool operator!=(const const_iterator& X) const;
+    inline bool operator==(const const_iterator& X) const;
+    
+    arma_aligned const field<oT>& M;
+    arma_aligned       uword      i;
+    };
+  
+  inline       iterator  begin();
+  inline const_iterator  begin() const;
+  inline const_iterator cbegin() const;
+  
+  inline       iterator  end();
+  inline const_iterator  end() const;
+  inline const_iterator cend() const;
+  
+  inline void  clear();
+  inline bool  empty() const;
+  inline uword size()  const;
+  
+    
+  private:
+  
+  inline void init(const field<oT>& x);
+  inline void init(const uword n_rows_in, const uword n_cols_in);
+  
+  inline void delete_objects();
+  inline void create_objects();
+  
+  friend class field_aux;
+  friend class subview_field<oT>;
+  
+  
+  public:
+  
+  #ifdef ARMA_EXTRA_FIELD_PROTO
+    #include ARMA_INCFILE_WRAP(ARMA_EXTRA_FIELD_PROTO)
+  #endif
+  };
+
+
+
+class field_aux
+  {
+  public:
+  
+  template<typename oT> inline static void reset_objects(field< oT >& x);
+  template<typename eT> inline static void reset_objects(field< Mat<eT> >& x);
+  template<typename eT> inline static void reset_objects(field< Col<eT> >& x);
+  template<typename eT> inline static void reset_objects(field< Row<eT> >& x);
+  template<typename eT> inline static void reset_objects(field< Cube<eT> >& x);
+                        inline static void reset_objects(field< std::string >& x);
+  
+  
+  template<typename oT> inline static bool save(const field< oT >& x,       const std::string&  name, const file_type type, std::string& err_msg);
+  template<typename oT> inline static bool save(const field< oT >& x,             std::ostream& os,   const file_type type, std::string& err_msg);
+  template<typename oT> inline static bool load(      field< oT >& x,       const std::string&  name, const file_type type, std::string& err_msg);
+  template<typename oT> inline static bool load(      field< oT >& x,             std::istream& is,   const file_type type, std::string& err_msg);
+
+  template<typename eT> inline static bool save(const field< Mat<eT> >& x,  const std::string&  name, const file_type type, std::string& err_msg);
+  template<typename eT> inline static bool save(const field< Mat<eT> >& x,        std::ostream& os,   const file_type type, std::string& err_msg);
+  template<typename eT> inline static bool load(      field< Mat<eT> >& x,  const std::string&  name, const file_type type, std::string& err_msg);
+  template<typename eT> inline static bool load(      field< Mat<eT> >& x,        std::istream& is,   const file_type type, std::string& err_msg);
+  
+  template<typename eT> inline static bool save(const field< Col<eT> >& x,  const std::string&  name, const file_type type, std::string& err_msg);
+  template<typename eT> inline static bool save(const field< Col<eT> >& x,        std::ostream& os,   const file_type type, std::string& err_msg);
+  template<typename eT> inline static bool load(      field< Col<eT> >& x,  const std::string&  name, const file_type type, std::string& err_msg);
+  template<typename eT> inline static bool load(      field< Col<eT> >& x,        std::istream& is,   const file_type type, std::string& err_msg);
+  
+  template<typename eT> inline static bool save(const field< Row<eT> >& x,  const std::string&  name, const file_type type, std::string& err_msg);
+  template<typename eT> inline static bool save(const field< Row<eT> >& x,        std::ostream& os,   const file_type type, std::string& err_msg);
+  template<typename eT> inline static bool load(      field< Row<eT> >& x,  const std::string&  name, const file_type type, std::string& err_msg);
+  template<typename eT> inline static bool load(      field< Row<eT> >& x,        std::istream& is,   const file_type type, std::string& err_msg);
+
+  template<typename eT> inline static bool save(const field< Cube<eT> >& x, const std::string&  name, const file_type type, std::string& err_msg);
+  template<typename eT> inline static bool save(const field< Cube<eT> >& x,       std::ostream& os,   const file_type type, std::string& err_msg);
+  template<typename eT> inline static bool load(      field< Cube<eT> >& x, const std::string&  name, const file_type type, std::string& err_msg);
+  template<typename eT> inline static bool load(      field< Cube<eT> >& x,       std::istream& is,   const file_type type, std::string& err_msg);
+  
+  inline static bool save(const field< std::string >& x, const std::string&  name, const file_type type, std::string& err_msg);
+  inline static bool save(const field< std::string >& x,       std::ostream& os,   const file_type type, std::string& err_msg);
+  inline static bool load(      field< std::string >& x, const std::string&  name, const file_type type, std::string& err_msg);
+  inline static bool load(      field< std::string >& x,       std::istream& is,   const file_type type, std::string& err_msg);
+  
+  };
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/field_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,2070 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// Copyright (C) 2009-2010 Ian Cullinan
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup field
+//! @{
+
+
+template<typename oT>
+inline
+field<oT>::~field()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  delete_objects();
+  
+  if(n_elem > sizeof(mem_local)/sizeof(oT*) )
+    {
+    delete [] mem;
+    }
+  
+  if(arma_config::debug == true)
+    {
+    // try to expose buggy user code that accesses deleted objects
+    access::rw(n_rows) = 0;
+    access::rw(n_cols) = 0;
+    access::rw(n_elem) = 0;
+    mem = 0;
+    }
+  }
+
+
+
+template<typename oT>
+inline
+field<oT>::field()
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , mem(0)
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+//! construct a field from a given field
+template<typename oT>
+inline
+field<oT>::field(const field& x)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , mem(0)
+  {
+  arma_extra_debug_sigprint(arma_boost::format("this = %x   x = %x") % this % &x);
+  
+  init(x);
+  }
+
+
+
+//! construct a field from a given field
+template<typename oT>
+inline
+const field<oT>&
+field<oT>::operator=(const field& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  init(x);
+  return *this;
+  }
+
+
+
+//! construct a field from subview_field (e.g. construct a field from a delayed subfield operation)
+template<typename oT>
+inline
+field<oT>::field(const subview_field<oT>& X)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , mem(0)
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  this->operator=(X);
+  }
+
+
+
+//! construct a field from subview_field (e.g. construct a field from a delayed subfield operation)
+template<typename oT>
+inline
+const field<oT>&
+field<oT>::operator=(const subview_field<oT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_field<oT>::extract(*this, X);
+  return *this;
+  }
+
+
+
+//! construct the field with the specified number of elements,
+//! assuming a column-major layout
+template<typename oT>
+inline
+field<oT>::field(const uword n_elem_in)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , mem(0)
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init(n_elem_in, 1);
+  }
+
+
+
+//! construct the field with the specified dimensions
+template<typename oT>
+inline
+field<oT>::field(const uword n_rows_in, const uword n_cols_in)
+  : n_rows(0)
+  , n_cols(0)
+  , n_elem(0)
+  , mem(0)
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init(n_rows_in, n_cols_in);
+  }
+
+
+
+//! change the field to have the specified number of elements,
+//! assuming a column-major layout (data is not preserved)
+template<typename oT>
+inline
+void
+field<oT>::set_size(const uword n_elem_in)
+  {
+  arma_extra_debug_sigprint(arma_boost::format("n_elem_in = %d") % n_elem_in);
+  
+  init(n_elem_in, 1);
+  }
+
+
+
+//! change the field to have the specified dimensions (data is not preserved)
+template<typename oT>
+inline
+void
+field<oT>::set_size(const uword n_rows_in, const uword n_cols_in)
+  {
+  arma_extra_debug_sigprint(arma_boost::format("n_rows_in = %d, n_cols_in = %d") % n_rows_in % n_cols_in);
+  
+  init(n_rows_in, n_cols_in);
+  }
+
+
+
+//! change the field to have the specified dimensions (data is not preserved)
+template<typename oT>
+template<typename oT2>
+inline
+void
+field<oT>::copy_size(const field<oT2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  init(x.n_rows, x.n_cols);
+  }
+
+
+
+//! linear element accessor (treats the field as a vector); no bounds check
+template<typename oT>
+arma_inline
+oT&
+field<oT>::operator[] (const uword i)
+  {
+  return (*mem[i]);
+  }
+  
+  
+  
+//! linear element accessor (treats the field as a vector); no bounds check
+template<typename oT>
+arma_inline
+const oT&
+field<oT>::operator[] (const uword i) const
+  {
+  return (*mem[i]);
+  }
+
+
+
+//! linear element accessor (treats the field as a vector); no bounds check
+template<typename oT>
+arma_inline
+oT&
+field<oT>::at(const uword i)
+  {
+  return (*mem[i]);
+  }
+  
+  
+  
+//! linear element accessor (treats the field as a vector); no bounds check
+template<typename oT>
+arma_inline
+const oT&
+field<oT>::at(const uword i) const
+  {
+  return (*mem[i]);
+  }
+
+
+
+//! linear element accessor (treats the field as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
+template<typename oT>
+arma_inline
+oT&
+field<oT>::operator() (const uword i)
+  {
+  arma_debug_check( (i >= n_elem), "field::operator(): index out of bounds");
+  return (*mem[i]);
+  }
+  
+  
+  
+//! linear element accessor (treats the field as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
+template<typename oT>
+arma_inline
+const oT&
+field<oT>::operator() (const uword i) const
+  {
+  arma_debug_check( (i >= n_elem), "field::operator(): index out of bounds");
+  return (*mem[i]);
+  }
+
+
+
+//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
+template<typename oT>
+arma_inline
+oT&
+field<oT>::operator() (const uword in_row, const uword in_col)
+  {
+  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "field::operator(): index out of bounds");
+  return (*mem[in_row + in_col*n_rows]);
+  }
+
+
+
+//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
+template<typename oT>
+arma_inline
+const oT&
+field<oT>::operator() (const uword in_row, const uword in_col) const
+  {
+  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "field::operator(): index out of bounds");
+  return (*mem[in_row + in_col*n_rows]);
+  }
+
+
+
+//! element accessor; no bounds check
+template<typename oT>
+arma_inline
+oT&
+field<oT>::at(const uword in_row, const uword in_col)
+  {
+  return (*mem[in_row + in_col*n_rows]);
+  }
+
+
+
+//! element accessor; no bounds check
+template<typename oT>
+arma_inline
+const oT&
+field<oT>::at(const uword in_row, const uword in_col) const
+  {
+  return (*mem[in_row + in_col*n_rows]);
+  }
+
+
+
+template<typename oT>
+inline
+field_injector< field<oT> >
+field<oT>::operator<<(const oT& val)
+  {
+  return field_injector< field<oT> >(*this, val);
+  }
+
+
+
+template<typename oT>
+inline
+field_injector< field<oT> >
+field<oT>::operator<<(const injector_end_of_row<>& x)
+  {
+  return field_injector< field<oT> >(*this, x);
+  }
+
+
+
+//! creation of subview_field (row of a field)
+template<typename oT>
+inline
+subview_field<oT>
+field<oT>::row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= n_rows), "field::row(): row out of bounds" );
+  
+  return subview_field<oT>(*this, row_num, 0, 1, n_cols);
+  }
+
+
+
+//! creation of subview_field (row of a field)
+template<typename oT>
+inline
+const subview_field<oT>
+field<oT>::row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (row_num >= n_rows), "field::row(): row out of bounds" );
+  
+  return subview_field<oT>(*this, row_num, 0, 1, n_cols);
+  }
+
+
+
+//! creation of subview_field (column of a field)
+template<typename oT>
+inline
+subview_field<oT>
+field<oT>::col(const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (col_num >= n_cols), "field::col(): out of bounds");
+  
+  return subview_field<oT>(*this, 0, col_num, n_rows, 1);
+  }
+
+
+
+//! creation of subview_field (column of a field)
+template<typename oT>
+inline
+const subview_field<oT>
+field<oT>::col(const uword col_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (col_num >= n_cols), "field::col(): out of bounds");
+  
+  return subview_field<oT>(*this, 0, col_num, n_rows, 1);
+  }
+
+
+
+//! creation of subview_field (subfield comprised of specified rows)
+template<typename oT>
+inline
+subview_field<oT>
+field<oT>::rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    ( (in_row1 > in_row2) || (in_row2 >= n_rows) ),
+    "field::rows(): indicies out of bounds or incorrectly used"
+    );
+  
+  const uword sub_n_rows = in_row2 - in_row1 + 1;
+  
+  return subview_field<oT>(*this, in_row1, 0, sub_n_rows, n_cols);
+  }
+
+
+
+//! creation of subview_field (subfield comprised of specified rows)
+template<typename oT>
+inline
+const subview_field<oT>
+field<oT>::rows(const uword in_row1, const uword in_row2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    ( (in_row1 > in_row2) || (in_row2 >= n_rows) ),
+    "field::rows(): indicies out of bounds or incorrectly used"
+    );
+  
+  const uword sub_n_rows = in_row2 - in_row1 + 1;
+  
+  return subview_field<oT>(*this, in_row1, 0, sub_n_rows, n_cols);
+  }
+
+
+
+//! creation of subview_field (subfield comprised of specified columns)
+template<typename oT>
+inline
+subview_field<oT>
+field<oT>::cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    ( (in_col1 > in_col2) || (in_col2 >= n_cols) ),
+    "field::cols(): indicies out of bounds or incorrectly used"
+    );
+  
+  const uword sub_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview_field<oT>(*this, 0, in_col1, n_rows, sub_n_cols);
+  }
+
+
+
+//! creation of subview_field (subfield comprised of specified columns)
+template<typename oT>
+inline
+const subview_field<oT>
+field<oT>::cols(const uword in_col1, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    ( (in_col1 > in_col2) || (in_col2 >= n_cols) ),
+    "field::cols(): indicies out of bounds or incorrectly used"
+    );
+  
+  const uword sub_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview_field<oT>(*this, 0, in_col1, n_rows, sub_n_cols);
+  }
+
+
+
+//! creation of subview_field (subfield with arbitrary dimensions)
+template<typename oT>
+inline
+subview_field<oT>
+field<oT>::subfield(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
+    "field::subfield(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword sub_n_rows = in_row2 - in_row1 + 1;
+  const uword sub_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview_field<oT>(*this, in_row1, in_col1, sub_n_rows, sub_n_cols);
+  }
+
+
+
+//! creation of subview_field (subfield with arbitrary dimensions)
+template<typename oT>
+inline
+const subview_field<oT>
+field<oT>::subfield(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
+    "field::subfield(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword sub_n_rows = in_row2 - in_row1 + 1;
+  const uword sub_n_cols = in_col2 - in_col1 + 1;
+  
+  return subview_field<oT>(*this, in_row1, in_col1, sub_n_rows, sub_n_cols);
+  }
+
+
+
+//! creation of subview_field (subfield with arbitrary dimensions)
+template<typename oT>
+inline
+subview_field<oT>
+field<oT>::subfield(const span& row_span, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  const uword local_n_cols = n_cols;
+  
+  const uword in_row1    = row_all ? 0            : row_span.a;
+  const uword in_row2    =                          row_span.b;
+  const uword sub_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  const uword in_col1    = col_all ? 0            : col_span.a;
+  const uword in_col2    =                          col_span.b;
+  const uword sub_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  arma_debug_check
+    (
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "field::subfield(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview_field<oT>(*this, in_row1, in_col1, sub_n_rows, sub_n_cols);
+  }
+
+
+
+//! creation of subview_field (subfield with arbitrary dimensions)
+template<typename oT>
+inline
+const subview_field<oT>
+field<oT>::subfield(const span& row_span, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  const uword local_n_cols = n_cols;
+  
+  const uword in_row1    = row_all ? 0            : row_span.a;
+  const uword in_row2    =                          row_span.b;
+  const uword sub_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  const uword in_col1    = col_all ? 0            : col_span.a;
+  const uword in_col2    =                          col_span.b;
+  const uword sub_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  arma_debug_check
+    (
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "field::subfield(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview_field<oT>(*this, in_row1, in_col1, sub_n_rows, sub_n_cols);
+  }
+
+
+
+template<typename oT>
+inline
+subview_field<oT>
+field<oT>::operator()(const span& row_span, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).subfield(row_span, col_span);
+  }
+
+
+
+template<typename oT>
+inline
+const subview_field<oT>
+field<oT>::operator()(const span& row_span, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).subfield(row_span, col_span);
+  }
+
+
+
+//! print contents of the field (to the cout stream),
+//! optionally preceding with a user specified line of text.
+//! the field class preserves the stream's flags
+//! but the associated operator<< function for type oT 
+//! may still modify the stream's parameters.
+//! NOTE: this function assumes that type oT can be printed,
+//! i.e. the function "std::ostream& operator<< (std::ostream&, const oT&)"
+//! has been defined.
+
+template<typename oT>
+inline
+void
+field<oT>::print(const std::string extra_text) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width();
+    
+    ARMA_DEFAULT_OSTREAM << extra_text << '\n';
+  
+    ARMA_DEFAULT_OSTREAM.width(orig_width);
+    }
+  
+  arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this);
+  }
+
+
+
+//! print contents of the field to a user specified stream,
+//! optionally preceding with a user specified line of text.
+//! the field class preserves the stream's flags
+//! but the associated operator<< function for type oT 
+//! may still modify the stream's parameters.
+//! NOTE: this function assumes that type oT can be printed,
+//! i.e. the function "std::ostream& operator<< (std::ostream&, const oT&)"
+//! has been defined.
+
+template<typename oT>
+inline
+void
+field<oT>::print(std::ostream& user_stream, const std::string extra_text) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(extra_text.length() != 0)
+    {
+    const std::streamsize orig_width = user_stream.width();
+    
+    user_stream << extra_text << '\n';
+  
+    user_stream.width(orig_width);
+    }
+  
+  arma_ostream::print(user_stream, *this);
+  }
+
+
+
+//! fill the field with an object
+template<typename oT>
+inline
+void
+field<oT>::fill(const oT& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  field<oT>& t = *this;
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    t[i] = x;
+    }
+  }
+
+
+
+//! reset the field to an empty state (i.e. the field will have no objects)
+template<typename oT>
+inline
+void
+field<oT>::reset()
+  {
+  arma_extra_debug_sigprint();
+  
+  init(0,0);
+  }
+
+
+
+//! reset each object
+template<typename oT>
+inline
+void
+field<oT>::reset_objects()
+  {
+  arma_extra_debug_sigprint();
+  
+  field_aux::reset_objects(*this);
+  }
+
+
+
+//! returns true if the field has no objects
+template<typename oT>
+arma_inline
+bool
+field<oT>::is_empty() const
+  {
+  return (n_elem == 0);
+  }
+
+
+
+//! returns true if the given index is currently in range
+template<typename oT>
+arma_inline
+arma_warn_unused
+bool
+field<oT>::in_range(const uword i) const
+  {
+  return (i < n_elem);
+  }
+
+
+
+//! returns true if the given start and end indices are currently in range
+template<typename oT>
+arma_inline
+arma_warn_unused
+bool
+field<oT>::in_range(const span& x) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(x.whole == true)
+    {
+    return true;
+    }
+  else
+    {
+    const uword a = x.a;
+    const uword b = x.b;
+    
+    return ( (a <= b) && (b < n_elem) );
+    }
+  }
+
+
+
+//! returns true if the given location is currently in range
+template<typename oT>
+arma_inline
+arma_warn_unused
+bool
+field<oT>::in_range(const uword in_row, const uword in_col) const
+  {
+  return ( (in_row < n_rows) && (in_col < n_cols) );
+  }
+
+
+
+template<typename oT>
+arma_inline
+arma_warn_unused
+bool
+field<oT>::in_range(const span& row_span, const uword in_col) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(row_span.whole == true)
+    {
+    return (in_col < n_cols);
+    }
+  else
+    {
+    const uword in_row1 = row_span.a;
+    const uword in_row2 = row_span.b;
+    
+    return ( (in_row1 <= in_row2) && (in_row2 < n_rows) && (in_col < n_cols) );
+    }
+  }
+
+
+
+template<typename oT>
+arma_inline
+arma_warn_unused
+bool
+field<oT>::in_range(const uword in_row, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(col_span.whole == true)
+    {
+    return (in_row < n_rows);
+    }
+  else
+    {
+    const uword in_col1 = col_span.a;
+    const uword in_col2 = col_span.b;
+  
+    return ( (in_row < n_rows) && (in_col1 <= in_col2) && (in_col2 < n_cols) );
+    }
+  }
+
+
+
+template<typename oT>
+arma_inline
+arma_warn_unused
+bool
+field<oT>::in_range(const span& row_span, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword in_row1 = row_span.a;
+  const uword in_row2 = row_span.b;
+  
+  const uword in_col1 = col_span.a;
+  const uword in_col2 = col_span.b;
+  
+  const bool rows_ok = row_span.whole ? true : ( (in_row1 <= in_row2) && (in_row2 < n_rows) );
+  const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2) && (in_col2 < n_cols) );
+  
+  return ( (rows_ok == true) && (cols_ok == true) );
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field<oT>::save(const std::string name, const file_type type, const bool print_status) const
+  {
+  arma_extra_debug_sigprint();
+  
+  std::string err_msg;
+  const bool save_okay = field_aux::save(*this, name, type, err_msg);
+  
+  if( (print_status == true) && (save_okay == false) )
+    {
+    if(err_msg.length() > 0)
+      {
+      arma_warn(true, "field::save(): ", err_msg, name);
+      }
+    else
+      {
+      arma_warn(true, "field::save(): couldn't write to ", name);
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field<oT>::save(std::ostream& os, const file_type type, const bool print_status) const
+  {
+  arma_extra_debug_sigprint();
+  
+  std::string err_msg;
+  const bool save_okay = field_aux::save(*this, os, type, err_msg);
+  
+  if( (print_status == true) && (save_okay == false) )
+    {
+    if(err_msg.length() > 0)
+      {
+      arma_warn(true, "field::save(): ", err_msg, "[ostream]");
+      }
+    else
+      {
+      arma_warn(true, "field::save(): couldn't write to [ostream]");
+      }
+    }
+  
+  return save_okay;
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field<oT>::load(const std::string name, const file_type type, const bool print_status)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::string err_msg;
+  const bool load_okay = field_aux::load(*this, name, type, err_msg);
+  
+  if( (print_status == true) && (load_okay == false) )
+    {
+    if(err_msg.length() > 0)
+      {
+      arma_warn(true, "field::load(): ", err_msg, name);
+      }
+    else
+      {
+      arma_warn(true, "field::load(): couldn't read from ", name);
+      }
+    }
+  
+  if(load_okay == false)
+    {
+    (*this).reset();
+    }
+  
+  return load_okay;
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field<oT>::load(std::istream& is, const file_type type, const bool print_status)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::string err_msg;
+  const bool load_okay = field_aux::load(*this, is, type, err_msg);
+  
+  if( (print_status == true) && (load_okay == false) )
+    {
+    if(err_msg.length() > 0)
+      {
+      arma_warn(true, "field::load(): ", err_msg, "[istream]");
+      }
+    else
+      {
+      arma_warn(true, "field::load(): couldn't read from [istream]");
+      }
+    }
+  
+  if(load_okay == false)
+    {
+    (*this).reset();
+    }
+  
+  return load_okay;
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field<oT>::quiet_save(const std::string name, const file_type type) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).save(name, type, false);
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field<oT>::quiet_save(std::ostream& os, const file_type type) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).save(os, type, false);
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field<oT>::quiet_load(const std::string name, const file_type type)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).load(name, type, false);
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field<oT>::quiet_load(std::istream& is, const file_type type)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).load(is, type, false);
+  }
+
+
+
+//! construct a field from a given field
+template<typename oT>
+inline
+void
+field<oT>::init(const field<oT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(this != &x)
+    {
+    const uword x_n_rows = x.n_rows;
+    const uword x_n_cols = x.n_cols;
+    
+    init(x_n_rows, x_n_cols);
+    
+    field& t = *this;
+    
+    for(uword ucol=0; ucol < x_n_cols; ++ucol)
+    for(uword urow=0; urow < x_n_rows; ++urow)
+      {
+      t.at(urow,ucol) = x.at(urow,ucol);
+      }
+    }
+  
+  }
+
+
+
+//! internal field construction; if the requested size is small enough, memory from the stack is used. otherwise memory is allocated via 'new'
+template<typename oT>
+inline
+void
+field<oT>::init(const uword n_rows_in, const uword n_cols_in)
+  {
+  arma_extra_debug_sigprint( arma_boost::format("n_rows_in = %d, n_cols_in = %d") % n_rows_in % n_cols_in );
+  
+  arma_debug_check
+    (
+      (
+      ( (n_rows_in > ARMA_MAX_UHWORD) || (n_cols_in > ARMA_MAX_UHWORD) )
+        ? ( (float(n_rows_in) * float(n_cols_in)) > float(ARMA_MAX_UWORD) )
+        : false
+      ),
+    "field::init(): requested size is too large"
+    );
+  
+  const uword n_elem_new = n_rows_in * n_cols_in;
+  
+  if(n_elem == n_elem_new)
+    {
+    // delete_objects();
+    // create_objects();
+    access::rw(n_rows) = n_rows_in;
+    access::rw(n_cols) = n_cols_in;
+    }
+  else
+    {
+    delete_objects();
+    
+    if(n_elem > sizeof(mem_local)/sizeof(oT*) )
+      {
+      delete [] mem;
+      }
+    
+    if(n_elem_new <= sizeof(mem_local)/sizeof(oT*) )
+      {
+      mem = mem_local;
+      }
+    else
+      {
+      mem = new(std::nothrow) oT* [n_elem_new];
+      arma_check_bad_alloc( (mem == 0), "field::init(): out of memory" );
+      }
+    
+    access::rw(n_elem) = n_elem_new;
+    
+    if(n_elem_new == 0)
+      {
+      access::rw(n_rows) = 0;
+      access::rw(n_cols) = 0;
+      }
+    else
+      {
+      access::rw(n_rows) = n_rows_in;
+      access::rw(n_cols) = n_cols_in;
+      }
+    
+    create_objects();
+    
+    }
+  
+  }
+
+
+
+template<typename oT>
+inline
+void
+field<oT>::delete_objects()
+  {
+  arma_extra_debug_sigprint( arma_boost::format("n_elem = %d") % n_elem );
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    if(mem[i] != 0)
+      {
+      delete mem[i];
+      mem[i] = 0;
+      }
+    }
+  
+  }
+
+
+
+template<typename oT>
+inline
+void
+field<oT>::create_objects()
+  {
+  arma_extra_debug_sigprint( arma_boost::format("n_elem = %d") % n_elem );
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    mem[i] = new oT;
+    }
+  
+  }
+
+
+
+template<typename oT>
+inline
+field<oT>::iterator::iterator(field<oT>& in_M, const bool at_end)
+  : M(in_M)
+  , i( (at_end == false) ? 0 : in_M.n_elem )
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename oT>
+inline
+oT&
+field<oT>::iterator::operator*()
+  {
+  return M[i];
+  }
+
+
+
+template<typename oT>
+inline
+typename field<oT>::iterator&
+field<oT>::iterator::operator++()
+  {
+  ++i;
+  
+  return *this;
+  }
+
+
+
+template<typename oT>
+inline
+void
+field<oT>::iterator::operator++(int)
+  {
+  operator++();
+  }
+
+
+
+template<typename oT>
+inline
+typename field<oT>::iterator&
+field<oT>::iterator::operator--()
+  {
+  if(i > 0)
+    {
+    --i;
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename oT>
+inline
+void
+field<oT>::iterator::operator--(int)
+  {
+  operator--();
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field<oT>::iterator::operator!=(const typename field<oT>::iterator& X) const
+  {
+  return (i != X.i);
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field<oT>::iterator::operator==(const typename field<oT>::iterator& X) const
+  {
+  return (i == X.i);
+  }
+
+
+
+template<typename oT>
+inline
+field<oT>::const_iterator::const_iterator(const field<oT>& in_M, const bool at_end)
+  : M(in_M)
+  , i( (at_end == false) ? 0 : in_M.n_elem )
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename oT>
+inline
+field<oT>::const_iterator::const_iterator(const typename field<oT>::iterator& X)
+  : M(X.M)
+  , i(X.i)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename oT>
+inline
+const oT&
+field<oT>::const_iterator::operator*() const
+  {
+  return M[i];
+  }
+
+
+
+template<typename oT>
+inline
+typename field<oT>::const_iterator&
+field<oT>::const_iterator::operator++()
+  {
+  ++i;
+  
+  return *this;
+  }
+
+
+
+template<typename oT>
+inline
+void
+field<oT>::const_iterator::operator++(int)
+  {
+  operator++();
+  }
+
+
+
+template<typename oT>
+inline
+typename field<oT>::const_iterator&
+field<oT>::const_iterator::operator--()
+  {
+  if(i > 0)
+    {
+    --i;
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename oT>
+inline
+void
+field<oT>::const_iterator::operator--(int)
+  {
+  operator--();
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field<oT>::const_iterator::operator!=(const typename field<oT>::const_iterator& X) const
+  {
+  return (i != X.i);
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field<oT>::const_iterator::operator==(const typename field<oT>::const_iterator& X) const
+  {
+  return (i == X.i);
+  }
+
+
+
+template<typename oT>
+inline
+typename field<oT>::iterator
+field<oT>::begin()
+  {
+  arma_extra_debug_sigprint();
+  
+  return field<oT>::iterator(*this);
+  }
+
+
+
+template<typename oT>
+inline
+typename field<oT>::const_iterator
+field<oT>::begin() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return field<oT>::const_iterator(*this);
+  }
+
+
+
+template<typename oT>
+inline
+typename field<oT>::const_iterator
+field<oT>::cbegin() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return field<oT>::const_iterator(*this);
+  }
+
+
+
+template<typename oT>
+inline
+typename field<oT>::iterator
+field<oT>::end()
+  {
+  arma_extra_debug_sigprint();
+  
+  return field<oT>::iterator(*this, true);
+  }
+
+
+
+template<typename oT>
+inline
+typename field<oT>::const_iterator
+field<oT>::end() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return field<oT>::const_iterator(*this, true);
+  }
+  
+
+
+template<typename oT>
+inline
+typename field<oT>::const_iterator
+field<oT>::cend() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return field<oT>::const_iterator(*this, true);
+  }
+
+
+
+template<typename oT>
+inline
+void
+field<oT>::clear()
+  {
+  reset();
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field<oT>::empty() const
+  {
+  return (n_elem == 0);
+  }
+
+
+
+template<typename oT>
+inline
+uword
+field<oT>::size() const
+  {
+  return n_elem;
+  }
+
+
+
+//
+//
+//
+
+
+
+template<typename oT>
+inline
+void
+field_aux::reset_objects(field<oT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  x.delete_objects();
+  x.create_objects();
+  }
+
+
+
+template<typename eT>
+inline
+void
+field_aux::reset_objects(field< Mat<eT> >& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  for(uword i=0; i<x.n_elem; ++i)
+    {
+    (*(x.mem[i])).reset();
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+field_aux::reset_objects(field< Col<eT> >& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  for(uword i=0; i<x.n_elem; ++i)
+    {
+    (*(x.mem[i])).reset();
+    }
+  }
+  
+  
+  
+template<typename eT>
+inline
+void
+field_aux::reset_objects(field< Row<eT> >& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  for(uword i=0; i<x.n_elem; ++i)
+    {
+    (*(x.mem[i])).reset();
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+field_aux::reset_objects(field< Cube<eT> >& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  for(uword i=0; i<x.n_elem; ++i)
+    {
+    (*(x.mem[i])).reset();
+    }
+  }
+
+
+
+inline
+void
+field_aux::reset_objects(field< std::string >& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  for(uword i=0; i<x.n_elem; ++i)
+    {
+    (*(x.mem[i])).clear();
+    }
+  }
+
+
+
+//
+//
+//
+
+
+
+template<typename oT>
+inline
+bool
+field_aux::save(const field<oT>&, const std::string&, const file_type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  err_msg = " [sorry, saving/loading this type of field is currently not supported] filename = ";
+  
+  return false;
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field_aux::save(const field<oT>&, std::ostream&, const file_type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  err_msg = " [sorry, saving/loading this type of field is currently not supported] filename = ";
+  
+  return false;
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field_aux::load(field<oT>&, const std::string&, const file_type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  err_msg = " [sorry, saving/loading this type of field is currently not supported] filename = ";
+  
+  return false;
+  }
+
+
+
+template<typename oT>
+inline
+bool
+field_aux::load(field<oT>&, std::istream&, const file_type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  err_msg = " [sorry, saving/loading this type of field is currently not supported] filename = ";
+  
+  return false;
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::save(const field< Mat<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case arma_binary:
+      return diskio::save_arma_binary(x, name);
+      break;
+      
+    case ppm_binary:
+      return diskio::save_ppm_binary(x, name);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::save(const field< Mat<eT> >& x, std::ostream& os, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case arma_binary:
+      return diskio::save_arma_binary(x, os);
+      break;
+      
+    case ppm_binary:
+      return diskio::save_ppm_binary(x, os);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::load(field< Mat<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case auto_detect:
+      return diskio::load_auto_detect(x, name, err_msg);
+      break;
+    
+    case arma_binary:
+      return diskio::load_arma_binary(x, name, err_msg);
+      break;
+      
+    case ppm_binary:
+      return diskio::load_ppm_binary(x, name, err_msg);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::load(field< Mat<eT> >& x, std::istream& is, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case auto_detect:
+      return diskio::load_auto_detect(x, is, err_msg);
+      break;
+    
+    case arma_binary:
+      return diskio::load_arma_binary(x, is, err_msg);
+      break;
+      
+    case ppm_binary:
+      return diskio::load_ppm_binary(x, is, err_msg);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::save(const field< Col<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case arma_binary:
+      return diskio::save_arma_binary(x, name);
+      break;
+      
+    case ppm_binary:
+      return diskio::save_ppm_binary(x, name);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::save(const field< Col<eT> >& x, std::ostream& os, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case arma_binary:
+      return diskio::save_arma_binary(x, os);
+      break;
+      
+    case ppm_binary:
+      return diskio::save_ppm_binary(x, os);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::load(field< Col<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case auto_detect:
+      return diskio::load_auto_detect(x, name, err_msg);
+      break;
+    
+    case arma_binary:
+      return diskio::load_arma_binary(x, name, err_msg);
+      break;
+      
+    case ppm_binary:
+      return diskio::load_ppm_binary(x, name, err_msg);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::load(field< Col<eT> >& x, std::istream& is, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case auto_detect:
+      return diskio::load_auto_detect(x, is, err_msg);
+      break;
+    
+    case arma_binary:
+      return diskio::load_arma_binary(x, is, err_msg);
+      break;
+      
+    case ppm_binary:
+      return diskio::load_ppm_binary(x, is, err_msg);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::save(const field< Row<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case arma_binary:
+      return diskio::save_arma_binary(x, name, err_msg);
+      break;
+      
+    case ppm_binary:
+      return diskio::save_ppm_binary(x, name, err_msg);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::save(const field< Row<eT> >& x, std::ostream& os, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case arma_binary:
+      return diskio::save_arma_binary(x, os, err_msg);
+      break;
+      
+    case ppm_binary:
+      return diskio::save_ppm_binary(x, os, err_msg);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::load(field< Row<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case auto_detect:
+      return diskio::load_auto_detect(x, name, err_msg);
+      break;
+    
+    case arma_binary:
+      return diskio::load_arma_binary(x, name, err_msg);
+      break;
+      
+    case ppm_binary:
+      return diskio::load_ppm_binary(x, name, err_msg);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::load(field< Row<eT> >& x, std::istream& is, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case auto_detect:
+      return diskio::load_auto_detect(x, is, err_msg);
+      break;
+    
+    case arma_binary:
+      return diskio::load_arma_binary(x, is, err_msg);
+      break;
+      
+    case ppm_binary:
+      return diskio::load_ppm_binary(x, is, err_msg);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::save(const field< Cube<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case arma_binary:
+      return diskio::save_arma_binary(x, name, err_msg);
+      break;
+      
+    case ppm_binary:
+      return diskio::save_ppm_binary(x, name, err_msg);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::save(const field< Cube<eT> >& x, std::ostream& os, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case arma_binary:
+      return diskio::save_arma_binary(x, os, err_msg);
+      break;
+      
+    case ppm_binary:
+      return diskio::save_ppm_binary(x, os, err_msg);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::load(field< Cube<eT> >& x, const std::string& name, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case auto_detect:
+      return diskio::load_auto_detect(x, name, err_msg);
+      break;
+    
+    case arma_binary:
+      return diskio::load_arma_binary(x, name, err_msg);
+      break;
+      
+    case ppm_binary:
+      return diskio::load_ppm_binary(x, name, err_msg);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+field_aux::load(field< Cube<eT> >& x, std::istream& is, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  switch(type)
+    {
+    case auto_detect:
+      return diskio::load_auto_detect(x, is, err_msg);
+      break;
+    
+    case arma_binary:
+      return diskio::load_arma_binary(x, is, err_msg);
+      break;
+      
+    case ppm_binary:
+      return diskio::load_ppm_binary(x, is, err_msg);
+      break;
+    
+    default:
+      err_msg = " [unsupported type] filename = ";
+      return false;
+    }
+  }
+
+
+
+inline
+bool
+field_aux::save(const field< std::string >& x, const std::string& name, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_ignore(type);
+  
+  err_msg.clear();
+  
+  return diskio::save_std_string(x, name);
+  }
+
+
+
+inline
+bool
+field_aux::save(const field< std::string >& x, std::ostream& os, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_ignore(type);
+  
+  err_msg.clear();
+  
+  return diskio::save_std_string(x, os);
+  }
+
+
+
+inline
+bool
+field_aux::load(field< std::string >& x, const std::string& name, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_ignore(type);
+  
+  return diskio::load_std_string(x, name, err_msg);
+  }
+
+
+
+inline
+bool
+field_aux::load(field< std::string >& x, std::istream& is, const file_type type, std::string& err_msg)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_ignore(type);
+  
+  return diskio::load_std_string(x, is, err_msg);
+  }
+
+
+
+#ifdef ARMA_EXTRA_FIELD_MEAT
+  #include ARMA_INCFILE_WRAP(ARMA_EXTRA_FIELD_MEAT)
+#endif
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_accu.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,331 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_accu
+//! @{
+
+
+
+template<typename T1>
+arma_hot
+inline
+typename T1::elem_type
+accu_proxy_linear(const Proxy<T1>& P)
+  {
+  typedef typename T1::elem_type      eT;
+  typedef typename Proxy<T1>::ea_type ea_type;
+  
+        ea_type A      = P.get_ea();
+  const uword   n_elem = P.get_n_elem();
+  
+  eT val1 = eT(0);
+  eT val2 = eT(0);
+  
+  uword i,j;
+  for(i=0, j=1; j < n_elem; i+=2, j+=2)
+    {
+    val1 += A[i];
+    val2 += A[j];
+    }
+  
+  if(i < n_elem)
+    {
+    val1 += A[i];   // equivalent to: val1 += A[n_elem-1];
+    }
+  
+  return (val1 + val2);
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+typename T1::elem_type
+accu_proxy_at(const Proxy<T1>& P)
+  {
+  typedef typename T1::elem_type eT;
+  
+  const uword n_rows = P.get_n_rows();
+  const uword n_cols = P.get_n_cols();
+  
+  eT val = eT(0);
+    
+  if(n_rows != 1)
+    {
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      val += P.at(row,col);
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+      {
+      val += P.at(0,col);
+      }
+    }
+  
+  return val;
+  }
+
+
+
+//! accumulate the elements of a matrix
+template<typename T1>
+arma_hot
+inline
+typename enable_if2< is_arma_type<T1>::value, typename T1::elem_type >::result
+accu(const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Proxy<T1> P(X);
+  
+  return (Proxy<T1>::prefer_at_accessor == false) ? accu_proxy_linear(P) : accu_proxy_at(P);
+  }
+
+
+
+//! explicit handling of Hamming norm (also known as zero norm)
+template<typename T1>
+inline
+arma_warn_unused
+uword
+accu(const mtOp<uword,T1,op_rel_noteq>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const eT val = X.aux;
+  
+  const Proxy<T1> P(X.m);
+  
+  uword n_nonzero = 0;
+    
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typedef typename Proxy<T1>::ea_type ea_type;
+    
+          ea_type A      = P.get_ea();
+    const uword   n_elem = P.get_n_elem();
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      if(A[i] != val) { ++n_nonzero; }
+      }
+    }
+  else
+    {
+    const uword P_n_cols = P.get_n_cols();
+    const uword P_n_rows = P.get_n_rows();
+    
+    if(P_n_rows == 1)
+      {
+      for(uword col=0; col < P_n_cols; ++col)
+        {
+        if(P.at(0,col) != val) { ++n_nonzero; }
+        }
+      }
+    else
+      {
+      for(uword col=0; col < P_n_cols; ++col)
+      for(uword row=0; row < P_n_rows; ++row)
+        {
+        if(P.at(row,col) != val) { ++n_nonzero; }
+        }
+      }
+    }
+  
+  return n_nonzero;
+  }
+
+
+
+//! accumulate the elements of a subview (submatrix)
+template<typename eT>
+arma_hot
+arma_pure
+arma_warn_unused
+inline
+eT
+accu(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();  
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  eT val = eT(0);
+  
+  if(X_n_rows == 1)
+    {
+    const Mat<eT>& A = X.m;
+    
+    const uword start_row = X.aux_row1;
+    const uword start_col = X.aux_col1;
+    
+    const uword end_col_p1 = start_col + X_n_cols;
+    
+    uword i,j;
+    for(i=start_col, j=start_col+1; j < end_col_p1; i+=2, j+=2)
+      {
+      val += A.at(start_row, i);
+      val += A.at(start_row, j);
+      }
+    
+    if(i < end_col_p1)
+      {
+      val += A.at(start_row, i);
+      }
+    }
+  else
+  if(X_n_cols == 1)
+    {
+    val = arrayops::accumulate( X.colptr(0), X_n_rows );
+    }
+  else
+    {
+    for(uword col=0; col < X_n_cols; ++col)
+      {
+      val += arrayops::accumulate( X.colptr(col), X_n_rows );
+      }
+    }
+  
+  return val;
+  }
+
+
+
+template<typename eT>
+arma_hot
+arma_pure
+arma_warn_unused
+inline
+eT
+accu(const subview_col<eT>& X)
+  {
+  arma_extra_debug_sigprint();  
+  
+  return arrayops::accumulate( X.colptr(0), X.n_rows );
+  }
+
+
+
+//! accumulate the elements of a cube
+template<typename T1>
+arma_hot
+arma_warn_unused
+inline
+typename T1::elem_type
+accu(const BaseCube<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type          eT;
+  typedef typename ProxyCube<T1>::ea_type ea_type;
+  
+  const ProxyCube<T1> A(X.get_ref());
+  
+  if(ProxyCube<T1>::prefer_at_accessor == false)
+    {
+          ea_type P      = A.get_ea();
+    const uword   n_elem = A.get_n_elem();
+    
+    eT val1 = eT(0);
+    eT val2 = eT(0);
+    
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      val1 += P[i];
+      val2 += P[j];
+      }
+    
+    if(i < n_elem)
+      {
+      val1 += P[i];
+      }
+    
+    return val1 + val2;
+    }
+  else
+    {
+    const uword n_rows   = A.get_n_rows();
+    const uword n_cols   = A.get_n_cols();
+    const uword n_slices = A.get_n_slices();
+    
+    eT val = eT(0);
+    
+    for(uword slice=0; slice<n_slices; ++slice)
+    for(uword col=0; col<n_cols; ++col)
+    for(uword row=0; row<n_rows; ++row)
+      {
+      val += A.at(row,col,slice);
+      }
+    
+    return val;
+    }
+  }
+
+
+
+template<typename T>
+arma_inline
+arma_warn_unused
+const typename arma_scalar_only<T>::result &
+accu(const T& x)
+  {
+  return x;
+  }
+
+
+
+//! accumulate values in a sparse object
+template<typename T1>
+arma_hot
+inline
+arma_warn_unused
+typename enable_if2<is_arma_sparse_type<T1>::value, typename T1::elem_type>::result
+accu(const T1& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const SpProxy<T1> p(x);
+  
+  if(SpProxy<T1>::must_use_iterator == false)
+    {
+    // direct counting
+    return arrayops::accumulate(p.get_values(), p.get_n_nonzero());
+    }
+  else
+    {
+    typename SpProxy<T1>::const_iterator_type it     = p.begin();
+    typename SpProxy<T1>::const_iterator_type it_end = p.end();
+    
+    eT result = eT(0);
+    
+    while(it != it_end)
+      {
+      result += (*it);
+      ++it;
+      }
+    
+    return result;
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_as_scalar.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,423 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_as_scalar
+//! @{
+
+
+
+template<uword N>
+struct as_scalar_redirect
+  {
+  template<typename T1>
+  inline static typename T1::elem_type apply(const T1& X);
+  };
+
+
+
+template<>
+struct as_scalar_redirect<2>
+  {
+  template<typename T1, typename T2>
+  inline static typename T1::elem_type apply(const Glue<T1,T2,glue_times>& X);
+  };
+
+
+template<>
+struct as_scalar_redirect<3>
+  {
+  template<typename T1, typename T2, typename T3>
+  inline static typename T1::elem_type apply(const Glue< Glue<T1, T2, glue_times>, T3, glue_times>& X);
+  };
+
+
+
+template<uword N>
+template<typename T1>
+inline
+typename T1::elem_type
+as_scalar_redirect<N>::apply(const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  // typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(X);
+  
+  arma_debug_check( (P.get_n_elem() != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
+  
+  return (Proxy<T1>::prefer_at_accessor == true) ? P.at(0,0) : P[0];
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+typename T1::elem_type
+as_scalar_redirect<2>::apply(const Glue<T1, T2, glue_times>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  // T1 must result in a matrix with one row
+  // T2 must result in a matrix with one column
+  
+  const bool has_all_mat        = is_Mat<T1>::value             && is_Mat<T2>::value; 
+  const bool prefer_at_accessor = Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor;
+  
+  const bool do_partial_unwrap = has_all_mat || prefer_at_accessor;
+  
+  if(do_partial_unwrap == true)
+    {
+    const partial_unwrap<T1> tmp1(X.A);
+    const partial_unwrap<T2> tmp2(X.B);
+    
+    typedef typename partial_unwrap<T1>::stored_type TA;
+    typedef typename partial_unwrap<T2>::stored_type TB;
+    
+    const TA& A = tmp1.M;
+    const TB& B = tmp2.M;
+    
+    const uword A_n_rows = (tmp1.do_trans == false) ? (TA::is_row ? 1 : A.n_rows) : (TA::is_col ? 1 : A.n_cols);
+    const uword A_n_cols = (tmp1.do_trans == false) ? (TA::is_col ? 1 : A.n_cols) : (TA::is_row ? 1 : A.n_rows);
+    
+    const uword B_n_rows = (tmp2.do_trans == false) ? (TB::is_row ? 1 : B.n_rows) : (TB::is_col ? 1 : B.n_cols);
+    const uword B_n_cols = (tmp2.do_trans == false) ? (TB::is_col ? 1 : B.n_cols) : (TB::is_row ? 1 : B.n_rows);
+    
+    arma_debug_check( (A_n_rows != 1) || (B_n_cols != 1) || (A_n_cols != B_n_rows), "as_scalar(): incompatible dimensions" );
+    
+    const eT val = op_dot::direct_dot(A.n_elem, A.memptr(), B.memptr());
+    
+    return (tmp1.do_times || tmp2.do_times) ? (val * tmp1.get_val() * tmp2.get_val()) : val;
+    }
+  else
+    {
+    const Proxy<T1> PA(X.A);
+    const Proxy<T2> PB(X.B);
+    
+    arma_debug_check
+      (
+      (PA.get_n_rows() != 1) || (PB.get_n_cols() != 1) || (PA.get_n_cols() != PB.get_n_rows()),
+      "as_scalar(): incompatible dimensions"
+      );
+    
+    return op_dot::apply_proxy(PA,PB);
+    }
+  }
+
+
+
+template<typename T1, typename T2, typename T3>
+inline
+typename T1::elem_type
+as_scalar_redirect<3>::apply(const Glue< Glue<T1, T2, glue_times>, T3, glue_times >& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  // T1 * T2 must result in a matrix with one row
+  // T3 must result in a matrix with one column
+  
+  typedef typename strip_inv    <T2           >::stored_type T2_stripped_1;
+  typedef typename strip_diagmat<T2_stripped_1>::stored_type T2_stripped_2;
+  
+  const strip_inv    <T2>            strip1(X.A.B);
+  const strip_diagmat<T2_stripped_1> strip2(strip1.M);
+  
+  const bool tmp2_do_inv     = strip1.do_inv;
+  const bool tmp2_do_diagmat = strip2.do_diagmat;
+  
+  if(tmp2_do_diagmat == false)
+    {
+    const Mat<eT> tmp(X);
+    
+    arma_debug_check( (tmp.n_elem != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
+    
+    return tmp[0];
+    }
+  else
+    {
+    const partial_unwrap<T1>            tmp1(X.A.A);
+    const partial_unwrap<T2_stripped_2> tmp2(strip2.M);
+    const partial_unwrap<T3>            tmp3(X.B);
+    
+    const Mat<eT>& A = tmp1.M;
+    const Mat<eT>& B = tmp2.M;
+    const Mat<eT>& C = tmp3.M;
+    
+    const uword A_n_rows = (tmp1.do_trans == false) ? A.n_rows : A.n_cols;
+    const uword A_n_cols = (tmp1.do_trans == false) ? A.n_cols : A.n_rows;
+    
+    const bool B_is_vec = B.is_vec();
+    
+    const uword B_n_rows = (B_is_vec == true) ? B.n_elem : ( (tmp2.do_trans == false) ? B.n_rows : B.n_cols );
+    const uword B_n_cols = (B_is_vec == true) ? B.n_elem : ( (tmp2.do_trans == false) ? B.n_cols : B.n_rows );
+    
+    const uword C_n_rows = (tmp3.do_trans == false) ? C.n_rows : C.n_cols;
+    const uword C_n_cols = (tmp3.do_trans == false) ? C.n_cols : C.n_rows;
+    
+    const eT val = tmp1.get_val() * tmp2.get_val() * tmp3.get_val();
+    
+    arma_debug_check
+      (
+      (A_n_rows != 1)        ||
+      (C_n_cols != 1)        ||
+      (A_n_cols != B_n_rows) ||
+      (B_n_cols != C_n_rows)
+      ,
+      "as_scalar(): incompatible dimensions"
+      );
+    
+    
+    if(B_is_vec == true)
+      {
+      if(tmp2_do_inv == true)
+        {
+        return val * op_dotext::direct_rowvec_invdiagvec_colvec(A.mem, B, C.mem);
+        }
+      else
+        {
+        return val * op_dot::direct_dot(A.n_elem, A.mem, B.mem, C.mem);
+        }
+      }
+    else
+      {
+      if(tmp2_do_inv == true)
+        {
+        return val * op_dotext::direct_rowvec_invdiagmat_colvec(A.mem, B, C.mem);
+        }
+      else
+        {
+        return val * op_dotext::direct_rowvec_diagmat_colvec(A.mem, B, C.mem);
+        }
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::elem_type
+as_scalar_diag(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   tmp(X.get_ref());
+  const Mat<eT>& A = tmp.M;
+  
+  arma_debug_check( (A.n_elem != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
+  
+  return A.mem[0];
+  }
+
+
+
+template<typename T1, typename T2, typename T3>
+inline
+typename T1::elem_type
+as_scalar_diag(const Glue< Glue<T1, T2, glue_times_diag>, T3, glue_times >& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  // T1 * T2 must result in a matrix with one row
+  // T3 must result in a matrix with one column
+  
+  typedef typename strip_diagmat<T2>::stored_type T2_stripped;
+  
+  const strip_diagmat<T2> strip(X.A.B);
+  
+  const partial_unwrap<T1>          tmp1(X.A.A);
+  const partial_unwrap<T2_stripped> tmp2(strip.M);
+  const partial_unwrap<T3>          tmp3(X.B);
+  
+  const Mat<eT>& A = tmp1.M;
+  const Mat<eT>& B = tmp2.M;
+  const Mat<eT>& C = tmp3.M;
+  
+  
+  const uword A_n_rows = (tmp1.do_trans == false) ? A.n_rows : A.n_cols;
+  const uword A_n_cols = (tmp1.do_trans == false) ? A.n_cols : A.n_rows;
+  
+  const bool B_is_vec = B.is_vec();
+  
+  const uword B_n_rows = (B_is_vec == true) ? B.n_elem : ( (tmp2.do_trans == false) ? B.n_rows : B.n_cols );
+  const uword B_n_cols = (B_is_vec == true) ? B.n_elem : ( (tmp2.do_trans == false) ? B.n_cols : B.n_rows );
+  
+  const uword C_n_rows = (tmp3.do_trans == false) ? C.n_rows : C.n_cols;
+  const uword C_n_cols = (tmp3.do_trans == false) ? C.n_cols : C.n_rows;
+  
+  const eT val = tmp1.get_val() * tmp2.get_val() * tmp3.get_val();
+  
+  arma_debug_check
+    (
+    (A_n_rows != 1)        ||
+    (C_n_cols != 1)        ||
+    (A_n_cols != B_n_rows) ||
+    (B_n_cols != C_n_rows)
+    ,
+    "as_scalar(): incompatible dimensions"
+    );
+  
+  
+  if(B_is_vec == true)
+    {
+    return val * op_dot::direct_dot(A.n_elem, A.mem, B.mem, C.mem);
+    }
+  else
+    {
+    return val * op_dotext::direct_rowvec_diagmat_colvec(A.mem, B, C.mem);
+    }
+  }
+
+
+
+template<typename T1, typename T2>
+arma_inline
+arma_warn_unused
+typename T1::elem_type
+as_scalar(const Glue<T1, T2, glue_times>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  if(is_glue_times_diag<T1>::value == false)
+    {
+    const sword N_mat = 1 + depth_lhs< glue_times, Glue<T1,T2,glue_times> >::num;
+    
+    arma_extra_debug_print(arma_boost::format("N_mat = %d") % N_mat);
+    
+    return as_scalar_redirect<N_mat>::apply(X);
+    }
+  else
+    {
+    return as_scalar_diag(X);
+    }
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+as_scalar(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  // typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(X.get_ref());
+  
+  arma_debug_check( (P.get_n_elem() != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
+  
+  return (Proxy<T1>::prefer_at_accessor == true) ? P.at(0,0) : P[0];
+  }
+
+
+// ensure the following two functions are aware of each other
+template<typename T1,              typename   eop_type> inline arma_warn_unused typename T1::elem_type as_scalar(const   eOp<T1,       eop_type>& X);
+template<typename T1, typename T2, typename eglue_type> inline arma_warn_unused typename T1::elem_type as_scalar(const eGlue<T1, T2, eglue_type>& X);
+
+
+
+template<typename T1, typename eop_type>
+inline
+arma_warn_unused
+typename T1::elem_type
+as_scalar(const eOp<T1, eop_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const eT val = as_scalar(X.P.Q);
+  
+  return eop_core<eop_type>::process(val, X.aux);
+  }
+
+
+
+template<typename T1, typename T2, typename eglue_type>
+inline
+arma_warn_unused
+typename T1::elem_type
+as_scalar(const eGlue<T1, T2, eglue_type>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const eT a = as_scalar(X.P1.Q);
+  const eT b = as_scalar(X.P2.Q);
+  
+  // the optimiser will keep only one return statement
+  
+       if(is_same_type<eglue_type, eglue_plus >::value == true) { return a + b; }
+  else if(is_same_type<eglue_type, eglue_minus>::value == true) { return a - b; }
+  else if(is_same_type<eglue_type, eglue_div  >::value == true) { return a / b; }
+  else if(is_same_type<eglue_type, eglue_schur>::value == true) { return a * b; }
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+as_scalar(const BaseCube<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  // typedef typename T1::elem_type eT;
+  
+  const ProxyCube<T1> P(X.get_ref());
+  
+  arma_debug_check( (P.get_n_elem() != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
+  
+  return (ProxyCube<T1>::prefer_at_accessor == true) ? P.at(0,0,0) : P[0];
+  }
+
+
+
+template<typename T>
+arma_inline
+arma_warn_unused
+const typename arma_scalar_only<T>::result &
+as_scalar(const T& x)
+  {
+  return x;
+  }
+
+
+
+template<typename T1>
+arma_inline
+arma_warn_unused
+typename T1::elem_type
+as_scalar(const SpBase<typename T1::elem_type, T1>& X)
+  {
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_spmat<T1>  tmp(X.get_ref());
+  const SpMat<eT>& A    = tmp.M;
+  
+  arma_debug_check( (A.n_elem != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
+  
+  return A.at(0,0);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_chol.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,58 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_chol
+//! @{
+
+
+
+template<typename T1>
+inline
+const Op<T1, op_chol>
+chol
+  (
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1, op_chol>(X.get_ref());
+  }
+
+
+
+template<typename T1>
+inline
+bool
+chol
+  (
+         Mat<typename T1::elem_type>&    out,
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  try
+    {
+    out = chol(X);
+    }
+  catch(std::runtime_error&)
+    {
+    return false;
+    }
+  
+  return true;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_conv.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,28 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_conv
+//! @{
+
+
+
+//! Convolution, which is also equivalent to polynomial multiplication and FIR digital filtering.
+
+template<typename T1, typename T2>
+inline
+const Glue<T1, T2, glue_conv>
+conv(const Base<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Glue<T1, T2, glue_conv>(A.get_ref(), B.get_ref());
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_conv_to.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,661 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_conv_to
+//! @{
+
+
+
+//! conversion from Armadillo Base and BaseCube objects to scalars
+//! (kept only for compatibility with old code; use as_scalar() instead for Base objects like Mat)
+template<typename out_eT>
+class conv_to
+  {
+  public:
+  
+  template<typename in_eT, typename T1>
+  inline static out_eT from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
+
+  template<typename in_eT, typename T1>
+  inline static out_eT from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
+  
+  template<typename in_eT, typename T1>
+  inline static out_eT from(const BaseCube<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
+  
+  template<typename in_eT, typename T1>
+  inline static out_eT from(const BaseCube<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
+  };
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+out_eT
+conv_to<out_eT>::from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  arma_type_check(( is_supported_elem_type<out_eT>::value == false ));
+  
+  const unwrap<T1>      tmp(in.get_ref());
+  const Mat<in_eT>& X = tmp.M;
+  
+  arma_debug_check( (X.n_elem != 1), "conv_to(): given object doesn't have exactly one element" );
+  
+  return out_eT(X.mem[0]);
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+out_eT
+conv_to<out_eT>::from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  arma_type_check(( is_supported_elem_type<out_eT>::value == false ));
+  
+  const unwrap<T1>      tmp(in.get_ref());
+  const Mat<in_eT>& X = tmp.M;
+  
+  arma_debug_check( (X.n_elem != 1), "conv_to(): given object doesn't have exactly one element" );
+  
+  out_eT out;
+  
+  arrayops::convert_cx_scalar(out, X.mem[0]);
+  
+  return out;
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+out_eT
+conv_to<out_eT>::from(const BaseCube<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  arma_type_check(( is_supported_elem_type<out_eT>::value == false ));
+  
+  const unwrap_cube<T1>  tmp(in.get_ref());
+  const Cube<in_eT>& X = tmp.M;
+  
+  arma_debug_check( (X.n_elem != 1), "conv_to(): given object doesn't have exactly one element" );
+  
+  return out_eT(X.mem[0]);
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+out_eT
+conv_to<out_eT>::from(const BaseCube<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  arma_type_check(( is_supported_elem_type<out_eT>::value == false ));
+  
+  const unwrap_cube<T1>  tmp(in.get_ref());
+  const Cube<in_eT>& X = tmp.M;
+  
+  arma_debug_check( (X.n_elem != 1), "conv_to(): given object doesn't have exactly one element" );
+  
+  out_eT out;
+  
+  arrayops::convert_cx_scalar(out, X.mem[0]);
+  
+  return out;
+  }
+
+
+
+//! conversion to Armadillo matrices from Armadillo Base objects, as well as from std::vector
+template<typename out_eT>
+class conv_to< Mat<out_eT> >
+  {
+  public:
+  
+  template<typename in_eT, typename T1>
+  inline static Mat<out_eT> from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
+  
+  template<typename in_eT, typename T1>
+  inline static Mat<out_eT> from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
+  
+  
+  
+  template<typename in_eT>
+  inline static Mat<out_eT> from(const std::vector<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
+  
+  template<typename in_eT>
+  inline static Mat<out_eT> from(const std::vector<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
+  };
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+Mat<out_eT>
+conv_to< Mat<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const unwrap<T1>      tmp(in.get_ref());
+  const Mat<in_eT>& X = tmp.M;
+  
+  Mat<out_eT> out(X.n_rows, X.n_cols);
+  
+  arrayops::convert( out.memptr(), X.memptr(), out.n_elem );
+  
+  return out;
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+Mat<out_eT>
+conv_to< Mat<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const unwrap<T1>      tmp(in.get_ref());
+  const Mat<in_eT>& X = tmp.M;
+  
+  Mat<out_eT> out(X.n_rows, X.n_cols);
+  
+  arrayops::convert_cx( out.memptr(), X.memptr(), out.n_elem );
+  
+  return out;
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT>
+inline
+Mat<out_eT>
+conv_to< Mat<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const uword N = uword( in.size() );
+  
+  Mat<out_eT> out(N, 1);
+  
+  if(N > 0)
+    {
+          out_eT* out_mem = out.memptr();
+    const  in_eT*  in_mem = &(in[0]);
+    
+    for(uword i=0; i<N; ++i)
+      {
+      out_mem[i] = out_eT( in_mem[i] );
+      }
+    }
+  
+  return out;
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT>
+inline
+Mat<out_eT>
+conv_to< Mat<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  Mat<out_eT> out(in.size(), 1);
+  
+  typename std::vector<in_eT>::const_iterator in_begin = in.begin();
+  typename std::vector<in_eT>::const_iterator in_end   = in.end();
+  
+  typename Mat<out_eT>::iterator out_begin = out.begin();
+  typename Mat<out_eT>::iterator out_end   = out.end();
+  
+  typename std::vector<in_eT>::const_iterator in_it;
+  typename Mat<out_eT>::iterator              out_it;
+  
+  for(in_it = in_begin, out_it = out_begin; (in_it != in_end) && (out_it != out_end); ++in_it, ++out_it)
+    {
+          out_eT& out_elem = (*out_it);
+    const in_eT&  in_elem  = (*in_it);
+    
+    arrayops::convert_cx_scalar(out_elem, in_elem);
+    }
+  
+  return out;
+  }
+
+
+
+//! conversion to Armadillo row vectors from Armadillo Base objects, as well as from std::vector
+template<typename out_eT>
+class conv_to< Row<out_eT> >
+  {
+  public:
+  
+  template<typename in_eT, typename T1>
+  inline static Row<out_eT> from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
+  
+  template<typename in_eT, typename T1>
+  inline static Row<out_eT> from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
+  
+  
+  
+  template<typename in_eT>
+  inline static Row<out_eT> from(const std::vector<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
+  
+  template<typename in_eT>
+  inline static Row<out_eT> from(const std::vector<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
+  };
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+Row<out_eT>
+conv_to< Row<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const unwrap<T1>      tmp(in.get_ref());
+  const Mat<in_eT>& X = tmp.M;
+  
+  arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" );
+  
+  Row<out_eT> out(X.n_elem);
+  
+  arrayops::convert( out.memptr(), X.memptr(), out.n_elem );
+  
+  return out;
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+Row<out_eT>
+conv_to< Row<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const unwrap<T1>      tmp(in.get_ref());
+  const Mat<in_eT>& X = tmp.M;
+  
+  arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" );
+  
+  Row<out_eT> out(X.n_rows, X.n_cols);
+  
+  arrayops::convert_cx( out.memptr(), X.memptr(), out.n_elem );
+  
+  return out;
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT>
+inline
+Row<out_eT>
+conv_to< Row<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const uword N = uword( in.size() );
+  
+  Row<out_eT> out(N);
+  
+  if(N > 0)
+    {
+          out_eT* out_mem = out.memptr();
+    const  in_eT*  in_mem = &(in[0]);
+    
+    for(uword i=0; i<N; ++i)
+      {
+      out_mem[i] = out_eT( in_mem[i] );
+      }
+    }
+  
+  return out;
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT>
+inline
+Row<out_eT>
+conv_to< Row<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  Row<out_eT> out( in.size() );
+  
+  typename std::vector<in_eT>::const_iterator in_begin = in.begin();
+  typename std::vector<in_eT>::const_iterator in_end   = in.end();
+  
+  typename Row<out_eT>::iterator out_begin = out.begin();
+  typename Row<out_eT>::iterator out_end   = out.end();
+  
+  typename std::vector<in_eT>::const_iterator in_it;
+  typename Row<out_eT>::iterator              out_it;
+  
+  for(in_it = in_begin, out_it = out_begin; (in_it != in_end) && (out_it != out_end); ++in_it, ++out_it)
+    {
+          out_eT& out_elem = (*out_it);
+    const in_eT&  in_elem  = (*in_it);
+    
+    arrayops::convert_cx_scalar(out_elem, in_elem);
+    }
+  
+  return out;
+  }
+
+
+
+//! conversion to Armadillo column vectors from Armadillo Base objects, as well as from std::vector
+template<typename out_eT>
+class conv_to< Col<out_eT> >
+  {
+  public:
+  
+  template<typename in_eT, typename T1>
+  inline static Col<out_eT> from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
+  
+  template<typename in_eT, typename T1>
+  inline static Col<out_eT> from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
+  
+  
+  
+  template<typename in_eT>
+  inline static Col<out_eT> from(const std::vector<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
+  
+  template<typename in_eT>
+  inline static Col<out_eT> from(const std::vector<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
+  };
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+Col<out_eT>
+conv_to< Col<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const unwrap<T1>      tmp(in.get_ref());
+  const Mat<in_eT>& X = tmp.M;
+  
+  arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" );
+  
+  Col<out_eT> out(X.n_elem);
+  
+  arrayops::convert( out.memptr(), X.memptr(), out.n_elem );
+  
+  return out;
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+Col<out_eT>
+conv_to< Col<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const unwrap<T1>      tmp(in.get_ref());
+  const Mat<in_eT>& X = tmp.M;
+  
+  arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" );
+  
+  Col<out_eT> out(X.n_rows, X.n_cols);
+  
+  arrayops::convert_cx( out.memptr(), X.memptr(), out.n_elem );
+  
+  return out;
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT>
+inline
+Col<out_eT>
+conv_to< Col<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_not_cx<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const uword N = uword( in.size() );
+  
+  Col<out_eT> out(N);
+  
+  if(N > 0)
+    {
+          out_eT* out_mem = out.memptr();
+    const  in_eT*  in_mem = &(in[0]);
+    
+    for(uword i=0; i<N; ++i)
+      {
+      out_mem[i] = out_eT( in_mem[i] );
+      }
+    }
+  
+  return out;
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT>
+inline
+Col<out_eT>
+conv_to< Col<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_cx_only<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  Col<out_eT> out( in.size() );
+  
+  typename std::vector<in_eT>::const_iterator in_begin = in.begin();
+  typename std::vector<in_eT>::const_iterator in_end   = in.end();
+  
+  typename Col<out_eT>::iterator out_begin = out.begin();
+  typename Col<out_eT>::iterator out_end   = out.end();
+  
+  typename std::vector<in_eT>::const_iterator in_it;
+  typename Col<out_eT>::iterator              out_it;
+  
+  for(in_it = in_begin, out_it = out_begin; (in_it != in_end) && (out_it != out_end); ++in_it, ++out_it)
+    {
+          out_eT& out_elem = (*out_it);
+    const in_eT&  in_elem  = (*in_it);
+    
+    arrayops::convert_cx_scalar(out_elem, in_elem);
+    }
+  
+  return out;
+  }
+
+
+
+//! conversion to Armadillo cubes from Armadillo BaseCube objects
+template<typename out_eT>
+class conv_to< Cube<out_eT> >
+  {
+  public:
+  
+  template<typename in_eT, typename T1>
+  inline static Cube<out_eT> from(const BaseCube<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
+  
+  template<typename in_eT, typename T1>
+  inline static Cube<out_eT> from(const BaseCube<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
+  };
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+Cube<out_eT>
+conv_to< Cube<out_eT> >::from(const BaseCube<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const unwrap_cube<T1>  tmp( in.get_ref() );
+  const Cube<in_eT>& X = tmp.M;
+  
+  Cube<out_eT> out(X.n_rows, X.n_cols, X.n_slices);
+  
+  arrayops::convert( out.memptr(), X.memptr(), out.n_elem );
+  
+  return out;
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+Cube<out_eT>
+conv_to< Cube<out_eT> >::from(const BaseCube<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const unwrap_cube<T1>  tmp( in.get_ref() );
+  const Cube<in_eT>& X = tmp.M;
+  
+  Cube<out_eT> out(X.n_rows, X.n_cols, X.n_slices);
+  
+  arrayops::convert_cx( out.memptr(), X.memptr(), out.n_elem );
+  
+  return out;
+  }
+
+
+
+//! conversion to std::vector from Armadillo Base objects
+template<typename out_eT>
+class conv_to< std::vector<out_eT> >
+  {
+  public:
+  
+  template<typename in_eT, typename T1>
+  inline static std::vector<out_eT> from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = 0);
+  
+  template<typename in_eT, typename T1>
+  inline static std::vector<out_eT> from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = 0);
+  };
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+std::vector<out_eT>
+conv_to< std::vector<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const unwrap<T1>      tmp(in.get_ref());
+  const Mat<in_eT>& X = tmp.M;
+  
+  arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" );
+  
+  const uword N = X.n_elem;
+  
+  std::vector<out_eT> out(N);
+  
+  if(N > 0)
+    {
+          out_eT* out_mem = &(out[0]);
+    const  in_eT*   X_mem = X.memptr();
+    
+    for(uword i=0; i<N; ++i)
+      {
+      out_mem[i] = out_eT( X_mem[i] );
+      }
+    }
+  
+  return out;
+  }
+
+
+
+template<typename out_eT>
+template<typename in_eT, typename T1>
+inline
+std::vector<out_eT>
+conv_to< std::vector<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const unwrap<T1>      tmp(in.get_ref());
+  const Mat<in_eT>& X = tmp.M;
+  
+  arma_debug_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object can't be interpreted as a vector" );
+  
+  std::vector<out_eT> out(X.n_elem);
+  
+  typename Mat<in_eT>::const_iterator X_begin = X.begin();
+  typename Mat<in_eT>::const_iterator X_end   = X.end();
+
+  typename std::vector<out_eT>::iterator out_begin = out.begin();
+  typename std::vector<out_eT>::iterator out_end   = out.end();
+  
+  typename Mat<in_eT>::const_iterator    X_it;
+  typename std::vector<out_eT>::iterator out_it;
+  
+  for(X_it = X_begin, out_it = out_begin; (X_it != X_end) && (out_it != out_end); ++X_it, ++out_it)
+    {
+          out_eT& out_elem = (*out_it);
+    const in_eT&  X_elem   = (*X_it);
+    
+    arrayops::convert_cx_scalar(out_elem, X_elem);
+    }
+  
+  return out;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_cor.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,43 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_cor
+//! @{
+
+
+
+template<typename T1>
+inline
+const Op<T1, op_cor>
+cor(const Base<typename T1::elem_type,T1>& X, const uword norm_type = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (norm_type > 1), "cor(): norm_type must be 0 or 1");
+  
+  return Op<T1, op_cor>(X.get_ref(), norm_type, 0);
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+const Glue<T1,T2,glue_cor>
+cor(const Base<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B, const uword norm_type = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (norm_type > 1), "cor(): norm_type must be 0 or 1");
+  
+  return Glue<T1, T2, glue_cor>(A.get_ref(), B.get_ref(), norm_type);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_cov.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,43 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_cov
+//! @{
+
+
+
+template<typename T1>
+inline
+const Op<T1, op_cov>
+cov(const Base<typename T1::elem_type,T1>& X, const uword norm_type = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (norm_type > 1), "cov(): norm_type must be 0 or 1");
+
+  return Op<T1, op_cov>(X.get_ref(), norm_type, 0);
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+const Glue<T1,T2,glue_cov>
+cov(const Base<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B, const uword norm_type = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (norm_type > 1), "cov(): norm_type must be 0 or 1");
+  
+  return Glue<T1, T2, glue_cov>(A.get_ref(), B.get_ref(), norm_type);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_cross.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,27 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_cross
+//! @{
+
+
+
+//! cross product (only valid for 3 dimensional vectors)
+template<typename T1, typename T2>
+inline
+const Glue<T1, T2, glue_cross>
+cross(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Glue<T1, T2, glue_cross>(X.get_ref(), Y.get_ref());
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_cumsum.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,119 @@
+// Copyright (C) 2010-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_cumsum
+//! @{
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_cumsum_mat>
+cumsum
+  (
+  const T1& X,
+  const uword dim = 0,
+  const typename enable_if< is_arma_type<T1>::value       == true  >::result* junk1 = 0,
+  const typename enable_if< resolves_to_vector<T1>::value == false >::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return Op<T1, op_cumsum_mat>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_cumsum_mat>
+cumsum
+  (
+  const T1& X,
+  const uword dim,
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1, op_cumsum_mat>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_cumsum_vec>
+cumsum
+  (
+  const T1& X,
+  const arma_empty_class junk1 = arma_empty_class(),
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return Op<T1, op_cumsum_vec>(X);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<Op<T1, op_cumsum_vec>, op_cumsum_mat>
+cumsum
+  (
+  const Op<T1, op_cumsum_vec>& X,
+  const uword dim,
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<Op<T1, op_cumsum_vec>, op_cumsum_mat>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<Op<T1, op_cumsum_vec>, op_cumsum_vec>
+cumsum
+  (
+  const Op<T1, op_cumsum_vec>& X,
+  const arma_empty_class junk1 = arma_empty_class(),
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return Op<Op<T1, op_cumsum_vec>, op_cumsum_vec>(X);
+  }
+
+
+
+template<typename T>
+arma_inline
+arma_warn_unused
+const typename arma_scalar_only<T>::result &
+cumsum(const T& x)
+  {
+  return x;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_det.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,175 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_det
+//! @{
+
+
+
+//! determinant of mat
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+det
+  (
+  const Base<typename T1::elem_type,T1>& X,
+  const bool slow = false,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return auxlib::det(X, slow);
+  }
+
+
+
+//! determinant of diagmat
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+det
+  (
+  const Op<T1, op_diagmat>& X,
+  const bool slow = false
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(slow);
+  
+  typedef typename T1::elem_type eT;
+  
+  const diagmat_proxy<T1> A(X.m);
+  
+  const uword N = A.n_elem;
+  
+  eT val1 = eT(1);
+  eT val2 = eT(1);
+  
+  uword i,j;
+  for(i=0, j=1; j<N; i+=2, j+=2)
+    {
+    val1 *= A[i];
+    val2 *= A[j];
+    }
+  
+  
+  if(i < N)
+    {
+    val1 *= A[i];
+    }
+  
+  return val1 * val2;
+  }
+
+
+
+//! determinant of a triangular matrix
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+det
+  (
+  const Op<T1, op_trimat>& X,
+  const bool slow = false
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(slow);
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(X.m);
+  
+  const uword N = P.get_n_rows();
+  
+  arma_debug_check( (N != P.get_n_cols()), "det(): matrix is not square" );
+  
+  eT val1 = eT(1);
+  eT val2 = eT(1);
+  
+  uword i,j;
+  for(i=0, j=1; j<N; i+=2, j+=2)
+    {
+    val1 *= P.at(i,i);
+    val2 *= P.at(j,j);
+    }
+  
+  if(i < N)
+    {
+    val1 *= P.at(i,i);
+    }
+  
+  return val1 * val2;
+  }
+
+
+
+//! determinant of inv(A), without doing the inverse operation
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+det
+  (
+  const Op<T1,op_inv>& in,
+  const bool slow = false,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  eT tmp = det(in.m, slow);
+  arma_warn( (tmp == eT(0)), "det(): warning: denominator is zero" );
+  
+  return eT(1) / tmp;
+  }
+
+
+
+//! determinant of trans(A)
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+det
+  (
+  const Op<T1,op_htrans>& in,
+  const bool slow = false,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk1 = 0,
+  const typename         arma_not_cx<typename T1::elem_type>::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return auxlib::det(in.m, slow);  // bypass op_htrans
+  }
+
+
+
+template<typename T>
+arma_inline
+arma_warn_unused
+const typename arma_scalar_only<T>::result &
+det(const T& x)
+  {
+  return x;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_diagmat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,37 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_diagmat
+//! @{
+
+
+//! interpret a matrix or a vector as a diagonal matrix (i.e. off-diagonal entries are zero)
+template<typename T1>
+arma_inline
+typename
+enable_if2
+  <
+  is_arma_type<T1>::value,
+  const Op<T1, op_diagmat>
+  >::result
+diagmat(const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_diagmat>(X);
+  }
+
+
+
+// TODO:
+// create "op_diagmat2", to allow placement of vector onto a sub- or super- diagonal.
+// op_diagmat2 is required, as other code assumes that op_diagmat indicates only the main diagonal)
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_diagvec.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,26 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_diagvec
+//! @{
+
+
+//! extract a diagonal from a matrix
+template<typename T1>
+arma_inline
+const Op<T1, op_diagvec>
+diagvec(const Base<typename T1::elem_type,T1>& X, const sword diag_id = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_diagvec>(X.get_ref(), ((diag_id < 0) ? -diag_id : diag_id), ((diag_id < 0) ? 1 : 0) );
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_dot.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,309 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_dot
+//! @{
+
+
+template<typename T1, typename T2>
+arma_inline
+arma_warn_unused
+typename
+enable_if2
+  <
+  is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value,
+  typename T1::elem_type
+  >::result
+dot
+  (
+  const T1& A,
+  const T2& B
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return op_dot::apply(A,B);
+  }
+
+
+
+template<typename T1, typename T2>
+arma_inline
+arma_warn_unused
+typename
+enable_if2
+  <
+  is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value,
+  typename T1::elem_type
+  >::result
+norm_dot
+  (
+  const T1& A, 
+  const T2& B
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return op_norm_dot::apply(A,B);
+  }
+
+
+
+//
+// cdot
+
+
+
+template<typename T1, typename T2>
+arma_inline
+arma_warn_unused
+typename
+enable_if2
+  <
+  is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value && is_not_complex<typename T1::elem_type>::value,
+  typename T1::elem_type
+  >::result
+cdot
+  (
+  const T1& A,
+  const T2& B
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return op_dot::apply(A,B);
+  }
+
+
+
+
+template<typename T1, typename T2>
+arma_inline
+arma_warn_unused
+typename
+enable_if2
+  <
+  is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value && is_complex<typename T1::elem_type>::value,
+  typename T1::elem_type
+  >::result
+cdot
+  (
+  const T1& A,
+  const T2& B
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return op_cdot::apply(A,B);
+  }
+
+
+
+// convert dot(htrans(x), y) to cdot(x,y)
+
+template<typename T1, typename T2>
+arma_inline
+arma_warn_unused
+typename
+enable_if2
+  <
+  is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value && is_complex<typename T1::elem_type>::value,
+  typename T1::elem_type
+  >::result
+dot
+  (
+  const Op<T1, op_htrans>& A,
+  const T2&                B
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return cdot(A.m, B);
+  }
+
+
+
+//
+// for sparse matrices
+// 
+
+
+
+namespace priv
+  {
+  
+  template<typename T1, typename T2>
+  arma_hot
+  inline
+  typename T1::elem_type
+  dot_helper(const SpProxy<T1>& pa, const SpProxy<T2>& pb)
+    {
+    typedef typename T1::elem_type eT;
+    
+    // Iterate over both objects and see when they are the same
+    eT result = eT(0);
+    
+    typename SpProxy<T1>::const_iterator_type a_it  = pa.begin();
+    typename SpProxy<T1>::const_iterator_type a_end = pa.end();
+    
+    typename SpProxy<T2>::const_iterator_type b_it  = pb.begin();
+    typename SpProxy<T2>::const_iterator_type b_end = pb.end();
+    
+    while((a_it != a_end) && (b_it != b_end))
+      {
+      if(a_it == b_it)
+        {
+        result += (*a_it) * (*b_it);
+        
+        ++a_it;
+        ++b_it;
+        }
+      else if((a_it.col() < b_it.col()) || ((a_it.col() == b_it.col()) && (a_it.row() < b_it.row())))
+        {
+        // a_it is "behind"
+        ++a_it;
+        }
+      else
+        {
+        // b_it is "behind"
+        ++b_it;
+        }
+      }
+    
+    return result;
+    }
+  
+  }
+
+
+
+//! dot product of two sparse objects
+template<typename T1, typename T2>
+arma_warn_unused
+arma_hot
+inline
+typename
+enable_if2
+  <(is_arma_sparse_type<T1>::value) && (is_arma_sparse_type<T2>::value) && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+   typename T1::elem_type
+  >::result
+dot
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> pa(x);
+  const SpProxy<T2> pb(y);
+  
+  arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "dot()");
+  
+  typedef typename T1::elem_type eT;
+  
+  typedef typename SpProxy<T1>::stored_type pa_Q_type;
+  typedef typename SpProxy<T2>::stored_type pb_Q_type;
+  
+  if(
+         ( (SpProxy<T1>::must_use_iterator == false) && (SpProxy<T2>::must_use_iterator == false) )
+      && ( (is_SpMat<pa_Q_type>::value     == true ) && (is_SpMat<pb_Q_type>::value     == true ) )   
+    )
+    {
+    const unwrap_spmat<pa_Q_type> tmp_a(pa.Q);
+    const unwrap_spmat<pb_Q_type> tmp_b(pb.Q);
+    
+    const SpMat<eT>& A = tmp_a.M;
+    const SpMat<eT>& B = tmp_b.M;
+    
+    if( &A == &B )
+      {
+      // We can do it directly!
+      return op_dot::direct_dot_arma(A.n_nonzero, A.values, A.values);
+      }
+    else
+      {
+      return priv::dot_helper(pa,pb);
+      }
+    }
+  else
+    {
+    return priv::dot_helper(pa,pb);
+    }
+  }
+
+
+
+//! dot product of one dense and one sparse object
+template<typename T1, typename T2>
+arma_warn_unused
+arma_hot
+inline
+typename
+enable_if2
+  <(is_arma_type<T1>::value) && (is_arma_sparse_type<T2>::value) && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+   typename T1::elem_type
+  >::result
+dot
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  const   Proxy<T1> pa(x);
+  const SpProxy<T2> pb(y);
+  
+  arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "dot()");
+  
+  typedef typename T1::elem_type eT;
+  
+  eT result = eT(0);
+  
+  typename SpProxy<T2>::const_iterator_type it     = pb.begin();
+  typename SpProxy<T2>::const_iterator_type it_end = pb.end();
+  
+  // prefer_at_accessor won't save us operations
+  while(it != it_end)
+    {
+    result += (*it) * pa.at(it.row(), it.col());
+    ++it;
+    }
+  
+  return result;
+  }
+
+
+
+//! dot product of one sparse and one dense object
+template<typename T1, typename T2>
+arma_warn_unused
+arma_hot
+inline
+typename
+enable_if2
+  <(is_arma_sparse_type<T1>::value) && (is_arma_type<T2>::value) && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+   typename T1::elem_type
+  >::result
+dot
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  // this is commutative
+  return dot(y, x);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_eig.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,327 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2009 Edmund Highcock
+// Copyright (C) 2011 Stanislav Funiak
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_eig
+//! @{
+
+
+//
+// symmetric/hermitian matrices
+//
+
+
+//! Eigenvalues of real/complex symmetric/hermitian matrix X
+template<typename T1>
+inline
+bool
+eig_sym
+  (
+         Col<typename T1::pod_type>&     eigval,
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  // unwrap_check not used as T1::elem_type and T1::pod_type may not be the same.
+  // furthermore, it doesn't matter if X is an alias of eigval, as auxlib::eig_sym() makes a copy of X
+  
+  const bool status = auxlib::eig_sym(eigval, X);
+  
+  if(status == false)
+    {
+    eigval.reset();
+    arma_bad("eig_sym(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+//! Eigenvalues of real/complex symmetric/hermitian matrix X
+template<typename T1>
+inline
+Col<typename T1::pod_type>
+eig_sym
+  (
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  Col<typename T1::pod_type> out;
+  const bool status = auxlib::eig_sym(out, X);
+
+  if(status == false)
+    {
+    out.reset();
+    arma_bad("eig_sym(): failed to converge");
+    }
+  
+  return out;
+  }
+
+
+
+//! Eigenvalues and eigenvectors of real/complex symmetric/hermitian matrix X
+template<typename T1> 
+inline
+bool
+eig_sym
+  (
+         Col<typename T1::pod_type>&     eigval,
+         Mat<typename T1::elem_type>&    eigvec,
+  const Base<typename T1::elem_type,T1>& X,
+  const char* method =                   "",
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eig_sym(): eigval is an alias of eigvec" );
+  
+  bool use_divide_and_conquer = false;
+  
+  const char sig = method[0];
+  
+  switch(sig)
+    {
+    case '\0':
+    case 's':
+      break;
+      
+    case 'd':
+      use_divide_and_conquer = true;
+      break;
+    
+    default:
+      {
+      arma_stop("eig_sym(): unknown method specified");
+      return false;
+      }
+    }
+  
+  const bool status = (use_divide_and_conquer == false) ? auxlib::eig_sym(eigval, eigvec, X) : auxlib::eig_sym_dc(eigval, eigvec, X);
+  
+  if(status == false)
+    {
+    eigval.reset();
+    eigvec.reset();
+    arma_bad("eig_sym(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+//
+// general matrices
+//
+
+
+
+//! Eigenvalues and eigenvectors (both left and right) of general real/complex square matrix X
+template<typename T1>
+inline
+bool
+eig_gen
+  (
+         Col< std::complex<typename T1::pod_type> >& eigval, 
+         Mat<typename T1::elem_type>&                l_eigvec,
+         Mat<typename T1::elem_type>&                r_eigvec,
+  const Base<typename T1::elem_type,T1>&             X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  arma_debug_check
+    (
+    ((&l_eigvec) == (&r_eigvec)),
+    "eig_gen(): l_eigvec is an alias of r_eigvec"
+    );
+  
+  arma_debug_check
+    (
+      (
+      (((void*)(&eigval)) == ((void*)(&l_eigvec)))
+      ||
+      (((void*)(&eigval)) == ((void*)(&r_eigvec)))
+      ),
+    "eig_gen(): eigval is an alias of l_eigvec or r_eigvec"
+    );
+  
+  const bool status = auxlib::eig_gen(eigval, l_eigvec, r_eigvec, X, 'b');
+  
+  if(status == false)
+    {
+    eigval.reset();
+    l_eigvec.reset();
+    r_eigvec.reset();
+    arma_bad("eig_gen(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+//! Eigenvalues and eigenvectors of general real square matrix X.
+//! Optional argument 'side' specifies which eigenvectors should be computed:
+//! 'r' for right (default) and 'l' for left.
+template<typename eT, typename T1>
+inline
+bool
+eig_gen
+  (
+        Col< std::complex<eT> >& eigval, 
+        Mat< std::complex<eT> >& eigvec,
+  const Base<eT, T1>&            X, 
+  const char                     side = 'r',
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  //std::cout << "real" << std::endl;
+  
+  arma_debug_check( ( ((void*)(&eigval)) == ((void*)(&eigvec)) ), "eig_gen(): eigval is an alias of eigvec" );
+  
+  Mat<eT> dummy_eigvec;
+  Mat<eT> tmp_eigvec;
+  
+  bool status;
+  
+  switch(side)
+    {
+    case 'r':
+      status = auxlib::eig_gen(eigval, dummy_eigvec, tmp_eigvec, X, side);
+      break;
+    
+    case 'l':
+      status = auxlib::eig_gen(eigval, tmp_eigvec, dummy_eigvec, X, side);
+      break;
+      
+    default:
+      arma_stop("eig_gen(): parameter 'side' is invalid");
+      status = false;
+    }
+  
+  if(status == false)
+    {
+    eigval.reset();
+    eigvec.reset();
+    arma_bad("eig_gen(): failed to converge", false);
+    }
+  else
+    {
+    const uword n = eigval.n_elem;
+    
+    if(n > 0)
+      {
+      eigvec.set_size(n,n);
+      
+      for(uword j=0; j<n; ++j)
+        {
+        if( (j < n-1) && (eigval[j] == std::conj(eigval[j+1])) )
+          {
+          // eigvec.col(j)   = Mat< std::complex<eT> >( tmp_eigvec.col(j),  tmp_eigvec.col(j+1) );
+          // eigvec.col(j+1) = Mat< std::complex<eT> >( tmp_eigvec.col(j), -tmp_eigvec.col(j+1) );
+          
+          for(uword i=0; i<n; ++i)
+            {
+            eigvec.at(i,j)   = std::complex<eT>( tmp_eigvec.at(i,j),  tmp_eigvec.at(i,j+1) );
+            eigvec.at(i,j+1) = std::complex<eT>( tmp_eigvec.at(i,j), -tmp_eigvec.at(i,j+1) );
+            }
+          
+          ++j;
+          }
+        else
+          {
+          // eigvec.col(i) = tmp_eigvec.col(i);
+          
+          for(uword i=0; i<n; ++i)
+            {
+            eigvec.at(i,j) = std::complex<eT>(tmp_eigvec.at(i,j), eT(0));
+            }
+          
+          }
+        }
+      }
+    }
+  
+  return status;
+  }
+
+
+
+//! Eigenvalues and eigenvectors of general complex square matrix X
+//! Optional argument 'side' specifies which eigenvectors should be computed:
+//! 'r' for right (default) and 'l' for left.
+template<typename T, typename T1>
+inline
+bool
+eig_gen
+  (
+         Col<std::complex<T> >&    eigval, 
+         Mat<std::complex<T> >&    eigvec,
+  const Base<std::complex<T>, T1>& X, 
+  const char                       side = 'r',
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  //std::cout << "complex" << std::endl;
+  
+  arma_debug_check( ( ((void*)(&eigval)) == ((void*)(&eigvec)) ), "eig_gen(): eigval is an alias of eigvec" );
+  
+  Mat< std::complex<T> > dummy_eigvec;
+  
+  bool status;
+  
+  switch(side)
+    {
+    case 'r':
+      status = auxlib::eig_gen(eigval, dummy_eigvec, eigvec, X, side);
+      break;
+    
+    case 'l':
+      status = auxlib::eig_gen(eigval, eigvec, dummy_eigvec, X, side);
+      break;
+      
+    default:
+      arma_stop("eig_gen(): parameter 'side' is invalid");
+      status = false;
+    }
+  
+  if(status == false)
+    {
+    eigval.reset();
+    eigvec.reset();
+    arma_bad("eig_gen(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_elem.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,697 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_elem
+//! @{
+
+
+
+//
+// find
+
+template<typename eT, typename T1>
+inline
+const mtOp<uword, T1, op_find>
+find(const Base<eT,T1>& X, const uword k = 0, const char* direction = "first")
+  {
+  arma_extra_debug_sigprint();
+  
+  const char sig = direction[0];
+  
+  arma_debug_check
+    (
+    (sig != 'f' && sig != 'F' && sig != 'l' && sig != 'L'),
+    "find(): 3rd input argument must be \"first\" or \"last\""
+    );
+  
+  const uword type = (sig == 'f' || sig == 'F') ? 0 : 1;
+  
+  return mtOp<uword, T1, op_find>(X.get_ref(), k, type);
+  }
+
+
+
+//
+// real
+
+template<typename T1>
+arma_inline
+const T1&
+real(const Base<typename T1::pod_type, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return X.get_ref();
+  }
+
+
+
+template<typename T1>
+arma_inline
+const T1&
+real(const BaseCube<typename T1::pod_type, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return X.get_ref();
+  }
+
+
+
+template<typename T1>
+inline
+const mtOp<typename T1::pod_type, T1, op_real>
+real(const Base<std::complex<typename T1::pod_type>, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<typename T1::pod_type, T1, op_real>( X.get_ref() );
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<typename T1::pod_type, T1, op_real>
+real(const BaseCube<std::complex<typename T1::pod_type>, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<typename T1::pod_type, T1, op_real>( X.get_ref() );
+  }
+
+
+
+//
+// imag
+
+template<typename T1>
+inline
+const Gen< Mat<typename T1::pod_type>, gen_zeros >
+imag(const Base<typename T1::pod_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Proxy<T1> A(X.get_ref());
+  
+  return Gen< Mat<typename T1::pod_type>, gen_zeros>(A.get_n_rows(), A.get_n_cols());
+  }
+
+
+
+template<typename T1>
+inline
+const GenCube<typename T1::pod_type, gen_zeros>
+imag(const BaseCube<typename T1::pod_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const ProxyCube<T1> A(X.get_ref());
+  
+  return GenCube<typename T1::pod_type, gen_zeros>(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
+  }
+
+
+
+template<typename T1>
+inline
+const mtOp<typename T1::pod_type, T1, op_imag>
+imag(const Base<std::complex<typename T1::pod_type>, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<typename T1::pod_type, T1, op_imag>( X.get_ref() );
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<typename T1::pod_type, T1, op_imag>
+imag(const BaseCube<std::complex<typename T1::pod_type>,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<typename T1::pod_type, T1, op_imag>( X.get_ref() );
+  }
+
+
+
+//
+// log
+
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_log> >::result
+log(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_log>(A);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_log>
+log(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_log>(A.get_ref());
+  }
+
+
+
+//
+// log2
+
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_log2> >::result
+log2(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_log2>(A);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_log2>
+log2(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_log2>(A.get_ref());
+  }
+
+
+
+//
+// log10
+
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_log10> >::result
+log10(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_log10>(A);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_log10>
+log10(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_log10>(A.get_ref());
+  }
+
+
+
+//
+// exp
+
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_exp> >::result
+exp(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_exp>(A);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_exp>
+exp(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_exp>(A.get_ref());
+  }
+
+
+
+// exp2
+
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_exp2> >::result
+exp2(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_exp2>(A);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_exp2>
+exp2(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_exp2>(A.get_ref());
+  }
+
+
+
+// exp10
+
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_exp10> >::result
+exp10(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_exp10>(A);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_exp10>
+exp10(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_exp10>(A.get_ref());
+  }
+
+
+
+//
+// abs
+
+
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_abs> >::result
+abs(const T1& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_ignore(junk);
+  
+  return eOp<T1, eop_abs>(X);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_abs>
+abs(const BaseCube<typename T1::elem_type,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_ignore(junk);
+  
+  return eOpCube<T1, eop_abs>(X.get_ref());
+  }
+
+
+
+template<typename T1>
+inline
+const mtOp<typename T1::pod_type, T1, op_abs>
+abs(const Base<std::complex<typename T1::pod_type>, T1>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_ignore(junk);
+  
+  return mtOp<typename T1::pod_type, T1, op_abs>( X.get_ref() );
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<typename T1::pod_type, T1, op_abs>
+abs(const BaseCube< std::complex<typename T1::pod_type>,T1>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_ignore(junk);
+  
+  return mtOpCube<typename T1::pod_type, T1, op_abs>( X.get_ref() );
+  }
+
+
+
+template<typename T1>
+arma_inline
+const SpOp<T1, spop_abs>
+abs(const SpBase<typename T1::elem_type,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return SpOp<T1, spop_abs>(X.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const mtSpOp<typename T1::pod_type, T1, spop_cx_abs>
+abs(const SpBase< std::complex<typename T1::pod_type>, T1>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return mtSpOp<typename T1::pod_type, T1, spop_cx_abs>(X.get_ref());
+  }
+
+
+
+//
+// square
+
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_square> >::result
+square(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_square>(A);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_square>
+square(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_square>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const SpOp<T1, spop_square>
+square(const SpBase<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpOp<T1, spop_square>(A.get_ref());
+  }
+
+
+
+//
+// sqrt
+
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_sqrt> >::result
+sqrt(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_sqrt>(A);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_sqrt>
+sqrt(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_sqrt>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const SpOp<T1, spop_sqrt>
+sqrt(const SpBase<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpOp<T1, spop_sqrt>(A.get_ref());
+  }
+
+
+
+//
+// conj
+
+template<typename T1>
+arma_inline
+const T1&
+conj(const Base<typename T1::pod_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+
+  return A.get_ref();
+  }
+
+
+
+template<typename T1>
+arma_inline
+const T1&
+conj(const BaseCube<typename T1::pod_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+
+  return A.get_ref();
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_conj>
+conj(const Base<std::complex<typename T1::pod_type>,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+
+  return eOp<T1, eop_conj>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_conj>
+conj(const BaseCube<std::complex<typename T1::pod_type>,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+
+  return eOpCube<T1, eop_conj>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const T1&
+conj(const eOp<T1, eop_conj>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return A.m;
+  }
+
+
+
+template<typename T1>
+arma_inline
+const T1&
+conj(const eOpCube<T1, eop_conj>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return A.m;
+  }
+
+
+
+// TODO: this needs a more elaborate template restriction mechanism to work properly,
+//       i.e. an overloaded version of thus function should do nothing if the input type is non-complex
+// 
+// //! the conjugate of the transpose of a complex matrix is the same as the hermitian transpose
+// template<typename T1>
+// arma_inline
+// const Op<T1, op_htrans>
+// conj(const Op<T1, op_strans>& A)
+//   {
+//   arma_extra_debug_sigprint();
+//   
+//   return Op<T1, op_htrans>(A.m);
+//   }
+
+
+
+// pow
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_pow>
+pow(const Base<typename T1::elem_type,T1>& A, const typename T1::elem_type exponent)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_pow>(A.get_ref(), exponent);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_pow>
+pow(const BaseCube<typename T1::elem_type,T1>& A, const typename T1::elem_type exponent)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_pow>(A.get_ref(), exponent);
+  }
+
+
+
+// pow, specialised handling (non-complex exponent for complex matrices)
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_pow>
+pow(const Base<typename T1::elem_type,T1>& A, const typename T1::elem_type::value_type exponent)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  return eOp<T1, eop_pow>(A.get_ref(), eT(exponent));
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_pow>
+pow(const BaseCube<typename T1::elem_type,T1>& A, const typename T1::elem_type::value_type exponent)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  return eOpCube<T1, eop_pow>(A.get_ref(), eT(exponent));
+  }
+
+
+
+//
+// floor
+
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_floor> >::result
+floor(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_floor>(A);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_floor>
+floor(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_floor>(A.get_ref());
+  }
+
+
+
+//
+// ceil
+
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_ceil> >::result
+ceil(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_ceil>(A);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_ceil>
+ceil(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_ceil>(A.get_ref());
+  }
+
+
+
+//
+// round
+
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_round> >::result
+round(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_round>(A);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_round>
+round(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_round>(A.get_ref());
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_eps.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,100 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup fn_eps
+//! @{
+
+
+
+//! \brief
+//! eps version for non-complex matrices and vectors
+template<typename T1>
+inline
+const eOp<T1, eop_eps>
+eps(const Base<typename T1::elem_type, T1>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return eOp<T1, eop_eps>(X.get_ref());
+  }
+
+
+
+//! \brief
+//! eps version for complex matrices and vectors
+template<typename T1>
+inline
+Mat< typename T1::pod_type >
+eps(const Base< std::complex<typename T1::pod_type>, T1>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_ignore(junk);
+  
+  typedef typename T1::pod_type   T;
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   tmp(X.get_ref());
+  const Mat<eT>& A = tmp.M;
+  
+  Mat<T> out(A.n_rows, A.n_cols);
+  
+         T* out_mem = out.memptr();
+  const eT* A_mem   = A.memptr();
+  const uword n_elem  = A.n_elem;
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    out_mem[i] = eop_aux::direct_eps( A_mem[i] );
+    }
+  
+  
+  return out;
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+typename arma_integral_only<eT>::result
+eps(const eT& x)
+  {
+  arma_ignore(x);
+  
+  return eT(0);
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+typename arma_real_only<eT>::result
+eps(const eT& x)
+  {
+  return eop_aux::direct_eps(x);
+  }
+
+
+
+template<typename T>
+arma_inline
+arma_warn_unused
+typename arma_real_only<T>::result
+eps(const std::complex<T>& x)
+  {
+  return eop_aux::direct_eps(x);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_eye.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,48 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_eye
+//! @{
+
+
+
+arma_inline
+const Gen<mat, gen_ones_diag>
+eye(const uword n_rows, const uword n_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Gen<mat, gen_ones_diag>(n_rows, n_cols);
+  }
+
+
+
+template<typename obj_type>
+arma_inline
+const Gen<obj_type, gen_ones_diag>
+eye(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only<obj_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  if(is_Col<obj_type>::value == true)
+    {
+    arma_debug_check( (n_cols != 1), "eye(): incompatible size" );
+    }
+  else
+  if(is_Row<obj_type>::value == true)
+    {
+    arma_debug_check( (n_rows != 1), "eye(): incompatible size" );
+    }
+  
+  return Gen<obj_type, gen_ones_diag>(n_rows, n_cols);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_fft.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,121 @@
+// Copyright (C) 2013 Conrad Sanderson
+// Copyright (C) 2013 NICTA (www.nicta.com.au)
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_fft
+//! @{
+
+
+
+// TODO:  fft(real)     -> complex [to be tested thoroughly]
+// TODO:  fft(complex)  -> complex [to be tested thoroughly]
+// TODO: ifft(complex)  -> complex [to be tested thoroughly]
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_real<typename T1::elem_type>::value),
+  const mtOp<std::complex<typename T1::pod_type>, T1, op_fft_real>
+  >::result
+fft(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<std::complex<typename T1::pod_type>, T1, op_fft_real>(A, uword(0), uword(1));
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_real<typename T1::elem_type>::value),
+  const mtOp<std::complex<typename T1::pod_type>, T1, op_fft_real>
+  >::result
+fft(const T1& A, const uword N)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<std::complex<typename T1::pod_type>, T1, op_fft_real>(A, N, uword(0));
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_complex_strict<typename T1::elem_type>::value),
+  const Op<T1, op_fft_cx>
+  >::result
+fft(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_fft_cx>(A, uword(0), uword(1));
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_complex_strict<typename T1::elem_type>::value),
+  const Op<T1, op_fft_cx>
+  >::result
+fft(const T1& A, const uword N)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_fft_cx>(A, N, uword(0));
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_complex_strict<typename T1::elem_type>::value),
+  const Op<T1, op_ifft_cx>
+  >::result
+ifft(const T1& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_ifft_cx>(A, uword(0), uword(1));
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_complex_strict<typename T1::elem_type>::value),
+  const Op<T1, op_ifft_cx>
+  >::result
+ifft(const T1& A, const uword N)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_ifft_cx>(A, N, uword(0));
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_flip.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,38 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_flip
+//! @{
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_flipud>
+flipud(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_flipud>(X.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_fliplr>
+fliplr(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_fliplr>(X.get_ref());
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_hist.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,45 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+template<typename T1>
+inline
+const mtOp<uword,T1,op_hist>
+hist
+  (
+  const Base<typename T1::elem_type,T1>& A,
+  const uword n_bins = 10,
+  const arma_empty_class junk1 = arma_empty_class(),
+  const typename arma_not_cx<typename T1::elem_type>::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return mtOp<uword,T1,op_hist>( A.get_ref(), n_bins, 0 );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+const mtGlue<uword,T1,T2,glue_hist>
+hist
+  (
+  const Base<typename T1::elem_type,T1>& A,
+  const Base<typename T1::elem_type,T2>& B,
+  const uword dim = 0,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return mtGlue<uword,T1,T2,glue_hist>( A.get_ref(), B.get_ref(), dim );
+  }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_histc.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,26 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// Copyright (C) 2012 Boris Sabanin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+template<typename T1, typename T2>
+inline
+const mtGlue<uword,T1,T2,glue_histc>
+histc
+  (
+  const Base<typename T1::elem_type,T1>& A,
+  const Base<typename T1::elem_type,T2>& B,
+  const uword dim = 0,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return mtGlue<uword,T1,T2,glue_histc>( A.get_ref(), B.get_ref(), dim );
+  }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_inv.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,115 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_inv
+//! @{
+
+
+
+//! delayed matrix inverse (general matrices)
+template<typename T1>
+arma_inline
+const Op<T1, op_inv>
+inv
+  (
+  const Base<typename T1::elem_type,T1>& X,
+  const bool slow = false,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1, op_inv>(X.get_ref(), ((slow == false) ? 0 : 1), 0);
+  }
+
+
+
+//! remove the inverse operation if applied twice consecutively
+template<typename T1>
+arma_inline
+const T1&
+inv(const Op<T1, op_inv>& X, const bool slow = false)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(slow);
+  
+  return X.m;
+  }
+
+
+
+//! delayed matrix inverse (triangular matrices)
+template<typename T1>
+arma_inline
+const Op<T1, op_inv_tr>
+inv
+  (
+  const Op<T1, op_trimat>& X,
+  const bool slow = false,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(slow);
+  arma_ignore(junk);
+  
+  return Op<T1, op_inv_tr>(X.m, X.aux_uword_a, 0);
+  }
+
+
+
+//! delayed matrix inverse (symmetric positive definite matrices)
+template<typename T1>
+arma_inline
+const Op<T1, op_inv_sympd>
+inv
+  (
+  const Op<T1, op_sympd>& X,
+  const bool slow = false,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(slow);
+  arma_ignore(junk);
+  
+  return Op<T1, op_inv_sympd>(X.m, 0, 0);
+  }
+
+
+
+template<typename T1>
+inline
+bool
+inv
+  (
+         Mat<typename T1::elem_type>&    out,
+  const Base<typename T1::elem_type,T1>& X,
+  const bool slow = false,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  try
+    {
+    out = inv(X,slow);
+    }
+  catch(std::runtime_error&)
+    {
+    return false;
+    }
+  
+  return true;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_join.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,50 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_join
+//! @{
+
+
+
+template<typename T1, typename T2>
+inline
+const Glue<T1, T2, glue_join>
+join_cols(const Base<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Glue<T1, T2, glue_join>(A.get_ref(), B.get_ref(), 0);
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+const Glue<T1, T2, glue_join>
+join_rows(const Base<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Glue<T1, T2, glue_join>(A.get_ref(), B.get_ref(), 1);
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+const GlueCube<T1, T2, glue_join>
+join_slices(const BaseCube<typename T1::elem_type,T1>& A, const BaseCube<typename T1::elem_type,T2>& B)
+  {
+  arma_extra_debug_sigprint();
+  
+  return GlueCube<T1, T2, glue_join>(A.get_ref(), B.get_ref());
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_kron.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,88 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_kron
+//! @{
+
+
+
+//! \brief
+//! kronecker product of two matrices,
+//! with the matrices having the same element type
+template<typename T1, typename T2>
+arma_inline
+const Glue<T1,T2,glue_kron>
+kron(const Base<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B)
+  {
+  arma_extra_debug_sigprint();
+
+  return Glue<T1, T2, glue_kron>(A.get_ref(), B.get_ref());
+  }
+
+
+
+//! \brief
+//! kronecker product of two matrices,
+//! with the matrices having different element types
+template<typename T, typename T1, typename T2>
+inline
+Mat<typename eT_promoter<T1,T2>::eT>
+kron(const Base<std::complex<T>,T1>& X, const Base<T,T2>& Y)
+  {
+  arma_extra_debug_sigprint();
+
+  typedef typename std::complex<T> eT1;
+
+  promote_type<eT1,T>::check();
+  
+  const unwrap<T1> tmp1(X.get_ref());
+  const unwrap<T2> tmp2(Y.get_ref());
+  
+  const Mat<eT1>& A = tmp1.M;
+  const Mat<T  >& B = tmp2.M;
+
+  Mat<eT1> out;
+  
+  glue_kron::direct_kron(out, A, B);
+  
+  return out;
+  }
+
+
+
+//! \brief
+//! kronecker product of two matrices,
+//! with the matrices having different element types
+template<typename T, typename T1, typename T2>
+inline
+Mat<typename eT_promoter<T1,T2>::eT>
+kron(const Base<T,T1>& X, const Base<std::complex<T>,T2>& Y)
+  {
+  arma_extra_debug_sigprint();
+
+  typedef typename std::complex<T> eT2;  
+
+  promote_type<T,eT2>::check();
+  
+  const unwrap<T1> tmp1(X.get_ref());
+  const unwrap<T2> tmp2(Y.get_ref());
+  
+  const Mat<T  >& A = tmp1.M;
+  const Mat<eT2>& B = tmp2.M;
+
+  Mat<eT2> out;
+  
+  glue_kron::direct_kron(out, A, B);
+  
+  return out;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_log_det.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,82 @@
+// Copyright (C) 2010-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_log_det
+//! @{
+
+
+
+//! log determinant of mat
+template<typename T1>
+inline
+bool
+log_det
+  (
+        typename T1::elem_type&          out_val,
+        typename T1::pod_type&           out_sign,
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return auxlib::log_det(out_val, out_sign, X);
+  }
+
+
+
+template<typename T1>
+inline
+void
+log_det
+  (
+        typename T1::elem_type& out_val,
+        typename T1::pod_type&  out_sign,
+  const Op<T1,op_diagmat>&      X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  typedef typename T1::pod_type   T;
+  
+  const diagmat_proxy<T1> A(X.m);
+  
+  const uword N = A.n_elem;
+  
+  if(N == 0)
+    {
+    out_val  = eT(0);
+    out_sign =  T(1);
+    
+    return;
+    }
+  
+  eT x = A[0];
+  
+  T  sign = (is_complex<eT>::value == false) ? ( (access::tmp_real(x) < T(0)) ? -1 : +1 ) : +1;
+  eT val  = (is_complex<eT>::value == false) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x);
+  
+  for(uword i=1; i<N; ++i)
+    {
+    x = A[i];
+    
+    sign *= (is_complex<eT>::value == false) ? ( (access::tmp_real(x) < T(0)) ? -1 : +1 ) : +1;
+    val  += (is_complex<eT>::value == false) ? std::log( (access::tmp_real(x) < T(0)) ? x*T(-1) : x ) : std::log(x);
+    }
+  
+  out_val  = val;
+  out_sign = sign;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_lu.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,78 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_lu
+//! @{
+
+
+
+//! immediate lower upper decomposition, permutation info is embedded into L (similar to Matlab/Octave)
+template<typename T1>
+inline
+bool
+lu
+  (
+         Mat<typename T1::elem_type>&    L,
+         Mat<typename T1::elem_type>&    U,
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  arma_debug_check( (&L == &U), "lu(): L and U are the same object");
+  
+  const bool status = auxlib::lu(L, U, X);
+  
+  if(status == false)
+    {
+    L.reset();
+    U.reset();
+    arma_bad("lu(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+//! immediate lower upper decomposition, also providing the permutation matrix
+template<typename T1>
+inline
+bool
+lu
+  (
+         Mat<typename T1::elem_type>&    L,
+         Mat<typename T1::elem_type>&    U, 
+         Mat<typename T1::elem_type>&    P,
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  arma_debug_check( ( (&L == &U) || (&L == &P) || (&U == &P) ), "lu(): two or more output objects are the same object");
+  
+  const bool status = auxlib::lu(L, U, P, X);
+  
+  if(status == false)
+    {
+    L.reset();
+    U.reset();
+    P.reset();
+    arma_bad("lu(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_max.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,180 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_max
+//! @{
+
+
+//! \brief
+//! Delayed 'maximum values' operation.
+//! The dimension, along which the maxima are found, is set via 'dim'.
+//! For dim = 0, the maximum value of each column is found (i.e. searches by traversing across rows).
+//! For dim = 1, the maximum value of each row is found (i.e. searches by traversing across columns).
+//! The default is dim = 0.
+
+template<typename T1>
+arma_inline
+const Op<T1, op_max>
+max
+  (
+  const T1& X,
+  const uword dim = 0,
+  const typename enable_if< is_arma_type<T1>::value       == true  >::result* junk1 = 0,
+  const typename enable_if< resolves_to_vector<T1>::value == false >::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return Op<T1, op_max>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_max>
+max
+  (
+  const T1& X,
+  const uword dim,
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1, op_max>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+max
+  (
+  const T1& X,
+  const arma_empty_class junk1 = arma_empty_class(),
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return op_max::max(X);
+  }
+
+
+
+//! \brief
+//! Immediate 'find maximum value' operation,
+//! invoked, for example, by: max(max(A))
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+max(const Op<T1, op_max>& in)
+  {
+  arma_extra_debug_sigprint();
+  arma_extra_debug_print("max(): two consecutive max() calls detected");
+  
+  return op_max::max(in.m);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op< Op<T1, op_max>, op_max>
+max(const Op<T1, op_max>& in, const uword dim)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op< Op<T1, op_max>, op_max>(in, dim, 0);
+  }
+
+
+
+template<typename T>
+arma_inline
+arma_warn_unused
+const typename arma_scalar_only<T>::result &
+max(const T& x)
+  {
+  return x;
+  }
+
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value == true) && (resolves_to_sparse_vector<T1>::value == true),
+  typename T1::elem_type
+  >::result
+max(const T1& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  return spop_max::vector_max(x);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value == true) && (resolves_to_sparse_vector<T1>::value == false),
+  const SpOp<T1, spop_max>
+  >::result
+max(const T1& X, const uword dim = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpOp<T1, spop_max>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+max(const SpOp<T1, spop_max>& X)
+  {
+  arma_extra_debug_sigprint();
+  arma_extra_debug_print("max(): two consecutive max() calls detected");
+  
+  return spop_max::vector_max(X.m);
+  }
+
+
+
+template<typename T1>
+inline
+const SpOp< SpOp<T1, spop_max>, spop_max>
+max(const SpOp<T1, spop_max>& in, const uword dim)
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpOp< SpOp<T1, spop_max>, spop_max>(in, dim, 0);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_mean.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,188 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_mean
+//! @{
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_mean>
+mean
+  (
+  const T1& X,
+  const uword dim = 0,
+  const typename enable_if< is_arma_type<T1>::value       == true  >::result* junk1 = 0,
+  const typename enable_if< resolves_to_vector<T1>::value == false >::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return Op<T1, op_mean>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_mean>
+mean
+  (
+  const T1& X,
+  const uword dim,
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1, op_mean>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+mean
+  (
+  const T1& X,
+  const arma_empty_class junk1 = arma_empty_class(),
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return op_mean::mean_all(X);
+  }
+
+
+
+//! \brief
+//! Immediate 'find mean value' operation,
+//! invoked, for example, by: mean(mean(A))
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+mean(const Op<T1, op_mean>& in)
+  {
+  arma_extra_debug_sigprint();
+  arma_extra_debug_print("mean(): two consecutive mean() calls detected");
+  
+  return op_mean::mean_all(in.m);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op< Op<T1, op_mean>, op_mean>
+mean(const Op<T1, op_mean>& in, const uword dim)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op< Op<T1, op_mean>, op_mean>(in, dim, 0);
+  }
+
+
+
+template<typename T>
+arma_inline
+arma_warn_unused
+const typename arma_scalar_only<T>::result &
+mean(const T& x)
+  {
+  return x;
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+const SpOp<T1, spop_mean>
+mean
+  (
+  const T1& X,
+  const uword dim = 0,
+  const typename enable_if< is_arma_sparse_type<T1>::value       == true  >::result* junk1 = 0,
+  const typename enable_if< resolves_to_sparse_vector<T1>::value == false >::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+
+  return SpOp<T1, spop_mean>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+const SpOp<T1, spop_mean>
+mean
+  (
+  const T1& X,
+  const uword dim,
+  const typename enable_if< resolves_to_sparse_vector<T1>::value == true >::result* junk1 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+
+  return SpOp<T1, spop_mean>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+mean
+  (
+  const T1& X,
+  const arma_empty_class junk1 = arma_empty_class(),
+  const typename enable_if< resolves_to_sparse_vector<T1>::value == true >::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+
+  return spop_mean::mean_all(X);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+mean(const SpOp<T1, spop_mean>& in)
+  {
+  arma_extra_debug_sigprint();
+  arma_extra_debug_print("mean(): two consecutive mean() calls detected");
+
+  return spop_mean::mean_all(in.m);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_median.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,82 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_median
+//! @{
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_median>
+median
+  (
+  const T1& X,
+  const uword dim = 0,
+  const typename enable_if< is_arma_type<T1>::value       == true  >::result* junk1 = 0,
+  const typename enable_if< resolves_to_vector<T1>::value == false >::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return Op<T1, op_median>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_median>
+median
+  (
+  const T1& X,
+  const uword dim,
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1, op_median>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+median
+  (
+  const T1& X,
+  const arma_empty_class junk1 = arma_empty_class(),
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return op_median::median_vec(X);
+  }
+
+
+
+template<typename T>
+arma_inline
+arma_warn_unused
+const typename arma_scalar_only<T>::result &
+median(const T& x)
+  {
+  return x;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_min.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,177 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_min
+//! @{
+
+//! \brief
+//! Delayed 'minimum values' operation.
+//! The dimension, along which the minima are found, is set via 'dim'.
+//! For dim = 0, the minimum value of each column is found (i.e. searches by traversing across rows).
+//! For dim = 1, the minimum value of each row is found (i.e. searches by traversing across columns).
+//! The default is dim = 0.
+
+template<typename T1>
+arma_inline
+const Op<T1, op_min>
+min
+  (
+  const T1& X,
+  const uword dim = 0,
+  const typename enable_if< is_arma_type<T1>::value       == true  >::result* junk1 = 0,
+  const typename enable_if< resolves_to_vector<T1>::value == false >::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return Op<T1, op_min>(X, dim, 0);
+  }
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_min>
+min
+  (
+  const T1& X,
+  const uword dim,
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1, op_min>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+min
+  (
+  const T1& X,
+  const arma_empty_class junk1 = arma_empty_class(),
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return op_min::min(X);
+  }
+
+
+
+//! \brief
+//! Immediate 'find minimum value' operation,
+//! invoked, for example, by: min(min(A))
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+min(const Op<T1, op_min>& in)
+  {
+  arma_extra_debug_sigprint();
+  arma_extra_debug_print("min(): two consecutive min() calls detected");
+  
+  return op_min::min(in.m);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op< Op<T1, op_min>, op_min>
+min(const Op<T1, op_min>& in, const uword dim)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op< Op<T1, op_min>, op_min>(in, dim, 0);
+  }
+
+
+
+template<typename T>
+arma_inline
+arma_warn_unused
+const typename arma_scalar_only<T>::result &
+min(const T& x)
+  {
+  return x;
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value == true) && (resolves_to_sparse_vector<T1>::value == true),
+  typename T1::elem_type
+  >::result
+min(const T1& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  return spop_min::vector_min(x);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value == true) && (resolves_to_sparse_vector<T1>::value == false),
+  const SpOp<T1, spop_min>
+  >::result
+min(const T1& X, const uword dim = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpOp<T1, spop_min>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+min(const SpOp<T1, spop_min>& X)
+  {
+  arma_extra_debug_sigprint();
+  arma_extra_debug_print("min(): two consecutive min() calls detected");
+  
+  return spop_min::vector_min(X.m);
+  }
+
+
+
+template<typename T1>
+inline
+const SpOp< SpOp<T1, spop_min>, spop_min>
+min(const SpOp<T1, spop_min>& in, const uword dim)
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpOp< SpOp<T1, spop_min>, spop_min>(in, dim, 0);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_misc.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,229 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_misc
+//! @{
+
+
+
+//! \brief
+//! Generate a vector with 'num' elements.
+//! The values of the elements linearly increase from 'start' upto (and including) 'end'.
+
+template<typename vec_type>
+inline
+vec_type
+linspace
+  (
+  const typename vec_type::pod_type start,
+  const typename vec_type::pod_type end,
+  const uword num = 100u,
+  const typename arma_Mat_Col_Row_only<vec_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename vec_type::elem_type eT;
+  typedef typename vec_type::pod_type   T;
+  
+  vec_type x;
+    
+  if(num >= 2)
+    {
+    x.set_size(num);
+    
+    eT* x_mem = x.memptr();
+    
+    const uword num_m1 = num - 1;
+    
+    if(is_non_integral<T>::value == true)
+      {
+      const T delta = (end-start)/T(num_m1);
+      
+      for(uword i=0; i<num_m1; ++i)
+        {
+        x_mem[i] = eT(start + i*delta);
+        }
+      
+      x_mem[num_m1] = eT(end);
+      }
+    else
+      {
+      const double delta = (end >= start) ? double(end-start)/double(num_m1) : -double(start-end)/double(num_m1);
+      
+      for(uword i=0; i<num_m1; ++i)
+        {
+        x_mem[i] = eT(double(start) + i*delta);
+        }
+      
+      x_mem[num_m1] = eT(end);
+      }
+    
+    return x;
+    }
+  else
+    {
+    x.set_size(1);
+    
+    x[0] = eT(end);
+    }
+  
+  return x;
+  }
+
+
+
+inline
+mat
+linspace(const double start, const double end, const uword num = 100u)
+  {
+  arma_extra_debug_sigprint();
+  return linspace<mat>(start, end, num);
+  }
+
+
+
+//
+// log_exp_add
+
+template<typename eT>
+inline
+typename arma_real_only<eT>::result
+log_add_exp(eT log_a, eT log_b)
+  {
+  if(log_a < log_b)
+    {
+    std::swap(log_a, log_b);
+    }
+  
+  const eT negdelta = log_b - log_a;
+  
+  if( (negdelta < Datum<eT>::log_min) || (arma_isfinite(negdelta) == false) )
+    {
+    return log_a;
+    }
+  else
+    {
+    #if defined(ARMA_HAVE_LOG1P)
+      return (log_a + log1p(std::exp(negdelta)));
+    #else
+      return (log_a + std::log(1.0 + std::exp(negdelta)));
+    #endif
+    }
+  }
+
+
+
+// for compatibility with earlier versions
+template<typename eT>
+inline
+typename arma_real_only<eT>::result
+log_add(eT log_a, eT log_b)
+  {
+  return log_add_exp(log_a, log_b);
+  }
+  
+
+
+template<typename eT>
+arma_inline
+arma_warn_unused
+bool
+is_finite(const eT x, const typename arma_scalar_only<eT>::result* junk = 0)
+  {
+  arma_ignore(junk);
+  
+  return arma_isfinite(x);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+bool
+is_finite(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   tmp(X.get_ref());
+  const Mat<eT>& A = tmp.M;
+  
+  return A.is_finite();
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+bool
+is_finite(const BaseCube<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_cube<T1> tmp(X.get_ref());
+  const Cube<eT>& A =   tmp.M;
+  
+  return A.is_finite();
+  }
+
+
+
+template<typename T1>
+arma_inline
+Op<T1, op_sympd>
+sympd(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_sympd>(X.get_ref());
+  }
+
+
+
+template<typename eT>
+inline
+void
+swap(Mat<eT>& A, Mat<eT>& B)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword A_mem_state = A.mem_state;
+  
+  if( (A.vec_state == B.vec_state) && (A_mem_state == B.mem_state) && ((A_mem_state == 0) || (A_mem_state == 3)) )
+    {
+    A.swap(B);
+    }
+  else
+    {
+    if(A.n_elem <= B.n_elem)
+      {
+      Mat<eT> C = A;
+      
+      A.steal_mem(B);
+      B.steal_mem(C);
+      }
+    else
+      {
+      Mat<eT> C = B;
+      
+      B.steal_mem(A);
+      A.steal_mem(C);
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_n_unique.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,120 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_n_unique
+//! @{
+
+
+//! \brief
+//! Get the number of unique nonzero elements in two sparse matrices.
+//! This is very useful for determining the amount of memory necessary before
+//! a sparse matrix operation on two matrices.
+
+template<typename T1, typename T2, typename op_n_unique_type>
+inline
+uword
+n_unique
+  (
+  const SpBase<typename T1::elem_type, T1>& x,
+  const SpBase<typename T2::elem_type, T2>& y,
+  const op_n_unique_type junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> pa(x.get_ref());
+  const SpProxy<T2> pb(y.get_ref());
+  
+  return n_unique(pa,pb,junk);
+  }
+
+
+
+template<typename T1, typename T2, typename op_n_unique_type>
+arma_hot
+inline
+uword
+n_unique
+  (
+  const SpProxy<T1>& pa,
+  const SpProxy<T2>& pb,
+  const op_n_unique_type junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  // Use iterators.
+  typename SpProxy<T1>::const_iterator_type x_it = pa.begin();
+  typename SpProxy<T2>::const_iterator_type y_it = pb.begin();
+
+  uword total_n_nonzero = 0;
+
+  while((x_it != pa.end()) || (y_it != pb.end()))
+    {
+    if(x_it == y_it)
+      {
+      if(op_n_unique_type::eval((*x_it), (*y_it)) != typename T1::elem_type(0))
+        {
+        ++total_n_nonzero;
+        }
+
+      ++x_it;
+      ++y_it;
+      }
+    else
+      {
+      if((x_it.col() < y_it.col()) || ((x_it.col() == y_it.col()) && (x_it.row() < y_it.row()))) // if y is closer to the end
+        {
+        if(op_n_unique_type::eval((*x_it), typename T1::elem_type(0)) != typename T1::elem_type(0))
+          {
+          ++total_n_nonzero;
+          }
+
+        ++x_it;
+        }
+      else // x is closer to the end
+        {
+        if(op_n_unique_type::eval(typename T1::elem_type(0), (*y_it)) != typename T1::elem_type(0))
+          {
+          ++total_n_nonzero;
+          }
+
+        ++y_it;
+        }
+      }
+    }
+
+  return total_n_nonzero;
+  }
+
+
+// Simple operators.
+struct op_n_unique_add
+  {
+  template<typename eT> inline static eT eval(const eT& l, const eT& r) { return (l + r); }
+  };
+
+struct op_n_unique_sub
+  {
+  template<typename eT> inline static eT eval(const eT& l, const eT& r) { return (l - r); }
+  };
+
+struct op_n_unique_mul
+  {
+  template<typename eT> inline static eT eval(const eT& l, const eT& r) { return (l * r); }
+  };
+
+struct op_n_unique_count
+  {
+  template<typename eT> inline static eT eval(const eT& l, const eT& r) { return 1; }
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_norm.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,814 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_norm
+//! @{
+
+
+
+template<typename T1>
+arma_hot
+inline
+typename T1::pod_type
+arma_vec_norm_1(const Proxy<T1>& P)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::pod_type T;
+  
+  T acc = T(0);
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type A = P.get_ea();
+    
+    const uword N = P.get_n_elem();
+    
+    T acc1 = T(0);
+    T acc2 = T(0);
+    
+    uword i,j;
+    for(i=0, j=1; j<N; i+=2, j+=2)
+      {
+      acc1 += std::abs(A[i]);
+      acc2 += std::abs(A[j]);
+      }
+    
+    if(i < N)
+      {
+      acc1 += std::abs(A[i]);
+      }
+    
+    acc = acc1 + acc2;
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    if(n_rows == 1)
+      {
+      for(uword col=0; col<n_cols; ++col)
+        {
+        acc += std::abs(P.at(0,col));
+        }
+      }
+    else
+      {
+      for(uword col=0; col<n_cols; ++col)
+        {
+        uword i,j;
+        
+        for(i=0, j=1; j<n_rows; i+=2, j+=2)
+          {
+          acc += std::abs(P.at(i,col));
+          acc += std::abs(P.at(j,col));
+          }
+        
+        if(i < n_rows)
+          {
+          acc += std::abs(P.at(i,col));
+          }
+        }
+      }
+    }
+    
+  return acc;
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+typename T1::pod_type
+arma_vec_norm_2
+  (
+  const Proxy<T1>& P,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::pod_type T;
+  
+  T acc = T(0);
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type A = P.get_ea();
+    
+    const uword N = P.get_n_elem();
+    
+    T acc1 = T(0);
+    T acc2 = T(0);
+    
+    uword i,j;
+    
+    for(i=0, j=1; j<N; i+=2, j+=2)
+      {
+      const T tmp_i = A[i];
+      const T tmp_j = A[j];
+      
+      acc1 += tmp_i * tmp_i;
+      acc2 += tmp_j * tmp_j;
+      }
+    
+    if(i < N)
+      {
+      const T tmp_i = A[i];
+      
+      acc1 += tmp_i * tmp_i;
+      }
+    
+    acc = acc1 + acc2;
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    if(n_rows == 1)
+      {
+      for(uword col=0; col<n_cols; ++col)
+        {
+        const T tmp = P.at(0,col);
+        
+        acc += tmp * tmp;
+        }
+      }
+    else
+      {
+      for(uword col=0; col<n_cols; ++col)
+        {
+        uword i,j;
+        for(i=0, j=1; j<n_rows; i+=2, j+=2)
+          {
+          const T tmp_i = P.at(i,col);
+          const T tmp_j = P.at(j,col);
+          
+          acc += tmp_i * tmp_i;
+          acc += tmp_j * tmp_j;
+          }
+        
+        if(i < n_rows)
+          {
+          const T tmp_i = P.at(i,col);
+          
+          acc += tmp_i * tmp_i;
+          }
+        }
+      }
+    }
+  
+  return std::sqrt(acc);
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+typename T1::pod_type
+arma_vec_norm_2
+  (
+  const Proxy<T1>& P,
+  const typename arma_cx_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::pod_type T;
+  
+  T acc = T(0);
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type A = P.get_ea();
+    
+    const uword N = P.get_n_elem();
+    
+    for(uword i=0; i<N; ++i)
+      {
+      const T tmp = std::abs(A[i]);
+      acc += tmp*tmp;
+      }
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    if(n_rows == 1)
+      {
+      for(uword col=0; col<n_cols; ++col)
+        {
+        const T tmp = std::abs(P.at(0,col));
+        acc += tmp*tmp;
+        }
+      }
+    else
+      {
+      for(uword col=0; col<n_cols; ++col)
+      for(uword row=0; row<n_rows; ++row)
+        {
+        const T tmp = std::abs(P.at(row,col));
+        acc += tmp*tmp;
+        }
+      }
+    }
+  
+  return std::sqrt(acc);
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+typename T1::pod_type
+arma_vec_norm_k
+  (
+  const Proxy<T1>& P,
+  const int k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::pod_type T;
+  
+  T acc = T(0);
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type A = P.get_ea();
+    
+    const uword N = P.get_n_elem();
+    
+    uword i,j;
+    
+    for(i=0, j=1; j<N; i+=2, j+=2)
+      {
+      acc += std::pow(std::abs(A[i]), k);
+      acc += std::pow(std::abs(A[j]), k);
+      }
+    
+    if(i < N)
+      {
+      acc += std::pow(std::abs(A[i]), k);
+      }
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    if(n_rows != 1)
+      {
+      for(uword col=0; col < n_cols; ++col)
+      for(uword row=0; row < n_rows; ++row)
+        {
+        acc += std::pow(std::abs(P.at(row,col)), k);
+        }
+      }
+    else
+      {
+      for(uword col=0; col < n_cols; ++col)
+        {
+        acc += std::pow(std::abs(P.at(0,col)), k);
+        }
+      }
+    }
+  
+  return std::pow(acc, T(1)/T(k));
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+typename T1::pod_type
+arma_vec_norm_max(const Proxy<T1>& P)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::pod_type T;
+  
+  const uword N = P.get_n_elem();
+  
+  T max_val = (N != 1) ? priv::most_neg<T>() : std::abs(P[0]);
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type A = P.get_ea();
+    
+    uword i,j;
+    for(i=0, j=1; j<N; i+=2, j+=2)
+      {
+      const T tmp_i = std::abs(A[i]);
+      const T tmp_j = std::abs(A[j]);
+      
+      if(max_val < tmp_i) { max_val = tmp_i; }
+      if(max_val < tmp_j) { max_val = tmp_j; }
+      }
+    
+    if(i < N)
+      {
+      const T tmp_i = std::abs(A[i]);
+      
+      if(max_val < tmp_i) { max_val = tmp_i; }
+      }
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    if(n_rows != 1)
+      {
+      for(uword col=0; col < n_cols; ++col)
+      for(uword row=0; row < n_rows; ++row)
+        {
+        const T tmp = std::abs(P.at(row,col));
+        
+        if(max_val < tmp) { max_val = tmp; }
+        }
+      }
+    else
+      {
+      for(uword col=0; col < n_cols; ++col)
+        {
+        const T tmp = std::abs(P.at(0,col));
+        
+        if(max_val < tmp) { max_val = tmp; }
+        }
+      }
+    }
+  
+  return max_val;
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+typename T1::pod_type
+arma_vec_norm_min(const Proxy<T1>& P)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::pod_type T;
+  
+  const uword N = P.get_n_elem();
+  
+  T min_val = (N != 1) ? priv::most_pos<T>() : std::abs(P[0]);
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type A = P.get_ea();
+    
+    uword i,j;
+    for(i=0, j=1; j<N; i+=2, j+=2)
+      {
+      const T tmp_i = std::abs(A[i]);
+      const T tmp_j = std::abs(A[j]);
+      
+      if(min_val > tmp_i) { min_val = tmp_i; }
+      if(min_val > tmp_j) { min_val = tmp_j; }
+      }
+    
+    if(i < N)
+      {
+      const T tmp_i = std::abs(A[i]);
+      
+      if(min_val > tmp_i) { min_val = tmp_i; }
+      }
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    if(n_rows != 1)
+      {
+      for(uword col=0; col < n_cols; ++col)
+      for(uword row=0; row < n_rows; ++row)
+        {
+        const T tmp = std::abs(P.at(row,col));
+        
+        if(min_val > tmp) { min_val = tmp; }
+        }
+      }
+    else
+      {
+      for(uword col=0; col < n_cols; ++col)
+        {
+        const T tmp = std::abs(P.at(0,col));
+        
+        if(min_val > tmp) { min_val = tmp; }
+        }
+      }
+    }
+  
+  return min_val;
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::pod_type
+arma_mat_norm_1(const Proxy<T1>& P)
+  {
+  arma_extra_debug_sigprint();
+  
+  // TODO: this can be sped up with a dedicated implementation
+  return as_scalar( max( sum(abs(P.Q), 0), 1) );
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::pod_type
+arma_mat_norm_2(const Proxy<T1>& P)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::pod_type   T;
+  
+  // TODO: is the SVD based approach only valid for square matrices?
+  
+  Col<T> S;
+  svd(S, P.Q);
+  
+  return (S.n_elem > 0) ? max(S) : T(0);
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::pod_type
+arma_mat_norm_inf(const Proxy<T1>& P)
+  {
+  arma_extra_debug_sigprint();
+  
+  // TODO: this can be sped up with a dedicated implementation
+  return as_scalar( max( sum(abs(P.Q), 1), 0) );
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename enable_if2< is_arma_type<T1>::value, typename T1::pod_type >::result
+norm
+  (
+  const T1& X,
+  const uword k,
+  const typename arma_real_or_cx_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::pod_type T;
+  
+  const Proxy<T1> P(X);
+  
+  if(P.get_n_elem() == 0)
+    {
+    return T(0);
+    }
+  
+  const bool is_vec = (P.get_n_rows() == 1) || (P.get_n_cols() == 1);
+  
+  if(is_vec == true)
+    {
+    switch(k)
+      {
+      case 1:
+        return arma_vec_norm_1(P);
+        break;
+      
+      case 2:
+        return arma_vec_norm_2(P);
+        break;
+      
+      default:
+        {
+        arma_debug_check( (k == 0), "norm(): k must be greater than zero"   );
+        return arma_vec_norm_k(P, int(k));
+        }
+      }
+    }
+  else
+    {
+    switch(k)
+      {
+      case 1:
+        return arma_mat_norm_1(P);
+        break;
+      
+      case 2:
+        return arma_mat_norm_2(P);
+        break;
+      
+      default:
+        arma_stop("norm(): unsupported matrix norm type");
+        return T(0);
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename enable_if2< is_arma_type<T1>::value, typename T1::pod_type >::result
+norm
+  (
+  const T1& X,
+  const char* method,
+  const typename arma_real_or_cx_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::pod_type T;
+  
+  const Proxy<T1> P(X);
+  
+  if(P.get_n_elem() == 0)
+    {
+    return T(0);
+    }
+  
+  const char sig    = method[0];
+  const bool is_vec = (P.get_n_rows() == 1) || (P.get_n_cols() == 1);
+  
+  if(is_vec == true)
+    {
+    if( (sig == 'i') || (sig == 'I') || (sig == '+') )   // max norm
+      {
+      return arma_vec_norm_max(P);
+      }
+    else
+    if(sig == '-')   // min norm
+      {
+      return arma_vec_norm_min(P);
+      }
+    else
+    if( (sig == 'f') || (sig == 'F') )
+      {
+      return arma_vec_norm_2(P);
+      }
+    else
+      {
+      arma_stop("norm(): unsupported vector norm type");
+      return T(0);
+      }
+    }
+  else
+    {
+    if( (sig == 'i') || (sig == 'I') || (sig == '+') )   // inf norm
+      {
+      return arma_mat_norm_inf(P);
+      }
+    else
+    if( (sig == 'f') || (sig == 'F') )
+      {
+      return arma_vec_norm_2(P);
+      }
+    else
+      {
+      arma_stop("norm(): unsupported matrix norm type");
+      return T(0);
+      }
+    }
+  }
+
+
+
+//
+// norms for sparse matrices
+
+
+
+template<typename T1>
+inline
+typename T1::pod_type
+arma_mat_norm_1(const SpProxy<T1>& P)
+  {
+  arma_extra_debug_sigprint();
+  
+  // TODO: this can be sped up with a dedicated implementation
+  return as_scalar( max( sum(abs(P.Q), 0), 1) );
+  }
+
+
+
+// template<typename T1>
+// inline
+// typename T1::pod_type
+// arma_mat_norm_2(const SpProxy<T1>& P)
+//   {
+//   arma_extra_debug_sigprint();
+//   
+//   // TODO: norm = sqrt( largest eigenvalue of (A^H)*A ), where ^H is the conjugate transpose
+//   // TODO: can use ARPACK or directly implement the Arnoldi iteration
+//   // http://math.stackexchange.com/questions/4368/computing-the-largest-eigenvalue-of-a-very-large-sparse-matrix
+//   }
+
+
+
+template<typename T1>
+inline
+typename T1::pod_type
+arma_mat_norm_inf(const SpProxy<T1>& P)
+  {
+  arma_extra_debug_sigprint();
+  
+  // TODO: this can be sped up with a dedicated implementation
+  return as_scalar( max( sum(abs(P.Q), 1), 0) );
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename enable_if2< is_arma_sparse_type<T1>::value, typename T1::pod_type >::result
+norm
+  (
+  const T1& X,
+  const uword k,
+  const typename arma_real_or_cx_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  typedef typename T1::pod_type   T;
+  
+  const SpProxy<T1> P(X);
+  
+  if(P.get_n_nonzero() == 0)
+    {
+    return T(0);
+    }
+  
+  const bool is_vec = (P.get_n_rows() == 1) || (P.get_n_cols() == 1);
+  
+  if(is_vec == true)
+    {
+    const unwrap_spmat<typename SpProxy<T1>::stored_type> tmp(P.Q);
+    const SpMat<eT>& A = tmp.M;
+    
+    // create a fake dense vector to allow reuse of code for dense vectors
+    Col<eT> fake_vector( access::rwp(A.values), A.n_nonzero, false );
+    
+    const Proxy< Col<eT> > P_fake_vector(fake_vector);
+    
+    switch(k)
+      {
+      case 1:
+        return arma_vec_norm_1(P_fake_vector);
+        break;
+      
+      case 2:
+        return arma_vec_norm_2(P_fake_vector);
+        break;
+      
+      default:
+        {
+        arma_debug_check( (k == 0), "norm(): k must be greater than zero"   );
+        return arma_vec_norm_k(P_fake_vector, int(k));
+        }
+      }
+    }
+  else
+    {
+    switch(k)
+      {
+      case 1:
+        return arma_mat_norm_1(P);
+        break;
+      
+      // case 2:
+      //   return arma_mat_norm_2(P);
+      //   break;
+      
+      default:
+        arma_stop("norm(): unsupported or unimplemented norm type for sparse matrices");
+        return T(0);
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename enable_if2< is_arma_sparse_type<T1>::value, typename T1::pod_type >::result
+norm
+  (
+  const T1& X,
+  const char* method,
+  const typename arma_real_or_cx_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  typedef typename T1::pod_type   T;
+  
+  const SpProxy<T1> P(X);
+  
+  if(P.get_n_nonzero() == 0)
+    {
+    return T(0);
+    }
+  
+  
+  const unwrap_spmat<typename SpProxy<T1>::stored_type> tmp(P.Q);
+  const SpMat<eT>& A = tmp.M;
+  
+  // create a fake dense vector to allow reuse of code for dense vectors
+  Col<eT> fake_vector( access::rwp(A.values), A.n_nonzero, false );
+  
+  const Proxy< Col<eT> > P_fake_vector(fake_vector);
+  
+  
+  const char sig    = method[0];
+  const bool is_vec = (P.get_n_rows() == 1) || (P.get_n_cols() == 1);
+  
+  if(is_vec == true)
+    {
+    if( (sig == 'i') || (sig == 'I') || (sig == '+') )   // max norm
+      {
+      return arma_vec_norm_max(P_fake_vector);
+      }
+    else
+    if(sig == '-')   // min norm
+      {
+      const T val = arma_vec_norm_min(P_fake_vector);
+      
+      if( P.get_n_nonzero() < P.get_n_elem() )
+        {
+        return (std::min)(T(0), val);
+        }
+      else
+        {
+        return val;
+        }
+      }
+    else
+    if( (sig == 'f') || (sig == 'F') )
+      {
+      return arma_vec_norm_2(P_fake_vector);
+      }
+    else
+      {
+      arma_stop("norm(): unsupported vector norm type");
+      return T(0);
+      }
+    }
+  else
+    {
+    if( (sig == 'i') || (sig == 'I') || (sig == '+') )   // inf norm
+      {
+      return arma_mat_norm_inf(P);
+      }
+    else
+    if( (sig == 'f') || (sig == 'F') )
+      {
+      return arma_vec_norm_2(P_fake_vector);
+      }
+    else
+      {
+      arma_stop("norm(): unsupported matrix norm type");
+      return T(0);
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_ones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,104 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_ones
+//! @{
+
+
+
+arma_inline
+const Gen<vec, gen_ones_full>
+ones(const uword n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Gen<vec, gen_ones_full>(n_elem, 1);
+  }
+
+
+
+template<typename obj_type>
+arma_inline
+const Gen<obj_type, gen_ones_full>
+ones(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only<obj_type>::result* junk2 = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  if(is_Row<obj_type>::value == true)
+    {
+    return Gen<obj_type, gen_ones_full>(1, n_elem);
+    }
+  else
+    {
+    return Gen<obj_type, gen_ones_full>(n_elem, 1);
+    }
+  }
+
+
+
+arma_inline
+const Gen<mat, gen_ones_full>
+ones(const uword n_rows, const uword n_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Gen<mat, gen_ones_full>(n_rows, n_cols);
+  }
+
+
+
+template<typename obj_type>
+inline
+const Gen<obj_type, gen_ones_full>
+ones(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only<obj_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  if(is_Col<obj_type>::value == true)
+    {
+    arma_debug_check( (n_cols != 1), "ones(): incompatible size" );
+    }
+  else
+  if(is_Row<obj_type>::value == true)
+    {
+    arma_debug_check( (n_rows != 1), "ones(): incompatible size" );
+    }
+  
+  return Gen<obj_type, gen_ones_full>(n_rows, n_cols);
+  }
+
+
+
+arma_inline
+const GenCube<cube::elem_type, gen_ones_full>
+ones(const uword n_rows, const uword n_cols, const uword n_slices)
+  {
+  arma_extra_debug_sigprint();
+  
+  return GenCube<cube::elem_type, gen_ones_full>(n_rows, n_cols, n_slices);
+  }
+
+
+
+template<typename cube_type>
+arma_inline
+const GenCube<typename cube_type::elem_type, gen_ones_full>
+ones(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only<cube_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return GenCube<typename cube_type::elem_type, gen_ones_full>(n_rows, n_cols, n_slices);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_pinv.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,61 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_pinv
+//! @{
+
+
+
+template<typename T1>
+inline
+const Op<T1, op_pinv>
+pinv
+  (
+  const Base<typename T1::elem_type,T1>& X,
+  const typename T1::elem_type tol = 0.0,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1, op_pinv>(X.get_ref(), tol);
+  }
+
+
+
+template<typename T1>
+inline
+bool
+pinv
+  (
+         Mat<typename T1::elem_type>&    out,
+  const Base<typename T1::elem_type,T1>& X,
+  const typename T1::elem_type tol = 0.0,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  try
+    {
+    out = pinv(X,tol);
+    }
+  catch(std::runtime_error&)
+    {
+    return false;
+    }
+  
+  return true;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_princomp.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,170 @@
+// Copyright (C) 2010-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2012 Conrad Sanderson
+// Copyright (C) 2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_princomp
+//! @{
+
+
+
+//! \brief
+//! principal component analysis -- 4 arguments version
+//! coeff_out    -> principal component coefficients
+//! score_out    -> projected samples
+//! latent_out   -> eigenvalues of principal vectors
+//! tsquared_out -> Hotelling's T^2 statistic
+template<typename T1>
+inline
+bool
+princomp
+  (
+         Mat<typename T1::elem_type>&    coeff_out,
+         Mat<typename T1::elem_type>&    score_out,
+         Col<typename T1::pod_type>&     latent_out,
+         Col<typename T1::elem_type>&    tsquared_out,
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const bool status = op_princomp::direct_princomp(coeff_out, score_out, latent_out, tsquared_out, X);
+  
+  if(status == false)
+    {
+    coeff_out.reset();
+    score_out.reset();
+    latent_out.reset();
+    tsquared_out.reset();
+    
+    arma_bad("princomp(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+//! \brief
+//! principal component analysis -- 3 arguments version
+//! coeff_out    -> principal component coefficients
+//! score_out    -> projected samples
+//! latent_out   -> eigenvalues of principal vectors
+template<typename T1>
+inline
+bool
+princomp
+  (
+         Mat<typename T1::elem_type>&    coeff_out,
+         Mat<typename T1::elem_type>&    score_out,
+         Col<typename T1::pod_type>&     latent_out,
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const bool status = op_princomp::direct_princomp(coeff_out, score_out, latent_out, X); 
+  
+  if(status == false)
+    {
+    coeff_out.reset();
+    score_out.reset();
+    latent_out.reset();
+    
+    arma_bad("princomp(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+//! \brief
+//! principal component analysis -- 2 arguments version
+//! coeff_out    -> principal component coefficients
+//! score_out    -> projected samples
+template<typename T1>
+inline
+bool
+princomp
+  (
+         Mat<typename T1::elem_type>&    coeff_out,
+         Mat<typename T1::elem_type>&    score_out,
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const bool status = op_princomp::direct_princomp(coeff_out, score_out, X); 
+  
+  if(status == false)
+    {
+    coeff_out.reset();
+    score_out.reset();
+    
+    arma_bad("princomp(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+//! \brief
+//! principal component analysis -- 1 argument version
+//! coeff_out    -> principal component coefficients
+template<typename T1>
+inline
+bool
+princomp
+  (
+         Mat<typename T1::elem_type>&    coeff_out,
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const bool status = op_princomp::direct_princomp(coeff_out, X);
+  
+  if(status == false)
+    {
+    coeff_out.reset();
+    
+    arma_bad("princomp(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+template<typename T1>
+inline
+const Op<T1, op_princomp>
+princomp
+  (
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1, op_princomp>(X.get_ref());
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_prod.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,120 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_prod
+//! @{
+
+
+//! \brief
+//! Delayed product of elements of a matrix along a specified dimension (either rows or columns).
+//! The result is stored in a dense matrix that has either one column or one row.
+//! For dim = 0, find the sum of each column (i.e. traverse across rows)
+//! For dim = 1, find the sum of each row (i.e. traverse across columns)
+//! The default is dim = 0.
+//! NOTE: this function works differently than in Matlab/Octave.
+
+template<typename T1>
+arma_inline
+const Op<T1, op_prod>
+prod
+  (
+  const T1& X,
+  const uword dim = 0,
+  const typename enable_if< is_arma_type<T1>::value       == true  >::result* junk1 = 0,
+  const typename enable_if< resolves_to_vector<T1>::value == false >::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return Op<T1, op_prod>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_prod>
+prod
+  (
+  const T1& X,
+  const uword dim,
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1, op_prod>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+prod
+  (
+  const T1& X,
+  const arma_empty_class junk1 = arma_empty_class(),
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return op_prod::prod( X );
+  }
+
+
+
+//! \brief
+//! Immediate 'product of all values' operation,
+//! invoked, for example, by: prod(prod(A))
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+prod(const Op<T1, op_prod>& in)
+  {
+  arma_extra_debug_sigprint();
+  arma_extra_debug_print("prod(): two consecutive prod() calls detected");
+  
+  return op_prod::prod( in.m );
+  }
+
+
+
+template<typename T1>
+inline
+const Op<Op<T1, op_prod>, op_prod>
+prod(const Op<T1, op_prod>& in, const uword dim)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<Op<T1, op_prod>, op_prod>(in, dim, 0);
+  }
+
+
+
+template<typename T>
+arma_inline
+arma_warn_unused
+const typename arma_scalar_only<T>::result &
+prod(const T& x)
+  {
+  return x;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_qr.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,76 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_qr
+//! @{
+
+
+
+//! QR decomposition
+template<typename T1>
+inline
+bool
+qr
+  (
+         Mat<typename T1::elem_type>&    Q,
+         Mat<typename T1::elem_type>&    R,
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  arma_debug_check( (&Q == &R), "qr(): Q and R are the same object");
+  
+  const bool status = auxlib::qr(Q, R, X);
+  
+  if(status == false)
+    {
+    Q.reset();
+    R.reset();
+    arma_bad("qr(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+//! economical QR decomposition
+template<typename T1>
+inline
+bool
+qr_econ
+  (
+         Mat<typename T1::elem_type>&    Q,
+         Mat<typename T1::elem_type>&    R,
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  arma_debug_check( (&Q == &R), "qr_econ(): Q and R are the same object");
+  
+  const bool status = auxlib::qr_econ(Q, R, X);
+  
+  if(status == false)
+    {
+    Q.reset();
+    R.reset();
+    arma_bad("qr_econ(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_randn.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,123 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_randn
+//! @{
+
+
+inline
+double
+randn()
+  {
+  return double(eop_aux_randn<double>());
+  }
+
+
+template<typename eT>
+inline
+typename arma_scalar_only<eT>::result
+randn()
+  {
+  return eT(eop_aux_randn<eT>());
+  }
+
+
+
+//! Generate a vector with all elements set to random values with a gaussian distribution (zero mean, unit variance)
+arma_inline
+const Gen<vec, gen_randn>
+randn(const uword n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Gen<vec, gen_randn>(n_elem, 1);
+  }
+
+
+
+template<typename obj_type>
+arma_inline
+const Gen<obj_type, gen_randn>
+randn(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only<obj_type>::result* junk2 = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  if(is_Row<obj_type>::value == true)
+    {
+    return Gen<obj_type, gen_randn>(1, n_elem);
+    }
+  else
+    {
+    return Gen<obj_type, gen_randn>(n_elem, 1);
+    }
+  }
+
+
+
+//! Generate a dense matrix with all elements set to random values with a gaussian distribution (zero mean, unit variance)
+arma_inline
+const Gen<mat, gen_randn>
+randn(const uword n_rows, const uword n_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Gen<mat, gen_randn>(n_rows, n_cols);
+  }
+
+
+
+template<typename obj_type>
+arma_inline
+const Gen<obj_type, gen_randn>
+randn(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only<obj_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  if(is_Col<obj_type>::value == true)
+    {
+    arma_debug_check( (n_cols != 1), "randn(): incompatible size" );
+    }
+  else
+  if(is_Row<obj_type>::value == true)
+    {
+    arma_debug_check( (n_rows != 1), "randn(): incompatible size" );
+    }
+  
+  return Gen<obj_type, gen_randn>(n_rows, n_cols);
+  }
+
+
+
+arma_inline
+const GenCube<cube::elem_type, gen_randn>
+randn(const uword n_rows, const uword n_cols, const uword n_slices)
+  {
+  arma_extra_debug_sigprint();
+  
+  return GenCube<cube::elem_type, gen_randn>(n_rows, n_cols, n_slices);
+  }
+
+
+
+template<typename cube_type>
+arma_inline
+const GenCube<typename cube_type::elem_type, gen_randn>
+randn(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only<cube_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();  
+  arma_ignore(junk);
+  
+  return GenCube<typename cube_type::elem_type, gen_randn>(n_rows, n_cols, n_slices);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_randu.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,123 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_randu
+//! @{
+
+
+inline
+double
+randu()
+  {
+  return double(eop_aux_randu<double>());
+  }
+
+
+template<typename eT>
+inline
+typename arma_scalar_only<eT>::result
+randu()
+  {
+  return eT(eop_aux_randu<eT>());
+  }
+
+
+
+//! Generate a vector with all elements set to random values in the [0,1] interval (uniform distribution)
+arma_inline
+const Gen<vec, gen_randu>
+randu(const uword n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Gen<vec, gen_randu>(n_elem, 1);
+  }
+
+
+
+template<typename obj_type>
+arma_inline
+const Gen<obj_type, gen_randu>
+randu(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only<obj_type>::result* junk2 = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  if(is_Row<obj_type>::value == true)
+    {
+    return Gen<obj_type, gen_randu>(1, n_elem);
+    }
+  else
+    {
+    return Gen<obj_type, gen_randu>(n_elem, 1);
+    }
+  }
+
+
+
+//! Generate a dense matrix with all elements set to random values in the [0,1] interval (uniform distribution)
+arma_inline
+const Gen<mat, gen_randu>
+randu(const uword n_rows, const uword n_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Gen<mat, gen_randu>(n_rows, n_cols);
+  }
+
+
+
+template<typename obj_type>
+arma_inline
+const Gen<obj_type, gen_randu>
+randu(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only<obj_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  if(is_Col<obj_type>::value == true)
+    {
+    arma_debug_check( (n_cols != 1), "randu(): incompatible size" );
+    }
+  else
+  if(is_Row<obj_type>::value == true)
+    {
+    arma_debug_check( (n_rows != 1), "randu(): incompatible size" );
+    }
+  
+  return Gen<obj_type, gen_randu>(n_rows, n_cols);
+  }
+
+
+
+arma_inline
+const GenCube<cube::elem_type, gen_randu>
+randu(const uword n_rows, const uword n_cols, const uword n_slices)
+  {
+  arma_extra_debug_sigprint();
+  
+  return GenCube<cube::elem_type, gen_randu>(n_rows, n_cols, n_slices);
+  }
+
+
+
+template<typename cube_type>
+arma_inline
+const GenCube<typename cube_type::elem_type, gen_randu>
+randu(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only<cube_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return GenCube<typename cube_type::elem_type, gen_randu>(n_rows, n_cols, n_slices);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_rank.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,71 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// Copyright (C) 2011 Stanislav Funiak
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_rank
+//! @{
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+uword
+rank
+  (
+  const Base<typename T1::elem_type,T1>& X,
+        typename T1::pod_type            tol = 0.0,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::pod_type T;
+  
+  uword  X_n_rows;
+  uword  X_n_cols;
+  Col<T> s;
+  
+  const bool  status = auxlib::svd(s, X, X_n_rows, X_n_cols);
+  const uword n_elem = s.n_elem;
+  
+  if(status == true)
+    {
+    if( (tol == T(0)) && (n_elem > 0) )
+      {
+      tol = (std::max)(X_n_rows, X_n_cols) * eop_aux::direct_eps(max(s));
+      }
+    
+    // count non zero valued elements in s
+    
+    const T*  s_mem  = s.memptr();
+          uword count  = 0;
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      if(s_mem[i] > tol)
+        {
+        ++count;
+        }
+      }
+    
+    return count;
+    }
+  else
+    {
+    arma_bad("rank(): failed to converge");
+    
+    return uword(0);
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_repmat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,29 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup fn_repmat
+//! @{
+
+
+//! \brief
+//! delayed 'repeat matrix' construction of a matrix
+template<typename T1>
+arma_inline
+const Op<T1, op_repmat>
+repmat(const Base<typename T1::elem_type,T1>& A, const uword r, const uword c)
+  {
+  arma_extra_debug_sigprint();
+
+  return Op<T1, op_repmat>(A.get_ref(), r, c);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_reshape.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,42 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_reshape
+//! @{
+
+
+
+template<typename T1>
+inline
+const Op<T1, op_reshape>
+reshape(const Base<typename T1::elem_type,T1>& X, const uword in_n_rows, const uword in_n_cols, const uword dim = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (dim > 1), "reshape(): dim must be 0 or 1");
+  
+  return Op<T1, op_reshape>(X.get_ref(), in_n_rows, in_n_cols, dim, 'j');
+  }
+
+
+
+template<typename T1>
+inline
+const OpCube<T1, op_reshape>
+reshape(const BaseCube<typename T1::elem_type,T1>& X, const uword in_n_rows, const uword in_n_cols, const uword in_n_slices, const uword dim = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (dim > 1), "reshape(): dim must be 0 or 1");
+  
+  return OpCube<T1, op_reshape>(X.get_ref(), in_n_rows, in_n_cols, in_n_slices, dim, 'j');
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_resize.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,38 @@
+// Copyright (C) 2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_resize
+//! @{
+
+
+
+template<typename T1>
+inline
+const Op<T1, op_resize>
+resize(const Base<typename T1::elem_type,T1>& X, const uword in_n_rows, const uword in_n_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_resize>(X.get_ref(), in_n_rows, in_n_cols);
+  }
+
+
+
+template<typename T1>
+inline
+const OpCube<T1, op_resize>
+resize(const BaseCube<typename T1::elem_type,T1>& X, const uword in_n_rows, const uword in_n_cols, const uword in_n_slices)
+  {
+  arma_extra_debug_sigprint();
+  
+  return OpCube<T1, op_resize>(X.get_ref(), in_n_rows, in_n_cols, in_n_slices);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_shuffle.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,33 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup fn_shuffle
+//! @{
+
+//! \brief
+//! Shuffle the rows or the columns of a matrix or vector in random fashion.
+//! If dim = 0, shuffle the columns (default operation).
+//! If dim = 1, shuffle the rows.
+
+template<typename T1>
+inline
+const Op<T1, op_shuffle>
+shuffle(const Base<typename T1::elem_type,T1>& X, const uword dim = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (dim > 1), "shuffle(): dim must be 0 or 1");
+  
+  return Op<T1, op_shuffle>(X.get_ref(), dim, 0);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_solve.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,90 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_solve
+//! @{
+
+
+
+//! Solve a system of linear equations, i.e., A*X = B, where X is unknown.
+//! For a square matrix A, this function is conceptually the same as X = inv(A)*B,
+//! but is done more efficiently.
+//! The number of rows in A and B must be the same.
+//! B can be either a column vector or a matrix.
+//! This function will also try to provide approximate solutions
+//! to under-determined as well as over-determined systems (non-square A matrices).
+
+template<typename T1, typename T2>
+inline
+const Glue<T1, T2, glue_solve>
+solve
+  (
+  const Base<typename T1::elem_type,T1>& A,
+  const Base<typename T1::elem_type,T2>& B,
+  const bool slow = false,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Glue<T1, T2, glue_solve>(A.get_ref(), B.get_ref(), ((slow == false) ? 0 : 1) );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+const Glue<T1, T2, glue_solve_tr>
+solve
+  (
+  const Op<T1, op_trimat>& A,
+  const Base<typename T1::elem_type,T2>& B,
+  const bool slow = false,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(slow);
+  arma_ignore(junk);
+  
+  return Glue<T1, T2, glue_solve_tr>(A.m, B.get_ref(), A.aux_uword_a);
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+bool
+solve
+  (
+         Mat<typename T1::elem_type>&    out,
+  const Base<typename T1::elem_type,T1>& A,
+  const Base<typename T1::elem_type,T2>& B,
+  const bool slow = false,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  try
+    {
+    out = solve( A.get_ref(), B.get_ref(), slow );
+    }
+  catch(std::runtime_error&)
+    {
+    return false;
+    }
+  
+  return true;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_sort.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,58 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_sort
+//! @{
+
+
+template<typename T1>
+arma_inline
+typename
+enable_if2
+  <
+  ( (is_arma_type<T1>::value == true) && (resolves_to_vector<T1>::value == false) ),
+  const Op<T1, op_sort>
+  >::result
+sort
+  (
+  const T1&   X,
+  const uword sort_type = 0,
+  const uword dim       = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_sort>(X, sort_type, dim);
+  }
+
+
+
+template<typename T1>
+arma_inline
+typename
+enable_if2
+  <
+  ( (is_arma_type<T1>::value == true) && (resolves_to_vector<T1>::value == true) ),
+  const Op<T1, op_sort>
+  >::result
+sort
+  (
+  const T1&   X,
+  const uword sort_type = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword dim = (T1::is_col) ? 0 : 1;
+  
+  return Op<T1, op_sort>(X, sort_type, dim);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_sort_index.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,196 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_sort_index
+//! @{
+
+
+
+
+template<typename T1, typename T2>
+struct arma_sort_index_packet
+  {
+  T1 val;
+  T2 index;
+  };
+
+
+
+class arma_sort_index_helper_ascend
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  arma_inline
+  bool
+  operator() (const arma_sort_index_packet<T1,T2>& A, const arma_sort_index_packet<T1,T2>& B) const
+    {
+    return (A.val < B.val);
+    }
+  };
+
+
+
+class arma_sort_index_helper_descend
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  arma_inline
+  bool
+  operator() (const arma_sort_index_packet<T1,T2>& A, const arma_sort_index_packet<T1,T2>& B) const
+    {
+    return (A.val > B.val);
+    }
+  };
+
+
+
+template<typename umat_elem_type, typename eT, const uword sort_direction, const uword sort_type>
+void
+inline
+sort_index_helper(umat_elem_type* out_mem, const eT* in_mem, const uword n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  std::vector< arma_sort_index_packet<eT, umat_elem_type> > packet_vec(n_elem);
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    packet_vec[i].val   = in_mem[i];
+    packet_vec[i].index = i;
+    }
+  
+  
+  if(sort_direction == 0)
+    {
+    // ascend
+    
+    arma_sort_index_helper_ascend comparator;
+    
+    if(sort_type == 0)
+      {
+      std::sort( packet_vec.begin(), packet_vec.end(), comparator );
+      }
+    else
+      {
+      std::stable_sort( packet_vec.begin(), packet_vec.end(), comparator );
+      }
+    }
+  else
+    {
+    // descend
+    
+    arma_sort_index_helper_descend comparator;
+    
+    if(sort_type == 0)
+      {
+      std::sort( packet_vec.begin(), packet_vec.end(), comparator );
+      }
+    else
+      {
+      std::stable_sort( packet_vec.begin(), packet_vec.end(), comparator );
+      }
+    }
+  
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    out_mem[i] = packet_vec[i].index;
+    }
+  }
+
+
+
+template<typename T1>
+inline
+umat
+sort_index
+  (
+  const Base<typename T1::elem_type,T1>& X,
+  const uword sort_direction = 0,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   tmp(X.get_ref());
+  const Mat<eT>& A = tmp.M;
+  
+  if(A.is_empty() == true)
+    {
+    return umat();
+    }
+  
+  arma_debug_check( (A.is_vec() == false), "sort_index(): currently only handles vectors");
+  
+  typedef typename umat::elem_type out_elem_type;
+  
+  umat out(A.n_rows, A.n_cols);
+  
+  if(sort_direction == 0)
+    {
+    sort_index_helper<out_elem_type, eT, 0, 0>(out.memptr(), A.mem, A.n_elem);
+    }
+  else
+    {
+    sort_index_helper<out_elem_type, eT, 1, 0>(out.memptr(), A.mem, A.n_elem);
+    }
+  
+  return out;
+  }
+
+
+
+template<typename T1>
+inline
+umat
+stable_sort_index
+  (
+  const Base<typename T1::elem_type,T1>& X,
+  const uword sort_direction = 0,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   tmp(X.get_ref());
+  const Mat<eT>& A = tmp.M;
+  
+  if(A.is_empty() == true)
+    {
+    return umat();
+    }
+  
+  arma_debug_check( (A.is_vec() == false), "stable_sort_index(): currently only handles vectors");
+  
+  typedef typename umat::elem_type out_elem_type;
+  
+  umat out(A.n_rows, A.n_cols);
+  
+  if(sort_direction == 0)
+    {
+    sort_index_helper<out_elem_type, eT, 0, 1>(out.memptr(), A.mem, A.n_elem);
+    }
+  else
+    {
+    sort_index_helper<out_elem_type, eT, 1, 1>(out.memptr(), A.mem, A.n_elem);
+    }
+  
+  return out;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_speye.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,48 @@
+// Copyright (C) 2012 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_speye
+//! @{
+
+
+
+//! Generate a sparse matrix with the values along the main diagonal set to one
+template<typename obj_type>
+inline
+obj_type
+speye(const uword n_rows, const uword n_cols, const typename arma_SpMat_SpCol_SpRow_only<obj_type>::result* junk = NULL)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  obj_type out;
+  
+  out.eye(n_rows, n_cols);
+  
+  return out;
+  }
+
+
+
+// Convenience shortcut method (no template parameter necessary)
+inline
+sp_mat
+speye(const uword n_rows, const uword n_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  sp_mat out;
+  
+  out.eye(n_rows, n_cols);
+  
+  return out;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_spones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,40 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_spones
+//! @{
+
+
+
+//! Generate a sparse matrix with the non-zero values in the same locations as in the given sparse matrix X,
+//! with the non-zero values set to one
+template<typename T1>
+inline
+SpMat<typename T1::elem_type>
+spones(const SpBase<typename T1::elem_type, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  SpMat<eT> out( X.get_ref() );
+  
+  const uword nnz = out.n_nonzero;
+  
+  eT* values = access::rwp(out.values);
+  
+  for(uword i=0; i < nnz; ++i)
+    {
+    values[i] = eT(1);
+    }
+  
+  return out;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_sprandn.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,83 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_sprandn
+//! @{
+
+
+
+//! Generate a sparse matrix with a randomly selected subset of the elements
+//! set to random values from a Gaussian distribution with zero mean and unit variance
+template<typename obj_type>
+inline
+obj_type
+sprandn
+  (
+  const uword  n_rows,
+  const uword  n_cols,
+  const double density,
+  const typename arma_SpMat_SpCol_SpRow_only<obj_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  if(is_SpCol<obj_type>::value == true)
+    {
+    arma_debug_check( (n_cols != 1), "sprandn(): incompatible size" );
+    }
+  else
+  if(is_SpRow<obj_type>::value == true)
+    {
+    arma_debug_check( (n_rows != 1), "sprandn(): incompatible size" );
+    }
+  
+  obj_type out;
+  
+  out.sprandn(n_rows, n_cols, density);
+  
+  return out;
+  }
+
+
+
+inline
+sp_mat
+sprandn(const uword n_rows, const uword n_cols, const double density)
+  {
+  arma_extra_debug_sigprint();
+  
+  sp_mat out;
+  
+  out.sprandn(n_rows, n_cols, density);
+  
+  return out;
+  }
+
+
+
+//! Generate a sparse matrix with the non-zero values in the same locations as in the given sparse matrix X,
+//! with the non-zero values set to random values from a Gaussian distribution with zero mean and unit variance
+template<typename T1>
+inline
+SpMat<typename T1::elem_type>
+sprandn(const SpBase<typename T1::elem_type, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  SpMat<eT> out( X.get_ref() );
+  
+  eop_aux_randn<eT>::fill( access::rwp(out.values), out.n_nonzero );
+  
+  return out;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_sprandu.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,83 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_sprandu
+//! @{
+
+
+
+//! Generate a sparse matrix with a randomly selected subset of the elements
+//! set to random values in the [0,1] interval (uniform distribution)
+template<typename obj_type>
+inline
+obj_type
+sprandu
+  (
+  const uword  n_rows,
+  const uword  n_cols,
+  const double density,
+  const typename arma_SpMat_SpCol_SpRow_only<obj_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  if(is_SpCol<obj_type>::value == true)
+    {
+    arma_debug_check( (n_cols != 1), "sprandu(): incompatible size" );
+    }
+  else
+  if(is_SpRow<obj_type>::value == true)
+    {
+    arma_debug_check( (n_rows != 1), "sprandu(): incompatible size" );
+    }
+  
+  obj_type out;
+  
+  out.sprandu(n_rows, n_cols, density);
+  
+  return out;
+  }
+
+
+
+inline
+sp_mat
+sprandu(const uword n_rows, const uword n_cols, const double density)
+  {
+  arma_extra_debug_sigprint();
+  
+  sp_mat out;
+  
+  out.sprandu(n_rows, n_cols, density);
+  
+  return out;
+  }
+
+
+
+//! Generate a sparse matrix with the non-zero values in the same locations as in the given sparse matrix X,
+//! with the non-zero values set to random values in the [0,1] interval (uniform distribution)
+template<typename T1>
+inline
+SpMat<typename T1::elem_type>
+sprandu(const SpBase<typename T1::elem_type, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  SpMat<eT> out( X.get_ref() );
+  
+  eop_aux_randu<eT>::fill( access::rwp(out.values), out.n_nonzero );
+  
+  return out;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_stddev.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,86 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_stddev
+//! @{
+
+
+
+template<typename T1>
+inline
+const mtOp<typename T1::pod_type, T1, op_stddev>
+stddev
+  (
+  const T1& X,
+  const uword norm_type = 0,
+  const uword dim = 0,
+  const typename enable_if< is_arma_type<T1>::value       == true  >::result* junk1 = 0,
+  const typename enable_if< resolves_to_vector<T1>::value == false >::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return mtOp<typename T1::pod_type, T1, op_stddev>(X, norm_type, dim);
+  }
+
+
+
+template<typename T1>
+inline
+const mtOp<typename T1::pod_type, T1, op_stddev>
+stddev
+  (
+  const T1& X,
+  const uword norm_type,
+  const uword dim,
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return mtOp<typename T1::pod_type, T1, op_stddev>(X, norm_type, dim);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::pod_type
+stddev
+  (
+  const T1& X,
+  const uword norm_type = 0,
+  const arma_empty_class junk1 = arma_empty_class(),
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return std::sqrt( op_var::var_vec(X, norm_type) );
+  }
+
+
+
+template<typename T>
+arma_inline
+arma_warn_unused
+const typename arma_scalar_only<T>::result
+stddev(const T&)
+  {
+  return T(0);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_strans.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,89 @@
+// Copyright (C) 2011-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2011-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_strans
+//! @{
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_strans>
+strans
+  (
+  const T1& X,
+  const typename enable_if< is_arma_type<T1>::value == true >::result* junk1 = 0,
+  const typename arma_cx_only<typename T1::elem_type>::result*         junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return Op<T1, op_strans>(X);
+  }
+
+
+
+// NOTE: for non-complex objects, deliberately returning op_htrans instead of op_strans,
+// NOTE: due to currently more optimisations available when using op_htrans, especially by glue_times
+template<typename T1>
+arma_inline
+const Op<T1, op_htrans>
+strans
+  (
+  const T1& X,
+  const typename enable_if< is_arma_type<T1>::value == true >::result* junk1 = 0,
+  const typename arma_not_cx<typename T1::elem_type>::result*          junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return Op<T1, op_htrans>(X);
+  }
+
+
+
+//! two consecutive transpose operations cancel each other
+template<typename T1>
+arma_inline
+const T1&
+strans(const Op<T1, op_strans>& X)
+  {
+  arma_extra_debug_sigprint();
+  arma_extra_debug_print("strans(): removing op_strans");
+  
+  return X.m;
+  }
+
+
+
+//
+// handling of sparse matrices
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  is_arma_sparse_type<T1>::value,
+  const SpOp<T1,spop_strans>
+  >::result
+strans(const T1& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpOp<T1,spop_strans>(x);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_sum.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,184 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_sum
+//! @{
+
+
+//! \brief
+//! Delayed sum of elements of a matrix along a specified dimension (either rows or columns).
+//! The result is stored in a dense matrix that has either one column or one row.
+//! For dim = 0, find the sum of each column (traverse across rows)
+//! For dim = 1, find the sum of each row (traverse across columns)
+//! The default is dim = 0.
+//! NOTE: the dim argument is different than in Matlab/Octave.
+
+template<typename T1>
+arma_inline
+const Op<T1, op_sum>
+sum
+  (
+  const T1& X,
+  const uword dim = 0,
+  const typename enable_if< is_arma_type<T1>::value       == true  >::result* junk1 = 0,
+  const typename enable_if< resolves_to_vector<T1>::value == false >::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return Op<T1, op_sum>(X, dim, 0);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_sum>
+sum
+  (
+  const T1& X,
+  const uword dim,
+  const typename enable_if< resolves_to_vector<T1>::value == true >::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1, op_sum>(X, dim, 0);
+  }
+
+
+
+//! \brief
+//! Immediate 'sum all values' operation for expressions which resolve to a vector 
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+sum
+  (
+  const T1& X,
+  const arma_empty_class junk1 = arma_empty_class(),
+  const typename enable_if< resolves_to_vector<T1>::value == true >::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return accu(X);
+  }
+
+
+
+//! \brief
+//! Immediate 'sum all values' operation,
+//! invoked, for example, by: sum(sum(A))
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+sum(const Op<T1, op_sum>& in)
+  {
+  arma_extra_debug_sigprint();
+  arma_extra_debug_print("sum(): two consecutive sum() calls detected");
+  
+  return accu(in.m);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<Op<T1, op_sum>, op_sum>
+sum(const Op<T1, op_sum>& in, const uword dim)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<Op<T1, op_sum>, op_sum>(in, dim, 0);
+  }
+
+
+
+template<typename T>
+arma_inline
+arma_warn_unused
+const typename arma_scalar_only<T>::result &
+sum(const T& x)
+  {
+  return x;
+  }
+
+
+
+//! sum of sparse object
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value == true) && (resolves_to_sparse_vector<T1>::value == true),
+  typename T1::elem_type
+  >::result
+sum(const T1& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  // sum elements
+  return accu(x);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value == true) && (resolves_to_sparse_vector<T1>::value == false),
+  const SpOp<T1,spop_sum>
+  >::result
+sum(const T1& x, const uword dim = 0)
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpOp<T1,spop_sum>(x, dim, 0);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::elem_type
+sum(const SpOp<T1, spop_sum>& in)
+  {
+  arma_extra_debug_sigprint();
+  arma_extra_debug_print("sum(): two consecutive sum() calls detected");
+  
+  return accu(in.m);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const SpOp<SpOp<T1, spop_sum>, spop_sum>
+sum(const SpOp<T1, spop_sum>& in, const uword dim)
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpOp<SpOp<T1, spop_sum>, spop_sum>(in, dim, 0);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_svd.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,194 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_svd
+//! @{
+
+
+
+template<typename T1>
+inline
+bool
+svd
+  (
+         Col<typename T1::pod_type>&     S,
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  // it doesn't matter if X is an alias of S, as auxlib::svd() makes a copy of X
+  
+  const bool status = auxlib::svd(S, X);
+  
+  if(status == false)
+    {
+    S.reset();
+    arma_bad("svd(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+template<typename T1>
+inline
+Col<typename T1::pod_type>
+svd
+  (
+  const Base<typename T1::elem_type,T1>& X,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  Col<typename T1::pod_type> out;
+  
+  const bool status = auxlib::svd(out, X);
+  
+  if(status == false)
+    {
+    out.reset();
+    arma_bad("svd(): failed to converge");
+    }
+  
+  return out;
+  }
+
+
+
+template<typename T1>
+inline
+bool
+svd
+  (
+         Mat<typename T1::elem_type>&    U,
+         Col<typename T1::pod_type >&    S,
+         Mat<typename T1::elem_type>&    V,
+  const Base<typename T1::elem_type,T1>& X,
+  const char* method =                   "",
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  arma_debug_check
+    (
+    ( ((void*)(&U) == (void*)(&S)) || (&U == &V) || ((void*)(&S) == (void*)(&V)) ),
+    "svd(): two or more output objects are the same object"
+    );
+  
+  bool use_divide_and_conquer = false;
+  
+  const char sig = method[0];
+  
+  switch(sig)
+    {
+    case '\0':
+    case 's':
+      break;
+      
+    case 'd':
+      use_divide_and_conquer = true;
+      break;
+    
+    default:
+      {
+      arma_stop("svd(): unknown method specified");
+      return false;
+      }
+    }
+  
+  // auxlib::svd() makes an internal copy of X
+  const bool status = (use_divide_and_conquer == false) ? auxlib::svd(U, S, V, X) : auxlib::svd_dc(U, S, V, X);
+  
+  if(status == false)
+    {
+    U.reset();
+    S.reset();
+    V.reset();
+    arma_bad("svd(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+template<typename T1>
+inline
+bool
+svd_econ
+  (
+         Mat<typename T1::elem_type>&    U,
+         Col<typename T1::pod_type >&    S,
+         Mat<typename T1::elem_type>&    V,
+  const Base<typename T1::elem_type,T1>& X,
+  const char                             mode = 'b',
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  arma_debug_check
+    (
+    ( ((void*)(&U) == (void*)(&S)) || (&U == &V) || ((void*)(&S) == (void*)(&V)) ),
+    "svd_econ(): two or more output objects are the same object"
+    );
+  
+  arma_debug_check
+    (
+    ( (mode != 'l') && (mode != 'r') && (mode != 'b') ),
+    "svd_econ(): parameter 'mode' is incorrect"
+    );
+  
+  
+  // auxlib::svd_econ() makes an internal copy of X
+  const bool status = auxlib::svd_econ(U, S, V, X, mode);
+  
+  if(status == false)
+    {
+    U.reset();
+    S.reset();
+    V.reset();
+    arma_bad("svd_econ(): failed to converge", false);
+    }
+  
+  return status;
+  }
+
+
+
+template<typename T1>
+arma_deprecated
+inline
+bool
+svd_thin
+  (
+         Mat<typename T1::elem_type>&    U,
+         Col<typename T1::pod_type >&    S,
+         Mat<typename T1::elem_type>&    V,
+  const Base<typename T1::elem_type,T1>& X,
+  const char                             mode = 'b',
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_ignore(junk);
+  
+  return svd_econ(U,S,V,X,mode);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_syl_lyap.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,91 @@
+// Copyright (C) 2011-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2011-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_syl_lyap
+//! @{
+
+
+//! find the solution of the Sylvester equation AX + XB = C
+template<typename T1, typename T2, typename T3>
+inline
+bool
+syl
+  (
+        Mat <typename T1::elem_type>   & out,
+  const Base<typename T1::elem_type,T1>& in_A,
+  const Base<typename T1::elem_type,T2>& in_B,
+  const Base<typename T1::elem_type,T3>& in_C,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> tmp_A(in_A.get_ref(), out);
+  const unwrap_check<T2> tmp_B(in_B.get_ref(), out);
+  const unwrap_check<T3> tmp_C(in_C.get_ref(), out);
+  
+  const Mat<eT>& A = tmp_A.M;
+  const Mat<eT>& B = tmp_B.M;
+  const Mat<eT>& C = tmp_C.M;
+  
+  const bool status = auxlib::syl(out, A, B, C);
+  
+  if(status == false)
+    {
+    out.reset();
+    arma_bad("syl(): equation appears to be singular", false);
+    }
+  
+  return status;
+  }
+
+
+
+template<typename T1, typename T2, typename T3>
+inline
+Mat<typename T1::elem_type>
+syl
+  (
+  const Base<typename T1::elem_type,T1>& in_A,
+  const Base<typename T1::elem_type,T2>& in_B,
+  const Base<typename T1::elem_type,T3>& in_C,
+  const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1> tmp_A( in_A.get_ref() );
+  const unwrap<T2> tmp_B( in_B.get_ref() );
+  const unwrap<T3> tmp_C( in_C.get_ref() );
+  
+  const Mat<eT>& A = tmp_A.M;
+  const Mat<eT>& B = tmp_B.M;
+  const Mat<eT>& C = tmp_C.M;
+  
+  Mat<eT> out;
+  
+  const bool status = auxlib::syl(out, A, B, C);
+  
+  if(status == false)
+    {
+    out.reset();
+    arma_bad("syl(): equation appears to be singular");
+    }
+  
+  return out;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_symmat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,37 @@
+// Copyright (C) 2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_symmat
+//! @{
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_symmat>
+symmatu(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_symmat>(X.get_ref(), 0, 0);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_symmat>
+symmatl(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_symmat>(X.get_ref(), 1, 0);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_toeplitz.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,50 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_toeplitz
+//! @{
+
+
+
+template<typename T1>
+inline
+Op<T1, op_toeplitz>
+toeplitz(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_toeplitz>( X.get_ref() );
+  }
+
+
+
+template<typename T1>
+inline
+Op<T1, op_toeplitz_c>
+circ_toeplitz(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_toeplitz_c>( X.get_ref() );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+Glue<T1, T2, glue_toeplitz>
+toeplitz(const Base<typename T1::elem_type,T1>& X, const Base<typename T1::elem_type,T2>& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Glue<T1, T2, glue_toeplitz>( X.get_ref(), Y.get_ref() );
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_trace.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,241 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_trace
+//! @{
+
+
+//! Immediate trace (sum of diagonal elements) of a square dense matrix
+template<typename T1>
+arma_hot
+arma_warn_unused
+inline
+typename enable_if2<is_arma_type<T1>::value, typename T1::elem_type>::result
+trace(const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> A(X);
+  
+  arma_debug_check( (A.get_n_rows() != A.get_n_cols()), "trace(): matrix must be square sized" );
+  
+  const uword N = A.get_n_rows();
+  
+  eT val1 = eT(0);
+  eT val2 = eT(0);
+  
+  uword i,j;
+  for(i=0, j=1; j<N; i+=2, j+=2)
+    {
+    val1 += A.at(i,i);
+    val2 += A.at(j,j);
+    }
+  
+  if(i < N)
+    {
+    val1 += A.at(i,i);
+    }
+  
+  return val1 + val2;
+  }
+
+
+
+template<typename T1>
+arma_hot
+arma_warn_unused
+inline
+typename T1::elem_type
+trace(const Op<T1, op_diagmat>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const diagmat_proxy<T1> A(X.m);
+  
+  const uword N = A.n_elem;
+  
+  eT val = eT(0);
+  
+  for(uword i=0; i<N; ++i)
+    {
+    val += A[i];
+    }
+  
+  return val;
+  }
+
+
+
+//! speedup for trace(A*B), where the result of A*B is a square sized matrix
+template<typename T1, typename T2>
+arma_hot
+inline
+typename T1::elem_type
+trace_mul_unwrap(const T1& XA, const T2& XB)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1>    PA(XA);
+  const unwrap<T2> tmpB(XB);
+  
+  const Mat<eT>& B = tmpB.M;
+  
+  arma_debug_assert_mul_size(PA.get_n_rows(), PA.get_n_cols(), B.n_rows, B.n_cols, "matrix multiplication");
+  
+  arma_debug_check( (PA.get_n_rows() != B.n_cols), "trace(): matrix must be square sized" );
+  
+  const uword N1 = PA.get_n_rows();   // equivalent to B.n_cols, due to square size requirements
+  const uword N2 = PA.get_n_cols();   // equivalent to B.n_rows, due to matrix multiplication requirements
+  
+  eT val = eT(0);
+  
+  for(uword i=0; i<N1; ++i)
+    {
+    const eT* B_colmem = B.colptr(i);
+    
+    eT acc1 = eT(0);
+    eT acc2 = eT(0);
+    
+    uword j,k;
+    for(j=0, k=1; k < N2; j+=2, k+=2)
+      {
+      const eT tmp_j = B_colmem[j];
+      const eT tmp_k = B_colmem[k];
+      
+      acc1 += PA.at(i,j) * tmp_j;
+      acc2 += PA.at(i,k) * tmp_k;
+      }
+    
+    if(j < N2)
+      {
+      acc1 += PA.at(i,j) * B_colmem[j];
+      }
+    
+    val += (acc1 + acc2);
+    }
+  
+  return val;
+  }
+
+
+
+//! speedup for trace(A*B), where the result of A*B is a square sized matrix
+template<typename T1, typename T2>
+arma_hot
+inline
+typename T1::elem_type
+trace_mul_proxy(const T1& XA, const T2& XB)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> PA(XA);
+  const Proxy<T2> PB(XB);
+  
+  if(is_Mat<typename Proxy<T2>::stored_type>::value == true)
+    {
+    return trace_mul_unwrap(PA.Q, PB.Q);
+    }
+  
+  arma_debug_assert_mul_size(PA.get_n_rows(), PA.get_n_cols(), PB.get_n_rows(), PB.get_n_cols(), "matrix multiplication");
+  
+  arma_debug_check( (PA.get_n_rows() != PB.get_n_cols()), "trace(): matrix must be square sized" );
+  
+  const uword N1 = PA.get_n_rows();   // equivalent to PB.get_n_cols(), due to square size requirements
+  const uword N2 = PA.get_n_cols();   // equivalent to PB.get_n_rows(), due to matrix multiplication requirements
+  
+  eT val = eT(0);
+  
+  for(uword i=0; i<N1; ++i)
+    {
+    eT acc1 = eT(0);
+    eT acc2 = eT(0);
+    
+    uword j,k;
+    for(j=0, k=1; k < N2; j+=2, k+=2)
+      {
+      const eT tmp_j = PB.at(j,i);
+      const eT tmp_k = PB.at(k,i);
+      
+      acc1 += PA.at(i,j) * tmp_j;
+      acc2 += PA.at(i,k) * tmp_k;
+      }
+    
+    if(j < N2)
+      {
+      acc1 += PA.at(i,j) * PB.at(j,i);
+      }
+    
+    val += (acc1 + acc2);
+    }
+  
+  return val;
+  }
+
+
+
+//! speedup for trace(A*B), where the result of A*B is a square sized matrix
+template<typename T1, typename T2>
+arma_hot
+arma_warn_unused
+inline
+typename T1::elem_type
+trace(const Glue<T1, T2, glue_times>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (is_Mat<T2>::value) ? trace_mul_unwrap(X.A, X.B) : trace_mul_proxy(X.A, X.B);
+  }
+
+
+
+//! trace of sparse object
+template<typename T1>
+arma_hot
+arma_warn_unused
+inline
+typename enable_if2<is_arma_sparse_type<T1>::value, typename T1::elem_type>::result
+trace(const T1& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> p(x);
+  
+  arma_debug_check( (p.get_n_rows() != p.get_n_cols()), "trace(): matrix must be square sized" );
+  
+  typedef typename T1::elem_type eT;
+  
+  eT result = eT(0);
+  
+  typename SpProxy<T1>::const_iterator_type it     = p.begin();
+  typename SpProxy<T1>::const_iterator_type it_end = p.end();
+  
+  while(it != it_end)
+    {
+    if(it.row() == it.col())
+      {
+      result += (*it);
+      }
+    
+    ++it;
+    }
+  
+  return result;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_trans.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,166 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_trans
+//! @{
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_htrans>
+trans
+  (
+  const T1& X,
+  const typename enable_if< is_arma_type<T1>::value == true >::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1, op_htrans>(X);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_htrans>
+htrans
+  (
+  const T1& X,
+  const typename enable_if< is_arma_type<T1>::value == true >::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1, op_htrans>(X);
+  }
+
+
+
+//! two consecutive transpose operations cancel each other
+template<typename T1>
+arma_inline
+const T1&
+trans(const Op<T1, op_htrans>& X)
+  {
+  arma_extra_debug_sigprint();
+  arma_extra_debug_print("trans(): removing op_htrans");
+  
+  return X.m;
+  }
+
+
+
+template<typename T1>
+arma_inline
+const T1&
+htrans(const Op<T1, op_htrans>& X)
+  {
+  arma_extra_debug_sigprint();
+  arma_extra_debug_print("htrans(): removing op_htrans");
+  
+  return X.m;
+  }
+
+
+
+//
+// handling of sparse matrices
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  is_arma_sparse_type<T1>::value,
+  const SpOp<T1,spop_strans>
+  >::result
+trans
+  (
+  const T1& x,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return SpOp<T1,spop_strans>(x);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  is_arma_sparse_type<T1>::value,
+  const SpOp<T1,spop_htrans>
+  >::result
+trans
+  (
+  const T1& x,
+  const typename arma_cx_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return SpOp<T1,spop_htrans>(x);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  is_arma_sparse_type<T1>::value,
+  const SpOp<T1,spop_strans>
+  >::result
+htrans
+  (
+  const T1& x,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return SpOp<T1,spop_strans>(x);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  is_arma_sparse_type<T1>::value,
+  const SpOp<T1,spop_htrans>
+  >::result
+htrans
+  (
+  const T1& x,
+  const typename arma_cx_only<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return SpOp<T1,spop_htrans>(x);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_trig.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,343 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_trig
+//! @{
+
+//
+// trigonometric functions:
+// cos family: cos, acos, cosh, acosh
+// sin family: sin, asin, sinh, asinh
+// tan family: tan, atan, tanh, atanh
+
+
+//
+// cos
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_cos>
+cos(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_cos>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_cos>
+cos(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_cos>(A.get_ref());
+  }
+
+
+
+//
+// acos
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_acos>
+acos(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_acos>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_acos>
+acos(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_acos>(A.get_ref());
+  }
+
+
+
+//
+// cosh
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_cosh>
+cosh(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_cosh>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_cosh>
+cosh(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_cosh>(A.get_ref());
+  }
+
+
+
+//
+// acosh
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_acosh>
+acosh(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_acosh>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_acosh>
+acosh(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_acosh>(A.get_ref());
+  }
+
+
+
+//
+// sin
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_sin>
+sin(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_sin>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_sin>
+sin(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_sin>(A.get_ref());
+  }
+
+
+
+//
+// asin
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_asin>
+asin(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_asin>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_asin>
+asin(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_asin>(A.get_ref());
+  }
+
+
+
+//
+// sinh
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_sinh>
+sinh(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_sinh>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_sinh>
+sinh(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_sinh>(A.get_ref());
+  }
+
+
+
+//
+// asinh
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_asinh>
+asinh(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_asinh>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_asinh>
+asinh(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_asinh>(A.get_ref());
+  }
+
+
+
+//
+// tan
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_tan>
+tan(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_tan>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_tan>
+tan(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_tan>(A.get_ref());
+  }
+
+
+
+//
+// atan
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_atan>
+atan(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_atan>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_atan>
+atan(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_atan>(A.get_ref());
+  }
+
+
+
+//
+// tanh
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_tanh>
+tanh(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_tanh>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_tanh>
+tanh(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_tanh>(A.get_ref());
+  }
+
+
+
+//
+// atanh
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_atanh>
+atanh(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_atanh>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_atanh>
+atanh(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_atanh>(A.get_ref());
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_trimat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,37 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_trimat
+//! @{
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_trimat>
+trimatu(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_trimat>(X.get_ref(), 0, 0);
+  }
+
+
+
+template<typename T1>
+arma_inline
+const Op<T1, op_trimat>
+trimatl(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_trimat>(X.get_ref(), 1, 0);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_trunc_exp.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,79 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup fn_trunc_exp
+//! @{
+
+
+
+template<typename eT>
+inline
+static
+typename arma_real_only<eT>::result
+trunc_exp(const eT x)
+  {
+  if(std::numeric_limits<eT>::is_iec559 && (x >= Math<eT>::log_max() ))
+    {
+    return std::numeric_limits<eT>::max();
+    }
+  else
+    {
+    return std::exp(x);
+    }
+  }
+
+
+
+template<typename eT>
+inline
+static
+typename arma_integral_only<eT>::result
+trunc_exp(const eT x)
+  {
+  return eT( trunc_exp( double(x) ) );
+  }
+
+
+
+template<typename T>
+inline
+static
+std::complex<T>
+trunc_exp(const std::complex<T>& x)
+  {
+  return std::polar( trunc_exp( x.real() ), x.imag() );
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_trunc_exp>
+trunc_exp(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_trunc_exp>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_trunc_exp>
+trunc_exp(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_trunc_exp>(A.get_ref());
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_trunc_log.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,85 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_trunc_log
+//! @{
+
+
+
+template<typename eT>
+inline
+static
+typename arma_real_only<eT>::result
+trunc_log(const eT x)
+  {
+  if(std::numeric_limits<eT>::is_iec559)
+    {
+    if(x == std::numeric_limits<eT>::infinity())
+      {
+      return Math<eT>::log_max();
+      }
+    else
+      {
+      return (x <= eT(0)) ? Math<eT>::log_min() : std::log(x);
+      }
+    }
+  else
+    {
+    return std::log(x);
+    }
+  }
+
+
+
+template<typename eT>
+inline
+static
+typename arma_integral_only<eT>::result
+trunc_log(const eT x)
+  {
+  return eT( trunc_log( double(x) ) );
+  }
+
+
+
+template<typename T>
+inline
+static
+std::complex<T>
+trunc_log(const std::complex<T>& x)
+  {
+  return std::complex<T>( trunc_log( std::abs(x) ), std::arg(x) );
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOp<T1, eop_trunc_log>
+trunc_log(const Base<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_trunc_log>(A.get_ref());
+  }
+
+
+
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_trunc_log>
+trunc_log(const BaseCube<typename T1::elem_type,T1>& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_trunc_log>(A.get_ref());
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_unique.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,24 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// Copyright (C) 2012 Arnold Wiliem
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+template<typename T1>
+inline
+const Op<T1,op_unique>
+unique
+  (
+  const Base<typename T1::elem_type,T1>& A,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return Op<T1,op_unique>( A.get_ref() );
+  }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_var.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,146 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_var
+//! @{
+
+
+
+template<typename T1>
+inline
+const mtOp<typename T1::pod_type, T1, op_var>
+var
+  (
+  const T1& X,
+  const uword norm_type = 0,
+  const uword dim = 0,
+  const typename enable_if< is_arma_type<T1>::value       == true  >::result* junk1 = 0,
+  const typename enable_if< resolves_to_vector<T1>::value == false >::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return mtOp<typename T1::pod_type, T1, op_var>(X, norm_type, dim);
+  }
+
+
+
+template<typename T1>
+inline
+const mtOp<typename T1::pod_type, T1, op_var>
+var
+  (
+  const T1& X,
+  const uword norm_type,
+  const uword dim,
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return mtOp<typename T1::pod_type, T1, op_var>(X, norm_type, dim);
+  }
+
+
+
+template<typename T1>
+inline
+arma_warn_unused
+typename T1::pod_type
+var
+  (
+  const T1& X,
+  const uword norm_type = 0,
+  const arma_empty_class junk1 = arma_empty_class(),
+  const typename enable_if<resolves_to_vector<T1>::value == true>::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  return op_var::var_vec( X, norm_type );
+  }
+
+
+
+template<typename T>
+arma_inline
+arma_warn_unused
+const typename arma_scalar_only<T>::result
+var(const T&)
+  {
+  return T(0);
+  }
+
+
+
+template<typename T1>
+inline
+const mtSpOp<typename T1::pod_type, T1, spop_var>
+var
+  (
+  const T1& X,
+  const uword norm_type = 0,
+  const uword dim = 0,
+  const typename enable_if< is_arma_sparse_type<T1>::value       == true  >::result* junk1 = 0,
+  const typename enable_if< resolves_to_sparse_vector<T1>::value == false >::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+
+  return mtSpOp<typename T1::pod_type, T1, spop_var>(X, norm_type, dim);
+  }
+
+
+
+template<typename T1>
+inline
+const mtSpOp<typename T1::pod_type, T1, spop_var>
+var
+  (
+  const T1& X,
+  const uword norm_type,
+  const uword dim = 0,
+  const typename enable_if<resolves_to_sparse_vector<T1>::value == true>::result* junk1 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+
+  return mtSpOp<typename T1::pod_type, T1, spop_var>(X, norm_type, dim);
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::pod_type
+var
+  (
+  const T1& X,
+  const uword norm_type = 0,
+  const arma_empty_class junk1 = arma_empty_class(),
+  const typename enable_if<resolves_to_sparse_vector<T1>::value == true>::result* junk2 = 0
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+
+  return spop_var::var_vec(X, norm_type);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/fn_zeros.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,105 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup fn_zeros
+//! @{
+
+
+//! Generate a vector with all elements set to zero
+arma_inline
+const Gen<vec, gen_zeros>
+zeros(const uword n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Gen<vec, gen_zeros>(n_elem, 1);
+  }
+
+
+
+template<typename obj_type>
+arma_inline
+const Gen<obj_type, gen_zeros>
+zeros(const uword n_elem, const arma_empty_class junk1 = arma_empty_class(), const typename arma_Mat_Col_Row_only<obj_type>::result* junk2 = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  if(is_Row<obj_type>::value == true)
+    {
+    return Gen<obj_type, gen_zeros>(1, n_elem);
+    }
+  else
+    {
+    return Gen<obj_type, gen_zeros>(n_elem, 1);
+    }
+  }
+
+
+
+//! Generate a dense matrix with all elements set to zero
+arma_inline
+const Gen<mat, gen_zeros>
+zeros(const uword n_rows, const uword n_cols)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Gen<mat, gen_zeros>(n_rows, n_cols);
+  }
+
+
+
+template<typename obj_type>
+arma_inline
+const Gen<obj_type, gen_zeros>
+zeros(const uword n_rows, const uword n_cols, const typename arma_Mat_Col_Row_only<obj_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  if(is_Col<obj_type>::value == true)
+    {
+    arma_debug_check( (n_cols != 1), "zeros(): incompatible size" );
+    }
+  else
+  if(is_Row<obj_type>::value == true)
+    {
+    arma_debug_check( (n_rows != 1), "zeros(): incompatible size" );
+    }
+  
+  return Gen<obj_type, gen_zeros>(n_rows, n_cols);
+  }
+
+
+
+arma_inline
+const GenCube<cube::elem_type, gen_zeros>
+zeros(const uword n_rows, const uword n_cols, const uword n_slices)
+  {
+  arma_extra_debug_sigprint();
+  
+  return GenCube<cube::elem_type, gen_zeros>(n_rows, n_cols, n_slices);
+  }
+
+
+
+template<typename cube_type>
+arma_inline
+const GenCube<typename cube_type::elem_type, gen_zeros>
+zeros(const uword n_rows, const uword n_cols, const uword n_slices, const typename arma_Cube_only<cube_type>::result* junk = 0)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  return GenCube<typename cube_type::elem_type, gen_zeros>(n_rows, n_cols, n_slices);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/format_wrap.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,546 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup format_wrap
+//! @{
+
+
+//! \namespace arma_boost namespace for functions and classes which partially emulate Boost functionality 
+namespace arma_boost
+  {
+  
+  #if defined(ARMA_USE_BOOST_FORMAT)
+
+    using boost::format;
+    using boost::basic_format;
+    using boost::str;
+
+  #else
+  
+    #if defined(ARMA_HAVE_STD_SNPRINTF)
+
+      #define arma_snprintf std::snprintf
+
+    #else
+
+      // better-than-nothing emulation of C99 snprintf(),
+      // with correct return value and null-terminated output string.
+      // note that _snprintf() provided by MS is not a good substitute for snprintf()
+
+      inline
+      int
+      arma_snprintf(char* out, size_t size, const char* fmt, ...)
+        {
+        size_t i;
+        
+        for(i=0; i<size; ++i)
+          {
+          out[i] = fmt[i];
+          if(fmt[i] == char(0))
+            break;
+          }
+        
+        if(size > 0)
+          out[size-1] = char(0);
+        
+        return int(i);
+        }
+
+    #endif
+    
+    class format
+      {
+      public:
+    
+      format(const char* in_fmt)
+        : A(in_fmt)
+        {
+        }
+    
+      format(const std::string& in_fmt)
+        : A(in_fmt)
+        {
+        }
+    
+    
+      const std::string A;
+    
+      private:
+      format();
+      };
+    
+    
+    
+    template<typename T1, typename T2>
+    class basic_format
+      {
+      public:
+    
+      basic_format(const T1& in_A, const T2& in_B)
+        : A(in_A)
+        , B(in_B)
+        {
+        }
+    
+      const T1& A;
+      const T2& B;
+    
+      private:
+      basic_format();
+      };
+    
+    
+    
+    template<typename T2>
+    inline
+    basic_format< format, T2 >
+    operator% (const format& X, const T2& arg)
+      {
+      return basic_format< format, T2 >(X, arg);
+      }
+    
+    
+    
+    template<typename T1, typename T2, typename T3>
+    inline
+    basic_format< basic_format<T1,T2>, T3 >
+    operator% (const basic_format<T1,T2>& X, const T3& arg)
+      {
+      return basic_format< basic_format<T1,T2>, T3 >(X, arg);
+      }
+    
+    
+    
+    template<typename T2>
+    inline
+    std::string
+    str(const basic_format< format, T2>& X)
+      {
+      char  local_buffer[1024];
+      char* buffer = local_buffer;
+      
+      int buffer_size   = 1024;
+      int required_size = buffer_size;
+   
+      bool using_local_buffer = true;
+      
+      std::string out;
+      
+      do
+        {
+        if(using_local_buffer == false)
+          {
+          buffer = new char[buffer_size];
+          }
+        
+        required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.c_str(), X.B);
+        
+        if(required_size < buffer_size)
+          {
+          if(required_size > 0)
+            {
+            out = buffer;
+            }
+          }
+        else
+          {
+          buffer_size *= 2;
+          }
+        
+        if(using_local_buffer == true)
+          {
+          using_local_buffer = false;
+          }
+        else
+          {
+          delete[] buffer;
+          }
+        
+        } while( (required_size >= buffer_size) );
+
+      return out;
+      }
+    
+    
+    
+    template<typename T2, typename T3>
+    inline
+    std::string
+    str(const basic_format< basic_format< format, T2>, T3>& X)
+      {
+      char  local_buffer[1024];
+      char* buffer = local_buffer;
+      
+      int buffer_size   = 1024;
+      int required_size = buffer_size;
+   
+      bool using_local_buffer = true;
+      
+      std::string out;
+      
+      do
+        {
+        if(using_local_buffer == false)
+          {
+          buffer = new char[buffer_size];
+          }
+        
+        required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.c_str(), X.A.B, X.B);
+        
+        if(required_size < buffer_size)
+          {
+          if(required_size > 0)
+            {
+            out = buffer;
+            }
+          }
+        else
+          {
+          buffer_size *= 2;
+          }
+        
+        if(using_local_buffer == true)
+          {
+          using_local_buffer = false;
+          }
+        else
+          {
+          delete[] buffer;
+          }
+        
+        } while( (required_size >= buffer_size) );
+
+      return out;
+      }
+    
+    
+    
+    template<typename T2, typename T3, typename T4>
+    inline
+    std::string
+    str(const basic_format< basic_format< basic_format< format, T2>, T3>, T4>& X)
+      {
+      char  local_buffer[1024];
+      char* buffer = local_buffer;
+      
+      int buffer_size   = 1024;
+      int required_size = buffer_size;
+   
+      bool using_local_buffer = true;
+      
+      std::string out;
+      
+      do
+        {
+        if(using_local_buffer == false)
+          {
+          buffer = new char[buffer_size];
+          }
+        
+        required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.c_str(), X.A.A.B, X.A.B, X.B);
+        
+        if(required_size < buffer_size)
+          {
+          if(required_size > 0)
+            {
+            out = buffer;
+            }
+          }
+        else
+          {
+          buffer_size *= 2;
+          }
+        
+        if(using_local_buffer == true)
+          {
+          using_local_buffer = false;
+          }
+        else
+          {
+          delete[] buffer;
+          }
+        
+        } while( (required_size >= buffer_size) );
+
+      return out;
+      }
+    
+    
+    
+    template<typename T2, typename T3, typename T4, typename T5>
+    inline
+    std::string
+    str(const basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>& X)
+      {
+      char  local_buffer[1024];
+      char* buffer = local_buffer;
+      
+      int buffer_size   = 1024;
+      int required_size = buffer_size;
+   
+      bool using_local_buffer = true;
+      
+      std::string out;
+      
+      do
+        {
+        if(using_local_buffer == false)
+          {
+          buffer = new char[buffer_size];
+          }
+        
+        required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.c_str(), X.A.A.A.B, X.A.A.B, X.A.B, X.B);
+        
+        if(required_size < buffer_size)
+          {
+          if(required_size > 0)
+            {
+            out = buffer;
+            }
+          }
+        else
+          {
+          buffer_size *= 2;
+          }
+        
+        if(using_local_buffer == true)
+          {
+          using_local_buffer = false;
+          }
+        else
+          {
+          delete[] buffer;
+          }
+        
+        } while( (required_size >= buffer_size) );
+
+      return out;
+      }
+    
+    
+    
+    template<typename T2, typename T3, typename T4, typename T5, typename T6>
+    inline
+    std::string
+    str(const basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>& X)
+      {
+      char  local_buffer[1024];
+      char* buffer = local_buffer;
+      
+      int buffer_size   = 1024;
+      int required_size = buffer_size;
+   
+      bool using_local_buffer = true;
+      
+      std::string out;
+      
+      do
+        {
+        if(using_local_buffer == false)
+          {
+          buffer = new char[buffer_size];
+          }
+        
+        required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.c_str(), X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B);
+        
+        if(required_size < buffer_size)
+          {
+          if(required_size > 0)
+            {
+            out = buffer;
+            }
+          }
+        else
+          {
+          buffer_size *= 2;
+          }
+        
+        if(using_local_buffer == true)
+          {
+          using_local_buffer = false;
+          }
+        else
+          {
+          delete[] buffer;
+          }
+        
+        } while( (required_size >= buffer_size) );
+
+      return out;
+      }
+    
+    
+    
+    template<typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
+    inline
+    std::string
+    str(const basic_format< basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>, T7>& X)
+      {
+      char  local_buffer[1024];
+      char* buffer = local_buffer;
+      
+      int buffer_size   = 1024;
+      int required_size = buffer_size;
+   
+      bool using_local_buffer = true;
+      
+      std::string out;
+      
+      do
+        {
+        if(using_local_buffer == false)
+          {
+          buffer = new char[buffer_size];
+          }
+        
+        required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.A.c_str(), X.A.A.A.A.A.B, X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B);
+        
+        if(required_size < buffer_size)
+          {
+          if(required_size > 0)
+            {
+            out = buffer;
+            }
+          }
+        else
+          {
+          buffer_size *= 2;
+          }
+        
+        if(using_local_buffer == true)
+          {
+          using_local_buffer = false;
+          }
+        else
+          {
+          delete[] buffer;
+          }
+        
+        } while( (required_size >= buffer_size) );
+
+      return out;
+      }
+    
+    
+    
+    template<typename T1>
+    struct format_metaprog
+      {
+      static const uword depth = 0;
+    
+      inline
+      static  
+      const std::string&
+      get_fmt(const T1& X)
+        {
+        return X.A;
+        }
+      };
+    
+    
+    
+    //template<>
+    template<typename T1, typename T2>
+    struct format_metaprog< basic_format<T1,T2> >
+      {
+      static const uword depth = 1 + format_metaprog<T1>::depth;
+    
+      inline
+      static
+      const std::string&
+      get_fmt(const T1& X)
+        {
+        return format_metaprog<T1>::get_fmt(X.A);
+        }
+    
+      };
+    
+    
+    
+    template<typename T1, typename T2>
+    inline
+    std::string
+    str(const basic_format<T1,T2>& X)
+      {
+      return format_metaprog< basic_format<T1,T2> >::get_fmt(X.A);
+      }
+    
+    
+    
+    template<typename T1, typename T2>
+    inline
+    std::ostream&
+    operator<< (std::ostream& o, const basic_format<T1,T2>& X)
+      {
+      o << str(X);
+      return o;
+      }
+        
+        
+  #endif
+  
+  
+  template<typename T> struct string_only              { };
+  template<>           struct string_only<std::string> { typedef std::string result; };
+  
+  template<typename T> struct char_only                { };
+  template<>           struct char_only<char         > { typedef char        result; };
+
+  template<typename T>
+  struct basic_format_only { };
+  
+  #if defined(ARMA_USE_BOOST_FORMAT)
+    template<typename T>
+    struct basic_format_only< basic_format<T>      > { typedef basic_format<T>     result; };
+  #else
+    template<typename T1, typename T2>
+    struct basic_format_only< basic_format<T1, T2> > { typedef basic_format<T1,T2> result; };
+  #endif
+
+
+
+  template<typename T1>
+  inline
+  static
+  const T1&
+  str_wrapper(const T1& x, const typename string_only<T1>::result* junk = 0)
+    {
+    arma_ignore(junk);
+    
+    return x;
+    }
+  
+  
+  
+  template<typename T1>
+  inline
+  static
+  const T1*
+  str_wrapper(const T1* x, const typename char_only<T1>::result* junk = 0)
+    {
+    arma_ignore(junk);
+    
+    return x;
+    }
+  
+  
+  
+  template<typename T1>
+  inline
+  static
+  std::string
+  str_wrapper(const T1& x, const typename basic_format_only<T1>::result* junk = 0)
+    {
+    arma_ignore(junk);
+    
+    return str(x);
+    }
+  
+  }
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/forward_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,211 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::ios;
+
+template<typename elem_type, typename derived> struct Base;
+template<typename elem_type, typename derived> struct BaseCube;
+
+template<typename eT> class Mat;
+template<typename eT> class Col;
+template<typename eT> class Row;
+template<typename eT> class Cube;
+template<typename eT> class xvec_htrans;
+template<typename oT> class field;
+
+template<typename eT> class subview;
+template<typename eT> class subview_col;
+template<typename eT> class subview_row;
+template<typename eT> class subview_row_strans;
+template<typename eT> class subview_row_htrans;
+template<typename eT> class subview_cube;
+template<typename oT> class subview_field;
+
+template<typename eT> class SpValProxy;
+template<typename eT> class SpMat;
+template<typename eT> class SpCol;
+template<typename eT> class SpRow;
+template<typename eT> class SpSubview;
+
+template<typename eT> class diagview;
+
+template<typename eT, typename T1>              class subview_elem1;
+template<typename eT, typename T1, typename T2> class subview_elem2;
+
+template<typename parent, unsigned int mode>              class subview_each1;
+template<typename parent, unsigned int mode, typename TB> class subview_each2;
+
+
+class arma_empty_class {};
+
+class diskio;
+
+class op_min;
+class op_max;
+
+class op_strans;
+class op_htrans;
+class op_htrans2;
+class op_inv;
+class op_sum;
+class op_abs;
+class op_diagmat;
+class op_trimat;
+class op_diagvec;
+
+class eop_conj;
+
+class glue_times;
+class glue_times_diag;
+
+class glue_rel_lt;
+class glue_rel_gt;
+class glue_rel_lteq;
+class glue_rel_gteq;
+class glue_rel_eq;
+class glue_rel_noteq;
+
+class op_rel_lt_pre;
+class op_rel_lt_post;
+class op_rel_gt_pre;
+class op_rel_gt_post;
+class op_rel_lteq_pre;
+class op_rel_lteq_post;
+class op_rel_gteq_pre;
+class op_rel_gteq_post;
+class op_rel_eq;
+class op_rel_noteq;
+
+class gen_ones_diag;
+class gen_ones_full;
+class gen_zeros;
+class gen_randu;
+class gen_randn;
+
+class glue_mixed_plus;
+class glue_mixed_minus;
+class glue_mixed_div;
+class glue_mixed_schur;
+class glue_mixed_times;
+
+class op_cx_scalar_times;
+class op_cx_scalar_plus;
+class op_cx_scalar_minus_pre;
+class op_cx_scalar_minus_post;
+class op_cx_scalar_div_pre;
+class op_cx_scalar_div_post;
+
+
+
+class op_subview_elem_equ;
+class op_subview_elem_inplace_plus;
+class op_subview_elem_inplace_minus;
+class op_subview_elem_inplace_schur;
+class op_subview_elem_inplace_div;
+
+
+
+template<const bool, const bool, const bool, const bool> class gemm;
+template<const bool, const bool, const bool>             class gemv;
+
+
+template<                 typename eT, typename gen_type> class  Gen; 
+
+template<                 typename T1, typename  op_type> class   Op; 
+template<                 typename T1, typename eop_type> class  eOp;
+template<typename out_eT, typename T1, typename  op_type> class mtOp;
+
+template<                 typename T1, typename T2, typename  glue_type> class   Glue;
+template<                 typename T1, typename T2, typename eglue_type> class  eGlue;
+template<typename out_eT, typename T1, typename T2, typename  glue_type> class mtGlue;
+
+
+
+template<                 typename eT, typename gen_type> class  GenCube; 
+
+template<                 typename T1, typename  op_type> class   OpCube; 
+template<                 typename T1, typename eop_type> class  eOpCube; 
+template<typename out_eT, typename T1, typename  op_type> class mtOpCube;
+
+template<                 typename T1, typename T2, typename  glue_type> class   GlueCube;
+template<                 typename T1, typename T2, typename eglue_type> class  eGlueCube;
+template<typename out_eT, typename T1, typename T2, typename  glue_type> class mtGlueCube;
+
+
+template<typename T1> class Proxy;
+template<typename T1> class ProxyCube;
+
+
+
+class spop_strans;
+class spop_htrans;
+class spop_scalar_times;
+
+class spglue_plus;
+class spglue_plus2;
+
+class spglue_minus;
+class spglue_minus2;
+
+class spglue_times;
+class spglue_times2;
+
+
+template<                 typename T1, typename spop_type> class   SpOp;
+template<typename out_eT, typename T1, typename spop_type> class mtSpOp;
+
+template<typename T1, typename T2, typename spglue_type> class SpGlue;
+
+
+template<typename T1> class SpProxy;
+
+
+
+struct arma_vec_indicator   {};
+struct arma_fixed_indicator {};
+
+
+//! \addtogroup injector
+//! @{
+
+template<typename Dummy = int> struct injector_end_of_row {};
+
+static const injector_end_of_row<> endr = injector_end_of_row<>();
+//!< endr indicates "end of row" when using the << operator;
+//!< similar conceptual meaning to std::endl
+
+//! @}
+
+
+
+//! \addtogroup diskio
+//! @{
+
+
+enum file_type
+  {
+  file_type_unknown,
+  auto_detect,  //!< Automatically detect the file type
+  raw_ascii,    //!< ASCII format (text), without any other information.
+  arma_ascii,   //!< Armadillo ASCII format (text), with information about matrix type and size
+  csv_ascii,    //!< comma separated values (CSV), without any other information
+  raw_binary,   //!< raw binary format, without any other information.
+  arma_binary,  //!< Armadillo binary format, with information about matrix type and size
+  pgm_binary,   //!< Portable Grey Map (greyscale image)
+  ppm_binary,   //!< Portable Pixel Map (colour image), used by the field and cube classes
+  hdf5_binary,  //!< Open binary format, not specific to Armadillo, which can store arbitrary data
+  coord_ascii   //!< simple co-ordinate format for sparse matrices
+  };
+
+
+//! @}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/gemm.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,532 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup gemm
+//! @{
+
+
+
+//! for tiny square matrices, size <= 4x4
+template<const bool do_trans_A=false, const bool use_alpha=false, const bool use_beta=false>
+class gemm_emul_tinysq
+  {
+  public:
+  
+  
+  template<typename eT, typename TA, typename TB>
+  arma_hot
+  inline
+  static
+  void
+  apply
+    (
+          Mat<eT>& C,
+    const TA&      A,
+    const TB&      B,
+    const eT alpha = eT(1),
+    const eT beta  = eT(0)
+    )
+    {
+    arma_extra_debug_sigprint();
+    
+    switch(A.n_rows)
+      {
+      case 4:
+        gemv_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply( C.colptr(3), A, B.colptr(3), alpha, beta );
+        
+      case 3:
+        gemv_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply( C.colptr(2), A, B.colptr(2), alpha, beta );
+        
+      case 2:
+        gemv_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply( C.colptr(1), A, B.colptr(1), alpha, beta );
+        
+      case 1:
+        gemv_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply( C.colptr(0), A, B.colptr(0), alpha, beta );
+        
+      default:
+        ;
+      }
+    }
+  
+  };
+
+
+
+template<const bool do_trans_A=false, const bool do_trans_B=false, const bool use_alpha=false, const bool use_beta=false>
+class gemm_emul_large
+  {
+  public:
+  
+  template<typename eT, typename TA, typename TB>
+  arma_hot
+  inline
+  static
+  void
+  apply
+    (
+          Mat<eT>& C,
+    const TA&      A,
+    const TB&      B,
+    const eT alpha = eT(1),
+    const eT beta  = eT(0)
+    )
+    {
+    arma_extra_debug_sigprint();
+
+    const uword A_n_rows = A.n_rows;
+    const uword A_n_cols = A.n_cols;
+    
+    const uword B_n_rows = B.n_rows;
+    const uword B_n_cols = B.n_cols;
+    
+    if( (do_trans_A == false) && (do_trans_B == false) )
+      {
+      arma_aligned podarray<eT> tmp(A_n_cols);
+      
+      eT* A_rowdata = tmp.memptr();
+      
+      for(uword row_A=0; row_A < A_n_rows; ++row_A)
+        {
+        //tmp.copy_row(A, row_A);
+        const eT acc0 = op_dot::dot_and_copy_row(A_rowdata, A, row_A, B.colptr(0), A_n_cols);
+        
+        if( (use_alpha == false) && (use_beta == false) )
+          {
+          C.at(row_A,0) = acc0;
+          }
+        else
+        if( (use_alpha == true) && (use_beta == false) )
+          {
+          C.at(row_A,0) = alpha * acc0;
+          }
+        else
+        if( (use_alpha == false) && (use_beta == true) )
+          {
+          C.at(row_A,0) = acc0 + beta*C.at(row_A,0);
+          }
+        else
+        if( (use_alpha == true) && (use_beta == true) )
+          {
+          C.at(row_A,0) = alpha*acc0 + beta*C.at(row_A,0);
+          }
+
+        //for(uword col_B=0; col_B < B_n_cols; ++col_B)
+        for(uword col_B=1; col_B < B_n_cols; ++col_B)
+          {
+          const eT acc = op_dot::direct_dot_arma(B_n_rows, A_rowdata, B.colptr(col_B));
+          
+          if( (use_alpha == false) && (use_beta == false) )
+            {
+            C.at(row_A,col_B) = acc;
+            }
+          else
+          if( (use_alpha == true) && (use_beta == false) )
+            {
+            C.at(row_A,col_B) = alpha * acc;
+            }
+          else
+          if( (use_alpha == false) && (use_beta == true) )
+            {
+            C.at(row_A,col_B) = acc + beta*C.at(row_A,col_B);
+            }
+          else
+          if( (use_alpha == true) && (use_beta == true) )
+            {
+            C.at(row_A,col_B) = alpha*acc + beta*C.at(row_A,col_B);
+            }
+          
+          }
+        }
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == false) )
+      {
+      for(uword col_A=0; col_A < A_n_cols; ++col_A)
+        {
+        // col_A is interpreted as row_A when storing the results in matrix C
+        
+        const eT* A_coldata = A.colptr(col_A);
+        
+        for(uword col_B=0; col_B < B_n_cols; ++col_B)
+          {
+          const eT acc = op_dot::direct_dot_arma(B_n_rows, A_coldata, B.colptr(col_B));
+          
+          if( (use_alpha == false) && (use_beta == false) )
+            {
+            C.at(col_A,col_B) = acc;
+            }
+          else
+          if( (use_alpha == true) && (use_beta == false) )
+            {
+            C.at(col_A,col_B) = alpha * acc;
+            }
+          else
+          if( (use_alpha == false) && (use_beta == true) )
+            {
+            C.at(col_A,col_B) = acc + beta*C.at(col_A,col_B);
+            }
+          else
+          if( (use_alpha == true) && (use_beta == true) )
+            {
+            C.at(col_A,col_B) = alpha*acc + beta*C.at(col_A,col_B);
+            }
+          
+          }
+        }
+      }
+    else
+    if( (do_trans_A == false) && (do_trans_B == true) )
+      {
+      Mat<eT> BB;
+      op_strans::apply_noalias(BB, B);
+      
+      gemm_emul_large<false, false, use_alpha, use_beta>::apply(C, A, BB, alpha, beta);
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == true) )
+      {
+      // mat B_tmp = trans(B);
+      // dgemm_arma<true, false,  use_alpha, use_beta>::apply(C, A, B_tmp, alpha, beta);
+      
+      
+      // By using the trans(A)*trans(B) = trans(B*A) equivalency,
+      // transpose operations are not needed
+      
+      arma_aligned podarray<eT> tmp(B.n_cols);
+      eT* B_rowdata = tmp.memptr();
+      
+      for(uword row_B=0; row_B < B_n_rows; ++row_B)
+        {
+        tmp.copy_row(B, row_B);
+        
+        for(uword col_A=0; col_A < A_n_cols; ++col_A)
+          {
+          const eT acc = op_dot::direct_dot_arma(A_n_rows, B_rowdata, A.colptr(col_A));
+          
+          if( (use_alpha == false) && (use_beta == false) )
+            {
+            C.at(col_A,row_B) = acc;
+            }
+          else
+          if( (use_alpha == true) && (use_beta == false) )
+            {
+            C.at(col_A,row_B) = alpha * acc;
+            }
+          else
+          if( (use_alpha == false) && (use_beta == true) )
+            {
+            C.at(col_A,row_B) = acc + beta*C.at(col_A,row_B);
+            }
+          else
+          if( (use_alpha == true) && (use_beta == true) )
+            {
+            C.at(col_A,row_B) = alpha*acc + beta*C.at(col_A,row_B);
+            }
+          
+          }
+        }
+      
+      }
+    }
+  
+  };
+  
+
+
+template<const bool do_trans_A=false, const bool do_trans_B=false, const bool use_alpha=false, const bool use_beta=false>
+class gemm_emul
+  {
+  public:
+  
+  
+  template<typename eT, typename TA, typename TB>
+  arma_hot
+  inline
+  static
+  void
+  apply
+    (
+          Mat<eT>& C,
+    const TA&      A,
+    const TB&      B,
+    const eT alpha = eT(1),
+    const eT beta  = eT(0),
+    const typename arma_not_cx<eT>::result* junk = 0
+    )
+    {
+    arma_extra_debug_sigprint();
+    arma_ignore(junk);
+    
+    const uword A_n_rows = A.n_rows;
+    const uword A_n_cols = A.n_cols;
+    
+    const uword B_n_rows = B.n_rows;
+    const uword B_n_cols = B.n_cols;
+    
+    if( (A_n_rows <= 4) && (A_n_rows == A_n_cols) && (A_n_rows == B_n_rows) && (B_n_rows == B_n_cols) )
+      {
+      if(do_trans_B == false)
+        {
+        gemm_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply(C, A, B, alpha, beta);
+        }
+      else
+        {
+        Mat<eT> BB(A_n_rows, A_n_rows);
+        op_strans::apply_noalias_tinysq(BB, B);
+        
+        gemm_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply(C, A, BB, alpha, beta);
+        }
+      }
+    else
+      {
+      gemm_emul_large<do_trans_A, do_trans_B, use_alpha, use_beta>::apply(C, A, B, alpha, beta);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  arma_hot
+  inline
+  static
+  void
+  apply
+    (
+          Mat<eT>& C,
+    const Mat<eT>& A,
+    const Mat<eT>& B,
+    const eT alpha = eT(1),
+    const eT beta  = eT(0),
+    const typename arma_cx_only<eT>::result* junk = 0
+    )
+    {
+    arma_extra_debug_sigprint();
+    arma_ignore(junk);
+    
+    // "better than nothing" handling of hermitian transposes for complex number matrices
+    
+    Mat<eT> tmp_A;
+    Mat<eT> tmp_B;
+    
+    if(do_trans_A)
+      {
+      op_htrans::apply_noalias(tmp_A, A);
+      }
+    
+    if(do_trans_B)
+      {
+      op_htrans::apply_noalias(tmp_B, B);
+      }
+    
+    const Mat<eT>& AA = (do_trans_A == false) ? A : tmp_A;
+    const Mat<eT>& BB = (do_trans_B == false) ? B : tmp_B;
+    
+    const uword A_n_rows = AA.n_rows;
+    const uword A_n_cols = AA.n_cols;
+    
+    const uword B_n_rows = BB.n_rows;
+    const uword B_n_cols = BB.n_cols;
+    
+    if( (A_n_rows <= 4) && (A_n_rows == A_n_cols) && (A_n_rows == B_n_rows) && (B_n_rows == B_n_cols) )
+      {
+      gemm_emul_tinysq<false, use_alpha, use_beta>::apply(C, AA, BB, alpha, beta);
+      }
+    else
+      {
+      gemm_emul_large<false, false, use_alpha, use_beta>::apply(C, AA, BB, alpha, beta);
+      }
+    }
+
+  };
+
+
+
+//! \brief
+//! Wrapper for ATLAS/BLAS dgemm function, using template arguments to control the arguments passed to dgemm.
+//! Matrix 'C' is assumed to have been set to the correct size (i.e. taking into account transposes)
+
+template<const bool do_trans_A=false, const bool do_trans_B=false, const bool use_alpha=false, const bool use_beta=false>
+class gemm
+  {
+  public:
+  
+  template<typename eT, typename TA, typename TB>
+  inline
+  static
+  void
+  apply_blas_type( Mat<eT>& C, const TA& A, const TB& B, const eT alpha = eT(1), const eT beta = eT(0) )
+    {
+    arma_extra_debug_sigprint();
+    
+    const uword threshold = (is_Mat_fixed<TA>::value && is_Mat_fixed<TB>::value)
+                            ? (is_complex<eT>::value ? 16u : 64u)
+                            : (is_complex<eT>::value ? 16u : 48u);
+    
+    if( (A.n_elem <= threshold) && (B.n_elem <= threshold) )
+      {
+      gemm_emul<do_trans_A, do_trans_B, use_alpha, use_beta>::apply(C,A,B,alpha,beta);
+      }
+    else
+      {
+      #if defined(ARMA_USE_ATLAS)
+        {
+        arma_extra_debug_print("atlas::cblas_gemm()");
+        
+        atlas::cblas_gemm<eT>
+          (
+          atlas::CblasColMajor,
+          (do_trans_A) ? ( is_complex<eT>::value ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans,
+          (do_trans_B) ? ( is_complex<eT>::value ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans,
+          C.n_rows,
+          C.n_cols,
+          (do_trans_A) ? A.n_rows : A.n_cols,
+          (use_alpha) ? alpha : eT(1),
+          A.mem,
+          (do_trans_A) ? A.n_rows : C.n_rows,
+          B.mem,
+          (do_trans_B) ? C.n_cols : ( (do_trans_A) ? A.n_rows : A.n_cols ),
+          (use_beta) ? beta : eT(0),
+          C.memptr(),
+          C.n_rows
+          );
+        }
+      #elif defined(ARMA_USE_BLAS)
+        {
+        arma_extra_debug_print("blas::gemm()");
+        
+        const char trans_A = (do_trans_A) ? ( is_complex<eT>::value ? 'C' : 'T' ) : 'N';
+        const char trans_B = (do_trans_B) ? ( is_complex<eT>::value ? 'C' : 'T' ) : 'N';
+        
+        const blas_int m   = C.n_rows;
+        const blas_int n   = C.n_cols;
+        const blas_int k   = (do_trans_A) ? A.n_rows : A.n_cols;
+        
+        const eT local_alpha = (use_alpha) ? alpha : eT(1);
+        
+        const blas_int lda = (do_trans_A) ? k : m;
+        const blas_int ldb = (do_trans_B) ? n : k;
+        
+        const eT local_beta  = (use_beta) ? beta : eT(0);
+        
+        arma_extra_debug_print( arma_boost::format("blas::gemm(): trans_A = %c") % trans_A );
+        arma_extra_debug_print( arma_boost::format("blas::gemm(): trans_B = %c") % trans_B );
+        
+        blas::gemm<eT>
+          (
+          &trans_A,
+          &trans_B,
+          &m,
+          &n,
+          &k,
+          &local_alpha,
+          A.mem,
+          &lda,
+          B.mem,
+          &ldb,
+          &local_beta,
+          C.memptr(),
+          &m
+          );
+        }
+      #else
+        {
+        gemm_emul<do_trans_A, do_trans_B, use_alpha, use_beta>::apply(C,A,B,alpha,beta);
+        }
+      #endif
+      }
+    }
+  
+  
+  
+  //! immediate multiplication of matrices A and B, storing the result in C
+  template<typename eT, typename TA, typename TB>
+  inline
+  static
+  void
+  apply( Mat<eT>& C, const TA& A, const TB& B, const eT alpha = eT(1), const eT beta = eT(0) )
+    {
+    gemm_emul<do_trans_A, do_trans_B, use_alpha, use_beta>::apply(C,A,B,alpha,beta);
+    }
+  
+  
+  
+  template<typename TA, typename TB>
+  arma_inline
+  static
+  void
+  apply
+    (
+          Mat<float>& C,
+    const TA&         A,
+    const TB&         B,
+    const float alpha = float(1),
+    const float beta  = float(0)
+    )
+    {
+    gemm<do_trans_A, do_trans_B, use_alpha, use_beta>::apply_blas_type(C,A,B,alpha,beta);
+    }
+  
+  
+  
+  template<typename TA, typename TB>
+  arma_inline
+  static
+  void
+  apply
+    (
+          Mat<double>& C,
+    const TA&          A,
+    const TB&          B,
+    const double alpha = double(1),
+    const double beta  = double(0)
+    )
+    {
+    gemm<do_trans_A, do_trans_B, use_alpha, use_beta>::apply_blas_type(C,A,B,alpha,beta);
+    }
+  
+  
+  
+  template<typename TA, typename TB>
+  arma_inline
+  static
+  void
+  apply
+    (
+          Mat< std::complex<float> >& C,
+    const TA&                         A,
+    const TB&                         B,
+    const std::complex<float> alpha = std::complex<float>(1),
+    const std::complex<float> beta  = std::complex<float>(0)
+    )
+    {
+    gemm<do_trans_A, do_trans_B, use_alpha, use_beta>::apply_blas_type(C,A,B,alpha,beta);
+    }
+  
+  
+  
+  template<typename TA, typename TB>
+  arma_inline
+  static
+  void
+  apply
+    (
+          Mat< std::complex<double> >& C,
+    const TA&                          A,
+    const TB&                          B,
+    const std::complex<double> alpha = std::complex<double>(1),
+    const std::complex<double> beta  = std::complex<double>(0)
+    )
+    {
+    gemm<do_trans_A, do_trans_B, use_alpha, use_beta>::apply_blas_type(C,A,B,alpha,beta);
+    }
+  
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/gemm_mixed.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,448 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup gemm_mixed
+//! @{
+
+
+
+//! \brief
+//! Matrix multplication where the matrices have differing element types.
+//! Uses caching for speedup.
+//! Matrix 'C' is assumed to have been set to the correct size (i.e. taking into account transposes)
+
+template<const bool do_trans_A=false, const bool do_trans_B=false, const bool use_alpha=false, const bool use_beta=false>
+class gemm_mixed_large
+  {
+  public:
+  
+  template<typename out_eT, typename in_eT1, typename in_eT2>
+  arma_hot
+  inline
+  static
+  void
+  apply
+    (
+          Mat<out_eT>& C,
+    const Mat<in_eT1>& A,
+    const Mat<in_eT2>& B,
+    const out_eT alpha = out_eT(1),
+    const out_eT beta  = out_eT(0)
+    )
+    {
+    arma_extra_debug_sigprint();
+    
+    const uword A_n_rows = A.n_rows;
+    const uword A_n_cols = A.n_cols;
+    
+    const uword B_n_rows = B.n_rows;
+    const uword B_n_cols = B.n_cols;
+    
+    if( (do_trans_A == false) && (do_trans_B == false) )
+      {
+      podarray<in_eT1> tmp(A_n_cols);
+      in_eT1* A_rowdata = tmp.memptr();
+      
+      for(uword row_A=0; row_A < A_n_rows; ++row_A)
+        {
+        tmp.copy_row(A, row_A);
+        
+        for(uword col_B=0; col_B < B_n_cols; ++col_B)
+          {
+          const in_eT2* B_coldata = B.colptr(col_B);
+          
+          out_eT acc = out_eT(0);
+          for(uword i=0; i < B_n_rows; ++i)
+            {
+            acc += upgrade_val<in_eT1,in_eT2>::apply(A_rowdata[i]) * upgrade_val<in_eT1,in_eT2>::apply(B_coldata[i]);
+            }
+        
+          if( (use_alpha == false) && (use_beta == false) )
+            {
+            C.at(row_A,col_B) = acc;
+            }
+          else
+          if( (use_alpha == true) && (use_beta == false) )
+            {
+            C.at(row_A,col_B) = alpha * acc;
+            }
+          else
+          if( (use_alpha == false) && (use_beta == true) )
+            {
+            C.at(row_A,col_B) = acc + beta*C.at(row_A,col_B);
+            }
+          else
+          if( (use_alpha == true) && (use_beta == true) )
+            {
+            C.at(row_A,col_B) = alpha*acc + beta*C.at(row_A,col_B);
+            }
+          
+          }
+        }
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == false) )
+      {
+      for(uword col_A=0; col_A < A_n_cols; ++col_A)
+        {
+        // col_A is interpreted as row_A when storing the results in matrix C
+        
+        const in_eT1* A_coldata = A.colptr(col_A);
+        
+        for(uword col_B=0; col_B < B_n_cols; ++col_B)
+          {
+          const in_eT2* B_coldata = B.colptr(col_B);
+          
+          out_eT acc = out_eT(0);
+          for(uword i=0; i < B_n_rows; ++i)
+            {
+            acc += upgrade_val<in_eT1,in_eT2>::apply(A_coldata[i]) * upgrade_val<in_eT1,in_eT2>::apply(B_coldata[i]);
+            }
+        
+          if( (use_alpha == false) && (use_beta == false) )
+            {
+            C.at(col_A,col_B) = acc;
+            }
+          else
+          if( (use_alpha == true) && (use_beta == false) )
+            {
+            C.at(col_A,col_B) = alpha * acc;
+            }
+          else
+          if( (use_alpha == false) && (use_beta == true) )
+            {
+            C.at(col_A,col_B) = acc + beta*C.at(col_A,col_B);
+            }
+          else
+          if( (use_alpha == true) && (use_beta == true) )
+            {
+            C.at(col_A,col_B) = alpha*acc + beta*C.at(col_A,col_B);
+            }
+          
+          }
+        }
+      }
+    else
+    if( (do_trans_A == false) && (do_trans_B == true) )
+      {
+      Mat<in_eT2> B_tmp;
+      
+      op_strans::apply_noalias(B_tmp, B);
+      
+      gemm_mixed_large<false, false, use_alpha, use_beta>::apply(C, A, B_tmp, alpha, beta);
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == true) )
+      {
+      // mat B_tmp = trans(B);
+      // dgemm_arma<true, false,  use_alpha, use_beta>::apply(C, A, B_tmp, alpha, beta);
+      
+      
+      // By using the trans(A)*trans(B) = trans(B*A) equivalency,
+      // transpose operations are not needed
+      
+      podarray<in_eT2> tmp(B_n_cols);
+      in_eT2* B_rowdata = tmp.memptr();
+      
+      for(uword row_B=0; row_B < B_n_rows; ++row_B)
+        {
+        tmp.copy_row(B, row_B);
+        
+        for(uword col_A=0; col_A < A_n_cols; ++col_A)
+          {
+          const in_eT1* A_coldata = A.colptr(col_A);
+          
+          out_eT acc = out_eT(0);
+          for(uword i=0; i < A_n_rows; ++i)
+            {
+            acc += upgrade_val<in_eT1,in_eT2>::apply(B_rowdata[i]) * upgrade_val<in_eT1,in_eT2>::apply(A_coldata[i]);
+            }
+        
+          if( (use_alpha == false) && (use_beta == false) )
+            {
+            C.at(col_A,row_B) = acc;
+            }
+          else
+          if( (use_alpha == true) && (use_beta == false) )
+            {
+            C.at(col_A,row_B) = alpha * acc;
+            }
+          else
+          if( (use_alpha == false) && (use_beta == true) )
+            {
+            C.at(col_A,row_B) = acc + beta*C.at(col_A,row_B);
+            }
+          else
+          if( (use_alpha == true) && (use_beta == true) )
+            {
+            C.at(col_A,row_B) = alpha*acc + beta*C.at(col_A,row_B);
+            }
+          
+          }
+        }
+      
+      }
+    }
+    
+  };
+
+
+
+//! Matrix multplication where the matrices have different element types.
+//! Simple version (no caching).
+//! Matrix 'C' is assumed to have been set to the correct size (i.e. taking into account transposes)
+template<const bool do_trans_A=false, const bool do_trans_B=false, const bool use_alpha=false, const bool use_beta=false>
+class gemm_mixed_small
+  {
+  public:
+  
+  template<typename out_eT, typename in_eT1, typename in_eT2>
+  arma_hot
+  inline
+  static
+  void
+  apply
+    (
+          Mat<out_eT>& C,
+    const Mat<in_eT1>& A,
+    const Mat<in_eT2>& B,
+    const out_eT alpha = out_eT(1),
+    const out_eT beta  = out_eT(0)
+    )
+    {
+    arma_extra_debug_sigprint();
+    
+    const uword A_n_rows = A.n_rows;
+    const uword A_n_cols = A.n_cols;
+    
+    const uword B_n_rows = B.n_rows;
+    const uword B_n_cols = B.n_cols;
+    
+    if( (do_trans_A == false) && (do_trans_B == false) )
+      {
+      for(uword row_A = 0; row_A < A_n_rows; ++row_A)
+        {
+        for(uword col_B = 0; col_B < B_n_cols; ++col_B)
+          {
+          const in_eT2* B_coldata = B.colptr(col_B);
+          
+          out_eT acc = out_eT(0);
+          for(uword i = 0; i < B_n_rows; ++i)
+            {
+            const out_eT val1 = upgrade_val<in_eT1,in_eT2>::apply(A.at(row_A,i));
+            const out_eT val2 = upgrade_val<in_eT1,in_eT2>::apply(B_coldata[i]);
+            acc += val1 * val2;
+            //acc += upgrade_val<in_eT1,in_eT2>::apply(A.at(row_A,i)) * upgrade_val<in_eT1,in_eT2>::apply(B_coldata[i]);
+            }
+          
+          if( (use_alpha == false) && (use_beta == false) )
+            {
+            C.at(row_A,col_B) = acc;
+            }
+          else
+          if( (use_alpha == true) && (use_beta == false) )
+            {
+            C.at(row_A,col_B) = alpha * acc;
+            }
+          else
+          if( (use_alpha == false) && (use_beta == true) )
+            {
+            C.at(row_A,col_B) = acc + beta*C.at(row_A,col_B);
+            }
+          else
+          if( (use_alpha == true) && (use_beta == true) )
+            {
+            C.at(row_A,col_B) = alpha*acc + beta*C.at(row_A,col_B);
+            }
+          }
+        }
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == false) )
+      {
+      for(uword col_A=0; col_A < A_n_cols; ++col_A)
+        {
+        // col_A is interpreted as row_A when storing the results in matrix C
+        
+        const in_eT1* A_coldata = A.colptr(col_A);
+        
+        for(uword col_B=0; col_B < B_n_cols; ++col_B)
+          {
+          const in_eT2* B_coldata = B.colptr(col_B);
+          
+          out_eT acc = out_eT(0);
+          for(uword i=0; i < B_n_rows; ++i)
+            {
+            acc += upgrade_val<in_eT1,in_eT2>::apply(A_coldata[i]) * upgrade_val<in_eT1,in_eT2>::apply(B_coldata[i]);
+            }
+        
+          if( (use_alpha == false) && (use_beta == false) )
+            {
+            C.at(col_A,col_B) = acc;
+            }
+          else
+          if( (use_alpha == true) && (use_beta == false) )
+            {
+            C.at(col_A,col_B) = alpha * acc;
+            }
+          else
+          if( (use_alpha == false) && (use_beta == true) )
+            {
+            C.at(col_A,col_B) = acc + beta*C.at(col_A,col_B);
+            }
+          else
+          if( (use_alpha == true) && (use_beta == true) )
+            {
+            C.at(col_A,col_B) = alpha*acc + beta*C.at(col_A,col_B);
+            }
+          
+          }
+        }
+      }
+    else
+    if( (do_trans_A == false) && (do_trans_B == true) )
+      {
+      for(uword row_A = 0; row_A < A_n_rows; ++row_A)
+        {
+        for(uword row_B = 0; row_B < B_n_rows; ++row_B)
+          {
+          out_eT acc = out_eT(0);
+          for(uword i = 0; i < B_n_cols; ++i)
+            {
+            acc += upgrade_val<in_eT1,in_eT2>::apply(A.at(row_A,i)) * upgrade_val<in_eT1,in_eT2>::apply(B.at(row_B,i));
+            }
+          
+          if( (use_alpha == false) && (use_beta == false) )
+            {
+            C.at(row_A,row_B) = acc;
+            }
+          else
+          if( (use_alpha == true) && (use_beta == false) )
+            {
+            C.at(row_A,row_B) = alpha * acc;
+            }
+          else
+          if( (use_alpha == false) && (use_beta == true) )
+            {
+            C.at(row_A,row_B) = acc + beta*C.at(row_A,row_B);
+            }
+          else
+          if( (use_alpha == true) && (use_beta == true) )
+            {
+            C.at(row_A,row_B) = alpha*acc + beta*C.at(row_A,row_B);
+            }
+          }
+        }
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == true) )
+      {
+      for(uword row_B=0; row_B < B_n_rows; ++row_B)
+        {
+        
+        for(uword col_A=0; col_A < A_n_cols; ++col_A)
+          {
+          const in_eT1* A_coldata = A.colptr(col_A);
+          
+          out_eT acc = out_eT(0);
+          for(uword i=0; i < A_n_rows; ++i)
+            {
+            acc += upgrade_val<in_eT1,in_eT2>::apply(B.at(row_B,i)) * upgrade_val<in_eT1,in_eT2>::apply(A_coldata[i]);
+            }
+        
+          if( (use_alpha == false) && (use_beta == false) )
+            {
+            C.at(col_A,row_B) = acc;
+            }
+          else
+          if( (use_alpha == true) && (use_beta == false) )
+            {
+            C.at(col_A,row_B) = alpha * acc;
+            }
+          else
+          if( (use_alpha == false) && (use_beta == true) )
+            {
+            C.at(col_A,row_B) = acc + beta*C.at(col_A,row_B);
+            }
+          else
+          if( (use_alpha == true) && (use_beta == true) )
+            {
+            C.at(col_A,row_B) = alpha*acc + beta*C.at(col_A,row_B);
+            }
+          
+          }
+        }
+      
+      }
+    }
+    
+  };
+
+
+
+
+
+//! \brief
+//! Matrix multplication where the matrices have differing element types.
+
+template<const bool do_trans_A=false, const bool do_trans_B=false, const bool use_alpha=false, const bool use_beta=false>
+class gemm_mixed
+  {
+  public:
+  
+  //! immediate multiplication of matrices A and B, storing the result in C
+  template<typename out_eT, typename in_eT1, typename in_eT2>
+  inline
+  static
+  void
+  apply
+    (
+          Mat<out_eT>& C,
+    const Mat<in_eT1>& A,
+    const Mat<in_eT2>& B,
+    const out_eT alpha = out_eT(1),
+    const out_eT beta  = out_eT(0)
+    )
+    {
+    arma_extra_debug_sigprint();
+    
+    Mat<in_eT1> tmp_A;
+    Mat<in_eT2> tmp_B;
+    
+    const bool predo_trans_A = ( (do_trans_A == true) && (is_complex<in_eT1>::value == true) );
+    const bool predo_trans_B = ( (do_trans_B == true) && (is_complex<in_eT2>::value == true) );
+    
+    if(do_trans_A)
+      {
+      op_htrans::apply_noalias(tmp_A, A);
+      }
+    
+    if(do_trans_B)
+      {
+      op_htrans::apply_noalias(tmp_B, B);
+      }
+     
+    const Mat<in_eT1>& AA = (predo_trans_A == false) ? A : tmp_A;
+    const Mat<in_eT2>& BB = (predo_trans_B == false) ? B : tmp_B;
+    
+    if( (AA.n_elem <= 64u) && (BB.n_elem <= 64u) )
+      {
+      gemm_mixed_small<((predo_trans_A) ? false : do_trans_A), ((predo_trans_B) ? false : do_trans_B), use_alpha, use_beta>::apply(C, AA, BB, alpha, beta);
+      }
+    else
+      {
+      gemm_mixed_large<((predo_trans_A) ? false : do_trans_A), ((predo_trans_B) ? false : do_trans_B), use_alpha, use_beta>::apply(C, AA, BB, alpha, beta);
+      }
+    }
+  
+  
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/gemv.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,585 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup gemv
+//! @{
+
+
+
+//! for tiny square matrices, size <= 4x4
+template<const bool do_trans_A=false, const bool use_alpha=false, const bool use_beta=false>
+class gemv_emul_tinysq
+  {
+  public:
+  
+  
+  template<const uword row, const uword col>
+  struct pos
+    {
+    static const uword n2 = (do_trans_A == false) ? (row + col*2) : (col + row*2);
+    static const uword n3 = (do_trans_A == false) ? (row + col*3) : (col + row*3);
+    static const uword n4 = (do_trans_A == false) ? (row + col*4) : (col + row*4);
+    };
+  
+  
+  
+  template<typename eT, const uword i>
+  arma_hot
+  arma_inline
+  static
+  void
+  assign(eT* y, const eT acc, const eT alpha, const eT beta)
+    {
+    if(use_beta == false)
+      {
+      y[i] = (use_alpha == false) ? acc : alpha*acc;
+      }
+    else
+      {
+      const eT tmp = y[i];
+      
+      y[i] = beta*tmp + ( (use_alpha == false) ? acc : alpha*acc );
+      }
+    }
+  
+  
+
+  template<typename eT, typename TA>
+  arma_hot
+  inline
+  static
+  void
+  apply( eT* y, const TA& A, const eT* x, const eT alpha = eT(1), const eT beta = eT(0) )
+    {
+    arma_extra_debug_sigprint();
+    
+    const eT*  Am = A.memptr();
+    
+    switch(A.n_rows)
+      {
+      case 1:
+        {
+        const eT acc = Am[0] * x[0];
+        
+        assign<eT, 0>(y, acc, alpha, beta);
+        }
+        break;
+      
+      
+      case 2:
+        {
+        const eT x0 = x[0];
+        const eT x1 = x[1];
+        
+        const eT acc0 = Am[pos<0,0>::n2]*x0 + Am[pos<0,1>::n2]*x1;
+        const eT acc1 = Am[pos<1,0>::n2]*x0 + Am[pos<1,1>::n2]*x1;
+        
+        assign<eT, 0>(y, acc0, alpha, beta);
+        assign<eT, 1>(y, acc1, alpha, beta);
+        }
+        break;
+      
+        
+      case 3:
+        {
+        const eT x0 = x[0];
+        const eT x1 = x[1];
+        const eT x2 = x[2];
+        
+        const eT acc0 = Am[pos<0,0>::n3]*x0 + Am[pos<0,1>::n3]*x1 + Am[pos<0,2>::n3]*x2;
+        const eT acc1 = Am[pos<1,0>::n3]*x0 + Am[pos<1,1>::n3]*x1 + Am[pos<1,2>::n3]*x2;
+        const eT acc2 = Am[pos<2,0>::n3]*x0 + Am[pos<2,1>::n3]*x1 + Am[pos<2,2>::n3]*x2;
+        
+        assign<eT, 0>(y, acc0, alpha, beta);
+        assign<eT, 1>(y, acc1, alpha, beta);
+        assign<eT, 2>(y, acc2, alpha, beta);
+        }
+        break;
+      
+      
+      case 4:
+        {
+        const eT x0 = x[0];
+        const eT x1 = x[1];
+        const eT x2 = x[2];
+        const eT x3 = x[3];
+        
+        const eT acc0 = Am[pos<0,0>::n4]*x0 + Am[pos<0,1>::n4]*x1 + Am[pos<0,2>::n4]*x2 + Am[pos<0,3>::n4]*x3;
+        const eT acc1 = Am[pos<1,0>::n4]*x0 + Am[pos<1,1>::n4]*x1 + Am[pos<1,2>::n4]*x2 + Am[pos<1,3>::n4]*x3;
+        const eT acc2 = Am[pos<2,0>::n4]*x0 + Am[pos<2,1>::n4]*x1 + Am[pos<2,2>::n4]*x2 + Am[pos<2,3>::n4]*x3;
+        const eT acc3 = Am[pos<3,0>::n4]*x0 + Am[pos<3,1>::n4]*x1 + Am[pos<3,2>::n4]*x2 + Am[pos<3,3>::n4]*x3;
+        
+        assign<eT, 0>(y, acc0, alpha, beta);
+        assign<eT, 1>(y, acc1, alpha, beta);
+        assign<eT, 2>(y, acc2, alpha, beta);
+        assign<eT, 3>(y, acc3, alpha, beta);
+        }
+        break;
+      
+      
+      default:
+        ;
+      }
+    }
+    
+  };
+
+
+
+class gemv_emul_large_helper
+  {
+  public:
+  
+  template<typename eT, typename TA>
+  arma_hot
+  inline
+  static
+  typename arma_not_cx<eT>::result
+  dot_row_col( const TA& A, const eT* x, const uword row, const uword N )
+    {
+    eT acc1 = eT(0);
+    eT acc2 = eT(0);
+    
+    uword i,j;
+    for(i=0, j=1; j < N; i+=2, j+=2)
+      {
+      const eT xi = x[i];
+      const eT xj = x[j];
+      
+      acc1 += A.at(row,i) * xi;
+      acc2 += A.at(row,j) * xj;
+      }
+    
+    if(i < N)
+      {
+      acc1 += A.at(row,i) * x[i];
+      }
+    
+    return (acc1 + acc2);
+    }
+  
+  
+  
+  template<typename eT, typename TA>
+  arma_hot
+  inline
+  static
+  typename arma_cx_only<eT>::result
+  dot_row_col( const TA& A, const eT* x, const uword row, const uword N )
+    {
+    typedef typename get_pod_type<eT>::result T;
+    
+    T val_real = T(0);
+    T val_imag = T(0);
+    
+    for(uword i=0; i<N; ++i)
+      {
+      const std::complex<T>& Ai = A.at(row,i);
+      const std::complex<T>& xi = x[i];
+      
+      const T a = Ai.real();
+      const T b = Ai.imag();
+      
+      const T c = xi.real();
+      const T d = xi.imag();
+      
+      val_real += (a*c) - (b*d);
+      val_imag += (a*d) + (b*c);
+      }
+    
+    return std::complex<T>(val_real, val_imag);
+    }
+  
+  };
+
+
+
+//! \brief
+//! Partial emulation of ATLAS/BLAS gemv().
+//! 'y' is assumed to have been set to the correct size (i.e. taking into account the transpose)
+
+template<const bool do_trans_A=false, const bool use_alpha=false, const bool use_beta=false>
+class gemv_emul_large
+  {
+  public:
+  
+  template<typename eT, typename TA>
+  arma_hot
+  inline
+  static
+  void
+  apply( eT* y, const TA& A, const eT* x, const eT alpha = eT(1), const eT beta = eT(0) )
+    {
+    arma_extra_debug_sigprint();
+    
+    const uword A_n_rows = A.n_rows;
+    const uword A_n_cols = A.n_cols;
+    
+    if(do_trans_A == false)
+      {
+      if(A_n_rows == 1)
+        {
+        const eT acc = op_dot::direct_dot_arma(A_n_cols, A.memptr(), x);
+        
+        if( (use_alpha == false) && (use_beta == false) )
+          {
+          y[0] = acc;
+          }
+        else
+        if( (use_alpha == true) && (use_beta == false) )
+          {
+          y[0] = alpha * acc;
+          }
+        else
+        if( (use_alpha == false) && (use_beta == true) )
+          {
+          y[0] = acc + beta*y[0];
+          }
+        else
+        if( (use_alpha == true) && (use_beta == true) )
+          {
+          y[0] = alpha*acc + beta*y[0];
+          }
+        }
+      else
+      for(uword row=0; row < A_n_rows; ++row)
+        {
+        const eT acc = gemv_emul_large_helper::dot_row_col(A, x, row, A_n_cols);
+        
+        if( (use_alpha == false) && (use_beta == false) )
+          {
+          y[row] = acc;
+          }
+        else
+        if( (use_alpha == true) && (use_beta == false) )
+          {
+          y[row] = alpha * acc;
+          }
+        else
+        if( (use_alpha == false) && (use_beta == true) )
+          {
+          y[row] = acc + beta*y[row];
+          }
+        else
+        if( (use_alpha == true) && (use_beta == true) )
+          {
+          y[row] = alpha*acc + beta*y[row];
+          }
+        }
+      }
+    else
+    if(do_trans_A == true)
+      {
+      for(uword col=0; col < A_n_cols; ++col)
+        {
+        // col is interpreted as row when storing the results in 'y'
+        
+        
+        // const eT* A_coldata = A.colptr(col);
+        // 
+        // eT acc = eT(0);
+        // for(uword row=0; row < A_n_rows; ++row)
+        //   {
+        //   acc += A_coldata[row] * x[row];
+        //   }
+        
+        const eT acc = op_dot::direct_dot_arma(A_n_rows, A.colptr(col), x);
+        
+        if( (use_alpha == false) && (use_beta == false) )
+          {
+          y[col] = acc;
+          }
+        else
+        if( (use_alpha == true) && (use_beta == false) )
+          {
+          y[col] = alpha * acc;
+          }
+        else
+        if( (use_alpha == false) && (use_beta == true) )
+          {
+          y[col] = acc + beta*y[col];
+          }
+        else
+        if( (use_alpha == true) && (use_beta == true) )
+          {
+          y[col] = alpha*acc + beta*y[col];
+          }
+        
+        }
+      }
+    }
+  
+  };
+
+
+
+template<const bool do_trans_A=false, const bool use_alpha=false, const bool use_beta=false>
+class gemv_emul
+  {
+  public:
+  
+  template<typename eT, typename TA>
+  arma_hot
+  inline
+  static
+  void
+  apply( eT* y, const TA& A, const eT* x, const eT alpha = eT(1), const eT beta = eT(0), const typename arma_not_cx<eT>::result* junk = 0 )
+    {
+    arma_extra_debug_sigprint();
+    arma_ignore(junk);
+    
+    const uword A_n_rows = A.n_rows;
+    const uword A_n_cols = A.n_cols;
+    
+    if( (A_n_rows <= 4) && (A_n_rows == A_n_cols) )
+      {
+      gemv_emul_tinysq<do_trans_A, use_alpha, use_beta>::apply(y, A, x, alpha, beta);
+      }
+    else
+      {
+      gemv_emul_large<do_trans_A, use_alpha, use_beta>::apply(y, A, x, alpha, beta);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  arma_hot
+  inline
+  static
+  void
+  apply( eT* y, const Mat<eT>& A, const eT* x, const eT alpha = eT(1), const eT beta = eT(0), const typename arma_cx_only<eT>::result* junk = 0 )
+    {
+    arma_extra_debug_sigprint();
+    arma_ignore(junk);
+    
+    Mat<eT> tmp_A;
+    
+    if(do_trans_A)
+      {
+      op_htrans::apply_noalias(tmp_A, A);
+      }
+    
+    const Mat<eT>& AA = (do_trans_A == false) ? A : tmp_A;
+    
+    const uword AA_n_rows = AA.n_rows;
+    const uword AA_n_cols = AA.n_cols;
+    
+    if( (AA_n_rows <= 4) && (AA_n_rows == AA_n_cols) )
+      {
+      gemv_emul_tinysq<false, use_alpha, use_beta>::apply(y, AA, x, alpha, beta);
+      }
+    else
+      {
+      gemv_emul_large<false, use_alpha, use_beta>::apply(y, AA, x, alpha, beta);
+      }
+    }
+  };
+
+
+
+//! \brief
+//! Wrapper for ATLAS/BLAS gemv function, using template arguments to control the arguments passed to gemv.
+//! 'y' is assumed to have been set to the correct size (i.e. taking into account the transpose)
+
+template<const bool do_trans_A=false, const bool use_alpha=false, const bool use_beta=false>
+class gemv
+  {
+  public:
+  
+  template<typename eT, typename TA>
+  inline
+  static
+  void
+  apply_blas_type( eT* y, const TA& A, const eT* x, const eT alpha = eT(1), const eT beta = eT(0) )
+    {
+    arma_extra_debug_sigprint();
+    
+    //const uword threshold = (is_complex<eT>::value == true) ? 16u : 64u;
+    const uword threshold = (is_complex<eT>::value == true) ? 64u : 100u;
+    
+    if(A.n_elem <= threshold)
+      {
+      gemv_emul<do_trans_A, use_alpha, use_beta>::apply(y,A,x,alpha,beta);
+      }
+    else
+      {
+      #if defined(ARMA_USE_ATLAS)
+        {
+        if(is_complex<eT>::value == false)
+          {
+          // use gemm() instead of gemv() to work around a speed issue in Atlas 3.8.4
+          
+          arma_extra_debug_print("atlas::cblas_gemm()");
+          
+          atlas::cblas_gemm<eT>
+            (
+            atlas::CblasColMajor,
+            (do_trans_A) ? ( is_complex<eT>::value ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans,
+            atlas::CblasNoTrans,
+            (do_trans_A) ? A.n_cols : A.n_rows,
+            1,
+            (do_trans_A) ? A.n_rows : A.n_cols,
+            (use_alpha) ? alpha : eT(1),
+            A.mem,
+            A.n_rows,
+            x,
+            (do_trans_A) ? A.n_rows : A.n_cols,
+            (use_beta) ? beta : eT(0),
+            y,
+            (do_trans_A) ? A.n_cols : A.n_rows
+            );
+          }
+        else
+          {
+          arma_extra_debug_print("atlas::cblas_gemv()");
+          
+          atlas::cblas_gemv<eT>
+            (
+            atlas::CblasColMajor,
+            (do_trans_A) ? ( is_complex<eT>::value ? CblasConjTrans : atlas::CblasTrans ) : atlas::CblasNoTrans,
+            A.n_rows,
+            A.n_cols,
+            (use_alpha) ? alpha : eT(1),
+            A.mem,
+            A.n_rows,
+            x,
+            1,
+            (use_beta) ? beta : eT(0),
+            y,
+            1
+            );
+          }
+        }
+      #elif defined(ARMA_USE_BLAS)
+        {
+        arma_extra_debug_print("blas::gemv()");
+        
+        const char      trans_A     = (do_trans_A) ? ( is_complex<eT>::value ? 'C' : 'T' ) : 'N';
+        const blas_int  m           = A.n_rows;
+        const blas_int  n           = A.n_cols;
+        const eT        local_alpha = (use_alpha) ? alpha : eT(1);
+        //const blas_int  lda         = A.n_rows;
+        const blas_int  inc         = 1;
+        const eT        local_beta  = (use_beta) ? beta : eT(0);
+        
+        arma_extra_debug_print( arma_boost::format("blas::gemv(): trans_A = %c") % trans_A );
+        
+        blas::gemv<eT>
+          (
+          &trans_A,
+          &m,
+          &n,
+          &local_alpha,
+          A.mem,
+          &m,  // lda
+          x,
+          &inc,
+          &local_beta,
+          y,
+          &inc
+          );
+        }
+      #else
+        {
+        gemv_emul<do_trans_A, use_alpha, use_beta>::apply(y,A,x,alpha,beta);
+        }
+      #endif
+      }
+    
+    }
+  
+  
+  
+  template<typename eT, typename TA>
+  arma_inline
+  static
+  void
+  apply( eT* y, const TA& A, const eT* x, const eT alpha = eT(1), const eT beta = eT(0) )
+    {
+    gemv_emul<do_trans_A, use_alpha, use_beta>::apply(y,A,x,alpha,beta);
+    }
+  
+  
+  
+  template<typename TA>
+  arma_inline
+  static
+  void
+  apply
+    (
+          float* y,
+    const TA&    A,
+    const float* x,
+    const float  alpha = float(1),
+    const float  beta  = float(0)
+    )
+    {
+    gemv<do_trans_A, use_alpha, use_beta>::apply_blas_type(y,A,x,alpha,beta);
+    }
+  
+  
+  
+  template<typename TA>
+  arma_inline
+  static
+  void
+  apply
+    (
+          double* y,
+    const TA&     A,
+    const double* x,
+    const double  alpha = double(1),
+    const double  beta  = double(0)
+    )
+    {
+    gemv<do_trans_A, use_alpha, use_beta>::apply_blas_type(y,A,x,alpha,beta);
+    }
+  
+  
+  
+  template<typename TA>
+  arma_inline
+  static
+  void
+  apply
+    (
+          std::complex<float>* y,
+    const TA&                  A,
+    const std::complex<float>* x,
+    const std::complex<float>  alpha = std::complex<float>(1),
+    const std::complex<float>  beta  = std::complex<float>(0)
+    )
+    {
+    gemv<do_trans_A, use_alpha, use_beta>::apply_blas_type(y,A,x,alpha,beta);
+    }
+
+
+  
+  template<typename TA>
+  arma_inline
+  static
+  void
+  apply
+    (
+          std::complex<double>* y,
+    const TA&                   A,
+    const std::complex<double>* x,
+    const std::complex<double>  alpha = std::complex<double>(1),
+    const std::complex<double>  beta  = std::complex<double>(0)
+    )
+    {
+    gemv<do_trans_A, use_alpha, use_beta>::apply_blas_type(y,A,x,alpha,beta);
+    }
+
+
+  
+  };
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_conv_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,25 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup glue_conv
+//! @{
+
+
+
+class glue_conv
+  {
+  public:
+
+  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_conv>& X);
+  };
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_conv_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,110 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup glue_conv
+//! @{
+
+
+//! rudimentary implementation of the convolution operation
+
+template<typename T1, typename T2>
+inline
+void
+glue_conv::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_conv>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> A_tmp(X.A, out);
+  const unwrap_check<T2> B_tmp(X.B, out);
+  
+  const Mat<eT>& A = A_tmp.M;
+  const Mat<eT>& B = B_tmp.M;
+  
+  arma_debug_check
+    (
+    ( ((A.is_vec() == false) && (A.is_empty() == false)) || ((B.is_vec() == false) && (B.is_empty() == false)) ),
+    "conv(): given object is not a vector"
+    );
+  
+  
+  const Mat<eT>& h = (A.n_elem <= B.n_elem) ? A : B;
+  const Mat<eT>& x = (A.n_elem <= B.n_elem) ? B : A;
+  
+  
+  const uword   h_n_elem = h.n_elem;
+  const uword   x_n_elem = x.n_elem;
+  const uword out_n_elem = h_n_elem + x_n_elem - 1;
+  
+  
+  if( (h_n_elem == 0) || (x_n_elem == 0) )
+    {
+    out.reset();
+    return;
+    }
+  
+  
+  (A.n_cols == 1) ? out.set_size(out_n_elem, 1) : out.set_size(1, out_n_elem);
+  
+  
+  const eT*   h_mem = h.memptr();
+  const eT*   x_mem = x.memptr();
+        eT* out_mem = out.memptr();
+  
+  
+  for(uword out_i = 0; out_i < (h_n_elem-1); ++out_i)
+    {
+    eT acc = eT(0);
+    
+    uword h_i = out_i;
+    
+    for(uword x_i = 0; x_i <= out_i; ++x_i, --h_i)
+      {
+      acc += h_mem[h_i] * x_mem[x_i];
+      }
+    
+    out_mem[out_i] = acc;
+    }
+  
+  
+  for(uword out_i = h_n_elem-1; out_i < out_n_elem - (h_n_elem-1); ++out_i)
+    {
+    eT acc = eT(0);
+   
+    uword h_i = h_n_elem - 1;
+    
+    for(uword x_i = out_i - h_n_elem + 1; x_i <= out_i; ++x_i, --h_i)
+      {
+      acc += h_mem[h_i] * x_mem[x_i];
+      }
+      
+    out_mem[out_i] = acc;
+    }
+  
+  
+  for(uword out_i = out_n_elem - (h_n_elem-1); out_i < out_n_elem; ++out_i)
+    {
+    eT acc = eT(0);
+    
+    uword h_i = h_n_elem - 1;
+    
+    for(uword x_i = out_i - h_n_elem + 1; x_i < x_n_elem; ++x_i, --h_i)
+      {
+      acc += h_mem[h_i] * x_mem[x_i];
+      }
+    
+    out_mem[out_i] = acc;
+    }
+  
+  
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_cor_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,29 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup glue_cor
+//! @{
+
+
+
+class glue_cor
+  {
+  public:
+
+  template<typename eT> inline static void direct_cor(Mat<eT>&                out, const Mat<eT>&                A, const Mat<eT>&                B, const uword norm_type);
+  template<typename T>  inline static void direct_cor(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat< std::complex<T> >& B, const uword norm_type);
+  
+  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cor>& X);
+  };
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_cor_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,176 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup glue_cor
+//! @{
+
+
+
+template<typename eT>
+inline
+void
+glue_cor::direct_cor(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(A.is_empty() || B.is_empty() )
+    {
+    out.reset();
+    return;
+    }
+  
+  if(A.is_vec() && B.is_vec())
+    {
+    arma_debug_check( (A.n_elem != B.n_elem), "cor(): the number of elements in the two vectors must match" );
+    
+    const eT* A_ptr = A.memptr();
+    const eT* B_ptr = B.memptr();
+    
+    eT A_acc   = eT(0);
+    eT B_acc   = eT(0);
+    eT out_acc = eT(0);
+    
+    const uword N = A.n_elem;
+    
+    for(uword i=0; i<N; ++i)
+      {
+      const eT A_tmp = A_ptr[i];
+      const eT B_tmp = B_ptr[i];
+      
+      A_acc += A_tmp;
+      B_acc += B_tmp;
+      
+      out_acc += A_tmp * B_tmp;
+      }
+    
+    out_acc -= (A_acc * B_acc)/eT(N);
+    
+    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);    
+    
+    out.set_size(1,1);
+    out[0] = out_acc/norm_val;
+    
+    const Mat<eT> stddev_A = (A.n_rows == 1) ? Mat<eT>(stddev(trans(A))) : Mat<eT>(stddev(A));
+    const Mat<eT> stddev_B = (B.n_rows == 1) ? Mat<eT>(stddev(trans(B))) : Mat<eT>(stddev(B));
+    
+    out /= stddev_A * stddev_B;
+    }
+  else
+    {
+    arma_debug_assert_mul_size(A, B, true, false, "cor()");
+    
+    const uword N = A.n_rows;
+    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
+    
+    out = trans(A) * B;
+    out -= (trans(sum(A)) * sum(B))/eT(N);
+    out /= norm_val;
+    out /= trans(stddev(A)) * stddev(B);
+    }
+  }
+
+
+
+template<typename T>
+inline
+void
+glue_cor::direct_cor(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat< std::complex<T> >& B, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<T> eT;
+  
+  if(A.is_empty() || B.is_empty() )
+    {
+    out.reset();
+    return;
+    }
+  
+  if(A.is_vec() && B.is_vec())
+    {
+    arma_debug_check( (A.n_elem != B.n_elem), "cor(): the number of elements in the two vectors must match" );
+    
+    const eT* A_ptr = A.memptr();
+    const eT* B_ptr = B.memptr();        
+    
+    eT A_acc   = eT(0);
+    eT B_acc   = eT(0);
+    eT out_acc = eT(0);
+    
+    const uword N = A.n_elem;
+    
+    for(uword i=0; i<N; ++i)
+      {
+      const eT A_tmp = A_ptr[i];
+      const eT B_tmp = B_ptr[i];
+      
+      A_acc += A_tmp;
+      B_acc += B_tmp;
+      
+      out_acc += std::conj(A_tmp) * B_tmp;
+      }
+    
+    out_acc -= (std::conj(A_acc) * B_acc)/eT(N);
+    
+    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
+    
+    out.set_size(1,1);
+    out[0] = out_acc/norm_val;
+    
+    const Mat<T> stddev_A = (A.n_rows == 1) ? Mat<T>(stddev(trans(A))) : Mat<T>(stddev(A));
+    const Mat<T> stddev_B = (B.n_rows == 1) ? Mat<T>(stddev(trans(B))) : Mat<T>(stddev(B));
+    
+    out /= conv_to< Mat<eT> >::from( stddev_A * stddev_B );
+    }
+  else
+    {
+    arma_debug_assert_mul_size(A, B, true, false, "cor()");
+    
+    const uword N = A.n_rows;
+    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
+    
+    out = trans(A) * B;                     // out = strans(conj(A)) * B;
+    out -= (trans(sum(A)) * sum(B))/eT(N);  // out -= (strans(conj(sum(A))) * sum(B))/eT(N);
+    out /= norm_val;
+    out /= conv_to< Mat<eT> >::from( trans(stddev(A)) * stddev(B) );
+    }
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_cor::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cor>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> A_tmp(X.A, out);
+  const unwrap_check<T2> B_tmp(X.B, out);
+  
+  const Mat<eT>& A = A_tmp.M;
+  const Mat<eT>& B = B_tmp.M;
+  
+  const uword norm_type = X.aux_uword;
+  
+  if(&A != &B)
+    {
+    glue_cor::direct_cor(out, A, B, norm_type);
+    }
+  else
+    {
+    op_cor::direct_cor(out, A, norm_type);
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_cov_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,29 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup glue_cov
+//! @{
+
+
+
+class glue_cov
+  {
+  public:
+
+  template<typename eT> inline static void direct_cov(Mat<eT>&                out, const Mat<eT>&                A, const Mat<eT>&                B, const uword norm_type);
+  template<typename T>  inline static void direct_cov(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat< std::complex<T> >& B, const uword norm_type);
+  
+  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cov>& X);
+  };
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_cov_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,153 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup glue_cov
+//! @{
+
+
+
+template<typename eT>
+inline
+void
+glue_cov::direct_cov(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+
+  if(A.is_vec() && B.is_vec())
+    {
+    arma_debug_check( (A.n_elem != B.n_elem), "cov(): the number of elements in A and B must match" );
+
+    const eT* A_ptr = A.memptr();
+    const eT* B_ptr = B.memptr();
+
+    eT A_acc   = eT(0);
+    eT B_acc   = eT(0);
+    eT out_acc = eT(0);
+
+    const uword N = A.n_elem;
+
+    for(uword i=0; i<N; ++i)
+      {
+      const eT A_tmp = A_ptr[i];
+      const eT B_tmp = B_ptr[i];
+
+      A_acc += A_tmp;
+      B_acc += B_tmp;
+
+      out_acc += A_tmp * B_tmp;
+      }
+
+    out_acc -= (A_acc * B_acc)/eT(N);
+
+    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
+
+    out.set_size(1,1);
+    out[0] = out_acc/norm_val;
+    }
+  else
+    {
+    arma_debug_assert_mul_size(A, B, true, false, "cov()");
+    
+    const uword N = A.n_rows;
+    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
+    
+    out = trans(A) * B;
+    out -= (trans(sum(A)) * sum(B))/eT(N);
+    out /= norm_val;
+    }
+  }
+
+
+
+template<typename T>
+inline
+void
+glue_cov::direct_cov(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat< std::complex<T> >& B, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+
+  typedef typename std::complex<T> eT;
+
+  if(A.is_vec() && B.is_vec())
+    { 
+    arma_debug_check( (A.n_elem != B.n_elem), "cov(): the number of elements in A and B must match" );
+
+    const eT* A_ptr = A.memptr();
+    const eT* B_ptr = B.memptr();        
+
+    eT A_acc   = eT(0);
+    eT B_acc   = eT(0);
+    eT out_acc = eT(0);
+
+    const uword N = A.n_elem;
+
+    for(uword i=0; i<N; ++i)
+      {
+      const eT A_tmp = A_ptr[i];
+      const eT B_tmp = B_ptr[i];
+
+      A_acc += A_tmp;
+      B_acc += B_tmp;
+
+      out_acc += std::conj(A_tmp) * B_tmp;
+      }
+
+    out_acc -= (std::conj(A_acc) * B_acc)/eT(N);
+
+    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
+
+    out.set_size(1,1);
+    out[0] = out_acc/norm_val;
+    }
+  else
+    {
+    arma_debug_assert_mul_size(A, B, true, false, "cov()");
+    
+    const uword N = A.n_rows;
+    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
+    
+    out = trans(A) * B;                     // out = strans(conj(A)) * B;
+    out -= (trans(sum(A)) * sum(B))/eT(N);  // out -= (strans(conj(sum(A))) * sum(B))/eT(N);
+    out /= norm_val;
+    }
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_cov::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cov>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  typedef typename T1::elem_type eT;
+
+  const unwrap_check<T1> A_tmp(X.A, out);
+  const unwrap_check<T2> B_tmp(X.B, out);
+
+  const Mat<eT>& A = A_tmp.M;
+  const Mat<eT>& B = B_tmp.M;
+  
+  const uword norm_type = X.aux_uword;
+
+  if(&A != &B)
+    {
+    glue_cov::direct_cov(out, A, B, norm_type);
+    }
+  else
+    {
+    op_cov::direct_cov(out, A, norm_type);
+    }
+  
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_cross_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,25 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup glue_cross
+//! @{
+
+
+
+class glue_cross
+  {
+  public:
+
+  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cross>& X);
+  };
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_cross_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,74 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup glue_cross
+//! @{
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_cross::apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_cross>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> PA(X.A);
+  const Proxy<T2> PB(X.B);
+  
+  arma_debug_check( ((PA.get_n_elem() != 3) || (PB.get_n_elem() != 3)), "cross(): input vectors must have 3 elements" );
+  
+  const uword PA_n_rows = Proxy<T1>::is_row ? 1 : PA.get_n_rows();
+  const uword PA_n_cols = Proxy<T1>::is_col ? 1 : PA.get_n_cols();
+  
+  out.set_size(PA_n_rows, PA_n_cols);
+  
+  eT* out_mem = out.memptr();
+  
+  if( (Proxy<T1>::prefer_at_accessor == false) && (Proxy<T2>::prefer_at_accessor == false) )
+    {
+    typename Proxy<T1>::ea_type A = PA.get_ea();
+    typename Proxy<T2>::ea_type B = PB.get_ea();
+    
+    const eT ax = A[0];
+    const eT ay = A[1];
+    const eT az = A[2];
+    
+    const eT bx = B[0];
+    const eT by = B[1];
+    const eT bz = B[2];
+    
+    out_mem[0] = ay*bz - az*by;
+    out_mem[1] = az*bx - ax*bz;
+    out_mem[2] = ax*by - ay*bx;
+    }
+  else
+    {
+    const bool PA_is_col = Proxy<T1>::is_col ? true : (PA_n_cols       == 1);
+    const bool PB_is_col = Proxy<T2>::is_col ? true : (PB.get_n_cols() == 1);
+    
+    const eT ax = PA.at(0,0);
+    const eT ay = PA_is_col ? PA.at(1,0) : PA.at(0,1);
+    const eT az = PA_is_col ? PA.at(2,0) : PA.at(0,2);
+    
+    const eT bx = PB.at(0,0);
+    const eT by = PB_is_col ? PB.at(1,0) : PB.at(0,1);
+    const eT bz = PB_is_col ? PB.at(2,0) : PB.at(0,2);
+    
+    out_mem[0] = ay*bz - az*by;
+    out_mem[1] = az*bx - ax*bz;
+    out_mem[2] = ax*by - ay*bx;
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_hist_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,15 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+class glue_hist
+   {
+   public:
+
+   template<typename T1, typename T2> inline static void apply(Mat<uword>& out, const mtGlue<uword,T1,T2,glue_hist>& in);
+   };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_hist_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,231 @@
+// Copyright (C) 2012-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2012-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_hist::apply(Mat<uword>& out, const mtGlue<uword,T1,T2,glue_hist>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword dim = in.aux_uword;
+  
+  const unwrap_check_mixed<T1> tmp1(in.A, out);
+  const unwrap_check_mixed<T2> tmp2(in.B, out);
+  
+  const Mat<eT>& X = tmp1.M;
+  const Mat<eT>& C = tmp2.M;
+  
+  
+  arma_debug_check
+    (
+    ((C.is_vec() == false) && (C.is_empty() == false)),
+    "hist(): parameter 'centers' must be a vector"
+    );
+  
+  arma_debug_check
+    (
+    (dim > 1),
+    "hist(): parameter 'dim' must be 0 or 1"
+    );
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  const uword X_n_elem = X.n_elem;
+  
+  const uword C_n_elem = C.n_elem;
+  
+  if( C_n_elem == 0 )
+    {
+    out.reset();
+    return;
+    }
+  
+  // for vectors we are currently ignoring the "dim" parameter
+  
+  uword out_n_rows = 0;
+  uword out_n_cols = 0;
+  
+  if(X.is_vec())
+    {
+    if(X.is_rowvec())
+      {
+      out_n_rows = 1;
+      out_n_cols = C_n_elem;
+      }
+    else
+    if(X.is_colvec())
+      {
+      out_n_rows = C_n_elem;
+      out_n_cols = 1;
+      }
+    }
+  else
+    {
+    if(dim == 0)
+      {
+      out_n_rows = C_n_elem;
+      out_n_cols = X_n_cols;
+      }
+    else
+    if(dim == 1)
+      {
+      out_n_rows = X_n_rows;
+      out_n_cols = C_n_elem;
+      }
+    }
+  
+  out.zeros(out_n_rows, out_n_cols);
+  
+  
+  const eT* C_mem    = C.memptr();
+  const eT  center_0 = C_mem[0];
+  
+  if(X.is_vec())
+    {
+    const eT*    X_mem   = X.memptr();
+          uword* out_mem = out.memptr();
+    
+    for(uword i=0; i < X_n_elem; ++i)
+      {
+      const eT val = X_mem[i];
+      
+      if(is_finite(val))
+        {
+        eT    opt_dist  = (val >= center_0) ? (val - center_0) : (center_0 - val);
+        uword opt_index = 0;
+        
+        for(uword j=1; j < C_n_elem; ++j)
+          {
+          const eT center = C_mem[j];
+          const eT dist   = (val >= center) ? (val - center) : (center - val);
+          
+          if(dist < opt_dist)
+            {
+            opt_dist  = dist;
+            opt_index = j;
+            }
+          else
+            {
+            break;
+            }
+          }
+        
+        out_mem[opt_index]++;
+        }
+      else
+        {
+        // -inf
+        if(val < eT(0)) { out_mem[0]++; }
+        
+        // +inf
+        if(val > eT(0)) { out_mem[C_n_elem-1]++; }
+        
+        // ignore NaN
+        }
+      }
+    }
+  else
+    {
+    if(dim == 0)
+      {
+      for(uword col=0; col < X_n_cols; ++col)
+        {
+        const eT*    X_coldata   = X.colptr(col);
+              uword* out_coldata = out.colptr(col);
+        
+        for(uword row=0; row < X_n_rows; ++row)
+          {
+          const eT val = X_coldata[row];
+          
+          if(arma_isfinite(val))
+            {
+            eT    opt_dist  = (center_0 >= val) ? (center_0 - val) : (val - center_0);
+            uword opt_index = 0;
+            
+            for(uword j=1; j < C_n_elem; ++j)
+              {
+              const eT center = C_mem[j];
+              const eT dist   = (center >= val) ? (center - val) : (val - center);
+              
+              if(dist < opt_dist)
+                {
+                opt_dist  = dist;
+                opt_index = j;
+                }
+              else
+                {
+                break;
+                }
+              }
+            
+            out_coldata[opt_index]++;
+            }
+          else
+            {
+            // -inf
+            if(val < eT(0)) { out_coldata[0]++; }
+            
+            // +inf
+            if(val > eT(0)) { out_coldata[C_n_elem-1]++; }
+            
+            // ignore NaN
+            }
+          }
+        }
+      }
+    else
+    if(dim == 1)
+      {
+      for(uword row=0; row < X_n_rows; ++row)
+        {
+        for(uword col=0; col < X_n_cols; ++col)
+          {
+          const eT val = X.at(row,col);
+          
+          if(arma_isfinite(val))
+            {
+            eT    opt_dist  = (center_0 >= val) ? (center_0 - val) : (val - center_0);
+            uword opt_index = 0;
+            
+            for(uword j=1; j < C_n_elem; ++j)
+              {
+              const eT center = C_mem[j];
+              const eT dist   = (center >= val) ? (center - val) : (val - center);
+              
+              if(dist < opt_dist)
+                {
+                opt_dist  = dist;
+                opt_index = j;
+                }
+              else
+                {
+                break;
+                }
+              }
+            
+            out.at(row,opt_index)++;
+            }
+          else
+            {
+            // -inf
+            if(val < eT(0)) { out.at(row,0)++; }
+            
+            // +inf
+            if(val > eT(0)) { out.at(row,C_n_elem-1)++; }
+            
+            // ignore NaN
+            }
+          }
+        }
+      }
+    }
+  }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_histc_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,16 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// Copyright (C) 2012 Boris Sabanin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+class glue_histc
+   {
+   public:
+
+   template<typename T1, typename T2> inline static void apply(Mat<uword>& out, const mtGlue<uword,T1,T2,glue_histc>& in);
+   };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_histc_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,174 @@
+// Copyright (C) 2012-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2012-2013 Conrad Sanderson
+// Copyright (C) 2012 Boris Sabanin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_histc::apply(Mat<uword>& out, const mtGlue<uword,T1,T2,glue_histc>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword dim = in.aux_uword;
+  
+  const unwrap_check_mixed<T1> tmp1(in.A, out);
+  const unwrap_check_mixed<T2> tmp2(in.B, out);
+  
+  const Mat<eT>& X = tmp1.M;
+  const Mat<eT>& E = tmp2.M;
+  
+  arma_debug_check
+    (
+    ((E.is_vec() == false) && (E.is_empty() == false)),
+    "histc(): parameter 'edges' must be a vector"
+    );
+  
+  arma_debug_check
+    (
+    (dim > 1),
+    "histc(): parameter 'dim' must be 0 or 1"
+    );
+  
+  const uword X_n_elem = X.n_elem;
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  const uword E_n_elem = E.n_elem;
+  
+  if( E_n_elem == 0 )
+    {
+    out.reset();
+    return;
+    }
+  
+  
+  // for vectors we are currently ignoring the "dim" parameter
+  
+  uword out_n_rows = 0;
+  uword out_n_cols = 0;
+  
+  if(X.is_vec())
+    {
+    if(X.is_rowvec())
+      {
+      out_n_rows = 1;
+      out_n_cols = E_n_elem;
+      }
+    else
+    if(X.is_colvec())
+      {
+      out_n_rows = E_n_elem;
+      out_n_cols = 1;
+      }
+    }
+  else
+    {
+    if(dim == 0)
+      {
+      out_n_rows = E_n_elem;
+      out_n_cols = X_n_cols;
+      }
+    else
+    if(dim == 1)
+      {
+      out_n_rows = X_n_rows;
+      out_n_cols = E_n_elem;
+      }
+    }
+  
+  out.zeros(out_n_rows, out_n_cols);
+  
+  const eT* E_mem = E.memptr();
+
+  if(X.is_vec() == true)
+    {
+          uword* out_mem = out.memptr();
+    const eT*    X_mem   = X.memptr();
+    
+    for(uword j=0; j<X_n_elem; ++j)
+      {
+      const eT val = X_mem[j];
+      
+      for(uword i=0; i<E_n_elem-1; ++i)
+        {
+        if( (E_mem[i] <= val) && (val < E_mem[i+1]) )
+          {
+          out_mem[i]++;
+          break;
+          }
+        else
+        if(val == E_mem[E_n_elem-1])
+          {
+          // in general, the above == operation doesn't make sense for floating point values (due to precision issues),
+          // but is included for compatibility with Matlab and Octave.
+          // Matlab folks must have been smoking something strong.
+          out_mem[E_n_elem-1]++;
+          break;
+          }
+        }
+      }
+    }
+  else
+  if(dim == 0)
+    {
+    for(uword col=0; col<X_n_cols; ++col)
+      {
+            uword* out_coldata = out.colptr(col);
+      const eT*    X_coldata   = X.colptr(col);
+      
+      for(uword row=0; row<X_n_rows; ++row)
+        {
+        const eT val = X_coldata[row];
+        
+        for(uword i=0; i<E_n_elem-1; ++i)
+          {
+          if( (E_mem[i] <= val) && (val < E_mem[i+1]) )
+            {
+            out_coldata[i]++;
+            break;
+            }
+          else
+          if(val == E_mem[E_n_elem-1])
+            {
+            out_coldata[E_n_elem-1]++;
+            break;
+            }
+          }
+        }
+      }
+    }
+  else
+  if(dim == 1)
+    {
+    for(uword row=0; row<X_n_rows; ++row)
+      {
+      for(uword col=0; col<X_n_cols; ++col)
+        {
+        const eT val = X.at(row,col);
+        
+        for(uword i=0; i<E_n_elem-1; ++i)
+          {
+          if( (E_mem[i] <= val) && (val < E_mem[i+1]) )
+            {
+            out.at(row,i)++;
+            break;
+            }
+          else
+          if(val == E_mem[E_n_elem-1])
+            {
+            out.at(row,E_n_elem-1)++;
+            break;
+            }
+          }
+        }
+      }
+    }
+  }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_join_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,29 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup glue_join
+//! @{
+
+
+
+class glue_join
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_join>& X);
+  
+  template<typename T1, typename T2>
+  inline static void apply(Cube<typename T1::elem_type>& out, const GlueCube<T1,T2,glue_join>& X);
+  };
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_join_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,190 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup glue_join
+//! @{
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_join::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_join>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+
+  const unwrap<T1> A_tmp(X.A);
+  const unwrap<T2> B_tmp(X.B);
+  
+  const Mat<eT>& A = A_tmp.M;
+  const Mat<eT>& B = B_tmp.M;
+  
+  const uword A_n_rows = A.n_rows;
+  const uword A_n_cols = A.n_cols;
+  
+  const uword B_n_rows = B.n_rows;
+  const uword B_n_cols = B.n_cols;
+  
+  const uword join_type = X.aux_uword;
+  
+  if(join_type == 0)
+    {
+    arma_debug_check
+      (
+      ( (A_n_cols != B_n_cols) && ( (A_n_rows > 0) || (A_n_cols > 0) ) && ( (B_n_rows > 0) || (B_n_cols > 0) ) ),
+      "join_cols(): number of columns must be the same"
+      );
+    }
+  else
+    {
+    arma_debug_check
+      (
+      ( (A_n_rows != B.n_rows) && ( (A_n_rows > 0) || (A_n_cols > 0) ) && ( (B_n_rows > 0) || (B_n_cols > 0) ) ),
+      "join_rows(): number of rows must be the same"
+      );
+    }
+  
+  
+  if( (&out != &A) && (&out != &B) )
+    {
+    if(join_type == 0)   // join columns (i.e. result matrix has more rows)
+      {
+      out.set_size( A_n_rows + B_n_rows, (std::max)(A_n_cols, B_n_cols) );
+      
+      if( out.n_elem > 0 )
+        {
+        if(A.is_empty() == false)
+          { 
+          out.submat(0,        0,   A_n_rows-1, out.n_cols-1) = A;
+          }
+          
+        if(B.is_empty() == false)
+          {
+          out.submat(A_n_rows, 0, out.n_rows-1, out.n_cols-1) = B;
+          }
+        }
+      }
+    else   // join rows  (i.e. result matrix has more columns)
+      {
+      out.set_size( (std::max)(A_n_rows, B_n_rows), A_n_cols + B_n_cols );
+      
+      if( out.n_elem > 0 )
+        {
+        if(A.is_empty() == false)
+          {
+          out.submat(0, 0,        out.n_rows-1,   A.n_cols-1) = A;
+          }
+        
+        if(B.is_empty() == false)
+          {
+          out.submat(0, A_n_cols, out.n_rows-1, out.n_cols-1) = B;
+          }
+        }
+      }
+    }
+  else  // we have aliasing
+    {
+    Mat<eT> C;
+    
+    if(join_type == 0)
+      {
+      C.set_size( A_n_rows + B_n_rows, (std::max)(A_n_cols, B_n_cols) );
+      
+      if( C.n_elem > 0 )
+        {
+        if(A.is_empty() == false)
+          {
+          C.submat(0,        0, A_n_rows-1, C.n_cols-1) = A;
+          }
+        
+        if(B.is_empty() == false)
+          {
+          C.submat(A_n_rows, 0, C.n_rows-1, C.n_cols-1) = B;
+          }
+        }
+      }
+    else
+      {
+      C.set_size( (std::max)(A_n_rows, B_n_rows), A_n_cols + B_n_cols );
+      
+      if( C.n_elem > 0 )
+        {
+        if(A.is_empty() == false)
+          {
+          C.submat(0, 0,        C.n_rows-1, A_n_cols-1) = A;
+          }
+        
+        if(B.is_empty() == false)
+          {
+          C.submat(0, A_n_cols, C.n_rows-1, C.n_cols-1) = B;
+          }
+        }
+      }
+    
+    out.steal_mem(C);
+    }
+  
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_join::apply(Cube<typename T1::elem_type>& out, const GlueCube<T1,T2,glue_join>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+
+  const unwrap_cube<T1> A_tmp(X.A);
+  const unwrap_cube<T2> B_tmp(X.B);
+  
+  const Cube<eT>& A = A_tmp.M;
+  const Cube<eT>& B = B_tmp.M;
+  
+  if(A.n_elem == 0)
+    {
+    out = B;
+    return;
+    }
+  
+  if(B.n_elem == 0)
+    {
+    out = A;
+    return;
+    }
+  
+  
+  arma_debug_check( ( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) ), "join_slices(): size of slices must be the same" );
+  
+  
+  if( (&out != &A) && (&out != &B) )
+    {
+    out.set_size(A.n_rows, A.n_cols, A.n_slices + B.n_slices);
+    
+    out.slices(0,          A.n_slices-1  ) = A;
+    out.slices(A.n_slices, out.n_slices-1) = B;
+    }
+  else  // we have aliasing
+    {
+    Cube<eT> C(A.n_rows, A.n_cols, A.n_slices + B.n_slices);
+    
+    C.slices(0,          A.n_slices-1) = A;
+    C.slices(A.n_slices, C.n_slices-1) = B;
+    
+    out.steal_mem(C);
+    }
+  
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_kron_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,30 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup glue_kron
+//! @{
+
+
+
+class glue_kron
+  {
+  public:
+
+  template<typename eT> inline static void direct_kron(Mat<eT>&                out, const Mat<eT>&                A, const Mat<eT>&                B);
+  template<typename T>  inline static void direct_kron(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat<T>&                 B);
+  template<typename T>  inline static void direct_kron(Mat< std::complex<T> >& out, const Mat<T>&                 A, const Mat< std::complex<T> >& B);
+  
+  template<typename T1, typename T2>   inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_kron>& X);
+  };
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_kron_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,124 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup glue_kron
+//! @{
+
+
+
+//! \brief
+//! both input matrices have the same element type
+template<typename eT>
+inline
+void
+glue_kron::direct_kron(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword A_rows = A.n_rows;
+  const uword A_cols = A.n_cols;
+  const uword B_rows = B.n_rows;
+  const uword B_cols = B.n_cols;
+  
+  out.set_size(A_rows*B_rows, A_cols*B_cols);
+  
+  for(uword i = 0; i < A_rows; i++)
+    {
+    for(uword j = 0; j < A_cols; j++)
+      {
+      out.submat(i*B_rows, j*B_cols, (i+1)*B_rows-1, (j+1)*B_cols-1) = A(i,j) * B; 
+      }
+    }  
+  }
+
+
+
+//! \brief
+//! different types of input matrices
+//! A -> complex, B -> basic element type
+template<typename T>
+inline
+void
+glue_kron::direct_kron(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat<T>& B)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<T> eT;
+  
+  const uword A_rows = A.n_rows;
+  const uword A_cols = A.n_cols;
+  const uword B_rows = B.n_rows;
+  const uword B_cols = B.n_cols;
+  
+  out.set_size(A_rows*B_rows, A_cols*B_cols);
+  
+  Mat<eT> tmp_B = conv_to< Mat<eT> >::from(B);
+  
+  for(uword i = 0; i < A_rows; i++)
+    {
+    for(uword j = 0; j < A_cols; j++)
+      {
+      out.submat(i*B_rows, j*B_cols, (i+1)*B_rows-1, (j+1)*B_cols-1) = A(i,j) * tmp_B; 
+      }
+    }  
+  }
+
+
+
+//! \brief
+//! different types of input matrices
+//! A -> basic element type, B -> complex
+template<typename T>
+inline
+void
+glue_kron::direct_kron(Mat< std::complex<T> >& out, const Mat<T>& A, const Mat< std::complex<T> >& B)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword A_rows = A.n_rows;
+  const uword A_cols = A.n_cols;
+  const uword B_rows = B.n_rows;
+  const uword B_cols = B.n_cols;
+  
+  out.set_size(A_rows*B_rows, A_cols*B_cols);
+  
+  for(uword i = 0; i < A_rows; i++)
+    {
+    for(uword j = 0; j < A_cols; j++)
+      {
+      out.submat(i*B_rows, j*B_cols, (i+1)*B_rows-1, (j+1)*B_cols-1) = A(i,j) * B; 
+      }
+    }  
+  }
+
+
+
+//! \brief
+//! apply Kronecker product for two objects with same element type
+template<typename T1, typename T2>
+inline
+void
+glue_kron::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_kron>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> A_tmp(X.A, out);
+  const unwrap_check<T2> B_tmp(X.B, out);
+  
+  const Mat<eT>& A = A_tmp.M;
+  const Mat<eT>& B = B_tmp.M;
+  
+  glue_kron::direct_kron(out, A, B); 
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_mixed_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,76 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup glue_mixed
+//! @{
+
+
+
+class glue_mixed_times
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_times>& X);
+  };
+
+
+
+class glue_mixed_plus
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_plus>& X);
+  
+  template<typename T1, typename T2>
+  inline static void apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_plus>& X);
+  };
+
+
+
+class glue_mixed_minus
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_minus>& X);
+  
+  template<typename T1, typename T2>
+  inline static void apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_minus>& X);
+  };
+
+
+
+class glue_mixed_div
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_div>& X);
+  
+  template<typename T1, typename T2>
+  inline static void apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_div>& X);
+  };
+
+
+
+class glue_mixed_schur
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_schur>& X);
+  
+  template<typename T1, typename T2>
+  inline static void apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_schur>& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_mixed_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,542 @@
+// Copyright (C) 2009-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup glue_mixed
+//! @{
+
+
+
+//! matrix multiplication with different element types
+template<typename T1, typename T2>
+inline
+void
+glue_mixed_times::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_times>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  const unwrap_check_mixed<T1> tmp1(X.A, out);
+  const unwrap_check_mixed<T2> tmp2(X.B, out);
+  
+  const Mat<eT1>& A = tmp1.M;
+  const Mat<eT2>& B = tmp2.M;
+  
+  arma_debug_assert_mul_size(A, B, "matrix multiplication");
+  
+  out.set_size(A.n_rows, B.n_cols);
+  
+  gemm_mixed<>::apply(out, A, B);
+  }
+
+
+
+//! matrix addition with different element types
+template<typename T1, typename T2>
+inline
+void
+glue_mixed_plus::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_plus>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  const Proxy<T1> A(X.A);
+  const Proxy<T2> B(X.B);
+  
+  arma_debug_assert_same_size(A, B, "addition");
+  
+  const uword n_rows = A.get_n_rows();
+  const uword n_cols = A.get_n_cols();
+  
+  out.set_size(n_rows, n_cols);
+  
+        out_eT* out_mem = out.memptr();
+  const uword   n_elem  = out.n_elem;
+    
+  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type AA = A.get_ea();
+    typename Proxy<T2>::ea_type BB = B.get_ea();
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      for(uword i=0; i<n_elem; ++i)
+        {
+        out_mem[i] = upgrade_val<eT1,eT2>::apply(AA[i]) + upgrade_val<eT1,eT2>::apply(BB[i]);
+        }
+      }
+    else
+      {
+      for(uword i=0; i<n_elem; ++i)
+        {
+        out_mem[i] = upgrade_val<eT1,eT2>::apply(AA[i]) + upgrade_val<eT1,eT2>::apply(BB[i]);
+        }
+      }
+    }
+  else
+    {
+    uword i = 0;
+    
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      out_mem[i] = upgrade_val<eT1,eT2>::apply(A.at(row,col)) + upgrade_val<eT1,eT2>::apply(B.at(row,col));
+      ++i;
+      }
+    }
+  }
+
+
+
+//! matrix subtraction with different element types
+template<typename T1, typename T2>
+inline
+void
+glue_mixed_minus::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_minus>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  const Proxy<T1> A(X.A);
+  const Proxy<T2> B(X.B);
+  
+  arma_debug_assert_same_size(A, B, "subtraction");
+  
+  const uword n_rows = A.get_n_rows();
+  const uword n_cols = A.get_n_cols();
+  
+  out.set_size(n_rows, n_cols);
+  
+        out_eT* out_mem = out.memptr();
+  const uword   n_elem  = out.n_elem;
+    
+  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type AA = A.get_ea();
+    typename Proxy<T2>::ea_type BB = B.get_ea();
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      for(uword i=0; i<n_elem; ++i)
+        {
+        out_mem[i] = upgrade_val<eT1,eT2>::apply(AA[i]) - upgrade_val<eT1,eT2>::apply(BB[i]);
+        }
+      }
+    else
+      {
+      for(uword i=0; i<n_elem; ++i)
+        {
+        out_mem[i] = upgrade_val<eT1,eT2>::apply(AA[i]) - upgrade_val<eT1,eT2>::apply(BB[i]);
+        }
+      }
+    }
+  else
+    {
+    uword i = 0;
+    
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      out_mem[i] = upgrade_val<eT1,eT2>::apply(A.at(row,col)) - upgrade_val<eT1,eT2>::apply(B.at(row,col));
+      ++i;
+      }
+    }
+  }
+
+
+
+//! element-wise matrix division with different element types
+template<typename T1, typename T2>
+inline
+void
+glue_mixed_div::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_div>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  const Proxy<T1> A(X.A);
+  const Proxy<T2> B(X.B);
+  
+  arma_debug_assert_same_size(A, B, "element-wise division");
+  
+  const uword n_rows = A.get_n_rows();
+  const uword n_cols = A.get_n_cols();
+  
+  out.set_size(n_rows, n_cols);
+  
+        out_eT* out_mem = out.memptr();
+  const uword   n_elem  = out.n_elem;
+    
+  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type AA = A.get_ea();
+    typename Proxy<T2>::ea_type BB = B.get_ea();
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      for(uword i=0; i<n_elem; ++i)
+        {
+        out_mem[i] = upgrade_val<eT1,eT2>::apply(AA[i]) / upgrade_val<eT1,eT2>::apply(BB[i]);
+        }
+      }
+    else
+      {
+      for(uword i=0; i<n_elem; ++i)
+        {
+        out_mem[i] = upgrade_val<eT1,eT2>::apply(AA[i]) / upgrade_val<eT1,eT2>::apply(BB[i]);
+        }
+      }
+    }
+  else
+    {
+    uword i = 0;
+    
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      out_mem[i] = upgrade_val<eT1,eT2>::apply(A.at(row,col)) / upgrade_val<eT1,eT2>::apply(B.at(row,col));
+      ++i;
+      }
+    }
+  }
+
+
+
+//! element-wise matrix multiplication with different element types
+template<typename T1, typename T2>
+inline
+void
+glue_mixed_schur::apply(Mat<typename eT_promoter<T1,T2>::eT>& out, const mtGlue<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_schur>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  const Proxy<T1> A(X.A);
+  const Proxy<T2> B(X.B);
+  
+  arma_debug_assert_same_size(A, B, "element-wise multiplication");
+  
+  const uword n_rows = A.get_n_rows();
+  const uword n_cols = A.get_n_cols();
+  
+  out.set_size(n_rows, n_cols);
+  
+        out_eT* out_mem = out.memptr();
+  const uword   n_elem  = out.n_elem;
+    
+  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type AA = A.get_ea();
+    typename Proxy<T2>::ea_type BB = B.get_ea();
+    
+    if(memory::is_aligned(out_mem))
+      {
+      memory::mark_as_aligned(out_mem);
+      
+      for(uword i=0; i<n_elem; ++i)
+        {
+        out_mem[i] = upgrade_val<eT1,eT2>::apply(AA[i]) * upgrade_val<eT1,eT2>::apply(BB[i]);
+        }
+      }
+    else
+      {
+      for(uword i=0; i<n_elem; ++i)
+        {
+        out_mem[i] = upgrade_val<eT1,eT2>::apply(AA[i]) * upgrade_val<eT1,eT2>::apply(BB[i]);
+        }
+      }
+    }
+  else
+    {
+    uword i = 0;
+    
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      out_mem[i] = upgrade_val<eT1,eT2>::apply(A.at(row,col)) * upgrade_val<eT1,eT2>::apply(B.at(row,col));
+      ++i;
+      }
+    }
+  }
+
+
+
+//
+//
+//
+
+
+
+//! cube addition with different element types
+template<typename T1, typename T2>
+inline
+void
+glue_mixed_plus::apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_plus>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  const ProxyCube<T1> A(X.A);
+  const ProxyCube<T2> B(X.B);
+  
+  arma_debug_assert_same_size(A, B, "addition");
+  
+  const uword n_rows   = A.get_n_rows();
+  const uword n_cols   = A.get_n_cols();
+  const uword n_slices = A.get_n_slices();
+
+  out.set_size(n_rows, n_cols, n_slices);
+  
+        out_eT* out_mem = out.memptr();
+  const uword    n_elem = out.n_elem;
+  
+  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    typename ProxyCube<T1>::ea_type AA = A.get_ea();
+    typename ProxyCube<T2>::ea_type BB = B.get_ea();
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      out_mem[i] = upgrade_val<eT1,eT2>::apply(AA[i]) + upgrade_val<eT1,eT2>::apply(BB[i]);
+      }
+    }
+  else
+    {
+    uword i = 0;
+    
+    for(uword slice = 0; slice < n_slices; ++slice)
+    for(uword col   = 0; col   < n_cols;   ++col  )
+    for(uword row   = 0; row   < n_rows;   ++row  )
+      {
+      out_mem[i] = upgrade_val<eT1,eT2>::apply(A.at(row,col,slice)) + upgrade_val<eT1,eT2>::apply(B.at(row,col,slice));
+      ++i;
+      }
+    }
+  }
+
+
+
+//! cube subtraction with different element types
+template<typename T1, typename T2>
+inline
+void
+glue_mixed_minus::apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_minus>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  const ProxyCube<T1> A(X.A);
+  const ProxyCube<T2> B(X.B);
+  
+  arma_debug_assert_same_size(A, B, "subtraction");
+  
+  const uword n_rows   = A.get_n_rows();
+  const uword n_cols   = A.get_n_cols();
+  const uword n_slices = A.get_n_slices();
+
+  out.set_size(n_rows, n_cols, n_slices);
+  
+        out_eT* out_mem = out.memptr();
+  const uword    n_elem = out.n_elem;
+  
+  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    typename ProxyCube<T1>::ea_type AA = A.get_ea();
+    typename ProxyCube<T2>::ea_type BB = B.get_ea();
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      out_mem[i] = upgrade_val<eT1,eT2>::apply(AA[i]) - upgrade_val<eT1,eT2>::apply(BB[i]);
+      }
+    }
+  else
+    {
+    uword i = 0;
+    
+    for(uword slice = 0; slice < n_slices; ++slice)
+    for(uword col   = 0; col   < n_cols;   ++col  )
+    for(uword row   = 0; row   < n_rows;   ++row  )
+      {
+      out_mem[i] = upgrade_val<eT1,eT2>::apply(A.at(row,col,slice)) - upgrade_val<eT1,eT2>::apply(B.at(row,col,slice));
+      ++i;
+      }
+    }
+  }
+
+
+
+//! element-wise cube division with different element types
+template<typename T1, typename T2>
+inline
+void
+glue_mixed_div::apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_div>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  const ProxyCube<T1> A(X.A);
+  const ProxyCube<T2> B(X.B);
+  
+  arma_debug_assert_same_size(A, B, "element-wise division");
+  
+  const uword n_rows   = A.get_n_rows();
+  const uword n_cols   = A.get_n_cols();
+  const uword n_slices = A.get_n_slices();
+
+  out.set_size(n_rows, n_cols, n_slices);
+  
+        out_eT* out_mem = out.memptr();
+  const uword    n_elem = out.n_elem;
+  
+  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    typename ProxyCube<T1>::ea_type AA = A.get_ea();
+    typename ProxyCube<T2>::ea_type BB = B.get_ea();
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      out_mem[i] = upgrade_val<eT1,eT2>::apply(AA[i]) / upgrade_val<eT1,eT2>::apply(BB[i]);
+      }
+    }
+  else
+    {
+    uword i = 0;
+    
+    for(uword slice = 0; slice < n_slices; ++slice)
+    for(uword col   = 0; col   < n_cols;   ++col  )
+    for(uword row   = 0; row   < n_rows;   ++row  )
+      {
+      out_mem[i] = upgrade_val<eT1,eT2>::apply(A.at(row,col,slice)) / upgrade_val<eT1,eT2>::apply(B.at(row,col,slice));
+      ++i;
+      }
+    }
+  }
+
+
+
+//! element-wise cube multiplication with different element types
+template<typename T1, typename T2>
+inline
+void
+glue_mixed_schur::apply(Cube<typename eT_promoter<T1,T2>::eT>& out, const mtGlueCube<typename eT_promoter<T1,T2>::eT, T1, T2, glue_mixed_schur>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  const ProxyCube<T1> A(X.A);
+  const ProxyCube<T2> B(X.B);
+  
+  arma_debug_assert_same_size(A, B, "element-wise multiplication");
+  
+  const uword n_rows   = A.get_n_rows();
+  const uword n_cols   = A.get_n_cols();
+  const uword n_slices = A.get_n_slices();
+
+  out.set_size(n_rows, n_cols, n_slices);
+  
+        out_eT* out_mem = out.memptr();
+  const uword    n_elem = out.n_elem;
+  
+  const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    typename ProxyCube<T1>::ea_type AA = A.get_ea();
+    typename ProxyCube<T2>::ea_type BB = B.get_ea();
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      out_mem[i] = upgrade_val<eT1,eT2>::apply(AA[i]) * upgrade_val<eT1,eT2>::apply(BB[i]);
+      }
+    }
+  else
+    {
+    uword i = 0;
+    
+    for(uword slice = 0; slice < n_slices; ++slice)
+    for(uword col   = 0; col   < n_cols;   ++col  )
+    for(uword row   = 0; row   < n_rows;   ++row  )
+      {
+      out_mem[i] = upgrade_val<eT1,eT2>::apply(A.at(row,col,slice)) * upgrade_val<eT1,eT2>::apply(B.at(row,col,slice));
+      ++i;
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_relational_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,92 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup glue_relational
+//! @{
+
+
+
+class glue_rel_lt
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(Mat <uword>& out, const mtGlue<uword, T1, T2, glue_rel_lt>& X);
+  
+  template<typename T1, typename T2>
+  inline static void apply(Cube <uword>& out, const mtGlueCube<uword, T1, T2, glue_rel_lt>& X);
+  };
+
+
+
+class glue_rel_gt
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(Mat <uword>& out, const mtGlue<uword, T1, T2, glue_rel_gt>& X);
+  
+  template<typename T1, typename T2>
+  inline static void apply(Cube <uword>& out, const mtGlueCube<uword, T1, T2, glue_rel_gt>& X);
+  };
+
+
+
+class glue_rel_lteq
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(Mat <uword>& out, const mtGlue<uword, T1, T2, glue_rel_lteq>& X);
+  
+  template<typename T1, typename T2>
+  inline static void apply(Cube <uword>& out, const mtGlueCube<uword, T1, T2, glue_rel_lteq>& X);
+  };
+
+
+
+class glue_rel_gteq
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(Mat <uword>& out, const mtGlue<uword, T1, T2, glue_rel_gteq>& X);
+  
+  template<typename T1, typename T2>
+  inline static void apply(Cube <uword>& out, const mtGlueCube<uword, T1, T2, glue_rel_gteq>& X);
+  };
+
+
+
+class glue_rel_eq
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(Mat <uword>& out, const mtGlue<uword, T1, T2, glue_rel_eq>& X);
+  
+  template<typename T1, typename T2>
+  inline static void apply(Cube <uword>& out, const mtGlueCube<uword, T1, T2, glue_rel_eq>& X);
+  };
+
+
+
+class glue_rel_noteq
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(Mat <uword>& out, const mtGlue<uword, T1, T2, glue_rel_noteq>& X);
+  
+  template<typename T1, typename T2>
+  inline static void apply(Cube <uword>& out, const mtGlueCube<uword, T1, T2, glue_rel_noteq>& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_relational_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,345 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup glue_relational
+//! @{
+
+
+
+#undef operator_rel
+#undef operator_str
+
+#undef arma_applier_mat
+#undef arma_applier_cube
+
+
+#define arma_applier_mat(operator_rel, operator_str) \
+  {\
+  const Proxy<T1> P1(X.A);\
+  const Proxy<T2> P2(X.B);\
+  \
+  arma_debug_assert_same_size(P1, P2, operator_str);\
+  \
+  const bool bad_alias = (Proxy<T1>::has_subview && P1.is_alias(out)) || (Proxy<T2>::has_subview && P2.is_alias(out));\
+  \
+  if(bad_alias == false)\
+    {\
+    \
+    const uword n_rows = P1.get_n_rows();\
+    const uword n_cols = P1.get_n_cols();\
+    \
+    out.set_size(n_rows, n_cols);\
+    \
+    uword* out_mem = out.memptr();\
+    \
+    const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor);\
+    \
+    if(prefer_at_accessor == false)\
+      {\
+      typename Proxy<T1>::ea_type A = P1.get_ea();\
+      typename Proxy<T2>::ea_type B = P2.get_ea();\
+      \
+      const uword n_elem = out.n_elem;\
+      \
+      for(uword i=0; i<n_elem; ++i)\
+        {\
+        out_mem[i] = (A[i] operator_rel B[i]) ? uword(1) : uword(0);\
+        }\
+      }\
+    else\
+      {\
+      if(n_rows == 1)\
+        {\
+        for(uword count=0; count < n_cols; ++count)\
+          {\
+          out_mem[count] = (P1.at(0,count) operator_rel P2.at(0,count)) ? uword(1) : uword(0);\
+          }\
+        }\
+      else\
+        {\
+        for(uword col=0; col<n_cols; ++col)\
+        for(uword row=0; row<n_rows; ++row)\
+          {\
+          *out_mem = (P1.at(row,col) operator_rel P2.at(row,col)) ? uword(1) : uword(0);\
+          out_mem++;\
+          }\
+        }\
+      }\
+    }\
+  else\
+    {\
+    const unwrap_check<typename Proxy<T1>::stored_type> tmp1(P1.Q, P1.is_alias(out));\
+    const unwrap_check<typename Proxy<T2>::stored_type> tmp2(P2.Q, P2.is_alias(out));\
+    \
+    out = (tmp1.M) operator_rel (tmp2.M);\
+    }\
+  }
+
+
+
+
+#define arma_applier_cube(operator_rel, operator_str) \
+  {\
+  const ProxyCube<T1> P1(X.A);\
+  const ProxyCube<T2> P2(X.B);\
+  \
+  arma_debug_assert_same_size(P1, P2, operator_str);\
+  \
+  const bool bad_alias = (ProxyCube<T1>::has_subview && P1.is_alias(out)) || (ProxyCube<T2>::has_subview && P2.is_alias(out));\
+  \
+  if(bad_alias == false)\
+    {\
+    \
+    const uword n_rows   = P1.get_n_rows();\
+    const uword n_cols   = P1.get_n_cols();\
+    const uword n_slices = P1.get_n_slices();\
+    \
+    out.set_size(n_rows, n_cols, n_slices);\
+    \
+    uword* out_mem = out.memptr();\
+    \
+    const bool prefer_at_accessor = (ProxyCube<T1>::prefer_at_accessor || ProxyCube<T2>::prefer_at_accessor);\
+    \
+    if(prefer_at_accessor == false)\
+      {\
+      typename ProxyCube<T1>::ea_type A = P1.get_ea();\
+      typename ProxyCube<T2>::ea_type B = P2.get_ea();\
+      \
+      const uword n_elem = out.n_elem;\
+      \
+      for(uword i=0; i<n_elem; ++i)\
+        {\
+        out_mem[i] = (A[i] operator_rel B[i]) ? uword(1) : uword(0);\
+        }\
+      }\
+    else\
+      {\
+      for(uword slice = 0; slice < n_slices; ++slice)\
+      for(uword col   = 0; col   < n_cols;   ++col  )\
+      for(uword row   = 0; row   < n_rows;   ++row  )\
+        {\
+        *out_mem = (P1.at(row,col,slice) operator_rel P2.at(row,col,slice)) ? uword(1) : uword(0);\
+        out_mem++;\
+        }\
+      }\
+    }\
+  else\
+    {\
+    const unwrap_cube<typename ProxyCube<T1>::stored_type> tmp1(P1.Q);\
+    const unwrap_cube<typename ProxyCube<T2>::stored_type> tmp2(P2.Q);\
+    \
+    out = (tmp1.M) operator_rel (tmp2.M);\
+    }\
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_rel_lt::apply
+  (
+        Mat   <uword>& out,
+  const mtGlue<uword, T1, T2, glue_rel_lt>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat(<, "operator<");
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_rel_gt::apply
+  (
+        Mat   <uword>& out,
+  const mtGlue<uword, T1, T2, glue_rel_gt>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat(>, "operator>");
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_rel_lteq::apply
+  (
+        Mat   <uword>& out,
+  const mtGlue<uword, T1, T2, glue_rel_lteq>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat(<=, "operator<=");
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_rel_gteq::apply
+  (
+        Mat   <uword>& out,
+  const mtGlue<uword, T1, T2, glue_rel_gteq>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat(>=, "operator>=");
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_rel_eq::apply
+  (
+        Mat   <uword>& out,
+  const mtGlue<uword, T1, T2, glue_rel_eq>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat(==, "operator==");
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_rel_noteq::apply
+  (
+        Mat   <uword>& out,
+  const mtGlue<uword, T1, T2, glue_rel_noteq>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat(!=, "operator!=");
+  }
+
+
+
+//
+//
+//
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_rel_lt::apply
+  (
+        Cube      <uword>& out,
+  const mtGlueCube<uword, T1, T2, glue_rel_lt>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube(<, "operator<");
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_rel_gt::apply
+  (
+        Cube      <uword>& out,
+  const mtGlueCube<uword, T1, T2, glue_rel_gt>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube(>, "operator>");
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_rel_lteq::apply
+  (
+        Cube      <uword>& out,
+  const mtGlueCube<uword, T1, T2, glue_rel_lteq>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube(<=, "operator<=");
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_rel_gteq::apply
+  (
+        Cube      <uword>& out,
+  const mtGlueCube<uword, T1, T2, glue_rel_gteq>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube(>=, "operator>=");
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_rel_eq::apply
+  (
+        Cube      <uword>& out,
+  const mtGlueCube<uword, T1, T2, glue_rel_eq>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube(==, "operator==");
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_rel_noteq::apply
+  (
+        Cube      <uword>& out,
+  const mtGlueCube<uword, T1, T2, glue_rel_noteq>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube(!=, "operator!=");
+  }
+
+
+
+#undef arma_applier_mat
+#undef arma_applier_cube
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_solve_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,35 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup glue_solve
+//! @{
+
+
+
+class glue_solve
+  {
+  public:
+  
+  template<typename eT, typename T2> inline static void solve_direct(Mat<eT>& out, Mat<eT>& A, const Base<eT,T2>& X, const bool slow);
+  
+  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_solve>& X);
+  };
+
+
+
+class glue_solve_tr
+  {
+  public:
+  
+  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_solve_tr>& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_solve_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,102 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup glue_solve
+//! @{
+
+
+
+template<typename eT, typename T2>
+inline
+void
+glue_solve::solve_direct(Mat<eT>& out, Mat<eT>& A, const Base<eT,T2>& X, const bool slow)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword A_n_rows = A.n_rows;
+  const uword A_n_cols = A.n_cols;
+  
+  bool status = false;
+  
+  if(A_n_rows == A_n_cols)
+    {
+    status = auxlib::solve(out, A, X, slow);
+    }
+  else
+  if(A_n_rows > A_n_cols)
+    {
+    arma_extra_debug_print("solve(): detected over-determined system");
+    status = auxlib::solve_od(out, A, X);
+    }
+  else
+    {
+    arma_extra_debug_print("solve(): detected under-determined system");
+    status = auxlib::solve_ud(out, A, X);
+    }
+  
+  if(status == false)
+    {
+    out.reset();
+    arma_bad("solve(): solution not found");
+    }
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_solve::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_solve>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  Mat<eT> A = X.A.get_ref();
+  
+  glue_solve::solve_direct( out, A, X.B, (X.aux_uword == 1) );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_solve_tr::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_solve_tr>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> A_tmp(X.A, out);
+  const unwrap_check<T2> B_tmp(X.B, out);
+  
+  const Mat<eT>& A = A_tmp.M;
+  const Mat<eT>& B = B_tmp.M;
+  
+  bool  err_state = false;
+  char* err_msg   = 0;
+  
+  arma_debug_set_error( err_state, err_msg, ((&A) == (&B)),           "solve(): A is an alias of B" );
+  arma_debug_set_error( err_state, err_msg, (A.n_rows != B.n_rows),   "solve(): number of rows in A and B must be the same" );
+  arma_debug_set_error( err_state, err_msg, (A.is_square() == false), "solve(): A is not a square matrix" );
+  
+  arma_debug_check(err_state, err_msg);
+  
+  const bool status = auxlib::solve_tr(out, A, B, X.aux_uword);
+  
+  if(status == false)
+    {
+    out.reset();
+    arma_bad("solve(): solution not found");
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_times_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,131 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup glue_times
+//! @{
+
+
+
+//! \brief
+//! Template metaprogram depth_lhs
+//! calculates the number of Glue<Tx,Ty, glue_type> instances on the left hand side argument of Glue<Tx,Ty, glue_type>
+//! i.e. it recursively expands each Tx, until the type of Tx is not "Glue<..,.., glue_type>"  (i.e the "glue_type" changes)
+
+template<typename glue_type, typename T1>
+struct depth_lhs
+  {
+  static const uword num = 0;
+  };
+
+template<typename glue_type, typename T1, typename T2>
+struct depth_lhs< glue_type, Glue<T1,T2,glue_type> >
+  {
+  static const uword num = 1 + depth_lhs<glue_type, T1>::num;
+  };
+
+
+
+template<bool is_eT_blas_type>
+struct glue_times_redirect2_helper
+  {
+  template<typename T1, typename T2>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X);
+  };
+
+
+template<>
+struct glue_times_redirect2_helper<true>
+  {
+  template<typename T1, typename T2>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X);
+  };
+
+
+
+template<uword N>
+struct glue_times_redirect
+  {
+  template<typename T1, typename T2>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X);
+  };
+
+
+template<>
+struct glue_times_redirect<2>
+  {
+  template<typename T1, typename T2>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X);
+  };
+
+
+template<>
+struct glue_times_redirect<3>
+  {
+  template<typename T1, typename T2, typename T3>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>,T3,glue_times>& X);
+  };
+
+
+template<>
+struct glue_times_redirect<4>
+  {
+  template<typename T1, typename T2, typename T3, typename T4>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue< Glue< Glue<T1,T2,glue_times>, T3, glue_times>, T4, glue_times>& X);
+  };
+
+
+
+//! Class which implements the immediate multiplication of two or more matrices
+class glue_times
+  {
+  public:
+  
+  
+  template<typename T1, typename T2>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X);
+  
+  
+  template<typename T1>
+  arma_hot inline static void apply_inplace(Mat<typename T1::elem_type>& out, const T1& X);
+  
+  template<typename T1, typename T2>
+  arma_hot inline static void apply_inplace_plus(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_times>& X, const sword sign);
+  
+  template<typename eT1, typename eT2>
+  inline static void apply_mixed(Mat<typename promote_type<eT1,eT2>::result>& out, const Mat<eT1>& X, const Mat<eT2>& Y);
+  
+  //
+  
+  template<typename eT, const bool do_trans_A, const bool do_trans_B, typename TA, typename TB>
+  arma_inline static uword mul_storage_cost(const TA& A, const TB& B);
+  
+  template<typename eT, const bool do_trans_A, const bool do_trans_B, const bool do_scalar_times, typename TA, typename TB>
+  arma_hot inline static void apply(Mat<eT>& out, const TA& A, const TB& B, const eT val);
+  
+  template<typename eT, const bool do_trans_A, const bool do_trans_B, const bool do_trans_C, const bool do_scalar_times, typename TA, typename TB, typename TC>
+  arma_hot inline static void apply(Mat<eT>& out, const TA& A, const TB& B, const TC& C, const eT val);
+  
+  template<typename eT, const bool do_trans_A, const bool do_trans_B, const bool do_trans_C, const bool do_trans_D, const bool do_scalar_times, typename TA, typename TB, typename TC, typename TD>
+  arma_hot inline static void apply(Mat<eT>& out, const TA& A, const TB& B, const TC& C, const TD& D, const eT val);
+  };
+
+
+
+class glue_times_diag
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_times_diag>& X);
+  
+  };
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_times_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,873 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup glue_times
+//! @{
+
+
+
+template<bool is_eT_blas_type>
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+glue_times_redirect2_helper<is_eT_blas_type>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const partial_unwrap_check<T1> tmp1(X.A, out);
+  const partial_unwrap_check<T2> tmp2(X.B, out);
+  
+  const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M;
+  const typename partial_unwrap_check<T2>::stored_type& B = tmp2.M;
+  
+  const bool use_alpha = partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times;
+  const eT       alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val()) : eT(0);
+  
+  glue_times::apply
+    <
+    eT,
+    partial_unwrap_check<T1>::do_trans,
+    partial_unwrap_check<T2>::do_trans,
+    (partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times)
+    >
+    (out, A, B, alpha);
+  }
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+glue_times_redirect2_helper<true>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  if(strip_inv<T1>::do_inv == false)
+    {
+    const partial_unwrap_check<T1> tmp1(X.A, out);
+    const partial_unwrap_check<T2> tmp2(X.B, out);
+    
+    const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M;
+    const typename partial_unwrap_check<T2>::stored_type& B = tmp2.M;
+    
+    const bool use_alpha = partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times;
+    const eT       alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val()) : eT(0);
+    
+    glue_times::apply
+      <
+      eT,
+      partial_unwrap_check<T1>::do_trans,
+      partial_unwrap_check<T2>::do_trans,
+      (partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times)
+      >
+      (out, A, B, alpha);
+    }
+  else
+    {
+    arma_extra_debug_print("glue_times_redirect<2>::apply(): detected inv(A)*B");
+    
+    const strip_inv<T1> A_strip(X.A);
+    
+    Mat<eT> A = A_strip.M;
+    
+    arma_debug_check( (A.is_square() == false), "inv(): given matrix is not square" );
+    
+    const unwrap_check<T2> B_tmp(X.B, out);
+    const Mat<eT>& B = B_tmp.M;
+    
+    glue_solve::solve_direct( out, A, B, A_strip.slow );
+    }
+  }
+
+
+
+template<uword N>
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+glue_times_redirect<N>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const partial_unwrap_check<T1> tmp1(X.A, out);
+  const partial_unwrap_check<T2> tmp2(X.B, out);
+  
+  const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M;
+  const typename partial_unwrap_check<T2>::stored_type& B = tmp2.M;
+  
+  const bool use_alpha = partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times;
+  const eT       alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val()) : eT(0);
+  
+  glue_times::apply
+    <
+    eT,
+    partial_unwrap_check<T1>::do_trans,
+    partial_unwrap_check<T2>::do_trans,
+    (partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times)
+    >
+    (out, A, B, alpha);
+  }
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+glue_times_redirect<2>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  glue_times_redirect2_helper< is_supported_blas_type<eT>::value >::apply(out, X);
+  }
+
+
+
+template<typename T1, typename T2, typename T3>
+arma_hot
+inline
+void
+glue_times_redirect<3>::apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>, T3, glue_times>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  // TODO: investigate detecting inv(A)*B*C and replacing with solve(A,B)*C
+  // TODO: investigate detecting A*inv(B)*C and replacing with A*solve(B,C)
+  
+  // there is exactly 3 objects
+  // hence we can safely expand X as X.A.A, X.A.B and X.B
+  
+  const partial_unwrap_check<T1> tmp1(X.A.A, out);
+  const partial_unwrap_check<T2> tmp2(X.A.B, out);
+  const partial_unwrap_check<T3> tmp3(X.B,   out);
+  
+  const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M;
+  const typename partial_unwrap_check<T2>::stored_type& B = tmp2.M;
+  const typename partial_unwrap_check<T3>::stored_type& C = tmp3.M;
+  
+  const bool use_alpha = partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times || partial_unwrap_check<T3>::do_times;
+  const eT       alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val() * tmp3.get_val()) : eT(0);
+  
+  glue_times::apply
+    <
+    eT,
+    partial_unwrap_check<T1>::do_trans,
+    partial_unwrap_check<T2>::do_trans,
+    partial_unwrap_check<T3>::do_trans,
+    (partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times || partial_unwrap_check<T3>::do_times)
+    >
+    (out, A, B, C, alpha);
+  }
+
+
+
+template<typename T1, typename T2, typename T3, typename T4>
+arma_hot
+inline
+void
+glue_times_redirect<4>::apply(Mat<typename T1::elem_type>& out, const Glue< Glue< Glue<T1,T2,glue_times>, T3, glue_times>, T4, glue_times>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  // there is exactly 4 objects
+  // hence we can safely expand X as X.A.A.A, X.A.A.B, X.A.B and X.B
+  
+  const partial_unwrap_check<T1> tmp1(X.A.A.A, out);
+  const partial_unwrap_check<T2> tmp2(X.A.A.B, out);
+  const partial_unwrap_check<T3> tmp3(X.A.B,   out);
+  const partial_unwrap_check<T4> tmp4(X.B,     out);
+  
+  const typename partial_unwrap_check<T1>::stored_type& A = tmp1.M;
+  const typename partial_unwrap_check<T2>::stored_type& B = tmp2.M;
+  const typename partial_unwrap_check<T3>::stored_type& C = tmp3.M;
+  const typename partial_unwrap_check<T4>::stored_type& D = tmp4.M;
+  
+  const bool use_alpha = partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times || partial_unwrap_check<T3>::do_times || partial_unwrap_check<T4>::do_times;
+  const eT       alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val() * tmp3.get_val() * tmp4.get_val()) : eT(0);
+  
+  glue_times::apply
+    <
+    eT,
+    partial_unwrap_check<T1>::do_trans,
+    partial_unwrap_check<T2>::do_trans,
+    partial_unwrap_check<T3>::do_trans,
+    partial_unwrap_check<T4>::do_trans,
+    (partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times || partial_unwrap_check<T3>::do_times || partial_unwrap_check<T4>::do_times)
+    >
+    (out, A, B, C, D, alpha);
+  }
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+glue_times::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const sword N_mat = 1 + depth_lhs< glue_times, Glue<T1,T2,glue_times> >::num;
+  
+  arma_extra_debug_print(arma_boost::format("N_mat = %d") % N_mat);
+  
+  glue_times_redirect<N_mat>::apply(out, X);
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+glue_times::apply_inplace(Mat<typename T1::elem_type>& out, const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> B_tmp(X, out);
+  const Mat<eT>& B     = B_tmp.M;
+  
+  arma_debug_assert_mul_size(out, B, "matrix multiplication");
+  
+  const uword out_n_rows = out.n_rows;
+  const uword out_n_cols = out.n_cols;
+  
+  if(out_n_cols == B.n_cols)
+    {
+    // size of resulting matrix is the same as 'out'
+    
+    podarray<eT> tmp(out_n_cols);
+    
+    eT* tmp_rowdata = tmp.memptr();
+    
+    for(uword row=0; row < out_n_rows; ++row)
+      {
+      tmp.copy_row(out, row);
+      
+      for(uword col=0; col < out_n_cols; ++col)
+        {
+        out.at(row,col) = op_dot::direct_dot( out_n_cols, tmp_rowdata, B.colptr(col) );
+        }
+      }
+    
+    }
+  else
+    {
+    const Mat<eT> tmp(out);
+    
+    glue_times::apply<eT, false, false, false>(out, tmp, B, eT(1));
+    }
+  
+  }
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+glue_times::apply_inplace_plus(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_times>& X, const sword sign)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const partial_unwrap_check<T1> tmp1(X.A, out);
+  const partial_unwrap_check<T2> tmp2(X.B, out);
+  
+  typedef typename partial_unwrap_check<T1>::stored_type TA;
+  typedef typename partial_unwrap_check<T2>::stored_type TB;
+  
+  const TA& A = tmp1.M;
+  const TB& B = tmp2.M;
+  
+  const bool do_trans_A = partial_unwrap_check<T1>::do_trans;
+  const bool do_trans_B = partial_unwrap_check<T2>::do_trans;
+  
+  const bool use_alpha = partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times || (sign < sword(0));
+  const eT       alpha = use_alpha ? ( tmp1.get_val() * tmp2.get_val() * ( (sign > sword(0)) ? eT(1) : eT(-1) ) ) : eT(0);
+  
+  arma_debug_assert_mul_size(A, B, do_trans_A, do_trans_B, "matrix multiplication");
+  
+  const uword result_n_rows = (do_trans_A == false) ? (TA::is_row ? 1 : A.n_rows) : (TA::is_col ? 1 : A.n_cols);
+  const uword result_n_cols = (do_trans_B == false) ? (TB::is_col ? 1 : B.n_cols) : (TB::is_row ? 1 : B.n_rows);
+  
+  arma_debug_assert_same_size(out.n_rows, out.n_cols, result_n_rows, result_n_cols, "addition");
+  
+  if(out.n_elem > 0)
+    {
+    if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == false) )
+      {
+      if( ((A.n_rows == 1) || (TA::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<true,         false, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
+        }
+      else
+      if( (B.n_cols == 1) || (TB::is_col) )
+        {
+        gemv<false,        false, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
+        }
+      else
+        {
+        gemm<false, false, false, true>::apply(out, A, B, alpha, eT(1));
+        }
+      }
+    else
+    if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == true) )
+      {
+      if( ((A.n_rows == 1) || (TA::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<true,         true, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
+        }
+      else
+      if( (B.n_cols == 1) || (TB::is_col) )
+        {
+        gemv<false,        true, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
+        }
+      else
+        {
+        gemm<false, false, true, true>::apply(out, A, B, alpha, eT(1));
+        }
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == false) && (use_alpha == false) )
+      {
+      if( ((A.n_cols == 1) || (TA::is_col)) && (is_complex<eT>::value == false) )
+        {
+        gemv<true,        false, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
+        }
+      else
+      if( (B.n_cols == 1) || (TB::is_col) )
+        {
+        gemv<true,        false, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
+        }
+      else
+        {
+        gemm<true, false, false, true>::apply(out, A, B, alpha, eT(1));
+        }
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == false) && (use_alpha == true) )
+      {
+      if( ((A.n_cols == 1) || (TA::is_col)) && (is_complex<eT>::value == false) )
+        {
+        gemv<true,        true, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
+        }
+      else
+      if( (B.n_cols == 1) || (TB::is_col) )
+        {
+        gemv<true,        true, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
+        }
+      else
+        {
+        gemm<true, false, true, true>::apply(out, A, B, alpha, eT(1));
+        }
+      }
+    else
+    if( (do_trans_A == false) && (do_trans_B == true) && (use_alpha == false) )
+      {
+      if( ((A.n_rows == 1) || (TA::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<false,       false, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
+        }
+      else
+      if( ((B.n_rows == 1) || (TB::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<false,       false, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
+        }
+      else
+        {
+        gemm<false, true, false, true>::apply(out, A, B, alpha, eT(1));
+        }
+      }
+    else
+    if( (do_trans_A == false) && (do_trans_B == true) && (use_alpha == true) )
+      {
+      if( ((A.n_rows == 1) || (TA::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<false,       true, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
+        }
+      else
+      if( ((B.n_rows == 1) || (TB::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<false,       true, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
+        }
+      else
+        {
+        gemm<false, true, true, true>::apply(out, A, B, alpha, eT(1));
+        }
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == true) && (use_alpha == false) )
+      {
+      if( ((A.n_cols == 1) || (TA::is_col)) && (is_complex<eT>::value == false) )
+        {
+        gemv<false,      false, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
+        }
+      else
+      if( ((B.n_rows == 1) || (TB::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<true,       false, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
+        }
+      else
+        {
+        gemm<true, true, false, true>::apply(out, A, B, alpha, eT(1));
+        }
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == true) && (use_alpha == true) )
+      {
+      if( ((A.n_cols == 1) || (TA::is_col)) && (is_complex<eT>::value == false) )
+        {
+        gemv<false,      true, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
+        }
+      else
+      if( ((B.n_rows == 1) || (TB::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<true,       true, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
+        }
+      else
+        {
+        gemm<true, true, true, true>::apply(out, A, B, alpha, eT(1));
+        }
+      }
+    }
+  
+  
+  }
+
+
+
+template<typename eT, const bool do_trans_A, const bool do_trans_B, typename TA, typename TB>
+arma_inline
+uword
+glue_times::mul_storage_cost(const TA& A, const TB& B)
+  {
+  const uword final_A_n_rows = (do_trans_A == false) ? ( TA::is_row ? 1 : A.n_rows ) : ( TA::is_col ? 1 : A.n_cols );
+  const uword final_B_n_cols = (do_trans_B == false) ? ( TB::is_col ? 1 : B.n_cols ) : ( TB::is_row ? 1 : B.n_rows );
+  
+  return final_A_n_rows * final_B_n_cols;
+  }
+
+
+
+template
+  <
+  typename   eT,
+  const bool do_trans_A,
+  const bool do_trans_B,
+  const bool use_alpha,
+  typename   TA,
+  typename   TB
+  >
+arma_hot
+inline
+void
+glue_times::apply
+  (
+        Mat<eT>& out,
+  const TA&      A,
+  const TB&      B,
+  const eT       alpha
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  //arma_debug_assert_mul_size(A, B, do_trans_A, do_trans_B, "matrix multiplication");
+  arma_debug_assert_trans_mul_size<do_trans_A, do_trans_B>(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication");
+  
+  const uword final_n_rows = (do_trans_A == false) ? (TA::is_row ? 1 : A.n_rows) : (TA::is_col ? 1 : A.n_cols);
+  const uword final_n_cols = (do_trans_B == false) ? (TB::is_col ? 1 : B.n_cols) : (TB::is_row ? 1 : B.n_rows);
+  
+  out.set_size(final_n_rows, final_n_cols);
+  
+  if( (A.n_elem > 0) && (B.n_elem > 0) )
+    {
+    if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == false) )
+      {
+      if( ((A.n_rows == 1) || (TA::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<true,         false, false>::apply(out.memptr(), B, A.memptr());
+        }
+      else
+      if( (B.n_cols == 1) || (TB::is_col) )
+        {
+        gemv<false,        false, false>::apply(out.memptr(), A, B.memptr());
+        }
+      else
+        {
+        gemm<false, false, false, false>::apply(out, A, B);
+        }
+      }
+    else
+    if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == true) )
+      {
+      if( ((A.n_rows == 1) || (TA::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<true,         true, false>::apply(out.memptr(), B, A.memptr(), alpha);
+        }
+      else
+      if( (B.n_cols == 1) || (TB::is_col) )
+        {
+        gemv<false,        true, false>::apply(out.memptr(), A, B.memptr(), alpha);
+        }
+      else
+        {
+        gemm<false, false, true, false>::apply(out, A, B, alpha);
+        }
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == false) && (use_alpha == false) )
+      {
+      if( ((A.n_cols == 1) || (TA::is_col)) && (is_complex<eT>::value == false) )
+        {
+        gemv<true,        false, false>::apply(out.memptr(), B, A.memptr());
+        }
+      else
+      if( (B.n_cols == 1) || (TB::is_col) )
+        {
+        gemv<true,        false, false>::apply(out.memptr(), A, B.memptr());
+        }
+      else
+        {
+        gemm<true, false, false, false>::apply(out, A, B);
+        }
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == false) && (use_alpha == true) )
+      {
+      if( ((A.n_cols == 1) || (TA::is_col)) && (is_complex<eT>::value == false) )
+        {
+        gemv<true,        true, false>::apply(out.memptr(), B, A.memptr(), alpha);
+        }
+      else
+      if( (B.n_cols == 1) || (TB::is_col) )
+        {
+        gemv<true,        true, false>::apply(out.memptr(), A, B.memptr(), alpha);
+        }
+      else
+        {
+        gemm<true, false, true, false>::apply(out, A, B, alpha);
+        }
+      }
+    else
+    if( (do_trans_A == false) && (do_trans_B == true) && (use_alpha == false) )
+      {
+      if( ((A.n_rows == 1) || (TA::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<false,       false, false>::apply(out.memptr(), B, A.memptr());
+        }
+      else
+      if( ((B.n_rows == 1) || (TB::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<false,       false, false>::apply(out.memptr(), A, B.memptr());
+        }
+      else
+        {
+        gemm<false, true, false, false>::apply(out, A, B);
+        }
+      }
+    else
+    if( (do_trans_A == false) && (do_trans_B == true) && (use_alpha == true) )
+      {
+      if( ((A.n_rows == 1) || (TA::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<false,       true, false>::apply(out.memptr(), B, A.memptr(), alpha);
+        }
+      else
+      if( ((B.n_rows == 1) || (TB::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<false,       true, false>::apply(out.memptr(), A, B.memptr(), alpha);
+        }
+      else
+        {
+        gemm<false, true, true, false>::apply(out, A, B, alpha);
+        }
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == true) && (use_alpha == false) )
+      {
+      if( ((A.n_cols == 1) || (TA::is_col)) && (is_complex<eT>::value == false) )
+        {
+        gemv<false,      false, false>::apply(out.memptr(), B, A.memptr());
+        }
+      else
+      if( ((B.n_rows == 1) || (TB::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<true,       false, false>::apply(out.memptr(), A, B.memptr());
+        }
+      else
+        {
+        gemm<true, true, false, false>::apply(out, A, B);
+        }
+      }
+    else
+    if( (do_trans_A == true) && (do_trans_B == true) && (use_alpha == true) )
+      {
+      if( ((A.n_cols == 1) || (TA::is_col)) && (is_complex<eT>::value == false) )
+        {
+        gemv<false,      true, false>::apply(out.memptr(), B, A.memptr(), alpha);
+        }
+      else
+      if( ((B.n_rows == 1) || (TB::is_row)) && (is_complex<eT>::value == false) )
+        {
+        gemv<true,       true, false>::apply(out.memptr(), A, B.memptr(), alpha);
+        }
+      else
+        {
+        gemm<true, true, true, false>::apply(out, A, B, alpha);
+        }
+      }
+    }
+  else
+    {
+    out.zeros();
+    }
+  }
+
+
+
+template
+  <
+  typename   eT,
+  const bool do_trans_A,
+  const bool do_trans_B,
+  const bool do_trans_C,
+  const bool use_alpha,
+  typename   TA,
+  typename   TB,
+  typename   TC
+  >
+arma_hot
+inline
+void
+glue_times::apply
+  (
+        Mat<eT>& out,
+  const TA&      A,
+  const TB&      B,
+  const TC&      C,
+  const eT       alpha
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT> tmp;
+  
+  const uword storage_cost_AB = glue_times::mul_storage_cost<eT, do_trans_A, do_trans_B>(A, B);
+  const uword storage_cost_BC = glue_times::mul_storage_cost<eT, do_trans_B, do_trans_C>(B, C);
+  
+  if(storage_cost_AB <= storage_cost_BC)
+    {
+    // out = (A*B)*C
+    
+    glue_times::apply<eT, do_trans_A, do_trans_B, use_alpha>(tmp, A,   B, alpha);
+    glue_times::apply<eT, false,      do_trans_C, false    >(out, tmp, C, eT(0));
+    }
+  else
+    {
+    // out = A*(B*C)
+    
+    glue_times::apply<eT, do_trans_B, do_trans_C, use_alpha>(tmp, B, C,   alpha);
+    glue_times::apply<eT, do_trans_A, false,      false    >(out, A, tmp, eT(0));
+    }
+  }
+
+
+
+template
+  <
+  typename   eT,
+  const bool do_trans_A,
+  const bool do_trans_B,
+  const bool do_trans_C,
+  const bool do_trans_D,
+  const bool use_alpha,
+  typename   TA,
+  typename   TB,
+  typename   TC,
+  typename   TD
+  >
+arma_hot
+inline
+void
+glue_times::apply
+  (
+        Mat<eT>& out,
+  const TA&      A,
+  const TB&      B,
+  const TC&      C,
+  const TD&      D,
+  const eT       alpha
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT> tmp;
+  
+  const uword storage_cost_AC = glue_times::mul_storage_cost<eT, do_trans_A, do_trans_C>(A, C);
+  const uword storage_cost_BD = glue_times::mul_storage_cost<eT, do_trans_B, do_trans_D>(B, D);
+  
+  if(storage_cost_AC <= storage_cost_BD)
+    {
+    // out = (A*B*C)*D
+    
+    glue_times::apply<eT, do_trans_A, do_trans_B, do_trans_C, use_alpha>(tmp, A, B, C, alpha);
+    
+    glue_times::apply<eT, false, do_trans_D, false>(out, tmp, D, eT(0));
+    }
+  else
+    {
+    // out = A*(B*C*D)
+    
+    glue_times::apply<eT, do_trans_B, do_trans_C, do_trans_D, use_alpha>(tmp, B, C, D, alpha);
+    
+    glue_times::apply<eT, do_trans_A, false, false>(out, A, tmp, eT(0));
+    }
+  }
+
+
+
+//
+// glue_times_diag
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+glue_times_diag::apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_times_diag>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const strip_diagmat<T1> S1(X.A);
+  const strip_diagmat<T2> S2(X.B);
+  
+  typedef typename strip_diagmat<T1>::stored_type T1_stripped;
+  typedef typename strip_diagmat<T2>::stored_type T2_stripped;
+  
+  if( (strip_diagmat<T1>::do_diagmat == true) && (strip_diagmat<T2>::do_diagmat == false) )
+    {
+    const diagmat_proxy_check<T1_stripped> A(S1.M, out);
+    
+    const unwrap_check<T2> tmp(X.B, out);
+    const Mat<eT>& B     = tmp.M;
+    
+    const uword A_n_elem = A.n_elem;
+    const uword B_n_rows = B.n_rows;
+    const uword B_n_cols = B.n_cols;
+    
+    arma_debug_assert_mul_size(A_n_elem, A_n_elem, B_n_rows, B_n_cols, "matrix multiplication");
+    
+    out.set_size(A_n_elem, B_n_cols);
+    
+    for(uword col=0; col < B_n_cols; ++col)
+      {
+            eT* out_coldata = out.colptr(col);
+      const eT* B_coldata   = B.colptr(col);
+      
+      uword i,j;
+      for(i=0, j=1; j < B_n_rows; i+=2, j+=2)
+        {
+        eT tmp_i = A[i];
+        eT tmp_j = A[j];
+        
+        tmp_i *= B_coldata[i];
+        tmp_j *= B_coldata[j];
+        
+        out_coldata[i] = tmp_i;
+        out_coldata[j] = tmp_j;
+        }
+      
+      if(i < B_n_rows)
+        {
+        out_coldata[i] = A[i] * B_coldata[i];
+        }
+      }
+    }
+  else
+  if( (strip_diagmat<T1>::do_diagmat == false) && (strip_diagmat<T2>::do_diagmat == true) )
+    {
+    const unwrap_check<T1> tmp(X.A, out);
+    const Mat<eT>& A     = tmp.M;
+    
+    const diagmat_proxy_check<T2_stripped> B(S2.M, out);
+    
+    const uword A_n_rows = A.n_rows;
+    const uword A_n_cols = A.n_cols;
+    const uword B_n_elem = B.n_elem;
+    
+    arma_debug_assert_mul_size(A_n_rows, A_n_cols, B_n_elem, B_n_elem, "matrix multiplication");
+    
+    out.set_size(A_n_rows, B_n_elem);
+    
+    for(uword col=0; col < A_n_cols; ++col)
+      {
+      const eT  val = B[col];
+      
+            eT* out_coldata = out.colptr(col);
+      const eT*   A_coldata =   A.colptr(col);
+      
+      uword i,j;
+      for(i=0, j=1; j < A_n_rows; i+=2, j+=2)
+        {
+        const eT tmp_i = A_coldata[i] * val;
+        const eT tmp_j = A_coldata[j] * val;
+        
+        out_coldata[i] = tmp_i;
+        out_coldata[j] = tmp_j;
+        }
+      
+      if(i < A_n_rows)
+        {
+        out_coldata[i] = A_coldata[i] * val;
+        }
+      }
+    }
+  else
+  if( (strip_diagmat<T1>::do_diagmat == true) && (strip_diagmat<T2>::do_diagmat == true) )
+    {
+    const diagmat_proxy_check<T1_stripped> A(S1.M, out);
+    const diagmat_proxy_check<T2_stripped> B(S2.M, out);
+    
+    const uword A_n_elem = A.n_elem;
+    const uword B_n_elem = B.n_elem;
+    
+    arma_debug_assert_mul_size(A_n_elem, A_n_elem, B_n_elem, B_n_elem, "matrix multiplication");
+    
+    out.zeros(A_n_elem, A_n_elem);
+    
+    for(uword i=0; i < A_n_elem; ++i)
+      {
+      out.at(i,i) = A[i] * B[i];
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_toeplitz_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,24 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup glue_toeplitz
+//! @{
+
+
+
+class glue_toeplitz
+  {
+  public:
+  
+  template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_toeplitz>& in);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/glue_toeplitz_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,63 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup glue_toeplitz
+//! @{
+
+
+
+template<typename T1, typename T2>
+inline
+void
+glue_toeplitz::apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_toeplitz>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> tmp1(in.A, out);
+  const unwrap_check<T2> tmp2(in.B, out);
+  
+  const Mat<eT>& A = tmp1.M;
+  const Mat<eT>& B = tmp2.M;
+  
+  arma_debug_check
+    (
+    ( ((A.is_vec() == false) && (A.is_empty() == false)) || ((B.is_vec() == false) && (B.is_empty() == false)) ),
+    "toeplitz(): given object is not a vector"
+    );
+  
+  const uword A_N = A.n_elem;
+  const uword B_N = B.n_elem;
+  
+  const eT* A_mem = A.memptr();
+  const eT* B_mem = B.memptr();
+  
+  out.set_size(A_N, B_N);
+  
+  if( out.is_empty() )  { return; }
+  
+  for(uword col=0; col < B_N; ++col)
+    {
+    eT* col_mem = out.colptr(col);
+    
+    uword i = 0;
+    for(uword row=col; row < A_N; ++row, ++i)  { col_mem[row] = A_mem[i]; }
+    }
+  
+  for(uword row=0; row < A_N; ++row)
+    {
+    uword i = 1;
+    for(uword col=(row+1); col < B_N; ++col, ++i)  { out.at(row,col) = B_mem[i]; }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/hdf5_misc.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,716 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+// Copyright (C) 2013 Szabolcs Horvat
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+//! \addtogroup hdf5_misc
+//! @{
+
+
+#if defined(ARMA_USE_HDF5)
+namespace hdf5_misc
+{
+
+
+//! Given a certain type, find the corresponding HDF5 datatype.  This can't be
+//! done entirely at compile time, unfortunately, because the H5T_* macros
+//! depend on function calls.
+template< typename eT >
+inline
+hid_t
+get_hdf5_type()
+  {
+  return -1; // Return invalid.
+  }
+
+
+
+//! Specializations for each valid element type
+//! (taken from all the possible typedefs of {u8, s8, ..., u64, s64} and the other native types.  
+//! We can't use the actual u8/s8 typedefs because their relations to the H5T_... types are unclear.
+template<>
+inline
+hid_t
+get_hdf5_type< unsigned char >()
+  {
+  return H5Tcopy(H5T_NATIVE_UCHAR);
+  }
+
+template<>
+inline
+hid_t
+get_hdf5_type< char >()
+  {
+  return H5Tcopy(H5T_NATIVE_CHAR);
+  }
+
+template<>
+inline
+hid_t
+get_hdf5_type< short >()
+  {
+  return H5Tcopy(H5T_NATIVE_SHORT);
+  }
+
+template<>
+inline
+hid_t
+get_hdf5_type< unsigned short >()
+  {
+  return H5Tcopy(H5T_NATIVE_USHORT);
+  }
+
+template<>
+inline
+hid_t
+get_hdf5_type< int >()
+  {
+  return H5Tcopy(H5T_NATIVE_INT);
+  }
+
+template<>
+inline
+hid_t
+get_hdf5_type< unsigned int >()
+  {
+  return H5Tcopy(H5T_NATIVE_UINT);
+  }
+
+template<>
+inline
+hid_t
+get_hdf5_type< long >()
+  {
+  return H5Tcopy(H5T_NATIVE_LONG);
+  }
+
+template<>
+inline
+hid_t
+get_hdf5_type< unsigned long >()
+  {
+  return H5Tcopy(H5T_NATIVE_ULONG);
+  }
+
+
+#if defined(ARMA_USE_U64S64) && defined(ULLONG_MAX)
+  template<>
+  inline
+  hid_t
+  get_hdf5_type< long long >()
+    {
+    return H5Tcopy(H5T_NATIVE_LLONG);
+    }
+
+  template<>
+  inline
+  hid_t
+  get_hdf5_type< unsigned long long >()
+    {
+    return H5Tcopy(H5T_NATIVE_ULLONG);
+    }
+#endif
+
+
+template<>
+inline
+hid_t
+get_hdf5_type< float >()
+  {
+  return H5Tcopy(H5T_NATIVE_FLOAT);
+  }
+
+template<>
+inline
+hid_t
+get_hdf5_type< double >()
+  {
+  return H5Tcopy(H5T_NATIVE_DOUBLE);
+  }
+
+
+
+//! Utility hid_t since HOFFSET() won't work with std::complex.
+template<typename eT>
+struct hdf5_complex_t
+  {
+  eT real;
+  eT imag;
+  };
+
+
+
+template<>
+inline
+hid_t
+get_hdf5_type< std::complex<float> >()
+  {
+  hid_t type = H5Tcreate(H5T_COMPOUND, sizeof(hdf5_complex_t<float>));
+  
+  H5Tinsert(type, "real", HOFFSET(hdf5_complex_t<float>, real), H5T_NATIVE_FLOAT);
+  H5Tinsert(type, "imag", HOFFSET(hdf5_complex_t<float>, imag), H5T_NATIVE_FLOAT);
+  
+  return type;
+  }
+
+
+
+template<>
+inline
+hid_t
+get_hdf5_type< std::complex<double> >()
+  {
+  hid_t type = H5Tcreate(H5T_COMPOUND, sizeof(hdf5_complex_t<double>));
+
+  H5Tinsert(type, "real", HOFFSET(hdf5_complex_t<double>, real), H5T_NATIVE_DOUBLE);
+  H5Tinsert(type, "imag", HOFFSET(hdf5_complex_t<double>, imag), H5T_NATIVE_DOUBLE);
+
+  return type;
+  }
+
+
+
+// Compare datatype against all supported types.
+inline
+bool
+is_supported_arma_hdf5_type(hid_t datatype)
+  {
+  hid_t  search_type;
+  
+  bool is_equal;
+  
+  
+  // start with most likely used types: double, complex<double>, float, complex<float>
+  
+  search_type = get_hdf5_type<double>();
+  is_equal = ( H5Tequal(datatype, search_type) > 0 );
+  H5Tclose(search_type);
+  if (is_equal) { return true; }
+  
+  search_type = get_hdf5_type< std::complex<double> >();
+  is_equal = ( H5Tequal(datatype, search_type) > 0 );
+  H5Tclose(search_type);
+  if (is_equal) { return true; }
+  
+  search_type = get_hdf5_type<float>();
+  is_equal = ( H5Tequal(datatype, search_type) > 0 );
+  H5Tclose(search_type);
+  if (is_equal) { return true; }
+  
+  search_type = get_hdf5_type< std::complex<float> >();
+  is_equal = ( H5Tequal(datatype, search_type) > 0 );
+  H5Tclose(search_type);
+  if (is_equal) { return true; }
+  
+  
+  // remaining supported types: u8, s8, u16, s16, u32, s32, u64, s64, ulng_t, slng_t
+  
+  search_type = get_hdf5_type<u8>();
+  is_equal = ( H5Tequal(datatype, search_type) > 0 );
+  H5Tclose(search_type);
+  if (is_equal) { return true; }
+  
+  search_type = get_hdf5_type<s8>();
+  is_equal = ( H5Tequal(datatype, search_type) > 0 );
+  H5Tclose(search_type);
+  if (is_equal) { return true; }
+  
+  search_type = get_hdf5_type<u16>();
+  is_equal = ( H5Tequal(datatype, search_type) > 0 );
+  H5Tclose(search_type);
+  if (is_equal) { return true; }
+  
+  search_type = get_hdf5_type<s16>();
+  is_equal = ( H5Tequal(datatype, search_type) > 0 );
+  H5Tclose(search_type);
+  if (is_equal) { return true; }
+  
+  search_type = get_hdf5_type<u32>();
+  is_equal = ( H5Tequal(datatype, search_type) > 0 );
+  H5Tclose(search_type);
+  if (is_equal) { return true; }
+  
+  search_type = get_hdf5_type<s32>();
+  is_equal = ( H5Tequal(datatype, search_type) > 0 );
+  H5Tclose(search_type);
+  if (is_equal) { return true; }
+  
+  #if defined(ARMA_USE_U64S64)
+    {
+    search_type = get_hdf5_type<u64>();
+    is_equal = ( H5Tequal(datatype, search_type) > 0 );
+    H5Tclose(search_type);
+    if (is_equal) { return true; }
+    
+    search_type = get_hdf5_type<s64>();
+    is_equal = ( H5Tequal(datatype, search_type) > 0 );
+    H5Tclose(search_type);
+    if (is_equal) { return true; }
+    }
+  #endif
+  
+  #if defined(ARMA_ALLOW_LONG)
+    {
+    search_type = get_hdf5_type<ulng_t>();
+    is_equal = ( H5Tequal(datatype, search_type) > 0 );
+    H5Tclose(search_type);
+    if (is_equal) { return true; }
+    
+    search_type = get_hdf5_type<slng_t>();
+    is_equal = ( H5Tequal(datatype, search_type) > 0 );
+    H5Tclose(search_type);
+    if (is_equal) { return true; }
+    }
+  #endif
+  
+  return false;
+  }
+
+
+
+//! Auxiliary functions and structs for search_hdf5_file.
+struct hdf5_search_info
+  {
+  const  std::vector<std::string>& names;
+  int    num_dims;
+  bool   exact;
+  hid_t  best_match;
+  size_t best_match_position; // Position of best match in names vector.
+  };
+
+
+
+inline
+herr_t
+hdf5_search_callback
+  (
+  hid_t             loc_id,
+  const char*       name,
+  const H5O_info_t* info,
+  void*             operator_data  // hdf5_search_info
+  )
+  {
+  hdf5_search_info* search_info = (hdf5_search_info*) operator_data;
+
+  // We are looking for datasets.
+  if (info->type == H5O_TYPE_DATASET)
+    {
+    // Check type of dataset to see if we could even load it.
+    hid_t dataset  = H5Dopen(loc_id, name, H5P_DEFAULT);
+    hid_t datatype = H5Dget_type(dataset);
+    
+    const bool is_supported = is_supported_arma_hdf5_type(datatype);
+    
+    H5Tclose(datatype);
+    H5Dclose(dataset);
+    
+    if(is_supported == false)
+      {
+      // Forget about it and move on.
+      return 0;
+      }
+    
+    // Now we have to check against our set of names.
+    // Only check names which could be better.
+    for (size_t string_pos = 0; string_pos < search_info->best_match_position; ++string_pos)
+      {
+      // name is the full path (/path/to/dataset); names[string_pos] may be
+      // "dataset", "/to/dataset", or "/path/to/dataset".
+      // So if we count the number of forward slashes in names[string_pos],
+      // and then simply take the last substring of name containing that number of slashes,
+      // we can do the comparison.
+      
+      // Count the number of forward slashes in names[string_pos].
+      uword count = 0;
+      for (uword i = 0; i < search_info->names[string_pos].length(); ++i)
+        {
+        if ((search_info->names[string_pos])[i] == '/') { ++count; }
+        }
+
+      // Count the number of forward slashes in the full name.
+      uword name_count = 0;
+      const std::string str = std::string(name);
+      for (uword i = 0; i < str.length(); ++i)
+        {
+        if (str[i] == '/') { ++count; }
+        }
+
+      // If we are asking for more slashes than we have, this can't be a match.
+      // Skip to below, where we decide whether or not to keep it anyway based
+      // on the exactness condition of the search.
+      if (count <= name_count)
+        {
+        size_t start_pos = (count == 0) ? 0 : std::string::npos;
+        while (count > 0)
+          {
+          // Move pointer to previous slash.
+          start_pos = str.rfind('/', start_pos);
+          
+          // Break if we've run out of slashes.
+          if (start_pos == std::string::npos) { break; }
+          
+          --count;
+          }
+
+        // Now take the substring (this may end up being the full string).
+        const std::string substring = str.substr(start_pos);
+
+        // Are they the same?
+        if (substring == search_info->names[string_pos])
+          {
+          // We have found the object; it must be better than our existing match.
+          hid_t match_candidate = H5Dopen(loc_id, name, H5P_DEFAULT);
+
+
+          // arma_check(match_candidate < 0, "Mat::load(): cannot open an HDF5 dataset");
+          if(match_candidate < 0)
+            {
+            return -1;
+            }
+          
+          
+          // Ensure that the dataset is valid and of the correct dimensionality.
+          hid_t filespace = H5Dget_space(match_candidate);
+          int num_dims = H5Sget_simple_extent_ndims(filespace);
+          
+          if (num_dims <= search_info->num_dims)
+            {
+            // Valid dataset -- we'll keep it.
+            // If we already have an existing match we have to close it.
+            if (search_info->best_match != -1)
+              {
+              H5Dclose(search_info->best_match);
+              }
+
+            search_info->best_match_position = string_pos;
+            search_info->best_match          = match_candidate;
+            }
+          
+          H5Sclose(filespace);
+          }
+        }
+      
+      
+      // If they are not the same, but we have not found anything and we don't need an exact match, take this.
+      if ((search_info->exact == false) && (search_info->best_match == -1))
+        {
+        hid_t match_candidate = H5Dopen(loc_id, name, H5P_DEFAULT);
+        
+        // arma_check(match_candidate < 0, "Mat::load(): cannot open an HDF5 dataset");
+        if(match_candidate < 0)
+          {
+          return -1;
+          }
+        
+        hid_t filespace = H5Dget_space(match_candidate);
+        int num_dims = H5Sget_simple_extent_ndims(filespace);
+        
+        if (num_dims <= search_info->num_dims)
+          {
+          // Valid dataset -- we'll keep it.
+          search_info->best_match = H5Dopen(loc_id, name, H5P_DEFAULT);
+          }
+        
+        H5Sclose(filespace);
+        }
+      }
+    }
+  
+  return 0;
+  }
+
+
+
+//! Search an HDF5 file for the given dataset names.  
+//! If 'exact' is true, failure to find a dataset in the list of names means that -1 is returned.
+//! If 'exact' is false and no datasets are found, -1 is returned.  
+//! The number of dimensions is used to help prune down invalid datasets;
+//! 2 dimensions is a matrix, 1 dimension is a vector, and 3 dimensions is a cube.  
+//! If the number of dimensions in a dataset is less than or equal to num_dims, 
+//! it will be considered -- for instance, a one-dimensional HDF5 vector can be loaded as a single-column matrix.
+inline
+hid_t
+search_hdf5_file
+  (
+  const std::vector<std::string>& names,
+  hid_t                           hdf5_file,
+  int                             num_dims = 2,
+  bool                            exact = false
+  )
+  {
+  hdf5_search_info search_info = { names, num_dims, exact, -1, names.size() };
+  
+  // We'll use the H5Ovisit to track potential entries.
+  herr_t status = H5Ovisit(hdf5_file, H5_INDEX_NAME, H5_ITER_NATIVE, hdf5_search_callback, void_ptr(&search_info));
+  
+  // Return the best match; it will be -1 if there was a problem.
+  return (status < 0) ? -1 : search_info.best_match;
+  }
+
+
+
+//! Load an HDF5 matrix into an array of type specified by datatype,
+//! then convert that into the desired array 'dest'.
+//! This should only be called when eT is not the datatype.
+template<typename eT>
+inline
+hid_t
+load_and_convert_hdf5
+  (
+  eT   *dest,
+  hid_t dataset,
+  hid_t datatype,
+  uword n_elem
+  )
+  {
+  
+  // We can't use nice template specializations here
+  // as the determination of the type of 'datatype' must be done at runtime.
+  // So we end up with this ugliness...
+  hid_t search_type;
+  
+  bool is_equal;
+  
+  
+  // u8
+  search_type = get_hdf5_type<u8>();
+  is_equal = (H5Tequal(datatype, search_type) > 0);
+  H5Tclose(search_type);
+  
+  if(is_equal)
+    {
+    Col<u8> v(n_elem);
+    hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+    arrayops::convert(dest, v.memptr(), n_elem);
+
+    return status;
+    }
+  
+  
+  // s8
+  search_type = get_hdf5_type<s8>();
+  is_equal = (H5Tequal(datatype, search_type) > 0);
+  H5Tclose(search_type);
+  
+  if(is_equal)
+    {
+    Col<s8> v(n_elem);
+    hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+    arrayops::convert(dest, v.memptr(), n_elem);
+
+    return status;
+    }
+  
+  
+  // u16
+  search_type = get_hdf5_type<u16>();
+  is_equal = (H5Tequal(datatype, search_type) > 0);
+  H5Tclose(search_type);
+  
+  if(is_equal)
+    {
+    Col<u16> v(n_elem);
+    hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+    arrayops::convert(dest, v.memptr(), n_elem);
+
+    return status;
+    }
+  
+  
+  // s16
+  search_type = get_hdf5_type<s16>();
+  is_equal = (H5Tequal(datatype, search_type) > 0);
+  H5Tclose(search_type);
+  
+  if(is_equal)
+    {
+    Col<s16> v(n_elem);
+    hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+    arrayops::convert(dest, v.memptr(), n_elem);
+
+    return status;
+    }
+  
+  
+  // u32
+  search_type = get_hdf5_type<u32>();
+  is_equal = (H5Tequal(datatype, search_type) > 0);
+  H5Tclose(search_type);
+  
+  if(is_equal)
+    {
+    Col<u32> v(n_elem);
+    hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+    arrayops::convert(dest, v.memptr(), n_elem);
+
+    return status;
+    }
+  
+  
+  // s32
+  search_type = get_hdf5_type<s32>();
+  is_equal = (H5Tequal(datatype, search_type) > 0);
+  H5Tclose(search_type);
+  
+  if(is_equal)
+    {
+    Col<s32> v(n_elem);
+    hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+    arrayops::convert(dest, v.memptr(), n_elem);
+
+    return status;
+    }
+  
+  
+  #if defined(ARMA_USE_U64S64)
+    {
+    // u64
+    search_type = get_hdf5_type<u64>();
+    is_equal = (H5Tequal(datatype, search_type) > 0);
+    H5Tclose(search_type);
+    
+    if(is_equal)
+      {
+      Col<u64> v(n_elem);
+      hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+      arrayops::convert(dest, v.memptr(), n_elem);
+
+      return status;
+      }
+    
+    
+    // s64
+    search_type = get_hdf5_type<s64>();
+    is_equal = (H5Tequal(datatype, search_type) > 0);
+    H5Tclose(search_type);
+    
+    if(is_equal)
+      {
+      Col<s64> v(n_elem);
+      hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+      arrayops::convert(dest, v.memptr(), n_elem);
+
+      return status;
+      }
+    }
+  #endif
+  
+  
+  #if defined(ARMA_ALLOW_LONG)
+    {
+    // ulng_t
+    search_type = get_hdf5_type<ulng_t>();
+    is_equal = (H5Tequal(datatype, search_type) > 0);
+    H5Tclose(search_type);
+    
+    if(is_equal)
+      {
+      Col<ulng_t> v(n_elem);
+      hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+      arrayops::convert(dest, v.memptr(), n_elem);
+
+      return status;
+      }
+    
+    
+    // slng_t
+    search_type = get_hdf5_type<slng_t>();
+    is_equal = (H5Tequal(datatype, search_type) > 0);
+    H5Tclose(search_type);
+    
+    if(is_equal)
+      {
+      Col<slng_t> v(n_elem);
+      hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+      arrayops::convert(dest, v.memptr(), n_elem);
+
+      return status;
+      }
+    }
+  #endif
+  
+  
+  // float
+  search_type = get_hdf5_type<float>();
+  is_equal = (H5Tequal(datatype, search_type) > 0);
+  H5Tclose(search_type);
+  
+  if(is_equal)
+    {
+    Col<float> v(n_elem);
+    hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+    arrayops::convert(dest, v.memptr(), n_elem);
+
+    return status;
+    }
+  
+  
+  // double
+  search_type = get_hdf5_type<double>();
+  is_equal = (H5Tequal(datatype, search_type) > 0);
+  H5Tclose(search_type);
+  
+  if(is_equal)
+    {
+    Col<double> v(n_elem);
+    hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+    arrayops::convert(dest, v.memptr(), n_elem);
+
+    return status;
+    }
+  
+  
+  // complex float
+  search_type = get_hdf5_type< std::complex<float> >();
+  is_equal = (H5Tequal(datatype, search_type) > 0);
+  H5Tclose(search_type);
+  
+  if(is_equal)
+    {
+    if(is_complex<eT>::value == false)
+      {
+      return -1; // can't read complex data into non-complex matrix/cube
+      }
+    
+    Col< std::complex<float> > v(n_elem);
+    hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+    arrayops::convert_cx(dest, v.memptr(), n_elem);
+    
+    return status;
+    }
+  
+  
+  // complex double
+  search_type = get_hdf5_type< std::complex<double> >();
+  is_equal = (H5Tequal(datatype, search_type) > 0);
+  H5Tclose(search_type);
+  
+  if(is_equal)
+    {
+    if(is_complex<eT>::value == false)
+      {
+      return -1; // can't read complex data into non-complex matrix/cube
+      }
+    
+    Col< std::complex<double> > v(n_elem);
+    hid_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, void_ptr(v.memptr()));
+    arrayops::convert_cx(dest, v.memptr(), n_elem);
+    
+    return status;
+    }
+  
+  
+  return -1; // Failure.
+  }
+
+
+
+}       // namespace hdf5_misc
+#endif  // #if defined(ARMA_USE_HDF5)
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/include_atlas.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,34 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+#if defined(ARMA_USE_ATLAS)
+  #if !defined(ARMA_ATLAS_INCLUDE_DIR)
+    extern "C"
+      {
+      #include <cblas.h>
+      #include <clapack.h>
+      }
+  #else
+    #define ARMA_STR1(x) x
+    #define ARMA_STR2(x) ARMA_STR1(x)
+    
+    #define ARMA_CBLAS   ARMA_STR2(ARMA_ATLAS_INCLUDE_DIR)ARMA_STR2(cblas.h)
+    #define ARMA_CLAPACK ARMA_STR2(ARMA_ATLAS_INCLUDE_DIR)ARMA_STR2(clapack.h)
+    
+    extern "C"
+      {
+      #include ARMA_INCFILE_WRAP(ARMA_CBLAS)
+      #include ARMA_INCFILE_WRAP(ARMA_CLAPACK)
+      }
+    
+    #undef ARMA_STR1
+    #undef ARMA_STR2
+    #undef ARMA_CBLAS
+    #undef ARMA_CLAPACK
+  #endif
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/injector_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,109 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup injector
+//! @{
+
+
+
+template<typename eT>
+class mat_injector_row
+  {
+  public:
+  
+  inline      mat_injector_row();
+  
+  inline void insert(const eT val) const;
+  
+  mutable uword        n_cols;
+  mutable podarray<eT> A;
+  mutable podarray<eT> B;
+  };
+
+
+
+template<typename T1>
+class mat_injector
+  {
+  public:
+  
+  typedef typename T1::elem_type elem_type;
+  
+  inline void  insert(const elem_type val) const;
+  inline void  end_of_row()                const;
+  inline      ~mat_injector();
+  
+  
+  private:
+  
+  inline mat_injector(T1& in_X, const elem_type val);
+  inline mat_injector(T1& in_X, const injector_end_of_row<>& x);
+  
+  T1&           X;
+  mutable uword n_rows;
+  
+  mutable podarray< mat_injector_row<elem_type>* >* AA;
+  mutable podarray< mat_injector_row<elem_type>* >* BB;
+  
+  friend class Mat<elem_type>;
+  friend class Row<elem_type>;
+  friend class Col<elem_type>;
+  };
+
+
+
+//
+
+
+
+template<typename oT>
+class field_injector_row
+  {
+  public:
+  
+  inline      field_injector_row();
+  inline     ~field_injector_row();
+  
+  inline void insert(const oT& val) const;
+  
+  mutable uword      n_cols;
+  mutable field<oT>* AA;
+  mutable field<oT>* BB;
+  };
+
+  
+  
+template<typename T1>
+class field_injector
+  {
+  public:
+  
+  typedef typename T1::object_type object_type;
+  
+  inline void  insert(const object_type& val) const;
+  inline void  end_of_row()                   const;
+  inline      ~field_injector();
+  
+  
+  private:
+  
+  inline field_injector(T1& in_X, const object_type& val);
+  inline field_injector(T1& in_X, const injector_end_of_row<>& x);
+  
+  T1&           X;
+  mutable uword n_rows;
+  
+  mutable podarray< field_injector_row<object_type>* >* AA;
+  mutable podarray< field_injector_row<object_type>* >* BB;
+  
+  friend class field<object_type>;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/injector_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,584 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup injector
+//! @{
+
+
+
+template<typename eT>
+inline
+mat_injector_row<eT>::mat_injector_row()
+  : n_cols(0)
+  {
+  arma_extra_debug_sigprint();
+  
+  A.set_size( podarray_prealloc_n_elem::val );
+  }
+
+
+
+template<typename eT>
+inline
+void
+mat_injector_row<eT>::insert(const eT val) const
+  {
+  arma_extra_debug_sigprint();
+  
+  if(n_cols < A.n_elem)
+    {
+    A[n_cols] = val;
+    ++n_cols;
+    }
+  else
+    {
+    B.set_size(2 * A.n_elem);
+    
+    arrayops::copy(B.memptr(), A.memptr(), n_cols);
+    
+    B[n_cols] = val;
+    ++n_cols;
+    
+    std::swap( access::rw(A.mem),    access::rw(B.mem)    );
+    std::swap( access::rw(A.n_elem), access::rw(B.n_elem) );
+    }
+  }
+
+
+
+//
+//
+//
+
+
+
+template<typename T1>
+inline
+mat_injector<T1>::mat_injector(T1& in_X, const typename mat_injector<T1>::elem_type val)
+  : X(in_X)
+  , n_rows(1)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename mat_injector<T1>::elem_type eT;
+  
+  AA = new podarray< mat_injector_row<eT>* >;
+  BB = new podarray< mat_injector_row<eT>* >;
+  
+  podarray< mat_injector_row<eT>* >& A = *AA;
+  
+  A.set_size(n_rows);
+  
+  for(uword row=0; row<n_rows; ++row)
+    {
+    A[row] = new mat_injector_row<eT>;
+    }
+  
+  (*(A[0])).insert(val);
+  }
+
+
+
+template<typename T1>
+inline
+mat_injector<T1>::mat_injector(T1& in_X, const injector_end_of_row<>& x)
+  : X(in_X)
+  , n_rows(1)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(x);
+  
+  typedef typename mat_injector<T1>::elem_type eT;
+  
+  AA = new podarray< mat_injector_row<eT>* >;
+  BB = new podarray< mat_injector_row<eT>* >;
+  
+  podarray< mat_injector_row<eT>* >& A = *AA;
+  
+  A.set_size(n_rows);
+  
+  for(uword row=0; row<n_rows; ++row)
+    {
+    A[row] = new mat_injector_row<eT>;
+    }
+  
+  (*this).end_of_row();
+  }
+
+
+
+template<typename T1>
+inline
+mat_injector<T1>::~mat_injector()
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename mat_injector<T1>::elem_type eT;
+  
+  podarray< mat_injector_row<eT>* >& A = *AA;
+  
+  if(n_rows > 0)
+    {
+    uword max_n_cols = (*(A[0])).n_cols;
+    
+    for(uword row=1; row<n_rows; ++row)
+      {
+      const uword n_cols = (*(A[row])).n_cols;
+      
+      if(max_n_cols < n_cols)
+        {
+        max_n_cols = n_cols;
+        }
+      }
+    
+    const uword max_n_rows = ((*(A[n_rows-1])).n_cols == 0) ? n_rows-1 : n_rows;
+    
+    if(is_Mat_only<T1>::value == true)
+      {
+      X.set_size(max_n_rows, max_n_cols);
+      
+      for(uword row=0; row<max_n_rows; ++row)
+        {
+        const uword n_cols = (*(A[row])).n_cols;
+        
+        for(uword col=0; col<n_cols; ++col)
+          {
+          X.at(row,col) = (*(A[row])).A[col];
+          }
+        
+        for(uword col=n_cols; col<max_n_cols; ++col)
+          {
+          X.at(row,col) = eT(0);
+          }
+        }
+      }
+    else
+    if(is_Row<T1>::value == true)
+      {
+      arma_debug_check( (max_n_rows > 1), "matrix initialisation: incompatible dimensions" );
+      
+      const uword n_cols = (*(A[0])).n_cols;
+      
+      X.set_size(1, n_cols);
+      
+      arrayops::copy( X.memptr(), (*(A[0])).A.memptr(), n_cols );
+      }
+    else
+    if(is_Col<T1>::value == true)
+      {
+      const bool is_vec = ( (max_n_rows == 1) || (max_n_cols == 1) );
+      
+      arma_debug_check( (is_vec == false), "matrix initialisation: incompatible dimensions" );
+      
+      const uword n_elem = (std::max)(max_n_rows, max_n_cols);
+      
+      X.set_size(n_elem, 1);
+      
+      uword i = 0;
+      for(uword row=0; row<max_n_rows; ++row)
+        {
+        const uword n_cols = (*(A[0])).n_cols;
+        
+        for(uword col=0; col<n_cols; ++col)
+          {
+          X[i] = (*(A[row])).A[col];
+          ++i;
+          }
+        
+        for(uword col=n_cols; col<max_n_cols; ++col)
+          {
+          X[i] = eT(0);
+          ++i;
+          }
+        }
+      }
+    }
+  
+  for(uword row=0; row<n_rows; ++row)
+    {
+    delete A[row];
+    }
+    
+  delete AA;
+  delete BB;
+  }
+
+
+
+template<typename T1>
+inline
+void
+mat_injector<T1>::insert(const typename mat_injector<T1>::elem_type val) const
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename mat_injector<T1>::elem_type eT;
+  
+  podarray< mat_injector_row<eT>* >& A = *AA;
+  
+  (*(A[n_rows-1])).insert(val);
+  }
+
+
+
+
+template<typename T1>
+inline
+void
+mat_injector<T1>::end_of_row() const
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename mat_injector<T1>::elem_type eT;
+  
+  podarray< mat_injector_row<eT>* >& A = *AA;
+  podarray< mat_injector_row<eT>* >& B = *BB;
+  
+  B.set_size( n_rows+1 );
+  
+  arrayops::copy(B.memptr(), A.memptr(), n_rows);
+  
+  for(uword row=n_rows; row<(n_rows+1); ++row)
+    {
+    B[row] = new mat_injector_row<eT>;
+    }
+  
+  std::swap(AA, BB);
+  
+  n_rows += 1;
+  }
+
+
+
+template<typename T1>
+arma_inline
+const mat_injector<T1>&
+operator<<(const mat_injector<T1>& ref, const typename mat_injector<T1>::elem_type val)
+  {
+  arma_extra_debug_sigprint();
+  
+  ref.insert(val);
+  
+  return ref;
+  }
+
+
+
+template<typename T1>
+arma_inline
+const mat_injector<T1>&
+operator<<(const mat_injector<T1>& ref, const injector_end_of_row<>& x)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(x);
+  
+  ref.end_of_row();
+  
+  return ref;
+  }
+
+
+
+//// using a mixture of operator << and , doesn't work yet
+//// e.g. A << 1, 2, 3 << endr
+//// in the above "3 << endr" requires special handling.
+//// similarly, special handling is necessary for "endr << 3"
+//// 
+// template<typename T1>
+// arma_inline
+// const mat_injector<T1>&
+// operator,(const mat_injector<T1>& ref, const typename mat_injector<T1>::elem_type val)
+//   {
+//   arma_extra_debug_sigprint();
+//   
+//   ref.insert(val);
+//   
+//   return ref;
+//   }
+
+
+
+// template<typename T1>
+// arma_inline
+// const mat_injector<T1>&
+// operator,(const mat_injector<T1>& ref, const injector_end_of_row<>& x)
+//   {
+//   arma_extra_debug_sigprint();
+//   arma_ignore(x);
+//   
+//   ref.end_of_row();
+//   
+//   return ref;
+//   }
+
+
+
+
+//
+//
+//
+
+
+
+template<typename oT>
+inline
+field_injector_row<oT>::field_injector_row()
+  : n_cols(0)
+  {
+  arma_extra_debug_sigprint();
+  
+  AA = new field<oT>;
+  BB = new field<oT>;
+  
+  field<oT>& A = *AA;
+  
+  A.set_size( field_prealloc_n_elem::val );
+  }
+
+
+
+template<typename oT>
+inline
+field_injector_row<oT>::~field_injector_row()
+  {
+  arma_extra_debug_sigprint();
+  
+  delete AA;
+  delete BB;
+  }
+
+
+
+template<typename oT>
+inline
+void
+field_injector_row<oT>::insert(const oT& val) const
+  {
+  arma_extra_debug_sigprint();
+  
+  field<oT>& A = *AA;
+  field<oT>& B = *BB;
+  
+  if(n_cols < A.n_elem)
+    {
+    A[n_cols] = val;
+    ++n_cols;
+    }
+  else
+    {
+    B.set_size(2 * A.n_elem);
+    
+    for(uword i=0; i<n_cols; ++i)
+      {
+      B[i] = A[i];
+      }
+    
+    B[n_cols] = val;
+    ++n_cols;
+    
+    std::swap(AA, BB);
+    }
+  }
+
+
+
+//
+//
+//
+
+
+template<typename T1>
+inline
+field_injector<T1>::field_injector(T1& in_X, const typename field_injector<T1>::object_type& val)
+  : X(in_X)
+  , n_rows(1)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename field_injector<T1>::object_type oT;
+  
+  AA = new podarray< field_injector_row<oT>* >;
+  BB = new podarray< field_injector_row<oT>* >;
+  
+  podarray< field_injector_row<oT>* >& A = *AA;
+  
+  A.set_size(n_rows);
+  
+  for(uword row=0; row<n_rows; ++row)
+    {
+    A[row] = new field_injector_row<oT>;
+    }
+  
+  (*(A[0])).insert(val);
+  }
+
+
+
+template<typename T1>
+inline
+field_injector<T1>::field_injector(T1& in_X, const injector_end_of_row<>& x)
+  : X(in_X)
+  , n_rows(1)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(x);
+  
+  typedef typename field_injector<T1>::object_type oT;
+  
+  AA = new podarray< field_injector_row<oT>* >;
+  BB = new podarray< field_injector_row<oT>* >;
+  
+  podarray< field_injector_row<oT>* >& A = *AA;
+  
+  A.set_size(n_rows);
+  
+  for(uword row=0; row<n_rows; ++row)
+    {
+    A[row] = new field_injector_row<oT>;
+    }
+  
+  (*this).end_of_row();
+  }
+
+
+
+template<typename T1>
+inline
+field_injector<T1>::~field_injector()
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename field_injector<T1>::object_type oT;
+  
+  podarray< field_injector_row<oT>* >& A = *AA;
+  
+  if(n_rows > 0)
+    {
+    uword max_n_cols = (*(A[0])).n_cols;
+    
+    for(uword row=1; row<n_rows; ++row)
+      {
+      const uword n_cols = (*(A[row])).n_cols;
+      
+      if(max_n_cols < n_cols)
+        {
+        max_n_cols = n_cols;
+        }
+      }
+      
+    const uword max_n_rows = ((*(A[n_rows-1])).n_cols == 0) ? n_rows-1 : n_rows;
+    
+    X.set_size(max_n_rows, max_n_cols);
+    
+    for(uword row=0; row<max_n_rows; ++row)
+      {
+      const uword n_cols = (*(A[row])).n_cols;
+      
+      for(uword col=0; col<n_cols; ++col)
+        {
+        const field<oT>& tmp = *((*(A[row])).AA);
+        X.at(row,col) = tmp[col];
+        }
+      
+      for(uword col=n_cols; col<max_n_cols; ++col)
+        {
+        X.at(row,col) = oT();
+        }
+      }
+    }
+  
+  
+  for(uword row=0; row<n_rows; ++row)
+    {
+    delete A[row];
+    }
+  
+  delete AA;
+  delete BB;
+  }
+
+
+
+template<typename T1>
+inline
+void
+field_injector<T1>::insert(const typename field_injector<T1>::object_type& val) const
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename field_injector<T1>::object_type oT;
+  
+  podarray< field_injector_row<oT>* >& A = *AA;
+  
+  (*(A[n_rows-1])).insert(val);
+  }
+
+
+
+
+template<typename T1>
+inline
+void
+field_injector<T1>::end_of_row() const
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename field_injector<T1>::object_type oT;
+  
+  podarray< field_injector_row<oT>* >& A = *AA;
+  podarray< field_injector_row<oT>* >& B = *BB;
+  
+  B.set_size( n_rows+1 );
+  
+  for(uword row=0; row<n_rows; ++row)
+    {
+    B[row] = A[row];
+    }
+  
+  for(uword row=n_rows; row<(n_rows+1); ++row)
+    {
+    B[row] = new field_injector_row<oT>;
+    }
+  
+  std::swap(AA, BB);
+  
+  n_rows += 1;
+  }
+
+
+
+template<typename T1>
+arma_inline
+const field_injector<T1>&
+operator<<(const field_injector<T1>& ref, const typename field_injector<T1>::object_type& val)
+  {
+  arma_extra_debug_sigprint();
+  
+  ref.insert(val);
+  
+  return ref;
+  }
+
+
+
+template<typename T1>
+arma_inline
+const field_injector<T1>&
+operator<<(const field_injector<T1>& ref, const injector_end_of_row<>& x)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(x);
+  
+  ref.end_of_row();
+  
+  return ref;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/lapack_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,358 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2009 Edmund Highcock
+// Copyright (C) 2011 James Sanders
+// Copyright (C) 2012 Eric Jon Sundstrom
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+#ifdef ARMA_USE_LAPACK
+
+
+#if !defined(ARMA_BLAS_CAPITALS)
+  
+  #define arma_sgetrf sgetrf
+  #define arma_dgetrf dgetrf
+  #define arma_cgetrf cgetrf
+  #define arma_zgetrf zgetrf
+  
+  #define arma_sgetri sgetri
+  #define arma_dgetri dgetri
+  #define arma_cgetri cgetri
+  #define arma_zgetri zgetri
+  
+  #define arma_strtri strtri
+  #define arma_dtrtri dtrtri
+  #define arma_ctrtri ctrtri
+  #define arma_ztrtri ztrtri
+  
+  #define arma_ssyev  ssyev
+  #define arma_dsyev  dsyev
+
+  #define arma_cheev  cheev
+  #define arma_zheev  zheev
+  
+  #define arma_ssyevd ssyevd
+  #define arma_dsyevd dsyevd
+  
+  #define arma_cheevd cheevd
+  #define arma_zheevd zheevd
+  
+  #define arma_sgeev  sgeev
+  #define arma_dgeev  dgeev
+  
+  #define arma_cgeev  cgeev
+  #define arma_zgeev  zgeev
+  
+  #define arma_spotrf spotrf
+  #define arma_dpotrf dpotrf
+  #define arma_cpotrf cpotrf
+  #define arma_zpotrf zpotrf
+  
+  #define arma_spotri spotri
+  #define arma_dpotri dpotri
+  #define arma_cpotri cpotri
+  #define arma_zpotri zpotri
+  
+  #define arma_sgeqrf sgeqrf
+  #define arma_dgeqrf dgeqrf
+  #define arma_cgeqrf cgeqrf
+  #define arma_zgeqrf zgeqrf
+  
+  #define arma_sorgqr sorgqr
+  #define arma_dorgqr dorgqr
+  
+  #define arma_cungqr cungqr
+  #define arma_zungqr zungqr
+  
+  #define arma_sgesvd sgesvd
+  #define arma_dgesvd dgesvd
+  
+  #define arma_cgesvd cgesvd
+  #define arma_zgesvd zgesvd
+  
+  #define arma_sgesdd sgesdd
+  #define arma_dgesdd dgesdd
+  #define arma_cgesdd cgesdd
+  #define arma_zgesdd zgesdd
+  
+  #define arma_sgesv  sgesv
+  #define arma_dgesv  dgesv
+  #define arma_cgesv  cgesv
+  #define arma_zgesv  zgesv
+  
+  #define arma_sgels  sgels
+  #define arma_dgels  dgels
+  #define arma_cgels  cgels
+  #define arma_zgels  zgels
+  
+  #define arma_strtrs strtrs
+  #define arma_dtrtrs dtrtrs
+  #define arma_ctrtrs ctrtrs
+  #define arma_ztrtrs ztrtrs
+
+  #define arma_sgees  sgees
+  #define arma_dgees  dgees
+  #define arma_cgees  cgees
+  #define arma_zgees  zgees
+  
+  #define arma_strsyl strsyl
+  #define arma_dtrsyl dtrsyl
+  #define arma_ctrsyl ctrsyl
+  #define arma_ztrsyl ztrsyl
+  
+  #define arma_ssytrf ssytrf
+  #define arma_dsytrf dsytrf
+  #define arma_csytrf csytrf
+  #define arma_zsytrf zsytrf
+  
+  #define arma_ssytri ssytri
+  #define arma_dsytri dsytri
+  #define arma_csytri csytri
+  #define arma_zsytri zsytri
+  
+#else
+  
+  #define arma_sgetrf SGETRF
+  #define arma_dgetrf DGETRF
+  #define arma_cgetrf CGETRF
+  #define arma_zgetrf ZGETRF
+  
+  #define arma_sgetri SGETRI
+  #define arma_dgetri DGETRI
+  #define arma_cgetri CGETRI
+  #define arma_zgetri ZGETRI
+  
+  #define arma_strtri STRTRI
+  #define arma_dtrtri DTRTRI
+  #define arma_ctrtri CTRTRI
+  #define arma_ztrtri ZTRTRI
+  
+  #define arma_ssyev  SSYEV
+  #define arma_dsyev  DSYEV
+  
+  #define arma_cheev  CHEEV
+  #define arma_zheev  ZHEEV
+  
+  #define arma_ssyevd SSYEVD
+  #define arma_dsyevd DSYEVD
+  
+  #define arma_cheevd CHEEVD
+  #define arma_zheevd ZHEEVD
+  
+  #define arma_sgeev  SGEEV
+  #define arma_dgeev  DGEEV
+  
+  #define arma_cgeev  CGEEV
+  #define arma_zgeev  ZGEEV
+  
+  #define arma_spotrf SPOTRF
+  #define arma_dpotrf DPOTRF
+  #define arma_cpotrf CPOTRF
+  #define arma_zpotrf ZPOTRF
+  
+  #define arma_spotri SPOTRI
+  #define arma_dpotri DPOTRI
+  #define arma_cpotri CPOTRI
+  #define arma_zpotri ZPOTRI
+  
+  #define arma_sgeqrf SGEQRF
+  #define arma_dgeqrf DGEQRF
+  #define arma_cgeqrf CGEQRF
+  #define arma_zgeqrf ZGEQRF
+  
+  #define arma_sorgqr SORGQR
+  #define arma_dorgqr DORGQR
+  
+  #define arma_cungqr CUNGQR
+  #define arma_zungqr ZUNGQR
+  
+  #define arma_sgesvd SGESVD
+  #define arma_dgesvd DGESVD
+  
+  #define arma_cgesvd CGESVD
+  #define arma_zgesvd ZGESVD
+  
+  #define arma_sgesdd SGESDD
+  #define arma_dgesdd DGESDD
+  #define arma_cgesdd CGESDD
+  #define arma_zgesdd ZGESDD
+  
+  #define arma_sgesv  SGESV
+  #define arma_dgesv  DGESV
+  #define arma_cgesv  CGESV
+  #define arma_zgesv  ZGESV
+  
+  #define arma_sgels  SGELS
+  #define arma_dgels  DGELS
+  #define arma_cgels  CGELS
+  #define arma_zgels  ZGELS
+  
+  #define arma_strtrs STRTRS
+  #define arma_dtrtrs DTRTRS
+  #define arma_ctrtrs CTRTRS
+  #define arma_ztrtrs ZTRTRS
+
+  #define arma_sgees  SGEES
+  #define arma_dgees  DGEES
+  #define arma_cgees  CGEES
+  #define arma_zgees  ZGEES
+
+  #define arma_strsyl STRSYL
+  #define arma_dtrsyl DTRSYL
+  #define arma_ctrsyl CTRSYL
+  #define arma_ztrsyl ZTRSYL
+  
+  #define arma_ssytrf SSYTRF
+  #define arma_dsytrf DSYTRF
+  #define arma_csytrf CSYTRF
+  #define arma_zsytrf ZSYTRF
+  
+  #define arma_ssytri SSYTRI
+  #define arma_dsytri DSYTRI
+  #define arma_csytri CSYTRI
+  #define arma_zsytri ZSYTRI
+  
+#endif
+
+
+
+extern "C"
+  {
+  // LU factorisation
+  void arma_fortran(arma_sgetrf)(blas_int* m, blas_int* n,  float* a, blas_int* lda, blas_int* ipiv, blas_int* info);
+  void arma_fortran(arma_dgetrf)(blas_int* m, blas_int* n, double* a, blas_int* lda, blas_int* ipiv, blas_int* info);
+  void arma_fortran(arma_cgetrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda, blas_int* ipiv, blas_int* info);
+  void arma_fortran(arma_zgetrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda, blas_int* ipiv, blas_int* info);
+  
+  // matrix inversion (using LU factorisation result)
+  void arma_fortran(arma_sgetri)(blas_int* n,  float* a, blas_int* lda, blas_int* ipiv,  float* work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_dgetri)(blas_int* n, double* a, blas_int* lda, blas_int* ipiv, double* work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_cgetri)(blas_int* n,  void*  a, blas_int* lda, blas_int* ipiv,   void* work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_zgetri)(blas_int* n,  void*  a, blas_int* lda, blas_int* ipiv,   void* work, blas_int* lwork, blas_int* info);
+  
+  // matrix inversion (triangular matrices)
+  void arma_fortran(arma_strtri)(char* uplo, char* diag, blas_int* n,  float* a, blas_int* lda, blas_int* info);
+  void arma_fortran(arma_dtrtri)(char* uplo, char* diag, blas_int* n, double* a, blas_int* lda, blas_int* info);
+  void arma_fortran(arma_ctrtri)(char* uplo, char* diag, blas_int* n,   void* a, blas_int* lda, blas_int* info);
+  void arma_fortran(arma_ztrtri)(char* uplo, char* diag, blas_int* n,   void* a, blas_int* lda, blas_int* info);
+  
+  // eigenvector decomposition of symmetric real matrices
+  void arma_fortran(arma_ssyev)(char* jobz, char* uplo, blas_int* n,  float* a, blas_int* lda,  float* w,  float* work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_dsyev)(char* jobz, char* uplo, blas_int* n, double* a, blas_int* lda, double* w, double* work, blas_int* lwork, blas_int* info);
+    
+  // eigenvector decomposition of hermitian matrices (complex)
+  void arma_fortran(arma_cheev)(char* jobz, char* uplo, blas_int* n,   void* a, blas_int* lda,  float* w,   void* work, blas_int* lwork,  float* rwork, blas_int* info);
+  void arma_fortran(arma_zheev)(char* jobz, char* uplo, blas_int* n,   void* a, blas_int* lda, double* w,   void* work, blas_int* lwork, double* rwork, blas_int* info);
+  
+  // eigenvector decomposition of symmetric real matrices by divide and conquer
+  void arma_fortran(arma_ssyevd)(char* jobz, char* uplo, blas_int* n,  float* a, blas_int* lda,  float* w,  float* work, blas_int* lwork, blas_int* iwork, blas_int* liwork, blas_int* info);
+  void arma_fortran(arma_dsyevd)(char* jobz, char* uplo, blas_int* n, double* a, blas_int* lda, double* w, double* work, blas_int* lwork, blas_int* iwork, blas_int* liwork, blas_int* info);
+  
+  // eigenvector decomposition of hermitian matrices (complex) by divide and conquer
+  void arma_fortran(arma_cheevd)(char* jobz, char* uplo, blas_int* n,   void* a, blas_int* lda,  float* w,   void* work, blas_int* lwork,  float* rwork, blas_int* lrwork, blas_int* iwork, blas_int* liwork, blas_int* info);
+  void arma_fortran(arma_zheevd)(char* jobz, char* uplo, blas_int* n,   void* a, blas_int* lda, double* w,   void* work, blas_int* lwork, double* rwork, blas_int* lrwork, blas_int* iwork, blas_int* liwork, blas_int* info);
+  
+  // eigenvector decomposition of general real matrices
+  void arma_fortran(arma_sgeev)(char* jobvl, char* jobvr, blas_int* n,  float* a, blas_int* lda,  float* wr,  float* wi,  float* vl, blas_int* ldvl,  float* vr, blas_int* ldvr,  float* work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_dgeev)(char* jobvl, char* jobvr, blas_int* n, double* a, blas_int* lda, double* wr, double* wi, double* vl, blas_int* ldvl, double* vr, blas_int* ldvr, double* work, blas_int* lwork, blas_int* info);
+  
+  // eigenvector decomposition of general complex matrices
+  void arma_fortran(arma_cgeev)(char* jobvl, char* jobvr, blas_int* n, void* a, blas_int* lda, void* w, void* vl, blas_int* ldvl, void* vr, blas_int* ldvr, void* work, blas_int* lwork,  float* rwork, blas_int* info);
+  void arma_fortran(arma_zgeev)(char* jobvl, char* jobvr, blas_int* n, void* a, blas_int* lda, void* w, void* vl, blas_int* ldvl, void* vr, blas_int* ldvr, void* work, blas_int* lwork, double* rwork, blas_int* info);
+  
+  // Cholesky decomposition
+  void arma_fortran(arma_spotrf)(char* uplo, blas_int* n,  float* a, blas_int* lda, blas_int* info);
+  void arma_fortran(arma_dpotrf)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* info);
+  void arma_fortran(arma_cpotrf)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info);
+  void arma_fortran(arma_zpotrf)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info);
+  
+  // matrix inversion (using Cholesky decomposition result)
+  void arma_fortran(arma_spotri)(char* uplo, blas_int* n,  float* a, blas_int* lda, blas_int* info);
+  void arma_fortran(arma_dpotri)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* info);
+  void arma_fortran(arma_cpotri)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info);
+  void arma_fortran(arma_zpotri)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info);
+  
+  // QR decomposition
+  void arma_fortran(arma_sgeqrf)(blas_int* m, blas_int* n,  float* a, blas_int* lda,  float* tau,  float* work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_dgeqrf)(blas_int* m, blas_int* n, double* a, blas_int* lda, double* tau, double* work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_cgeqrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_zgeqrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info);
+  
+  // Q matrix calculation from QR decomposition (real matrices)
+  void arma_fortran(arma_sorgqr)(blas_int* m, blas_int* n, blas_int* k,  float* a, blas_int* lda,  float* tau,  float* work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_dorgqr)(blas_int* m, blas_int* n, blas_int* k, double* a, blas_int* lda, double* tau, double* work, blas_int* lwork, blas_int* info);
+  
+  // Q matrix calculation from QR decomposition (complex matrices)
+  void arma_fortran(arma_cungqr)(blas_int* m, blas_int* n, blas_int* k,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_zungqr)(blas_int* m, blas_int* n, blas_int* k,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info);
+  
+  // SVD (real matrices)
+  void arma_fortran(arma_sgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, float*  a, blas_int* lda, float*  s, float*  u, blas_int* ldu, float*  vt, blas_int* ldvt, float*  work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_dgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, double* a, blas_int* lda, double* s, double* u, blas_int* ldu, double* vt, blas_int* ldvt, double* work, blas_int* lwork, blas_int* info);
+  
+  // SVD (complex matrices)
+  void arma_fortran(arma_cgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, void*   a, blas_int* lda, float*  s, void*   u, blas_int* ldu, void*   vt, blas_int* ldvt, void*   work, blas_int* lwork, float*  rwork, blas_int* info);
+  void arma_fortran(arma_zgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, void*   a, blas_int* lda, double* s, void*   u, blas_int* ldu, void*   vt, blas_int* ldvt, void*   work, blas_int* lwork, double* rwork, blas_int* info);
+  
+  // SVD (real matrices) by divide and conquer
+  void arma_fortran(arma_sgesdd)(char* jobz, blas_int* m, blas_int* n, float*  a, blas_int* lda, float*  s, float*  u, blas_int* ldu, float*  vt, blas_int* ldvt, float*  work, blas_int* lwork, blas_int* iwork, blas_int* info);
+  void arma_fortran(arma_dgesdd)(char* jobz, blas_int* m, blas_int* n, double* a, blas_int* lda, double* s, double* u, blas_int* ldu, double* vt, blas_int* ldvt, double* work, blas_int* lwork, blas_int* iwork, blas_int* info);
+  
+  // SVD (complex matrices) by divide and conquer
+  void arma_fortran(arma_cgesdd)(char* jobz, blas_int* m, blas_int* n, void* a, blas_int* lda, float*  s, void* u, blas_int* ldu, void* vt, blas_int* ldvt, void* work, blas_int* lwork, float*  rwork, blas_int* iwork, blas_int* info);
+  void arma_fortran(arma_zgesdd)(char* jobz, blas_int* m, blas_int* n, void* a, blas_int* lda, double* s, void* u, blas_int* ldu, void* vt, blas_int* ldvt, void* work, blas_int* lwork, double* rwork, blas_int* iwork, blas_int* info);
+  
+  // solve system of linear equations, using LU decomposition
+  void arma_fortran(arma_sgesv)(blas_int* n, blas_int* nrhs, float*  a, blas_int* lda, blas_int* ipiv, float*  b, blas_int* ldb, blas_int* info);
+  void arma_fortran(arma_dgesv)(blas_int* n, blas_int* nrhs, double* a, blas_int* lda, blas_int* ipiv, double* b, blas_int* ldb, blas_int* info);
+  void arma_fortran(arma_cgesv)(blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, blas_int* ipiv, void*   b, blas_int* ldb, blas_int* info);
+  void arma_fortran(arma_zgesv)(blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, blas_int* ipiv, void*   b, blas_int* ldb, blas_int* info);
+  
+  // solve over/underdetermined system of linear equations
+  void arma_fortran(arma_sgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, float*  a, blas_int* lda, float*  b, blas_int* ldb, float*  work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_dgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, double* a, blas_int* lda, double* b, blas_int* ldb, double* work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_cgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, void*   b, blas_int* ldb, void*   work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_zgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, void*   b, blas_int* ldb, void*   work, blas_int* lwork, blas_int* info);
+  
+  // solve a triangular system of linear equations
+  void arma_fortran(arma_strtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const float*  a, blas_int* lda, float*  b, blas_int* ldb, blas_int* info);
+  void arma_fortran(arma_dtrtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const double* a, blas_int* lda, double* b, blas_int* ldb, blas_int* info);
+  void arma_fortran(arma_ctrtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const void*   a, blas_int* lda, void*   b, blas_int* ldb, blas_int* info);
+  void arma_fortran(arma_ztrtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const void*   a, blas_int* lda, void*   b, blas_int* ldb, blas_int* info);
+  
+  // Schur decomposition (real matrices)
+  void arma_fortran(arma_sgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, float*  a, blas_int* lda, blas_int* sdim, float*  wr, float*  wi, float*  vs, blas_int* ldvs, float*  work, blas_int* lwork, blas_int* bwork, blas_int* info);
+  void arma_fortran(arma_dgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, double* a, blas_int* lda, blas_int* sdim, double* wr, double* wi, double* vs, blas_int* ldvs, double* work, blas_int* lwork, blas_int* bwork, blas_int* info);
+  
+  // Schur decomposition (complex matrices)
+  void arma_fortran(arma_cgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, void* a, blas_int* lda, blas_int* sdim, void* w, void* vs, blas_int* ldvs, void* work, blas_int* lwork, float*  rwork, blas_int* bwork, blas_int* info);
+  void arma_fortran(arma_zgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, void* a, blas_int* lda, blas_int* sdim, void* w, void* vs, blas_int* ldvs, void* work, blas_int* lwork, double* rwork, blas_int* bwork, blas_int* info);
+  
+  // solve a Sylvester equation ax + xb = c, with a and b assumed to be in Schur form
+  void arma_fortran(arma_strsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const float*  a, blas_int* lda, const float*  b, blas_int* ldb, float*  c, blas_int* ldc, float*  scale, blas_int* info);
+  void arma_fortran(arma_dtrsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const double* a, blas_int* lda, const double* b, blas_int* ldb, double* c, blas_int* ldc, double* scale, blas_int* info);
+  void arma_fortran(arma_ctrsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const void*   a, blas_int* lda, const void*   b, blas_int* ldb, void*   c, blas_int* ldc, float*  scale, blas_int* info);
+  void arma_fortran(arma_ztrsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const void*   a, blas_int* lda, const void*   b, blas_int* ldb, void*   c, blas_int* ldc, double* scale, blas_int* info);
+  
+  void arma_fortran(arma_ssytrf)(char* uplo, blas_int* n, float*  a, blas_int* lda, blas_int* ipiv, float*  work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_dsytrf)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* ipiv, double* work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_csytrf)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* lwork, blas_int* info);
+  void arma_fortran(arma_zsytrf)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* lwork, blas_int* info);
+  
+  void arma_fortran(arma_ssytri)(char* uplo, blas_int* n, float*  a, blas_int* lda, blas_int* ipiv, float*  work, blas_int* info);
+  void arma_fortran(arma_dsytri)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* ipiv, double* work, blas_int* info);
+  void arma_fortran(arma_csytri)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* info);
+  void arma_fortran(arma_zsytri)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* info);
+  
+  // void arma_fortran(arma_dgeqp3)(blas_int* m, blas_int* n, double* a, blas_int* lda, blas_int* jpvt, double* tau, double* work, blas_int* lwork, blas_int* info);
+  // void arma_fortran(arma_dormqr)(char* side, char* trans, blas_int* m, blas_int* n, blas_int* k, double* a, blas_int* lda, double* tau, double* c, blas_int* ldc, double* work, blas_int* lwork, blas_int* info);
+  // void  arma_fortran(arma_dposv)(char* uplo, blas_int* n, blas_int* nrhs, double* a, blas_int* lda, double* b, blas_int* ldb, blas_int* info);
+  }
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/lapack_wrapper.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,818 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2009 Edmund Highcock
+// Copyright (C) 2011 James Sanders
+// Copyright (C) 2012 Eric Jon Sundstrom
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+#ifdef ARMA_USE_LAPACK
+
+
+//! \namespace lapack namespace for LAPACK functions
+namespace lapack
+  {
+  
+  
+  template<typename eT>
+  inline
+  void
+  getrf(blas_int* m, blas_int* n, eT* a, blas_int* lda, blas_int* ipiv, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_sgetrf)(m, n, (T*)a, lda, ipiv, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dgetrf)(m, n, (T*)a, lda, ipiv, info);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_cgetrf)(m, n, (T*)a, lda, ipiv, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_zgetrf)(m, n, (T*)a, lda, ipiv, info);
+      }
+    }
+    
+    
+    
+  template<typename eT>
+  inline
+  void
+  getri(blas_int* n,  eT* a, blas_int* lda, blas_int* ipiv, eT* work, blas_int* lwork, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_sgetri)(n, (T*)a, lda, ipiv, (T*)work, lwork, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dgetri)(n, (T*)a, lda, ipiv, (T*)work, lwork, info);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_cgetri)(n, (T*)a, lda, ipiv, (T*)work, lwork, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_zgetri)(n, (T*)a, lda, ipiv, (T*)work, lwork, info);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  trtri(char* uplo, char* diag, blas_int* n, eT* a, blas_int* lda, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_strtri)(uplo, diag, n, (T*)a, lda, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dtrtri)(uplo, diag, n, (T*)a, lda, info);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_ctrtri)(uplo, diag, n, (T*)a, lda, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_ztrtri)(uplo, diag, n, (T*)a, lda, info);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  syev(char* jobz, char* uplo, blas_int* n, eT* a, blas_int* lda, eT* w,  eT* work, blas_int* lwork, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_ssyev)(jobz, uplo, n, (T*)a, lda, (T*)w, (T*)work, lwork, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dsyev)(jobz, uplo, n, (T*)a, lda, (T*)w, (T*)work, lwork, info);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  syevd(char* jobz, char* uplo, blas_int* n, eT* a, blas_int* lda, eT* w,  eT* work, blas_int* lwork, blas_int* iwork, blas_int* liwork, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_ssyevd)(jobz, uplo, n, (T*)a, lda, (T*)w, (T*)work, lwork, iwork, liwork, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dsyevd)(jobz, uplo, n, (T*)a, lda, (T*)w, (T*)work, lwork, iwork, liwork, info);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  heev
+    (
+    char* jobz, char* uplo, blas_int* n,
+    eT* a, blas_int* lda, typename eT::value_type* w,
+    eT* work, blas_int* lwork, typename eT::value_type* rwork,
+    blas_int* info
+    )
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef float T;
+      typedef typename std::complex<T> cx_T;
+      arma_fortran(arma_cheev)(jobz, uplo, n, (cx_T*)a, lda, (T*)w, (cx_T*)work, lwork, (T*)rwork, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef double T;
+      typedef typename std::complex<T> cx_T;
+      arma_fortran(arma_zheev)(jobz, uplo, n, (cx_T*)a, lda, (T*)w, (cx_T*)work, lwork, (T*)rwork, info);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  heevd
+    (
+    char* jobz, char* uplo, blas_int* n,
+    eT* a, blas_int* lda, typename eT::value_type* w,
+    eT* work, blas_int* lwork, typename eT::value_type* rwork, 
+    blas_int* lrwork, blas_int* iwork, blas_int* liwork,
+    blas_int* info
+    )
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef float T;
+      typedef typename std::complex<T> cx_T;
+      arma_fortran(arma_cheevd)(jobz, uplo, n, (cx_T*)a, lda, (T*)w, (cx_T*)work, lwork, (T*)rwork, lrwork, iwork, liwork, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef double T;
+      typedef typename std::complex<T> cx_T;
+      arma_fortran(arma_zheevd)(jobz, uplo, n, (cx_T*)a, lda, (T*)w, (cx_T*)work, lwork, (T*)rwork, lrwork, iwork, liwork, info);
+      }
+    }
+  
+	
+	
+  template<typename eT>
+  inline
+  void
+  geev
+    (
+    char* jobvl, char* jobvr, blas_int* n, 
+    eT* a, blas_int* lda, eT* wr, eT* wi, eT* vl, 
+    blas_int* ldvl, eT* vr, blas_int* ldvr, 
+    eT* work, blas_int* lwork,
+    blas_int* info
+    )
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_sgeev)(jobvl, jobvr, n,  (T*)a, lda, (T*)wr, (T*)wi, (T*)vl, ldvl, (T*)vr, ldvr, (T*)work, lwork, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dgeev)(jobvl, jobvr, n,  (T*)a, lda, (T*)wr, (T*)wi, (T*)vl, ldvl, (T*)vr, ldvr, (T*)work, lwork, info);
+      }
+    }
+
+
+  template<typename eT>
+  inline
+  void
+  cx_geev
+    (
+    char* jobvl, char* jobvr, blas_int* n, 
+    eT* a, blas_int* lda, eT* w, 
+    eT* vl, blas_int* ldvl, 
+    eT* vr, blas_int* ldvr, 
+    eT* work, blas_int* lwork, typename eT::value_type* rwork, 
+    blas_int* info
+    )
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef float T;
+      typedef typename std::complex<T> cx_T;
+      arma_fortran(arma_cgeev)(jobvl, jobvr, n, (cx_T*)a, lda, (cx_T*)w, (cx_T*)vl, ldvl, (cx_T*)vr, ldvr, (cx_T*)work, lwork, (T*)rwork, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef double T;
+      typedef typename std::complex<T> cx_T;
+      arma_fortran(arma_zgeev)(jobvl, jobvr, n, (cx_T*)a, lda, (cx_T*)w, (cx_T*)vl, ldvl, (cx_T*)vr, ldvr, (cx_T*)work, lwork, (T*)rwork, info);
+      }
+    }
+  
+
+
+  
+  template<typename eT>
+  inline
+  void
+  potrf(char* uplo, blas_int* n, eT* a, blas_int* lda, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_spotrf)(uplo, n, (T*)a, lda, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dpotrf)(uplo, n, (T*)a, lda, info);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_cpotrf)(uplo, n, (T*)a, lda, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_zpotrf)(uplo, n, (T*)a, lda, info);
+      }
+    
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  potri(char* uplo, blas_int* n, eT* a, blas_int* lda, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_spotri)(uplo, n, (T*)a, lda, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dpotri)(uplo, n, (T*)a, lda, info);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_cpotri)(uplo, n, (T*)a, lda, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_zpotri)(uplo, n, (T*)a, lda, info);
+      }
+    
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  geqrf(blas_int* m, blas_int* n, eT* a, blas_int* lda, eT* tau, eT* work, blas_int* lwork, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_sgeqrf)(m, n, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dgeqrf)(m, n, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_cgeqrf)(m, n, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_zgeqrf)(m, n, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
+      }
+    
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  orgqr(blas_int* m, blas_int* n, blas_int* k, eT* a, blas_int* lda, eT* tau, eT* work, blas_int* lwork, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_sorgqr)(m, n, k, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dorgqr)(m, n, k, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
+      }
+    }
+
+
+  
+  template<typename eT>
+  inline
+  void
+  ungqr(blas_int* m, blas_int* n, blas_int* k, eT* a, blas_int* lda, eT* tau, eT* work, blas_int* lwork, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_cungqr)(m, n, k, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_zungqr)(m, n, k, (T*)a, lda, (T*)tau, (T*)work, lwork, info);
+      }
+    }
+  
+  
+  template<typename eT>
+  inline
+  void
+  gesvd
+    (
+    char* jobu, char* jobvt, blas_int* m, blas_int* n, eT* a, blas_int* lda,
+    eT* s, eT* u, blas_int* ldu, eT* vt, blas_int* ldvt,
+    eT* work, blas_int* lwork, blas_int* info
+    )
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_sgesvd)(jobu, jobvt, m, n, (T*)a, lda, (T*)s, (T*)u, ldu, (T*)vt, ldvt, (T*)work, lwork, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dgesvd)(jobu, jobvt, m, n, (T*)a, lda, (T*)s, (T*)u, ldu, (T*)vt, ldvt, (T*)work, lwork, info);
+      }
+    }
+  
+  
+  
+  template<typename T>
+  inline
+  void
+  cx_gesvd
+    (
+    char* jobu, char* jobvt, blas_int* m, blas_int* n, std::complex<T>* a, blas_int* lda,
+    T* s, std::complex<T>* u, blas_int* ldu, std::complex<T>* vt, blas_int* ldvt, 
+    std::complex<T>* work, blas_int* lwork, T* rwork, blas_int* info
+    )
+    {
+    arma_type_check(( is_supported_blas_type<T>::value == false ));
+    arma_type_check(( is_supported_blas_type< std::complex<T> >::value == false ));
+    
+    if(is_float<T>::value == true)
+      {
+      typedef float bT;
+      arma_fortran(arma_cgesvd)
+        (
+        jobu, jobvt, m, n, (std::complex<bT>*)a, lda,
+        (bT*)s, (std::complex<bT>*)u, ldu, (std::complex<bT>*)vt, ldvt,
+        (std::complex<bT>*)work, lwork, (bT*)rwork, info
+        );
+      }
+    else
+    if(is_double<T>::value == true)
+      {
+      typedef double bT;
+      arma_fortran(arma_zgesvd)
+        (
+        jobu, jobvt, m, n, (std::complex<bT>*)a, lda,
+        (bT*)s, (std::complex<bT>*)u, ldu, (std::complex<bT>*)vt, ldvt,
+        (std::complex<bT>*)work, lwork, (bT*)rwork, info
+        );
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  gesdd
+    (
+    char* jobz, blas_int* m, blas_int* n,
+    eT* a, blas_int* lda, eT* s, eT* u, blas_int* ldu, eT* vt, blas_int* ldvt,
+    eT* work, blas_int* lwork, blas_int* iwork, blas_int* info
+    )
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_sgesdd)(jobz, m, n, (T*)a, lda, (T*)s, (T*)u, ldu, (T*)vt, ldvt, (T*)work, lwork, iwork, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dgesdd)(jobz, m, n, (T*)a, lda, (T*)s, (T*)u, ldu, (T*)vt, ldvt, (T*)work, lwork, iwork, info);
+      }
+    }
+  
+  
+  
+  template<typename T>
+  inline
+  void
+  cx_gesdd
+    (
+    char* jobz, blas_int* m, blas_int* n,
+    std::complex<T>* a, blas_int* lda, T* s, std::complex<T>* u, blas_int* ldu, std::complex<T>* vt, blas_int* ldvt,
+    std::complex<T>* work, blas_int* lwork, T* rwork, blas_int* iwork, blas_int* info
+    )
+    {
+    arma_type_check(( is_supported_blas_type<T>::value == false ));
+    arma_type_check(( is_supported_blas_type< std::complex<T> >::value == false ));
+    
+    if(is_float<T>::value == true)
+      {
+      typedef float bT;
+      arma_fortran(arma_cgesdd)
+        (
+        jobz, m, n,
+        (std::complex<bT>*)a, lda, (bT*)s, (std::complex<bT>*)u, ldu, (std::complex<bT>*)vt, ldvt,
+        (std::complex<bT>*)work, lwork, (bT*)rwork, iwork, info
+        );
+      }
+    else
+    if(is_double<T>::value == true)
+      {
+      typedef double bT;
+      arma_fortran(arma_zgesdd)
+        (
+        jobz, m, n,
+        (std::complex<bT>*)a, lda, (bT*)s, (std::complex<bT>*)u, ldu, (std::complex<bT>*)vt, ldvt,
+        (std::complex<bT>*)work, lwork, (bT*)rwork, iwork, info
+        );
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  gesv(blas_int* n, blas_int* nrhs, eT* a, blas_int* lda, blas_int* ipiv, eT* b, blas_int* ldb, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_sgesv)(n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dgesv)(n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_cgesv)(n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_zgesv)(n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  gels(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, eT* a, blas_int* lda, eT* b, blas_int* ldb, eT* work, blas_int* lwork, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_sgels)(trans, m, n, nrhs, (T*)a, lda, (T*)b, ldb, (T*)work, lwork, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dgels)(trans, m, n, nrhs, (T*)a, lda, (T*)b, ldb, (T*)work, lwork, info);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_cgels)(trans, m, n, nrhs, (T*)a, lda, (T*)b, ldb, (T*)work, lwork, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_zgels)(trans, m, n, nrhs, (T*)a, lda, (T*)b, ldb, (T*)work, lwork, info);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  trtrs(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const eT* a, blas_int* lda, eT* b, blas_int* ldb, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_strtrs)(uplo, trans, diag, n, nrhs, (T*)a, lda, (T*)b, ldb, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dtrtrs)(uplo, trans, diag, n, nrhs, (T*)a, lda, (T*)b, ldb, info);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_ctrtrs)(uplo, trans, diag, n, nrhs, (T*)a, lda, (T*)b, ldb, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_ztrtrs)(uplo, trans, diag, n, nrhs, (T*)a, lda, (T*)b, ldb, info);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  gees(char* jobvs, char* sort, blas_int* select, blas_int* n, eT* a, blas_int* lda, blas_int* sdim, eT* wr, eT* wi, eT* vs, blas_int* ldvs, eT* work, blas_int* lwork, blas_int* bwork, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_sgees)(jobvs, sort, select, n, (T*)a, lda, sdim, (T*)wr, (T*)wi, (T*)vs, ldvs, (T*)work, lwork, bwork, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dgees)(jobvs, sort, select, n, (T*)a, lda, sdim, (T*)wr, (T*)wi, (T*)vs, ldvs, (T*)work, lwork, bwork, info);
+      }
+    }
+  
+  
+  
+  template<typename T>
+  inline
+  void
+  cx_gees(char* jobvs, char* sort, blas_int* select, blas_int* n, std::complex<T>* a, blas_int* lda, blas_int* sdim, std::complex<T>* w, std::complex<T>* vs, blas_int* ldvs, std::complex<T>* work, blas_int* lwork, T* rwork, blas_int* bwork, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<T>::value == false ));
+    arma_type_check(( is_supported_blas_type< std::complex<T> >::value == false ));
+    
+    if(is_float<T>::value == true)
+      {
+      typedef float bT;
+      typedef std::complex<bT> cT;
+      arma_fortran(arma_cgees)(jobvs, sort, select, n, (cT*)a, lda, sdim, (cT*)w, (cT*)vs, ldvs, (cT*)work, lwork, (bT*)rwork, bwork, info);
+      }
+    else
+    if(is_double<T>::value == true)
+      {
+      typedef double bT;
+      typedef std::complex<bT> cT;
+      arma_fortran(arma_zgees)(jobvs, sort, select, n, (cT*)a, lda, sdim, (cT*)w, (cT*)vs, ldvs, (cT*)work, lwork, (bT*)rwork, bwork, info);
+      }
+    }
+  
+  
+  
+  template<typename eT>
+  inline
+  void
+  trsyl(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const eT* a, blas_int* lda, const eT* b, blas_int* ldb, eT* c, blas_int* ldc, eT* scale, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_strsyl)(transa, transb, isgn, m, n, (T*)a, lda, (T*)b, ldb, (T*)c, ldc, (T*)scale, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dtrsyl)(transa, transb, isgn, m, n, (T*)a, lda, (T*)b, ldb, (T*)c, ldc, (T*)scale, info);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_ctrsyl)(transa, transb, isgn, m, n, (T*)a, lda, (T*)b, ldb, (T*)c, ldc, (float*)scale, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_ztrsyl)(transa, transb, isgn, m, n, (T*)a, lda, (T*)b, ldb, (T*)c, ldc, (double*)scale, info);
+      }
+    }
+  
+  
+  template<typename eT>
+  inline
+  void
+  sytrf(char* uplo, blas_int* n, eT* a, blas_int* lda, blas_int* ipiv, eT* work, blas_int* lwork, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_ssytrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dsytrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_csytrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_zsytrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info);
+      }
+    }
+  
+  
+  template<typename eT>
+  inline
+  void
+  sytri(char* uplo, blas_int* n, eT* a, blas_int* lda, blas_int* ipiv, eT* work, blas_int* info)
+    {
+    arma_type_check(( is_supported_blas_type<eT>::value == false ));
+    
+    if(is_float<eT>::value == true)
+      {
+      typedef float T;
+      arma_fortran(arma_ssytri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info);
+      }
+    else
+    if(is_double<eT>::value == true)
+      {
+      typedef double T;
+      arma_fortran(arma_dsytri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info);
+      }
+    else
+    if(is_supported_complex_float<eT>::value == true)
+      {
+      typedef std::complex<float> T;
+      arma_fortran(arma_csytri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info);
+      }
+    else
+    if(is_supported_complex_double<eT>::value == true)
+      {
+      typedef std::complex<double> T;
+      arma_fortran(arma_zsytri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info);
+      }
+    }
+  
+  
+  }
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/memory.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,209 @@
+// Copyright (C) 2012-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2012-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup memory
+//! @{
+
+
+class memory
+  {
+  public:
+  
+                        arma_inline             static uword enlarge_to_mult_of_chunksize(const uword n_elem);
+  
+  template<typename eT> arma_inline arma_malloc static eT*   acquire(const uword n_elem);
+  
+  template<typename eT> arma_inline arma_malloc static eT*   acquire_chunked(const uword n_elem);
+  
+  template<typename eT> arma_inline             static void  release(eT* mem);
+  
+  
+  template<typename eT> arma_inline static bool      is_aligned(const eT*  mem);
+  template<typename eT> arma_inline static void mark_as_aligned(      eT*& mem);
+  template<typename eT> arma_inline static void mark_as_aligned(const eT*& mem);
+  };
+
+
+
+arma_inline
+uword
+memory::enlarge_to_mult_of_chunksize(const uword n_elem)
+  {
+  const uword chunksize = arma_config::spmat_chunksize;
+  
+  // this relies on integer division
+  const uword n_elem_mod = ((n_elem % chunksize) != 0) ? ((n_elem / chunksize) + 1) * chunksize : n_elem;
+  
+  return n_elem_mod;
+  }
+
+
+
+template<typename eT>
+arma_inline
+arma_malloc
+eT*
+memory::acquire(const uword n_elem)
+  {
+  #if   defined(ARMA_USE_TBB_ALLOC)
+    {
+    return ( (eT *) scalable_malloc(sizeof(eT)*n_elem) );
+    }
+  #elif defined(ARMA_USE_MKL_ALLOC)
+    {
+    return ( (eT *) mkl_malloc( sizeof(eT)*n_elem, 128 ) );
+    }
+  #elif defined(ARMA_HAVE_POSIX_MEMALIGN)
+    {
+    eT* memptr;
+    
+    const size_t alignment = 16;  // change the 16 to 64 if you wish to align to the cache line
+    
+    int status = posix_memalign((void **)&memptr, ( (alignment >= sizeof(void*)) ? alignment : sizeof(void*) ), sizeof(eT)*n_elem);
+    
+    return (status == 0) ? memptr : NULL;
+    }
+  #elif defined(_MSC_VER)
+    {
+    return ( (eT *) _aligned_malloc( sizeof(eT)*n_elem, 16 ) );  // lives in malloc.h
+    }
+  #else
+    {
+    //return ( new(std::nothrow) eT[n_elem] );
+    return ( (eT *) malloc(sizeof(eT)*n_elem) );
+    }
+  #endif
+  
+  // TODO: for mingw, use __mingw_aligned_malloc
+  }
+
+
+
+//! get memory in multiples of chunks, holding at least n_elem
+template<typename eT>
+arma_inline
+arma_malloc
+eT*
+memory::acquire_chunked(const uword n_elem)
+  {
+  const uword n_elem_mod = memory::enlarge_to_mult_of_chunksize(n_elem);
+  
+  return memory::acquire<eT>(n_elem_mod);
+  }
+
+
+
+template<typename eT>
+arma_inline
+void
+memory::release(eT* mem)
+  {
+  #if   defined(ARMA_USE_TBB_ALLOC)
+    {
+    scalable_free( (void *)(mem) );
+    }
+  #elif defined(ARMA_USE_MKL_ALLOC)
+    {
+    mkl_free( (void *)(mem) );
+    }
+  #elif defined(ARMA_HAVE_POSIX_MEMALIGN)
+    {
+    free( (void *)(mem) );
+    }
+  #elif defined(_MSC_VER)
+    {
+    _aligned_free( (void *)(mem) );
+    }
+  #else
+    {
+    //delete [] mem;
+    free( (void *)(mem) );
+    }
+  #endif
+  
+  // TODO: for mingw, use __mingw_aligned_free
+  }
+
+
+
+template<typename eT>
+arma_inline
+bool
+memory::is_aligned(const eT* mem)
+  {
+  #if (defined(ARMA_HAVE_ICC_ASSUME_ALIGNED) || defined(ARMA_HAVE_GCC_ASSUME_ALIGNED)) && !defined(ARMA_DONT_CHECK_ALIGNMENT)
+    {
+    return ((std::ptrdiff_t(mem) & 0x0F) == 0);
+    }
+  #else
+    {
+    arma_ignore(mem);
+    
+    return false;
+    }
+  #endif
+  }
+
+
+
+template<typename eT>
+arma_inline
+void
+memory::mark_as_aligned(eT*& mem)
+  {
+  #if defined(ARMA_HAVE_ICC_ASSUME_ALIGNED)
+    {
+    __assume_aligned(mem, 16);
+    }
+  #elif defined(ARMA_HAVE_GCC_ASSUME_ALIGNED)
+    {
+    mem = (eT*)__builtin_assume_aligned(mem, 16);
+    }
+  #else
+    {
+    arma_ignore(mem);
+    }
+  #endif
+  
+  // TODO: MSVC?  __assume( (mem & 0x0F) == 0 );
+  //
+  // http://comments.gmane.org/gmane.comp.gcc.patches/239430
+  // GCC __builtin_assume_aligned is similar to ICC's __assume_aligned,
+  // so for lvalue first argument ICC's __assume_aligned can be emulated using
+  // #define __assume_aligned(lvalueptr, align) lvalueptr = __builtin_assume_aligned (lvalueptr, align) 
+  //
+  // http://www.inf.ethz.ch/personal/markusp/teaching/263-2300-ETH-spring11/slides/class19.pdf
+  // http://software.intel.com/sites/products/documentation/hpc/composerxe/en-us/cpp/lin/index.htm
+  // http://d3f8ykwhia686p.cloudfront.net/1live/intel/CompilerAutovectorizationGuide.pdf
+  }
+
+
+
+template<typename eT>
+arma_inline
+void
+memory::mark_as_aligned(const eT*& mem)
+  {
+  #if defined(ARMA_HAVE_ICC_ASSUME_ALIGNED)
+    {
+    __assume_aligned(mem, 16);
+    }
+  #elif defined(ARMA_HAVE_GCC_ASSUME_ALIGNED)
+    {
+    mem = (const eT*)__builtin_assume_aligned(mem, 16);
+    }
+  #else
+    {
+    arma_ignore(mem);
+    }
+  #endif
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/mtGlueCube_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,33 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup mtGlueCube
+//! @{
+
+
+
+template<typename out_eT, typename T1, typename T2, typename glue_type>
+class mtGlueCube : public BaseCube<out_eT, mtGlueCube<out_eT, T1, T2, glue_type> >
+  {
+  public:
+  
+  typedef          out_eT                       elem_type;
+  typedef typename get_pod_type<out_eT>::result pod_type;
+  
+  arma_inline  mtGlueCube(const T1& in_A, const T2& in_B);
+  arma_inline  mtGlueCube(const T1& in_A, const T2& in_B, const uword in_aux_uword);
+  arma_inline ~mtGlueCube();
+  
+  arma_aligned const T1&   A;         //!< first operand
+  arma_aligned const T2&   B;         //!< second operand
+  arma_aligned       uword aux_uword; //!< storage of auxiliary data, uword format
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/mtGlueCube_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,46 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup mtGlueCube
+//! @{
+
+
+
+template<typename out_eT, typename T1, typename T2, typename glue_type>
+inline
+mtGlueCube<out_eT,T1,T2,glue_type>::mtGlueCube(const T1& in_A, const T2& in_B)
+  : A(in_A)
+  , B(in_B)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename out_eT, typename T1, typename T2, typename glue_type>
+inline
+mtGlueCube<out_eT,T1,T2,glue_type>::mtGlueCube(const T1& in_A, const T2& in_B, const uword in_aux_uword)
+  : A(in_A)
+  , B(in_B)
+  , aux_uword(in_aux_uword)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename out_eT, typename T1, typename T2, typename glue_type>
+inline
+mtGlueCube<out_eT,T1,T2,glue_type>::~mtGlueCube()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/mtGlue_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,36 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup mtGlue
+//! @{
+
+
+
+template<typename out_eT, typename T1, typename T2, typename glue_type>
+class mtGlue : public Base<out_eT, mtGlue<out_eT, T1, T2, glue_type> >
+  {
+  public:
+  
+  typedef          out_eT                       elem_type;
+  typedef typename get_pod_type<out_eT>::result pod_type;
+  
+  static const bool is_row = ( is_glue_mixed_elem<glue_type>::value && (T1::is_row || T2::is_row) ) || ( is_glue_mixed_times<glue_type>::value && T1::is_row );
+  static const bool is_col = ( is_glue_mixed_elem<glue_type>::value && (T1::is_col || T2::is_col) ) || ( is_glue_mixed_times<glue_type>::value && T2::is_col );
+  
+  arma_inline  mtGlue(const T1& in_A, const T2& in_B);
+  arma_inline  mtGlue(const T1& in_A, const T2& in_B, const uword in_aux_uword);
+  arma_inline ~mtGlue();
+  
+  arma_aligned const T1&   A;         //!< first operand
+  arma_aligned const T2&   B;         //!< second operand
+  arma_aligned       uword aux_uword; //!< storage of auxiliary data, uword format
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/mtGlue_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,46 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup mtGlue
+//! @{
+
+
+
+template<typename out_eT, typename T1, typename T2, typename glue_type>
+inline
+mtGlue<out_eT,T1,T2,glue_type>::mtGlue(const T1& in_A, const T2& in_B)
+  : A(in_A)
+  , B(in_B)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename out_eT, typename T1, typename T2, typename glue_type>
+inline
+mtGlue<out_eT,T1,T2,glue_type>::mtGlue(const T1& in_A, const T2& in_B, const uword in_aux_uword)
+  : A(in_A)
+  , B(in_B)
+  , aux_uword(in_aux_uword)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename out_eT, typename T1, typename T2, typename glue_type>
+inline
+mtGlue<out_eT,T1,T2,glue_type>::~mtGlue()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/mtOpCube_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,45 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup mtOpCube
+//! @{
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+class mtOpCube : public BaseCube<out_eT, mtOpCube<out_eT, T1, op_type> >
+  {
+  public:
+  
+  typedef          out_eT                       elem_type;
+  typedef typename get_pod_type<out_eT>::result pod_type;
+
+  typedef typename T1::elem_type                in_eT;
+
+  inline explicit mtOpCube(const T1& in_m);
+  inline          mtOpCube(const T1& in_m, const in_eT in_aux);
+  inline          mtOpCube(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
+  inline          mtOpCube(const T1& in_m, const in_eT in_aux,         const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
+  
+  inline          mtOpCube(const char junk, const T1& in_m, const out_eT in_aux);
+  
+  inline         ~mtOpCube();
+    
+  
+  arma_aligned const T1&    m;            //!< storage of reference to the operand (eg. a matrix)
+  arma_aligned       in_eT  aux;          //!< storage of auxiliary data, using the element type as used by T1
+  arma_aligned       out_eT aux_out_eT;   //!< storage of auxiliary data, using the element type as specified by the out_eT template parameter
+  arma_aligned       uword  aux_uword_a;  //!< storage of auxiliary data, uword format
+  arma_aligned       uword  aux_uword_b;  //!< storage of auxiliary data, uword format
+  arma_aligned       uword  aux_uword_c;  //!< storage of auxiliary data, uword format
+  
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/mtOpCube_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,83 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup mtOpCube
+//! @{
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtOpCube<out_eT, T1, op_type>::mtOpCube(const T1& in_m)
+  : m(in_m)
+  {
+  arma_extra_debug_sigprint();
+  }
+  
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtOpCube<out_eT, T1, op_type>::mtOpCube(const T1& in_m, const typename T1::elem_type in_aux)
+  : m(in_m)
+  , aux(in_aux)
+  {
+  arma_extra_debug_sigprint();
+  }
+  
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtOpCube<out_eT, T1, op_type>::mtOpCube(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c)
+  : m(in_m)
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  , aux_uword_c(in_aux_uword_c)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtOpCube<out_eT, T1, op_type>::mtOpCube(const T1& in_m, const typename T1::elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c)
+  : m(in_m)
+  , aux(in_aux)
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  , aux_uword_c(in_aux_uword_c)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtOpCube<out_eT, T1, op_type>::mtOpCube(const char junk, const T1& in_m, const out_eT in_aux)
+  : m(in_m)
+  , aux_out_eT(in_aux)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  }
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtOpCube<out_eT, T1, op_type>::~mtOpCube()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/mtOp_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,47 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup mtOp
+//! @{
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+class mtOp : public Base<out_eT, mtOp<out_eT, T1, op_type> >
+  {
+  public:
+  
+  typedef          out_eT                       elem_type;
+  typedef typename get_pod_type<out_eT>::result pod_type;
+
+  typedef typename T1::elem_type                in_eT;
+
+  static const bool is_row = T1::is_row && is_op_mixed_elem<op_type>::value;
+  static const bool is_col = T1::is_col && is_op_mixed_elem<op_type>::value; 
+  
+  inline explicit mtOp(const T1& in_m);
+  inline          mtOp(const T1& in_m, const in_eT in_aux);
+  inline          mtOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
+  inline          mtOp(const T1& in_m, const in_eT in_aux,         const uword in_aux_uword_a, const uword in_aux_uword_b);
+  
+  inline          mtOp(const char junk, const T1& in_m, const out_eT in_aux);
+  
+  inline         ~mtOp();
+    
+  
+  arma_aligned const T1&    m;            //!< storage of reference to the operand (eg. a matrix)
+  arma_aligned       in_eT  aux;          //!< storage of auxiliary data, using the element type as used by T1
+  arma_aligned       out_eT aux_out_eT;   //!< storage of auxiliary data, using the element type as specified by the out_eT template parameter
+  arma_aligned       uword  aux_uword_a;  //!< storage of auxiliary data, uword format
+  arma_aligned       uword  aux_uword_b;  //!< storage of auxiliary data, uword format
+  
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/mtOp_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,82 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup mtOp
+//! @{
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtOp<out_eT, T1, op_type>::mtOp(const T1& in_m)
+  : m(in_m)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtOp<out_eT, T1, op_type>::mtOp(const T1& in_m, const typename T1::elem_type in_aux)
+  : m(in_m)
+  , aux(in_aux)
+  {
+  arma_extra_debug_sigprint();
+  }
+  
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtOp<out_eT, T1, op_type>::mtOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b)
+  : m(in_m)
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtOp<out_eT, T1, op_type>::mtOp(const T1& in_m, const typename T1::elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b)
+  : m(in_m)
+  , aux(in_aux)
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtOp<out_eT, T1, op_type>::mtOp(const char junk, const T1& in_m, const out_eT in_aux)
+  : m(in_m)
+  , aux_out_eT(in_aux)
+  {
+  arma_ignore(junk);
+  
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtOp<out_eT, T1, op_type>::~mtOp()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/mtSpOp_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,41 @@
+// Copyright (C) 2012 Ryan Curtin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup mtSpOp
+//! @{
+
+// Class for delayed multi-type sparse operations.  These are operations where
+// the resulting type is different than the stored type.
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+class mtSpOp : public SpBase<out_eT, mtSpOp<out_eT, T1, op_type> >
+  {
+  public:
+
+  typedef          out_eT                       elem_type;
+  typedef typename get_pod_type<out_eT>::result pod_type;
+
+  typedef typename T1::elem_type                in_eT;
+
+  static const bool is_row = false;
+  static const bool is_col = false;
+
+  inline explicit mtSpOp(const T1& in_m);
+  inline          mtSpOp(const T1& in_m, const uword aux_uword_a, const uword aux_uword_b);
+
+  inline          ~mtSpOp();
+
+  arma_aligned const T1&    m;
+  arma_aligned       uword  aux_uword_a;
+  arma_aligned       uword  aux_uword_b;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/mtSpOp_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,40 @@
+// Copyright (C) 2012 Ryan Curtin
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup mtSpOp
+//! @{
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtSpOp<out_eT, T1, op_type>::mtSpOp(const T1& in_m)
+  : m(in_m)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtSpOp<out_eT, T1, op_type>::mtSpOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b)
+  : m(in_m)
+  , aux_uword_a(in_aux_uword_a)
+  , aux_uword_b(in_aux_uword_b)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+inline
+mtSpOp<out_eT, T1, op_type>::~mtSpOp()
+  {
+  arma_extra_debug_sigprint();
+  }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_chol_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,25 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_chol
+//! @{
+
+
+
+class op_chol
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_chol>& X);
+
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_chol_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,32 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_chol
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+op_chol::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_chol>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool status = auxlib::chol(out, X.m);
+  
+  if(status == false)
+    {
+    out.reset();
+    arma_bad("chol(): failed to converge");
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_cor_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,28 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_cor
+//! @{
+
+
+
+class op_cor
+  {
+  public:
+  
+  template<typename eT> inline static void direct_cor(Mat<eT>&                out, const Mat<eT>& X,                const uword norm_type);
+  template<typename  T> inline static void direct_cor(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& X, const uword norm_type);
+  
+  template<typename T1> inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cor>& in);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_cor_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,109 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_cor
+//! @{
+
+
+
+template<typename eT>
+inline
+void
+op_cor::direct_cor(Mat<eT>& out, const Mat<eT>& A, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(A.is_empty())
+    {
+    out.reset();
+    return;
+    }
+  
+  if(A.is_vec())
+    {
+    out.set_size(1,1);
+    out[0] = eT(1);
+    }
+  else
+    {
+    const uword N = A.n_rows;
+    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
+
+    const Row<eT> acc = sum(A);
+    const Row<eT> sd  = stddev(A);
+
+    out = (trans(A) * A);
+    out -= (trans(acc) * acc)/eT(N);
+    out /= norm_val;
+    out /= trans(sd) * sd;
+    }
+  }
+
+
+
+template<typename T>
+inline
+void
+op_cor::direct_cor(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+
+  typedef typename std::complex<T> eT;
+
+  if(A.is_empty())
+    {
+    out.reset();
+    return;
+    }
+  
+  if(A.is_vec())
+    {
+    out.set_size(1,1);
+    out[0] = eT(1);
+    }
+  else
+    {
+    const uword N = A.n_rows;
+    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
+
+    const Row<eT> acc = sum(A);
+    const Row<T>  sd  = stddev(A);
+
+    out = trans(A) * A;               // out = strans(conj(A)) * A;
+    out -= (trans(acc) * acc)/eT(N);  // out -= (strans(conj(acc)) * acc)/eT(N);
+    out /= norm_val;
+
+    //out = out / (trans(sd) * sd);
+    out /= conv_to< Mat<eT> >::from(trans(sd) * sd);
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_cor::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cor>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> tmp(in.m, out);
+  const Mat<eT>& A     = tmp.M;
+  
+  const uword norm_type = in.aux_uword_a;
+  
+  op_cor::direct_cor(out, A, norm_type);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_cov_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,28 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_cov
+//! @{
+
+
+
+class op_cov
+  {
+  public:
+  
+  template<typename eT> inline static void direct_cov(Mat<eT>&                out, const Mat<eT>& X,                const uword norm_type);
+  template<typename  T> inline static void direct_cov(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& X, const uword norm_type);
+  
+  template<typename T1> inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cov>& in);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_cov_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,107 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_cov
+//! @{
+
+
+
+template<typename eT>
+inline
+void
+op_cov::direct_cov(Mat<eT>& out, const Mat<eT>& A, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(A.is_vec())
+    {
+    if(A.n_rows == 1)
+      {
+      out = var(trans(A), norm_type);      
+      }
+    else
+      {
+      out = var(A, norm_type);
+      }
+    }
+  else
+    {
+    const uword N = A.n_rows;
+    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
+
+    const Row<eT> acc = sum(A);
+
+    out = trans(A) * A;
+    out -= (trans(acc) * acc)/eT(N);
+    out /= norm_val;
+    }
+  }
+
+
+
+template<typename T>
+inline
+void
+op_cov::direct_cov(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<T> eT;
+  
+  if(A.is_vec())
+    {
+    if(A.n_rows == 1)
+      {
+      const Mat<T> tmp_mat = var(trans(A), norm_type);
+      out.set_size(1,1);
+      out[0] = tmp_mat[0];
+      }
+    else
+      {
+      const Mat<T> tmp_mat = var(A, norm_type);
+      out.set_size(1,1);
+      out[0] = tmp_mat[0];
+      }
+    }
+  else
+    {
+    const uword N = A.n_rows;
+    const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N);
+    
+    const Row<eT> acc = sum(A);
+    
+    out = trans(A) * A;               // out = strans(conj(A)) * A;
+    out -= (trans(acc) * acc)/eT(N);  // out -= (strans(conj(acc)) * acc)/eT(N);
+    out /= norm_val;
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_cov::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cov>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> tmp(in.m, out);
+  const Mat<eT>& A     = tmp.M;
+  
+  const uword norm_type = in.aux_uword_a;
+  
+  op_cov::direct_cov(out, A, norm_type);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_cumsum_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,32 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_cumsum
+//! @{
+
+
+
+class op_cumsum_mat
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cumsum_mat>& in);
+  };
+
+
+
+class op_cumsum_vec
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cumsum_vec>& in);
+  };
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_cumsum_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,105 @@
+// Copyright (C) 2010-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_cumsum
+//! @{
+
+
+template<typename T1>
+inline
+void
+op_cumsum_mat::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cumsum_mat>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1>  tmp(in.m, out);
+  const Mat<eT>&      X = tmp.M;
+  
+  const uword dim = in.aux_uword_a;
+  arma_debug_check( (dim > 1), "cumsum(): incorrect usage. dim must be 0 or 1");
+  
+  out.copy_size(X);
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  if(dim == 0)
+    {
+    arma_extra_debug_print("op_cumsum::apply(), dim = 0");
+    
+    for(uword col=0; col<X_n_cols; ++col)
+      {
+            eT* out_colmem = out.colptr(col);
+      const eT* X_colmem   = X.colptr(col);
+      
+      eT acc = eT(0);
+      
+      for(uword row=0; row<X_n_rows; ++row)
+        {
+        acc += X_colmem[row];
+        
+        out_colmem[row] = acc;
+        }
+      }
+    }
+  else
+  if(dim == 1)
+    {
+    arma_extra_debug_print("op_cumsum::apply(), dim = 1");
+    
+    for(uword row=0; row<X_n_rows; ++row)
+      {
+      eT acc = eT(0);
+      
+      for(uword col=0; col<X_n_cols; ++col)
+        {
+        acc += X.at(row,col);
+        
+        out.at(row,col) = acc;
+        }
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_cumsum_vec::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cumsum_vec>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1>   tmp(in.m, out);
+  const Mat<eT>&       X = tmp.M;
+  
+  const uword n_elem = X.n_elem;
+  
+  out.copy_size(X);
+  
+        eT* out_mem = out.memptr();
+  const eT* X_mem   = X.memptr();
+  
+  eT acc = eT(0);
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    acc += X_mem[i];
+    
+    out_mem[i] = acc;
+    }
+  }
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_cx_scalar_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,158 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_cx_scalar
+//! @{
+
+
+
+class op_cx_scalar_times
+  {
+  public:
+  
+  template<typename T1>
+  inline static void
+  apply
+    (
+          Mat< typename std::complex<typename T1::pod_type> >& out,
+    const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>& X
+    );
+  
+  template<typename T1>
+  inline static void
+  apply
+    (
+             Cube< typename std::complex<typename T1::pod_type> >& out,
+    const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>& X
+    );
+
+  };
+
+
+
+class op_cx_scalar_plus
+  {
+  public:
+  
+  template<typename T1>
+  inline static void
+  apply
+    (
+          Mat< typename std::complex<typename T1::pod_type> >& out,
+    const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>& X
+    );
+  
+  template<typename T1>
+  inline static void
+  apply
+    (
+             Cube< typename std::complex<typename T1::pod_type> >& out,
+    const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>& X
+    );
+
+  };
+
+
+
+class op_cx_scalar_minus_pre
+  {
+  public:
+  
+  template<typename T1>
+  inline static void
+  apply
+    (
+          Mat< typename std::complex<typename T1::pod_type> >& out,
+    const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>& X
+    );
+  
+  template<typename T1>
+  inline static void
+  apply
+    (
+             Cube< typename std::complex<typename T1::pod_type> >& out,
+    const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>& X
+    );
+
+  };
+
+
+
+class op_cx_scalar_minus_post
+  {
+  public:
+  
+  template<typename T1>
+  inline static void
+  apply
+    (
+          Mat< typename std::complex<typename T1::pod_type> >& out,
+    const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>& X
+    );
+  
+  template<typename T1>
+  inline static void
+  apply
+    (
+             Cube< typename std::complex<typename T1::pod_type> >& out,
+    const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>& X
+    );
+
+  };
+
+
+
+class op_cx_scalar_div_pre
+  {
+  public:
+  
+  template<typename T1>
+  inline static void
+  apply
+    (
+          Mat< typename std::complex<typename T1::pod_type> >& out,
+    const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>& X
+    );
+  
+  template<typename T1>
+  inline static void
+  apply
+    (
+             Cube< typename std::complex<typename T1::pod_type> >& out,
+    const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>& X
+    );
+
+  };
+
+
+
+class op_cx_scalar_div_post
+  {
+  public:
+  
+  template<typename T1>
+  inline static void
+  apply
+    (
+          Mat< typename std::complex<typename T1::pod_type> >& out,
+    const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>& X
+    );
+  
+  template<typename T1>
+  inline static void
+  apply
+    (
+             Cube< typename std::complex<typename T1::pod_type> >& out,
+    const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>& X
+    );
+
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_cx_scalar_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,459 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_cx_scalar
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+op_cx_scalar_times::apply
+  (
+        Mat< typename std::complex<typename T1::pod_type> >& out,
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<typename T1::pod_type> eT;
+  
+  const Proxy<T1> A(X.m);
+  
+  const uword n_rows = A.get_n_rows();
+  const uword n_cols = A.get_n_cols();
+  
+  out.set_size(n_rows, n_cols);
+  
+  const eT  k       = X.aux_out_eT;
+        eT* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = A.get_n_elem();
+  
+    for(uword i=0; i<n_elem; ++i)
+      {
+      out_mem[i] = A[i] * k;
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      *out_mem = A.at(row,col) * k;  ++out_mem;
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_cx_scalar_plus::apply
+  (
+        Mat< typename std::complex<typename T1::pod_type> >& out,
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<typename T1::pod_type> eT;
+  
+  const Proxy<T1> A(X.m);
+  
+  const uword n_rows = A.get_n_rows();
+  const uword n_cols = A.get_n_cols();
+  
+  out.set_size(n_rows, n_cols);
+  
+  const eT  k       = X.aux_out_eT;
+        eT* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = A.get_n_elem();
+  
+    for(uword i=0; i<n_elem; ++i)
+      {
+      out_mem[i] = A[i] + k;
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      *out_mem = A.at(row,col) + k;  ++out_mem;
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_cx_scalar_minus_pre::apply
+  (
+        Mat< typename std::complex<typename T1::pod_type> >& out,
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<typename T1::pod_type> eT;
+  
+  const Proxy<T1> A(X.m);
+  
+  const uword n_rows = A.get_n_rows();
+  const uword n_cols = A.get_n_cols();
+  
+  out.set_size(n_rows, n_cols);
+  
+  const eT  k       = X.aux_out_eT;
+        eT* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = A.get_n_elem();
+  
+    for(uword i=0; i<n_elem; ++i)
+      {
+      out_mem[i] = k - A[i];
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      *out_mem = k - A.at(row,col);  ++out_mem;
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_cx_scalar_minus_post::apply
+  (
+        Mat< typename std::complex<typename T1::pod_type> >& out,
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<typename T1::pod_type> eT;
+  
+  const Proxy<T1> A(X.m);
+  
+  const uword n_rows = A.get_n_rows();
+  const uword n_cols = A.get_n_cols();
+  
+  out.set_size(n_rows, n_cols);
+  
+  const eT  k       = X.aux_out_eT;
+        eT* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = A.get_n_elem();
+  
+    for(uword i=0; i<n_elem; ++i)
+      {
+      out_mem[i] = A[i] - k;
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      *out_mem = A.at(row,col) - k;  ++out_mem;
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_cx_scalar_div_pre::apply
+  (
+        Mat< typename std::complex<typename T1::pod_type> >& out,
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<typename T1::pod_type> eT;
+  
+  const Proxy<T1> A(X.m);
+  
+  const uword n_rows = A.get_n_rows();
+  const uword n_cols = A.get_n_cols();
+  
+  out.set_size(n_rows, n_cols);
+  
+  const eT  k       = X.aux_out_eT;
+        eT* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = A.get_n_elem();
+  
+    for(uword i=0; i<n_elem; ++i)
+      {
+      out_mem[i] = k / A[i];
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      *out_mem = k / A.at(row,col);  ++out_mem;
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_cx_scalar_div_post::apply
+  (
+        Mat< typename std::complex<typename T1::pod_type> >& out,
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<typename T1::pod_type> eT;
+  
+  const Proxy<T1> A(X.m);
+  
+  const uword n_rows = A.get_n_rows();
+  const uword n_cols = A.get_n_cols();
+  
+  out.set_size(n_rows, n_cols);
+  
+  const eT  k       = X.aux_out_eT;
+        eT* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    const uword n_elem = A.get_n_elem();
+  
+    for(uword i=0; i<n_elem; ++i)
+      {
+      out_mem[i] = A[i] / k;
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      *out_mem = A.at(row,col) / k;  ++out_mem;
+      }
+    }
+  }
+
+
+
+//
+//
+//
+
+
+
+template<typename T1>
+inline
+void
+op_cx_scalar_times::apply
+  (
+           Cube< typename std::complex<typename T1::pod_type> >& out,
+  const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<typename T1::pod_type> eT;
+  
+  const ProxyCube<T1> A(X.m);
+  
+  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
+  
+  const eT    k       = X.aux_out_eT;
+  const uword n_elem  = out.n_elem;
+        eT*   out_mem = out.memptr();
+  
+  // TODO: implement handling for ProxyCube<T1>::prefer_at_accessor == true
+  for(uword i=0; i<n_elem; ++i)
+    {
+    out_mem[i] = A[i] * k;
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_cx_scalar_plus::apply
+  (
+           Cube< typename std::complex<typename T1::pod_type> >& out,
+  const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<typename T1::pod_type> eT;
+  
+  const ProxyCube<T1> A(X.m);
+  
+  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
+  
+  const eT    k       = X.aux_out_eT;
+  const uword n_elem  = out.n_elem;
+        eT*   out_mem = out.memptr();
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    out_mem[i] = A[i] + k;
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_cx_scalar_minus_pre::apply
+  (
+           Cube< typename std::complex<typename T1::pod_type> >& out,
+  const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<typename T1::pod_type> eT;
+  
+  const ProxyCube<T1> A(X.m);
+  
+  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
+  
+  const eT    k       = X.aux_out_eT;
+  const uword n_elem  = out.n_elem;
+        eT*   out_mem = out.memptr();
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    out_mem[i] = k - A[i];
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_cx_scalar_minus_post::apply
+  (
+           Cube< typename std::complex<typename T1::pod_type> >& out,
+  const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<typename T1::pod_type> eT;
+  
+  const ProxyCube<T1> A(X.m);
+  
+  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
+  
+  const eT    k       = X.aux_out_eT;
+  const uword n_elem  = out.n_elem;
+        eT*   out_mem = out.memptr();
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    out_mem[i] = A[i] - k;
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_cx_scalar_div_pre::apply
+  (
+           Cube< typename std::complex<typename T1::pod_type> >& out,
+  const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<typename T1::pod_type> eT;
+  
+  const ProxyCube<T1> A(X.m);
+  
+  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
+  
+  const eT    k       = X.aux_out_eT;
+  const uword n_elem  = out.n_elem;
+        eT*   out_mem = out.memptr();
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    out_mem[i] = k / A[i];
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_cx_scalar_div_post::apply
+  (
+           Cube< typename std::complex<typename T1::pod_type> >& out,
+  const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<typename T1::pod_type> eT;
+  
+  const ProxyCube<T1> A(X.m);
+  
+  out.set_size(A.get_n_rows(), A.get_n_cols(), A.get_n_slices());
+  
+  const eT    k       = X.aux_out_eT;
+  const uword n_elem  = out.n_elem;
+        eT*   out_mem = out.memptr();
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    out_mem[i] = A[i] / k;
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_diagmat_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,24 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_diagmat
+//! @{
+
+
+
+class op_diagmat
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_diagmat>& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_diagmat_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,131 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_diagmat
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+op_diagmat::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagmat>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(X.m);
+  
+  const uword n_rows = P.get_n_rows();
+  const uword n_cols = P.get_n_cols();
+  
+  const bool P_is_vec = (n_rows == 1) || (n_cols == 1);
+  
+  
+  if(P.is_alias(out) == false)
+    {
+    if(P_is_vec)    // generate a diagonal matrix out of a vector
+      {
+      const uword N = (n_rows == 1) ? n_cols : n_rows;
+      
+      out.zeros(N, N);
+      
+      if(Proxy<T1>::prefer_at_accessor == false)
+        {
+        typename Proxy<T1>::ea_type P_ea = P.get_ea();
+        
+        for(uword i=0; i < N; ++i) { out.at(i,i) = P_ea[i]; }
+        }
+      else
+        {
+        if(n_rows == 1)
+          {
+          for(uword i=0; i < N; ++i) { out.at(i,i) = P.at(0,i); }
+          }
+        else
+          {
+          for(uword i=0; i < N; ++i) { out.at(i,i) = P.at(i,0); }
+          }
+        }
+      }
+    else   // generate a diagonal matrix out of a matrix
+      {
+      arma_debug_check( (n_rows != n_cols), "diagmat(): given matrix is not square" );
+      
+      out.zeros(n_rows, n_rows);
+      
+      for(uword i=0; i < n_rows; ++i) { out.at(i,i) = P.at(i,i); }
+      }
+    }
+  else   // we have aliasing
+    {
+    if(P_is_vec)   // generate a diagonal matrix out of a vector
+      {
+      const uword N = (n_rows == 1) ? n_cols : n_rows;
+      
+      podarray<eT> tmp(N);
+      eT* tmp_mem = tmp.memptr();
+      
+      if(Proxy<T1>::prefer_at_accessor == false)
+        {
+        typename Proxy<T1>::ea_type P_ea = P.get_ea();
+        
+        for(uword i=0; i < N; ++i) { tmp_mem[i] = P_ea[i]; }
+        }
+      else
+        {
+        if(n_rows == 1)
+          {
+          for(uword i=0; i < N; ++i) { tmp_mem[i] = P.at(0,i); }
+          }
+        else
+          {
+          for(uword i=0; i < N; ++i) { tmp_mem[i] = P.at(i,0); }
+          }
+        }
+      
+      out.zeros(N, N);
+      
+      for(uword i=0; i < N; ++i) { out.at(i,i) = tmp_mem[i]; }
+      }
+    else   // generate a diagonal matrix out of a matrix
+      {
+      arma_debug_check( (n_rows != n_cols), "diagmat(): given matrix is not square" );
+      
+      if( (Proxy<T1>::has_subview == false) && (Proxy<T1>::fake_mat == false) )
+        {
+        // NOTE: we have aliasing and it's not due to a subview, hence we're assuming that the output matrix already has the correct size
+        
+        for(uword i=0; i < n_rows; ++i)
+          {
+          const eT val = P.at(i,i);
+          
+          arrayops::inplace_set(out.colptr(i), eT(0), n_rows);
+          
+          out.at(i,i) = val;
+          }
+        }
+      else
+        {
+        podarray<eT> tmp(n_rows);
+        eT* tmp_mem = tmp.memptr();
+        
+        for(uword i=0; i < n_rows; ++i)  { tmp_mem[i] = P.at(i,i); }
+        
+        out.zeros(n_rows, n_rows);
+        
+        for(uword i=0; i < n_rows; ++i)  { out.at(i,i) = tmp_mem[i]; }
+        }
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_diagvec_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,30 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_diagvec
+//! @{
+
+
+
+class op_diagvec
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_diagvec>& X);
+  
+  template<typename T1>
+  arma_hot inline static void apply_unwrap(Mat<typename T1::elem_type>& out, const T1& X,       const uword row_offset, const uword col_offset, const uword len);
+  
+  template<typename T1>
+  arma_hot inline static void apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P, const uword row_offset, const uword col_offset, const uword len);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_diagvec_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,132 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_diagvec
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+op_diagvec::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagvec>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword a = X.aux_uword_a;
+  const uword b = X.aux_uword_b;
+  
+  const uword row_offset = (b >  0) ? a : 0;
+  const uword col_offset = (b == 0) ? a : 0;
+  
+  const Proxy<T1> P(X.m);
+  
+  const uword n_rows = P.get_n_rows();
+  const uword n_cols = P.get_n_cols();
+  
+  arma_debug_check
+    (
+    ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
+    "diagvec(): requested diagonal is out of bounds"
+    );
+  
+  const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
+  
+  if(is_Mat<typename Proxy<T1>::stored_type>::value)
+    {
+    op_diagvec::apply_unwrap(out, P.Q, row_offset, col_offset, len);
+    }
+  else
+    {
+    if(P.is_alias(out) == false)
+      {
+      op_diagvec::apply_proxy(out, P, row_offset, col_offset, len);
+      }
+    else
+      {
+      Mat<eT> tmp;
+      
+      op_diagvec::apply_proxy(tmp, P, row_offset, col_offset, len);
+      
+      out.steal_mem(tmp);
+      }
+    }
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_diagvec::apply_unwrap(Mat<typename T1::elem_type>& out, const T1& X, const uword row_offset, const uword col_offset, const uword len)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> tmp_A(X, out);
+  const Mat<eT>& A =     tmp_A.M;
+  
+  out.set_size(len, 1);
+  
+  eT* out_mem = out.memptr();
+  
+  uword i,j;
+  for(i=0, j=1; j < len; i+=2, j+=2)
+    {
+    const eT tmp_i = A.at( i + row_offset, i + col_offset );
+    const eT tmp_j = A.at( j + row_offset, j + col_offset );
+    
+    out_mem[i] = tmp_i;
+    out_mem[j] = tmp_j;
+    }
+  
+  if(i < len)
+    {
+    out_mem[i] = A.at( i + row_offset, i + col_offset );
+    }
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_diagvec::apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P, const uword row_offset, const uword col_offset, const uword len)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  out.set_size(len, 1);
+  
+  eT* out_mem = out.memptr();
+  
+  uword i,j;
+  for(i=0, j=1; j < len; i+=2, j+=2)
+    {
+    const eT tmp_i = P.at( i + row_offset, i + col_offset );
+    const eT tmp_j = P.at( j + row_offset, j + col_offset );
+    
+    out_mem[i] = tmp_i;
+    out_mem[j] = tmp_j;
+    }
+  
+  if(i < len)
+    {
+    out_mem[i] = P.at( i + row_offset, i + col_offset );
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_dot_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,101 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_dot
+//! @{
+
+//! \brief
+//! dot product operation 
+
+class op_dot
+  {
+  public:
+  
+  template<typename eT>
+  arma_hot arma_pure arma_inline static
+  typename arma_not_cx<eT>::result
+  direct_dot_arma(const uword n_elem, const eT* const A, const eT* const B);
+  
+  template<typename eT>
+  arma_hot arma_pure inline static
+  typename arma_cx_only<eT>::result
+  direct_dot_arma(const uword n_elem, const eT* const A, const eT* const B);
+  
+  template<typename eT>
+  arma_hot arma_pure inline static typename arma_real_only<eT>::result
+  direct_dot(const uword n_elem, const eT* const A, const eT* const B);
+  
+  template<typename eT>
+  arma_hot arma_pure inline static typename arma_cx_only<eT>::result
+  direct_dot(const uword n_elem, const eT* const A, const eT* const B);
+  
+  template<typename eT>
+  arma_hot arma_pure inline static typename arma_integral_only<eT>::result
+  direct_dot(const uword n_elem, const eT* const A, const eT* const B);
+  
+  
+  template<typename eT>
+  arma_hot arma_pure inline static eT direct_dot(const uword n_elem, const eT* const A, const eT* const B, const eT* C);
+  
+  template<typename T1, typename T2>
+  arma_hot inline static typename T1::elem_type apply(const T1& X, const T2& Y);
+  
+  template<typename T1, typename T2>
+  arma_hot inline static typename  arma_not_cx<typename T1::elem_type>::result apply_proxy(const Proxy<T1>& PA, const Proxy<T2>& PB);
+  
+  template<typename T1, typename T2>
+  arma_hot inline static typename arma_cx_only<typename T1::elem_type>::result apply_proxy(const Proxy<T1>& PA, const Proxy<T2>& PB);
+  
+  template<typename eT, typename TA>
+  arma_hot inline static eT dot_and_copy_row(eT* out, const TA& A, const uword row, const eT* B_mem, const uword N);
+  };
+
+
+
+//! \brief
+//! normalised dot product operation 
+
+class op_norm_dot
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  arma_hot inline static typename T1::elem_type apply       (const T1& X, const T2& Y);
+  
+  template<typename T1, typename T2>
+  arma_hot inline static typename T1::elem_type apply_unwrap(const T1& X, const T2& Y);
+  };
+
+
+
+//! \brief
+//! complex conjugate dot product operation
+
+class op_cdot
+  {
+  public:
+  
+  template<typename eT>
+  arma_hot inline static eT direct_cdot_arma(const uword n_elem, const eT* const A, const eT* const B);
+  
+  template<typename eT>
+  arma_hot inline static eT direct_cdot(const uword n_elem, const eT* const A, const eT* const B);
+  
+  template<typename T1, typename T2>
+  arma_hot inline static typename T1::elem_type apply       (const T1& X, const T2& Y);
+  
+  template<typename T1, typename T2>
+  arma_hot inline static typename T1::elem_type apply_unwrap(const T1& X, const T2& Y);
+  
+  template<typename T1, typename T2>
+  arma_hot inline static typename T1::elem_type apply_proxy (const T1& X, const T2& Y);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_dot_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,637 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_dot
+//! @{
+
+
+
+//! for two arrays, generic version for non-complex values
+template<typename eT>
+arma_hot
+arma_pure
+arma_inline
+typename arma_not_cx<eT>::result
+op_dot::direct_dot_arma(const uword n_elem, const eT* const A, const eT* const B)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT val1 = eT(0);
+  eT val2 = eT(0);
+  
+  uword i, j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    val1 += A[i] * B[i];
+    val2 += A[j] * B[j];
+    }
+  
+  if(i < n_elem)
+    {
+    val1 += A[i] * B[i];
+    }
+  
+  return val1 + val2;
+  }
+
+
+
+//! for two arrays, generic version for complex values
+template<typename eT>
+arma_hot
+arma_pure
+inline
+typename arma_cx_only<eT>::result
+op_dot::direct_dot_arma(const uword n_elem, const eT* const A, const eT* const B)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  T val_real = T(0);
+  T val_imag = T(0);
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    const std::complex<T>& X = A[i];
+    const std::complex<T>& Y = B[i];
+    
+    const T a = X.real();
+    const T b = X.imag();
+    
+    const T c = Y.real();
+    const T d = Y.imag();
+    
+    val_real += (a*c) - (b*d);
+    val_imag += (a*d) + (b*c);
+    }
+  
+  return std::complex<T>(val_real, val_imag);
+  }
+
+
+
+//! for two arrays, float and double version
+template<typename eT>
+arma_hot
+arma_pure
+inline
+typename arma_real_only<eT>::result
+op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B)
+  {
+  arma_extra_debug_sigprint();
+  
+  if( n_elem <= 32u )
+    {
+    return op_dot::direct_dot_arma(n_elem, A, B);
+    }
+  else
+    {
+    #if defined(ARMA_USE_ATLAS)
+      {
+      arma_extra_debug_print("atlas::cblas_dot()");
+      
+      return atlas::cblas_dot(n_elem, A, B);
+      }
+    #elif defined(ARMA_USE_BLAS)
+      {
+      arma_extra_debug_print("blas::dot()");
+      
+      return blas::dot(n_elem, A, B);
+      }
+    #else
+      {
+      return op_dot::direct_dot_arma(n_elem, A, B);
+      }
+    #endif
+    }
+  }
+
+
+
+//! for two arrays, complex version
+template<typename eT>
+inline
+arma_hot
+arma_pure
+typename arma_cx_only<eT>::result
+op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B)
+  {
+  if( n_elem <= 16u )
+    {
+    return op_dot::direct_dot_arma(n_elem, A, B);
+    }
+  else
+    {
+    #if defined(ARMA_USE_ATLAS)
+      {
+      arma_extra_debug_print("atlas::cx_cblas_dot()");
+      
+      return atlas::cx_cblas_dot(n_elem, A, B);
+      }
+    #elif defined(ARMA_USE_BLAS)
+      {
+      arma_extra_debug_print("blas::dot()");
+      
+      return blas::dot(n_elem, A, B);
+      }
+    #else
+      {
+      return op_dot::direct_dot_arma(n_elem, A, B);
+      }
+    #endif
+    }
+  }
+
+
+
+//! for two arrays, integral version
+template<typename eT>
+arma_hot
+arma_pure
+inline
+typename arma_integral_only<eT>::result
+op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B)
+  {
+  return op_dot::direct_dot_arma(n_elem, A, B);
+  }
+
+
+
+
+//! for three arrays
+template<typename eT>
+arma_hot
+arma_pure
+inline
+eT
+op_dot::direct_dot(const uword n_elem, const eT* const A, const eT* const B, const eT* C)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT val = eT(0);
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    val += A[i] * B[i] * C[i];
+    }
+
+  return val;
+  }
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+typename T1::elem_type
+op_dot::apply(const T1& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor) || (Proxy<T2>::prefer_at_accessor);
+  
+  const bool do_unwrap = ((is_Mat<T1>::value == true) && (is_Mat<T2>::value == true)) || prefer_at_accessor;
+  
+  if(do_unwrap == true)
+    {
+    const unwrap<T1> tmp1(X);
+    const unwrap<T2> tmp2(Y);
+    
+    const typename unwrap<T1>::stored_type& A = tmp1.M;
+    const typename unwrap<T2>::stored_type& B = tmp2.M;
+    
+    arma_debug_check
+      (
+      (A.n_elem != B.n_elem),
+      "dot(): objects must have the same number of elements"
+      );
+    
+    return op_dot::direct_dot(A.n_elem, A.memptr(), B.memptr());
+    }
+  else
+    {
+    const Proxy<T1> PA(X);
+    const Proxy<T2> PB(Y);
+    
+    arma_debug_check( (PA.get_n_elem() != PB.get_n_elem()), "dot(): objects must have the same number of elements" );
+    
+    return op_dot::apply_proxy(PA,PB);
+    }
+  }
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+typename arma_not_cx<typename T1::elem_type>::result
+op_dot::apply_proxy(const Proxy<T1>& PA, const Proxy<T2>& PB)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type      eT;
+  typedef typename Proxy<T1>::ea_type ea_type1;
+  typedef typename Proxy<T2>::ea_type ea_type2;
+  
+  const uword N = PA.get_n_elem();
+  
+  ea_type1 A = PA.get_ea();
+  ea_type2 B = PB.get_ea();
+  
+  eT val1 = eT(0);
+  eT val2 = eT(0);
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<N; i+=2, j+=2)
+    {
+    val1 += A[i] * B[i];
+    val2 += A[j] * B[j];
+    }
+  
+  if(i < N)
+    {
+    val1 += A[i] * B[i];
+    }
+  
+  return val1 + val2;
+  }
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+typename arma_cx_only<typename T1::elem_type>::result
+op_dot::apply_proxy(const Proxy<T1>& PA, const Proxy<T2>& PB)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type            eT;
+  typedef typename get_pod_type<eT>::result  T;
+  
+  typedef typename Proxy<T1>::ea_type ea_type1;
+  typedef typename Proxy<T2>::ea_type ea_type2;
+  
+  const uword N = PA.get_n_elem();
+  
+  ea_type1 A = PA.get_ea();
+  ea_type2 B = PB.get_ea();
+  
+  T val_real = T(0);
+  T val_imag = T(0);
+  
+  for(uword i=0; i<N; ++i)
+    {
+    const std::complex<T> xx = A[i];
+    const std::complex<T> yy = B[i];
+    
+    const T a = xx.real();
+    const T b = xx.imag();
+    
+    const T c = yy.real();
+    const T d = yy.imag();
+    
+    val_real += (a*c) - (b*d);
+    val_imag += (a*d) + (b*c);
+    }
+  
+  return std::complex<T>(val_real, val_imag);
+  }
+
+
+
+template<typename eT, typename TA>
+arma_hot
+inline
+eT
+op_dot::dot_and_copy_row(eT* out, const TA& A, const uword row, const eT* B_mem, const uword N)
+  {
+  eT acc1 = eT(0);
+  eT acc2 = eT(0);
+  
+  uword i,j;
+  for(i=0, j=1; j < N; i+=2, j+=2)
+    {
+    const eT val_i = A.at(row, i);
+    const eT val_j = A.at(row, j);
+    
+    out[i] = val_i;
+    out[j] = val_j;
+    
+    acc1 += val_i * B_mem[i];
+    acc2 += val_j * B_mem[j];
+    }
+  
+  if(i < N)
+    {
+    const eT val_i = A.at(row, i);
+    
+    out[i] = val_i;
+    
+    acc1 += val_i * B_mem[i];
+    }
+  
+  return acc1 + acc2;
+  }
+
+
+
+//
+// op_norm_dot
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+typename T1::elem_type
+op_norm_dot::apply(const T1& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type      eT;
+  typedef typename Proxy<T1>::ea_type ea_type1;
+  typedef typename Proxy<T2>::ea_type ea_type2;
+  
+  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor) && (Proxy<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    const Proxy<T1> PA(X);
+    const Proxy<T2> PB(Y);
+    
+    const uword N  = PA.get_n_elem();
+    
+    arma_debug_check( (N != PB.get_n_elem()), "norm_dot(): objects must have the same number of elements" );
+    
+    ea_type1 A = PA.get_ea();
+    ea_type2 B = PB.get_ea();
+    
+    eT acc1 = eT(0);
+    eT acc2 = eT(0);
+    eT acc3 = eT(0);
+    
+    for(uword i=0; i<N; ++i)
+      {
+      const eT tmpA = A[i];
+      const eT tmpB = B[i];
+      
+      acc1 += tmpA * tmpA;
+      acc2 += tmpB * tmpB;
+      acc3 += tmpA * tmpB;
+      }
+    
+    return acc3 / ( std::sqrt(acc1 * acc2) );
+    }
+  else
+    {
+    return op_norm_dot::apply_unwrap(X, Y);
+    }
+  }
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+typename T1::elem_type
+op_norm_dot::apply_unwrap(const T1& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1> tmp1(X);
+  const unwrap<T2> tmp2(Y);
+  
+  const Mat<eT>& A = tmp1.M;
+  const Mat<eT>& B = tmp2.M;
+  
+  
+  arma_debug_check( (A.n_elem != B.n_elem), "norm_dot(): objects must have the same number of elements" );
+  
+  const uword N = A.n_elem;
+  
+  const eT* A_mem = A.memptr();
+  const eT* B_mem = B.memptr();
+  
+  eT acc1 = eT(0);
+  eT acc2 = eT(0);
+  eT acc3 = eT(0);
+  
+  for(uword i=0; i<N; ++i)
+    {
+    const eT tmpA = A_mem[i];
+    const eT tmpB = B_mem[i];
+    
+    acc1 += tmpA * tmpA;
+    acc2 += tmpB * tmpB;
+    acc3 += tmpA * tmpB;
+    }
+    
+  return acc3 / ( std::sqrt(acc1 * acc2) );
+  }
+
+
+
+//
+// op_cdot
+
+
+
+template<typename eT>
+arma_hot
+arma_pure
+inline
+eT
+op_cdot::direct_cdot_arma(const uword n_elem, const eT* const A, const eT* const B)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  T val_real = T(0);
+  T val_imag = T(0);
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    const std::complex<T>& X = A[i];
+    const std::complex<T>& Y = B[i];
+    
+    const T a = X.real();
+    const T b = X.imag();
+    
+    const T c = Y.real();
+    const T d = Y.imag();
+    
+    val_real += (a*c) + (b*d);
+    val_imag += (a*d) - (b*c);
+    }
+  
+  return std::complex<T>(val_real, val_imag);
+  }
+
+
+
+template<typename eT>
+arma_hot
+arma_pure
+inline
+eT
+op_cdot::direct_cdot(const uword n_elem, const eT* const A, const eT* const B)
+  {
+  arma_extra_debug_sigprint();
+  
+  if( n_elem <= 32u )
+    {
+    return op_cdot::direct_cdot_arma(n_elem, A, B);
+    }
+  else
+    {
+    #if defined(ARMA_USE_BLAS)
+      {
+      arma_extra_debug_print("blas::gemv()");
+      
+      // using gemv() workaround due to compatibility issues with cdotc() and zdotc()
+      
+      const char trans   = 'C';
+      
+      const blas_int m   = blas_int(n_elem);
+      const blas_int n   = 1;
+      //const blas_int lda = (n_elem > 0) ? blas_int(n_elem) : blas_int(1);
+      const blas_int inc = 1;
+      
+      const eT alpha     = eT(1);
+      const eT beta      = eT(0);
+      
+      eT result[2];  // paranoia: using two elements instead of one
+      
+      //blas::gemv(&trans, &m, &n, &alpha, A, &lda, B, &inc, &beta, &result[0], &inc);
+      blas::gemv(&trans, &m, &n, &alpha, A, &m, B, &inc, &beta, &result[0], &inc);
+      
+      return result[0];
+      }
+    #elif defined(ARMA_USE_ATLAS)
+      {
+      // TODO: use dedicated atlas functions cblas_cdotc_sub() and cblas_zdotc_sub() and retune threshold
+
+      return op_cdot::direct_cdot_arma(n_elem, A, B);
+      }
+    #else
+      {
+      return op_cdot::direct_cdot_arma(n_elem, A, B);
+      }
+    #endif
+    }
+  }
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+typename T1::elem_type
+op_cdot::apply(const T1& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  if( (is_Mat<T1>::value == true) && (is_Mat<T2>::value == true) )
+    {
+    return op_cdot::apply_unwrap(X,Y);
+    }
+  else
+    {
+    return op_cdot::apply_proxy(X,Y);
+    }
+  }
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+typename T1::elem_type
+op_cdot::apply_unwrap(const T1& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1> tmp1(X);
+  const unwrap<T2> tmp2(Y);
+  
+  const Mat<eT>& A = tmp1.M;
+  const Mat<eT>& B = tmp2.M;
+  
+  arma_debug_check( (A.n_elem != B.n_elem), "cdot(): objects must have the same number of elements" );
+  
+  return op_cdot::direct_cdot( A.n_elem, A.mem, B.mem );
+  }
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+typename T1::elem_type
+op_cdot::apply_proxy(const T1& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type            eT;
+  typedef typename get_pod_type<eT>::result  T;
+  
+  typedef typename Proxy<T1>::ea_type ea_type1;
+  typedef typename Proxy<T2>::ea_type ea_type2;
+  
+  const bool prefer_at_accessor = (Proxy<T1>::prefer_at_accessor) || (Proxy<T2>::prefer_at_accessor);
+  
+  if(prefer_at_accessor == false)
+    {
+    const Proxy<T1> PA(X);
+    const Proxy<T2> PB(Y);
+    
+    const uword N = PA.get_n_elem();
+    
+    arma_debug_check( (N != PB.get_n_elem()), "cdot(): objects must have the same number of elements" );
+    
+    ea_type1 A = PA.get_ea();
+    ea_type2 B = PB.get_ea();
+    
+    T val_real = T(0);
+    T val_imag = T(0);
+    
+    for(uword i=0; i<N; ++i)
+      {
+      const std::complex<T> AA = A[i];
+      const std::complex<T> BB = B[i];
+      
+      const T a = AA.real();
+      const T b = AA.imag();
+      
+      const T c = BB.real();
+      const T d = BB.imag();
+      
+      val_real += (a*c) + (b*d);
+      val_imag += (a*d) - (b*c);
+      }
+    
+    return std::complex<T>(val_real, val_imag);
+    }
+  else
+    {
+    return op_cdot::apply_unwrap( X, Y );
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_dotext_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,39 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_dotext
+//! @{
+
+
+
+class op_dotext
+  {
+  public:
+  
+  
+  template<typename eT>
+  inline static eT direct_rowvec_mat_colvec       (const eT* A_mem, const Mat<eT>& B, const eT* C_mem);
+  
+  template<typename eT>
+  inline static eT direct_rowvec_transmat_colvec  (const eT* A_mem, const Mat<eT>& B, const eT* C_mem);
+  
+  template<typename eT>
+  inline static eT direct_rowvec_diagmat_colvec   (const eT* A_mem, const Mat<eT>& B, const eT* C_mem);
+  
+  template<typename eT>
+  inline static eT direct_rowvec_invdiagmat_colvec(const eT* A_mem, const Mat<eT>& B, const eT* C_mem);
+  
+  template<typename eT>
+  inline static eT direct_rowvec_invdiagvec_colvec(const eT* A_mem, const Mat<eT>& B, const eT* C_mem);
+  
+  };
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_dotext_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,204 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_dotext
+//! @{
+
+
+
+template<typename eT>
+inline
+eT
+op_dotext::direct_rowvec_mat_colvec
+  (
+  const eT*      A_mem,
+  const Mat<eT>& B,
+  const eT*      C_mem
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword cost_AB = B.n_cols;
+  const uword cost_BC = B.n_rows;
+  
+  if(cost_AB <= cost_BC)
+    {
+    podarray<eT> tmp(B.n_cols);
+    
+    for(uword col=0; col<B.n_cols; ++col)
+      {
+      const eT* B_coldata = B.colptr(col);
+      
+      eT val = eT(0);
+      for(uword i=0; i<B.n_rows; ++i)
+        {
+        val += A_mem[i] * B_coldata[i];
+        }
+        
+      tmp[col] = val;
+      }
+    
+    return op_dot::direct_dot(B.n_cols, tmp.mem, C_mem);
+    }
+  else
+    {
+    podarray<eT> tmp(B.n_rows);
+    
+    for(uword row=0; row<B.n_rows; ++row)
+      {
+      eT val = eT(0);
+      for(uword col=0; col<B.n_cols; ++col)
+        {
+        val += B.at(row,col) * C_mem[col];
+        }
+      
+      tmp[row] = val;
+      }
+    
+    return op_dot::direct_dot(B.n_rows, A_mem, tmp.mem);
+    }
+  
+  
+  }
+
+
+
+template<typename eT>
+inline
+eT
+op_dotext::direct_rowvec_transmat_colvec
+  (
+  const eT*      A_mem,
+  const Mat<eT>& B,
+  const eT*      C_mem
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword cost_AB = B.n_rows;
+  const uword cost_BC = B.n_cols;
+  
+  if(cost_AB <= cost_BC)
+    {
+    podarray<eT> tmp(B.n_rows);
+    
+    for(uword row=0; row<B.n_rows; ++row)
+      {
+      eT val = eT(0);
+      
+      for(uword i=0; i<B.n_cols; ++i)
+        {
+        val += A_mem[i] * B.at(row,i);
+        }
+        
+      tmp[row] = val;
+      }
+    
+    return op_dot::direct_dot(B.n_rows, tmp.mem, C_mem);
+    }
+  else
+    {
+    podarray<eT> tmp(B.n_cols);
+    
+    for(uword col=0; col<B.n_cols; ++col)
+      {
+      const eT* B_coldata = B.colptr(col);
+      
+      eT val = eT(0);
+      
+      for(uword i=0; i<B.n_rows; ++i)
+        {
+        val += B_coldata[i] * C_mem[i];
+        }
+      
+      tmp[col] = val;
+      }
+    
+    return op_dot::direct_dot(B.n_cols, A_mem, tmp.mem);
+    }
+  
+  
+  }
+
+
+
+template<typename eT>
+inline
+eT
+op_dotext::direct_rowvec_diagmat_colvec
+  (
+  const eT*      A_mem,
+  const Mat<eT>& B,
+  const eT*      C_mem
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  eT val = eT(0);
+
+  for(uword i=0; i<B.n_rows; ++i)
+    {
+    val += A_mem[i] * B.at(i,i) * C_mem[i];
+    }
+
+  return val;
+  }
+
+
+
+template<typename eT>
+inline
+eT
+op_dotext::direct_rowvec_invdiagmat_colvec
+  (
+  const eT*      A_mem,
+  const Mat<eT>& B,
+  const eT*      C_mem
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  eT val = eT(0);
+
+  for(uword i=0; i<B.n_rows; ++i)
+    {
+    val += (A_mem[i] * C_mem[i]) / B.at(i,i);
+    }
+
+  return val;
+  }
+
+
+
+template<typename eT>
+inline
+eT
+op_dotext::direct_rowvec_invdiagvec_colvec
+  (
+  const eT*      A_mem,
+  const Mat<eT>& B,
+  const eT*      C_mem
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  const eT* B_mem = B.mem;
+  
+  eT val = eT(0);
+
+  for(uword i=0; i<B.n_elem; ++i)
+    {
+    val += (A_mem[i] * C_mem[i]) / B_mem[i];
+    }
+
+  return val;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_fft_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,52 @@
+// Copyright (C) 2013 Conrad Sanderson
+// Copyright (C) 2013 NICTA (www.nicta.com.au)
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_fft
+//! @{
+
+
+
+class op_fft_real
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply( Mat< std::complex<typename T1::pod_type> >& out, const mtOp<std::complex<typename T1::pod_type>,T1,op_fft_real>& in );
+  };
+
+
+
+class op_fft_cx
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply( Mat<typename T1::elem_type>& out, const Op<T1,op_fft_cx>& in );
+  
+  template<typename T1, bool inverse>
+  inline static void apply_noalias(Mat<typename T1::elem_type>& out, const Proxy<T1>& P, const uword a, const uword b);
+
+  template<typename T1> arma_hot inline static void copy_vec       (typename Proxy<T1>::elem_type* dest, const Proxy<T1>& P, const uword N);
+  template<typename T1> arma_hot inline static void copy_vec_proxy (typename Proxy<T1>::elem_type* dest, const Proxy<T1>& P, const uword N);
+  template<typename T1> arma_hot inline static void copy_vec_unwrap(typename Proxy<T1>::elem_type* dest, const Proxy<T1>& P, const uword N);
+  };
+
+
+
+class op_ifft_cx
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply( Mat<typename T1::elem_type>& out, const Op<T1,op_ifft_cx>& in );
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_fft_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,373 @@
+// Copyright (C) 2013 Conrad Sanderson
+// Copyright (C) 2013 NICTA (www.nicta.com.au)
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_fft
+//! @{
+
+
+
+//
+// op_fft_real
+
+
+
+template<typename T1>
+inline
+void
+op_fft_real::apply( Mat< std::complex<typename T1::pod_type> >& out, const mtOp<std::complex<typename T1::pod_type>,T1,op_fft_real>& in )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::pod_type         in_eT;
+  typedef typename std::complex<in_eT> out_eT;
+  
+  const Proxy<T1> P(in.m);
+  
+  const uword n_rows = P.get_n_rows();
+  const uword n_cols = P.get_n_cols();
+  const uword n_elem = P.get_n_elem();
+  
+  const bool is_vec = ( (n_rows == 1) || (n_cols == 1) );
+  
+  const uword N_orig = (is_vec)              ? n_elem         : n_rows;
+  const uword N_user = (in.aux_uword_b == 0) ? in.aux_uword_a : N_orig;
+  
+  fft_engine<out_eT,false> worker(N_user);
+  
+  // no need to worry about aliasing, as we're going from a real object to complex complex, which by definition cannot alias
+  
+  if(is_vec)
+    {
+    (n_cols == 1) ? out.set_size(N_user, 1) : out.set_size(1, N_user);
+    
+    if( (out.n_elem == 0) || (N_orig == 0) )
+      {
+      out.zeros();
+      return;
+      }
+    
+    if( (N_user == 1) && (N_orig >= 1) )
+      {
+      out[0] = out_eT( P[0] );
+      return;
+      }
+    
+    podarray<out_eT> data(N_user);
+    
+    out_eT* data_mem = data.memptr();
+    
+    if(N_user > N_orig)  { arrayops::inplace_set( &data_mem[N_orig], out_eT(0), (N_user - N_orig) ); }
+    
+    const uword N = (std::min)(N_user, N_orig);
+    
+    if(Proxy<T1>::prefer_at_accessor == false)
+      {
+      typename Proxy<T1>::ea_type X = P.get_ea();
+      
+      for(uword i=0; i < N; ++i)  { data_mem[i] = out_eT( X[i], in_eT(0) ); }
+      }
+    else
+      {
+      if(n_cols == 1)
+        {
+        for(uword i=0; i < N; ++i)  { data_mem[i] = out_eT( P.at(i,0), in_eT(0) ); }
+        }
+      else
+        {
+        for(uword i=0; i < N; ++i)  { data_mem[i] = out_eT( P.at(0,i), in_eT(0) ); }
+        }
+      }
+    
+    worker.run( out.memptr(), data_mem );
+    }
+  else
+    {
+    // process each column seperately
+    
+    out.set_size(N_user, n_cols);
+    
+    if( (out.n_elem == 0) || (N_orig == 0) )
+      {
+      out.zeros();
+      return;
+      }
+    
+    if( (N_user == 1) && (N_orig >= 1) )
+      {
+      for(uword col=0; col < n_cols; ++col)  { out.at(0,col) = out_eT( P.at(0,col) ); }
+      
+      return;
+      }
+    
+    podarray<out_eT> data(N_user);
+    
+    out_eT* data_mem = data.memptr();
+    
+    if(N_user > N_orig)  { arrayops::inplace_set( &data_mem[N_orig], out_eT(0), (N_user - N_orig) ); }
+    
+    const uword N = (std::min)(N_user, N_orig);
+    
+    for(uword col=0; col < n_cols; ++col)
+      {
+      for(uword i=0; i < N; ++i)  { data_mem[i] = P.at(i, col); }
+      
+      worker.run( out.colptr(col), data_mem );
+      }
+    }
+  }
+
+
+
+//
+// op_fft_cx
+
+
+template<typename T1>
+inline
+void
+op_fft_cx::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_fft_cx>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(in.m);
+  
+  if(P.is_alias(out) == false)
+    {
+    op_fft_cx::apply_noalias<T1,false>(out, P, in.aux_uword_a, in.aux_uword_b);
+    }
+  else
+    {
+    Mat<eT> tmp;
+    
+    op_fft_cx::apply_noalias<T1,false>(tmp, P, in.aux_uword_a, in.aux_uword_b);
+    
+    out.steal_mem(tmp);
+    }
+  }
+  
+
+
+template<typename T1, bool inverse>
+inline
+void
+op_fft_cx::apply_noalias(Mat<typename T1::elem_type>& out, const Proxy<T1>& P, const uword a, const uword b)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword n_rows = P.get_n_rows();
+  const uword n_cols = P.get_n_cols();
+  const uword n_elem = P.get_n_elem();
+  
+  const bool is_vec = ( (n_rows == 1) || (n_cols == 1) );
+  
+  const uword N_orig = (is_vec) ? n_elem : n_rows;
+  const uword N_user = (b == 0) ? a      : N_orig;
+  
+  fft_engine<eT,inverse> worker(N_user);
+  
+  if(is_vec)
+    {
+    (n_cols == 1) ? out.set_size(N_user, 1) : out.set_size(1, N_user);
+    
+    if( (out.n_elem == 0) || (N_orig == 0) )
+      {
+      out.zeros();
+      return;
+      }
+    
+    if( (N_user == 1) && (N_orig >= 1) )
+      {
+      out[0] = P[0];
+      return;
+      }
+    
+    if( (N_user > N_orig) || (is_Mat<typename Proxy<T1>::stored_type>::value == false) )
+      {
+      podarray<eT> data(N_user);
+      
+      eT* data_mem = data.memptr();
+      
+      if(N_user > N_orig)  { arrayops::inplace_set( &data_mem[N_orig], eT(0), (N_user - N_orig) ); }
+      
+      op_fft_cx::copy_vec( data_mem, P, (std::min)(N_user, N_orig) );
+      
+      worker.run( out.memptr(), data_mem );
+      }
+    else
+      {
+      const unwrap< typename Proxy<T1>::stored_type > tmp(P.Q);
+      
+      worker.run( out.memptr(), tmp.M.memptr() );
+      }
+    }
+  else
+    {
+    // process each column seperately
+    
+    out.set_size(N_user, n_cols);
+    
+    if( (out.n_elem == 0) || (N_orig == 0) )
+      {
+      out.zeros();
+      return;
+      }
+    
+    if( (N_user == 1) && (N_orig >= 1) )
+      {
+      for(uword col=0; col < n_cols; ++col)  { out.at(0,col) = P.at(0,col); }
+      
+      return;
+      }
+    
+    if( (N_user > N_orig) || (is_Mat<typename Proxy<T1>::stored_type>::value == false) )
+      {
+      podarray<eT> data(N_user);
+      
+      eT* data_mem = data.memptr();
+      
+      if(N_user > N_orig)  { arrayops::inplace_set( &data_mem[N_orig], eT(0), (N_user - N_orig) ); }
+      
+      const uword N = (std::min)(N_user, N_orig);
+      
+      for(uword col=0; col < n_cols; ++col)
+        {
+        for(uword i=0; i < N; ++i)  { data_mem[i] = P.at(i, col); }
+        
+        worker.run( out.colptr(col), data_mem );
+        }
+      }
+    else
+      {
+      const unwrap< typename Proxy<T1>::stored_type > tmp(P.Q);
+      
+      for(uword col=0; col < n_cols; ++col)
+        {
+        worker.run( out.colptr(col), tmp.M.colptr(col) );
+        }
+      }
+    }
+    
+  
+  // correct the scaling for the inverse transform
+  if(inverse == true)
+    {
+    typedef typename get_pod_type<eT>::result T;
+    
+    const T k = T(1) / T(N_user);
+    
+    eT* out_mem = out.memptr();
+    
+    const uword out_n_elem = out.n_elem;
+    
+    for(uword i=0; i < out_n_elem; ++i)  { out_mem[i] *= k; }
+    }
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_fft_cx::copy_vec(typename Proxy<T1>::elem_type* dest, const Proxy<T1>& P, const uword N)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(is_Mat< typename Proxy<T1>::stored_type >::value == true)
+    {
+    op_fft_cx::copy_vec_unwrap(dest, P, N);
+    }
+  else
+    {
+    op_fft_cx::copy_vec_proxy(dest, P, N);
+    }
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_fft_cx::copy_vec_unwrap(typename Proxy<T1>::elem_type* dest, const Proxy<T1>& P, const uword N)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap< typename Proxy<T1>::stored_type > tmp(P.Q);
+  
+  arrayops::copy(dest, tmp.M.memptr(), N);
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_fft_cx::copy_vec_proxy(typename Proxy<T1>::elem_type* dest, const Proxy<T1>& P, const uword N)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type X = P.get_ea();
+    
+    for(uword i=0; i < N; ++i)  { dest[i] = X[i]; }
+    }
+  else
+    {
+    if(P.get_n_cols() == 1)
+      {
+      for(uword i=0; i < N; ++i)  { dest[i] = P.at(i,0); }
+      }
+    else
+      {
+      for(uword i=0; i < N; ++i)  { dest[i] = P.at(0,i); }
+      }
+    }
+  }
+
+
+
+//
+// op_ifft_cx
+
+
+template<typename T1>
+inline
+void
+op_ifft_cx::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_ifft_cx>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(in.m);
+  
+  if(P.is_alias(out) == false)
+    {
+    op_fft_cx::apply_noalias<T1,true>(out, P, in.aux_uword_a, in.aux_uword_b);
+    }
+  else
+    {
+    Mat<eT> tmp;
+    
+    op_fft_cx::apply_noalias<T1,true>(tmp, P, in.aux_uword_a, in.aux_uword_b);
+    
+    out.steal_mem(tmp);
+    }
+  }
+  
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_find_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,76 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// Copyright (C) 2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_find
+//! @{
+
+
+
+class op_find
+  {
+  public:
+  
+  template<typename T1>
+  inline static uword
+  helper
+    (
+    Mat<uword>& indices,
+    const Base<typename T1::elem_type, T1>& X
+    );
+  
+  template<typename T1, typename op_type>
+  inline static uword
+  helper
+    (
+    Mat<uword>& indices,
+    const mtOp<uword, T1, op_type>& X,
+    const typename arma_op_rel_only<op_type>::result junk1 = 0,
+    const typename arma_not_cx<typename T1::elem_type>::result junk2 = 0
+    );
+  
+  template<typename T1, typename op_type>
+  inline static uword
+  helper
+    (
+    Mat<uword>& indices,
+    const mtOp<uword, T1, op_type>& X,
+    const typename arma_op_rel_only<op_type>::result junk1 = 0,
+    const typename arma_cx_only<typename T1::elem_type>::result junk2 = 0
+    );
+  
+  template<typename T1, typename T2, typename glue_type>
+  inline static uword
+  helper
+    (
+    Mat<uword>& indices,
+    const mtGlue<uword, T1, T2, glue_type>& X,
+    const typename arma_glue_rel_only<glue_type>::result junk1 = 0,
+    const typename arma_not_cx<typename T1::elem_type>::result junk2 = 0,
+    const typename arma_not_cx<typename T2::elem_type>::result junk3 = 0
+    );
+  
+  template<typename T1, typename T2, typename glue_type>
+  inline static uword
+  helper
+    (
+    Mat<uword>& indices,
+    const mtGlue<uword, T1, T2, glue_type>& X,
+    const typename arma_glue_rel_only<glue_type>::result junk1 = 0,
+    const typename arma_cx_only<typename T1::elem_type>::result junk2 = 0,
+    const typename arma_cx_only<typename T2::elem_type>::result junk3 = 0
+    );
+  
+  template<typename T1>
+  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_find>& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_find_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,387 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// Copyright (C) 2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_find
+//! @{
+
+
+
+template<typename T1>
+inline
+uword
+op_find::helper
+  (
+  Mat<uword>& indices,
+  const Base<typename T1::elem_type, T1>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> A(X.get_ref());
+  
+  const uword n_elem = A.get_n_elem();
+  
+  indices.set_size(n_elem, 1);
+  
+  uword* indices_mem = indices.memptr();
+  uword  n_nz        = 0;
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type PA = A.get_ea();
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      if(PA[i] != eT(0))  { indices_mem[n_nz] = i;  ++n_nz; }
+      }
+    }
+  else
+    {
+    const uword n_rows = A.get_n_rows();
+    const uword n_cols = A.get_n_cols();
+    
+    uword i = 0;
+    
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      if(A.at(row,col) != eT(0))  { indices_mem[n_nz] = i; ++n_nz; }
+      
+      ++i;
+      }
+    }
+  
+  return n_nz;
+  }
+
+
+
+template<typename T1, typename op_type>
+inline
+uword
+op_find::helper
+  (
+  Mat<uword>& indices,
+  const mtOp<uword, T1, op_type>& X,
+  const typename arma_op_rel_only<op_type>::result           junk1,
+  const typename arma_not_cx<typename T1::elem_type>::result junk2
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  typedef typename T1::elem_type eT;
+  
+  const eT val = X.aux;
+  
+  const Proxy<T1> A(X.m);
+  
+  const uword n_elem = A.get_n_elem();
+  
+  indices.set_size(n_elem, 1);
+  
+  uword* indices_mem = indices.memptr();
+  uword  n_nz        = 0;
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type PA = A.get_ea();
+    
+    uword i,j;
+    for(i=0, j=1; j < n_elem; i+=2, j+=2)
+      {
+      const eT tpi = PA[i];
+      const eT tpj = PA[j];
+      
+      bool not_zero_i;
+      bool not_zero_j;
+      
+           if(is_same_type<op_type, op_rel_lt_pre   >::value == true)  { not_zero_i = (val <  tpi); }
+      else if(is_same_type<op_type, op_rel_lt_post  >::value == true)  { not_zero_i = (tpi <  val); }
+      else if(is_same_type<op_type, op_rel_gt_pre   >::value == true)  { not_zero_i = (val >  tpi); }
+      else if(is_same_type<op_type, op_rel_gt_post  >::value == true)  { not_zero_i = (tpi >  val); }
+      else if(is_same_type<op_type, op_rel_lteq_pre >::value == true)  { not_zero_i = (val <= tpi); }
+      else if(is_same_type<op_type, op_rel_lteq_post>::value == true)  { not_zero_i = (tpi <= val); }
+      else if(is_same_type<op_type, op_rel_gteq_pre >::value == true)  { not_zero_i = (val >= tpi); }
+      else if(is_same_type<op_type, op_rel_gteq_post>::value == true)  { not_zero_i = (tpi >= val); }
+      else if(is_same_type<op_type, op_rel_eq       >::value == true)  { not_zero_i = (tpi == val); }
+      else if(is_same_type<op_type, op_rel_noteq    >::value == true)  { not_zero_i = (tpi != val); }
+      else not_zero_i = false;
+      
+           if(is_same_type<op_type, op_rel_lt_pre   >::value == true)  { not_zero_j = (val <  tpj); }
+      else if(is_same_type<op_type, op_rel_lt_post  >::value == true)  { not_zero_j = (tpj <  val); }
+      else if(is_same_type<op_type, op_rel_gt_pre   >::value == true)  { not_zero_j = (val >  tpj); }
+      else if(is_same_type<op_type, op_rel_gt_post  >::value == true)  { not_zero_j = (tpj >  val); }
+      else if(is_same_type<op_type, op_rel_lteq_pre >::value == true)  { not_zero_j = (val <= tpj); }
+      else if(is_same_type<op_type, op_rel_lteq_post>::value == true)  { not_zero_j = (tpj <= val); }
+      else if(is_same_type<op_type, op_rel_gteq_pre >::value == true)  { not_zero_j = (val >= tpj); }
+      else if(is_same_type<op_type, op_rel_gteq_post>::value == true)  { not_zero_j = (tpj >= val); }
+      else if(is_same_type<op_type, op_rel_eq       >::value == true)  { not_zero_j = (tpj == val); }
+      else if(is_same_type<op_type, op_rel_noteq    >::value == true)  { not_zero_j = (tpj != val); }
+      else not_zero_j = false;
+      
+      if(not_zero_i == true)  { indices_mem[n_nz] = i;  ++n_nz; }
+      if(not_zero_j == true)  { indices_mem[n_nz] = j;  ++n_nz; }
+      }
+    
+    if(i < n_elem)
+      {
+      bool not_zero;
+      
+      const eT tmp = PA[i];
+      
+           if(is_same_type<op_type, op_rel_lt_pre   >::value == true)  { not_zero = (val <  tmp); }
+      else if(is_same_type<op_type, op_rel_lt_post  >::value == true)  { not_zero = (tmp <  val); }
+      else if(is_same_type<op_type, op_rel_gt_pre   >::value == true)  { not_zero = (val >  tmp); }
+      else if(is_same_type<op_type, op_rel_gt_post  >::value == true)  { not_zero = (tmp >  val); }
+      else if(is_same_type<op_type, op_rel_lteq_pre >::value == true)  { not_zero = (val <= tmp); }
+      else if(is_same_type<op_type, op_rel_lteq_post>::value == true)  { not_zero = (tmp <= val); }
+      else if(is_same_type<op_type, op_rel_gteq_pre >::value == true)  { not_zero = (val >= tmp); }
+      else if(is_same_type<op_type, op_rel_gteq_post>::value == true)  { not_zero = (tmp >= val); }
+      else if(is_same_type<op_type, op_rel_eq       >::value == true)  { not_zero = (tmp == val); }
+      else if(is_same_type<op_type, op_rel_noteq    >::value == true)  { not_zero = (tmp != val); }
+      else not_zero = false;
+      
+      if(not_zero == true)  { indices_mem[n_nz] = i;  ++n_nz; }
+      }
+    }
+  else
+    {
+    const uword n_rows = A.get_n_rows();
+    const uword n_cols = A.get_n_cols();
+    
+    uword i = 0;
+    
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      const eT tmp = A.at(row,col);
+      
+      bool not_zero;
+      
+           if(is_same_type<op_type, op_rel_lt_pre   >::value == true)  { not_zero = (val <  tmp); }
+      else if(is_same_type<op_type, op_rel_lt_post  >::value == true)  { not_zero = (tmp <  val); }
+      else if(is_same_type<op_type, op_rel_gt_pre   >::value == true)  { not_zero = (val >  tmp); }
+      else if(is_same_type<op_type, op_rel_gt_post  >::value == true)  { not_zero = (tmp >  val); }
+      else if(is_same_type<op_type, op_rel_lteq_pre >::value == true)  { not_zero = (val <= tmp); }
+      else if(is_same_type<op_type, op_rel_lteq_post>::value == true)  { not_zero = (tmp <= val); }
+      else if(is_same_type<op_type, op_rel_gteq_pre >::value == true)  { not_zero = (val >= tmp); }
+      else if(is_same_type<op_type, op_rel_gteq_post>::value == true)  { not_zero = (tmp >= val); }
+      else if(is_same_type<op_type, op_rel_eq       >::value == true)  { not_zero = (tmp == val); }
+      else if(is_same_type<op_type, op_rel_noteq    >::value == true)  { not_zero = (tmp != val); }
+      else not_zero = false;
+      
+      if(not_zero == true)  { indices_mem[n_nz] = i;  ++n_nz; }
+      
+      ++i;
+      }
+    }
+  
+  return n_nz;
+  }
+
+
+
+template<typename T1, typename op_type>
+inline
+uword
+op_find::helper
+  (
+  Mat<uword>& indices,
+  const mtOp<uword, T1, op_type>& X,
+  const typename arma_op_rel_only<op_type>::result            junk1,
+  const typename arma_cx_only<typename T1::elem_type>::result junk2
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  
+  typedef typename T1::elem_type      eT;
+  typedef typename Proxy<T1>::ea_type ea_type;
+  
+  const eT val = X.aux;
+  
+  const Proxy<T1> A(X.m);
+  
+  ea_type     PA     = A.get_ea();
+  const uword n_elem = A.get_n_elem();
+  
+  indices.set_size(n_elem, 1);
+  
+  uword* indices_mem = indices.memptr();
+  uword  n_nz        = 0;
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    const eT tmp = PA[i];
+    
+    bool not_zero;
+    
+         if(is_same_type<op_type, op_rel_eq   >::value == true)  { not_zero = (tmp == val); }
+    else if(is_same_type<op_type, op_rel_noteq>::value == true)  { not_zero = (tmp != val); }
+    else not_zero = false;
+    
+    if(not_zero == true) { indices_mem[n_nz] = i;  ++n_nz; }
+    }
+  
+  return n_nz;
+  }
+
+
+
+template<typename T1, typename T2, typename glue_type>
+inline
+uword
+op_find::helper
+  (
+  Mat<uword>& indices,
+  const mtGlue<uword, T1, T2, glue_type>& X,
+  const typename arma_glue_rel_only<glue_type>::result       junk1,
+  const typename arma_not_cx<typename T1::elem_type>::result junk2,
+  const typename arma_not_cx<typename T2::elem_type>::result junk3
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  arma_ignore(junk3);
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename Proxy<T1>::ea_type ea_type1;
+  typedef typename Proxy<T2>::ea_type ea_type2;
+  
+  const Proxy<T1> A(X.A);
+  const Proxy<T2> B(X.B);
+  
+  arma_debug_assert_same_size(A, B, "relational operator");
+  
+  ea_type1 PA = A.get_ea();
+  ea_type2 PB = B.get_ea();
+  
+  const uword n_elem = B.get_n_elem();
+  
+  indices.set_size(n_elem, 1);
+  
+  uword* indices_mem = indices.memptr();
+  uword  n_nz        = 0;
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    const eT1 tmp1 = PA[i];
+    const eT2 tmp2 = PB[i];
+    
+    bool not_zero;
+    
+         if(is_same_type<glue_type, glue_rel_lt    >::value == true)  { not_zero = (tmp1 <  tmp2); }
+    else if(is_same_type<glue_type, glue_rel_gt    >::value == true)  { not_zero = (tmp1 >  tmp2); }
+    else if(is_same_type<glue_type, glue_rel_lteq  >::value == true)  { not_zero = (tmp1 <= tmp2); }
+    else if(is_same_type<glue_type, glue_rel_gteq  >::value == true)  { not_zero = (tmp1 >= tmp2); }
+    else if(is_same_type<glue_type, glue_rel_eq    >::value == true)  { not_zero = (tmp1 == tmp2); }
+    else if(is_same_type<glue_type, glue_rel_noteq >::value == true)  { not_zero = (tmp1 != tmp2); }
+    else not_zero = false;
+    
+    if(not_zero == true)  { indices_mem[n_nz] = i;  ++n_nz; }
+    }
+  
+  return n_nz;
+  }
+
+
+
+template<typename T1, typename T2, typename glue_type>
+inline
+uword
+op_find::helper
+  (
+  Mat<uword>& indices,
+  const mtGlue<uword, T1, T2, glue_type>& X,
+  const typename arma_glue_rel_only<glue_type>::result        junk1,
+  const typename arma_cx_only<typename T1::elem_type>::result junk2,
+  const typename arma_cx_only<typename T2::elem_type>::result junk3
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+  arma_ignore(junk3);
+  
+  typedef typename Proxy<T1>::ea_type ea_type1;
+  typedef typename Proxy<T2>::ea_type ea_type2;
+  
+  const Proxy<T1> A(X.A);
+  const Proxy<T2> B(X.B);
+  
+  arma_debug_assert_same_size(A, B, "relational operator");
+  
+  ea_type1 PA = A.get_ea();
+  ea_type2 PB = B.get_ea();
+  
+  const uword n_elem = B.get_n_elem();
+  
+  indices.set_size(n_elem, 1);
+  
+  uword* indices_mem = indices.memptr();
+  uword  n_nz        = 0;
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    bool not_zero;
+    
+         if(is_same_type<glue_type, glue_rel_eq    >::value == true)  { not_zero = (PA[i] == PB[i]); }
+    else if(is_same_type<glue_type, glue_rel_noteq >::value == true)  { not_zero = (PA[i] != PB[i]); }
+    else not_zero = false;
+    
+    if(not_zero == true)  { indices_mem[n_nz] = i;  ++n_nz; }
+    }
+  
+  return n_nz;
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_find::apply(Mat<uword>& out, const mtOp<uword, T1, op_find>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword k    = X.aux_uword_a;
+  const uword type = X.aux_uword_b;
+  
+  Mat<uword> indices;
+  const uword n_nz = op_find::helper(indices, X.m);
+  
+  if(n_nz > 0)
+    {
+    if(type == 0)   // "first"
+      {
+      out = (k > 0 && k <= n_nz) ? indices.rows(0,      k-1   ) : indices.rows(0, n_nz-1);
+      }
+    else   // "last"
+      {
+      out = (k > 0 && k <= n_nz) ? indices.rows(n_nz-k, n_nz-1) : indices.rows(0, n_nz-1);
+      }
+    }
+  else
+    {
+    out.set_size(0,1);  // empty column vector
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_flip_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,37 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_flip
+//! @{
+
+
+
+class op_flipud
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_flipud>& in);
+
+  };
+
+
+
+
+class op_fliplr
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_fliplr>& in);
+
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_flip_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,82 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_flip
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+op_flipud::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_flipud>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>  tmp(in.m);
+  const Mat<eT> X = tmp.M;
+  
+  if(&out != &X)
+    {
+    out.copy_size(X);
+    
+    for(uword i=0; i<X.n_rows; ++i)
+      {
+      out.row(i) = X.row(X.n_rows-1 - i);
+      }
+    }
+  else
+    {
+    const uword N = X.n_rows / 2;
+    
+    for(uword i=0; i<N; ++i)
+      {
+      out.swap_rows(i, X.n_rows-1 - i);
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_fliplr::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_fliplr>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>  tmp(in.m);
+  const Mat<eT> X = tmp.M;
+  
+  if(&out != &X)
+    {
+    out.copy_size(X);
+    
+    for(uword i=0; i<X.n_cols; ++i)
+      {
+      out.col(i) = X.col(X.n_cols-1 - i);
+      }
+    }
+  else
+    {
+    const uword N = X.n_cols / 2;
+    
+    for(uword i=0; i<N; ++i)
+      {
+      out.swap_cols(i, X.n_cols-1 - i);
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_hist_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,25 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_hist
+//! @{
+
+
+
+class op_hist
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_hist>& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_hist_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,82 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_hist
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+op_hist::apply(Mat<uword>& out, const mtOp<uword, T1, op_hist>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword n_bins = X.aux_uword_a;
+  
+  const unwrap_check_mixed<T1> tmp(X.m, out);
+  const Mat<eT>& A           = tmp.M;
+  
+  
+        uword A_n_elem = A.n_elem;
+  const eT*   A_mem    = A.memptr();
+  
+  eT min_val = priv::most_pos<eT>();
+  eT max_val = priv::most_neg<eT>();
+  
+  uword i,j;
+  for(i=0, j=1; j < A_n_elem; i+=2, j+=2)
+    {
+    const eT val_i = A_mem[i];
+    const eT val_j = A_mem[j];
+    
+    if(min_val > val_i) { min_val = val_i; }
+    if(min_val > val_j) { min_val = val_j; }
+      
+    if(max_val < val_i) { max_val = val_i; }
+    if(max_val < val_j) { max_val = val_j; }
+    }
+  
+  if(i < A_n_elem)
+    {
+    const eT val_i = A_mem[i];
+    
+    if(min_val > val_i) { min_val = val_i; }
+    if(max_val < val_i) { max_val = val_i; }
+    }
+  
+  if(arma_isfinite(min_val) == false) { min_val = priv::most_neg<eT>(); }
+  if(arma_isfinite(max_val) == false) { max_val = priv::most_pos<eT>(); }
+  
+  if(n_bins >= 1)
+    {
+    Col<eT> c(n_bins);
+    eT* c_mem = c.memptr();
+    
+    for(uword ii=0; ii < n_bins; ++ii)
+      {
+      c_mem[ii] = (0.5 + ii) / double(n_bins);   // TODO: may need to be modified for integer matrices
+      }
+    
+    c = ((max_val - min_val) * c) + min_val;
+    
+    out = hist(A, c);
+    }
+  else
+    {
+    out.reset();
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_htrans_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,80 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_htrans
+//! @{
+
+
+//! 'hermitian transpose' operation
+
+class op_htrans
+  {
+  public:
+  
+  template<typename eT>
+  arma_hot arma_inline static void apply_noalias(Mat<eT>& out, const Mat<eT>& A, const typename arma_not_cx<eT>::result* junk = 0);
+  
+  template<typename eT>
+  arma_hot inline static void apply_noalias(Mat<eT>& out, const Mat<eT>& A, const typename arma_cx_only<eT>::result* junk = 0);
+  
+  //
+  
+  template<typename eT>
+  arma_hot arma_inline static void apply(Mat<eT>& out, const Mat<eT>& A, const typename arma_not_cx<eT>::result* junk = 0);
+  
+  template<typename eT>
+  arma_hot inline static void apply(Mat<eT>& out, const Mat<eT>& A, const typename arma_cx_only<eT>::result* junk = 0);
+  
+  //
+  
+  template<typename T1>
+  arma_hot inline static void apply_proxy(Mat<typename T1::elem_type>& out, const T1& X);
+  
+  //
+  
+  template<typename T1>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_htrans>& in, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0);
+  
+  template<typename T1>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_htrans>& in, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0);
+  
+  //
+  
+  template<typename T1>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Op< Op<T1, op_trimat>, op_htrans>& in);
+  };
+
+
+
+class op_htrans2
+  {
+  public:
+  
+  template<typename eT>
+  arma_hot inline static void apply_noalias(Mat<eT>& out, const Mat<eT>& A, const eT val);
+  
+  template<typename eT>
+  arma_hot inline static void apply(Mat<eT>& out, const Mat<eT>& A, const eT val);
+  
+  //
+  
+  template<typename T1>
+  arma_hot inline static void apply_proxy(Mat<typename T1::elem_type>& out, const T1& X, const typename T1::elem_type val);
+  
+  //
+  
+  template<typename T1>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_htrans2>& in, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0);
+  
+  template<typename T1>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_htrans2>& in, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_htrans_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,495 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_htrans
+//! @{
+
+
+
+template<typename eT>
+arma_hot
+arma_inline
+void
+op_htrans::apply_noalias(Mat<eT>& out, const Mat<eT>& A, const typename arma_not_cx<eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  op_strans::apply_noalias(out, A);
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+op_htrans::apply_noalias(Mat<eT>& out, const Mat<eT>& A, const typename arma_cx_only<eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const uword A_n_rows = A.n_rows;
+  const uword A_n_cols = A.n_cols;
+  
+  out.set_size(A_n_cols, A_n_rows);
+  
+  if( (A_n_cols == 1) || (A_n_rows == 1) )
+    {
+    const uword n_elem = A.n_elem;
+    
+    const eT* A_mem   = A.memptr();
+          eT* out_mem = out.memptr();
+    
+    for(uword i=0; i < n_elem; ++i)
+      {
+      out_mem[i] = std::conj(A_mem[i]);
+      }
+    }
+  else
+    {
+    for(uword in_row = 0; in_row < A_n_rows; ++in_row)
+      {
+      const uword out_col = in_row;
+      
+      for(uword in_col = 0; in_col < A_n_cols; ++in_col)
+        {
+        const uword out_row = in_col;
+        out.at(out_row, out_col) = std::conj( A.at(in_row, in_col) );
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+arma_inline
+void
+op_htrans::apply(Mat<eT>& out, const Mat<eT>& A, const typename arma_not_cx<eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  op_strans::apply(out, A);
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+op_htrans::apply(Mat<eT>& out, const Mat<eT>& A, const typename arma_cx_only<eT>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  if(&out != &A)
+    {
+    op_htrans::apply_noalias(out, A);
+    }
+  else
+    {
+    const uword n_rows = out.n_rows;
+    const uword n_cols = out.n_cols;
+      
+    if(n_rows == n_cols)
+      {
+      arma_extra_debug_print("doing in-place hermitian transpose of a square matrix");
+      
+      for(uword col=0; col < n_cols; ++col)
+        {
+        eT* coldata = out.colptr(col);
+        
+        out.at(col,col) = std::conj( out.at(col,col) );
+        
+        for(uword row=(col+1); row < n_rows; ++row)
+          {
+          const eT val1 = std::conj(coldata[row]);
+          const eT val2 = std::conj(out.at(col,row));
+          
+          out.at(col,row) = val1;
+          coldata[row]    = val2;
+          }
+        }
+      }
+    else
+      {
+      Mat<eT> tmp;
+      op_htrans::apply_noalias(tmp, A);
+      
+      out.steal_mem(tmp);
+      }
+    }
+  
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_htrans::apply_proxy(Mat<typename T1::elem_type>& out, const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(X);
+  
+  // allow detection of in-place transpose
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) && (Proxy<T1>::fake_mat == false) )
+    {
+    const unwrap<typename Proxy<T1>::stored_type> tmp(P.Q);
+    
+    op_htrans::apply(out, tmp.M);
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    const bool is_alias = P.is_alias(out);
+    
+    if( (resolves_to_vector<T1>::value == true) && (Proxy<T1>::prefer_at_accessor == false) )
+      {
+      if(is_alias == false)
+        {
+        out.set_size(n_cols, n_rows);
+        
+        eT* out_mem = out.memptr();
+        
+        const uword n_elem = P.get_n_elem();
+        
+        typename Proxy<T1>::ea_type Pea = P.get_ea();
+        
+        for(uword i=0; i < n_elem; ++i)
+          {
+          out_mem[i] = std::conj(Pea[i]);
+          }
+        }
+      else  // aliasing
+        {
+        Mat<eT> out2(n_cols, n_rows);
+        
+        eT* out_mem = out2.memptr();
+        
+        const uword n_elem = P.get_n_elem();
+        
+        typename Proxy<T1>::ea_type Pea = P.get_ea();
+        
+        for(uword i=0; i < n_elem; ++i)
+          {
+          out_mem[i] = std::conj(Pea[i]);
+          }
+        
+        out.steal_mem(out2);
+        }
+      }
+    else
+      {
+      if(is_alias == false)
+        {
+        out.set_size(n_cols, n_rows);
+        
+        for(uword k=0; k < n_cols; ++k)
+        for(uword i=0; i < n_rows; ++i)
+          {
+          out.at(k,i) = std::conj(P.at(i,k));
+          }
+        }
+      else // aliasing
+        {
+        Mat<eT> out2(n_cols, n_rows);
+        
+        for(uword k=0; k < n_cols; ++k)
+        for(uword i=0; i < n_rows; ++i)
+          {
+          out2.at(k,i) = std::conj(P.at(i,k));
+          }
+        
+        out.steal_mem(out2);
+        }
+      }
+    }
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_htrans::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_htrans>& in, const typename arma_not_cx<typename T1::elem_type>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  op_strans::apply_proxy(out, in.m);
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_htrans::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_htrans>& in, const typename arma_cx_only<typename T1::elem_type>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  op_htrans::apply_proxy(out, in.m);
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_htrans::apply(Mat<typename T1::elem_type>& out, const Op< Op<T1, op_trimat>, op_htrans>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   tmp(in.m.m);
+  const Mat<eT>& A = tmp.M;
+  
+  const bool upper = in.m.aux_uword_a;
+  
+  op_trimat::apply_htrans(out, A, upper);
+  }
+
+
+
+//
+// op_htrans2
+
+
+
+template<typename eT>
+arma_hot
+arma_inline
+void
+op_htrans2::apply_noalias(Mat<eT>& out, const Mat<eT>& A, const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword A_n_rows = A.n_rows;
+  const uword A_n_cols = A.n_cols;
+  
+  out.set_size(A_n_cols, A_n_rows);
+  
+  if( (A_n_cols == 1) || (A_n_rows == 1) )
+    {
+    const uword n_elem = A.n_elem;
+    
+    const eT* A_mem   = A.memptr();
+          eT* out_mem = out.memptr();
+    
+    for(uword i=0; i < n_elem; ++i)
+      {
+      out_mem[i] = val * std::conj(A_mem[i]);
+      }
+    }
+  else
+    {
+    for(uword in_row = 0; in_row < A_n_rows; ++in_row)
+      {
+      const uword out_col = in_row;
+      
+      for(uword in_col = 0; in_col < A_n_cols; ++in_col)
+        {
+        const uword out_row = in_col;
+        out.at(out_row, out_col) = val * std::conj( A.at(in_row, in_col) );
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+op_htrans2::apply(Mat<eT>& out, const Mat<eT>& A, const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(&out != &A)
+    {
+    op_htrans2::apply_noalias(out, A, val);
+    }
+  else
+    {
+    const uword n_rows = out.n_rows;
+    const uword n_cols = out.n_cols;
+      
+    if(n_rows == n_cols)
+      {
+      arma_extra_debug_print("doing in-place hermitian transpose of a square matrix");
+      
+      // TODO: do multiplication while swapping
+      
+      for(uword col=0; col < n_cols; ++col)
+        {
+        eT* coldata = out.colptr(col);
+        
+        out.at(col,col) = std::conj( out.at(col,col) );
+        
+        for(uword row=(col+1); row < n_rows; ++row)
+          {
+          const eT val1 = std::conj(coldata[row]);
+          const eT val2 = std::conj(out.at(col,row));
+          
+          out.at(col,row) = val1;
+          coldata[row]    = val2;
+          }
+        }
+      
+      arrayops::inplace_mul( out.memptr(), val, out.n_elem );
+      }
+    else
+      {
+      Mat<eT> tmp;
+      op_htrans2::apply_noalias(tmp, A, val);
+      
+      out.steal_mem(tmp);
+      }
+    }
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_htrans2::apply_proxy(Mat<typename T1::elem_type>& out, const T1& X, const typename T1::elem_type val)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(X);
+  
+  // allow detection of in-place transpose
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) && (Proxy<T1>::fake_mat == false) )
+    {
+    const unwrap<typename Proxy<T1>::stored_type> tmp(P.Q);
+    
+    op_htrans2::apply(out, tmp.M, val);
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    const bool is_alias = P.is_alias(out);
+    
+    if( (resolves_to_vector<T1>::value == true) && (Proxy<T1>::prefer_at_accessor == false) )
+      {
+      if(is_alias == false)
+        {
+        out.set_size(n_cols, n_rows);
+        
+        eT* out_mem = out.memptr();
+        
+        const uword n_elem = P.get_n_elem();
+        
+        typename Proxy<T1>::ea_type Pea = P.get_ea();
+        
+        for(uword i=0; i < n_elem; ++i)
+          {
+          out_mem[i] = val * std::conj(Pea[i]);
+          }
+        }
+      else  // aliasing
+        {
+        Mat<eT> out2(n_cols, n_rows);
+        
+        eT* out_mem = out2.memptr();
+        
+        const uword n_elem = P.get_n_elem();
+        
+        typename Proxy<T1>::ea_type Pea = P.get_ea();
+        
+        for(uword i=0; i < n_elem; ++i)
+          {
+          out_mem[i] = val * std::conj(Pea[i]);
+          }
+        
+        out.steal_mem(out2);
+        }
+      }
+    else
+      {
+      if(is_alias == false)
+        {
+        out.set_size(n_cols, n_rows);
+        
+        for(uword k=0; k < n_cols; ++k)
+        for(uword i=0; i < n_rows; ++i)
+          {
+          out.at(k,i) = val * std::conj(P.at(i,k));
+          }
+        }
+      else // aliasing
+        {
+        Mat<eT> out2(n_cols, n_rows);
+        
+        for(uword k=0; k < n_cols; ++k)
+        for(uword i=0; i < n_rows; ++i)
+          {
+          out2.at(k,i) = val * std::conj(P.at(i,k));
+          }
+        
+        out.steal_mem(out2);
+        }
+      }
+    }
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_htrans2::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_htrans2>& in, const typename arma_not_cx<typename T1::elem_type>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  op_strans2::apply_proxy(out, in.m, in.aux);
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_htrans2::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_htrans2>& in, const typename arma_cx_only<typename T1::elem_type>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  op_htrans2::apply_proxy(out, in.m, in.aux);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_inv_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,53 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_inv
+//! @{
+
+
+
+//! 'invert matrix' operation (general matrices)
+class op_inv
+  {
+  public:
+  
+  template<typename eT>
+  inline static void apply(Mat<eT>& out, const Mat<eT>& A, const bool slow = false);
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv>& in);
+  
+  template<typename T1>
+  inline static void apply_diag(Mat<typename T1::elem_type>& out, const Base<typename T1::elem_type, T1>& X);
+  };
+
+
+
+//! 'invert matrix' operation (triangular matrices)
+class op_inv_tr
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv_tr>& in);
+  };
+
+
+
+//! 'invert matrix' operation (symmetric positive definite matrices)
+class op_inv_sympd
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv_sympd>& in);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_inv_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,132 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_inv
+//! @{
+
+
+//! immediate inverse of a matrix, storing the result in a dense matrix
+template<typename eT>
+inline
+void
+op_inv::apply(Mat<eT>& out, const Mat<eT>& A, const bool slow)
+  {
+  arma_extra_debug_sigprint();
+  
+  // no need to check for aliasing, due to:
+  // - auxlib::inv() copies A to out before inversion
+  // - for 2x2 and 3x3 matrices the code is alias safe
+  
+  bool status = auxlib::inv(out, A, slow);
+  
+  if(status == false)
+    {
+    out.reset();
+    arma_bad("inv(): matrix appears to be singular");
+    }
+  }
+
+
+
+//! immediate inverse of T1, storing the result in a dense matrix
+template<typename T1>
+inline
+void
+op_inv::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const strip_diagmat<T1> strip(X.m);
+  
+  if(strip.do_diagmat == true)
+    {
+    op_inv::apply_diag(out, strip.M);
+    }
+  else
+    {
+    const uword mode = X.aux_uword_a;
+    
+    const bool status = (mode == 0) ? auxlib::inv(out, X.m) : auxlib::inv(out, X.m, true);
+    
+    if(status == false)
+      {
+      out.reset();
+      arma_bad("inv(): matrix appears to be singular");
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_inv::apply_diag(Mat<typename T1::elem_type>& out, const Base<typename T1::elem_type, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const diagmat_proxy_check<T1> A(X.get_ref(), out);
+  
+  const uword N = A.n_elem;
+  
+  out.set_size(N,N);
+  
+  for(uword col=0; col<N; ++col)
+    {
+    for(uword row=0; row<col; ++row)   { out.at(row,col) = eT(0); }
+    
+    out.at(col,col) = eT(1) / A[col];
+    
+    for(uword row=col+1; row<N; ++row) { out.at(row,col) = eT(0); }
+    }
+  
+  }
+
+
+
+//! inverse of T1 (triangular matrices)
+template<typename T1>
+inline
+void
+op_inv_tr::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv_tr>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool status = auxlib::inv_tr(out, X.m, X.aux_uword_a);
+  
+  if(status == false)
+    {
+    out.reset();
+    arma_bad("inv(): matrix appears to be singular");
+    }
+  }
+
+
+
+//! inverse of T1 (symmetric positive definite matrices)
+template<typename T1>
+inline
+void
+op_inv_sympd::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_inv_sympd>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool status = auxlib::inv_sympd(out, X.m, X.aux_uword_a);
+  
+  if(status == false)
+    {
+    out.reset();
+    arma_bad("inv(): matrix appears to be singular");
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_max_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,63 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_max
+//! @{
+
+
+
+//! Class for finding maximum values in a matrix
+class op_max
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_max>& in);
+  
+  
+  //
+  // for non-complex numbers
+  
+  template<typename eT>
+  inline static eT direct_max(const eT* const X, const uword N);
+  
+  template<typename eT>
+  inline static eT direct_max(const eT* const X, const uword N, uword& index_of_max_val);
+  
+  template<typename eT>
+  inline static eT direct_max(const Mat<eT>& X, const uword row);
+  
+  template<typename eT>
+  inline static eT max(const subview<eT>& X);
+  
+  template<typename T1>
+  inline static typename arma_not_cx<typename T1::elem_type>::result max(const Base<typename T1::elem_type, T1>& X);
+  
+  
+  //
+  // for complex numbers
+  
+  template<typename T>
+  inline static std::complex<T> direct_max(const std::complex<T>* const X, const uword n_elem);
+  
+  template<typename T>
+  inline static std::complex<T> direct_max(const std::complex<T>* const X, const uword n_elem, uword& index_of_max_val);
+  
+  template<typename T>
+  inline static std::complex<T> direct_max(const Mat< std::complex<T> >& X, const uword row);
+  
+  template<typename T>
+  inline static std::complex<T> max(const subview< std::complex<T> >& X);
+  
+  template<typename T1>
+  inline static typename arma_cx_only<typename T1::elem_type>::result max(const Base<typename T1::elem_type, T1>& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_max_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,565 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_max
+//! @{
+
+
+
+//! \brief
+//! For each row or for each column, find the maximum value.
+//! The result is stored in a dense matrix that has either one column or one row.
+//! The dimension, for which the maxima are found, is set via the max() function.
+template<typename T1>
+inline
+void
+op_max::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_max>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> tmp(in.m, out);
+  const Mat<eT>& X     = tmp.M;
+  
+  const uword dim = in.aux_uword_a;
+  arma_debug_check( (dim > 1), "max(): incorrect usage. dim must be 0 or 1");
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  if(dim == 0)
+    {
+    arma_extra_debug_print("op_max::apply(), dim = 0");
+    
+    arma_debug_check( (X_n_rows == 0), "max(): given object has zero rows" );
+
+    out.set_size(1, X_n_cols);
+    
+    eT* out_mem = out.memptr();
+    
+    for(uword col=0; col<X_n_cols; ++col)
+      {
+      out_mem[col] = op_max::direct_max( X.colptr(col), X_n_rows );
+      }
+    }
+  else
+  if(dim == 1)
+    {
+    arma_extra_debug_print("op_max::apply(), dim = 1");
+    
+    arma_debug_check( (X_n_cols == 0), "max(): given object has zero columns" );
+
+    out.set_size(X_n_rows, 1);
+    
+    eT* out_mem = out.memptr();
+    
+    for(uword row=0; row<X_n_rows; ++row)
+      {
+      out_mem[row] = op_max::direct_max( X, row );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_pure
+inline
+eT
+op_max::direct_max(const eT* const X, const uword n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT max_val = priv::most_neg<eT>();
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT X_i = X[i];
+    const eT X_j = X[j];
+    
+    if(X_i > max_val) { max_val = X_i; }
+    if(X_j > max_val) { max_val = X_j; }
+    }
+  
+  
+  if(i < n_elem)
+    {
+    const eT X_i = X[i];
+    
+    if(X_i > max_val) { max_val = X_i; }
+    }
+  
+  return max_val;
+  }
+
+
+
+template<typename eT>
+inline
+eT
+op_max::direct_max(const eT* const X, const uword n_elem, uword& index_of_max_val)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT max_val = priv::most_neg<eT>();
+  
+  uword best_index = 0;
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT X_i = X[i];
+    const eT X_j = X[j];
+    
+    if(X_i > max_val)
+      {
+      max_val    = X_i;
+      best_index = i;
+      }
+    
+    if(X_j > max_val)
+      {
+      max_val    = X_j;
+      best_index = j;
+      }
+    }
+  
+  
+  if(i < n_elem)
+    {
+    const eT X_i = X[i];
+    
+    if(X_i > max_val)
+      {
+      max_val    = X_i;
+      best_index = i;
+      }
+    }
+  
+  index_of_max_val = best_index;
+  
+  return max_val;
+  }
+
+
+
+template<typename eT>
+inline
+eT
+op_max::direct_max(const Mat<eT>& X, const uword row)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword X_n_cols = X.n_cols;
+  
+  eT max_val = priv::most_neg<eT>();
+  
+  uword i,j;
+  for(i=0, j=1; j < X_n_cols; i+=2, j+=2)
+    {
+    const eT tmp_i = X.at(row,i);
+    const eT tmp_j = X.at(row,j);
+    
+    if(tmp_i > max_val) { max_val = tmp_i; }
+    if(tmp_j > max_val) { max_val = tmp_j; }
+    }
+  
+  if(i < X_n_cols)
+    {
+    const eT tmp_i = X.at(row,i);
+    
+    if(tmp_i > max_val) { max_val = tmp_i; }
+    }
+  
+  return max_val;
+  }
+
+
+
+template<typename eT>
+inline
+eT
+op_max::max(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (X.n_elem == 0), "max(): given object has no elements" );
+
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  eT max_val = priv::most_neg<eT>();
+  
+  if(X_n_rows == 1)
+    {
+    const Mat<eT>& A = X.m;
+    
+    const uword start_row = X.aux_row1;
+    const uword start_col = X.aux_col1;
+    
+    const uword end_col_p1 = start_col + X_n_cols;
+  
+    uword i,j;
+    for(i=start_col, j=start_col+1; j < end_col_p1; i+=2, j+=2)
+      {
+      const eT tmp_i = A.at(start_row, i);
+      const eT tmp_j = A.at(start_row, j);
+      
+      if(tmp_i > max_val) { max_val = tmp_i; }
+      if(tmp_j > max_val) { max_val = tmp_j; }
+      }
+    
+    if(i < end_col_p1)
+      {
+      const eT tmp_i = A.at(start_row, i);
+      
+      if(tmp_i > max_val) { max_val = tmp_i; }
+      }
+    }
+  else
+    {
+    for(uword col=0; col < X_n_cols; ++col)
+      {
+      eT tmp_val = op_max::direct_max(X.colptr(col), X_n_rows);
+      
+      if(tmp_val > max_val) { max_val = tmp_val; }
+      }
+    }
+  
+  return max_val;
+  }
+
+
+
+template<typename T1>
+inline
+typename arma_not_cx<typename T1::elem_type>::result
+op_max::max(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(X.get_ref());
+  
+  const uword n_elem = P.get_n_elem();
+  
+  arma_debug_check( (n_elem == 0), "max(): given object has no elements" );
+  
+  eT max_val = priv::most_neg<eT>();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typedef typename Proxy<T1>::ea_type ea_type;
+    
+    ea_type A = P.get_ea();
+    
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      const eT tmp_i = A[i];
+      const eT tmp_j = A[j];
+      
+      if(tmp_i > max_val) { max_val = tmp_i; }
+      if(tmp_j > max_val) { max_val = tmp_j; }
+      }
+    
+    if(i < n_elem)
+      {
+      const eT tmp_i = A[i];
+      
+      if(tmp_i > max_val) { max_val = tmp_i; }
+      }
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    if(n_rows == 1)
+      {
+      uword i,j;
+      for(i=0, j=1; j < n_cols; i+=2, j+=2)
+        {
+        const eT tmp_i = P.at(0,i);
+        const eT tmp_j = P.at(0,j);
+        
+        if(tmp_i > max_val) { max_val = tmp_i; }
+        if(tmp_j > max_val) { max_val = tmp_j; }
+        }
+      
+      if(i < n_cols)
+        {
+        const eT tmp_i = P.at(0,i);
+        
+        if(tmp_i > max_val) { max_val = tmp_i; }
+        }
+      }
+    else
+      {
+      for(uword col=0; col < n_cols; ++col)
+        {
+        uword i,j;
+        for(i=0, j=1; j < n_rows; i+=2, j+=2)
+          {
+          const eT tmp_i = P.at(i,col);
+          const eT tmp_j = P.at(j,col);
+          
+          if(tmp_i > max_val) { max_val = tmp_i; }
+          if(tmp_j > max_val) { max_val = tmp_j; }
+          }
+          
+        if(i < n_rows)
+          {
+          const eT tmp_i = P.at(i,col);
+          
+          if(tmp_i > max_val) { max_val = tmp_i; }
+          }
+        }
+      }
+    }
+  
+  return max_val;
+  }
+
+
+
+template<typename T>
+inline
+std::complex<T>
+op_max::direct_max(const std::complex<T>* const X, const uword n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  uword index   = 0;
+  T   max_val = priv::most_neg<T>();
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    const T tmp_val = std::abs(X[i]);
+    
+    if(tmp_val > max_val)
+      {
+      max_val = tmp_val;
+      index   = i;
+      }
+    }
+  
+  return X[index];
+  }
+
+
+
+template<typename T>
+inline
+std::complex<T>
+op_max::direct_max(const std::complex<T>* const X, const uword n_elem, uword& index_of_max_val)
+  {
+  arma_extra_debug_sigprint();
+  
+  uword index   = 0;
+  T   max_val = priv::most_neg<T>();
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    const T tmp_val = std::abs(X[i]);
+    
+    if(tmp_val > max_val)
+      {
+      max_val = tmp_val;
+      index   = i;
+      }
+    }
+  
+  index_of_max_val = index;
+  
+  return X[index];
+  }
+
+
+
+template<typename T>
+inline 
+std::complex<T>
+op_max::direct_max(const Mat< std::complex<T> >& X, const uword row)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword X_n_cols = X.n_cols;
+  
+  uword index   = 0;
+  T   max_val = priv::most_neg<T>();
+  
+  for(uword col=0; col<X_n_cols; ++col)
+    {
+    const T tmp_val = std::abs(X.at(row,col));
+    
+    if(tmp_val > max_val)
+      {
+      max_val = tmp_val;
+      index   = col;
+      }
+    }
+  
+  return X.at(row,index);
+  }
+
+
+
+template<typename T>
+inline
+std::complex<T>
+op_max::max(const subview< std::complex<T> >& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (X.n_elem == 0), "max(): given object has no elements" );
+  
+  const Mat< std::complex<T> >& A = X.m;
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  const uword start_row = X.aux_row1;
+  const uword start_col = X.aux_col1;
+  
+  const uword end_row_p1 = start_row + X_n_rows;
+  const uword end_col_p1 = start_col + X_n_cols;
+  
+  T max_val = priv::most_neg<T>();
+  
+  uword best_row = 0;
+  uword best_col = 0;
+    
+  if(X_n_rows == 1)
+    {
+    best_col = 0;
+    
+    for(uword col=start_col; col < end_col_p1; ++col)
+      {
+      const T tmp_val = std::abs( A.at(start_row, col) );
+      
+      if(tmp_val > max_val)
+        {
+        max_val  = tmp_val;
+        best_col = col;
+        }
+      }
+    
+    best_row = start_row;
+    }
+  else
+    {
+    for(uword col=start_col; col < end_col_p1; ++col)
+    for(uword row=start_row; row < end_row_p1; ++row)
+      {
+      const T tmp_val = std::abs( A.at(row, col) );
+      
+      if(tmp_val > max_val)
+        {
+        max_val  = tmp_val;
+        best_row = row;
+        best_col = col;
+        }
+      }
+    }
+  
+  return A.at(best_row, best_col);
+  }
+
+
+
+template<typename T1>
+inline
+typename arma_cx_only<typename T1::elem_type>::result
+op_max::max(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type            eT;
+  typedef typename get_pod_type<eT>::result T;
+  
+  const Proxy<T1> P(X.get_ref());
+  
+  const uword n_elem = P.get_n_elem();
+  
+  arma_debug_check( (n_elem == 0), "max(): given object has no elements" );
+  
+  T max_val = priv::most_neg<T>();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typedef typename Proxy<T1>::ea_type ea_type;
+    
+    ea_type A = P.get_ea();
+    
+    uword index = 0;
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      const T tmp = std::abs(A[i]);
+      
+      if(tmp > max_val)
+        {
+        max_val = tmp;
+        index   = i;
+        }
+      }
+    
+    return( A[index] );
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    uword best_row = 0;
+    uword best_col = 0;
+    
+    if(n_rows == 1)
+      {
+      for(uword col=0; col < n_cols; ++col)
+        {
+        const T tmp = std::abs(P.at(0,col));
+        
+        if(tmp > max_val)
+          {
+          max_val  = tmp;
+          best_col = col;
+          }
+        }
+      }
+    else
+      {
+      for(uword col=0; col < n_cols; ++col)
+      for(uword row=0; row < n_rows; ++row)
+        {
+        const T tmp = std::abs(P.at(row,col));
+        
+        if(tmp > max_val)
+          {
+          max_val = tmp;
+          
+          best_row = row;
+          best_col = col;
+          }
+        }
+      }
+    
+    return P.at(best_row, best_col);
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_mean_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,75 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_mean
+//! @{
+
+
+//! Class for finding mean values of a matrix
+class op_mean
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_mean>& in);
+  
+
+  //
+  
+  template<typename eT>
+  inline static eT direct_mean(const eT* const X, const uword N);
+  
+  template<typename eT>
+  inline static eT direct_mean_robust(const eT* const X, const uword N);
+  
+
+  //
+  
+  template<typename eT>
+  inline static eT direct_mean(const Mat<eT>& X, const uword row);
+  
+  template<typename eT>
+  inline static eT direct_mean_robust(const Mat<eT>& X, const uword row);
+  
+
+  //
+  
+  template<typename eT>
+  inline static eT mean_all(const subview<eT>& X);
+  
+  template<typename eT>
+  inline static eT mean_all_robust(const subview<eT>& X);
+  
+  
+  //
+  
+  template<typename eT>
+  inline static eT mean_all(const diagview<eT>& X);
+  
+  template<typename eT>
+  inline static eT mean_all_robust(const diagview<eT>& X);
+  
+  
+  //
+  
+  template<typename T1>
+  inline static typename T1::elem_type mean_all(const Base<typename T1::elem_type, T1>& X);
+  
+  
+  //
+  
+  template<typename eT>
+  arma_inline static eT robust_mean(const eT A, const eT B);
+  
+  template<typename T>
+  arma_inline static std::complex<T> robust_mean(const std::complex<T>& A, const std::complex<T>& B);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_mean_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,376 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_mean
+//! @{
+
+
+
+//! \brief
+//! For each row or for each column, find the mean value.
+//! The result is stored in a dense matrix that has either one column or one row.
+//! The dimension, for which the means are found, is set via the mean() function.
+template<typename T1>
+inline
+void
+op_mean::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_mean>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> tmp(in.m, out);
+  const Mat<eT>& X = tmp.M;
+  
+  const uword dim = in.aux_uword_a;
+  arma_debug_check( (dim > 1), "mean(): incorrect usage. dim must be 0 or 1");
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  if(dim == 0)
+    {
+    arma_extra_debug_print("op_mean::apply(), dim = 0");
+    
+    out.set_size( (X_n_rows > 0) ? 1 : 0, X_n_cols );
+    
+    if(X_n_rows > 0)
+      {
+      eT* out_mem = out.memptr();
+      
+      for(uword col=0; col < X_n_cols; ++col)
+        {
+        out_mem[col] = op_mean::direct_mean( X.colptr(col), X_n_rows );
+        }
+      }
+    }
+  else
+  if(dim == 1)
+    {
+    arma_extra_debug_print("op_mean::apply(), dim = 1");
+    
+    out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0);
+    
+    if(X_n_cols > 0)
+      {
+      eT* out_mem = out.memptr();
+      
+      for(uword row=0; row < X_n_rows; ++row)
+        {
+        out_mem[row] = op_mean::direct_mean( X, row );
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_pure
+inline
+eT
+op_mean::direct_mean(const eT* const X, const uword n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  const eT result = arrayops::accumulate(X, n_elem) / T(n_elem);
+  
+  return arma_isfinite(result) ? result : op_mean::direct_mean_robust(X, n_elem);
+  }
+
+
+
+template<typename eT>
+arma_pure
+inline
+eT
+op_mean::direct_mean_robust(const eT* const X, const uword n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  // use an adapted form of the mean finding algorithm from the running_stat class
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  uword i,j;
+  
+  eT r_mean = eT(0);
+  
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT Xi = X[i];
+    const eT Xj = X[j];
+    
+    r_mean = r_mean + (Xi - r_mean)/T(j);    // we need i+1, and j is equivalent to i+1 here
+    r_mean = r_mean + (Xj - r_mean)/T(j+1);
+    }
+  
+  
+  if(i < n_elem)
+    {
+    const eT Xi = X[i];
+    
+    r_mean = r_mean + (Xi - r_mean)/T(i+1);
+    }
+  
+  return r_mean;
+  }
+
+
+
+template<typename eT>
+inline
+eT
+op_mean::direct_mean(const Mat<eT>& X, const uword row)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  const uword X_n_cols = X.n_cols;
+  
+  eT val = eT(0);
+  
+  uword i,j;
+  for(i=0, j=1; j < X_n_cols; i+=2, j+=2)
+    {
+    val += X.at(row,i);
+    val += X.at(row,j);
+    }
+  
+  if(i < X_n_cols)
+    {
+    val += X.at(row,i);
+    }
+  
+  const eT result = val / T(X_n_cols);
+  
+  return arma_isfinite(result) ? result : op_mean::direct_mean_robust(X, row);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+op_mean::direct_mean_robust(const Mat<eT>& X, const uword row)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  const uword X_n_cols = X.n_cols;
+  
+  eT r_mean = eT(0);
+  
+  for(uword col=0; col < X_n_cols; ++col)
+    {
+    r_mean = r_mean + (X.at(row,col) - r_mean)/T(col+1);
+    }
+  
+  return r_mean;
+  }
+
+
+
+template<typename eT>
+inline
+eT
+op_mean::mean_all(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  const uword X_n_elem = X.n_elem;
+  
+  arma_debug_check( (X_n_elem == 0), "mean(): given object has no elements" );
+  
+  eT val = eT(0);
+  
+  if(X_n_rows == 1)
+    {
+    const Mat<eT>& A = X.m;
+    
+    const uword start_row = X.aux_row1;
+    const uword start_col = X.aux_col1;
+    
+    const uword end_col_p1 = start_col + X_n_cols;
+    
+    uword i,j;
+    for(i=start_col, j=start_col+1; j < end_col_p1; i+=2, j+=2)
+      {
+      val += A.at(start_row, i);
+      val += A.at(start_row, j);
+      }
+    
+    if(i < end_col_p1)
+      {
+      val += A.at(start_row, i);
+      }
+    }
+  else
+    {
+    for(uword col=0; col < X_n_cols; ++col)
+      {
+      val += arrayops::accumulate(X.colptr(col), X_n_rows);
+      }
+    }
+  
+  const eT result = val / T(X_n_elem);
+  
+  return arma_isfinite(result) ? result : op_mean::mean_all_robust(X);
+  }
+
+
+
+template<typename eT>
+inline 
+eT
+op_mean::mean_all_robust(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  const uword start_row = X.aux_row1;
+  const uword start_col = X.aux_col1;
+  
+  const uword end_row_p1 = start_row + X_n_rows;
+  const uword end_col_p1 = start_col + X_n_cols;
+  
+  const Mat<eT>& A = X.m;
+  
+  
+  eT r_mean = eT(0);
+  
+  if(X_n_rows == 1)
+    {
+    uword i=0;
+    
+    for(uword col = start_col; col < end_col_p1; ++col, ++i)
+      {
+      r_mean = r_mean + (A.at(start_row,col) - r_mean)/T(i+1);
+      }
+    }
+  else
+    {
+    uword i=0;
+    
+    for(uword col = start_col; col < end_col_p1; ++col)
+    for(uword row = start_row; row < end_row_p1; ++row, ++i)
+      {
+      r_mean = r_mean + (A.at(row,col) - r_mean)/T(i+1);
+      }
+    }
+  
+  return r_mean;
+  }
+
+
+
+template<typename eT>
+inline 
+eT
+op_mean::mean_all(const diagview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  const uword X_n_elem = X.n_elem;
+  
+  arma_debug_check( (X_n_elem == 0), "mean(): given object has no elements" );
+  
+  eT val = eT(0);
+  
+  for(uword i=0; i<X_n_elem; ++i)
+    {
+    val += X[i];
+    }
+  
+  const eT result = val / T(X_n_elem);
+  
+  return arma_isfinite(result) ? result : op_mean::mean_all_robust(X);
+  }
+
+
+
+template<typename eT>
+inline 
+eT
+op_mean::mean_all_robust(const diagview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  const uword X_n_elem = X.n_elem;
+  
+  eT r_mean = eT(0);
+  
+  for(uword i=0; i<X_n_elem; ++i)
+    {
+    r_mean = r_mean + (X[i] - r_mean)/T(i+1);
+    }
+  
+  return r_mean;
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::elem_type 
+op_mean::mean_all(const Base<typename T1::elem_type, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   tmp(X.get_ref());
+  const Mat<eT>& A = tmp.M;
+  
+  const uword A_n_elem = A.n_elem;
+  
+  arma_debug_check( (A_n_elem == 0), "mean(): given object has no elements" );
+  
+  return op_mean::direct_mean(A.memptr(), A_n_elem);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+op_mean::robust_mean(const eT A, const eT B)
+  {
+  return A + (B - A)/eT(2);
+  }
+
+
+
+template<typename T>
+arma_inline
+std::complex<T>
+op_mean::robust_mean(const std::complex<T>& A, const std::complex<T>& B)
+  {
+  return A + (B - A)/T(2);
+  }
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_median_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,64 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_median
+//! @{
+
+
+template<typename T>
+struct arma_cx_median_packet
+  {
+  T     val;
+  uword index;
+  };
+
+
+
+template<typename T>
+arma_inline
+bool
+operator< (const arma_cx_median_packet<T>& A, const arma_cx_median_packet<T>& B)
+  {
+  return A.val < B.val;
+  }
+
+
+
+//! Class for finding median values of a matrix
+class op_median
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& in);
+  
+  template<typename T, typename T1>
+  inline static void apply(Mat< std::complex<T> >& out, const Op<T1,op_median>& in);
+  
+  //
+  //
+  
+  template<typename T1>
+  inline static typename T1::elem_type median_vec(const T1& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0);
+  
+  template<typename T1>
+  inline static typename T1::elem_type median_vec(const T1& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0);
+  
+  //
+  //
+  
+  template<typename eT>
+  inline static eT direct_median(std::vector<eT>& X);
+  
+  template<typename T>
+  inline static void direct_cx_median_index(uword& out_index1, uword& out_index2, std::vector< arma_cx_median_packet<T> >& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_median_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,414 @@
+// Copyright (C) 2009-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2013 Conrad Sanderson
+// Copyright (C) 2013 Ruslan Shestopalyuk
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_median
+//! @{
+
+
+
+//! \brief
+//! For each row or for each column, find the median value.
+//! The result is stored in a dense matrix that has either one column or one row.
+//! The dimension, for which the medians are found, is set via the median() function.
+template<typename T1>
+inline
+void
+op_median::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword dim = in.aux_uword_a;
+  arma_debug_check( (dim > 1), "median(): incorrect usage. dim must be 0 or 1");
+  
+  const Proxy<T1> P(in.m);
+  
+  typedef typename Proxy<T1>::stored_type P_stored_type;
+  
+  const bool is_alias = P.is_alias(out);
+  
+  if( (is_Mat<P_stored_type>::value == true) || is_alias )
+    {
+    const unwrap_check<P_stored_type> tmp(P.Q, is_alias);
+    
+    const typename unwrap_check<P_stored_type>::stored_type& X = tmp.M;
+    
+    const uword X_n_rows = X.n_rows;
+    const uword X_n_cols = X.n_cols;
+    
+    if(dim == 0)  // in each column
+      {
+      arma_extra_debug_print("op_median::apply(), dim = 0");
+      
+      arma_debug_check( (X_n_rows == 0), "median(): given object has zero rows" );
+      
+      out.set_size(1, X_n_cols);
+      
+      std::vector<eT> tmp_vec(X_n_rows);
+      
+      for(uword col=0; col < X_n_cols; ++col)
+        {
+        arrayops::copy( &(tmp_vec[0]), X.colptr(col), X_n_rows );
+        
+        out[col] = op_median::direct_median(tmp_vec);
+        }
+      }
+    else  // in each row
+      {
+      arma_extra_debug_print("op_median::apply(), dim = 1");
+      
+      arma_debug_check( (X_n_cols == 0), "median(): given object has zero columns" );
+      
+      out.set_size(X_n_rows, 1);
+      
+      std::vector<eT> tmp_vec(X_n_cols);
+        
+      for(uword row=0; row < X_n_rows; ++row)
+        {
+        for(uword col=0; col < X_n_cols; ++col)  { tmp_vec[col] = X.at(row,col); }
+        
+        out[row] = op_median::direct_median(tmp_vec);
+        }
+      }
+    }
+  else
+    {
+    const uword P_n_rows = P.get_n_rows();
+    const uword P_n_cols = P.get_n_cols();
+    
+    if(dim == 0)  // in each column
+      {
+      arma_extra_debug_print("op_median::apply(), dim = 0");
+      
+      arma_debug_check( (P_n_rows == 0), "median(): given object has zero rows" );
+      
+      out.set_size(1, P_n_cols);
+      
+      std::vector<eT> tmp_vec(P_n_rows);
+      
+      for(uword col=0; col < P_n_cols; ++col)
+        {
+        for(uword row=0; row < P_n_rows; ++row)  { tmp_vec[row] = P.at(row,col); }
+        
+        out[col] = op_median::direct_median(tmp_vec);
+        }
+      }
+    else  // in each row
+      {
+      arma_extra_debug_print("op_median::apply(), dim = 1");
+      
+      arma_debug_check( (P_n_cols == 0), "median(): given object has zero columns" );
+      
+      out.set_size(P_n_rows, 1);
+      
+      std::vector<eT> tmp_vec(P_n_cols);
+        
+      for(uword row=0; row < P_n_rows; ++row)
+        {
+        for(uword col=0; col < P_n_cols; ++col)  { tmp_vec[col] = P.at(row,col); }
+        
+        out[row] = op_median::direct_median(tmp_vec);
+        }
+      }
+    }
+  }
+
+
+
+//! Implementation for complex numbers
+template<typename T, typename T1>
+inline
+void
+op_median::apply(Mat< std::complex<T> >& out, const Op<T1,op_median>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<T> eT;
+  
+  arma_type_check(( is_same_type<eT, typename T1::elem_type>::value == false ));
+  
+  const unwrap_check<T1> tmp(in.m, out);
+  const Mat<eT>&     X = tmp.M;
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  const uword dim = in.aux_uword_a;
+  arma_debug_check( (dim > 1), "median(): incorrect usage. dim must be 0 or 1");
+  
+  if(dim == 0)  // in each column
+    {
+    arma_extra_debug_print("op_median::apply(), dim = 0");
+    
+    arma_debug_check( (X_n_rows == 0), "median(): given object has zero rows" );
+
+    out.set_size(1, X_n_cols);
+    
+    std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_rows);
+    
+    for(uword col=0; col<X_n_cols; ++col)
+      {
+      const eT* colmem = X.colptr(col);
+      
+      for(uword row=0; row<X_n_rows; ++row)
+        {
+        tmp_vec[row].val   = std::abs(colmem[row]);
+        tmp_vec[row].index = row;
+        }
+      
+      uword index1;
+      uword index2;
+      op_median::direct_cx_median_index(index1, index2, tmp_vec);
+        
+      out[col] = op_mean::robust_mean(colmem[index1], colmem[index2]);
+      }
+    }
+  else
+  if(dim == 1)  // in each row
+    {
+    arma_extra_debug_print("op_median::apply(), dim = 1");
+    
+    arma_debug_check( (X_n_cols == 0), "median(): given object has zero columns" );
+    
+    out.set_size(X_n_rows, 1);
+    
+    std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_cols);
+    
+    for(uword row=0; row<X_n_rows; ++row)
+      {
+      for(uword col=0; col<X_n_cols; ++col)
+        {
+        tmp_vec[col].val   = std::abs(X.at(row,col));
+        tmp_vec[col].index = col;
+        }
+      
+      uword index1;
+      uword index2;
+      op_median::direct_cx_median_index(index1, index2, tmp_vec);
+      
+      out[row] = op_mean::robust_mean( X.at(row,index1), X.at(row,index2) );
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::elem_type
+op_median::median_vec
+  (
+  const T1& X,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  typedef typename Proxy<T1>::stored_type P_stored_type;
+    
+  const Proxy<T1> P(X);
+  
+  const uword n_elem = P.get_n_elem();
+  
+  arma_debug_check( (n_elem == 0), "median(): given object has no elements" );
+  
+  std::vector<eT> tmp_vec(n_elem);
+  
+  if(is_Mat<P_stored_type>::value == true)
+    {
+    const unwrap<P_stored_type> tmp(P.Q);
+    
+    const typename unwrap_check<P_stored_type>::stored_type& Y = tmp.M;
+    
+    arrayops::copy( &(tmp_vec[0]), Y.memptr(), n_elem );
+    }
+  else
+    {
+    if(Proxy<T1>::prefer_at_accessor == false)
+      {
+      typedef typename Proxy<T1>::ea_type ea_type;
+      
+      ea_type A = P.get_ea();
+      
+      for(uword i=0; i<n_elem; ++i)  { tmp_vec[i] = A[i]; }
+      }
+    else
+      {
+      const uword n_rows = P.get_n_rows();
+      const uword n_cols = P.get_n_cols();
+      
+      if(n_cols == 1)
+        {
+        for(uword row=0; row < n_rows; ++row)  { tmp_vec[row] = P.at(row,0); }
+        }
+      else
+      if(n_rows == 1)
+        {
+        for(uword col=0; col < n_cols; ++col)  { tmp_vec[col] = P.at(0,col); }
+        }
+      else
+        {
+        arma_stop("op_median::median_vec(): expected a vector" );
+        }
+      }
+    }
+  
+  return op_median::direct_median(tmp_vec);
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::elem_type
+op_median::median_vec
+  (
+  const T1& X,
+  const typename arma_cx_only<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  typedef typename T1::pod_type   T;
+  
+  const Proxy<T1> P(X);
+  
+  const uword n_elem = P.get_n_elem();
+  
+  arma_debug_check( (n_elem == 0), "median(): given object has no elements" );
+  
+  std::vector< arma_cx_median_packet<T> > tmp_vec(n_elem);
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typedef typename Proxy<T1>::ea_type ea_type;
+    
+    ea_type A = P.get_ea();
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      tmp_vec[i].val   = std::abs( A[i] );
+      tmp_vec[i].index = i;
+      }
+    
+    uword index1;
+    uword index2;
+    op_median::direct_cx_median_index(index1, index2, tmp_vec);
+    
+    return op_mean::robust_mean( A[index1], A[index2] );
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    if(n_cols == 1)
+      {
+      for(uword row=0; row < n_rows; ++row)
+        {
+        tmp_vec[row].val   = std::abs( P.at(row,0) );
+        tmp_vec[row].index = row;
+        }
+      
+      uword index1;
+      uword index2;
+      op_median::direct_cx_median_index(index1, index2, tmp_vec);
+      
+      return op_mean::robust_mean( P.at(index1,0), P.at(index2,0) );
+      }
+    else
+    if(n_rows == 1)
+      {
+      for(uword col=0; col < n_cols; ++col)
+        {
+        tmp_vec[col].val   = std::abs( P.at(0,col) );
+        tmp_vec[col].index = col;
+        }
+      
+      uword index1;
+      uword index2;
+      op_median::direct_cx_median_index(index1, index2, tmp_vec);
+      
+      return op_mean::robust_mean( P.at(0,index1), P.at(0,index2) );
+      }
+    else
+      {
+      arma_stop("op_median::median_vec(): expected a vector" );
+      
+      return eT(0);
+      }
+    }
+  }
+
+
+
+//! find the median value of a std::vector (contents is modified)
+template<typename eT>
+inline 
+eT
+op_median::direct_median(std::vector<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword n_elem = uword(X.size());
+  const uword half   = n_elem/2;
+  
+  std::nth_element(X.begin(), X.begin() + half, X.end());
+  
+  if((n_elem % 2) == 0)
+    {
+    return op_mean::robust_mean(*(std::max_element(X.begin(), X.begin() + half)), X[half]);
+    }
+  else
+    {
+    return X[half];
+    }
+  }
+
+
+
+template<typename T>
+inline 
+void
+op_median::direct_cx_median_index
+  (
+  uword& out_index1, 
+  uword& out_index2, 
+  std::vector< arma_cx_median_packet<T> >& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword n_elem = uword(X.size());
+  const uword half   = n_elem/2;
+  
+  std::nth_element(X.begin(), X.begin() + half, X.end());
+  
+  if((n_elem % 2) == 0)
+    {
+    out_index1 = std::max_element(X.begin(), X.begin() + half)->index;
+    out_index2 = X[half].index;
+    }
+  else
+    {
+    out_index1 = X[half].index;
+    out_index2 = out_index1;
+    }
+  }
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_min_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,62 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_min
+//! @{
+
+
+//! Class for finding minimum values in a matrix
+class op_min
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_min>& in);
+  
+  
+  //
+  // for non-complex numbers
+  
+  template<typename eT>
+  inline static eT direct_min(const eT* const X, const uword N);
+  
+  template<typename eT>
+  inline static eT direct_min(const eT* const X, const uword N, uword& index_of_min_val);
+  
+  template<typename eT>
+  inline static eT direct_min(const Mat<eT>& X, const uword row);
+  
+  template<typename eT>
+  inline static eT min(const subview<eT>& X);
+  
+  template<typename T1>
+  inline static typename arma_not_cx<typename T1::elem_type>::result min(const Base<typename T1::elem_type, T1>& X);
+  
+  
+  //
+  // for complex numbers
+  
+  template<typename T>
+  inline static std::complex<T> direct_min(const std::complex<T>* const X, const uword n_elem);
+  
+  template<typename T>
+  inline static std::complex<T> direct_min(const std::complex<T>* const X, const uword n_elem, uword& index_of_min_val);
+  
+  template<typename T>
+  inline static std::complex<T> direct_min(const Mat< std::complex<T> >& X, const uword row);
+  
+  template<typename T>
+  inline static std::complex<T> min(const subview< std::complex<T> >&X);
+  
+  template<typename T1>
+  inline static typename arma_cx_only<typename T1::elem_type>::result min(const Base<typename T1::elem_type, T1>& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_min_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,559 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_min
+//! @{
+
+
+
+//! \brief
+//! For each row or for each column, find the minimum value.
+//! The result is stored in a dense matrix that has either one column or one row.
+//! The dimension, for which the minima are found, is set via the min() function.
+template<typename T1>
+inline void op_min::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_min>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> tmp(in.m, out);
+  const Mat<eT>&     X = tmp.M;
+  
+  const uword dim = in.aux_uword_a;
+  arma_debug_check( (dim > 1), "min(): incorrect usage. dim must be 0 or 1");
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  if(dim == 0)  // min in each column
+    {
+    arma_extra_debug_print("op_min::apply(), dim = 0");
+    
+    arma_debug_check( (X_n_rows == 0), "min(): given object has zero rows" );
+
+    out.set_size(1, X_n_cols);
+    
+    eT* out_mem = out.memptr();
+    
+    for(uword col=0; col<X_n_cols; ++col)
+      {
+      out_mem[col] = op_min::direct_min( X.colptr(col), X_n_rows );
+      }
+    }
+  else
+  if(dim == 1)  // min in each row
+    {
+    arma_extra_debug_print("op_min::apply(), dim = 1");
+    
+    arma_debug_check( (X_n_cols == 0), "min(): given object has zero columns" );
+
+    out.set_size(X_n_rows, 1);
+    
+    eT* out_mem = out.memptr();
+    
+    for(uword row=0; row<X_n_rows; ++row)
+      {
+      out_mem[row] = op_min::direct_min( X, row );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_pure
+inline 
+eT
+op_min::direct_min(const eT* const X, const uword n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT min_val = priv::most_pos<eT>();
+  
+  uword i,j;
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT X_i = X[i];
+    const eT X_j = X[j];
+    
+    if(X_i < min_val) { min_val = X_i; }
+    if(X_j < min_val) { min_val = X_j; }
+    }
+  
+  if(i < n_elem)
+    {
+    const eT X_i = X[i];
+    
+    if(X_i < min_val) { min_val = X_i; }
+    }
+  
+  return min_val;
+  }
+
+
+
+template<typename eT>
+inline 
+eT
+op_min::direct_min(const eT* const X, const uword n_elem, uword& index_of_min_val)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT min_val = priv::most_pos<eT>();
+  
+  uword best_index = 0;
+  
+  uword i,j;
+  for(i=0, j=1; j<n_elem; i+=2, j+=2)
+    {
+    const eT X_i = X[i];
+    const eT X_j = X[j];
+    
+    if(X_i < min_val)
+      {
+      min_val    = X_i;
+      best_index = i;
+      }
+    
+    if(X_j < min_val)
+      {
+      min_val    = X_j;
+      best_index = j;
+      }
+    }
+  
+  if(i < n_elem)
+    {
+    const eT X_i = X[i];
+    
+    if(X_i < min_val)
+      {
+      min_val    = X_i;
+      best_index = i;
+      }
+    }
+  
+  index_of_min_val = best_index;
+  
+  return min_val;
+  }  
+
+
+
+template<typename eT>
+inline 
+eT
+op_min::direct_min(const Mat<eT>& X, const uword row)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword X_n_cols = X.n_cols;
+  
+  eT min_val = priv::most_pos<eT>();
+  
+  uword i,j;
+  for(i=0, j=1; j < X_n_cols; i+=2, j+=2)
+    {
+    const eT tmp_i = X.at(row,i);
+    const eT tmp_j = X.at(row,j);
+    
+    if(tmp_i < min_val) { min_val = tmp_i; }
+    if(tmp_j < min_val) { min_val = tmp_j; }
+    }
+  
+  if(i < X_n_cols)
+    {
+    const eT tmp_i = X.at(row,i);
+    
+    if(tmp_i < min_val) { min_val = tmp_i; }
+    }
+  
+  return min_val;
+  }
+
+
+
+template<typename eT>
+inline
+eT
+op_min::min(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (X.n_elem == 0), "min(): given object has no elements" );
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  eT min_val = priv::most_pos<eT>();
+  
+  if(X_n_rows == 1)
+    {
+    const Mat<eT>& A = X.m;
+    
+    const uword start_row = X.aux_row1;
+    const uword start_col = X.aux_col1;
+    
+    const uword end_col_p1 = start_col + X_n_cols;
+  
+    uword i,j;
+    for(i=start_col, j=start_col+1; j < end_col_p1; i+=2, j+=2)
+      {
+      const eT tmp_i = A.at(start_row, i);
+      const eT tmp_j = A.at(start_row, j);
+      
+      if(tmp_i < min_val) { min_val = tmp_i; }
+      if(tmp_j < min_val) { min_val = tmp_j; }
+      }
+    
+    if(i < end_col_p1)
+      {
+      const eT tmp_i = A.at(start_row, i);
+      
+      if(tmp_i < min_val) { min_val = tmp_i; }
+      }
+    }
+  else
+    {
+    for(uword col=0; col < X_n_cols; ++col)
+      {
+      eT tmp_val = op_min::direct_min(X.colptr(col), X_n_rows);
+      
+      if(tmp_val < min_val) { min_val = tmp_val; }
+      }
+    }
+  
+  return min_val;
+  }
+
+
+
+template<typename T1>
+inline
+typename arma_not_cx<typename T1::elem_type>::result
+op_min::min(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(X.get_ref());
+  
+  const uword n_elem = P.get_n_elem();
+  
+  arma_debug_check( (n_elem == 0), "min(): given object has no elements" );
+  
+  eT min_val = priv::most_pos<eT>();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typedef typename Proxy<T1>::ea_type ea_type;
+    
+    ea_type A = P.get_ea();
+    
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      const eT tmp_i = A[i];
+      const eT tmp_j = A[j];
+      
+      if(tmp_i < min_val) { min_val = tmp_i; }
+      if(tmp_j < min_val) { min_val = tmp_j; }
+      }
+    
+    if(i < n_elem)
+      {
+      const eT tmp_i = A[i];
+      
+      if(tmp_i < min_val) { min_val = tmp_i; }
+      }
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    if(n_rows == 1)
+      {
+      uword i,j;
+      for(i=0, j=1; j < n_cols; i+=2, j+=2)
+        {
+        const eT tmp_i = P.at(0,i);
+        const eT tmp_j = P.at(0,j);
+        
+        if(tmp_i < min_val) { min_val = tmp_i; }
+        if(tmp_j < min_val) { min_val = tmp_j; }
+        }
+      
+      if(i < n_cols)
+        {
+        const eT tmp_i = P.at(0,i);
+        
+        if(tmp_i < min_val) { min_val = tmp_i; }
+        }
+      }
+    else
+      {
+      for(uword col=0; col < n_cols; ++col)
+        {
+        uword i,j;
+        for(i=0, j=1; j < n_rows; i+=2, j+=2)
+          {
+          const eT tmp_i = P.at(i,col);
+          const eT tmp_j = P.at(j,col);
+          
+          if(tmp_i < min_val) { min_val = tmp_i; }
+          if(tmp_j < min_val) { min_val = tmp_j; }
+          }
+          
+        if(i < n_rows)
+          {
+          const eT tmp_i = P.at(i,col);
+          
+          if(tmp_i < min_val) { min_val = tmp_i; }
+          }
+        }
+      }
+    }
+  
+  return min_val;
+  }
+
+
+
+template<typename T>
+inline 
+std::complex<T>
+op_min::direct_min(const std::complex<T>* const X, const uword n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  uword index   = 0;
+  T     min_val = priv::most_pos<T>();
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    const T tmp_val = std::abs(X[i]);
+    
+    if(tmp_val < min_val)
+      {
+      min_val = tmp_val;
+      index   = i;
+      }
+    }
+  
+  return X[index];
+  }
+
+
+
+template<typename T>
+inline 
+std::complex<T>
+op_min::direct_min(const std::complex<T>* const X, const uword n_elem, uword& index_of_min_val)
+  {
+  arma_extra_debug_sigprint();
+  
+  uword index   = 0;
+  T     min_val = priv::most_pos<T>();
+  
+  for(uword i=0; i<n_elem; ++i)
+    {
+    const T tmp_val = std::abs(X[i]);
+    
+    if(tmp_val < min_val)
+      {
+      min_val = tmp_val;
+      index   = i;
+      }
+    }
+  
+  index_of_min_val = index;
+  
+  return X[index];
+  }
+
+
+
+template<typename T>
+inline 
+std::complex<T>
+op_min::direct_min(const Mat< std::complex<T> >& X, const uword row)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword X_n_cols = X.n_cols;
+  
+  uword index   = 0;
+  T   min_val = priv::most_pos<T>();
+  
+  for(uword col=0; col<X_n_cols; ++col)
+    {
+    const T tmp_val = std::abs(X.at(row,col));
+    
+    if(tmp_val < min_val)
+      {
+      min_val = tmp_val;
+      index   = col;
+      }
+    }
+  
+  return X.at(row,index);
+  }
+
+
+
+template<typename T>
+inline
+std::complex<T>
+op_min::min(const subview< std::complex<T> >& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (X.n_elem == 0), "min(): given object has no elements" );
+  
+  const Mat< std::complex<T> >& A = X.m;
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  const uword start_row = X.aux_row1;
+  const uword start_col = X.aux_col1;
+  
+  const uword end_row_p1 = start_row + X_n_rows;
+  const uword end_col_p1 = start_col + X_n_cols;
+  
+  T min_val = priv::most_pos<T>();
+  
+  uword best_row = 0;
+  uword best_col = 0;
+    
+  if(X_n_rows == 1)
+    {
+    best_col = 0;
+    
+    for(uword col=start_col; col < end_col_p1; ++col)
+      {
+      const T tmp_val = std::abs( A.at(start_row, col) );
+      
+      if(tmp_val < min_val)
+        {
+        min_val  = tmp_val;
+        best_col = col;
+        }
+      }
+    
+    best_row = start_row;
+    }
+  else
+    {
+    for(uword col=start_col; col < end_col_p1; ++col)
+    for(uword row=start_row; row < end_row_p1; ++row)
+      {
+      const T tmp_val = std::abs( A.at(row, col) );
+      
+      if(tmp_val < min_val)
+        {
+        min_val  = tmp_val;
+        best_row = row;
+        best_col = col;
+        }
+      }
+    }
+  
+  return A.at(best_row, best_col);
+  }
+
+
+
+template<typename T1>
+inline
+typename arma_cx_only<typename T1::elem_type>::result
+op_min::min(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type            eT;
+  typedef typename get_pod_type<eT>::result T;
+  
+  const Proxy<T1> P(X.get_ref());
+  
+  const uword n_elem = P.get_n_elem();
+  
+  arma_debug_check( (n_elem == 0), "min(): given object has no elements" );
+  
+  T min_val = priv::most_pos<T>();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typedef typename Proxy<T1>::ea_type ea_type;
+    
+    ea_type A = P.get_ea();
+    
+    uword index = 0;
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      const T tmp = std::abs(A[i]);
+      
+      if(tmp < min_val)
+        {
+        min_val = tmp;
+        index   = i;
+        }
+      }
+    
+    return( A[index] );
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    uword best_row = 0;
+    uword best_col = 0;
+    
+    if(n_rows == 1)
+      {
+      for(uword col=0; col < n_cols; ++col)
+        {
+        const T tmp = std::abs(P.at(0,col));
+        
+        if(tmp < min_val)
+          {
+          min_val  = tmp;
+          best_col = col;
+          }
+        }
+      }
+    else
+      {
+      for(uword col=0; col < n_cols; ++col)
+      for(uword row=0; row < n_rows; ++row)
+        {
+        const T tmp = std::abs(P.at(row,col));
+        
+        if(tmp < min_val)
+          {
+          min_val = tmp;
+          
+          best_row = row;
+          best_col = col;
+          }
+        }
+      }
+    
+    return P.at(best_row, best_col);
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_misc_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,63 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_misc
+//! @{
+
+
+
+class op_real
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply( Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_real>& X);
+  
+  template<typename T1>
+  inline static void apply( Cube<typename T1::pod_type>& out, const mtOpCube<typename T1::pod_type, T1, op_real>& X);
+  };
+
+
+
+class op_imag
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply( Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_imag>& X);
+  
+  template<typename T1>
+  inline static void apply( Cube<typename T1::pod_type>& out, const mtOpCube<typename T1::pod_type, T1, op_imag>& X);
+  };
+
+
+
+class op_abs
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply( Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_abs>& X);
+  
+  template<typename T1>
+  inline static void apply( Cube<typename T1::pod_type>& out, const mtOpCube<typename T1::pod_type, T1, op_abs>& X);
+  };
+
+
+
+class op_sympd
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply( Mat<typename T1::elem_type>& out, const Op<T1, op_sympd>& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_misc_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,290 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_misc
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+op_real::apply( Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_real>& X )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::pod_type T;
+  
+  const Proxy<T1> P(X.m);
+  
+  const uword n_rows = P.get_n_rows();
+  const uword n_cols = P.get_n_cols();
+    
+  out.set_size(n_rows, n_cols);
+  
+  T* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typedef typename Proxy<T1>::ea_type ea_type;
+    
+    const uword   n_elem  = P.get_n_elem();
+          ea_type A       = P.get_ea();
+    
+    for(uword i=0; i < n_elem; ++i)
+      {
+      out_mem[i] = std::real( A[i] );
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      *out_mem = std::real( P.at(row,col) );
+      out_mem++;
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_real::apply( Cube<typename T1::pod_type>& out, const mtOpCube<typename T1::pod_type, T1, op_real>& X )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::pod_type T;
+  
+  const ProxyCube<T1> P(X.m);
+  
+  const uword n_rows   = P.get_n_rows();
+  const uword n_cols   = P.get_n_cols();
+  const uword n_slices = P.get_n_slices();
+    
+  out.set_size(n_rows, n_cols, n_slices);
+  
+  T* out_mem = out.memptr();
+
+  if(ProxyCube<T1>::prefer_at_accessor == false)
+    {
+    typedef typename ProxyCube<T1>::ea_type ea_type;
+    
+    const uword   n_elem  = P.get_n_elem();
+          ea_type A       = P.get_ea();
+    
+    for(uword i=0; i < n_elem; ++i)
+      {
+      out_mem[i] = std::real( A[i] );
+      }
+    }
+  else
+    {
+    for(uword slice=0; slice < n_slices; ++slice)
+    for(uword col=0;   col   < n_cols;   ++col  )
+    for(uword row=0;   row   < n_rows;   ++row  )
+      {
+      *out_mem = std::real( P.at(row,col,slice) );
+      out_mem++;
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_imag::apply( Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_imag>& X )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::pod_type T;
+  
+  const Proxy<T1> P(X.m);
+  
+  const uword n_rows = P.get_n_rows();
+  const uword n_cols = P.get_n_cols();
+    
+  out.set_size(n_rows, n_cols);
+  
+  T* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typedef typename Proxy<T1>::ea_type ea_type;
+    
+    const uword   n_elem  = P.get_n_elem();
+          ea_type A       = P.get_ea();
+    
+    for(uword i=0; i < n_elem; ++i)
+      {
+      out_mem[i] = std::imag( A[i] );
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      *out_mem = std::imag( P.at(row,col) );
+      out_mem++;
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_imag::apply( Cube<typename T1::pod_type>& out, const mtOpCube<typename T1::pod_type, T1, op_imag>& X )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::pod_type T;
+  
+  const ProxyCube<T1> P(X.m);
+  
+  const uword n_rows   = P.get_n_rows();
+  const uword n_cols   = P.get_n_cols();
+  const uword n_slices = P.get_n_slices();
+    
+  out.set_size(n_rows, n_cols, n_slices);
+  
+  T* out_mem = out.memptr();
+
+  if(ProxyCube<T1>::prefer_at_accessor == false)
+    {
+    typedef typename ProxyCube<T1>::ea_type ea_type;
+    
+    const uword   n_elem  = P.get_n_elem();
+          ea_type A       = P.get_ea();
+    
+    for(uword i=0; i < n_elem; ++i)
+      {
+      out_mem[i] = std::imag( A[i] );
+      }
+    }
+  else
+    {
+    for(uword slice=0; slice < n_slices; ++slice)
+    for(uword col=0;   col   < n_cols;   ++col  )
+    for(uword row=0;   row   < n_rows;   ++row  )
+      {
+      *out_mem = std::imag( P.at(row,col,slice) );
+      out_mem++;
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_abs::apply( Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_abs>& X )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::pod_type T;
+  
+  const Proxy<T1> P(X.m);
+  
+  const uword n_rows = P.get_n_rows();
+  const uword n_cols = P.get_n_cols();
+    
+  out.set_size(n_rows, n_cols);
+  
+  T* out_mem = out.memptr();
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typedef typename Proxy<T1>::ea_type ea_type;
+    
+    const uword   n_elem  = P.get_n_elem();
+          ea_type A       = P.get_ea();
+    
+    for(uword i=0; i < n_elem; ++i)
+      {
+      out_mem[i] = std::abs( A[i] );
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+    for(uword row=0; row < n_rows; ++row)
+      {
+      *out_mem = std::abs( P.at(row,col) );
+      out_mem++;
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_abs::apply( Cube<typename T1::pod_type>& out, const mtOpCube<typename T1::pod_type, T1, op_abs>& X )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::pod_type T;
+  
+  const ProxyCube<T1> P(X.m);
+  
+  const uword n_rows   = P.get_n_rows();
+  const uword n_cols   = P.get_n_cols();
+  const uword n_slices = P.get_n_slices();
+    
+  out.set_size(n_rows, n_cols, n_slices);
+  
+  T* out_mem = out.memptr();
+
+  if(ProxyCube<T1>::prefer_at_accessor == false)
+    {
+    typedef typename ProxyCube<T1>::ea_type ea_type;
+    
+    const uword   n_elem  = P.get_n_elem();
+          ea_type A       = P.get_ea();
+    
+    for(uword i=0; i < n_elem; ++i)
+      {
+      out_mem[i] = std::abs( A[i] );
+      }
+    }
+  else
+    {
+    for(uword slice=0; slice < n_slices; ++slice)
+    for(uword col=0;   col   < n_cols;   ++col  )
+    for(uword row=0;   row   < n_rows;   ++row  )
+      {
+      *out_mem = std::abs( P.at(row,col,slice) );
+      out_mem++;
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_sympd::apply( Mat<typename T1::elem_type>& out, const Op<T1, op_sympd>& X )
+  {
+  arma_extra_debug_sigprint();
+  
+  out = X.m;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_pinv_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,27 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_pinv
+//! @{
+
+
+
+class op_pinv
+  {
+  public:
+  
+  template<typename eT> inline static void direct_pinv(Mat<eT>& out, const Mat<eT>& A, const eT in_tol);
+  
+  template<typename T1> inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_pinv>& in);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_pinv_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,123 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// Copyright (C) 2011 Stanislav Funiak
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_pinv
+//! @{
+
+
+
+template<typename eT>
+inline
+void
+op_pinv::direct_pinv(Mat<eT>& out, const Mat<eT>& A, const eT in_tol)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  T tol = access::tmp_real(in_tol);
+  
+  arma_debug_check((tol < T(0)), "pinv(): tolerance must be >= 0");
+  
+  const uword n_rows = A.n_rows;
+  const uword n_cols = A.n_cols;
+  
+  // economical SVD decomposition 
+  Mat<eT> U;
+  Col< T> s;
+  Mat<eT> V;
+  
+  const bool status = (n_cols > n_rows) ? auxlib::svd_econ(U,s,V,trans(A),'b') : auxlib::svd_econ(U,s,V,A,'b');
+  
+  if(status == false)
+    {
+    out.reset();
+    arma_bad("pinv(): svd failed");
+    return;
+    }
+  
+  const uword s_n_elem = s.n_elem;
+  const T*    s_mem    = s.memptr();
+  
+  // set tolerance to default if it hasn't been specified as an argument 
+  if( (tol == T(0)) && (s_n_elem > 0) )
+    {
+    tol = (std::max)(n_rows, n_cols) * eop_aux::direct_eps( op_max::direct_max(s_mem, s_n_elem) );
+    }
+  
+  
+  // count non zero valued elements in s
+  
+  uword count = 0;
+  
+  for(uword i = 0; i < s_n_elem; ++i)
+    {
+    if(s_mem[i] > tol)
+      {
+      ++count;
+      }
+    }
+  
+  if(count != 0)
+    {
+    Col<T> s2(count);
+    
+    T* s2_mem = s2.memptr();
+    
+    uword count2 = 0;
+    
+    for(uword i=0; i < s_n_elem; ++i)
+      {
+      const T val = s_mem[i];
+      
+      if(val > tol)
+        {
+        s2_mem[count2] = T(1) / val;
+        ++count2;
+        }
+      }
+    
+    
+    if(n_rows >= n_cols)
+      {
+      out = ( V.n_cols > count ? V.cols(0,count-1) : V ) * diagmat(s2) * trans( U.n_cols > count ? U.cols(0,count-1) : U );
+      }
+    else
+      {
+      out = ( U.n_cols > count ? U.cols(0,count-1) : U ) * diagmat(s2) * trans( V.n_cols > count ? V.cols(0,count-1) : V );
+      }
+    }
+  else
+    {
+    out.zeros(n_cols, n_rows);
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_pinv::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_pinv>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   tmp(in.m);
+  const Mat<eT>& A = tmp.M;
+  
+  op_pinv::direct_pinv(out, A, in.aux);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_princomp_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,119 @@
+// Copyright (C) 2010-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2012 Conrad Sanderson
+// Copyright (C) 2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_princomp
+//! @{
+
+
+
+class op_princomp
+  {
+  public:
+  
+  //
+  // real element versions
+  
+  template<typename T1>
+  inline static bool
+  direct_princomp
+    (
+           Mat<typename T1::elem_type>&     coeff_out,
+    const Base<typename T1::elem_type, T1>& X,
+    const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
+    );
+  
+  template<typename T1>
+  inline static bool
+  direct_princomp
+    (
+           Mat<typename T1::elem_type>&     coeff_out,
+           Mat<typename T1::elem_type>&     score_out,
+    const Base<typename T1::elem_type, T1>& X,
+    const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
+    );
+  
+  template<typename T1>
+  inline static bool
+  direct_princomp
+    (
+           Mat<typename T1::elem_type>&     coeff_out,
+           Mat<typename T1::elem_type>&     score_out,
+           Col<typename T1::elem_type>&     latent_out,
+    const Base<typename T1::elem_type, T1>& X,
+    const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
+    );
+  
+  template<typename T1>
+  inline static bool
+  direct_princomp
+    (
+           Mat<typename T1::elem_type>&     coeff_out,
+           Mat<typename T1::elem_type>&     score_out,
+           Col<typename T1::elem_type>&     latent_out,
+           Col<typename T1::elem_type>&     tsquared_out,
+    const Base<typename T1::elem_type, T1>& X,
+    const typename arma_not_cx<typename T1::elem_type>::result* junk = 0
+    );
+  
+  
+  //
+  // complex element versions
+  
+  template<typename T1>
+  inline static bool
+  direct_princomp
+    (
+           Mat< std::complex<typename T1::pod_type> >&     coeff_out,
+    const Base< std::complex<typename T1::pod_type>, T1 >& X,
+    const typename arma_cx_only<typename T1::elem_type>::result* junk = 0
+    );
+  
+  template<typename T1>
+  inline static bool
+  direct_princomp
+    (
+           Mat< std::complex<typename T1::pod_type> >&     coeff_out,
+           Mat< std::complex<typename T1::pod_type> >&     score_out,
+    const Base< std::complex<typename T1::pod_type>, T1 >& X,
+    const typename arma_cx_only<typename T1::elem_type>::result* junk = 0
+    );
+  
+  template<typename T1>
+  inline static bool
+  direct_princomp
+    (
+           Mat< std::complex<typename T1::pod_type> >&     coeff_out,
+           Mat< std::complex<typename T1::pod_type> >&     score_out,
+           Col<              typename T1::pod_type  >&     latent_out,
+    const Base< std::complex<typename T1::pod_type>, T1 >& X,
+    const typename arma_cx_only<typename T1::elem_type>::result* junk = 0
+    );
+  
+  template<typename T1>
+  inline static bool
+  direct_princomp
+    (
+           Mat< std::complex<typename T1::pod_type> >&     coeff_out,
+           Mat< std::complex<typename T1::pod_type> >&     score_out,
+           Col<              typename T1::pod_type  >&     latent_out,
+           Col< std::complex<typename T1::pod_type> >&     tsquared_out,
+    const Base< std::complex<typename T1::pod_type>, T1 >& X,
+    const typename arma_cx_only<typename T1::elem_type>::result* junk = 0
+    );
+  
+  
+  template<typename T1>
+  inline static void
+  apply(Mat<typename T1::elem_type>& out, const Op<T1,op_princomp>& in);
+  
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_princomp_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,651 @@
+// Copyright (C) 2010-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2012 Conrad Sanderson
+// Copyright (C) 2010 Dimitrios Bouzas
+// Copyright (C) 2011 Stanislav Funiak
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_princomp
+//! @{
+
+
+
+//! \brief
+//! principal component analysis -- 4 arguments version
+//! computation is done via singular value decomposition
+//! coeff_out    -> principal component coefficients
+//! score_out    -> projected samples
+//! latent_out   -> eigenvalues of principal vectors
+//! tsquared_out -> Hotelling's T^2 statistic
+template<typename T1>
+inline
+bool
+op_princomp::direct_princomp
+  (
+         Mat<typename T1::elem_type>&     coeff_out,
+         Mat<typename T1::elem_type>&     score_out,
+         Col<typename T1::elem_type>&     latent_out,
+         Col<typename T1::elem_type>&     tsquared_out,
+  const Base<typename T1::elem_type, T1>& X,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> Y( X.get_ref(), score_out );
+  const Mat<eT>& in    = Y.M;
+
+  const uword n_rows = in.n_rows;
+  const uword n_cols = in.n_cols;
+  
+  if(n_rows > 1) // more than one sample
+    {
+    // subtract the mean - use score_out as temporary matrix
+    score_out = in - repmat(mean(in), n_rows, 1);
+ 	  
+    // singular value decomposition
+    Mat<eT> U;
+    Col<eT> s;
+    
+    const bool svd_ok = svd(U,s,coeff_out,score_out);
+    
+    if(svd_ok == false)
+      {
+      return false;
+      }
+    
+    
+    //U.reset();  // TODO: do we need this ?  U will get automatically deleted anyway
+    
+    // normalize the eigenvalues
+    s /= std::sqrt( double(n_rows - 1) );
+    
+    // project the samples to the principals
+    score_out *= coeff_out;
+    
+    if(n_rows <= n_cols) // number of samples is less than their dimensionality
+      {
+      score_out.cols(n_rows-1,n_cols-1).zeros();
+      
+      //Col<eT> s_tmp = zeros< Col<eT> >(n_cols);
+      Col<eT> s_tmp(n_cols);
+      s_tmp.zeros();
+      
+      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
+      s = s_tmp;
+          
+      // compute the Hotelling's T-squared
+      s_tmp.rows(0,n_rows-2) = eT(1) / s_tmp.rows(0,n_rows-2);
+      
+      const Mat<eT> S = score_out * diagmat(Col<eT>(s_tmp));   
+      tsquared_out = sum(S%S,1); 
+      }
+    else
+      {
+      // compute the Hotelling's T-squared   
+      const Mat<eT> S = score_out * diagmat(Col<eT>( eT(1) / s));
+      tsquared_out = sum(S%S,1);
+      }
+            
+    // compute the eigenvalues of the principal vectors
+    latent_out = s%s;
+    }
+  else // 0 or 1 samples
+    {
+    coeff_out.eye(n_cols, n_cols);
+    
+    score_out.copy_size(in);
+    score_out.zeros();
+    
+    latent_out.set_size(n_cols);
+    latent_out.zeros();
+    
+    tsquared_out.set_size(n_rows);
+    tsquared_out.zeros();
+    }
+  
+  return true;
+  }
+
+
+
+//! \brief
+//! principal component analysis -- 3 arguments version
+//! computation is done via singular value decomposition
+//! coeff_out    -> principal component coefficients
+//! score_out    -> projected samples
+//! latent_out   -> eigenvalues of principal vectors
+template<typename T1>
+inline
+bool
+op_princomp::direct_princomp
+  (
+         Mat<typename T1::elem_type>&     coeff_out,
+         Mat<typename T1::elem_type>&     score_out,
+         Col<typename T1::elem_type>&     latent_out,
+  const Base<typename T1::elem_type, T1>& X,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> Y( X.get_ref(), score_out );
+  const Mat<eT>& in    = Y.M;
+  
+  const uword n_rows = in.n_rows;
+  const uword n_cols = in.n_cols;
+  
+  if(n_rows > 1) // more than one sample
+    {
+    // subtract the mean - use score_out as temporary matrix
+    score_out = in - repmat(mean(in), n_rows, 1);
+ 	  
+    // singular value decomposition
+    Mat<eT> U;
+    Col<eT> s;
+    
+    const bool svd_ok = svd(U,s,coeff_out,score_out);
+    
+    if(svd_ok == false)
+      {
+      return false;
+      }
+    
+    
+    // U.reset();
+    
+    // normalize the eigenvalues
+    s /= std::sqrt( double(n_rows - 1) );
+    
+    // project the samples to the principals
+    score_out *= coeff_out;
+    
+    if(n_rows <= n_cols) // number of samples is less than their dimensionality
+      {
+      score_out.cols(n_rows-1,n_cols-1).zeros();
+      
+      Col<eT> s_tmp = zeros< Col<eT> >(n_cols);
+      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
+      s = s_tmp;
+      }
+      
+    // compute the eigenvalues of the principal vectors
+    latent_out = s%s;
+    
+    }
+  else // 0 or 1 samples
+    {
+    coeff_out.eye(n_cols, n_cols);
+    
+    score_out.copy_size(in);
+    score_out.zeros();
+    
+    latent_out.set_size(n_cols);
+    latent_out.zeros(); 
+    }
+  
+  return true;
+  }
+
+
+
+//! \brief
+//! principal component analysis -- 2 arguments version
+//! computation is done via singular value decomposition
+//! coeff_out    -> principal component coefficients
+//! score_out    -> projected samples
+template<typename T1>
+inline
+bool
+op_princomp::direct_princomp
+  (
+         Mat<typename T1::elem_type>&     coeff_out,
+         Mat<typename T1::elem_type>&     score_out,
+  const Base<typename T1::elem_type, T1>& X,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> Y( X.get_ref(), score_out );
+  const Mat<eT>& in    = Y.M;
+  
+  const uword n_rows = in.n_rows;
+  const uword n_cols = in.n_cols;
+  
+  if(n_rows > 1) // more than one sample
+    {
+    // subtract the mean - use score_out as temporary matrix
+    score_out = in - repmat(mean(in), n_rows, 1);
+ 	  
+    // singular value decomposition
+    Mat<eT> U;
+    Col<eT> s;
+    
+    const bool svd_ok = svd(U,s,coeff_out,score_out);
+    
+    if(svd_ok == false)
+      {
+      return false;
+      }
+    
+    // U.reset();
+    
+    // normalize the eigenvalues
+    s /= std::sqrt( double(n_rows - 1) );
+    
+    // project the samples to the principals
+    score_out *= coeff_out;
+    
+    if(n_rows <= n_cols) // number of samples is less than their dimensionality
+      {
+      score_out.cols(n_rows-1,n_cols-1).zeros();
+      
+      Col<eT> s_tmp = zeros< Col<eT> >(n_cols);
+      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
+      s = s_tmp;
+      }
+    }
+  else // 0 or 1 samples
+    {
+    coeff_out.eye(n_cols, n_cols);
+    score_out.copy_size(in);
+    score_out.zeros();
+    }
+  
+  return true;
+  }
+
+
+
+//! \brief
+//! principal component analysis -- 1 argument version
+//! computation is done via singular value decomposition
+//! coeff_out    -> principal component coefficients
+template<typename T1>
+inline
+bool
+op_princomp::direct_princomp
+  (
+         Mat<typename T1::elem_type>&     coeff_out,
+  const Base<typename T1::elem_type, T1>& X,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>    Y( X.get_ref() );
+  const Mat<eT>& in = Y.M;
+  
+  if(in.n_elem != 0)
+    {
+    // singular value decomposition
+    Mat<eT> U;
+    Col<eT> s;
+    
+    const Mat<eT> tmp = in - repmat(mean(in), in.n_rows, 1);
+    
+    const bool svd_ok = svd(U,s,coeff_out, tmp);
+    
+    if(svd_ok == false)
+      {
+      return false;
+      }
+    }
+  else
+    {
+    coeff_out.eye(in.n_cols, in.n_cols);
+    }
+  
+  return true;
+  }
+
+
+
+//! \brief
+//! principal component analysis -- 4 arguments complex version
+//! computation is done via singular value decomposition
+//! coeff_out    -> principal component coefficients
+//! score_out    -> projected samples
+//! latent_out   -> eigenvalues of principal vectors
+//! tsquared_out -> Hotelling's T^2 statistic
+template<typename T1>
+inline
+bool
+op_princomp::direct_princomp
+  (
+         Mat< std::complex<typename T1::pod_type> >&     coeff_out,
+         Mat< std::complex<typename T1::pod_type> >&     score_out,
+         Col<              typename T1::pod_type  >&     latent_out,
+         Col< std::complex<typename T1::pod_type> >&     tsquared_out,
+  const Base< std::complex<typename T1::pod_type>, T1 >& X,
+  const typename arma_cx_only<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::pod_type     T;
+  typedef          std::complex<T> eT;
+  
+  const unwrap_check<T1> Y( X.get_ref(), score_out );
+  const Mat<eT>& in    = Y.M;
+  
+  const uword n_rows = in.n_rows;
+  const uword n_cols = in.n_cols;
+  
+  if(n_rows > 1) // more than one sample
+    {
+    // subtract the mean - use score_out as temporary matrix
+    score_out = in - repmat(mean(in), n_rows, 1);
+ 	  
+    // singular value decomposition
+    Mat<eT> U;
+    Col<T> s;
+    
+    const bool svd_ok = svd(U,s,coeff_out,score_out); 
+    
+    if(svd_ok == false)
+      {
+      return false;
+      }
+    
+    
+    //U.reset();
+    
+    // normalize the eigenvalues
+    s /= std::sqrt( double(n_rows - 1) );
+    
+    // project the samples to the principals
+    score_out *= coeff_out;
+    
+    if(n_rows <= n_cols) // number of samples is less than their dimensionality
+      {
+      score_out.cols(n_rows-1,n_cols-1).zeros();
+      
+      Col<T> s_tmp = zeros< Col<T> >(n_cols);
+      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
+      s = s_tmp;
+          
+      // compute the Hotelling's T-squared   
+      s_tmp.rows(0,n_rows-2) = 1.0 / s_tmp.rows(0,n_rows-2);
+      const Mat<eT> S = score_out * diagmat(Col<T>(s_tmp));                     
+      tsquared_out = sum(S%S,1); 
+      }
+    else
+      {
+      // compute the Hotelling's T-squared   
+      const Mat<eT> S = score_out * diagmat(Col<T>(T(1) / s));                     
+      tsquared_out = sum(S%S,1);
+      }
+    
+    // compute the eigenvalues of the principal vectors
+    latent_out = s%s;
+    
+    }
+  else // 0 or 1 samples
+    {
+    coeff_out.eye(n_cols, n_cols);
+    
+    score_out.copy_size(in);
+    score_out.zeros();
+      
+    latent_out.set_size(n_cols);
+    latent_out.zeros();
+      
+    tsquared_out.set_size(n_rows);
+    tsquared_out.zeros();
+    }
+  
+  return true;
+  }
+
+
+
+//! \brief
+//! principal component analysis -- 3 arguments complex version
+//! computation is done via singular value decomposition
+//! coeff_out    -> principal component coefficients
+//! score_out    -> projected samples
+//! latent_out   -> eigenvalues of principal vectors
+template<typename T1>
+inline
+bool
+op_princomp::direct_princomp
+  (
+         Mat< std::complex<typename T1::pod_type> >&     coeff_out,
+         Mat< std::complex<typename T1::pod_type> >&     score_out,
+         Col<              typename T1::pod_type  >&     latent_out,
+  const Base< std::complex<typename T1::pod_type>, T1 >& X,
+  const typename arma_cx_only<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::pod_type     T;
+  typedef          std::complex<T> eT;
+  
+  const unwrap_check<T1> Y( X.get_ref(), score_out );
+  const Mat<eT>& in    = Y.M;
+  
+  const uword n_rows = in.n_rows;
+  const uword n_cols = in.n_cols;
+  
+  if(n_rows > 1) // more than one sample
+    {
+    // subtract the mean - use score_out as temporary matrix
+    score_out = in - repmat(mean(in), n_rows, 1);
+ 	  
+    // singular value decomposition
+    Mat<eT> U;
+    Col< T> s;
+    
+    const bool svd_ok = svd(U,s,coeff_out,score_out);
+    
+    if(svd_ok == false)
+      {
+      return false;
+      }
+    
+    
+    // U.reset();
+    
+    // normalize the eigenvalues
+    s /= std::sqrt( double(n_rows - 1) );
+    
+    // project the samples to the principals
+    score_out *= coeff_out;
+    
+    if(n_rows <= n_cols) // number of samples is less than their dimensionality
+      {
+      score_out.cols(n_rows-1,n_cols-1).zeros();
+      
+      Col<T> s_tmp = zeros< Col<T> >(n_cols);
+      s_tmp.rows(0,n_rows-2) = s.rows(0,n_rows-2);
+      s = s_tmp;
+      }
+      
+    // compute the eigenvalues of the principal vectors
+    latent_out = s%s;
+
+    }
+  else // 0 or 1 samples
+    {
+    coeff_out.eye(n_cols, n_cols);
+
+    score_out.copy_size(in);
+    score_out.zeros();
+
+    latent_out.set_size(n_cols);
+    latent_out.zeros();
+    }
+  
+  return true;
+  }
+
+
+
+//! \brief
+//! principal component analysis -- 2 arguments complex version
+//! computation is done via singular value decomposition
+//! coeff_out    -> principal component coefficients
+//! score_out    -> projected samples
+template<typename T1>
+inline
+bool
+op_princomp::direct_princomp
+  (
+         Mat< std::complex<typename T1::pod_type> >&     coeff_out,
+         Mat< std::complex<typename T1::pod_type> >&     score_out,
+  const Base< std::complex<typename T1::pod_type>, T1 >& X,
+  const typename arma_cx_only<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::pod_type     T;
+  typedef          std::complex<T> eT;
+  
+  const unwrap_check<T1> Y( X.get_ref(), score_out );
+  const Mat<eT>& in    = Y.M;
+  
+  const uword n_rows = in.n_rows;
+  const uword n_cols = in.n_cols;
+  
+  if(n_rows > 1) // more than one sample
+    {
+    // subtract the mean - use score_out as temporary matrix
+    score_out = in - repmat(mean(in), n_rows, 1);
+ 	  
+    // singular value decomposition
+    Mat<eT> U;
+    Col< T> s;
+    
+    const bool svd_ok = svd(U,s,coeff_out,score_out);
+    
+    if(svd_ok == false)
+      {
+      return false;
+      }
+    
+    // U.reset();
+    
+    // normalize the eigenvalues
+    s /= std::sqrt( double(n_rows - 1) );
+
+    // project the samples to the principals
+    score_out *= coeff_out;
+
+    if(n_rows <= n_cols) // number of samples is less than their dimensionality
+      {
+      score_out.cols(n_rows-1,n_cols-1).zeros();
+      }
+
+    }
+  else // 0 or 1 samples
+    {
+    coeff_out.eye(n_cols, n_cols);
+    
+    score_out.copy_size(in);
+    score_out.zeros();
+    }
+  
+  return true;
+  }
+
+
+
+//! \brief
+//! principal component analysis -- 1 argument complex version
+//! computation is done via singular value decomposition
+//! coeff_out    -> principal component coefficients
+template<typename T1>
+inline
+bool
+op_princomp::direct_princomp
+  (
+         Mat< std::complex<typename T1::pod_type> >&     coeff_out,
+  const Base< std::complex<typename T1::pod_type>, T1 >& X,
+  const typename arma_cx_only<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::pod_type     T;
+  typedef          std::complex<T> eT;
+  
+  const unwrap<T1>    Y( X.get_ref() );
+  const Mat<eT>& in = Y.M;
+  
+  if(in.n_elem != 0)
+    {
+ 	  // singular value decomposition
+ 	  Mat<eT> U;
+    Col< T> s;
+    
+    const Mat<eT> tmp = in - repmat(mean(in), in.n_rows, 1);
+    
+    const bool svd_ok = svd(U,s,coeff_out, tmp);
+    
+    if(svd_ok == false)
+      {
+      return false;
+      }
+    }
+  else
+    {
+    coeff_out.eye(in.n_cols, in.n_cols);
+    }
+  
+  return true;
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_princomp::apply
+  (
+        Mat<typename T1::elem_type>& out,
+  const Op<T1,op_princomp>&          in
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> tmp(in.m, out);
+  const Mat<eT>& A     = tmp.M;
+  
+  const bool status = op_princomp::direct_princomp(out, A);
+  
+  if(status == false)
+    {
+    out.reset();
+    
+    arma_bad("princomp(): failed to converge");
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_prod_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,28 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_prod
+//! @{
+
+//! Class for finding products of values in a matrix  (e.g. along rows or columns)
+class op_prod
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1, op_prod>& in);
+  
+  template<typename eT>
+  inline static eT prod(const subview<eT>& S);
+  
+  template<typename T1>
+  inline static typename T1::elem_type prod(const Base<typename T1::elem_type,T1>& X);
+  };
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_prod_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,196 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_prod
+//! @{
+
+//! \brief
+//! Immediate product of elements of a matrix along a specified dimension (either rows or columns).
+//! The result is stored in a dense matrix that has either one column or one row.
+//! See the prod() function for more details.
+template<typename T1>
+inline
+void
+op_prod::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_prod>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword dim = in.aux_uword_a;
+  arma_debug_check( (dim > 1), "prod(): incorrect usage. dim must be 0 or 1");
+  
+  const unwrap_check<T1> tmp(in.m, out);
+  const Mat<eT>& X     = tmp.M;
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+    
+  if(dim == 0)  // traverse across rows (i.e. find the product in each column)
+    {
+    out.set_size(1, X_n_cols);
+    
+    eT* out_mem = out.memptr();
+    
+    for(uword col=0; col<X_n_cols; ++col)
+      {
+      out_mem[col] = arrayops::product(X.colptr(col), X_n_rows);
+      }
+    }
+  else  // traverse across columns (i.e. find the product in each row)
+    {
+    out.set_size(X_n_rows, 1);
+    
+    eT* out_mem = out.memptr();
+    
+    for(uword row=0; row<X_n_rows; ++row)
+      {
+      eT val = eT(1);
+      
+      uword i,j;
+      for(i=0, j=1; j < X_n_cols; i+=2, j+=2)
+        {
+        val *= X.at(row,i);
+        val *= X.at(row,j);
+        }
+      
+      if(i < X_n_cols)
+        {
+        val *= X.at(row,i);
+        }
+      
+      out_mem[row] = val;
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+eT
+op_prod::prod(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  eT val = eT(1);
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  if(X_n_rows == 1)
+    {
+    const Mat<eT>& A = X.m;
+  
+    const uword start_row = X.aux_row1;
+    const uword start_col = X.aux_col1;
+    
+    const uword end_col_p1 = start_col + X_n_cols;
+    
+    uword i,j;
+    for(i=start_col, j=start_col+1; j < end_col_p1; i+=2, j+=2)
+      {
+      val *= A.at(start_row, i);
+      val *= A.at(start_row, j);
+      }
+    
+    if(i < end_col_p1)
+      {
+      val *= A.at(start_row, i);
+      }
+    }
+  else
+    {
+    for(uword col=0; col < X_n_cols; ++col)
+      {
+      val *= arrayops::product( X.colptr(col), X_n_rows );
+      }
+    }
+  
+  return val;
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::elem_type
+op_prod::prod(const Base<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(X.get_ref());
+  
+  eT val = eT(1);
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typedef typename Proxy<T1>::ea_type ea_type;
+    
+    const ea_type A = P.get_ea();
+    
+    const uword n_elem = P.get_n_elem();
+    
+    uword i,j;
+    for(i=0, j=1; j < n_elem; i+=2, j+=2)
+      {
+      val *= A[i];
+      val *= A[j];
+      }
+    
+    if(i < n_elem)
+      {
+      val *= A[i];
+      }
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    if(n_rows == 1)
+      {
+      uword i,j;
+      for(i=0, j=1; j < n_cols; i+=2, j+=2)
+        {
+        val *= P.at(0,i);
+        val *= P.at(0,j);
+        }
+      
+      if(i < n_cols)
+        {
+        val *= P.at(0,i);
+        }
+      }
+    else
+      {
+      for(uword col=0; col < n_cols; ++col)
+        {
+        uword i,j;
+        for(i=0, j=1; j < n_rows; i+=2, j+=2)
+          {
+          val *= P.at(i,col);
+          val *= P.at(j,col);
+          }
+        
+        if(i < n_rows)
+          {
+          val *= P.at(i,col);
+          }
+        }
+      }
+    }
+  
+  return val;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_relational_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,144 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_relational
+//! @{
+
+
+
+class op_rel_lt_pre
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lt_pre>& X);
+  
+  template<typename T1>
+  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lt_pre>& X);
+  };
+
+
+
+class op_rel_lt_post
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lt_post>& X);
+  
+  template<typename T1>
+  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lt_post>& X);
+  };
+
+
+
+class op_rel_gt_pre
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gt_pre>& X);
+  
+  template<typename T1>
+  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gt_pre>& X);
+  };
+
+
+
+class op_rel_gt_post
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gt_post>& X);
+  
+  template<typename T1>
+  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gt_post>& X);
+  };
+
+
+
+class op_rel_lteq_pre
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lteq_pre>& X);
+  
+  template<typename T1>
+  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lteq_pre>& X);
+  };
+
+
+
+class op_rel_lteq_post
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lteq_post>& X);
+  
+  template<typename T1>
+  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lteq_post>& X);
+  };
+
+
+
+class op_rel_gteq_pre
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gteq_pre>& X);
+  
+  template<typename T1>
+  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gteq_pre>& X);
+  };
+
+
+
+class op_rel_gteq_post
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gteq_post>& X);
+  
+  template<typename T1>
+  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gteq_post>& X);
+  };
+
+
+
+class op_rel_eq
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_eq>& X);
+  
+  template<typename T1>
+  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_eq>& X);
+  };
+
+
+
+class op_rel_noteq
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_noteq>& X);
+  
+  template<typename T1>
+  inline static void apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_noteq>& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_relational_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,500 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_relational
+//! @{
+
+
+#undef operator_rel
+
+#undef arma_applier_mat_pre
+#undef arma_applier_mat_post
+
+#undef arma_applier_cube_pre
+#undef arma_applier_cube_post
+
+
+#define arma_applier_mat_pre(operator_rel) \
+  {\
+  typedef typename T1::elem_type      eT;\
+  typedef typename Proxy<T1>::ea_type ea_type;\
+  \
+  const eT val = X.aux;\
+  \
+  const Proxy<T1> P(X.m);\
+  \
+  const uword n_rows = P.get_n_rows();\
+  const uword n_cols = P.get_n_cols();\
+  \
+  const bool bad_alias = ( Proxy<T1>::has_subview && P.is_alias(out) );\
+  \
+  if(bad_alias == false)\
+    {\
+    out.set_size(n_rows, n_cols);\
+    \
+    uword* out_mem = out.memptr();\
+    \
+    if(Proxy<T1>::prefer_at_accessor == false)\
+      {\
+            ea_type PA     = P.get_ea();\
+      const uword   n_elem = out.n_elem;\
+      \
+      for(uword i=0; i<n_elem; ++i)\
+        {\
+        out_mem[i] = (val operator_rel PA[i]) ? uword(1) : uword(0);\
+        }\
+      }\
+    else\
+      {\
+      if(n_rows == 1)\
+        {\
+        for(uword count=0; count < n_cols; ++count)\
+          {\
+          out_mem[count] = (val operator_rel P.at(0,count)) ? uword(1) : uword(0);\
+          }\
+        }\
+      else\
+        {\
+        for(uword col=0; col < n_cols; ++col)\
+        for(uword row=0; row < n_rows; ++row)\
+          {\
+          *out_mem = (val operator_rel P.at(row,col)) ? uword(1) : uword(0);\
+          out_mem++;\
+          }\
+        }\
+      }\
+    }\
+  else\
+    {\
+    const Mat<eT> tmp(P.Q);\
+    \
+    out = (val) operator_rel (tmp);\
+    }\
+  }
+
+
+
+#define arma_applier_mat_post(operator_rel) \
+  {\
+  typedef typename T1::elem_type      eT;\
+  typedef typename Proxy<T1>::ea_type ea_type;\
+  \
+  const eT val = X.aux;\
+  \
+  const Proxy<T1> P(X.m);\
+  \
+  const uword n_rows = P.get_n_rows();\
+  const uword n_cols = P.get_n_cols();\
+  \
+  const bool bad_alias = ( Proxy<T1>::has_subview && P.is_alias(out) );\
+  \
+  if(bad_alias == false)\
+    {\
+    out.set_size(n_rows, n_cols);\
+    \
+    uword* out_mem = out.memptr();\
+    \
+    if(Proxy<T1>::prefer_at_accessor == false)\
+      {\
+            ea_type PA     = P.get_ea();\
+      const uword   n_elem = out.n_elem;\
+      \
+      for(uword i=0; i<n_elem; ++i)\
+        {\
+        out_mem[i] = (PA[i] operator_rel val) ? uword(1) : uword(0);\
+        }\
+      }\
+    else\
+      {\
+      if(n_rows == 1)\
+        {\
+        for(uword count=0; count < n_cols; ++count)\
+          {\
+          out_mem[count] = (P.at(0,count) operator_rel val) ? uword(1) : uword(0);\
+          }\
+        }\
+      else\
+        {\
+        for(uword col=0; col < n_cols; ++col)\
+        for(uword row=0; row < n_rows; ++row)\
+          {\
+          *out_mem = (P.at(row,col) operator_rel val) ? uword(1) : uword(0);\
+          out_mem++;\
+          }\
+        }\
+      }\
+    }\
+  else\
+    {\
+    const Mat<eT> tmp(P.Q);\
+    \
+    out = (tmp) operator_rel (val);\
+    }\
+  }
+
+
+
+#define arma_applier_cube_pre(operator_rel) \
+  {\
+  typedef typename T1::elem_type          eT;\
+  typedef typename ProxyCube<T1>::ea_type ea_type;\
+  \
+  const eT val = X.aux;\
+  \
+  const ProxyCube<T1> P(X.m);\
+  \
+  const uword n_rows   = P.get_n_rows();\
+  const uword n_cols   = P.get_n_cols();\
+  const uword n_slices = P.get_n_slices();\
+  \
+  const bool bad_alias = ( ProxyCube<T1>::has_subview && P.is_alias(out) );\
+  \
+  if(bad_alias == false)\
+    {\
+    out.set_size(n_rows, n_cols, n_slices);\
+    \
+    uword* out_mem = out.memptr();\
+    \
+    if(ProxyCube<T1>::prefer_at_accessor == false)\
+      {\
+            ea_type PA     = P.get_ea();\
+      const uword   n_elem = out.n_elem;\
+      \
+      for(uword i=0; i<n_elem; ++i)\
+        {\
+        out_mem[i] = (val operator_rel PA[i]) ? uword(1) : uword(0);\
+        }\
+      }\
+    else\
+      {\
+      for(uword slice=0; slice < n_slices; ++slice)\
+      for(uword col=0;   col   < n_cols;   ++col  )\
+      for(uword row=0;   row   < n_rows;   ++row  )\
+        {\
+        *out_mem = (val operator_rel P.at(row,col,slice)) ? uword(1) : uword(0);\
+        out_mem++;\
+        }\
+      }\
+    }\
+  else\
+    {\
+    const unwrap_cube<typename ProxyCube<T1>::stored_type> tmp(P.Q);\
+    \
+    out = (val) operator_rel (tmp.M);\
+    }\
+  }
+
+
+
+#define arma_applier_cube_post(operator_rel) \
+  {\
+  typedef typename T1::elem_type          eT;\
+  typedef typename ProxyCube<T1>::ea_type ea_type;\
+  \
+  const eT val = X.aux;\
+  \
+  const ProxyCube<T1> P(X.m);\
+  \
+  const uword n_rows   = P.get_n_rows();\
+  const uword n_cols   = P.get_n_cols();\
+  const uword n_slices = P.get_n_slices();\
+  \
+  const bool bad_alias = ( ProxyCube<T1>::has_subview && P.is_alias(out) );\
+  \
+  if(bad_alias == false)\
+    {\
+    out.set_size(n_rows, n_cols, n_slices);\
+    \
+    uword* out_mem = out.memptr();\
+    \
+    if(ProxyCube<T1>::prefer_at_accessor == false)\
+      {\
+            ea_type PA     = P.get_ea();\
+      const uword   n_elem = out.n_elem;\
+      \
+      for(uword i=0; i<n_elem; ++i)\
+        {\
+        out_mem[i] = (PA[i] operator_rel val) ? uword(1) : uword(0);\
+        }\
+      }\
+    else\
+      {\
+      for(uword slice=0; slice < n_slices; ++slice)\
+      for(uword col=0;   col   < n_cols;   ++col  )\
+      for(uword row=0;   row   < n_rows;   ++row  )\
+        {\
+        *out_mem = (P.at(row,col,slice) operator_rel val) ? uword(1) : uword(0);\
+        out_mem++;\
+        }\
+      }\
+    }\
+  else\
+    {\
+    const unwrap_cube<typename ProxyCube<T1>::stored_type> tmp(P.Q);\
+    \
+    out = (tmp.M) operator_rel (val);\
+    }\
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_lt_pre::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lt_pre>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat_pre( < );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_gt_pre::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gt_pre>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat_pre( > );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_lteq_pre::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lteq_pre>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat_pre( <= );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_gteq_pre::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gteq_pre>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat_pre( >= );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_lt_post::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lt_post>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat_post( < );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_gt_post::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gt_post>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat_post( > );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_lteq_post::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_lteq_post>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat_post( <= );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_gteq_post::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_gteq_post>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat_post( >= );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_eq::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_eq>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat_post( == );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_noteq::apply(Mat<uword>& out, const mtOp<uword, T1, op_rel_noteq>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_mat_post( != );
+  }
+
+
+
+//
+//
+//
+
+
+
+template<typename T1>
+inline
+void
+op_rel_lt_pre::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lt_pre>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube_pre( < );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_gt_pre::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gt_pre>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube_pre( > );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_lteq_pre::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lteq_pre>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube_pre( <= );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_gteq_pre::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gteq_pre>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube_pre( >= );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_lt_post::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lt_post>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube_post( < );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_gt_post::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gt_post>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube_post( > );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_lteq_post::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_lteq_post>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube_post( <= );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_gteq_post::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_gteq_post>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube_post( >= );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_eq::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_eq>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube_post( == );
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_rel_noteq::apply(Cube<uword>& out, const mtOpCube<uword, T1, op_rel_noteq>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_applier_cube_post( != );
+  }
+
+
+
+#undef arma_applier_mat_pre
+#undef arma_applier_mat_post
+
+#undef arma_applier_cube_pre
+#undef arma_applier_cube_post
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_repmat_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,24 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_repmat
+//! @{
+
+
+
+class op_repmat
+  {
+  public:
+  template<typename T1> inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_repmat>& in);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_repmat_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,93 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_repmat
+//! @{
+
+
+
+//! \brief
+//! implementation of the 'repeat matrix' operation, used for constructing matrices
+template<typename T1>
+inline
+void
+op_repmat::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_repmat>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1> tmp(in.m, out);
+  const Mat<eT>& X     = tmp.M;
+  
+  const uword copies_per_row = in.aux_uword_a;
+  const uword copies_per_col = in.aux_uword_b;
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  out.set_size(X_n_rows * copies_per_row, X_n_cols * copies_per_col);
+  
+  const uword out_n_rows = out.n_rows;
+  const uword out_n_cols = out.n_cols;
+  
+  // if( (out_n_rows > 0) && (out_n_cols > 0) )
+  //   {
+  //   for(uword col = 0; col < out_n_cols; col += X_n_cols)
+  //   for(uword row = 0; row < out_n_rows; row += X_n_rows)
+  //     {
+  //     out.submat(row, col, row+X_n_rows-1, col+X_n_cols-1) = X;
+  //     }
+  //   }
+  
+  if( (out_n_rows > 0) && (out_n_cols > 0) )
+    {
+    if(copies_per_row != 1)
+      {
+      for(uword col_copy=0; col_copy < copies_per_col; ++col_copy)
+        {
+        const uword out_col_offset = X_n_cols * col_copy;
+        
+        for(uword col=0; col < X_n_cols; ++col)
+          {
+                eT* out_colptr = out.colptr(col + out_col_offset);
+          const eT* X_colptr   = X.colptr(col);
+          
+          for(uword row_copy=0; row_copy < copies_per_row; ++row_copy)
+            {
+            const uword out_row_offset = X_n_rows * row_copy;
+            
+            arrayops::copy( &out_colptr[out_row_offset], X_colptr, X_n_rows );
+            }
+          }
+        }
+      }
+    else
+      {
+      for(uword col_copy=0; col_copy < copies_per_col; ++col_copy)
+        {
+        const uword out_col_offset = X_n_cols * col_copy;
+        
+        for(uword col=0; col < X_n_cols; ++col)
+          {
+                eT* out_colptr = out.colptr(col + out_col_offset);
+          const eT* X_colptr   = X.colptr(col);
+          
+          arrayops::copy( out_colptr, X_colptr, X_n_rows );
+          }
+        }
+      }
+    }
+  
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_reshape_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,25 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_reshape
+//! @{
+
+
+
+class op_reshape
+  {
+  public:
+  
+  template<typename T1> inline static void apply( Mat<typename T1::elem_type>& out, const     Op<T1,op_reshape>& in);
+  template<typename T1> inline static void apply(Cube<typename T1::elem_type>& out, const OpCube<T1,op_reshape>& in);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_reshape_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,256 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_reshape
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+op_reshape::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_reshape>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   A_tmp(in.m);
+  const Mat<eT>& A = A_tmp.M;
+  
+  const bool is_alias = (&out == &A);
+  
+  const uword in_n_rows = in.aux_uword_a;
+  const uword in_n_cols = in.aux_uword_b;
+  const uword in_dim    = in.aux_uword_c;
+  
+  const uword in_n_elem = in_n_rows * in_n_cols;
+  
+  if(A.n_elem == in_n_elem)
+    {
+    if(in_dim == 0)
+      {
+      if(is_alias == false)
+        {
+        out.set_size(in_n_rows, in_n_cols);
+        arrayops::copy( out.memptr(), A.memptr(), out.n_elem );
+        }
+      else  // &out == &A, i.e. inplace resize
+        {
+        const bool same_size = ( (out.n_rows == in_n_rows) && (out.n_cols == in_n_cols) );
+        
+        if(same_size == false)
+          {
+          arma_debug_check
+            (
+            (out.mem_state == 3),
+            "reshape(): size can't be changed as template based size specification is in use"
+            );
+          
+          access::rw(out.n_rows) = in_n_rows;
+          access::rw(out.n_cols) = in_n_cols;
+          }
+        }
+      }
+    else
+      {
+      unwrap_check< Mat<eT> > B_tmp(A, is_alias);
+      const Mat<eT>& B      = B_tmp.M;
+      
+      out.set_size(in_n_rows, in_n_cols);
+      
+      eT* out_mem = out.memptr();
+      uword i = 0;
+      
+      const uword B_n_rows = B.n_rows;
+      const uword B_n_cols = B.n_cols;
+      
+      for(uword row=0; row<B_n_rows; ++row)
+      for(uword col=0; col<B_n_cols; ++col)
+        {
+        out_mem[i] = B.at(row,col);
+        ++i;
+        }
+      }
+    }
+  else
+    {
+    const unwrap_check< Mat<eT> > B_tmp(A, is_alias);
+    const Mat<eT>& B            = B_tmp.M;
+    
+    const uword n_elem_to_copy = (std::min)(B.n_elem, in_n_elem);
+    
+    out.set_size(in_n_rows, in_n_cols);
+    
+    eT* out_mem = out.memptr();
+    
+    if(in_dim == 0)
+      {
+      arrayops::copy( out_mem, B.memptr(), n_elem_to_copy );
+      }
+    else
+      {
+      uword row = 0;
+      uword col = 0;
+      
+      const uword B_n_cols = B.n_cols;
+      
+      for(uword i=0; i<n_elem_to_copy; ++i)
+        {
+        out_mem[i] = B.at(row,col);
+        
+        ++col;
+        
+        if(col >= B_n_cols)
+          {
+          col = 0;
+          ++row;
+          }
+        }
+      }
+    
+    for(uword i=n_elem_to_copy; i<in_n_elem; ++i)
+      {
+      out_mem[i] = eT(0);
+      }
+    
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_reshape::apply(Cube<typename T1::elem_type>& out, const OpCube<T1,op_reshape>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_cube<T1> A_tmp(in.m);
+  const Cube<eT>& A   = A_tmp.M;
+  
+  const uword in_n_rows   = in.aux_uword_a;
+  const uword in_n_cols   = in.aux_uword_b;
+  const uword in_n_slices = in.aux_uword_c;
+  const uword in_dim      = in.aux_uword_d;
+  
+  const uword in_n_elem = in_n_rows * in_n_cols * in_n_slices;
+  
+  if(A.n_elem == in_n_elem)
+    {
+    if(in_dim == 0)
+      {
+      if(&out != &A)
+        {
+        out.set_size(in_n_rows, in_n_cols, in_n_slices);
+        arrayops::copy( out.memptr(), A.memptr(), out.n_elem );
+        }
+      else  // &out == &A, i.e. inplace resize
+        {
+        const bool same_size = ( (out.n_rows == in_n_rows) && (out.n_cols == in_n_cols) && (out.n_slices == in_n_slices) );
+        
+        if(same_size == false)
+          {
+          arma_debug_check
+            (
+            (out.mem_state == 3),
+            "reshape(): size can't be changed as template based size specification is in use"
+            );
+          
+          out.delete_mat();
+          
+          access::rw(out.n_rows)       = in_n_rows;
+          access::rw(out.n_cols)       = in_n_cols;
+          access::rw(out.n_elem_slice) = in_n_rows * in_n_cols;
+          access::rw(out.n_slices)     = in_n_slices;
+          
+          out.create_mat();
+          }
+        }
+      }
+    else
+      {
+      unwrap_cube_check< Cube<eT> > B_tmp(A, out);
+      const Cube<eT>& B           = B_tmp.M;
+      
+      out.set_size(in_n_rows, in_n_cols, in_n_slices);
+      
+      eT* out_mem = out.memptr();
+      uword i = 0;
+      
+      const uword B_n_rows   = B.n_rows;
+      const uword B_n_cols   = B.n_cols;
+      const uword B_n_slices = B.n_slices;
+      
+      for(uword slice=0; slice<B_n_slices; ++slice)
+      for(uword row=0; row<B_n_rows; ++row)
+      for(uword col=0; col<B_n_cols; ++col)
+        {
+        out_mem[i] = B.at(row,col,slice);
+        ++i;
+        }
+      }
+    }
+  else
+    {
+    const unwrap_cube_check< Cube<eT> > B_tmp(A, out);
+    const Cube<eT>& B                 = B_tmp.M;
+    
+    const uword n_elem_to_copy = (std::min)(B.n_elem, in_n_elem);
+    
+    out.set_size(in_n_rows, in_n_cols, in_n_slices);
+    
+    eT* out_mem = out.memptr();
+    
+    if(in_dim == 0)
+      {
+      arrayops::copy( out_mem, B.memptr(), n_elem_to_copy );
+      }
+    else
+      {
+      uword row   = 0;
+      uword col   = 0;
+      uword slice = 0;
+      
+      const uword B_n_rows = B.n_rows;
+      const uword B_n_cols = B.n_cols;
+      
+      for(uword i=0; i<n_elem_to_copy; ++i)
+        {
+        out_mem[i] = B.at(row,col,slice);
+        
+        ++col;
+        
+        if(col >= B_n_cols)
+          {
+          col = 0;
+          ++row;
+          
+          if(row >= B_n_rows)
+            {
+            row = 0;
+            ++slice;
+            }
+          }
+        }
+      }
+    
+    for(uword i=n_elem_to_copy; i<in_n_elem; ++i)
+      {
+      out_mem[i] = eT(0);
+      }
+    
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_resize_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,25 @@
+// Copyright (C) 2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_resize
+//! @{
+
+
+
+class op_resize
+  {
+  public:
+  
+  template<typename T1> inline static void apply( Mat<typename T1::elem_type>& out, const     Op<T1,op_resize>& in);
+  template<typename T1> inline static void apply(Cube<typename T1::elem_type>& out, const OpCube<T1,op_resize>& in);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_resize_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,114 @@
+// Copyright (C) 2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_resize
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+op_resize::apply(Mat<typename T1::elem_type>& actual_out, const Op<T1,op_resize>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword out_n_rows = in.aux_uword_a;
+  const uword out_n_cols = in.aux_uword_b;
+  
+  const unwrap<T1>   tmp(in.m);
+  const Mat<eT>& A = tmp.M;
+  
+  const uword A_n_rows = A.n_rows;
+  const uword A_n_cols = A.n_cols;
+  
+  Mat<eT> B;
+  
+  const bool alias = (&actual_out == &A);
+  
+  Mat<eT>& out = alias ? B : actual_out;
+  
+  out.set_size(out_n_rows, out_n_cols);
+  
+  if( (out_n_rows > A_n_rows) || (out_n_cols > A_n_cols) )
+    {
+    out.zeros();
+    }
+  
+  if( (out.n_elem > 0) && (A.n_elem > 0) )
+    {
+    const uword end_row = (std::min)(out_n_rows, A_n_rows) - 1;
+    const uword end_col = (std::min)(out_n_cols, A_n_cols) - 1;
+    
+    out.submat(0, 0, end_row, end_col) = A.submat(0, 0, end_row, end_col);
+    }
+  
+  if(alias)
+    {
+    actual_out.steal_mem(B);
+    }
+  
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_resize::apply(Cube<typename T1::elem_type>& actual_out, const OpCube<T1,op_resize>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword out_n_rows   = in.aux_uword_a;
+  const uword out_n_cols   = in.aux_uword_b;
+  const uword out_n_slices = in.aux_uword_c;
+  
+  const unwrap_cube<T1> tmp(in.m);
+  const Cube<eT>& A   = tmp.M;
+  
+  const uword A_n_rows   = A.n_rows;
+  const uword A_n_cols   = A.n_cols;
+  const uword A_n_slices = A.n_slices;
+  
+  Cube<eT> B;
+  
+  const bool alias = (&actual_out == &A);
+  
+  Cube<eT>& out = alias ? B : actual_out;
+  
+  out.set_size(out_n_rows, out_n_cols, out_n_slices);
+  
+  if( (out_n_rows > A_n_rows) || (out_n_cols > A_n_cols) || (out_n_slices > A_n_slices) )
+    {
+    out.zeros();
+    }
+  
+  if( (out.n_elem > 0) && (A.n_elem > 0) )
+    {
+    const uword end_row   = (std::min)(out_n_rows,   A_n_rows)   - 1;
+    const uword end_col   = (std::min)(out_n_cols,   A_n_cols)   - 1;
+    const uword end_slice = (std::min)(out_n_slices, A_n_slices) - 1;
+    
+    out.subcube(0, 0, 0, end_row, end_col, end_slice) = A.subcube(0, 0, 0, end_row, end_col, end_slice);
+    }
+  
+  if(alias)
+    {
+    actual_out.steal_mem(B);
+    }
+  
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_shuffle_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,25 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_shuffle
+//! @{
+
+
+
+class op_shuffle
+  {
+  public:
+  
+  template<typename T1> inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_shuffle>& in);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_shuffle_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,193 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// Copyright (C) 2009-2010 Dimitrios Bouzas
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_shuffle
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+op_shuffle::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_shuffle>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   tmp(in.m);
+  const Mat<eT>& X = tmp.M;
+  
+  if(X.is_empty()) { out.copy_size(X); return; }
+  
+  const uword dim = in.aux_uword_a;
+  const uword N   = (dim == 0) ? X.n_rows : X.n_cols;
+  
+  // see "fn_sort_index.hpp" for the definition of "arma_sort_index_packet"
+  // and the associated comparison functor
+  std::vector< arma_sort_index_packet<int,uword> > packet_vec(N);
+  
+  for(uword i=0; i<N; ++i)
+    {
+    packet_vec[i].val   = std::rand();
+    packet_vec[i].index = i;
+    }
+  
+  arma_sort_index_helper_ascend comparator;
+
+  std::sort( packet_vec.begin(), packet_vec.end(), comparator );
+  
+  const bool is_alias = (&out == &X);
+  
+  if(X.is_vec() == false)
+    {
+    if(is_alias == false)
+      {
+      arma_extra_debug_print("op_shuffle::apply(): matrix");
+      
+      out.copy_size(X);
+      
+      if(dim == 0)
+        {
+        for(uword i=0; i<N; ++i) { out.row(i) = X.row(packet_vec[i].index); }
+        }
+      else
+        {
+        for(uword i=0; i<N; ++i) { out.col(i) = X.col(packet_vec[i].index); }
+        }
+      }
+    else  // in-place shuffle
+      {
+      arma_extra_debug_print("op_shuffle::apply(): in-place matrix");
+      
+      // reuse the val member variable of packet_vec
+      // to indicate whether a particular row or column
+      // has already been shuffled
+      
+      for(uword i=0; i<N; ++i)
+        {
+        packet_vec[i].val = 0;
+        }
+        
+      if(dim == 0)
+        {
+        for(uword i=0; i<N; ++i)
+          {
+          if(packet_vec[i].val == 0)
+            {
+            const uword j = packet_vec[i].index;
+            
+            out.swap_rows(i, j);
+            
+            packet_vec[j].val = 1;
+            }
+          }
+        }
+      else
+        {
+        for(uword i=0; i<N; ++i)
+          {
+          if(packet_vec[i].val == 0)
+            {
+            const uword j = packet_vec[i].index;
+            
+            out.swap_cols(i, j);
+            
+            packet_vec[j].val = 1;
+            }
+          }
+        }
+      }
+    }
+  else  // we're dealing with a vector
+    {
+    if(is_alias == false)
+      {
+      arma_extra_debug_print("op_shuffle::apply(): vector");
+      
+      out.copy_size(X);
+      
+      if(dim == 0)
+        {
+        if(X.n_rows > 1)  // i.e. column vector
+          {
+          for(uword i=0; i<N; ++i) { out[i] = X[ packet_vec[i].index ]; }
+          }
+        else
+          {
+          out = X;
+          }
+        }
+      else
+        {
+        if(X.n_cols > 1)  // i.e. row vector
+          {
+          for(uword i=0; i<N; ++i) { out[i] = X[ packet_vec[i].index ]; }
+          }
+        else
+          {
+          out = X;
+          }
+        }
+      }
+    else  // in-place shuffle
+      {
+      arma_extra_debug_print("op_shuffle::apply(): in-place vector");
+      
+      // reuse the val member variable of packet_vec
+      // to indicate whether a particular row or column
+      // has already been shuffled
+      
+      for(uword i=0; i<N; ++i)
+        {
+        packet_vec[i].val = 0;
+        }
+        
+      if(dim == 0)
+        {
+        if(X.n_rows > 1)  // i.e. column vector
+          {
+          for(uword i=0; i<N; ++i)
+            {
+            if(packet_vec[i].val == 0)
+              {
+              const uword j = packet_vec[i].index;
+              
+              std::swap(out[i], out[j]);
+              
+              packet_vec[j].val = 1;
+              }
+            }
+          }
+        }
+      else
+        {
+        if(X.n_cols > 1)  // i.e. row vector
+          {
+          for(uword i=0; i<N; ++i)
+            {
+            if(packet_vec[i].val == 0)
+              {
+              const uword j = packet_vec[i].index;
+              
+              std::swap(out[i], out[j]);
+              
+              packet_vec[j].val = 1;
+              }
+            }
+          }
+        }
+      }
+    }
+  
+  }
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_sort_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,36 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_sort
+//! @{
+
+
+
+class op_sort
+  {
+  public:
+  
+  template<typename eT>
+  inline static void copy_row(eT* X, const Mat<eT>& A, const uword row);
+  
+  template<typename eT>
+  inline static void copy_row(Mat<eT>& A, const eT* X, const uword row);
+  
+  template<typename eT>
+  inline static void direct_sort(eT* X, const uword N, const uword sort_type = 0);
+  
+  template<typename eT>
+  inline static void direct_sort_ascending(eT* X, const uword N);
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sort>& in);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_sort_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,236 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_sort
+//! @{
+
+
+
+template<typename eT>
+class arma_ascend_sort_helper
+  {
+  public:
+  
+  arma_inline
+  bool
+  operator() (eT a, eT b) const
+    {
+    return (a < b);
+    }
+  };
+  
+
+
+template<typename eT>
+class arma_descend_sort_helper
+  {
+  public:
+  
+  arma_inline
+  bool
+  operator() (eT a, eT b) const
+    {
+    return (a > b);
+    }
+  };
+  
+
+
+template<typename T>
+class arma_ascend_sort_helper< std::complex<T> >
+  {
+  public:
+  
+  typedef typename std::complex<T> eT;
+  
+  inline
+  bool
+  operator() (const eT& a, const eT& b) const
+    {
+    return (std::abs(a) < std::abs(b));
+    }
+  };
+
+
+
+template<typename T>
+class arma_descend_sort_helper< std::complex<T> >
+  {
+  public:
+  
+  typedef typename std::complex<T> eT;
+  
+  inline
+  bool
+  operator() (const eT& a, const eT& b) const
+    {
+    return (std::abs(a) > std::abs(b));
+    }
+  };
+
+
+
+template<typename eT>
+inline 
+void
+op_sort::direct_sort(eT* X, const uword n_elem, const uword sort_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(sort_type == 0)
+    {
+    arma_ascend_sort_helper<eT> comparator;
+    
+    std::sort(&X[0], &X[n_elem], comparator);
+    }
+  else
+    {
+    arma_descend_sort_helper<eT> comparator;
+    
+    std::sort(&X[0], &X[n_elem], comparator);
+    }
+  }
+
+
+
+template<typename eT>
+inline 
+void
+op_sort::direct_sort_ascending(eT* X, const uword n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_ascend_sort_helper<eT> comparator;
+    
+  std::sort(&X[0], &X[n_elem], comparator);
+  }
+
+
+
+template<typename eT>
+inline 
+void
+op_sort::copy_row(eT* X, const Mat<eT>& A, const uword row)
+  {
+  const uword N = A.n_cols;
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<N; i+=2, j+=2)
+    {
+    X[i] = A.at(row,i);
+    X[j] = A.at(row,j);
+    }
+  
+  if(i < N)
+    {
+    X[i] = A.at(row,i);
+    }
+  }
+
+
+
+template<typename eT>
+inline 
+void
+op_sort::copy_row(Mat<eT>& A, const eT* X, const uword row)
+  {
+  const uword N = A.n_cols;
+  
+  uword i,j;
+  
+  for(i=0, j=1; j<N; i+=2, j+=2)
+    {
+    A.at(row,i) = X[i]; 
+    A.at(row,j) = X[j];
+    }
+  
+  if(i < N)
+    {
+    A.at(row,i) = X[i];
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_sort::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sort>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1>   tmp(in.m, out);
+  const Mat<eT>&       X = tmp.M;
+  
+  const uword sort_type = in.aux_uword_a;
+  const uword dim       = in.aux_uword_b;
+  
+  arma_debug_check( (sort_type > 1),          "sort(): incorrect usage. sort_type must be 0 or 1");
+  arma_debug_check( (dim > 1),                "sort(): incorrect usage. dim must be 0 or 1"      );
+  arma_debug_check( (X.is_finite() == false), "sort(): given object has non-finite elements"     );
+  
+  if( (X.n_rows * X.n_cols) <= 1 )
+    {
+    out = X;
+    return;
+    }
+  
+  
+  if(dim == 0)  // sort the contents of each column
+    {
+    arma_extra_debug_print("op_sort::apply(), dim = 0");
+    
+    out = X;
+    
+    const uword n_rows = out.n_rows;
+    const uword n_cols = out.n_cols;
+      
+    for(uword col=0; col < n_cols; ++col)
+      {
+      op_sort::direct_sort( out.colptr(col), n_rows, sort_type );
+      }
+    }
+  else
+  if(dim == 1)  // sort the contents of each row
+    {
+    if(X.n_rows == 1)  // a row vector
+      {
+      arma_extra_debug_print("op_sort::apply(), dim = 1, vector specific");
+      
+      out = X;
+      op_sort::direct_sort(out.memptr(), out.n_elem, sort_type);
+      }
+    else  // not a row vector
+      {
+      arma_extra_debug_print("op_sort::apply(), dim = 1, generic");
+      
+      out.copy_size(X);
+      
+      const uword n_rows = out.n_rows;
+      const uword n_cols = out.n_cols;
+      
+      podarray<eT> tmp_array(n_cols);
+      
+      for(uword row=0; row < n_rows; ++row)
+        {
+        op_sort::copy_row(tmp_array.memptr(), X, row);
+        
+        op_sort::direct_sort( tmp_array.memptr(), n_cols, sort_type );
+        
+        op_sort::copy_row(out, tmp_array.memptr(), row);
+        }
+      }
+    }
+  
+  }
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_stddev_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,21 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_stddev
+//! @{
+
+//! Class for finding the standard deviation
+class op_stddev
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_stddev>& in);
+  };
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_stddev_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,80 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_stddev
+//! @{
+
+
+//! \brief
+//! For each row or for each column, find the standard deviation.
+//! The result is stored in a dense matrix that has either one column or one row.
+//! The dimension for which the standard deviations are found is set via the stddev() function.
+template<typename T1>
+inline
+void
+op_stddev::apply(Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_stddev>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type  in_eT;
+  typedef typename T1::pod_type  out_eT;
+  
+  const unwrap_check_mixed<T1> tmp(in.m, out);
+  const Mat<in_eT>&        X = tmp.M;
+  
+  const uword norm_type = in.aux_uword_a;
+  const uword dim       = in.aux_uword_b;
+  
+  arma_debug_check( (norm_type > 1), "stddev(): incorrect usage. norm_type must be 0 or 1");
+  arma_debug_check( (dim > 1),       "stddev(): incorrect usage. dim must be 0 or 1"      );
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  if(dim == 0)
+    {
+    arma_extra_debug_print("op_stddev::apply(), dim = 0");
+
+    arma_debug_check( (X_n_rows == 0), "stddev(): given object has zero rows" );
+    
+    out.set_size(1, X_n_cols);
+    
+    out_eT* out_mem = out.memptr();
+    
+    for(uword col=0; col<X_n_cols; ++col)
+      {
+      out_mem[col] = std::sqrt( op_var::direct_var( X.colptr(col), X_n_rows, norm_type ) );
+      }
+    }
+  else
+  if(dim == 1)
+    {
+    arma_extra_debug_print("op_stddev::apply(), dim = 1");
+    
+    arma_debug_check( (X_n_cols == 0), "stddev(): given object has zero columns" );
+
+    out.set_size(X_n_rows, 1);
+    
+    podarray<in_eT> dat(X_n_cols);
+    
+    in_eT*  dat_mem = dat.memptr();
+    out_eT* out_mem = out.memptr();
+    
+    for(uword row=0; row<X_n_rows; ++row)
+      {
+      dat.copy_row(X, row);
+      
+      out_mem[row] = std::sqrt( op_var::direct_var( dat_mem, X_n_cols, norm_type) );
+      }
+    }
+  }
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_strans_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,74 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_strans
+//! @{
+
+
+//! 'matrix transpose' operation (simple transpose, ie. without taking the conjugate of the elements)
+
+class op_strans
+  {
+  public:
+  
+  template<const bool do_flip, const uword row, const uword col>
+  struct pos
+    {
+    static const uword n2 = (do_flip == false) ? (row + col*2) : (col + row*2);
+    static const uword n3 = (do_flip == false) ? (row + col*3) : (col + row*3);
+    static const uword n4 = (do_flip == false) ? (row + col*4) : (col + row*4);
+    };
+  
+  template<typename eT, typename TA>
+  arma_hot inline static void apply_noalias_tinysq(Mat<eT>& out, const TA& A);
+  
+  template<typename eT, typename TA>
+  arma_hot inline static void apply_noalias(Mat<eT>& out, const TA& A);
+  
+  template<typename eT, typename TA>
+  arma_hot inline static void apply(Mat<eT>& out, const TA& A);
+  
+  template<typename T1>
+  arma_hot inline static void apply_proxy(Mat<typename T1::elem_type>& out, const T1& X);
+  
+  template<typename T1>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_strans>& in);
+  };
+
+
+
+class op_strans2
+  {
+  public:
+  
+  template<const bool do_flip, const uword row, const uword col>
+  struct pos
+    {
+    static const uword n2 = (do_flip == false) ? (row + col*2) : (col + row*2);
+    static const uword n3 = (do_flip == false) ? (row + col*3) : (col + row*3);
+    static const uword n4 = (do_flip == false) ? (row + col*4) : (col + row*4);
+    };
+  
+  template<typename eT, typename TA>
+  arma_hot inline static void apply_noalias_tinysq(Mat<eT>& out, const TA& A, const eT val);
+  
+  template<typename eT, typename TA>
+  arma_hot inline static void apply_noalias(Mat<eT>& out, const TA& A, const eT val);
+  
+  template<typename eT, typename TA>
+  arma_hot inline static void apply(Mat<eT>& out, const TA& A, const eT val);
+  
+  template<typename T1>
+  arma_hot inline static void apply_proxy(Mat<typename T1::elem_type>& out, const T1& X, const typename T1::elem_type val);
+  
+  // NOTE: there is no direct handling of Op<T1,op_strans2>, as op_strans2::apply_proxy() is currently only called by op_htrans2 for non-complex numbers
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_strans_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,690 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_strans
+//! @{
+
+
+
+//! for tiny square matrices (size <= 4x4)
+template<typename eT, typename TA>
+arma_hot
+inline
+void
+op_strans::apply_noalias_tinysq(Mat<eT>& out, const TA& A)
+  {
+  const eT*   Am =   A.memptr();
+        eT* outm = out.memptr();
+  
+  switch(A.n_rows)
+    {
+    case 1:
+      {
+      outm[0] = Am[0];
+      }
+      break;
+      
+    case 2:
+      {
+      outm[pos<false,0,0>::n2] = Am[pos<true,0,0>::n2];
+      outm[pos<false,1,0>::n2] = Am[pos<true,1,0>::n2];
+      
+      outm[pos<false,0,1>::n2] = Am[pos<true,0,1>::n2];
+      outm[pos<false,1,1>::n2] = Am[pos<true,1,1>::n2];
+      }
+      break;
+    
+    case 3:
+      {
+      outm[pos<false,0,0>::n3] = Am[pos<true,0,0>::n3];
+      outm[pos<false,1,0>::n3] = Am[pos<true,1,0>::n3];
+      outm[pos<false,2,0>::n3] = Am[pos<true,2,0>::n3];
+      
+      outm[pos<false,0,1>::n3] = Am[pos<true,0,1>::n3];
+      outm[pos<false,1,1>::n3] = Am[pos<true,1,1>::n3];
+      outm[pos<false,2,1>::n3] = Am[pos<true,2,1>::n3];
+      
+      outm[pos<false,0,2>::n3] = Am[pos<true,0,2>::n3];
+      outm[pos<false,1,2>::n3] = Am[pos<true,1,2>::n3];
+      outm[pos<false,2,2>::n3] = Am[pos<true,2,2>::n3];
+      }
+      break;
+    
+    case 4:
+      {
+      outm[pos<false,0,0>::n4] = Am[pos<true,0,0>::n4];
+      outm[pos<false,1,0>::n4] = Am[pos<true,1,0>::n4];
+      outm[pos<false,2,0>::n4] = Am[pos<true,2,0>::n4];
+      outm[pos<false,3,0>::n4] = Am[pos<true,3,0>::n4];
+      
+      outm[pos<false,0,1>::n4] = Am[pos<true,0,1>::n4];
+      outm[pos<false,1,1>::n4] = Am[pos<true,1,1>::n4];
+      outm[pos<false,2,1>::n4] = Am[pos<true,2,1>::n4];
+      outm[pos<false,3,1>::n4] = Am[pos<true,3,1>::n4];
+      
+      outm[pos<false,0,2>::n4] = Am[pos<true,0,2>::n4];
+      outm[pos<false,1,2>::n4] = Am[pos<true,1,2>::n4];
+      outm[pos<false,2,2>::n4] = Am[pos<true,2,2>::n4];
+      outm[pos<false,3,2>::n4] = Am[pos<true,3,2>::n4];
+      
+      outm[pos<false,0,3>::n4] = Am[pos<true,0,3>::n4];
+      outm[pos<false,1,3>::n4] = Am[pos<true,1,3>::n4];
+      outm[pos<false,2,3>::n4] = Am[pos<true,2,3>::n4];
+      outm[pos<false,3,3>::n4] = Am[pos<true,3,3>::n4];
+      }
+      break;
+    
+    default:
+      ;
+    }
+  
+  }
+
+
+
+//! Immediate transpose of a dense matrix
+template<typename eT, typename TA>
+arma_hot
+inline
+void
+op_strans::apply_noalias(Mat<eT>& out, const TA& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword A_n_cols = A.n_cols;
+  const uword A_n_rows = A.n_rows;
+  
+  out.set_size(A_n_cols, A_n_rows);
+  
+  if( (TA::is_row) || (TA::is_col) || (A_n_cols == 1) || (A_n_rows == 1) )
+    {
+    arrayops::copy( out.memptr(), A.memptr(), A.n_elem );
+    }
+  else
+    {
+    if( (A_n_rows <= 4) && (A_n_rows == A_n_cols) )
+      {
+      op_strans::apply_noalias_tinysq(out, A);
+      }
+    else
+      {
+      for(uword k=0; k < A_n_cols; ++k)
+        {
+        uword i, j;
+        
+        const eT* colptr = A.colptr(k);
+        
+        for(i=0, j=1; j < A_n_rows; i+=2, j+=2)
+          {
+          const eT tmp_i = colptr[i];
+          const eT tmp_j = colptr[j];
+          
+          out.at(k, i) = tmp_i;
+          out.at(k, j) = tmp_j;
+          }
+        
+        if(i < A_n_rows)
+          {
+          out.at(k, i) = colptr[i];
+          }
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT, typename TA>
+arma_hot
+inline
+void
+op_strans::apply(Mat<eT>& out, const TA& A)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(&out != &A)
+    {
+    op_strans::apply_noalias(out, A);
+    }
+  else
+    {
+    const uword n_rows = A.n_rows;
+    const uword n_cols = A.n_cols;
+    
+    if(n_rows == n_cols)
+      {
+      arma_extra_debug_print("op_strans::apply(): doing in-place transpose of a square matrix");
+      
+      const uword N = n_rows;
+      
+      for(uword k=0; k < N; ++k)
+        {
+        eT* colptr = out.colptr(k);
+        
+        uword i,j;
+        
+        for(i=(k+1), j=(k+2); j < N; i+=2, j+=2)
+          {
+          std::swap(out.at(k,i), colptr[i]);
+          std::swap(out.at(k,j), colptr[j]);
+          }
+        
+        if(i < N)
+          {
+          std::swap(out.at(k,i), colptr[i]);
+          }
+        }
+      }
+    else
+      {
+      Mat<eT> tmp;
+      op_strans::apply_noalias(tmp, A);
+      
+      out.steal_mem(tmp);
+      }
+    }
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_strans::apply_proxy(Mat<typename T1::elem_type>& out, const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(X);
+  
+  // allow detection of in-place transpose
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) && (Proxy<T1>::fake_mat == false) )
+    {
+    const unwrap<typename Proxy<T1>::stored_type> tmp(P.Q);
+    
+    op_strans::apply(out, tmp.M);
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    const bool is_alias = P.is_alias(out);
+    
+    if( (resolves_to_vector<T1>::value == true) && (Proxy<T1>::prefer_at_accessor == false) )
+      {
+      if(is_alias == false)
+        {
+        out.set_size(n_cols, n_rows);
+        
+        eT* out_mem = out.memptr();
+        
+        const uword n_elem = P.get_n_elem();
+        
+        typename Proxy<T1>::ea_type Pea = P.get_ea();
+        
+        uword i,j;
+        for(i=0, j=1; j < n_elem; i+=2, j+=2)
+          {
+          const eT tmp_i = Pea[i];
+          const eT tmp_j = Pea[j];
+          
+          out_mem[i] = tmp_i;
+          out_mem[j] = tmp_j;
+          }
+        
+        if(i < n_elem)
+          {
+          out_mem[i] = Pea[i];
+          }
+        }
+      else  // aliasing
+        {
+        Mat<eT> out2(n_cols, n_rows);
+        
+        eT* out_mem = out2.memptr();
+        
+        const uword n_elem = P.get_n_elem();
+        
+        typename Proxy<T1>::ea_type Pea = P.get_ea();
+        
+        uword i,j;
+        for(i=0, j=1; j < n_elem; i+=2, j+=2)
+          {
+          const eT tmp_i = Pea[i];
+          const eT tmp_j = Pea[j];
+          
+          out_mem[i] = tmp_i;
+          out_mem[j] = tmp_j;
+          }
+        
+        if(i < n_elem)
+          {
+          out_mem[i] = Pea[i];
+          }
+        
+        out.steal_mem(out2);
+        }
+      }
+    else   // general matrix transpose
+      {
+      if(is_alias == false)
+        {
+        out.set_size(n_cols, n_rows);
+        
+        for(uword k=0; k < n_cols; ++k)
+          {
+          uword i, j;
+          
+          for(i=0, j=1; j < n_rows; i+=2, j+=2)
+            {
+            const eT tmp_i = P.at(i,k);
+            const eT tmp_j = P.at(j,k);
+            
+            out.at(k,i) = tmp_i;
+            out.at(k,j) = tmp_j;
+            }
+          
+          if(i < n_rows)
+            {
+            out.at(k,i) = P.at(i,k);
+            }
+          }
+        }
+      else // aliasing
+        {
+        Mat<eT> out2(n_cols, n_rows);
+        
+        for(uword k=0; k < n_cols; ++k)
+          {
+          uword i, j;
+          
+          for(i=0, j=1; j < n_rows; i+=2, j+=2)
+            {
+            const eT tmp_i = P.at(i,k);
+            const eT tmp_j = P.at(j,k);
+            
+            out2.at(k,i) = tmp_i;
+            out2.at(k,j) = tmp_j;
+            }
+          
+          if(i < n_rows)
+            {
+            out2.at(k,i) = P.at(i,k);
+            }
+          }
+        
+        out.steal_mem(out2);
+        }
+      }
+    }
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_strans::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_strans>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  op_strans::apply_proxy(out, in.m);
+  }
+
+
+
+//
+// op_strans2
+
+
+
+//! for tiny square matrices (size <= 4x4)
+template<typename eT, typename TA>
+arma_hot
+inline
+void
+op_strans2::apply_noalias_tinysq(Mat<eT>& out, const TA& A, const eT val)
+  {
+  const eT* Am   =   A.memptr();
+        eT* outm = out.memptr();
+  
+  switch(A.n_rows)
+    {
+    case 1:
+      {
+      outm[0] = val * Am[0];
+      }
+      break;
+      
+    case 2:
+      {
+      outm[pos<false,0,0>::n2] = val * Am[pos<true,0,0>::n2];
+      outm[pos<false,1,0>::n2] = val * Am[pos<true,1,0>::n2];
+      
+      outm[pos<false,0,1>::n2] = val * Am[pos<true,0,1>::n2];
+      outm[pos<false,1,1>::n2] = val * Am[pos<true,1,1>::n2];
+      }
+      break;
+    
+    case 3:
+      {
+      outm[pos<false,0,0>::n3] = val * Am[pos<true,0,0>::n3];
+      outm[pos<false,1,0>::n3] = val * Am[pos<true,1,0>::n3];
+      outm[pos<false,2,0>::n3] = val * Am[pos<true,2,0>::n3];
+      
+      outm[pos<false,0,1>::n3] = val * Am[pos<true,0,1>::n3];
+      outm[pos<false,1,1>::n3] = val * Am[pos<true,1,1>::n3];
+      outm[pos<false,2,1>::n3] = val * Am[pos<true,2,1>::n3];
+      
+      outm[pos<false,0,2>::n3] = val * Am[pos<true,0,2>::n3];
+      outm[pos<false,1,2>::n3] = val * Am[pos<true,1,2>::n3];
+      outm[pos<false,2,2>::n3] = val * Am[pos<true,2,2>::n3];
+      }
+      break;
+    
+    case 4:
+      {
+      outm[pos<false,0,0>::n4] = val * Am[pos<true,0,0>::n4];
+      outm[pos<false,1,0>::n4] = val * Am[pos<true,1,0>::n4];
+      outm[pos<false,2,0>::n4] = val * Am[pos<true,2,0>::n4];
+      outm[pos<false,3,0>::n4] = val * Am[pos<true,3,0>::n4];
+      
+      outm[pos<false,0,1>::n4] = val * Am[pos<true,0,1>::n4];
+      outm[pos<false,1,1>::n4] = val * Am[pos<true,1,1>::n4];
+      outm[pos<false,2,1>::n4] = val * Am[pos<true,2,1>::n4];
+      outm[pos<false,3,1>::n4] = val * Am[pos<true,3,1>::n4];
+      
+      outm[pos<false,0,2>::n4] = val * Am[pos<true,0,2>::n4];
+      outm[pos<false,1,2>::n4] = val * Am[pos<true,1,2>::n4];
+      outm[pos<false,2,2>::n4] = val * Am[pos<true,2,2>::n4];
+      outm[pos<false,3,2>::n4] = val * Am[pos<true,3,2>::n4];
+      
+      outm[pos<false,0,3>::n4] = val * Am[pos<true,0,3>::n4];
+      outm[pos<false,1,3>::n4] = val * Am[pos<true,1,3>::n4];
+      outm[pos<false,2,3>::n4] = val * Am[pos<true,2,3>::n4];
+      outm[pos<false,3,3>::n4] = val * Am[pos<true,3,3>::n4];
+      }
+      break;
+    
+    default:
+      ;
+    }
+  
+  }
+
+
+
+template<typename eT, typename TA>
+arma_hot
+inline
+void
+op_strans2::apply_noalias(Mat<eT>& out, const TA& A, const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword A_n_cols = A.n_cols;
+  const uword A_n_rows = A.n_rows;
+  
+  out.set_size(A_n_cols, A_n_rows);
+  
+  if( (TA::is_col) || (TA::is_row) || (A_n_cols == 1) || (A_n_rows == 1) )
+    {
+    const uword N = A.n_elem;
+    
+    const eT*   A_mem =   A.memptr();
+          eT* out_mem = out.memptr();
+    
+    uword i,j;
+    for(i=0, j=1; j < N; i+=2, j+=2)
+      {
+      const eT tmp_i = A_mem[i];
+      const eT tmp_j = A_mem[j];
+      
+      out_mem[i] = val * tmp_i;
+      out_mem[j] = val * tmp_j;
+      }
+    
+    if(i < N)
+      {
+      out_mem[i] = val * A_mem[i];
+      }
+    }
+  else
+    {
+    if( (A_n_rows <= 4) && (A_n_rows == A_n_cols) )
+      {
+      op_strans2::apply_noalias_tinysq(out, A, val);
+      }
+    else
+      {
+      for(uword k=0; k < A_n_cols; ++k)
+        {
+        uword i, j;
+        
+        const eT* colptr = A.colptr(k);
+        
+        for(i=0, j=1; j < A_n_rows; i+=2, j+=2)
+          {
+          const eT tmp_i = colptr[i];
+          const eT tmp_j = colptr[j];
+          
+          out.at(k, i) = val * tmp_i;
+          out.at(k, j) = val * tmp_j;
+          }
+        
+        if(i < A_n_rows)
+          {
+          out.at(k, i) = val * colptr[i];
+          }
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT, typename TA>
+arma_hot
+inline
+void
+op_strans2::apply(Mat<eT>& out, const TA& A, const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(&out != &A)
+    {
+    op_strans2::apply_noalias(out, A, val);
+    }
+  else
+    {
+    const uword n_rows = out.n_rows;
+    const uword n_cols = out.n_cols;
+    
+    if(n_rows == n_cols)
+      {
+      arma_extra_debug_print("op_strans2::apply(): doing in-place transpose of a square matrix");
+      
+      const uword N = n_rows;
+      
+      // TODO: do multiplication while swapping
+      
+      for(uword k=0; k < N; ++k)
+        {
+        eT* colptr = out.colptr(k);
+        
+        uword i,j;
+        
+        for(i=(k+1), j=(k+2); j < N; i+=2, j+=2)
+          {
+          std::swap(out.at(k,i), colptr[i]);
+          std::swap(out.at(k,j), colptr[j]);
+          }
+        
+        if(i < N)
+          {
+          std::swap(out.at(k,i), colptr[i]);
+          }
+        }
+      
+      arrayops::inplace_mul( out.memptr(), val, out.n_elem );
+      }
+    else
+      {
+      Mat<eT> tmp;
+      op_strans2::apply_noalias(tmp, A, val);
+      
+      out.steal_mem(tmp);
+      }
+    }
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+op_strans2::apply_proxy(Mat<typename T1::elem_type>& out, const T1& X, const typename T1::elem_type val)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(X);
+  
+  // allow detection of in-place transpose
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) && (Proxy<T1>::fake_mat == false) )
+    {
+    const unwrap<typename Proxy<T1>::stored_type> tmp(P.Q);
+    
+    op_strans2::apply(out, tmp.M, val);
+    }
+  else
+    {
+    const uword n_rows = P.get_n_rows();
+    const uword n_cols = P.get_n_cols();
+    
+    const bool is_alias = P.is_alias(out);
+    
+    if( (resolves_to_vector<T1>::value == true) && (Proxy<T1>::prefer_at_accessor == false) )
+      {
+      if(is_alias == false)
+        {
+        out.set_size(n_cols, n_rows);
+        
+        eT* out_mem = out.memptr();
+        
+        const uword n_elem = P.get_n_elem();
+        
+        typename Proxy<T1>::ea_type Pea = P.get_ea();
+        
+        uword i,j;
+        for(i=0, j=1; j < n_elem; i+=2, j+=2)
+          {
+          const eT tmp_i = Pea[i];
+          const eT tmp_j = Pea[j];
+          
+          out_mem[i] = val * tmp_i;
+          out_mem[j] = val * tmp_j;
+          }
+        
+        if(i < n_elem)
+          {
+          out_mem[i] = val * Pea[i];
+          }
+        }
+      else  // aliasing
+        {
+        Mat<eT> out2(n_cols, n_rows);
+        
+        eT* out_mem = out2.memptr();
+        
+        const uword n_elem = P.get_n_elem();
+        
+        typename Proxy<T1>::ea_type Pea = P.get_ea();
+        
+        uword i,j;
+        for(i=0, j=1; j < n_elem; i+=2, j+=2)
+          {
+          const eT tmp_i = Pea[i];
+          const eT tmp_j = Pea[j];
+          
+          out_mem[i] = val * tmp_i;
+          out_mem[j] = val * tmp_j;
+          }
+        
+        if(i < n_elem)
+          {
+          out_mem[i] = val * Pea[i];
+          }
+        
+        out.steal_mem(out2);
+        }
+      }
+    else   // general matrix transpose
+      {
+      if(is_alias == false)
+        {
+        out.set_size(n_cols, n_rows);
+        
+        for(uword k=0; k < n_cols; ++k)
+          {
+          uword i, j;
+          
+          for(i=0, j=1; j < n_rows; i+=2, j+=2)
+            {
+            const eT tmp_i = P.at(i,k);
+            const eT tmp_j = P.at(j,k);
+            
+            out.at(k,i) = val * tmp_i;
+            out.at(k,j) = val * tmp_j;
+            }
+          
+          if(i < n_rows)
+            {
+            out.at(k,i) = val * P.at(i,k);
+            }
+          }
+        }
+      else // aliasing
+        {
+        Mat<eT> out2(n_cols, n_rows);
+        
+        for(uword k=0; k < n_cols; ++k)
+          {
+          uword i, j;
+          
+          for(i=0, j=1; j < n_rows; i+=2, j+=2)
+            {
+            const eT tmp_i = P.at(i,k);
+            const eT tmp_j = P.at(j,k);
+            
+            out2.at(k,i) = val * tmp_i;
+            out2.at(k,j) = val * tmp_j;
+            }
+          
+          if(i < n_rows)
+            {
+            out2.at(k,i) = val * P.at(i,k);
+            }
+          }
+        
+        out.steal_mem(out2);
+        }
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_sum_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,22 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_sum
+//! @{
+
+//! Class for finding sums of values in a matrix  (e.g. along rows or columns)
+class op_sum
+  {
+  public:
+  
+  template<typename T1>
+  arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1, op_sum>& in);
+  };
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_sum_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,141 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_sum
+//! @{
+
+//! \brief
+//! Immediate sum of elements of a matrix along a specified dimension (either rows or columns).
+//! The result is stored in a dense matrix that has either one column or one row.
+//! See the sum() function for more details.
+template<typename T1>
+arma_hot
+inline
+void
+op_sum::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sum>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword dim = in.aux_uword_a;
+  arma_debug_check( (dim > 1), "sum(): incorrect usage. dim must be 0 or 1");
+  
+  const Proxy<T1> P(in.m);
+  
+  typedef typename Proxy<T1>::stored_type P_stored_type;
+  
+  const bool is_alias = P.is_alias(out);
+  
+  if( (is_Mat<P_stored_type>::value == true) || is_alias )
+    {
+    const unwrap_check<P_stored_type> tmp(P.Q, is_alias);
+    
+    const typename unwrap_check<P_stored_type>::stored_type& X = tmp.M;
+    
+    const uword X_n_rows = X.n_rows;
+    const uword X_n_cols = X.n_cols;
+    
+    if(dim == 0)  // traverse across rows (i.e. find the sum in each column)
+      {
+      out.set_size(1, X_n_cols);
+      
+      eT* out_mem = out.memptr();
+      
+      for(uword col=0; col < X_n_cols; ++col)
+        {
+        out_mem[col] = arrayops::accumulate( X.colptr(col), X_n_rows );
+        }
+      }
+    else  // traverse across columns (i.e. find the sum in each row)
+      {
+      out.set_size(X_n_rows, 1);
+      
+      eT* out_mem = out.memptr();
+        
+      for(uword row=0; row < X_n_rows; ++row)
+        {
+        eT val = eT(0);
+        
+        uword i,j;
+        for(i=0, j=1; j < X_n_cols; i+=2, j+=2)
+          {
+          val += X.at(row,i);
+          val += X.at(row,j);
+          }
+        
+        if(i < X_n_cols)
+          {
+          val += X.at(row,i);
+          }
+        
+        out_mem[row] = val;
+        }
+      }
+    }
+  else
+    {
+    const uword P_n_rows = P.get_n_rows();
+    const uword P_n_cols = P.get_n_cols();
+    
+    if(dim == 0)  // traverse across rows (i.e. find the sum in each column)
+      {
+      out.set_size(1, P_n_cols);
+      
+      eT* out_mem = out.memptr();
+      
+      for(uword col=0; col < P_n_cols; ++col)
+        {
+        eT val = eT(0);
+        
+        uword i,j;
+        for(i=0, j=1; j < P_n_rows; i+=2, j+=2)
+          {
+          val += P.at(i,col);
+          val += P.at(j,col);
+          }
+        
+        if(i < P_n_rows)
+          {
+          val += P.at(i,col);
+          }
+        
+        out_mem[col] = val;
+        }
+      }
+    else  // traverse across columns (i.e. find the sum in each row)
+      {
+      out.set_size(P_n_rows, 1);
+      
+      eT* out_mem = out.memptr();
+      
+      for(uword row=0; row < P_n_rows; ++row)
+        {
+        eT val = eT(0);
+        
+        uword i,j;
+        for(i=0, j=1; j < P_n_cols; i+=2, j+=2)
+          {
+          val += P.at(row,i);
+          val += P.at(row,j);
+          }
+        
+        if(i < P_n_cols)
+          {
+          val += P.at(row,i);
+          }
+        
+        out_mem[row] = val;
+        }
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_symmat_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,27 @@
+// Copyright (C) 2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_symmat
+//! @{
+
+
+
+class op_symmat
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_symmat>& in, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0);
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_symmat>& in, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_symmat_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,186 @@
+// Copyright (C) 2011-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2011-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_symmat
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+op_symmat::apply
+  (
+        Mat<typename T1::elem_type>& out,
+  const Op<T1,op_symmat>&            in,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   tmp(in.m);
+  const Mat<eT>& A = tmp.M;
+  
+  arma_debug_check( (A.is_square() == false), "symmatu()/symmatl(): given matrix must be square" );
+  
+  const uword N     = A.n_rows;
+  const bool  upper = (in.aux_uword_a == 0);
+  
+  if(&out != &A)
+    {
+    out.copy_size(A);
+    
+    if(upper)
+      {
+      // upper triangular: copy the diagonal and the elements above the diagonal
+      
+      for(uword i=0; i<N; ++i)
+        {
+        const eT* A_data   = A.colptr(i);
+              eT* out_data = out.colptr(i);
+        
+        arrayops::copy( out_data, A_data, i+1 );
+        }
+      }
+    else
+      {
+      // lower triangular: copy the diagonal and the elements below the diagonal
+      
+      for(uword i=0; i<N; ++i)
+        {
+        const eT* A_data   = A.colptr(i);
+              eT* out_data = out.colptr(i);
+        
+        arrayops::copy( &out_data[i], &A_data[i], N-i );
+        }
+      }
+    }
+  
+  
+  if(upper)
+    {
+    // reflect elements across the diagonal from upper triangle to lower triangle
+    
+    for(uword col=1; col < N; ++col)
+      {
+      const eT* coldata = out.colptr(col);
+      
+      for(uword row=0; row < col; ++row)
+        {
+        out.at(col,row) = coldata[row];
+        }
+      }
+    }
+  else
+    {
+    // reflect elements across the diagonal from lower triangle to upper triangle
+    
+    for(uword col=0; col < N; ++col)
+      {
+      const eT* coldata = out.colptr(col);
+      
+      for(uword row=(col+1); row < N; ++row)
+        {
+        out.at(col,row) = coldata[row];
+        }
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_symmat::apply
+  (
+        Mat<typename T1::elem_type>& out,
+  const Op<T1,op_symmat>&            in,
+  const typename arma_cx_only<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   tmp(in.m);
+  const Mat<eT>& A = tmp.M;
+  
+  arma_debug_check( (A.is_square() == false), "symmatu()/symmatl(): given matrix must be square" );
+  
+  const uword N     = A.n_rows;
+  const bool  upper = (in.aux_uword_a == 0);
+  
+  if(&out != &A)
+    {
+    out.copy_size(A);
+    
+    if(upper)
+      {
+      // upper triangular: copy the diagonal and the elements above the diagonal
+      
+      for(uword i=0; i<N; ++i)
+        {
+        const eT* A_data   = A.colptr(i);
+              eT* out_data = out.colptr(i);
+        
+        arrayops::copy( out_data, A_data, i+1 );
+        }
+      }
+    else
+      {
+      // lower triangular: copy the diagonal and the elements below the diagonal
+      
+      for(uword i=0; i<N; ++i)
+        {
+        const eT* A_data   = A.colptr(i);
+              eT* out_data = out.colptr(i);
+        
+        arrayops::copy( &out_data[i], &A_data[i], N-i );
+        }
+      }
+    }
+  
+  
+  if(upper)
+    {
+    // reflect elements across the diagonal from upper triangle to lower triangle
+    
+    for(uword col=1; col < N; ++col)
+      {
+      const eT* coldata = out.colptr(col);
+      
+      for(uword row=0; row < col; ++row)
+        {
+        out.at(col,row) = std::conj(coldata[row]);
+        }
+      }
+    }
+  else
+    {
+    // reflect elements across the diagonal from lower triangle to upper triangle
+    
+    for(uword col=0; col < N; ++col)
+      {
+      const eT* coldata = out.colptr(col);
+      
+      for(uword row=(col+1); row < N; ++row)
+        {
+        out.at(col,row) = std::conj(coldata[row]);
+        }
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_toeplitz_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,34 @@
+// Copyright (C) 2013 Conrad Sanderson
+// Copyright (C) 2013 NICTA (www.nicta.com.au)
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_toeplitz
+//! @{
+
+
+
+class op_toeplitz
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_toeplitz>& in);
+  };
+
+
+
+class op_toeplitz_c
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_toeplitz_c>& in);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_toeplitz_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,100 @@
+// Copyright (C) 2013 Conrad Sanderson
+// Copyright (C) 2013 NICTA (www.nicta.com.au)
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_toeplitz
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+op_toeplitz::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_toeplitz>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1>  tmp(in.m, out);
+  const Mat<eT>& X      = tmp.M;
+  
+  arma_debug_check( ((X.is_vec() == false) && (X.is_empty() == false)), "toeplitz(): given object is not a vector" );
+  
+  const uword N     = X.n_elem;
+  const eT*   X_mem = X.memptr();
+  
+  out.set_size(N,N);
+  
+  for(uword col=0; col < N; ++col)
+    {
+    eT* col_mem = out.colptr(col);
+    
+    uword i;
+    
+    i = col;
+    for(uword row=0; row < col; ++row, --i) { col_mem[row] = X_mem[i]; }
+    
+    i = 0;
+    for(uword row=col; row < N; ++row, ++i) { col_mem[row] = X_mem[i]; }      
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_toeplitz_c::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_toeplitz_c>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap_check<T1>  tmp(in.m, out);
+  const Mat<eT>& X      = tmp.M;
+  
+  arma_debug_check( ((X.is_vec() == false) && (X.is_empty() == false)), "circ_toeplitz(): given object is not a vector" );
+  
+  const uword N     = X.n_elem;
+  const eT*   X_mem = X.memptr();
+  
+  out.set_size(N,N);
+  
+  if(X.is_rowvec() == true)
+    {
+    for(uword row=0; row < N; ++row)
+      {
+      uword i;
+      
+      i = row;
+      for(uword col=0; col < row; ++col, --i)  { out.at(row,col) = X_mem[N-i]; }
+      
+      i = 0;
+      for(uword col=row; col < N; ++col, ++i)  { out.at(row,col) = X_mem[i];   }
+      }
+    }
+  else
+    {
+    for(uword col=0; col < N; ++col)
+      {
+      eT* col_mem = out.colptr(col);
+      
+      uword i;
+      
+      i = col;
+      for(uword row=0; row < col; ++row, --i)  { col_mem[row] = X_mem[N-i]; }
+      
+      i = 0;
+      for(uword row=col; row < N; ++row, ++i)  { col_mem[row] = X_mem[i];   }
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_trimat_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,41 @@
+// Copyright (C) 2010-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2012 Conrad Sanderson
+// Copyright (C) 2011 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_trimat
+//! @{
+
+
+
+class op_trimat
+  {
+  public:
+  
+  template<typename eT>
+  inline static void fill_zeros(Mat<eT>& A, const bool upper);
+  
+  //
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_trimat>& in);
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<Op<T1,op_htrans>, op_trimat>& in);
+  
+  //
+  
+  template<typename eT>
+  inline static void apply_htrans(Mat<eT>& out, const Mat<eT>& A, const bool upper, const typename arma_not_cx<eT>::result* junk = 0);
+  
+  template<typename eT>
+  inline static void apply_htrans(Mat<eT>& out, const Mat<eT>& A, const bool upper, const typename arma_cx_only<eT>::result* junk = 0);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_trimat_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,243 @@
+// Copyright (C) 2010-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2012 Conrad Sanderson
+// Copyright (C) 2011      Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_trimat
+//! @{
+
+
+
+template<typename eT>
+inline
+void
+op_trimat::fill_zeros(Mat<eT>& out, const bool upper)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword N = out.n_rows;
+  
+  if(upper)
+    {
+    // upper triangular: set all elements below the diagonal to zero
+    
+    for(uword i=0; i<N; ++i)
+      {
+      eT* data = out.colptr(i);
+      
+      arrayops::inplace_set( &data[i+1], eT(0), (N-(i+1)) );
+      }
+    }
+  else
+    {
+    // lower triangular: set all elements above the diagonal to zero
+    
+    for(uword i=1; i<N; ++i)
+      {
+      eT* data = out.colptr(i);
+      
+      arrayops::inplace_set( data, eT(0), i );
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_trimat::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_trimat>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   tmp(in.m);
+  const Mat<eT>& A = tmp.M;
+  
+  arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square" );
+  
+  const uword N     = A.n_rows;
+  const bool  upper = (in.aux_uword_a == 0);
+  
+  if(&out != &A)
+    {
+    out.copy_size(A);
+    
+    if(upper)
+      {
+      // upper triangular: copy the diagonal and the elements above the diagonal
+      for(uword i=0; i<N; ++i)
+        {
+        const eT* A_data   = A.colptr(i);
+              eT* out_data = out.colptr(i);
+        
+        arrayops::copy( out_data, A_data, i+1 );
+        }
+      }
+    else
+      {
+      // lower triangular: copy the diagonal and the elements below the diagonal
+      for(uword i=0; i<N; ++i)
+        {
+        const eT* A_data   = A.colptr(i);
+              eT* out_data = out.colptr(i);
+        
+        arrayops::copy( &out_data[i], &A_data[i], N-i );
+        }
+      }
+    }
+  
+  op_trimat::fill_zeros(out, upper);
+  }
+
+
+
+template<typename T1>
+inline
+void
+op_trimat::apply(Mat<typename T1::elem_type>& out, const Op<Op<T1, op_htrans>, op_trimat>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const unwrap<T1>   tmp(in.m.m);
+  const Mat<eT>& A = tmp.M;
+  
+  const bool upper = (in.aux_uword_a == 0);
+  
+  op_trimat::apply_htrans(out, A, upper);
+  }
+
+
+
+template<typename eT>
+inline
+void
+op_trimat::apply_htrans
+  (
+        Mat<eT>& out,
+  const Mat<eT>& A,
+  const bool     upper,
+  const typename arma_not_cx<eT>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  // This specialisation is for trimatl(trans(X)) = trans(trimatu(X)) and also
+  // trimatu(trans(X)) = trans(trimatl(X)).  We want to avoid the creation of an
+  // extra temporary.
+  
+  // It doesn't matter if the input and output matrices are the same; we will
+  // pull data from the upper or lower triangular to the lower or upper
+  // triangular (respectively) and then set the rest to 0, so overwriting issues
+  // aren't present.
+  
+  arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square" );
+  
+  const uword N = A.n_rows;
+  
+  if(&out != &A)
+    {
+    out.copy_size(A);
+    }
+  
+  // We can't really get away with any array copy operations here,
+  // unfortunately...
+  
+  if(upper)
+    {
+    // Upper triangular: but since we're transposing, we're taking the lower
+    // triangular and putting it in the upper half.
+    for(uword row = 0; row < N; ++row)
+      {
+      eT* out_colptr = out.colptr(row);
+      
+      for(uword col = 0; col <= row; ++col)
+        {
+        //out.at(col, row) = A.at(row, col);
+        out_colptr[col] = A.at(row, col);
+        }
+      }
+    }
+  else
+    {
+    // Lower triangular: but since we're transposing, we're taking the upper
+    // triangular and putting it in the lower half.
+    for(uword row = 0; row < N; ++row)
+      {
+      for(uword col = row; col < N; ++col)
+        {
+        out.at(col, row) = A.at(row, col);
+        }
+      }
+    }
+  
+  op_trimat::fill_zeros(out, upper);
+  }
+
+
+
+template<typename eT>
+inline
+void
+op_trimat::apply_htrans
+  (
+        Mat<eT>& out,
+  const Mat<eT>& A,
+  const bool     upper,
+  const typename arma_cx_only<eT>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square" );
+  
+  const uword N = A.n_rows;
+  
+  if(&out != &A)
+    {
+    out.copy_size(A);
+    }
+  
+  if(upper)
+    {
+    // Upper triangular: but since we're transposing, we're taking the lower
+    // triangular and putting it in the upper half.
+    for(uword row = 0; row < N; ++row)
+      {
+      eT* out_colptr = out.colptr(row);
+      
+      for(uword col = 0; col <= row; ++col)
+        {
+        //out.at(col, row) = std::conj( A.at(row, col) );
+        out_colptr[col] = std::conj( A.at(row, col) );
+        }
+      }
+    }
+  else
+    {
+    // Lower triangular: but since we're transposing, we're taking the upper
+    // triangular and putting it in the lower half.
+    for(uword row = 0; row < N; ++row)
+      {
+      for(uword col = row; col < N; ++col)
+        {
+        out.at(col, row) = std::conj( A.at(row, col) );
+        }
+      }
+    }
+  
+  op_trimat::fill_zeros(out, upper);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_unique_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,26 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// Copyright (C) 2012 Arnold Wiliem
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_unique
+//! @{
+
+
+
+class op_unique
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_unique>& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_unique_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,149 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// Copyright (C) 2012 Arnold Wiliem
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup op_unique
+//! @{
+
+
+
+// TODO: add an efficient implementation for complex numbers
+
+template<typename T1>
+inline
+void
+op_unique::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_unique>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const Proxy<T1> P(X.m);
+  
+  const uword in_n_rows = P.get_n_rows();
+  const uword in_n_cols = P.get_n_cols();
+  const uword in_n_elem = P.get_n_elem();
+  
+  
+  if(in_n_elem <= 1)
+    {
+    if(in_n_elem == 1)
+      {
+      const eT tmp = P[0];
+      
+      out.set_size(in_n_rows, in_n_cols);
+      
+      out[0] = tmp;
+      }
+    else
+      {
+      out.set_size(in_n_rows, in_n_cols);
+      }
+    
+    return;
+    }
+  
+  
+  std::vector<eT> lvec(in_n_elem);
+  
+  
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type Pea = P.get_ea();
+    
+    uword i,j;
+    for(i=0, j=1; j < in_n_elem; i+=2, j+=2)
+      {
+      const eT tmp_i = Pea[i];
+      const eT tmp_j = Pea[j];
+      
+      lvec[i] = tmp_i;
+      lvec[j] = tmp_j;
+      }
+    
+    if(i < in_n_elem)
+      {
+      lvec[i] = Pea[i];
+      }
+    }
+  else
+    {
+    uword i = 0;
+    
+    for(uword col=0; col < in_n_cols; ++col)
+    for(uword row=0; row < in_n_rows; ++row, ++i)
+      {
+      lvec[i] = P.at(row,col);
+      }
+    }
+  
+  std::sort( lvec.begin(), lvec.end() );
+  
+  uword N_unique = 1;
+  
+  for(uword i=1; i < in_n_elem; ++i)
+    {
+    const eT a = lvec[i-1];
+    const eT b = lvec[i  ];
+    
+    const eT diff = a - b;
+    
+    if(diff != eT(0)) { ++N_unique; }
+    }
+  
+  uword out_n_rows;
+  uword out_n_cols;
+  
+  if( (in_n_rows == 1) || (in_n_cols == 1) )
+    {
+    if(in_n_rows == 1)
+      {
+      out_n_rows = 1;
+      out_n_cols = N_unique;
+      }
+    else
+      {
+      out_n_rows = N_unique;
+      out_n_cols = 1;
+      }
+    }
+  else
+    {
+    out_n_rows = N_unique;
+    out_n_cols = 1;
+    }
+  
+  // we don't need to worry about aliasing at this stage, as all the data is stored in lvec
+  out.set_size(out_n_rows, out_n_cols);
+  
+  eT* out_mem = out.memptr();
+  
+  if(in_n_elem > 0) { out_mem[0] = lvec[0]; }
+  
+  N_unique = 1;
+  
+  for(uword i=1; i < in_n_elem; ++i)
+    {
+    const eT a = lvec[i-1];
+    const eT b = lvec[i  ];
+    
+    const eT diff = a - b;
+    
+    if(diff != eT(0))
+      {
+      out_mem[N_unique] = b;
+      ++N_unique;
+      }
+    }
+  
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_var_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,55 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_var
+//! @{
+
+
+
+//! Class for finding variance values of a matrix
+class op_var
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_var>& in);
+  
+  
+  //
+  
+  template<typename eT>
+  inline static typename get_pod_type<eT>::result var_vec(const subview_col<eT>& X, const uword norm_type = 0);
+
+  template<typename eT>
+  inline static typename get_pod_type<eT>::result var_vec(const subview_row<eT>& X, const uword norm_type = 0);
+  
+  template<typename T1>
+  inline static typename T1::pod_type var_vec(const Base<typename T1::elem_type, T1>& X, const uword norm_type = 0);
+  
+  
+  //
+  
+  template<typename eT>
+  inline static eT direct_var(const eT* const X, const uword N, const uword norm_type = 0);
+  
+  template<typename eT>
+  inline static eT direct_var_robust(const eT* const X, const uword N, const uword norm_type = 0);
+  
+  
+  //
+  
+  template<typename T>
+  inline static  T direct_var(const std::complex<T>* const X, const uword N, const uword norm_type = 0);
+  
+  template<typename T>
+  inline static  T direct_var_robust(const std::complex<T>* const X, const uword N, const uword norm_type = 0);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/op_var_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,302 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup op_var
+//! @{
+
+
+//! \brief
+//! For each row or for each column, find the variance.
+//! The result is stored in a dense matrix that has either one column or one row.
+//! The dimension, for which the variances are found, is set via the var() function.
+template<typename T1>
+inline
+void
+op_var::apply(Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_var>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type  in_eT;
+  typedef typename T1::pod_type  out_eT;
+  
+  const unwrap_check_mixed<T1> tmp(in.m, out);
+  const Mat<in_eT>&        X = tmp.M;
+  
+  const uword norm_type = in.aux_uword_a;
+  const uword dim       = in.aux_uword_b;
+  
+  arma_debug_check( (norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1");
+  arma_debug_check( (dim > 1),       "var(): incorrect usage. dim must be 0 or 1"      );
+  
+  const uword X_n_rows = X.n_rows;
+  const uword X_n_cols = X.n_cols;
+  
+  if(dim == 0)
+    {
+    arma_extra_debug_print("op_var::apply(), dim = 0");
+    
+    arma_debug_check( (X_n_rows == 0), "var(): given object has zero rows" );
+    
+    out.set_size(1, X_n_cols);
+    
+    out_eT* out_mem = out.memptr();
+    
+    for(uword col=0; col<X_n_cols; ++col)
+      {
+      out_mem[col] = op_var::direct_var( X.colptr(col), X_n_rows, norm_type );
+      }
+    }
+  else
+  if(dim == 1)
+    {
+    arma_extra_debug_print("op_var::apply(), dim = 1");
+    
+    arma_debug_check( (X_n_cols == 0), "var(): given object has zero columns" );
+    
+    out.set_size(X_n_rows, 1);
+    
+    podarray<in_eT> dat(X_n_cols);
+    
+    in_eT*  dat_mem = dat.memptr();
+    out_eT* out_mem = out.memptr();
+    
+    for(uword row=0; row<X_n_rows; ++row)
+      {
+      dat.copy_row(X, row);
+      
+      out_mem[row] = op_var::direct_var( dat_mem, X_n_cols, norm_type );
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::pod_type
+op_var::var_vec(const Base<typename T1::elem_type, T1>& X, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  arma_debug_check( (norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1");
+  
+  const Proxy<T1> P(X.get_ref());
+  
+  const podarray<eT> tmp(P);
+  
+  return op_var::direct_var(tmp.memptr(), tmp.n_elem, norm_type);
+  }
+
+
+
+template<typename eT>
+inline
+typename get_pod_type<eT>::result
+op_var::var_vec(const subview_col<eT>& X, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1");
+  
+  return op_var::direct_var(X.colptr(0), X.n_rows, norm_type);
+  }
+
+
+
+
+template<typename eT>
+inline
+typename get_pod_type<eT>::result
+op_var::var_vec(const subview_row<eT>& X, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( (norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1");
+  
+  const Mat<eT>& A = X.m;
+  
+  const uword start_row = X.aux_row1;
+  const uword start_col = X.aux_col1;
+  
+  const uword end_col_p1 = start_col + X.n_cols;
+  
+  podarray<eT> tmp(X.n_elem);
+  eT* tmp_mem = tmp.memptr();
+  
+  for(uword i=0, col=start_col; col < end_col_p1; ++col, ++i)
+    {
+    tmp_mem[i] = A.at(start_row, col);
+    }
+  
+  return op_var::direct_var(tmp.memptr(), tmp.n_elem, norm_type);
+  }
+
+
+
+//! find the variance of an array
+template<typename eT>
+inline
+eT
+op_var::direct_var(const eT* const X, const uword n_elem, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(n_elem >= 2)
+    {
+    const eT acc1 = op_mean::direct_mean(X, n_elem);
+    
+    eT acc2 = eT(0);
+    eT acc3 = eT(0);
+    
+    uword i,j;
+    
+    for(i=0, j=1; j<n_elem; i+=2, j+=2)
+      {
+      const eT Xi = X[i];
+      const eT Xj = X[j];
+      
+      const eT tmpi = acc1 - Xi;
+      const eT tmpj = acc1 - Xj;
+      
+      acc2 += tmpi*tmpi + tmpj*tmpj;
+      acc3 += tmpi      + tmpj;
+      }
+    
+    if(i < n_elem)
+      {
+      const eT Xi = X[i];
+      
+      const eT tmpi = acc1 - Xi;
+      
+      acc2 += tmpi*tmpi;
+      acc3 += tmpi;
+      }
+    
+    const eT norm_val = (norm_type == 0) ? eT(n_elem-1) : eT(n_elem);
+    const eT var_val  = (acc2 - acc3*acc3/eT(n_elem)) / norm_val;
+    
+    return arma_isfinite(var_val) ? var_val : op_var::direct_var_robust(X, n_elem, norm_type);
+    }
+  else
+    {
+    return eT(0);
+    }
+  }
+
+
+
+//! find the variance of an array (robust but slow)
+template<typename eT>
+inline
+eT
+op_var::direct_var_robust(const eT* const X, const uword n_elem, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(n_elem > 1)
+    {
+    eT r_mean = X[0];
+    eT r_var  = eT(0);
+    
+    for(uword i=1; i<n_elem; ++i)
+      {
+      const eT tmp      = X[i] - r_mean;
+      const eT i_plus_1 = eT(i+1);
+      
+      r_var  = eT(i-1)/eT(i) * r_var + (tmp*tmp)/i_plus_1;
+      
+      r_mean = r_mean + tmp/i_plus_1;
+      }
+    
+    return (norm_type == 0) ? r_var : (eT(n_elem-1)/eT(n_elem)) * r_var;
+    }
+  else
+    {
+    return eT(0);
+    }
+  }
+
+
+
+//! find the variance of an array (version for complex numbers)
+template<typename T>
+inline
+T
+op_var::direct_var(const std::complex<T>* const X, const uword n_elem, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<T> eT;
+  
+  if(n_elem >= 2)
+    {
+    const eT acc1 = op_mean::direct_mean(X, n_elem);
+    
+    T  acc2 =  T(0);
+    eT acc3 = eT(0);
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      const eT tmp = acc1 - X[i];
+      
+      acc2 += std::norm(tmp);
+      acc3 += tmp;
+      }
+    
+    const T norm_val = (norm_type == 0) ? T(n_elem-1) : T(n_elem);
+    const T var_val  = (acc2 - std::norm(acc3)/T(n_elem)) / norm_val;
+    
+    return arma_isfinite(var_val) ? var_val : op_var::direct_var_robust(X, n_elem, norm_type);
+    }
+  else
+    {
+    return T(0);
+    }
+  }
+
+
+
+//! find the variance of an array (version for complex numbers) (robust but slow)
+template<typename T>
+inline
+T
+op_var::direct_var_robust(const std::complex<T>* const X, const uword n_elem, const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<T> eT;
+  
+  if(n_elem > 1)
+    {
+    eT r_mean = X[0];
+     T r_var  = T(0);
+    
+    for(uword i=1; i<n_elem; ++i)
+      {
+      const eT tmp      = X[i] - r_mean;
+      const  T i_plus_1 = T(i+1);
+      
+      r_var  = T(i-1)/T(i) * r_var + std::norm(tmp)/i_plus_1;
+      
+      r_mean = r_mean + tmp/i_plus_1;
+      }
+    
+    return (norm_type == 0) ? r_var : (T(n_elem-1)/T(n_elem)) * r_var;
+    }
+  else
+    {
+    return T(0);
+    }
+  }
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/operator_cube_div.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,123 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup operator_cube_div
+//! @{
+
+  
+
+//! BaseCube / scalar
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_scalar_div_post>
+operator/
+  (
+  const BaseCube<typename T1::elem_type,T1>& X,
+  const typename T1::elem_type               k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_scalar_div_post>(X.get_ref(), k);
+  }
+
+
+
+//! scalar / BaseCube
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_scalar_div_pre>
+operator/
+  (
+  const typename T1::elem_type               k,
+  const BaseCube<typename T1::elem_type,T1>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_scalar_div_pre>(X.get_ref(), k);
+  }
+
+
+
+//! complex scalar / non-complex BaseCube (experimental)
+template<typename T1>
+arma_inline
+const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>
+operator/
+  (
+  const std::complex<typename T1::pod_type>& k,
+  const BaseCube<typename T1::pod_type, T1>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>('j', X.get_ref(), k);
+  }
+
+
+
+//! non-complex BaseCube / complex scalar (experimental)
+template<typename T1>
+arma_inline
+const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>
+operator/
+  (
+  const BaseCube<typename T1::pod_type, T1>& X,
+  const std::complex<typename T1::pod_type>& k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>('j', X.get_ref(), k);
+  }
+
+
+
+//! element-wise division of BaseCube objects with same element type
+template<typename T1, typename T2>
+arma_inline
+const eGlueCube<T1, T2, eglue_div>
+operator/
+  (
+  const BaseCube<typename T1::elem_type,T1>& X,
+  const BaseCube<typename T1::elem_type,T2>& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eGlueCube<T1, T2, eglue_div>(X.get_ref(), Y.get_ref());
+  }
+
+
+
+//! element-wise division of BaseCube objects with different element types
+template<typename T1, typename T2>
+inline
+const mtGlueCube<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_div>
+operator/
+  (
+  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T1_result, T1>& X,
+  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T2_result, T2>& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  return mtGlueCube<out_eT, T1, T2, glue_mixed_div>( X.get_ref(), Y.get_ref() );
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/operator_cube_minus.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,155 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup operator_cube_minus
+//! @{
+
+
+
+//! unary -
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_neg>
+operator-
+  (
+  const BaseCube<typename T1::elem_type,T1>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_neg>(X.get_ref());
+  }
+
+
+
+//! cancellation of two consecutive negations: -(-T1)
+template<typename T1>
+arma_inline
+const T1&
+operator-
+  (
+  const eOpCube<T1, eop_neg>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return X.m;
+  }
+
+
+
+//! BaseCube - scalar
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_scalar_minus_post>
+operator-
+  (
+  const BaseCube<typename T1::elem_type,T1>& X,
+  const typename T1::elem_type               k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_scalar_minus_post>(X.get_ref(), k);
+  }
+
+
+
+//! scalar - BaseCube
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_scalar_minus_pre>
+operator-
+  (
+  const typename T1::elem_type               k,
+  const BaseCube<typename T1::elem_type,T1>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_scalar_minus_pre>(X.get_ref(), k);
+  }
+
+
+
+//! complex scalar - non-complex BaseCube (experimental)
+template<typename T1>
+arma_inline
+const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>
+operator-
+  (
+  const std::complex<typename T1::pod_type>& k,
+  const BaseCube<typename T1::pod_type, T1>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>('j', X.get_ref(), k);
+  }
+
+
+
+//! non-complex BaseCube - complex scalar (experimental)
+template<typename T1>
+arma_inline
+const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>
+operator-
+  (
+  const BaseCube<typename T1::pod_type, T1>& X,
+  const std::complex<typename T1::pod_type>& k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>('j', X.get_ref(), k);
+  }
+
+
+
+//! subtraction of BaseCube objects with same element type
+template<typename T1, typename T2>
+arma_inline
+const eGlueCube<T1, T2, eglue_minus>
+operator-
+  (
+  const BaseCube<typename T1::elem_type,T1>& X,
+  const BaseCube<typename T1::elem_type,T2>& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eGlueCube<T1, T2, eglue_minus>(X.get_ref(), Y.get_ref());
+  }
+
+
+
+//! subtraction of BaseCube objects with different element types
+template<typename T1, typename T2>
+inline
+const mtGlueCube<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_minus>
+operator-
+  (
+  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T1_result, T1>& X,
+  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T2_result, T2>& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  return mtGlueCube<out_eT, T1, T2, glue_mixed_minus>( X.get_ref(), Y.get_ref() );
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/operator_cube_plus.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,139 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup operator_cube_plus
+//! @{
+
+
+
+//! unary plus operation (does nothing, but is required for completeness)
+template<typename T1>
+arma_inline
+const BaseCube<typename T1::elem_type,T1>&
+operator+
+  (
+  const BaseCube<typename T1::elem_type,T1>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return X;
+  }
+
+
+
+//! BaseCube + scalar
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_scalar_plus>
+operator+
+  (
+  const BaseCube<typename T1::elem_type,T1>& X,
+  const typename T1::elem_type               k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_scalar_plus>(X.get_ref(), k);
+  }
+
+
+
+//! scalar + BaseCube
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_scalar_plus>
+operator+
+  (
+  const typename T1::elem_type               k,
+  const BaseCube<typename T1::elem_type,T1>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_scalar_plus>(X.get_ref(), k);
+  }
+
+
+
+//! non-complex BaseCube + complex scalar (experimental)
+template<typename T1>
+arma_inline
+const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>
+operator+
+  (
+  const BaseCube<typename T1::pod_type, T1>& X,
+  const std::complex<typename T1::pod_type>& k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>('j', X.get_ref(), k);
+  }
+
+
+
+//! complex scalar + non-complex BaseCube (experimental)
+template<typename T1>
+arma_inline
+const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>
+operator+
+  (
+  const std::complex<typename T1::pod_type>& k,
+  const BaseCube<typename T1::pod_type, T1>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>('j', X.get_ref(), k);  // NOTE: order is swapped
+  }
+
+
+
+//! addition of BaseCube objects with same element type
+template<typename T1, typename T2>
+arma_inline
+const eGlueCube<T1, T2, eglue_plus>
+operator+
+  (
+  const BaseCube<typename T1::elem_type,T1>& X,
+  const BaseCube<typename T1::elem_type,T2>& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eGlueCube<T1, T2, eglue_plus>(X.get_ref(), Y.get_ref());
+  }
+
+
+
+//! addition of BaseCube objects with different element types
+template<typename T1, typename T2>
+inline
+const mtGlueCube<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_plus>
+operator+
+  (
+  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T1_result, T1>& X,
+  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T2_result, T2>& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  return mtGlueCube<out_eT, T1, T2, glue_mixed_plus>( X.get_ref(), Y.get_ref() );
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/operator_cube_relational.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,263 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup operator_cube_relational
+//! @{
+
+
+
+// <  : lt
+// >  : gt
+// <= : lteq
+// >= : gteq
+// == : eq
+// != : noteq
+
+
+
+template<typename T1, typename T2>
+inline
+const mtGlueCube<uword, T1, T2, glue_rel_lt>
+operator<
+(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T2>& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtGlueCube<uword, T1, T2, glue_rel_lt>( X.get_ref(), Y.get_ref() );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+const mtGlueCube<uword, T1, T2, glue_rel_gt>
+operator>
+(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T2>& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtGlueCube<uword, T1, T2, glue_rel_gt>( X.get_ref(), Y.get_ref() );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+const mtGlueCube<uword, T1, T2, glue_rel_lteq>
+operator<=
+(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T2>& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtGlueCube<uword, T1, T2, glue_rel_lteq>( X.get_ref(), Y.get_ref() );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+const mtGlueCube<uword, T1, T2, glue_rel_gteq>
+operator>=
+(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T2>& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtGlueCube<uword, T1, T2, glue_rel_gteq>( X.get_ref(), Y.get_ref() );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+const mtGlueCube<uword, T1, T2, glue_rel_eq>
+operator==
+(const BaseCube<typename T1::elem_type,T1>& X, const BaseCube<typename T1::elem_type,T2>& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtGlueCube<uword, T1, T2, glue_rel_eq>( X.get_ref(), Y.get_ref() );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+const mtGlueCube<uword, T1, T2, glue_rel_noteq>
+operator!=
+(const BaseCube<typename T1::elem_type,T1>& X, const BaseCube<typename T1::elem_type,T2>& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtGlueCube<uword, T1, T2, glue_rel_noteq>( X.get_ref(), Y.get_ref() );
+  }
+
+
+
+//
+//
+//
+
+
+
+template<typename T1>
+inline
+const mtOpCube<uword, T1, op_rel_lt_pre>
+operator<
+(const typename arma_not_cx<typename T1::elem_type>::result val, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<uword, T1, op_rel_lt_pre>(X.get_ref(), val);
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<uword, T1, op_rel_lt_post>
+operator<
+(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result val)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<uword, T1, op_rel_lt_post>(X.get_ref(), val);
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<uword, T1, op_rel_gt_pre>
+operator>
+(const typename arma_not_cx<typename T1::elem_type>::result val, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<uword, T1, op_rel_gt_pre>(X.get_ref(), val);
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<uword, T1, op_rel_gt_post>
+operator>
+(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result val)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<uword, T1, op_rel_gt_post>(X.get_ref(), val);
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<uword, T1, op_rel_lteq_pre>
+operator<=
+(const typename arma_not_cx<typename T1::elem_type>::result val, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<uword, T1, op_rel_lteq_pre>(X.get_ref(), val);
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<uword, T1, op_rel_lteq_post>
+operator<=
+(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result val)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<uword, T1, op_rel_lteq_post>(X.get_ref(), val);
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<uword, T1, op_rel_gteq_pre>
+operator>=
+(const typename arma_not_cx<typename T1::elem_type>::result val, const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<uword, T1, op_rel_gteq_pre>(X.get_ref(), val);
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<uword, T1, op_rel_gteq_post>
+operator>=
+(const BaseCube<typename arma_not_cx<typename T1::elem_type>::result,T1>& X, const typename arma_not_cx<typename T1::elem_type>::result val)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<uword, T1, op_rel_gteq_post>(X.get_ref(), val);
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<uword, T1, op_rel_eq>
+operator==
+(const typename T1::elem_type val, const BaseCube<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<uword, T1, op_rel_eq>(X.get_ref(), val);
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<uword, T1, op_rel_eq>
+operator==
+(const BaseCube<typename T1::elem_type,T1>& X, const typename T1::elem_type val)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<uword, T1, op_rel_eq>(X.get_ref(), val);
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<uword, T1, op_rel_noteq>
+operator!=
+(const typename T1::elem_type val, const BaseCube<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<uword, T1, op_rel_noteq>(X.get_ref(), val);
+  }
+
+
+
+template<typename T1>
+inline
+const mtOpCube<uword, T1, op_rel_noteq>
+operator!=
+(const BaseCube<typename T1::elem_type,T1>& X, const typename T1::elem_type val)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<uword, T1, op_rel_noteq>(X.get_ref(), val);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/operator_cube_schur.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,57 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup operator_cube_schur
+//! @{
+
+
+// operator %, which we define it to do a schur product (element-wise multiplication)
+
+
+//! element-wise multiplication of BaseCube objects with same element type
+template<typename T1, typename T2>
+arma_inline
+const eGlueCube<T1, T2, eglue_schur>
+operator%
+  (
+  const BaseCube<typename T1::elem_type,T1>& X,
+  const BaseCube<typename T1::elem_type,T2>& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eGlueCube<T1, T2, eglue_schur>(X.get_ref(), Y.get_ref());
+  }
+
+
+
+//! element-wise multiplication of BaseCube objects with different element types
+template<typename T1, typename T2>
+inline
+const mtGlueCube<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_schur>
+operator%
+  (
+  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T1_result, T1>& X,
+  const BaseCube< typename force_different_type<typename T1::elem_type, typename T2::elem_type>::T2_result, T2>& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  return mtGlueCube<out_eT, T1, T2, glue_mixed_schur>( X.get_ref(), Y.get_ref() );
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/operator_cube_times.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,84 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+
+//! \addtogroup operator_cube_times
+//! @{
+
+
+
+//! BaseCube * scalar
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_scalar_times>
+operator*
+  (
+  const BaseCube<typename T1::elem_type,T1>& X,
+  const typename T1::elem_type               k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_scalar_times>(X.get_ref(), k);
+  }
+
+
+
+//! scalar * BaseCube
+template<typename T1>
+arma_inline
+const eOpCube<T1, eop_scalar_times>
+operator*
+  (
+  const typename T1::elem_type               k,
+  const BaseCube<typename T1::elem_type,T1>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOpCube<T1, eop_scalar_times>(X.get_ref(), k);
+  }
+
+
+
+//! non-complex BaseCube * complex scalar (experimental)
+template<typename T1>
+arma_inline
+const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>
+operator*
+  (
+  const BaseCube<typename T1::pod_type, T1>& X,
+  const std::complex<typename T1::pod_type>& k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>('j', X.get_ref(), k);
+  }
+
+
+
+//! complex scalar * non-complex BaseCube (experimental)
+template<typename T1>
+arma_inline
+const mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>
+operator*
+  (
+  const std::complex<typename T1::pod_type>& k,
+  const BaseCube<typename T1::pod_type, T1>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOpCube<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>('j', X.get_ref(), k);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/operator_div.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,279 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup operator_div
+//! @{
+
+
+
+//! Base / scalar
+template<typename T1>
+arma_inline
+typename
+enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_scalar_div_post> >::result
+operator/
+  (
+  const T1&                    X,
+  const typename T1::elem_type k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_scalar_div_post>(X, k);
+  }
+
+
+
+//! scalar / Base
+template<typename T1>
+arma_inline
+typename
+enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_scalar_div_pre> >::result
+operator/
+  (
+  const typename T1::elem_type k,
+  const T1&                    X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_scalar_div_pre>(X, k);
+  }
+
+
+
+//! complex scalar / non-complex Base
+template<typename T1>
+arma_inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_complex<typename T1::elem_type>::value == false),
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>
+  >::result
+operator/
+  (
+  const std::complex<typename T1::pod_type>& k,
+  const T1&                                  X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>('j', X, k);
+  }
+
+
+
+//! non-complex Base / complex scalar
+template<typename T1>
+arma_inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_complex<typename T1::elem_type>::value == false),
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>
+  >::result
+operator/
+  (
+  const T1&                                  X,
+  const std::complex<typename T1::pod_type>& k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>('j', X, k);
+  }
+
+
+
+//! element-wise division of Base objects with same element type
+template<typename T1, typename T2>
+arma_inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  const eGlue<T1, T2, eglue_div>
+  >::result
+operator/
+  (
+  const T1& X,
+  const T2& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eGlue<T1, T2, eglue_div>(X, Y);
+  }
+
+
+
+//! element-wise division of Base objects with different element types
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_type<T2>::value && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value == false)),
+  const mtGlue<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_div>
+  >::result
+operator/
+  (
+  const T1& X,
+  const T2& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  return mtGlue<out_eT, T1, T2, glue_mixed_div>( X, Y );
+  }
+
+
+
+//! element-wise division of sparse matrix by scalar
+template<typename T1>
+inline
+typename
+enable_if2<is_arma_sparse_type<T1>::value, SpMat<typename T1::elem_type> >::result
+operator/
+  (
+  const T1&                    X,
+  const typename T1::elem_type y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  SpMat<typename T1::elem_type> result(X);
+  
+  result /= y;
+  
+  return result;
+  }
+
+
+
+//! element-wise division of one sparse and one dense object
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  SpMat<typename T1::elem_type>
+  >::result
+operator/
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const SpProxy<T1> pa(x);
+  const   Proxy<T2> pb(y);
+  
+  const uword n_rows = pa.get_n_rows();
+  const uword n_cols = pa.get_n_cols();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, pb.get_n_rows(), pb.get_n_cols(), "element-wise division");
+  
+  SpMat<eT> result(n_rows, n_cols);
+  
+  uword new_n_nonzero = 0;
+  
+  for(uword col=0; col < n_cols; ++col)
+  for(uword row=0; row < n_rows; ++row)
+    {
+    const eT val = pa.at(row,col) / pb.at(row, col);
+    
+    if(val != eT(0))
+      {
+      ++new_n_nonzero;
+      }
+    }
+  
+  result.mem_resize(new_n_nonzero);
+  
+  uword cur_pos = 0;
+  
+  for(uword col=0; col < n_cols; ++col)
+  for(uword row=0; row < n_rows; ++row)
+    {
+    const eT val = pa.at(row,col) / pb.at(row, col);
+    
+    if(val != eT(0))
+      {
+      access::rw(result.values[cur_pos]) = val;
+      access::rw(result.row_indices[cur_pos]) = row;
+      ++access::rw(result.col_ptrs[col + 1]);
+      ++cur_pos;
+      }
+    }
+  
+  // Fix column pointers
+  for(uword col = 1; col <= result.n_cols; ++col)
+    {
+    access::rw(result.col_ptrs[col]) += result.col_ptrs[col - 1];
+    }
+  
+  return result;
+  }
+
+
+
+//! element-wise division of one dense and one sparse object
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  Mat<typename T1::elem_type>
+  >::result
+operator/
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const   Proxy<T1> pa(x);
+  const SpProxy<T2> pb(y);
+  
+  const uword n_rows = pa.get_n_rows();
+  const uword n_cols = pa.get_n_cols();
+  
+  arma_debug_assert_same_size(n_rows, n_cols, pb.get_n_rows(), pb.get_n_cols(), "element-wise division");
+  
+  Mat<eT> result(n_rows, n_cols);
+  
+  for(uword col=0; col < n_cols; ++col)
+  for(uword row=0; row < n_rows; ++row)
+    {
+    result.at(row, col) = pa.at(row, col) / pb.at(row, col);
+    }
+  
+  return result;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/operator_minus.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,271 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup operator_minus
+//! @{
+
+
+
+//! unary -
+template<typename T1>
+arma_inline
+typename
+enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_neg> >::result
+operator-
+(const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1,eop_neg>(X);
+  }
+
+
+
+//! cancellation of two consecutive negations: -(-T1)
+template<typename T1>
+arma_inline
+const T1&
+operator-
+(const eOp<T1, eop_neg>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return X.m;
+  }
+
+
+
+//! Base - scalar
+template<typename T1>
+arma_inline
+typename
+enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_scalar_minus_post> >::result
+operator-
+  (
+  const T1&                    X,
+  const typename T1::elem_type k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_scalar_minus_post>(X, k);
+  }
+
+
+
+//! scalar - Base
+template<typename T1>
+arma_inline
+typename
+enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_scalar_minus_pre> >::result
+operator-
+  (
+  const typename T1::elem_type k,
+  const T1&                    X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_scalar_minus_pre>(X, k);
+  }
+
+
+
+//! complex scalar - non-complex Base
+template<typename T1>
+arma_inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_complex<typename T1::elem_type>::value == false),
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>
+  >::result
+operator-
+  (
+  const std::complex<typename T1::pod_type>& k,
+  const T1&                                  X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_pre>('j', X, k);
+  }
+
+
+
+//! non-complex Base - complex scalar
+template<typename T1>
+arma_inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_complex<typename T1::elem_type>::value == false),
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>
+  >::result
+operator-
+  (
+  const T1&                                  X,
+  const std::complex<typename T1::pod_type>& k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_minus_post>('j', X, k);
+  }
+
+
+
+//! subtraction of Base objects with same element type
+template<typename T1, typename T2>
+arma_inline
+typename
+enable_if2
+  <
+  is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value,
+  const eGlue<T1, T2, eglue_minus>
+  >::result
+operator-
+  (
+  const T1& X,
+  const T2& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eGlue<T1, T2, eglue_minus>(X, Y);
+  }
+
+
+
+//! subtraction of Base objects with different element types
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_type<T2>::value && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value == false)),
+  const mtGlue<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_minus>
+  >::result
+operator-
+  (
+  const T1& X,
+  const T2& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  return mtGlue<out_eT, T1, T2, glue_mixed_minus>( X, Y );
+  }
+
+
+
+//! subtraction of two sparse objects
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  const SpGlue<T1,T2,spglue_minus>
+  >::result
+operator-
+  (
+  const T1& X,
+  const T2& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpGlue<T1,T2,spglue_minus>(X,Y);
+  }
+
+
+
+//! subtraction of one sparse and one dense object
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  Mat<typename T1::elem_type>
+  >::result
+operator-
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> pa(x);
+  
+  Mat<typename T1::elem_type> result(-y);
+  
+  arma_debug_assert_same_size( pa.get_n_rows(), pa.get_n_cols(), result.n_rows, result.n_cols, "subtraction" );
+  
+  typename SpProxy<T1>::const_iterator_type it     = pa.begin();
+  typename SpProxy<T1>::const_iterator_type it_end = pa.end();
+  
+  while(it != it_end)
+    {
+    result.at(it.row(), it.col()) += (*it);
+    ++it;
+    }
+  
+  return result;
+  }
+
+
+
+//! subtraction of one dense and one sparse object
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  Mat<typename T1::elem_type>
+  >::result
+operator-
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<typename T1::elem_type> result(x);
+  
+  const SpProxy<T2> pb(y.get_ref());
+  
+  arma_debug_assert_same_size( result.n_rows, result.n_cols, pb.get_n_rows(), pb.get_n_cols(), "subtraction" );
+  
+  typename SpProxy<T2>::const_iterator_type it     = pb.begin();
+  typename SpProxy<T2>::const_iterator_type it_end = pb.end();
+
+  while(it != it_end)
+    {
+    result.at(it.row(), it.col()) -= (*it);
+    ++it;
+    }
+  
+  return result;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/operator_ostream.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,92 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup operator_ostream
+//! @{
+
+
+
+template<typename eT, typename T1>
+inline
+std::ostream&
+operator<< (std::ostream& o, const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap<T1> tmp(X.get_ref());
+  
+  arma_ostream::print(o, tmp.M, true);
+  
+  return o;
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+std::ostream&
+operator<< (std::ostream& o, const SpBase<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap_spmat<T1> tmp(X.get_ref());
+  
+  arma_ostream::print(o, tmp.M, true);
+  
+  return o;
+  }
+
+
+
+template<typename T1>
+inline
+std::ostream&
+operator<< (std::ostream& o, const BaseCube<typename T1::elem_type,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap_cube<T1> tmp(X.get_ref());
+  
+  arma_ostream::print(o, tmp.M, true);
+  
+  return o;
+  }
+
+
+
+//! Print the contents of a field to the specified stream.
+template<typename T1>
+inline
+std::ostream&
+operator<< (std::ostream& o, const field<T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_ostream::print(o, X);
+  
+  return o;
+  }
+
+
+
+//! Print the contents of a subfield to the specified stream
+template<typename T1>
+inline
+std::ostream&
+operator<< (std::ostream& o, const subview_field<T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_ostream::print(o, X);
+
+  return o;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/operator_plus.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,235 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup operator_plus
+//! @{
+
+
+
+//! unary plus operation (does nothing, but is required for completeness)
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const T1& >::result
+operator+
+(const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return X;
+  }
+
+
+
+//! Base + scalar
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_scalar_plus> >::result
+operator+
+(const T1& X, const typename T1::elem_type k)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_scalar_plus>(X, k);
+  }
+
+
+
+//! scalar + Base
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_scalar_plus> >::result
+operator+
+(const typename T1::elem_type k, const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_scalar_plus>(X, k);  // NOTE: order is swapped
+  }
+
+
+
+//! non-complex Base + complex scalar
+template<typename T1>
+arma_inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_complex<typename T1::elem_type>::value == false),
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>
+  >::result
+operator+
+  (
+  const T1&                                  X,
+  const std::complex<typename T1::pod_type>& k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>('j', X, k);
+  }
+
+
+
+//! complex scalar + non-complex Base
+template<typename T1>
+arma_inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_complex<typename T1::elem_type>::value == false),
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>
+  >::result
+operator+
+  (
+  const std::complex<typename T1::pod_type>& k,
+  const T1&                                  X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_plus>('j', X, k);  // NOTE: order is swapped
+  }
+
+
+
+//! addition of user-accessible Armadillo objects with same element type
+template<typename T1, typename T2>
+arma_inline
+typename
+enable_if2
+  <
+  is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value,
+  const eGlue<T1, T2, eglue_plus>
+  >::result
+operator+
+  (
+  const T1& X,
+  const T2& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eGlue<T1, T2, eglue_plus>(X, Y);
+  }
+
+
+
+//! addition of user-accessible Armadillo objects with different element types
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_type<T2>::value && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value == false)),
+  const mtGlue<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_plus>
+  >::result
+operator+
+  (
+  const T1& X,
+  const T2& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  return mtGlue<out_eT, T1, T2, glue_mixed_plus>( X, Y );
+  }
+
+
+
+//! addition of two sparse objects
+template<typename T1, typename T2>
+inline
+arma_hot
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  SpGlue<T1,T2,spglue_plus>
+  >::result
+operator+
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpGlue<T1,T2,spglue_plus>(x, y);
+  }
+
+
+
+//! addition of sparse and non-sparse object
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  Mat<typename T1::elem_type>
+  >::result
+operator+
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<typename T1::elem_type> result(x);
+  
+  const SpProxy<T2> pb(y);
+  
+  arma_debug_assert_same_size( result.n_rows, result.n_cols, pb.get_n_rows(), pb.get_n_cols(), "addition" );
+  
+  typename SpProxy<T2>::const_iterator_type it     = pb.begin();
+  typename SpProxy<T2>::const_iterator_type it_end = pb.end();
+  
+  while(it != it_end)
+    {
+    result.at(it.row(), it.col()) += (*it);
+    ++it;
+    }
+  
+  return result;
+  }
+
+
+
+//! addition of sparse and non-sparse object
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  Mat<typename T1::elem_type>
+  >::result
+operator+
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  // Just call the other order (these operations are commutative)
+  return (y + x);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/operator_relational.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,352 @@
+// Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup operator_relational
+//! @{
+
+
+// <  : lt
+// >  : gt
+// <= : lteq
+// >= : gteq
+// == : eq
+// != : noteq
+
+
+
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_type<T2>::value && (is_complex<typename T1::elem_type>::value == false) && (is_complex<typename T2::elem_type>::value == false)),
+  const mtGlue<uword, T1, T2, glue_rel_lt>
+  >::result
+operator<
+(const T1& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtGlue<uword, T1, T2, glue_rel_lt>( X, Y );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_type<T2>::value && (is_complex<typename T1::elem_type>::value == false) && (is_complex<typename T2::elem_type>::value == false)),
+  const mtGlue<uword, T1, T2, glue_rel_gt>
+  >::result
+operator>
+(const T1& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtGlue<uword, T1, T2, glue_rel_gt>( X, Y );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_type<T2>::value && (is_complex<typename T1::elem_type>::value == false) && (is_complex<typename T2::elem_type>::value == false)),
+  const mtGlue<uword, T1, T2, glue_rel_lteq>
+  >::result
+operator<=
+(const T1& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtGlue<uword, T1, T2, glue_rel_lteq>( X, Y );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_type<T2>::value && (is_complex<typename T1::elem_type>::value == false) && (is_complex<typename T2::elem_type>::value == false)),
+  const mtGlue<uword, T1, T2, glue_rel_gteq>
+  >::result
+operator>=
+(const T1& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtGlue<uword, T1, T2, glue_rel_gteq>( X, Y );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_type<T2>::value),
+  const mtGlue<uword, T1, T2, glue_rel_eq>
+  >::result
+operator==
+(const T1& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtGlue<uword, T1, T2, glue_rel_eq>( X, Y );
+  }
+
+
+
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_type<T2>::value),
+  const mtGlue<uword, T1, T2, glue_rel_noteq>
+  >::result
+operator!=
+(const T1& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtGlue<uword, T1, T2, glue_rel_noteq>( X, Y );
+  }
+
+
+
+//
+//
+//
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && (is_complex<typename T1::elem_type>::value == false)),
+  const mtOp<uword, T1, op_rel_lt_pre>
+  >::result
+operator<
+(const typename T1::elem_type val, const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<uword, T1, op_rel_lt_pre>(X, val);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && (is_complex<typename T1::elem_type>::value == false)),
+  const mtOp<uword, T1, op_rel_lt_post>
+  >::result
+operator<
+(const T1& X, const typename T1::elem_type val)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<uword, T1, op_rel_lt_post>(X, val);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && (is_complex<typename T1::elem_type>::value == false)),
+  const mtOp<uword, T1, op_rel_gt_pre>
+  >::result
+operator>
+(const typename T1::elem_type val, const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<uword, T1, op_rel_gt_pre>(X, val);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && (is_complex<typename T1::elem_type>::value == false)),
+  const mtOp<uword, T1, op_rel_gt_post>
+  >::result
+operator>
+(const T1& X, const typename T1::elem_type val)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<uword, T1, op_rel_gt_post>(X, val);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && (is_complex<typename T1::elem_type>::value == false)),
+  const mtOp<uword, T1, op_rel_lteq_pre>
+  >::result
+operator<=
+(const typename T1::elem_type val, const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<uword, T1, op_rel_lteq_pre>(X, val);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && (is_complex<typename T1::elem_type>::value == false)),
+  const mtOp<uword, T1, op_rel_lteq_post>
+  >::result
+operator<=
+(const T1& X, const typename T1::elem_type val)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<uword, T1, op_rel_lteq_post>(X, val);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && (is_complex<typename T1::elem_type>::value == false)),
+  const mtOp<uword, T1, op_rel_gteq_pre>
+  >::result
+operator>=
+(const typename T1::elem_type val, const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<uword, T1, op_rel_gteq_pre>(X, val);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && (is_complex<typename T1::elem_type>::value == false)),
+  const mtOp<uword, T1, op_rel_gteq_post>
+  >::result
+operator>=
+(const T1& X, const typename T1::elem_type val)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<uword, T1, op_rel_gteq_post>(X, val);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  is_arma_type<T1>::value,
+  const mtOp<uword, T1, op_rel_eq>
+  >::result
+operator==
+(const typename T1::elem_type val, const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<uword, T1, op_rel_eq>(X, val);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  is_arma_type<T1>::value,
+  const mtOp<uword, T1, op_rel_eq>
+  >::result
+operator==
+(const T1& X, const typename T1::elem_type val)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<uword, T1, op_rel_eq>(X, val);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  is_arma_type<T1>::value,
+  const mtOp<uword, T1, op_rel_noteq>
+  >::result
+operator!=
+(const typename T1::elem_type val, const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<uword, T1, op_rel_noteq>(X, val);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  is_arma_type<T1>::value,
+  const mtOp<uword, T1, op_rel_noteq>
+  >::result
+operator!=
+(const T1& X, const typename T1::elem_type val)
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<uword, T1, op_rel_noteq>(X, val);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/operator_schur.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,256 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup operator_schur
+//! @{
+
+
+// operator %, which we define it to do a schur product (element-wise multiplication)
+
+
+//! element-wise multiplication of user-accessible Armadillo objects with same element type
+template<typename T1, typename T2>
+arma_inline
+typename
+enable_if2
+  <
+  is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value,
+  const eGlue<T1, T2, eglue_schur>
+  >::result
+operator%
+  (
+  const T1& X,
+  const T2& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return eGlue<T1, T2, eglue_schur>(X, Y);
+  }
+
+
+
+//! element-wise multiplication of user-accessible Armadillo objects with different element types
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_type<T2>::value && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value == false)),
+  const mtGlue<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_schur>
+  >::result
+operator%
+  (
+  const T1& X,
+  const T2& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  return mtGlue<out_eT, T1, T2, glue_mixed_schur>( X, Y );
+  }
+
+
+
+//! element-wise multiplication of two sparse matrices
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  SpMat<typename T1::elem_type>
+  >::result
+operator%
+  (
+  const SpBase<typename T1::elem_type, T1>& x,
+  const SpBase<typename T2::elem_type, T2>& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+
+  const SpProxy<T1> pa(x.get_ref());
+  const SpProxy<T2> pb(y.get_ref());
+
+  arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "element-wise multiplication");
+
+  SpMat<typename T1::elem_type> result(pa.get_n_rows(), pa.get_n_cols());
+  
+  if( (pa.get_n_nonzero() != 0) && (pb.get_n_nonzero() != 0) )
+    {
+    // Resize memory to correct size.
+    result.mem_resize(n_unique(x, y, op_n_unique_mul()));
+    
+    // Now iterate across both matrices.
+    typename SpProxy<T1>::const_iterator_type x_it = pa.begin();
+    typename SpProxy<T2>::const_iterator_type y_it = pb.begin();
+    
+    typename SpProxy<T1>::const_iterator_type x_end = pa.end();
+    typename SpProxy<T2>::const_iterator_type y_end = pb.end();
+    
+    uword cur_val = 0;
+    while((x_it != x_end) || (y_it != y_end))
+      {
+      if(x_it == y_it)
+        {
+        const eT val = (*x_it) * (*y_it);
+        
+        if (val != eT(0))
+          {
+          access::rw(result.values[cur_val]) = val;
+          access::rw(result.row_indices[cur_val]) = x_it.row();
+          ++access::rw(result.col_ptrs[x_it.col() + 1]);
+          ++cur_val;
+          }
+        
+        ++x_it;
+        ++y_it;
+        }
+      else
+        {
+        const uword x_it_row = x_it.row();
+        const uword x_it_col = x_it.col();
+        
+        const uword y_it_row = y_it.row();
+        const uword y_it_col = y_it.col();
+        
+        if((x_it_col < y_it_col) || ((x_it_col == y_it_col) && (x_it_row < y_it_row))) // if y is closer to the end
+          {
+          ++x_it;
+          }
+        else
+          {
+          ++y_it;
+          }
+        }
+      }
+    
+    // Fix column pointers to be cumulative.
+    for(uword c = 1; c <= result.n_cols; ++c)
+      {
+      access::rw(result.col_ptrs[c]) += result.col_ptrs[c - 1];
+      }
+    }
+  
+  return result;
+  }
+
+
+
+//! element-wise multiplication of one dense and one sparse object
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  SpMat<typename T1::elem_type>
+  >::result
+operator%
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const   Proxy<T1> pa(x);
+  const SpProxy<T2> pb(y);
+  
+  arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "element-wise multiplication");
+  
+  SpMat<eT> result(pa.get_n_rows(), pa.get_n_cols());
+  
+  // count new size
+  uword new_n_nonzero = 0;
+  
+  typename SpProxy<T2>::const_iterator_type it     = pb.begin();
+  typename SpProxy<T2>::const_iterator_type it_end = pb.end();
+  
+  while(it != it_end)
+    {
+    if( ((*it) * pa.at(it.row(), it.col())) != eT(0) )
+      {
+      ++new_n_nonzero;
+      }
+    
+    ++it;
+    }
+  
+  // Resize memory accordingly.
+  result.mem_resize(new_n_nonzero);
+  
+  uword cur_val = 0;
+  
+  typename SpProxy<T2>::const_iterator_type it2 = pb.begin();
+  
+  while(it2 != it_end)
+    {
+    const uword it2_row = it2.row();
+    const uword it2_col = it2.col();
+    
+    const eT val = (*it2) * pa.at(it2_row, it2_col);
+    
+    if(val != eT(0))
+      {
+      access::rw(result.values[cur_val]) = val;
+      access::rw(result.row_indices[cur_val]) = it2_row;
+      ++access::rw(result.col_ptrs[it2_col + 1]);
+      ++cur_val;
+      }
+    
+    ++it2;
+    }
+  
+  // Fix column pointers.
+  for(uword c = 1; c <= result.n_cols; ++c)
+    {
+    access::rw(result.col_ptrs[c]) += result.col_ptrs[c - 1];
+    }
+  
+  return result;
+  }
+
+
+
+//! element-wise multiplication of one sparse and one dense object
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  SpMat<typename T1::elem_type>
+  >::result
+operator%
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  // This operation is commutative.
+  return (y % x);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/operator_times.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,547 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// Copyright (C) 2012 Ryan Curtin
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup operator_times
+//! @{
+
+
+
+//! Base * scalar
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_scalar_times> >::result
+operator*
+(const T1& X, const typename T1::elem_type k)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_scalar_times>(X,k);
+  }
+
+
+
+//! scalar * Base
+template<typename T1>
+arma_inline
+typename enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_scalar_times> >::result
+operator*
+(const typename T1::elem_type k, const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return eOp<T1, eop_scalar_times>(X,k);  // NOTE: order is swapped
+  }
+
+
+
+//! non-complex Base * complex scalar
+template<typename T1>
+arma_inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_complex<typename T1::elem_type>::value == false),
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>
+  >::result
+operator*
+  (
+  const T1&                                  X,
+  const std::complex<typename T1::pod_type>& k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>('j', X, k);
+  }
+
+
+
+//! complex scalar * non-complex Base
+template<typename T1>
+arma_inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_complex<typename T1::elem_type>::value == false),
+  const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>
+  >::result
+operator*
+  (
+  const std::complex<typename T1::pod_type>& k,
+  const T1&                                  X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_times>('j', X, k);
+  }
+
+
+
+//! scalar * trans(T1)
+template<typename T1>
+arma_inline
+const Op<T1, op_htrans2>
+operator*
+(const typename T1::elem_type k, const Op<T1, op_htrans>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_htrans2>(X.m, k);
+  }
+
+
+
+//! trans(T1) * scalar
+template<typename T1>
+arma_inline
+const Op<T1, op_htrans2>
+operator*
+(const Op<T1, op_htrans>& X, const typename T1::elem_type k)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Op<T1, op_htrans2>(X.m, k);
+  }
+
+
+
+//! Base * diagmat
+template<typename T1, typename T2>
+arma_inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  const Glue<T1, Op<T2, op_diagmat>, glue_times_diag>
+  >::result
+operator*
+(const T1& X, const Op<T2, op_diagmat>& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Glue<T1, Op<T2, op_diagmat>, glue_times_diag>(X, Y);
+  }
+
+
+
+//! diagmat * Base
+template<typename T1, typename T2>
+arma_inline
+typename
+enable_if2
+  <
+  (is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  const Glue<Op<T1, op_diagmat>, T2, glue_times_diag>
+  >::result
+operator*
+(const Op<T1, op_diagmat>& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Glue<Op<T1, op_diagmat>, T2, glue_times_diag>(X, Y);
+  }
+
+
+
+//! diagmat * diagmat
+template<typename T1, typename T2>
+inline
+Mat< typename promote_type<typename T1::elem_type, typename T2::elem_type>::result >
+operator*
+(const Op<T1, op_diagmat>& X, const Op<T2, op_diagmat>& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  const diagmat_proxy<T1> A(X.m);
+  const diagmat_proxy<T2> B(Y.m);
+  
+  arma_debug_assert_mul_size(A.n_elem, A.n_elem, B.n_elem, B.n_elem, "matrix multiplication");
+  
+  const uword N = A.n_elem;
+  
+  Mat<out_eT> out(N,N);
+  
+  out.zeros();
+  
+  for(uword i=0; i<N; ++i)
+    {
+    out.at(i,i) = upgrade_val<eT1,eT2>::apply( A[i] ) * upgrade_val<eT1,eT2>::apply( B[i] );
+    }
+  
+  return out;
+  }
+
+
+
+//! multiplication of Base objects with same element type
+template<typename T1, typename T2>
+arma_inline
+typename
+enable_if2
+  <
+  is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value,
+  const Glue<T1, T2, glue_times>
+  >::result
+operator*
+(const T1& X, const T2& Y)
+  {
+  arma_extra_debug_sigprint();
+  
+  return Glue<T1, T2, glue_times>(X, Y);
+  }
+
+
+
+//! multiplication of Base objects with different element types
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_type<T2>::value && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value == false)),
+  const mtGlue< typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_times >
+  >::result
+operator*
+  (
+  const T1& X,
+  const T2& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT1;
+  typedef typename T2::elem_type eT2;
+  
+  typedef typename promote_type<eT1,eT2>::result out_eT;
+  
+  promote_type<eT1,eT2>::check();
+  
+  return mtGlue<out_eT, T1, T2, glue_mixed_times>( X, Y );
+  }
+
+
+
+//! sparse multiplied by scalar
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  is_arma_sparse_type<T1>::value,
+  SpOp<T1,spop_scalar_times>
+  >::result
+operator*
+  (
+  const T1& X,
+  const typename T1::elem_type k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpOp<T1,spop_scalar_times>(X, k);
+  }
+
+
+
+template<typename T1>
+inline
+typename
+enable_if2
+  <
+  is_arma_sparse_type<T1>::value,
+  SpOp<T1,spop_scalar_times>
+  >::result
+operator*
+  (
+  const typename T1::elem_type k,
+  const T1& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpOp<T1,spop_scalar_times>(X, k);
+  }
+
+
+
+//! multiplication of two sparse objects
+template<typename T1, typename T2>
+inline
+arma_hot
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  const SpGlue<T1,T2,spglue_times>
+  >::result
+operator*
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+
+  return SpGlue<T1,T2,spglue_times>(x, y);
+  }
+
+
+
+//! convert "(sparse + sparse) * scalar" to specialised operation "scalar * (sparse + sparse)"
+template<typename T1, typename T2>
+inline
+const SpGlue<T1,T2,spglue_plus2>
+operator*
+  (
+  const SpGlue<T1,T2,spglue_plus>& X,
+  const typename T1::elem_type k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpGlue<T1,T2,spglue_plus2>(X.A, X.B, k);
+  }
+
+
+
+//! convert "scalar * (sparse + sparse)" to specialised operation 
+template<typename T1, typename T2>
+inline
+const SpGlue<T1,T2,spglue_plus2>
+operator*
+  (
+  const typename T1::elem_type k,
+  const SpGlue<T1,T2,spglue_plus>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpGlue<T1,T2,spglue_plus2>(X.A, X.B, k);
+  }
+
+
+
+//! convert "(sparse - sparse) * scalar" to specialised operation "scalar * (sparse - sparse)"
+template<typename T1, typename T2>
+inline
+const SpGlue<T1,T2,spglue_minus2>
+operator*
+  (
+  const SpGlue<T1,T2,spglue_minus>& X,
+  const typename T1::elem_type k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpGlue<T1,T2,spglue_minus2>(X.A, X.B, k);
+  }
+
+
+
+//! convert "scalar * (sparse - sparse)" to specialised operation 
+template<typename T1, typename T2>
+inline
+const SpGlue<T1,T2,spglue_minus2>
+operator*
+  (
+  const typename T1::elem_type k,
+  const SpGlue<T1,T2,spglue_minus>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpGlue<T1,T2,spglue_minus2>(X.A, X.B, k);
+  }
+
+
+
+//! convert "(sparse*sparse) * scalar" to specialised operation "scalar * (sparse*sparse)"
+template<typename T1, typename T2>
+inline
+const SpGlue<T1,T2,spglue_times2>
+operator*
+  (
+  const SpGlue<T1,T2,spglue_times>& X,
+  const typename T1::elem_type k
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpGlue<T1,T2,spglue_times2>(X.A, X.B, k);
+  }
+
+
+
+//! convert "scalar * (sparse*sparse)" to specialised operation
+template<typename T1, typename T2>
+inline
+const SpGlue<T1,T2,spglue_times2>
+operator*
+  (
+  const typename T1::elem_type k,
+  const SpGlue<T1,T2,spglue_times>& X
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpGlue<T1,T2,spglue_times2>(X.A, X.B, k);
+  }
+
+
+
+//! convert "(scalar*sparse) * sparse" to specialised operation "scalar * (sparse*sparse)"
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  is_arma_sparse_type<T2>::value,
+  const SpGlue<T1,T2,spglue_times2>
+  >::result
+operator*
+  (
+  const SpOp<T1,spop_scalar_times>& X,
+  const T2& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpGlue<T1,T2,spglue_times2>(X.m, Y, X.aux);
+  }
+
+
+
+//! convert "sparse * (scalar*sparse)" to specialised operation "scalar * (sparse*sparse)"
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  is_arma_sparse_type<T1>::value,
+  const SpGlue<T1,T2,spglue_times2>
+  >::result
+operator*
+  (
+  const T1& X,
+  const SpOp<T2,spop_scalar_times>& Y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  return SpGlue<T1,T2,spglue_times2>(X, Y.m, Y.aux);
+  }
+
+
+
+//! multiplication of one sparse and one dense object
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  Mat<typename T1::elem_type>
+  >::result
+operator*
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> pa(x);
+  const   Proxy<T2> pb(y);
+  
+  arma_debug_assert_mul_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "matrix multiplication");
+  
+  Mat<typename T1::elem_type> result(pa.get_n_rows(), pb.get_n_cols());
+  result.zeros();
+  
+  if( (pa.get_n_nonzero() > 0) && (pb.get_n_elem() > 0) )
+    {
+    typename SpProxy<T1>::const_iterator_type x_it     = pa.begin();
+    typename SpProxy<T1>::const_iterator_type x_it_end = pa.end();
+    
+    const uword result_n_cols = result.n_cols;
+      
+    while(x_it != x_it_end)
+      {
+      for(uword col = 0; col < result_n_cols; ++col)
+        {
+        result.at(x_it.row(), col) += (*x_it) * pb.at(x_it.col(), col);
+        }
+      
+      ++x_it;
+      }
+    }
+  
+  return result;
+  }
+
+
+
+//! multiplication of one dense and one sparse object
+template<typename T1, typename T2>
+inline
+typename
+enable_if2
+  <
+  (is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
+  Mat<typename T1::elem_type>
+  >::result
+operator*
+  (
+  const T1& x,
+  const T2& y
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  const   Proxy<T1> pa(x);
+  const SpProxy<T2> pb(y);
+  
+  arma_debug_assert_mul_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "matrix multiplication");
+  
+  Mat<typename T1::elem_type> result(pa.get_n_rows(), pb.get_n_cols());
+  result.zeros();
+  
+  if( (pa.get_n_elem() > 0) && (pb.get_n_nonzero() > 0) )
+    {
+    typename SpProxy<T2>::const_iterator_type y_col_it     = pb.begin();
+    typename SpProxy<T2>::const_iterator_type y_col_it_end = pb.end();
+    
+    const uword result_n_rows = result.n_rows;
+    
+    while(y_col_it != y_col_it_end)
+      {
+      for(uword row = 0; row < result_n_rows; ++row)
+        {
+        result.at(row, y_col_it.col()) += pa.at(row, y_col_it.row()) * (*y_col_it);
+        }
+      
+      ++y_col_it;
+      }
+    }
+  
+  return result;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/podarray_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,82 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup podarray
+//! @{
+
+
+
+struct podarray_prealloc_n_elem
+  {
+  static const uword val = 16;
+  };
+
+
+
+//! A lightweight array for POD types. For internal use only!
+template<typename eT>
+class podarray
+  {
+  public:
+  
+  arma_aligned const uword n_elem; //!< number of elements held
+  arma_aligned       eT*   mem;    //!< pointer to memory used by the object
+  
+  
+  protected:
+  //! internal memory, to avoid calling the 'new' operator for small amounts of memory.
+  arma_align_mem eT mem_local[ podarray_prealloc_n_elem::val ];
+  
+  
+  public:
+  
+  inline ~podarray();
+  inline  podarray();
+  
+  inline                 podarray (const podarray& x);
+  inline const podarray& operator=(const podarray& x);
+  
+  arma_inline explicit podarray(const uword new_N);
+  
+  arma_inline explicit podarray(const eT* X, const uword new_N);
+  
+  template<typename T1>
+  inline explicit podarray(const Proxy<T1>& P);
+  
+  arma_inline eT& operator[] (const uword i);
+  arma_inline eT  operator[] (const uword i) const;
+  
+  arma_inline eT& operator() (const uword i);
+  arma_inline eT  operator() (const uword i) const;
+  
+  inline void set_min_size(const uword min_n_elem);
+  
+  inline void set_size(const uword new_n_elem);
+  inline void reset();
+  
+  
+  inline void fill(const eT val);
+  
+  inline void zeros();
+  inline void zeros(const uword new_n_elem);
+  
+  arma_inline       eT* memptr();
+  arma_inline const eT* memptr() const;
+  
+  arma_hot inline void copy_row(const Mat<eT>& A, const uword row);
+  
+  
+  protected:
+  
+  inline void init_cold(const uword new_n_elem);
+  inline void init_warm(const uword new_n_elem);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/podarray_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,404 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup podarray
+//! @{
+
+
+template<typename eT>
+arma_hot
+inline
+podarray<eT>::~podarray()
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  if(n_elem > podarray_prealloc_n_elem::val )
+    {
+    memory::release( mem );
+    }
+  }
+
+
+
+template<typename eT>
+inline
+podarray<eT>::podarray()
+  : n_elem(0)
+  , mem   (0)
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+template<typename eT>
+inline
+podarray<eT>::podarray(const podarray& x)
+  : n_elem(x.n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword x_n_elem = x.n_elem;
+  
+  init_cold(x_n_elem);
+  
+  arrayops::copy( memptr(), x.memptr(), x_n_elem );
+  }
+
+
+
+template<typename eT>
+inline
+const podarray<eT>&
+podarray<eT>::operator=(const podarray& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(this != &x)
+    {
+    const uword x_n_elem = x.n_elem;
+    
+    init_warm(x_n_elem);
+    
+    arrayops::copy( memptr(), x.memptr(), x_n_elem );
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+arma_hot
+arma_inline
+podarray<eT>::podarray(const uword new_n_elem)
+  : n_elem(new_n_elem)
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold(new_n_elem);
+  }
+
+
+
+template<typename eT>
+arma_inline
+podarray<eT>::podarray(const eT* X, const uword new_n_elem)
+  : n_elem(new_n_elem)
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  init_cold(new_n_elem);
+  
+  arrayops::copy( memptr(), X, new_n_elem );
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+podarray<eT>::podarray(const Proxy<T1>& P)
+  : n_elem(P.get_n_elem())
+  {
+  arma_extra_debug_sigprint_this(this);
+  
+  const uword P_n_elem = P.get_n_elem();
+    
+  init_cold(P_n_elem);
+  
+  eT* out_mem = (*this).memptr();
+    
+  if(Proxy<T1>::prefer_at_accessor == false)
+    {
+    typename Proxy<T1>::ea_type A = P.get_ea();
+    
+    uword i,j;
+    for(i=0, j=1; j < P_n_elem; i+=2, j+=2)
+      {
+      const eT val_i = A[i];
+      const eT val_j = A[j];
+      
+      out_mem[i] = val_i;
+      out_mem[j] = val_j;
+      }
+    
+    if(i < P_n_elem)
+      {
+      out_mem[i] = A[i];
+      }
+    }
+  else
+    {
+    const uword P_n_rows = P.get_n_rows();
+    const uword P_n_cols = P.get_n_cols();
+    
+    if(P_n_rows != 1)
+      {
+      uword count = 0;
+      
+      for(uword col=0; col < P_n_cols; ++col)
+      for(uword row=0; row < P_n_rows; ++row, ++count)
+        {
+        out_mem[count] = P.at(row,col);
+        }
+      }
+    else
+      {
+      for(uword col=0; col < P_n_cols; ++col)
+        {
+        out_mem[col] = P.at(0,col);
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+podarray<eT>::operator[] (const uword i) const
+  {
+  return mem[i];
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT&
+podarray<eT>::operator[] (const uword i)
+  {
+  return access::rw(mem[i]);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+podarray<eT>::operator() (const uword i) const
+  {
+  arma_debug_check( (i >= n_elem), "podarray::operator(): index out of bounds");
+  
+  return mem[i];
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT&
+podarray<eT>::operator() (const uword i)
+  {
+  arma_debug_check( (i >= n_elem), "podarray::operator(): index out of bounds");
+  
+  return access::rw(mem[i]);
+  }
+
+
+
+template<typename eT>
+inline
+void
+podarray<eT>::set_min_size(const uword min_n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(min_n_elem > n_elem)
+    {  
+    init_warm(min_n_elem);
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+podarray<eT>::set_size(const uword new_n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  init_warm(new_n_elem);
+  }
+
+
+
+template<typename eT>
+inline
+void
+podarray<eT>::reset()
+  {
+  arma_extra_debug_sigprint();
+  
+  init_warm(0);
+  }
+
+
+
+template<typename eT>
+inline
+void
+podarray<eT>::fill(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  arrayops::inplace_set(memptr(), val, n_elem);
+  }
+
+
+
+template<typename eT>
+inline
+void
+podarray<eT>::zeros()
+  {
+  arma_extra_debug_sigprint();
+  
+  fill(eT(0));
+  }
+
+
+
+template<typename eT>
+inline
+void
+podarray<eT>::zeros(const uword new_n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  init_warm(new_n_elem);
+  
+  fill(eT(0));
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT*
+podarray<eT>::memptr()
+  {
+  return mem;
+  }
+
+
+
+template<typename eT>
+arma_inline
+const eT*
+podarray<eT>::memptr() const
+  {
+  return mem;
+  }
+
+
+
+template<typename eT>
+arma_hot
+inline
+void
+podarray<eT>::copy_row(const Mat<eT>& A, const uword row)
+  {
+  const uword cols = A.n_cols;
+  
+  // note: this function assumes that the podarray has been set to the correct size beforehand
+  eT* out = memptr();
+  
+  switch(cols)
+    {
+    default:
+      {
+      uword i,j;
+      for(i=0, j=1; j < cols; i+=2, j+=2)
+        {
+        const eT tmp_i = A.at(row, i);
+        const eT tmp_j = A.at(row, j);
+        
+        out[i] = tmp_i;
+        out[j] = tmp_j;
+        }
+      
+      if(i < cols)
+        {
+        out[i] = A.at(row, i);
+        }
+      }
+      break;
+    
+    case 8:  out[7] = A.at(row, 7);
+    case 7:  out[6] = A.at(row, 6);
+    case 6:  out[5] = A.at(row, 5);
+    case 5:  out[4] = A.at(row, 4);
+    case 4:  out[3] = A.at(row, 3);
+    case 3:  out[2] = A.at(row, 2);
+    case 2:  out[1] = A.at(row, 1);
+    case 1:  out[0] = A.at(row, 0);
+    case 0:  ;
+    }
+  }
+
+
+template<typename eT>
+arma_hot
+inline
+void
+podarray<eT>::init_cold(const uword new_n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(new_n_elem <= podarray_prealloc_n_elem::val )
+    {
+    mem = mem_local;
+    }
+  else
+    {
+    mem = memory::acquire<eT>(new_n_elem);
+    
+    arma_check_bad_alloc( (mem == 0), "arma::podarray: out of memory" );
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+podarray<eT>::init_warm(const uword new_n_elem)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(n_elem == new_n_elem)
+    {
+    return;
+    }
+    
+  if(n_elem > podarray_prealloc_n_elem::val )
+    {
+    memory::release( mem );
+    }
+  
+  if(new_n_elem <= podarray_prealloc_n_elem::val )
+    {
+    mem = mem_local;
+    }
+  else
+    {
+    mem = memory::acquire<eT>(new_n_elem);
+    
+    arma_check_bad_alloc( (mem == 0), "arma::podarray: out of memory" );
+    }
+  
+  access::rw(n_elem) = new_n_elem;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/promote_type.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,237 @@
+// Copyright (C) 2009-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup promote_type
+//! @{
+
+
+template<typename T1, typename T2>
+struct is_promotable
+  {
+  static const bool value = false;
+  typedef T1 result;
+  };
+
+
+struct is_promotable_ok
+  {
+  static const bool value = true;
+  };
+
+
+template<typename T> struct is_promotable<T,               T> : public is_promotable_ok { typedef T               result; };
+template<typename T> struct is_promotable<std::complex<T>, T> : public is_promotable_ok { typedef std::complex<T> result; };
+
+template<> struct is_promotable<std::complex<double>, std::complex<float> > : public is_promotable_ok { typedef std::complex<double> result; };
+template<> struct is_promotable<std::complex<double>, float>                : public is_promotable_ok { typedef std::complex<double> result; };
+template<> struct is_promotable<std::complex<float>,  double>               : public is_promotable_ok { typedef std::complex<double> result; };
+
+
+#if defined(ARMA_USE_U64S64)
+template<typename t> struct is_promotable<std::complex<t>, u64>    : public is_promotable_ok { typedef std::complex<t> result; };
+template<typename t> struct is_promotable<std::complex<t>, s64>    : public is_promotable_ok { typedef std::complex<t> result; };
+#endif
+#if defined(ARMA_ALLOW_LONG)
+template<typename t> struct is_promotable<std::complex<t>, ulng_t> : public is_promotable_ok { typedef std::complex<t> result; };
+template<typename t> struct is_promotable<std::complex<t>, slng_t> : public is_promotable_ok { typedef std::complex<t> result; };
+#endif
+template<typename T> struct is_promotable<std::complex<T>, s32>    : public is_promotable_ok { typedef std::complex<T> result; };
+template<typename T> struct is_promotable<std::complex<T>, u32>    : public is_promotable_ok { typedef std::complex<T> result; };
+template<typename T> struct is_promotable<std::complex<T>, s16>    : public is_promotable_ok { typedef std::complex<T> result; };
+template<typename T> struct is_promotable<std::complex<T>, u16>    : public is_promotable_ok { typedef std::complex<T> result; };
+template<typename T> struct is_promotable<std::complex<T>, s8>     : public is_promotable_ok { typedef std::complex<T> result; };
+template<typename T> struct is_promotable<std::complex<T>, u8>     : public is_promotable_ok { typedef std::complex<T> result; };
+
+
+template<> struct is_promotable<double, float > : public is_promotable_ok { typedef double result; };
+#if defined(ARMA_USE_U64S64)
+template<> struct is_promotable<double, s64   > : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<double, u64   > : public is_promotable_ok { typedef double result; };
+#endif
+#if defined(ARMA_ALLOW_LONG)
+template<> struct is_promotable<double, slng_t> : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<double, ulng_t> : public is_promotable_ok { typedef double result; };
+#endif
+template<> struct is_promotable<double, s32   > : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<double, u32   > : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<double, s16   > : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<double, u16   > : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<double, s8    > : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<double, u8    > : public is_promotable_ok { typedef double result; };
+
+#if defined(ARMA_USE_U64S64)
+template<> struct is_promotable<float, s64   > : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<float, u64   > : public is_promotable_ok { typedef float result; };
+#endif
+#if defined(ARMA_ALLOW_LONG)
+template<> struct is_promotable<float, slng_t> : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<float, ulng_t> : public is_promotable_ok { typedef float result; };
+#endif
+template<> struct is_promotable<float, s32   > : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<float, u32   > : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<float, s16   > : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<float, u16   > : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<float, s8    > : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<float, u8    > : public is_promotable_ok { typedef float result; };
+
+#if defined(ARMA_USE_U64S64)
+template<> struct is_promotable<u64, u32> : public is_promotable_ok { typedef u64 result; };
+template<> struct is_promotable<u64, u16> : public is_promotable_ok { typedef u64 result; };
+template<> struct is_promotable<u64, u8 > : public is_promotable_ok { typedef u64 result; };
+#endif
+
+#if defined(ARMA_USE_U64S64)
+template<> struct is_promotable<s64, u64> : public is_promotable_ok { typedef s64 result; };  // float ?  
+template<> struct is_promotable<s64, u32> : public is_promotable_ok { typedef s64 result; };
+template<> struct is_promotable<s64, s32> : public is_promotable_ok { typedef s64 result; };
+template<> struct is_promotable<s64, s16> : public is_promotable_ok { typedef s64 result; };
+template<> struct is_promotable<s64, u16> : public is_promotable_ok { typedef s64 result; };
+template<> struct is_promotable<s64, s8 > : public is_promotable_ok { typedef s64 result; };
+template<> struct is_promotable<s64, u8 > : public is_promotable_ok { typedef s64 result; };
+#endif
+
+template<> struct is_promotable<s32, u32> : public is_promotable_ok { typedef s32 result; };  // float ?  
+template<> struct is_promotable<s32, s16> : public is_promotable_ok { typedef s32 result; };
+template<> struct is_promotable<s32, u16> : public is_promotable_ok { typedef s32 result; };
+template<> struct is_promotable<s32, s8 > : public is_promotable_ok { typedef s32 result; };
+template<> struct is_promotable<s32, u8 > : public is_promotable_ok { typedef s32 result; };
+
+template<> struct is_promotable<u32, s16> : public is_promotable_ok { typedef s32 result; };  // float ?
+template<> struct is_promotable<u32, u16> : public is_promotable_ok { typedef u32 result; };
+template<> struct is_promotable<u32, s8 > : public is_promotable_ok { typedef s32 result; };  // float ?
+template<> struct is_promotable<u32, u8 > : public is_promotable_ok { typedef u32 result; };
+
+template<> struct is_promotable<s16, u16> : public is_promotable_ok { typedef s16 result; };  // s32 ?
+template<> struct is_promotable<s16, s8 > : public is_promotable_ok { typedef s16 result; };
+template<> struct is_promotable<s16, u8 > : public is_promotable_ok { typedef s16 result; };
+
+template<> struct is_promotable<u16, s8> : public is_promotable_ok { typedef s16 result; };  // s32 ?
+template<> struct is_promotable<u16, u8> : public is_promotable_ok { typedef u16 result; };
+
+template<> struct is_promotable<s8, u8> : public is_promotable_ok { typedef s8 result; };  // s16 ?
+
+
+
+
+//
+// mirrored versions
+
+template<typename T> struct is_promotable<T, std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
+
+template<> struct is_promotable<std::complex<float>, std::complex<double> > : public is_promotable_ok { typedef std::complex<double> result; };
+template<> struct is_promotable<float,               std::complex<double> > : public is_promotable_ok { typedef std::complex<double> result; };
+template<> struct is_promotable<double,              std::complex<float>  > : public is_promotable_ok { typedef std::complex<double> result; };
+
+#if defined(ARMA_USE_U64S64)
+template<typename T> struct is_promotable<s64,    std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
+template<typename T> struct is_promotable<u64,    std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
+#endif
+#if defined(ARMA_ALLOW_LONG)
+template<typename T> struct is_promotable<slng_t, std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
+template<typename T> struct is_promotable<ulng_t, std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
+#endif
+template<typename T> struct is_promotable<s32,    std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
+template<typename T> struct is_promotable<u32,    std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
+template<typename T> struct is_promotable<s16,    std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
+template<typename T> struct is_promotable<u16,    std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
+template<typename T> struct is_promotable<s8,     std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
+template<typename T> struct is_promotable<u8,     std::complex<T> > : public is_promotable_ok { typedef std::complex<T> result; };
+
+
+template<> struct is_promotable<float,  double> : public is_promotable_ok { typedef double result; };
+#if defined(ARMA_USE_U64S64)
+template<> struct is_promotable<s64,    double> : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<u64,    double> : public is_promotable_ok { typedef double result; };
+#endif
+#if defined(ARMA_ALLOW_LONG)
+template<> struct is_promotable<slng_t, double> : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<ulng_t, double> : public is_promotable_ok { typedef double result; };
+#endif
+template<> struct is_promotable<s32,    double> : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<u32,    double> : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<s16,    double> : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<u16,    double> : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<s8,     double> : public is_promotable_ok { typedef double result; };
+template<> struct is_promotable<u8,     double> : public is_promotable_ok { typedef double result; };
+
+#if defined(ARMA_USE_U64S64)
+template<> struct is_promotable<s64,    float> : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<u64,    float> : public is_promotable_ok { typedef float result; };
+#endif
+#if defined(ARMA_ALLOW_LONG)
+template<> struct is_promotable<slng_t, float> : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<ulng_t, float> : public is_promotable_ok { typedef float result; };
+#endif
+template<> struct is_promotable<s32,    float> : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<u32,    float> : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<s16,    float> : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<u16,    float> : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<s8,     float> : public is_promotable_ok { typedef float result; };
+template<> struct is_promotable<u8,     float> : public is_promotable_ok { typedef float result; };
+
+#if defined(ARMA_USE_U64S64)
+template<> struct is_promotable<u32, u64> : public is_promotable_ok { typedef u64 result; };
+template<> struct is_promotable<u16, u64> : public is_promotable_ok { typedef u64 result; };
+template<> struct is_promotable<u8,  u64> : public is_promotable_ok { typedef u64 result; };
+#endif
+
+#if defined(ARMA_USE_U64S64)
+template<> struct is_promotable<u64, s64> : public is_promotable_ok { typedef s64 result; };  // float ?  
+template<> struct is_promotable<u32, s64> : public is_promotable_ok { typedef s64 result; };
+template<> struct is_promotable<s16, s64> : public is_promotable_ok { typedef s64 result; };
+template<> struct is_promotable<u16, s64> : public is_promotable_ok { typedef s64 result; };
+template<> struct is_promotable<s8 , s64> : public is_promotable_ok { typedef s64 result; };
+template<> struct is_promotable<u8 , s64> : public is_promotable_ok { typedef s64 result; };
+#endif
+
+template<> struct is_promotable<u32, s32> : public is_promotable_ok { typedef s32 result; };  // float ?  
+template<> struct is_promotable<s16, s32> : public is_promotable_ok { typedef s32 result; };
+template<> struct is_promotable<u16, s32> : public is_promotable_ok { typedef s32 result; };
+template<> struct is_promotable<s8 , s32> : public is_promotable_ok { typedef s32 result; };
+template<> struct is_promotable<u8 , s32> : public is_promotable_ok { typedef s32 result; };
+
+template<> struct is_promotable<s16, u32> : public is_promotable_ok { typedef s32 result; };  // float ?
+template<> struct is_promotable<u16, u32> : public is_promotable_ok { typedef u32 result; };
+template<> struct is_promotable<s8 , u32> : public is_promotable_ok { typedef s32 result; };  // float ?
+template<> struct is_promotable<u8 , u32> : public is_promotable_ok { typedef u32 result; };
+
+template<> struct is_promotable<u16, s16> : public is_promotable_ok { typedef s16 result; };  // s32 ?
+template<> struct is_promotable<s8 , s16> : public is_promotable_ok { typedef s16 result; };
+template<> struct is_promotable<u8 , s16> : public is_promotable_ok { typedef s16 result; };
+
+template<> struct is_promotable<s8, u16> : public is_promotable_ok { typedef s16 result; };  // s32 ?
+template<> struct is_promotable<u8, u16> : public is_promotable_ok { typedef u16 result; };
+
+template<> struct is_promotable<u8, s8> : public is_promotable_ok { typedef s8 result; };  // s16 ?
+
+
+
+
+
+template<typename T1, typename T2>
+struct promote_type
+  {
+  inline static void check()
+    {
+    arma_type_check(( is_promotable<T1,T2>::value == false ));
+    }
+  
+  typedef typename is_promotable<T1,T2>::result result;
+  };
+
+
+
+template<typename T1, typename T2>
+struct eT_promoter
+  {
+  typedef typename promote_type<typename T1::elem_type, typename T2::elem_type>::result eT;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/restrictors.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,223 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup restrictors
+//! @{
+
+
+
+// structures for template based restrictions of input/output arguments
+// (part of the SFINAE approach)
+// http://en.wikipedia.org/wiki/SFINAE
+
+
+template<typename T> struct arma_scalar_only { };
+
+template<> struct arma_scalar_only<u8>     { typedef u8     result; };
+template<> struct arma_scalar_only<s8>     { typedef s8     result; };
+template<> struct arma_scalar_only<u16>    { typedef u16    result; };
+template<> struct arma_scalar_only<s16>    { typedef s16    result; };
+template<> struct arma_scalar_only<u32>    { typedef u32    result; };
+template<> struct arma_scalar_only<s32>    { typedef s32    result; };
+#if defined(ARMA_USE_U64S64)
+template<> struct arma_scalar_only<u64>    { typedef u64    result; };
+template<> struct arma_scalar_only<s64>    { typedef s64    result; };
+#endif
+template<> struct arma_scalar_only<float>  { typedef float  result; };
+template<> struct arma_scalar_only<double> { typedef double result; };
+#if defined(ARMA_ALLOW_LONG)
+template<> struct arma_scalar_only<ulng_t> { typedef ulng_t result; };
+template<> struct arma_scalar_only<slng_t> { typedef slng_t result; };
+#endif
+
+template<typename T>
+struct arma_scalar_only< std::complex<T> > { typedef std::complex<T> result; };
+
+
+
+template<typename T> struct arma_integral_only { };
+
+template<> struct arma_integral_only<u8>  { typedef u8  result; };
+template<> struct arma_integral_only<s8>  { typedef s8  result; };
+template<> struct arma_integral_only<u16> { typedef u16 result; };
+template<> struct arma_integral_only<s16> { typedef s16 result; };
+template<> struct arma_integral_only<u32> { typedef u32 result; };
+template<> struct arma_integral_only<s32> { typedef s32 result; };
+#if defined(ARMA_USE_U64S64)
+template<> struct arma_integral_only<u64> { typedef u64 result; };
+template<> struct arma_integral_only<s64> { typedef s64 result; };
+#endif
+#if defined(ARMA_ALLOW_LONG)
+template<> struct arma_integral_only<ulng_t> { typedef ulng_t result; };
+template<> struct arma_integral_only<slng_t> { typedef slng_t result; };
+#endif
+
+
+
+template<typename T> struct arma_unsigned_integral_only { };
+
+template<> struct arma_unsigned_integral_only<u8>     { typedef u8     result; };
+template<> struct arma_unsigned_integral_only<u16>    { typedef u16    result; };
+template<> struct arma_unsigned_integral_only<u32>    { typedef u32    result; };
+#if defined(ARMA_USE_U64S64)
+template<> struct arma_unsigned_integral_only<u64>    { typedef u64    result; };
+#endif
+#if defined(ARMA_ALLOW_LONG)
+template<> struct arma_unsigned_integral_only<ulng_t> { typedef ulng_t result; };
+#endif
+
+
+
+template<typename T> struct arma_signed_integral_only { };
+
+template<> struct arma_signed_integral_only<s8>     { typedef s8     result; };
+template<> struct arma_signed_integral_only<s16>    { typedef s16    result; };
+template<> struct arma_signed_integral_only<s32>    { typedef s32    result; };
+#if defined(ARMA_USE_U64S64)
+template<> struct arma_signed_integral_only<s64>    { typedef s64    result; };
+#endif
+#if defined(ARMA_ALLOW_LONG)
+template<> struct arma_signed_integral_only<slng_t> { typedef slng_t result; };
+#endif
+
+
+
+template<typename T> struct arma_signed_only { };
+
+template<> struct arma_signed_only<s8>     { typedef s8     result; };
+template<> struct arma_signed_only<s16>    { typedef s16    result; };
+template<> struct arma_signed_only<s32>    { typedef s32    result; };
+#if defined(ARMA_USE_U64S64)
+template<> struct arma_signed_only<s64>    { typedef s64    result; };
+#endif
+template<> struct arma_signed_only<float>  { typedef float  result; };
+template<> struct arma_signed_only<double> { typedef double result; };
+#if defined(ARMA_ALLOW_LONG)
+template<> struct arma_signed_only<slng_t> { typedef slng_t result; };
+#endif
+
+template<typename T> struct arma_signed_only< std::complex<T> > { typedef std::complex<T> result; };
+
+
+
+template<typename T> struct arma_real_only { };
+
+template<> struct arma_real_only<float>  { typedef float  result; };
+template<> struct arma_real_only<double> { typedef double result; };
+
+
+template<typename T> struct arma_real_or_cx_only { };
+
+template<> struct arma_real_or_cx_only< float >                { typedef float                result; };
+template<> struct arma_real_or_cx_only< double >               { typedef double               result; };
+template<> struct arma_real_or_cx_only< std::complex<float>  > { typedef std::complex<float>  result; };
+template<> struct arma_real_or_cx_only< std::complex<double> > { typedef std::complex<double> result; };
+
+
+
+template<typename T> struct arma_cx_only { };
+
+template<> struct arma_cx_only< std::complex<float>  > { typedef std::complex<float>  result; };
+template<> struct arma_cx_only< std::complex<double> > { typedef std::complex<double> result; };
+
+
+
+template<typename T> struct arma_not_cx                    { typedef T result; };
+template<typename T> struct arma_not_cx< std::complex<T> > { };
+
+
+
+template<typename T> struct arma_blas_type_only { };
+
+template<> struct arma_blas_type_only< float                > { typedef float                result; };
+template<> struct arma_blas_type_only< double               > { typedef double               result; };
+template<> struct arma_blas_type_only< std::complex<float>  > { typedef std::complex<float>  result; };
+template<> struct arma_blas_type_only< std::complex<double> > { typedef std::complex<double> result; };
+
+
+
+template<typename T> struct arma_not_blas_type { typedef T result; };
+
+template<> struct arma_not_blas_type< float                > {  };
+template<> struct arma_not_blas_type< double               > {  };
+template<> struct arma_not_blas_type< std::complex<float>  > {  };
+template<> struct arma_not_blas_type< std::complex<double> > {  };
+
+
+
+template<typename T> struct arma_op_rel_only { };
+
+template<> struct arma_op_rel_only< op_rel_lt_pre    > { typedef int result; };
+template<> struct arma_op_rel_only< op_rel_lt_post   > { typedef int result; };
+template<> struct arma_op_rel_only< op_rel_gt_pre    > { typedef int result; };
+template<> struct arma_op_rel_only< op_rel_gt_post   > { typedef int result; };
+template<> struct arma_op_rel_only< op_rel_lteq_pre  > { typedef int result; };
+template<> struct arma_op_rel_only< op_rel_lteq_post > { typedef int result; };
+template<> struct arma_op_rel_only< op_rel_gteq_pre  > { typedef int result; };
+template<> struct arma_op_rel_only< op_rel_gteq_post > { typedef int result; };
+template<> struct arma_op_rel_only< op_rel_eq        > { typedef int result; };
+template<> struct arma_op_rel_only< op_rel_noteq     > { typedef int result; };
+
+
+
+template<typename T> struct arma_not_op_rel { typedef int result; };
+
+template<> struct arma_not_op_rel< op_rel_lt_pre    > { };
+template<> struct arma_not_op_rel< op_rel_lt_post   > { };
+template<> struct arma_not_op_rel< op_rel_gt_pre    > { };
+template<> struct arma_not_op_rel< op_rel_gt_post   > { };
+template<> struct arma_not_op_rel< op_rel_lteq_pre  > { };
+template<> struct arma_not_op_rel< op_rel_lteq_post > { };
+template<> struct arma_not_op_rel< op_rel_gteq_pre  > { };
+template<> struct arma_not_op_rel< op_rel_gteq_post > { };
+template<> struct arma_not_op_rel< op_rel_eq        > { };
+template<> struct arma_not_op_rel< op_rel_noteq     > { };
+
+
+
+template<typename T> struct arma_glue_rel_only { };
+
+template<> struct arma_glue_rel_only< glue_rel_lt    > { typedef int result; };
+template<> struct arma_glue_rel_only< glue_rel_gt    > { typedef int result; };
+template<> struct arma_glue_rel_only< glue_rel_lteq  > { typedef int result; };
+template<> struct arma_glue_rel_only< glue_rel_gteq  > { typedef int result; };
+template<> struct arma_glue_rel_only< glue_rel_eq    > { typedef int result; };
+template<> struct arma_glue_rel_only< glue_rel_noteq > { typedef int result; };
+
+
+
+template<typename T> struct arma_Mat_Col_Row_only { };
+
+template<typename eT> struct arma_Mat_Col_Row_only< Mat<eT> > { typedef Mat<eT> result; };
+template<typename eT> struct arma_Mat_Col_Row_only< Col<eT> > { typedef Col<eT> result; };
+template<typename eT> struct arma_Mat_Col_Row_only< Row<eT> > { typedef Row<eT> result; };
+
+
+
+template<typename  T> struct arma_Cube_only             { };
+template<typename eT> struct arma_Cube_only< Cube<eT> > { typedef Cube<eT> result; };
+
+
+template<typename T> struct arma_SpMat_SpCol_SpRow_only { };
+
+template<typename eT> struct arma_SpMat_SpCol_SpRow_only< SpMat<eT> > { typedef SpMat<eT> result; };
+template<typename eT> struct arma_SpMat_SpCol_SpRow_only< SpCol<eT> > { typedef SpCol<eT> result; };
+template<typename eT> struct arma_SpMat_SpCol_SpRow_only< SpRow<eT> > { typedef SpRow<eT> result; };
+
+
+
+template<bool> struct enable_if       {                     };
+template<>     struct enable_if<true> { typedef int result; };
+
+
+template<bool, typename result_type > struct enable_if2                    {                             };
+template<      typename result_type > struct enable_if2<true, result_type> { typedef result_type result; };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/running_stat_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,108 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup running_stat
+//! @{
+
+
+
+template<typename eT>
+class arma_counter
+  {
+  public:
+  
+  inline ~arma_counter();
+  inline  arma_counter();
+  
+  inline const arma_counter& operator++();
+  inline void                operator++(int);
+  
+  inline void reset();
+  inline eT   value()         const;
+  inline eT   value_plus_1()  const;
+  inline eT   value_minus_1() const;
+  
+  
+  private:
+  
+  arma_aligned eT    d_count;
+  arma_aligned uword i_count;
+  };
+
+
+
+//! Class for keeping statistics of a continuously sampled process / signal.
+//! Useful if the storage of individual samples is not necessary or desired.
+//! Also useful if the number of samples is not known beforehand or exceeds 
+//! available memory.
+template<typename eT>
+class running_stat
+  {
+  public:
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  
+  inline ~running_stat();
+  inline  running_stat();
+  
+  inline void operator() (const T sample);
+  inline void operator() (const std::complex<T>& sample);
+  
+  inline void reset();
+  
+  inline eT mean() const;
+  
+  inline  T var   (const uword norm_type = 0) const;
+  inline  T stddev(const uword norm_type = 0) const;
+  
+  inline eT min()  const;
+  inline eT max()  const;
+  
+  inline T count() const;
+  
+  //
+  //
+  
+  private:
+  
+  arma_aligned arma_counter<T> counter;
+  
+  arma_aligned eT r_mean;
+  arma_aligned  T r_var;
+  
+  arma_aligned eT min_val;
+  arma_aligned eT max_val;
+  
+  arma_aligned  T min_val_norm;
+  arma_aligned  T max_val_norm;
+  
+  
+  friend class running_stat_aux;
+  };
+
+
+
+class running_stat_aux
+  {
+  public:
+  
+  template<typename eT>
+  inline static void update_stats(running_stat<eT>&               x,  const eT               sample);
+  
+  template<typename T>
+  inline static void update_stats(running_stat< std::complex<T> >& x, const T                sample);
+  
+  template<typename T>
+  inline static void update_stats(running_stat< std::complex<T> >& x, const std::complex<T>& sample);
+  
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/running_stat_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,420 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup running_stat
+//! @{
+
+
+
+template<typename eT>
+inline
+arma_counter<eT>::~arma_counter()
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+template<typename eT>
+inline
+arma_counter<eT>::arma_counter()
+  : d_count(   eT(0))
+  , i_count(uword(0))
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+template<typename eT>
+inline
+const arma_counter<eT>& 
+arma_counter<eT>::operator++()
+  {
+  if(i_count < ARMA_MAX_UWORD)
+    {
+    i_count++;
+    }
+  else
+    {
+    d_count += eT(ARMA_MAX_UWORD);
+    i_count  = 1;
+    }
+  
+  return *this;
+  }
+
+
+
+template<typename eT>
+inline
+void
+arma_counter<eT>::operator++(int)
+  {
+  operator++();
+  }
+
+
+
+template<typename eT>
+inline
+void
+arma_counter<eT>::reset()
+  {
+  d_count =    eT(0);
+  i_count = uword(0);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+arma_counter<eT>::value() const
+  {
+  return d_count + eT(i_count);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+arma_counter<eT>::value_plus_1() const
+  {
+  if(i_count < ARMA_MAX_UWORD)
+    {
+    return d_count + eT(i_count + 1);
+    }
+  else
+    {
+    return d_count + eT(ARMA_MAX_UWORD) + eT(1);
+    }
+  }
+
+
+
+template<typename eT>
+inline
+eT
+arma_counter<eT>::value_minus_1() const
+  {
+  if(i_count > 0)
+    {
+    return d_count + eT(i_count - 1);
+    }
+  else
+    {
+    return d_count - eT(1);
+    }
+  }
+
+
+
+//
+
+
+
+template<typename eT>
+running_stat<eT>::~running_stat()
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+template<typename eT>
+running_stat<eT>::running_stat()
+  : r_mean      (                          eT(0))
+  , r_var       (typename running_stat<eT>::T(0))
+  , min_val     (                          eT(0))
+  , max_val     (                          eT(0))
+  , min_val_norm(typename running_stat<eT>::T(0))
+  , max_val_norm(typename running_stat<eT>::T(0))
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+//! update statistics to reflect new sample
+template<typename eT>
+inline
+void
+running_stat<eT>::operator() (const typename running_stat<eT>::T sample)
+  {
+  arma_extra_debug_sigprint();
+  
+  if( arma_isfinite(sample) == false )
+    {
+    arma_warn(true, "running_stat: sample ignored as it is non-finite" );
+    return;
+    }
+  
+  running_stat_aux::update_stats(*this, sample);
+  }
+
+
+
+//! update statistics to reflect new sample (version for complex numbers)
+template<typename eT>
+inline
+void
+running_stat<eT>::operator() (const std::complex< typename running_stat<eT>::T >& sample)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_type_check(( is_same_type<eT, std::complex< typename running_stat<eT>::T > >::value == false ));
+  
+  if( arma_isfinite(sample) == false )
+    {
+    arma_warn(true, "running_stat: sample ignored as it is non-finite" );
+    return;
+    }
+  
+  running_stat_aux::update_stats(*this, sample);
+  }
+
+
+
+//! set all statistics to zero
+template<typename eT>
+inline
+void
+running_stat<eT>::reset()
+  {
+  arma_extra_debug_sigprint();
+  
+  // typedef typename running_stat<eT>::T T;
+  
+  counter.reset();
+  
+  r_mean       = eT(0);
+  r_var        =  T(0);
+  
+  min_val      = eT(0);
+  max_val      = eT(0);
+  
+  min_val_norm =  T(0);
+  max_val_norm =  T(0);
+  }
+
+
+
+//! mean or average value
+template<typename eT>
+inline
+eT
+running_stat<eT>::mean() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return r_mean;
+  }
+
+
+
+//! variance
+template<typename eT>
+inline
+typename running_stat<eT>::T
+running_stat<eT>::var(const uword norm_type) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const T N = counter.value();
+  
+  if(N > T(1))
+    {
+    if(norm_type == 0)
+      {
+      return r_var;
+      }
+    else
+      {
+      const T N_minus_1 = counter.value_minus_1();
+      return (N_minus_1/N) * r_var;
+      }
+    }
+  else
+    {
+    return T(0);
+    }
+  }
+
+
+
+//! standard deviation
+template<typename eT>
+inline
+typename running_stat<eT>::T
+running_stat<eT>::stddev(const uword norm_type) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return std::sqrt( (*this).var(norm_type) );
+  }
+
+
+
+//! minimum value
+template<typename eT>
+inline
+eT
+running_stat<eT>::min() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return min_val;
+  }
+
+
+
+//! maximum value
+template<typename eT>
+inline
+eT
+running_stat<eT>::max() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return max_val;
+  }
+
+
+
+//! number of samples so far
+template<typename eT>
+inline
+typename get_pod_type<eT>::result
+running_stat<eT>::count() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return counter.value();
+  }
+
+
+
+//! update statistics to reflect new sample
+template<typename eT>
+inline
+void
+running_stat_aux::update_stats(running_stat<eT>& x, const eT sample)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename running_stat<eT>::T T;
+  
+  const T N = x.counter.value();
+  
+  if(N > T(0))
+    {
+    if(sample < x.min_val)
+      {
+      x.min_val = sample;
+      }
+    
+    if(sample > x.max_val)
+      {
+      x.max_val = sample;
+      }
+    
+    const T  N_plus_1   = x.counter.value_plus_1();
+    const T  N_minus_1  = x.counter.value_minus_1();
+    
+    // note: variance has to be updated before the mean
+    
+    const eT tmp = sample - x.r_mean;
+    
+    x.r_var  = N_minus_1/N * x.r_var + (tmp*tmp)/N_plus_1;
+    
+    x.r_mean = x.r_mean + (sample - x.r_mean)/N_plus_1;
+    //x.r_mean = (N/N_plus_1)*x.r_mean + sample/N_plus_1;
+    //x.r_mean = (x.r_mean + sample/N) * N/N_plus_1;
+    }
+  else
+    {
+    x.r_mean  = sample;
+    x.min_val = sample;
+    x.max_val = sample;
+    
+    // r_var is initialised to zero
+    // in the constructor and reset()
+    }
+  
+  x.counter++;
+  }
+
+
+
+//! update statistics to reflect new sample (version for complex numbers)
+template<typename T>
+inline
+void
+running_stat_aux::update_stats(running_stat< std::complex<T> >& x, const T sample)
+  {
+  arma_extra_debug_sigprint();
+
+  running_stat_aux::update_stats(x, std::complex<T>(sample));
+  }
+
+
+
+//! alter statistics to reflect new sample (version for complex numbers)
+template<typename T>
+inline
+void
+running_stat_aux::update_stats(running_stat< std::complex<T> >& x, const std::complex<T>& sample)
+  {
+  arma_extra_debug_sigprint();
+  
+  const T sample_norm = std::norm(sample);
+  const T N           = x.counter.value();
+  
+  if(N > T(0))
+    {
+    if(sample_norm < x.min_val_norm)
+      {
+      x.min_val_norm = sample_norm;
+      x.min_val      = sample;
+      }
+    
+    if(sample_norm > x.max_val_norm)
+      {
+      x.max_val_norm = sample_norm;
+      x.max_val      = sample;
+      }
+    
+    const T  N_plus_1   = x.counter.value_plus_1();
+    const T  N_minus_1  = x.counter.value_minus_1();
+    
+    x.r_var = N_minus_1/N * x.r_var + std::norm(sample - x.r_mean)/N_plus_1;
+    
+    x.r_mean = x.r_mean + (sample - x.r_mean)/N_plus_1;
+    //x.r_mean = (N/N_plus_1)*x.r_mean + sample/N_plus_1;
+    //x.r_mean = (x.r_mean + sample/N) * N/N_plus_1;
+    }
+  else
+    {
+    x.r_mean       = sample;
+    x.min_val      = sample;
+    x.max_val      = sample;
+    x.min_val_norm = sample_norm;
+    x.max_val_norm = sample_norm;
+    
+    // r_var is initialised to zero
+    // in the constructor and reset()
+    }
+  
+  x.counter++;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/running_stat_vec_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,110 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup running_stat_vec
+//! @{
+
+
+
+//! Class for keeping statistics of a continuously sampled process / signal.
+//! Useful if the storage of individual samples is not necessary or desired.
+//! Also useful if the number of samples is not known beforehand or exceeds 
+//! available memory.
+template<typename eT>
+class running_stat_vec
+  {
+  public:
+  
+  typedef typename get_pod_type<eT>::result T;
+  
+  inline ~running_stat_vec();
+  inline  running_stat_vec(const bool in_calc_cov = false);
+  
+  inline running_stat_vec(const running_stat_vec& in_rsv);
+  
+  inline const running_stat_vec& operator=(const running_stat_vec& in_rsv);
+  
+  template<typename T1> arma_hot inline void operator() (const Base<               T,  T1>& X);
+  template<typename T1> arma_hot inline void operator() (const Base< std::complex<T>,  T1>& X);
+  
+  inline void reset();
+  
+  inline const Mat<eT>&  mean() const;
+  
+  inline const Mat< T>&  var   (const uword norm_type = 0);
+  inline       Mat< T>   stddev(const uword norm_type = 0) const;
+  inline const Mat<eT>&  cov   (const uword norm_type = 0);
+  
+  inline const Mat<eT>& min() const;
+  inline const Mat<eT>& max() const;
+  
+  inline T count() const;
+  
+  //
+  //
+  
+  private:
+  
+  const bool calc_cov;
+  
+  arma_aligned arma_counter<T> counter;
+  
+  arma_aligned Mat<eT> r_mean;
+  arma_aligned Mat< T> r_var;
+  arma_aligned Mat<eT> r_cov;
+  
+  arma_aligned Mat<eT> min_val;
+  arma_aligned Mat<eT> max_val;
+  
+  arma_aligned Mat< T> min_val_norm;
+  arma_aligned Mat< T> max_val_norm;
+  
+  arma_aligned Mat< T> r_var_dummy;
+  arma_aligned Mat<eT> r_cov_dummy;
+  
+  arma_aligned Mat<eT> tmp1;
+  arma_aligned Mat<eT> tmp2;
+  
+  friend class running_stat_vec_aux;
+  };
+
+
+
+class running_stat_vec_aux
+  {
+  public:
+  
+  template<typename eT>
+  inline static void update_stats(running_stat_vec< eT >&              x, const Mat<eT>&                sample);
+  
+  template<typename T>
+  inline static void update_stats(running_stat_vec< std::complex<T> >& x, const Mat< T>&                sample);
+  
+  template<typename T>
+  inline static void update_stats(running_stat_vec< std::complex<T> >& x, const Mat< std::complex<T> >& sample);
+  
+  //
+  
+  template<typename eT>
+  inline static Mat<eT> var(const running_stat_vec< eT >&              x, const uword norm_type = 0);
+  
+  template<typename T>
+  inline static Mat< T> var(const running_stat_vec< std::complex<T> >& x, const uword norm_type = 0);
+  
+  //
+  
+  template<typename eT>
+  inline static Mat<              eT > cov(const running_stat_vec< eT >&              x, const uword norm_type = 0);
+  
+  template<typename T>
+  inline static Mat< std::complex<T> > cov(const running_stat_vec< std::complex<T> >& x, const uword norm_type = 0);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/running_stat_vec_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,573 @@
+// Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup running_stat_vec
+//! @{
+
+
+
+template<typename eT>
+running_stat_vec<eT>::~running_stat_vec()
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+template<typename eT>
+running_stat_vec<eT>::running_stat_vec(const bool in_calc_cov)
+  : calc_cov(in_calc_cov)
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+template<typename eT>
+running_stat_vec<eT>::running_stat_vec(const running_stat_vec<eT>& in_rsv)
+  : calc_cov    (in_rsv.calc_cov)
+  , counter     (in_rsv.counter)
+  , r_mean      (in_rsv.r_mean)
+  , r_var       (in_rsv.r_var)
+  , r_cov       (in_rsv.r_cov)
+  , min_val     (in_rsv.min_val)
+  , max_val     (in_rsv.max_val)
+  , min_val_norm(in_rsv.min_val_norm)
+  , max_val_norm(in_rsv.max_val_norm)
+  {
+  arma_extra_debug_sigprint_this(this);
+  }
+
+
+
+template<typename eT>
+const running_stat_vec<eT>&
+running_stat_vec<eT>::operator=(const running_stat_vec<eT>& in_rsv)
+  {
+  arma_extra_debug_sigprint();
+  
+  access::rw(calc_cov) = in_rsv.calc_cov;
+  
+  counter      = in_rsv.counter;
+  r_mean       = in_rsv.r_mean;
+  r_var        = in_rsv.r_var;
+  r_cov        = in_rsv.r_cov;
+  min_val      = in_rsv.min_val;
+  max_val      = in_rsv.max_val;
+  min_val_norm = in_rsv.min_val_norm;
+  max_val_norm = in_rsv.max_val_norm;
+  
+  return *this;
+  }
+
+
+
+//! update statistics to reflect new sample
+template<typename eT>
+template<typename T1>
+arma_hot
+inline
+void
+running_stat_vec<eT>::operator() (const Base<typename get_pod_type<eT>::result, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  //typedef typename get_pod_type<eT>::result T;
+  
+  const unwrap<T1>        tmp(X.get_ref());
+  const Mat<eT>& sample = tmp.M;
+  
+  if( sample.is_empty() )
+    {
+    return;
+    }
+  
+  if( sample.is_finite() == false )
+    {
+    arma_warn(true, "running_stat_vec: sample ignored as it has non-finite elements");
+    return;
+    }
+  
+  running_stat_vec_aux::update_stats(*this, sample);
+  }
+
+
+
+//! update statistics to reflect new sample (version for complex numbers)
+template<typename eT>
+template<typename T1>
+arma_hot
+inline
+void
+running_stat_vec<eT>::operator() (const Base<std::complex<typename get_pod_type<eT>::result>, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  //typedef typename std::complex<typename get_pod_type<eT>::result> eT;
+  
+  const unwrap<T1>        tmp(X.get_ref());
+  const Mat<eT>& sample = tmp.M;
+  
+  if( sample.is_empty() )
+    {
+    return;
+    }
+  
+  if( sample.is_finite() == false )
+    {
+    arma_warn(true, "running_stat_vec: sample ignored as it has non-finite elements");
+    return;
+    }
+  
+  running_stat_vec_aux::update_stats(*this, sample);
+  }
+
+
+
+//! set all statistics to zero
+template<typename eT>
+inline
+void
+running_stat_vec<eT>::reset()
+  {
+  arma_extra_debug_sigprint();
+  
+  counter.reset();
+  
+  r_mean.reset();
+  r_var.reset();
+  r_cov.reset();
+  
+  min_val.reset();
+  max_val.reset();
+  
+  min_val_norm.reset();
+  max_val_norm.reset();
+  
+  r_var_dummy.reset();
+  r_cov_dummy.reset();
+  
+  tmp1.reset();
+  tmp2.reset();
+  }
+
+
+
+//! mean or average value
+template<typename eT>
+inline
+const Mat<eT>&
+running_stat_vec<eT>::mean() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return r_mean;
+  }
+
+
+
+//! variance
+template<typename eT>
+inline
+const Mat<typename get_pod_type<eT>::result>&
+running_stat_vec<eT>::var(const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  const T N = counter.value();
+  
+  if(N > T(1))
+    {
+    if(norm_type == 0)
+      {
+      return r_var;
+      }
+    else
+      {
+      const T N_minus_1 = counter.value_minus_1();
+      
+      r_var_dummy = (N_minus_1/N) * r_var;
+      
+      return r_var_dummy;
+      }
+    }
+  else
+    {
+    r_var_dummy.zeros(r_mean.n_rows, r_mean.n_cols);
+    
+    return r_var_dummy;
+    }
+  
+  }
+
+
+
+//! standard deviation
+template<typename eT>
+inline
+Mat<typename get_pod_type<eT>::result>
+running_stat_vec<eT>::stddev(const uword norm_type) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const T N = counter.value();
+  
+  if(N > T(1))
+    {
+    if(norm_type == 0)
+      {
+      return sqrt(r_var);
+      }
+    else
+      {
+      const T N_minus_1 = counter.value_minus_1();
+      
+      return sqrt( (N_minus_1/N) * r_var );
+      }
+    }
+  else
+    {
+    return Mat<T>();
+    }
+  }
+
+
+
+//! covariance
+template<typename eT>
+inline
+const Mat<eT>&
+running_stat_vec<eT>::cov(const uword norm_type)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(calc_cov == true)
+    {
+    const T N = counter.value();
+    
+    if(N > T(1))
+      {
+      if(norm_type == 0)
+        {
+        return r_cov;
+        }
+      else
+        {
+        const T N_minus_1 = counter.value_minus_1();
+        
+        r_cov_dummy = (N_minus_1/N) * r_cov;
+        
+        return r_cov_dummy;
+        }
+      }
+    else
+      {
+      r_cov_dummy.zeros(r_mean.n_rows, r_mean.n_cols);
+      
+      return r_cov_dummy;
+      }
+    }
+  else
+    {
+    r_cov_dummy.reset();
+    
+    return r_cov_dummy;
+    }
+  
+  }
+
+
+
+//! vector with minimum values
+template<typename eT>
+inline
+const Mat<eT>&
+running_stat_vec<eT>::min() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return min_val;
+  }
+
+
+
+//! vector with maximum values
+template<typename eT>
+inline
+const Mat<eT>&
+running_stat_vec<eT>::max() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return max_val;
+  }
+
+
+
+//! number of samples so far
+template<typename eT>
+inline
+typename get_pod_type<eT>::result
+running_stat_vec<eT>::count() const
+  {
+  arma_extra_debug_sigprint();
+  
+  return counter.value();
+  }
+
+
+
+//
+
+
+
+//! update statistics to reflect new sample
+template<typename eT>
+inline
+void
+running_stat_vec_aux::update_stats(running_stat_vec<eT>& x, const Mat<eT>& sample)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename running_stat_vec<eT>::T T;
+  
+  const T N = x.counter.value();
+  
+  if(N > T(0))
+    {
+    arma_debug_assert_same_size(x.r_mean, sample, "running_stat_vec(): dimensionality mismatch");
+    
+    const uword n_elem      = sample.n_elem;
+    const eT*   sample_mem  = sample.memptr();
+          eT*   r_mean_mem  = x.r_mean.memptr();
+           T*   r_var_mem   = x.r_var.memptr();
+          eT*   min_val_mem = x.min_val.memptr();
+          eT*   max_val_mem = x.max_val.memptr();
+    
+    const T  N_plus_1   = x.counter.value_plus_1();
+    const T  N_minus_1  = x.counter.value_minus_1();
+    
+    if(x.calc_cov == true)
+      {
+      Mat<eT>& tmp1 = x.tmp1;
+      Mat<eT>& tmp2 = x.tmp2;
+      
+      tmp1 = sample - x.r_mean;
+      
+      if(sample.n_cols == 1)
+        {
+        tmp2 = tmp1*trans(tmp1);
+        }
+      else
+        {
+        tmp2 = trans(tmp1)*tmp1;
+        }
+      
+      x.r_cov *= (N_minus_1/N);
+      x.r_cov += tmp2 / N_plus_1;
+      }
+    
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      const eT val = sample_mem[i];
+      
+      if(val < min_val_mem[i])
+        {
+        min_val_mem[i] = val;
+        }
+      
+      if(val > max_val_mem[i])
+        {
+        max_val_mem[i] = val;
+        }
+        
+      const eT r_mean_val = r_mean_mem[i];
+      const eT tmp        = val - r_mean_val;
+    
+      r_var_mem[i] = N_minus_1/N * r_var_mem[i] + (tmp*tmp)/N_plus_1;
+      
+      r_mean_mem[i] = r_mean_val + (val - r_mean_val)/N_plus_1;
+      }
+    }
+  else
+    {
+    arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector");
+    
+    x.r_mean.set_size(sample.n_rows, sample.n_cols);
+    
+    x.r_var.zeros(sample.n_rows, sample.n_cols);
+    
+    if(x.calc_cov == true)
+      {
+      x.r_cov.zeros(sample.n_elem, sample.n_elem);
+      }
+    
+    x.min_val.set_size(sample.n_rows, sample.n_cols);
+    x.max_val.set_size(sample.n_rows, sample.n_cols);
+    
+    
+    const uword n_elem      = sample.n_elem;
+    const eT*   sample_mem  = sample.memptr();
+          eT*   r_mean_mem  = x.r_mean.memptr();
+          eT*   min_val_mem = x.min_val.memptr();
+          eT*   max_val_mem = x.max_val.memptr();
+          
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      const eT val = sample_mem[i];
+      
+      r_mean_mem[i]  = val;
+      min_val_mem[i] = val;
+      max_val_mem[i] = val;
+      }
+    }
+  
+  x.counter++;
+  }
+
+
+
+//! update statistics to reflect new sample (version for complex numbers)
+template<typename T>
+inline
+void
+running_stat_vec_aux::update_stats(running_stat_vec< std::complex<T> >& x, const Mat<T>& sample)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat< std::complex<T> > tmp = conv_to< Mat< std::complex<T> > >::from(sample);
+  
+  running_stat_vec_aux::update_stats(x, tmp);
+  }
+
+
+
+//! alter statistics to reflect new sample (version for complex numbers)
+template<typename T>
+inline
+void
+running_stat_vec_aux::update_stats(running_stat_vec< std::complex<T> >& x, const Mat< std::complex<T> >& sample)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename std::complex<T> eT;
+  
+  const T N = x.counter.value();
+  
+  if(N > T(0))
+    {
+    arma_debug_assert_same_size(x.r_mean, sample, "running_stat_vec(): dimensionality mismatch");
+    
+    const uword n_elem           = sample.n_elem;
+    const eT*   sample_mem       = sample.memptr();
+          eT*   r_mean_mem       = x.r_mean.memptr();
+           T*   r_var_mem        = x.r_var.memptr();
+          eT*   min_val_mem      = x.min_val.memptr();
+          eT*   max_val_mem      = x.max_val.memptr();
+           T*   min_val_norm_mem = x.min_val_norm.memptr();
+           T*   max_val_norm_mem = x.max_val_norm.memptr();
+    
+    const T  N_plus_1   = x.counter.value_plus_1();
+    const T  N_minus_1  = x.counter.value_minus_1();
+    
+    if(x.calc_cov == true)
+      {
+      Mat<eT>& tmp1 = x.tmp1;
+      Mat<eT>& tmp2 = x.tmp2;
+      
+      tmp1 = sample - x.r_mean;
+      
+      if(sample.n_cols == 1)
+        {
+        tmp2 = arma::conj(tmp1)*strans(tmp1);
+        }
+      else
+        {
+        tmp2 = trans(tmp1)*tmp1;  //tmp2 = strans(conj(tmp1))*tmp1;
+        }
+      
+      x.r_cov *= (N_minus_1/N);
+      x.r_cov += tmp2 / N_plus_1;
+      }
+    
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      const eT& val      = sample_mem[i];
+      const  T  val_norm = std::norm(val);
+      
+      if(val_norm < min_val_norm_mem[i])
+        {
+        min_val_norm_mem[i] = val_norm;
+        min_val_mem[i]      = val;
+        }
+      
+      if(val_norm > max_val_norm_mem[i])
+        {
+        max_val_norm_mem[i] = val_norm;
+        max_val_mem[i]      = val;
+        }
+      
+      const eT& r_mean_val = r_mean_mem[i];
+      
+      r_var_mem[i] = N_minus_1/N * r_var_mem[i] + std::norm(val - r_mean_val)/N_plus_1;
+      
+      r_mean_mem[i] = r_mean_val + (val - r_mean_val)/N_plus_1;
+      }
+    
+    }
+  else
+    {
+    arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector");
+    
+    x.r_mean.set_size(sample.n_rows, sample.n_cols);
+    
+    x.r_var.zeros(sample.n_rows, sample.n_cols);
+    
+    if(x.calc_cov == true)
+      {
+      x.r_cov.zeros(sample.n_elem, sample.n_elem);
+      }
+    
+    x.min_val.set_size(sample.n_rows, sample.n_cols);
+    x.max_val.set_size(sample.n_rows, sample.n_cols);
+    
+    x.min_val_norm.set_size(sample.n_rows, sample.n_cols);
+    x.max_val_norm.set_size(sample.n_rows, sample.n_cols);
+    
+    
+    const uword n_elem           = sample.n_elem;
+    const eT*   sample_mem       = sample.memptr();
+          eT*   r_mean_mem       = x.r_mean.memptr();
+          eT*   min_val_mem      = x.min_val.memptr();
+          eT*   max_val_mem      = x.max_val.memptr();
+           T*   min_val_norm_mem = x.min_val_norm.memptr();
+           T*   max_val_norm_mem = x.max_val_norm.memptr();
+    
+    for(uword i=0; i<n_elem; ++i)
+      {
+      const eT& val      = sample_mem[i];
+      const  T  val_norm = std::norm(val);
+      
+      r_mean_mem[i]  = val;
+      min_val_mem[i] = val;
+      max_val_mem[i] = val;
+      
+      min_val_norm_mem[i] = val_norm;
+      max_val_norm_mem[i] = val_norm;
+      }
+    }
+  
+  x.counter++;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/span.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,84 @@
+// Copyright (C) 2010-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2012 Conrad Sanderson
+// Copyright (C) 2011 Stanislav Funiak
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+//! \addtogroup span
+//! @{
+
+
+struct span_alt {};
+
+
+template<typename Dummy = int>
+class span_base
+  {
+  public:
+  static const span_alt all;
+  };
+
+
+template<typename Dummy>
+const span_alt span_base<Dummy>::all = span_alt();
+
+
+class span : public span_base<>
+  {
+  public:
+
+  uword a;
+  uword b;
+  bool  whole;
+  
+  inline
+  span()
+    : whole(true)
+    {
+    }
+  
+  
+  inline
+  span(const span_alt&)
+    : whole(true)
+    {
+    }
+  
+  // TODO:
+  // if the "explicit" keyword is removed or commented out,
+  // the compiler will be able to automatically convert integers to an instance of the span class.
+  // this is useful for Cube::operator()(span&, span&, span&),
+  // but it might have unintended consequences or interactions elsewhere.
+  // as such, removal of "explicit" needs thorough testing.
+  inline
+  explicit
+  span(const uword in_a)
+    : a(in_a)
+    , b(in_a)
+    , whole(false)
+    {
+    }
+  
+  
+  #if defined(ARMA_USE_CXX11)
+    span(const double in_a) = delete;
+  #endif
+  
+  
+  inline
+  span(const uword in_a, const uword in_b)
+    : a(in_a)
+    , b(in_b)
+    , whole(false)
+    {
+    }
+
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spglue_minus_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,37 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spglue_minus
+//! @{
+
+
+
+class spglue_minus
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  arma_hot inline static void apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_minus>& X);
+  
+  template<typename eT, typename T1, typename T2>
+  arma_hot inline static void apply_noalias(SpMat<eT>& result, const SpProxy<T1>& pa, const SpProxy<T2>& pb);
+  };
+
+
+
+class spglue_minus2
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  arma_hot inline static void apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_minus2>& X);
+  };
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spglue_minus_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,175 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spglue_minus
+//! @{
+
+
+
+template<typename T1, typename T2>
+inline
+void
+spglue_minus::apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_minus>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const SpProxy<T1> pa(X.A);
+  const SpProxy<T2> pb(X.B);
+  
+  const bool is_alias = pa.is_alias(out) || pb.is_alias(out);
+  
+  if(is_alias == false)
+    {
+    spglue_minus::apply_noalias(out, pa, pb);
+    }
+  else
+    {
+    SpMat<eT> tmp;
+    spglue_minus::apply_noalias(tmp, pa, pb);
+    
+    out.steal_mem(tmp);
+    }
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+arma_hot
+inline
+void
+spglue_minus::apply_noalias(SpMat<eT>& result, const SpProxy<T1>& pa, const SpProxy<T2>& pb)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "subtraction");
+  
+  if( (pa.get_n_nonzero() != 0) && (pb.get_n_nonzero() != 0) )
+    {
+    result.set_size(pa.get_n_rows(), pa.get_n_cols());
+
+    // Resize memory to correct size.
+    result.mem_resize(n_unique(pa, pb, op_n_unique_sub()));
+
+    // Now iterate across both matrices.
+    typename SpProxy<T1>::const_iterator_type x_it = pa.begin();
+    typename SpProxy<T2>::const_iterator_type y_it = pb.begin();
+
+    typename SpProxy<T1>::const_iterator_type x_end = pa.end();
+    typename SpProxy<T2>::const_iterator_type y_end = pb.end();
+    
+    uword cur_val = 0;
+    while((x_it != x_end) || (y_it != y_end))
+      {
+      if(x_it == y_it)
+        {
+        const eT val = (*x_it) - (*y_it);
+        
+        if (val != eT(0))
+          {
+          access::rw(result.values[cur_val]) = val;
+          access::rw(result.row_indices[cur_val]) = x_it.row();
+          ++access::rw(result.col_ptrs[x_it.col() + 1]);
+          ++cur_val;
+          }
+
+        ++x_it;
+        ++y_it;
+        }
+      else
+        {
+        const uword x_it_row = x_it.row();
+        const uword x_it_col = x_it.col();
+        
+        const uword y_it_row = y_it.row();
+        const uword y_it_col = y_it.col();
+        
+        if((x_it_col < y_it_col) || ((x_it_col == y_it_col) && (x_it_row < y_it_row))) // if y is closer to the end
+          {
+          access::rw(result.values[cur_val]) = (*x_it);
+          access::rw(result.row_indices[cur_val]) = x_it_row;
+          ++access::rw(result.col_ptrs[x_it_col + 1]);
+          ++cur_val;
+          ++x_it;
+          }
+        else
+          {
+          access::rw(result.values[cur_val]) = -(*y_it);
+          access::rw(result.row_indices[cur_val]) = y_it_row;
+          ++access::rw(result.col_ptrs[y_it_col + 1]);
+          ++cur_val;
+          ++y_it;
+          }
+        }
+      }
+
+    // Fix column pointers to be cumulative.
+    for(uword c = 1; c <= result.n_cols; ++c)
+      {
+      access::rw(result.col_ptrs[c]) += result.col_ptrs[c - 1];
+      }
+    }
+  else
+    {
+    if(pa.get_n_nonzero() == 0)
+      {
+      result = pb.Q;
+      result *= eT(-1);
+      
+      return;
+      }
+    
+    if(pb.get_n_nonzero() == 0)
+      {
+      result = pa.Q;
+      return;
+      }
+    }
+  }
+
+
+
+//
+//
+// spglue_minus2: scalar*(A - B)
+
+
+
+template<typename T1, typename T2>
+inline
+void
+spglue_minus2::apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_minus2>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const SpProxy<T1> pa(X.A);
+  const SpProxy<T2> pb(X.B);
+  
+  const bool is_alias = pa.is_alias(out) || pb.is_alias(out);
+  
+  if(is_alias == false)
+    {
+    spglue_minus::apply_noalias(out, pa, pb);
+    }
+  else
+    {
+    SpMat<eT> tmp;
+    spglue_minus::apply_noalias(tmp, pa, pb);
+    
+    out.steal_mem(tmp);
+    }
+  
+  out *= X.aux;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spglue_plus_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,37 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spglue_plus
+//! @{
+
+
+
+class spglue_plus
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  arma_hot inline static void apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_plus>& X);
+  
+  template<typename eT, typename T1, typename T2>
+  arma_hot inline static void apply_noalias(SpMat<eT>& out, const SpProxy<T1>& pa, const SpProxy<T2>& pb);
+  };
+
+
+
+class spglue_plus2
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  arma_hot inline static void apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_plus2>& X);
+  };
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spglue_plus_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,179 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spglue_plus
+//! @{
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+spglue_plus::apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_plus>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const SpProxy<T1> pa(X.A);
+  const SpProxy<T2> pb(X.B);
+  
+  const bool is_alias = pa.is_alias(out) || pb.is_alias(out);
+  
+  if(is_alias == false)
+    {
+    spglue_plus::apply_noalias(out, pa, pb);
+    }
+  else
+    {
+    SpMat<eT> tmp;
+    spglue_plus::apply_noalias(tmp, pa, pb);
+    
+    out.steal_mem(tmp);
+    }
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+arma_hot
+inline
+void
+spglue_plus::apply_noalias(SpMat<eT>& out, const SpProxy<T1>& pa, const SpProxy<T2>& pb)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "addition");
+
+  if( (pa.get_n_nonzero() != 0) && (pb.get_n_nonzero() != 0) )
+    {
+    out.set_size(pa.get_n_rows(), pa.get_n_cols());
+    
+    // Resize memory to correct size.
+    out.mem_resize(n_unique(pa, pb, op_n_unique_add()));
+    
+    // Now iterate across both matrices.
+    typename SpProxy<T1>::const_iterator_type x_it = pa.begin();
+    typename SpProxy<T2>::const_iterator_type y_it = pb.begin();
+    
+    typename SpProxy<T1>::const_iterator_type x_end = pa.end();
+    typename SpProxy<T2>::const_iterator_type y_end = pb.end();
+    
+    uword cur_val = 0;
+    while( (x_it != x_end) || (y_it != y_end) )
+      {
+      if(x_it == y_it)
+        {
+        const eT val = (*x_it) + (*y_it);
+        
+        if (val != eT(0))
+          {
+          access::rw(out.values[cur_val]) = val;
+          access::rw(out.row_indices[cur_val]) = x_it.row();
+          ++access::rw(out.col_ptrs[x_it.col() + 1]);
+          ++cur_val;
+          }
+
+        ++x_it;
+        ++y_it;
+        }
+      else
+        {
+        const uword x_it_row = x_it.row();
+        const uword x_it_col = x_it.col();
+        
+        const uword y_it_row = y_it.row();
+        const uword y_it_col = y_it.col();
+        
+        if((x_it_col < y_it_col) || ((x_it_col == y_it_col) && (x_it_row < y_it_row))) // if y is closer to the end
+          {
+          access::rw(out.values[cur_val]) = (*x_it);
+          access::rw(out.row_indices[cur_val]) = x_it_row;
+          ++access::rw(out.col_ptrs[x_it_col + 1]);
+          ++cur_val;
+          ++x_it;
+          }
+        else
+          {
+          access::rw(out.values[cur_val]) = (*y_it);
+          access::rw(out.row_indices[cur_val]) = y_it_row;
+          ++access::rw(out.col_ptrs[y_it_col + 1]);
+          ++cur_val;
+          ++y_it;
+          }
+        }
+      }
+    
+    const uword out_n_cols = out.n_cols;
+    
+    uword* col_ptrs = access::rwp(out.col_ptrs);
+    
+    // Fix column pointers to be cumulative.
+    for(uword c = 1; c <= out_n_cols; ++c)
+      {
+      col_ptrs[c] += col_ptrs[c - 1];
+      }
+    }
+  else
+    {
+    if(pa.get_n_nonzero() == 0)
+      {
+      out = pb.Q;
+      return;
+      }
+    
+    if(pb.get_n_nonzero() == 0)
+      {
+      out = pa.Q;
+      return;
+      }
+    }
+  }
+
+
+
+//
+//
+// spglue_plus2: scalar*(A + B)
+
+
+
+template<typename T1, typename T2>
+arma_hot
+inline
+void
+spglue_plus2::apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_plus2>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const SpProxy<T1> pa(X.A);
+  const SpProxy<T2> pb(X.B);
+  
+  const bool is_alias = pa.is_alias(out) || pb.is_alias(out);
+  
+  if(is_alias == false)
+    {
+    spglue_plus::apply_noalias(out, pa, pb);
+    }
+  else
+    {
+    SpMat<eT> tmp;
+    spglue_plus::apply_noalias(tmp, pa, pb);
+    
+    out.steal_mem(tmp);
+    }
+  
+  out *= X.aux;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spglue_times_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,37 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spglue_times
+//! @{
+
+
+
+class spglue_times
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_times>& X);
+  
+  template<typename eT, typename T1, typename T2>
+  arma_hot inline static void apply_noalias(SpMat<eT>& c, const SpProxy<T1>& pa, const SpProxy<T2>& pb);
+  };
+
+
+
+class spglue_times2
+  {
+  public:
+  
+  template<typename T1, typename T2>
+  inline static void apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_times2>& X);
+  };
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spglue_times_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,289 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spglue_times
+//! @{
+
+
+
+template<typename T1, typename T2>
+inline
+void
+spglue_times::apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_times>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const SpProxy<T1> pa(X.A);
+  const SpProxy<T2> pb(X.B);
+  
+  const bool is_alias = pa.is_alias(out) || pb.is_alias(out);
+  
+  if(is_alias == false)
+    {
+    spglue_times::apply_noalias(out, pa, pb);
+    }
+  else
+    {
+    SpMat<eT> tmp;
+    spglue_times::apply_noalias(tmp, pa, pb);
+    
+    out.steal_mem(tmp);
+    }
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+arma_hot
+inline
+void
+spglue_times::apply_noalias(SpMat<eT>& c, const SpProxy<T1>& pa, const SpProxy<T2>& pb)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword x_n_rows = pa.get_n_rows();
+  const uword x_n_cols = pa.get_n_cols();
+  const uword y_n_rows = pb.get_n_rows();
+  const uword y_n_cols = pb.get_n_cols();
+
+  arma_debug_assert_mul_size(x_n_rows, x_n_cols, y_n_rows, y_n_cols, "matrix multiplication");
+
+  // First we must determine the structure of the new matrix (column pointers).
+  // This follows the algorithm described in 'Sparse Matrix Multiplication
+  // Package (SMMP)' (R.E. Bank and C.C. Douglas, 2001).  Their description of
+  // "SYMBMM" does not include anything about memory allocation.  In addition it
+  // does not consider that there may be elements which space may be allocated
+  // for but which evaluate to zero anyway.  So we have to modify the algorithm
+  // to work that way.  For the "SYMBMM" implementation we will not determine
+  // the row indices but instead just the column pointers.
+  
+  //SpMat<typename T1::elem_type> c(x_n_rows, y_n_cols); // Initializes col_ptrs to 0.
+  c.zeros(x_n_rows, y_n_cols);
+  
+  //if( (pa.get_n_elem() == 0) || (pb.get_n_elem() == 0) )
+  if( (pa.get_n_nonzero() == 0) || (pb.get_n_nonzero() == 0) )
+    {
+    return;
+    }
+  
+  // Auxiliary storage which denotes when items have been found.
+  podarray<uword> index(x_n_rows);
+  index.fill(x_n_rows); // Fill with invalid links.
+  
+  typename SpProxy<T2>::const_iterator_type y_it  = pb.begin();
+  typename SpProxy<T2>::const_iterator_type y_end = pb.end();
+
+  // SYMBMM: calculate column pointers for resultant matrix to obtain a good
+  // upper bound on the number of nonzero elements.
+  uword cur_col_length = 0;
+  uword last_ind = x_n_rows + 1;
+  do
+    {
+    const uword y_it_row = y_it.row();
+    
+    // Look through the column that this point (*y_it) could affect.
+    typename SpProxy<T1>::const_iterator_type x_it = pa.begin_col(y_it_row);
+    
+    while(x_it.col() == y_it_row)
+      {
+      // A point at x(i, j) and y(j, k) implies a point at c(i, k).
+      if(index[x_it.row()] == x_n_rows)
+        {
+        index[x_it.row()] = last_ind;
+        last_ind = x_it.row();
+        ++cur_col_length;
+        }
+
+      ++x_it;
+      }
+
+    const uword old_col = y_it.col();
+    ++y_it;
+
+    // See if column incremented.
+    if(old_col != y_it.col())
+      {
+      // Set column pointer (this is not a cumulative count; that is done later).
+      access::rw(c.col_ptrs[old_col + 1]) = cur_col_length;
+      cur_col_length = 0;
+
+      // Return index markers to zero.  Use last_ind for traversal.
+      while(last_ind != x_n_rows + 1)
+        {
+        const uword tmp = index[last_ind];
+        index[last_ind] = x_n_rows;
+        last_ind = tmp;
+        }
+      }
+    }
+  while(y_it != y_end);
+
+  // Accumulate column pointers.
+  for(uword i = 0; i < c.n_cols; ++i)
+    {
+    access::rw(c.col_ptrs[i + 1]) += c.col_ptrs[i];
+    }
+
+  // Now that we know a decent bound on the number of nonzero elements, allocate
+  // the memory and fill it.
+  c.mem_resize(c.col_ptrs[c.n_cols]);
+
+  // Now the implementation of the NUMBMM algorithm.
+  uword cur_pos = 0; // Current position in c matrix.
+  podarray<eT> sums(x_n_rows); // Partial sums.
+  sums.zeros();
+  
+  // setting the size of 'sorted_indices' to x_n_rows is a better-than-nothing guess;
+  // the correct minimum size is determined later
+  podarray<uword> sorted_indices(x_n_rows);
+  
+  // last_ind is already set to x_n_rows, and cur_col_length is already set to 0.
+  // We will loop through all columns as necessary.
+  uword cur_col = 0;
+  while(cur_col < c.n_cols)
+    {
+    // Skip to next column with elements in it.
+    while((cur_col < c.n_cols) && (c.col_ptrs[cur_col] == c.col_ptrs[cur_col + 1]))
+      {
+      // Update current column pointer to actual number of nonzero elements up
+      // to this point.
+      access::rw(c.col_ptrs[cur_col]) = cur_pos;
+      ++cur_col;
+      }
+
+    if(cur_col == c.n_cols)
+      {
+      break;
+      }
+
+    // Update current column pointer.
+    access::rw(c.col_ptrs[cur_col]) = cur_pos;
+
+    // Check all elements in this column.
+    typename SpProxy<T2>::const_iterator_type y_col_it = pb.begin_col(cur_col);
+    
+    while(y_col_it.col() == cur_col)
+      {
+      // Check all elements in the column of the other matrix corresponding to
+      // the row of this column.
+      typename SpProxy<T1>::const_iterator_type x_col_it = pa.begin_col(y_col_it.row());
+
+      const eT y_value = (*y_col_it);
+
+      while(x_col_it.col() == y_col_it.row())
+        {
+        // A point at x(i, j) and y(j, k) implies a point at c(i, k).
+        // Add to partial sum.
+        const eT x_value = (*x_col_it);
+        sums[x_col_it.row()] += (x_value * y_value);
+
+        // Add point if it hasn't already been marked.
+        if(index[x_col_it.row()] == x_n_rows)
+          {
+          index[x_col_it.row()] = last_ind;
+          last_ind = x_col_it.row();
+          }
+
+        ++x_col_it;
+        }
+
+      ++y_col_it;
+      }
+
+    // Now sort the indices that were used in this column.
+    //podarray<uword> sorted_indices(c.col_ptrs[cur_col + 1] - c.col_ptrs[cur_col]);
+    sorted_indices.set_min_size(c.col_ptrs[cur_col + 1] - c.col_ptrs[cur_col]);
+    
+    // .set_min_size() can only enlarge the array to the specified size,
+    // hence if we request a smaller size than already allocated,
+    // no new memory allocation is done
+    
+    
+    uword cur_index = 0;
+    while(last_ind != x_n_rows + 1)
+      {
+      const uword tmp = last_ind;
+
+      // Check that it wasn't a "fake" nonzero element.
+      if(sums[tmp] != eT(0))
+        {
+        // Assign to next open position.
+        sorted_indices[cur_index] = tmp;
+        ++cur_index;
+        }
+
+      last_ind = index[tmp];
+      index[tmp] = x_n_rows;
+      }
+
+    // Now sort the indices.
+    if (cur_index != 0)
+      {
+      op_sort::direct_sort_ascending(sorted_indices.memptr(), cur_index);
+
+      for(uword k = 0; k < cur_index; ++k)
+        {
+        const uword row = sorted_indices[k];
+        access::rw(c.row_indices[cur_pos]) = row;
+        access::rw(c.values[cur_pos]) = sums[row];
+        sums[row] = eT(0);
+        ++cur_pos;
+        }
+      }
+
+    // Move to next column.
+    ++cur_col;
+    }
+
+  // Update last column pointer and resize to actual memory size.
+  access::rw(c.col_ptrs[c.n_cols]) = cur_pos;
+  c.mem_resize(cur_pos);
+  }
+
+
+
+//
+//
+// spglue_times2: scalar*(A * B)
+
+
+
+template<typename T1, typename T2>
+inline
+void
+spglue_times2::apply(SpMat<typename T1::elem_type>& out, const SpGlue<T1,T2,spglue_times2>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const SpProxy<T1> pa(X.A);
+  const SpProxy<T2> pb(X.B);
+  
+  const bool is_alias = pa.is_alias(out) || pb.is_alias(out);
+  
+  if(is_alias == false)
+    {
+    spglue_times::apply_noalias(out, pa, pb);
+    }
+  else
+    {
+    SpMat<eT> tmp;
+    spglue_times::apply_noalias(tmp, pa, pb);
+    
+    out.steal_mem(tmp);
+    }
+  
+  out *= X.aux;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_htrans_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,29 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_htrans
+//! @{
+
+
+//! 'hermitian transpose' operation
+
+class spop_htrans
+  {
+  public:
+  
+  // handling of sparse matrices
+  
+  template<typename T1>
+  arma_hot inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_htrans>& in, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0);
+  
+  template<typename T1>
+  arma_hot inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_htrans>& in, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_htrans_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,95 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_htrans
+//! @{
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+spop_htrans::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_htrans>& in, const typename arma_not_cx<typename T1::elem_type>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  spop_strans::apply_proxy(out, in.m);
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+spop_htrans::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_htrans>& in, const typename arma_cx_only<typename T1::elem_type>::result* junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  const SpProxy<T1> p(in.m);
+  
+  if(p.is_alias(out) == false)
+    {
+    out.set_size( p.get_n_cols(), p.get_n_rows() );
+    
+    out.mem_resize(p.get_n_nonzero());
+    
+    typename SpProxy<T1>::const_row_iterator_type it = p.begin_row();
+    
+    while(it.pos() < p.get_n_nonzero())
+      {
+      access::rw(out.values[it.pos()]) = std::conj(*it);
+      access::rw(out.row_indices[it.pos()]) = it.col(); // transpose
+      ++access::rw(out.col_ptrs[it.row() + 1]);
+      
+      ++it;
+      }
+    
+    // Fix column pointers.
+    const uword out_n_cols = out.n_cols;
+    
+    for(uword c = 1; c <= out_n_cols; ++c)
+      {
+      access::rw(out.col_ptrs[c]) += out.col_ptrs[c - 1];
+      }
+    }
+  else
+    {
+    SpMat<typename T1::elem_type> result( p.get_n_cols(), p.get_n_rows() );
+    
+    result.mem_resize(p.get_n_nonzero());
+    
+    typename SpProxy<T1>::const_row_iterator_type it = p.begin_row();
+    
+    while(it.pos() < p.get_n_nonzero())
+      {
+      access::rw(result.values[it.pos()]) = std::conj(*it);
+      access::rw(result.row_indices[it.pos()]) = it.col(); // transpose
+      ++access::rw(result.col_ptrs[it.row() + 1]);
+      
+      ++it;
+      }
+    
+    // Fix column pointers.
+    const uword result_n_cols = result.n_cols;
+    
+    for(uword c = 1; c <= result_n_cols; ++c)
+      {
+      access::rw(result.col_ptrs[c]) += result.col_ptrs[c - 1];
+      }
+    
+    out.steal_mem(result);
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_max_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_max
+//! @{
+
+
+class spop_max
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T1, spop_max>& in);
+  
+  template<typename T1>
+  inline static void apply_noalias(SpMat<typename T1::elem_type>& out, const SpProxy<T1>& p, const uword dim, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0);
+  
+  template<typename T1>
+  inline static void apply_noalias(SpMat<typename T1::elem_type>& out, const SpProxy<T1>& p, const uword dim, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0);
+  
+  
+  
+  template<typename T1>
+  inline static typename T1::elem_type vector_max(const T1& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0);
+  
+  template<typename T1>
+  inline static typename T1::elem_type vector_max(const T1& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0);
+  };
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_max_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,469 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_max
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+spop_max::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_max>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword dim = in.aux_uword_a;
+  arma_debug_check((dim > 1), "max(): incorrect usage. dim must be 0 or 1");
+  
+  const SpProxy<T1> p(in.m);
+  
+  if(p.is_alias(out) == false)
+    {
+    spop_max::apply_noalias(out, p, dim);
+    }
+  else
+    {
+    SpMat<eT> tmp;
+    
+    spop_max::apply_noalias(tmp, p, dim);
+    
+    out.steal_mem(tmp);
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+spop_max::apply_noalias
+  (
+        SpMat<typename T1::elem_type>& result,
+  const SpProxy<T1>&                   p,
+  const uword                          dim,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+
+  if(dim == 0)
+    {
+    // maximum in each column
+    result.set_size(1, p.get_n_cols());
+    
+    if(p.get_n_nonzero() == 0)
+      {
+      return;
+      }
+
+    typename SpProxy<T1>::const_iterator_type it = p.begin();
+
+    uword cur_col = it.col();
+    uword elem_in_col = 1;
+    eT cur_max = (*it);
+    ++it;
+
+    while(it != p.end())
+      {
+      if(it.col() != cur_col)
+        {
+        // was the column full?
+        if(elem_in_col == p.get_n_rows())
+          {
+          result.at(0, cur_col) = cur_max;
+          }
+        else
+          {
+          result.at(0, cur_col) = std::max(eT(0), cur_max);
+          }
+
+        cur_col = it.col();
+        elem_in_col = 0;
+        cur_max = (*it);
+        }
+      else
+        {
+        cur_max = std::max(cur_max, *it);
+        }
+
+      ++elem_in_col;
+      ++it;
+      }
+
+    if(elem_in_col == p.get_n_rows())
+      {
+      result.at(0, cur_col) = cur_max;
+      }
+    else
+      {
+      result.at(0, cur_col) = std::max(eT(0), cur_max);
+      }
+    }
+  else
+    {
+    // maximum in each row
+    result.set_size(p.get_n_rows(), 1);
+  
+    if(p.get_n_nonzero() == 0)
+      {
+      return;
+      }
+
+    typename SpProxy<T1>::const_row_iterator_type it = p.begin_row();
+
+    uword cur_row = it.row();
+    uword elem_in_row = 1;
+    eT cur_max = (*it);
+    ++it;
+
+    while(it.pos() < p.get_n_nonzero())
+      {
+      if(it.row() != cur_row)
+        {
+        // was the row full?
+        if(elem_in_row == p.get_n_cols())
+          {
+          result.at(cur_row, 0) = cur_max;
+          }
+        else
+          {
+          result.at(cur_row, 0) = std::max(eT(0), cur_max);
+          }
+
+        cur_row = it.row();
+        elem_in_row = 0;
+        cur_max = (*it);
+        }
+      else
+        {
+        cur_max = std::max(cur_max, *it);
+        }
+
+      ++elem_in_row;
+      ++it;
+      }
+
+    if(elem_in_row == p.get_n_cols())
+      {
+      result.at(cur_row, 0) = cur_max;
+      }
+    else
+      {
+      result.at(cur_row, 0) = std::max(eT(0), cur_max);
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+spop_max::apply_noalias
+  (
+        SpMat<typename T1::elem_type>& result,
+  const SpProxy<T1>&                   p,
+  const uword                          dim,
+  const typename arma_cx_only<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type            eT;
+  typedef typename get_pod_type<eT>::result  T;
+  
+  if(dim == 0)
+    {
+    // maximum in each column
+    result.set_size(1, p.get_n_cols());
+  
+    if(p.get_n_nonzero() == 0)
+      {
+      return;
+      }
+    
+    typename SpProxy<T1>::const_iterator_type it = p.begin();
+    
+    uword cur_col = it.col();
+    uword elem_in_col = 1;
+    
+    eT cur_max_orig = *it;
+     T cur_max_abs  = std::abs(cur_max_orig);
+    
+    ++it;
+    
+    while(it != p.end())
+      {
+      if(it.col() != cur_col)
+        {
+        // was the column full?
+        if(elem_in_col == p.get_n_rows())
+          {
+          result.at(0, cur_col) = cur_max_orig;
+          }
+        else
+          {
+          eT val1 = eT(0);
+          
+          result.at(0, cur_col) = ( std::abs(val1) >= cur_max_abs ) ? val1 : cur_max_orig;
+          }
+        
+        cur_col = it.col();
+        elem_in_col = 0;
+        
+        cur_max_orig = *it;
+        cur_max_abs  = std::abs(cur_max_orig);
+        }
+      else
+        {
+        eT val1_orig = *it;
+         T val1_abs  = std::abs(val1_orig);
+        
+        if( val1_abs >= cur_max_abs )
+          {
+          cur_max_abs  = val1_abs;
+          cur_max_orig = val1_orig;
+          }
+        }
+
+      ++elem_in_col;
+      ++it;
+      }
+
+    if(elem_in_col == p.get_n_rows())
+      {
+      result.at(0, cur_col) = cur_max_orig;
+      }
+    else
+      {
+      eT val1 = eT(0);
+      
+      result.at(0, cur_col) = ( std::abs(val1) >= cur_max_abs ) ? val1 : cur_max_orig;
+      }
+    }
+  else
+    {
+    // maximum in each row
+    result.set_size(p.get_n_rows(), 1);
+  
+    if(p.get_n_nonzero() == 0)
+      {
+      return;
+      }
+    
+    typename SpProxy<T1>::const_row_iterator_type it = p.begin_row();
+    
+    uword cur_row = it.row();
+    uword elem_in_row = 1;
+    
+    eT cur_max_orig = *it;
+     T cur_max_abs  = std::abs(cur_max_orig);
+    
+    ++it;
+    
+    while(it.pos() < p.get_n_nonzero())
+      {
+      if(it.row() != cur_row)
+        {
+        // was the row full?
+        if(elem_in_row == p.get_n_cols())
+          {
+          result.at(cur_row, 0) = cur_max_orig;
+          }
+        else
+          {
+          eT val1 = eT(0);
+          
+          result.at(cur_row, 0) = ( std::abs(val1) >= cur_max_abs ) ? val1 : cur_max_orig;
+          }
+
+        cur_row = it.row();
+        elem_in_row = 0;
+        
+        cur_max_orig = *it;
+        cur_max_abs  = std::abs(cur_max_orig);
+        }
+      else
+        {
+        eT val1_orig = *it;
+         T val1_abs  = std::abs(val1_orig);
+        
+        if( val1_abs >= cur_max_abs )
+          {
+          cur_max_abs  = val1_abs;
+          cur_max_orig = val1_orig;
+          }
+        }
+
+      ++elem_in_row;
+      ++it;
+      }
+
+    if(elem_in_row == p.get_n_cols())
+      {
+      result.at(cur_row, 0) = cur_max_orig;
+      }
+    else
+      {
+      eT val1 = eT(0);
+      
+      result.at(cur_row, 0) = ( std::abs(val1) >= cur_max_abs ) ? val1 : cur_max_orig;
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::elem_type
+spop_max::vector_max
+  (
+  const T1& x,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  const SpProxy<T1> p(x);
+  
+  if(p.get_n_nonzero() == 0)
+    {
+    return eT(0);
+    }
+  
+  if(SpProxy<T1>::must_use_iterator == false)
+    {
+    // direct access of values
+    if(p.get_n_nonzero() == p.get_n_elem())
+      {
+      return op_max::direct_max(p.get_values(), p.get_n_nonzero());
+      }
+    else
+      {
+      return std::max(eT(0), op_max::direct_max(p.get_values(), p.get_n_nonzero()));
+      }
+    }
+  else
+    {
+    // use iterator
+    typename SpProxy<T1>::const_iterator_type it = p.begin();
+
+    eT result = (*it);
+    ++it;
+
+    while(it != p.end())
+      {
+      if((*it) > result)
+        {
+        result = (*it);
+        }
+
+      ++it;
+      }
+
+    if(p.get_n_nonzero() == p.get_n_elem())
+      {
+      return result;
+      }
+    else
+      {
+      return std::max(eT(0), result);
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::elem_type
+spop_max::vector_max
+  (
+  const T1& x,
+  const typename arma_cx_only<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type            eT;
+  typedef typename get_pod_type<eT>::result  T;
+
+  const SpProxy<T1> p(x);
+
+  if(p.get_n_nonzero() == 0)
+    {
+    return eT(0);
+    }
+
+  if(SpProxy<T1>::must_use_iterator == false)
+    {
+    // direct access of values
+    if(p.get_n_nonzero() == p.get_n_elem())
+      {
+      return op_max::direct_max(p.get_values(), p.get_n_nonzero());
+      }
+    else
+      {
+      const eT val1 = eT(0);
+      const eT val2 = op_max::direct_max(p.get_values(), p.get_n_nonzero());
+      
+      return ( std::abs(val1) >= std::abs(val2) ) ? val1 : val2;
+      }
+    }
+  else
+    {
+    // use iterator
+    typename SpProxy<T1>::const_iterator_type it = p.begin();
+
+    eT best_val_orig = *it;
+     T best_val_abs  = std::abs(best_val_orig);
+    
+    ++it;
+    
+    while(it != p.end())
+      {
+      eT val_orig = *it;
+       T val_abs  = std::abs(val_orig);
+      
+      if(val_abs > best_val_abs)
+        {
+        best_val_abs  = val_abs;
+        best_val_orig = val_orig;
+        }
+
+      ++it;
+      }
+
+    if(p.get_n_nonzero() == p.get_n_elem())
+      {
+      return best_val_orig;
+      }
+    else
+      {
+      const eT val1 = eT(0);
+      
+      return ( std::abs(val1) >= best_val_abs ) ? val1 : best_val_orig;
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_mean_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,45 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_mean
+//! @{
+
+
+//! Class for finding mean values of a sparse matrix
+class spop_mean
+  {
+  public:
+
+  // Apply mean into an output sparse matrix (or vector).
+  template<typename T1>
+  inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T1, spop_mean>& in);
+
+  template<typename T1>
+  inline static void apply_noalias(SpMat<typename T1::elem_type>& out, const SpProxy<T1>& p, const uword dim);
+  
+  // Take direct mean of a set of values.  Length of array and number of values can be different.
+  template<typename eT>
+  inline static eT direct_mean(const eT* const X, const uword length, const uword N);
+
+  template<typename eT>
+  inline static eT direct_mean_robust(const eT* const X, const uword length, const uword N);
+
+  template<typename T1>
+  inline static typename T1::elem_type mean_all(const SpBase<typename T1::elem_type, T1>& X);
+
+  // Take the mean using an iterator.
+  template<typename T1, typename eT>
+  inline static eT iterator_mean(T1& it, const T1& end, const uword n_zero, const eT junk);
+
+  template<typename T1, typename eT>
+  inline static eT iterator_mean_robust(T1& it, const T1& end, const uword n_zero, const eT junk);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_mean_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,257 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_mean
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+spop_mean::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1, spop_mean>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword dim = in.aux_uword_a;
+  arma_debug_check((dim > 1), "mean(): incorrect usage. dim must be 0 or 1");
+  
+  SpProxy<T1> p(in.m);
+  
+  if(p.is_alias(out) == false)
+    {
+    spop_mean::apply_noalias(out, p, dim);
+    }
+  else
+    {
+    SpMat<eT> tmp;
+    
+    spop_mean::apply_noalias(tmp, p, dim);
+    
+    out.steal_mem(tmp);
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+spop_mean::apply_noalias
+  (
+        SpMat<typename T1::elem_type>& out_ref,
+  const SpProxy<T1>&                   p,
+  const uword                          dim
+  )
+  {
+  arma_extra_debug_sigprint();
+
+  typedef typename T1::elem_type eT;
+  
+  const uword p_n_rows = p.get_n_rows();
+  const uword p_n_cols = p.get_n_cols();
+
+  if (dim == 0)
+    {
+    arma_extra_debug_print("spop_mean::apply_noalias(), dim = 0");
+
+    out_ref.set_size((p_n_rows > 0) ? 1 : 0, p_n_cols);
+
+    if(p_n_rows > 0)
+      {
+      for(uword col = 0; col < p_n_cols; ++col)
+        {
+        // Do we have to use an iterator or can we use memory directly?
+        if(SpProxy<T1>::must_use_iterator == true)
+          {
+          typename SpProxy<T1>::const_iterator_type it  = p.begin_col(col);
+          typename SpProxy<T1>::const_iterator_type end = p.begin_col(col + 1);
+          
+          const uword n_zero = p.get_n_rows() - (end.pos() - it.pos());
+          
+          out_ref.at(col) = spop_mean::iterator_mean(it, end, n_zero, eT(0));
+          }
+        else
+          {
+          out_ref.at(col) = spop_mean::direct_mean
+            (
+            &p.get_values()[p.get_col_ptrs()[col]],
+            p.get_col_ptrs()[col + 1] - p.get_col_ptrs()[col],
+            p.get_n_rows()
+            );
+          }
+        }
+      }
+    }
+  else if (dim == 1)
+    {
+    arma_extra_debug_print("spop_mean::apply_noalias(), dim = 1");
+    
+    out_ref.set_size(p_n_rows, (p_n_cols > 0) ? 1 : 0);
+    
+    if(p_n_cols > 0)
+      {
+      for(uword row = 0; row < p_n_rows; ++row)
+        {
+        // We must use an iterator regardless of how it is stored.
+        typename SpProxy<T1>::const_row_iterator_type it  = p.begin_row(row);
+        typename SpProxy<T1>::const_row_iterator_type end = p.end_row(row);
+        
+        const uword n_zero = p.get_n_cols() - (end.pos() - it.pos());
+        
+        out_ref.at(row) = spop_mean::iterator_mean(it, end, n_zero, eT(0));
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+eT
+spop_mean::direct_mean
+  (
+  const eT* const X,
+  const uword length,
+  const uword N
+  )
+  {
+  arma_extra_debug_sigprint();
+
+  typedef typename get_pod_type<eT>::result T;
+
+  const eT result = arrayops::accumulate(X, length) / T(N);
+
+  return arma_isfinite(result) ? result : spop_mean::direct_mean_robust(X, length, N);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+spop_mean::direct_mean_robust
+  (
+  const eT* const X,
+  const uword length,
+  const uword N
+  )
+  {
+  arma_extra_debug_sigprint();
+
+  typedef typename get_pod_type<eT>::result T;
+
+  uword i, j;
+
+  eT r_mean = eT(0);
+
+  const uword diff = (N - length); // number of zeros
+
+  for(i = 0, j = 1; j < length; i += 2, j += 2)
+    {
+    const eT Xi = X[i];
+    const eT Xj = X[j];
+
+    r_mean += (Xi - r_mean) / T(diff + j);
+    r_mean += (Xj - r_mean) / T(diff + j + 1);
+    }
+
+  if(i < length)
+    {
+    const eT Xi = X[i];
+
+    r_mean += (Xi - r_mean) / T(diff + i + 1);
+    }
+
+  return r_mean;
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::elem_type
+spop_mean::mean_all(const SpBase<typename T1::elem_type, T1>& X)
+  {
+  arma_extra_debug_sigprint();
+
+  SpProxy<T1> p(X.get_ref());
+
+  if (SpProxy<T1>::must_use_iterator == true)
+    {
+    typename SpProxy<T1>::const_iterator_type it  = p.begin();
+    typename SpProxy<T1>::const_iterator_type end = p.end();
+
+    return spop_mean::iterator_mean(it, end, p.get_n_elem() - p.get_n_nonzero(), typename T1::elem_type(0));
+    }
+  else // must_use_iterator == false; that is, we can directly access the values array
+    {
+    return spop_mean::direct_mean(p.get_values(), p.get_n_nonzero(), p.get_n_elem());
+    }
+  }
+
+
+
+template<typename T1, typename eT>
+inline
+eT
+spop_mean::iterator_mean(T1& it, const T1& end, const uword n_zero, const eT junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+
+  typedef typename get_pod_type<eT>::result T;
+
+  eT sum = eT(0);
+
+  T1 backup_it(it); // in case we have to use robust iterator_mean
+
+  const uword it_begin_pos = it.pos();
+
+  while (it != end)
+    {
+    sum += (*it);
+    ++it;
+    }
+
+  const eT result = sum / T(n_zero + (it.pos() - it_begin_pos));
+
+  return arma_isfinite(result) ? result : spop_mean::iterator_mean_robust(backup_it, end, n_zero, eT(0));
+  }
+
+
+
+template<typename T1, typename eT>
+inline
+eT
+spop_mean::iterator_mean_robust(T1& it, const T1& end, const uword n_zero, const eT junk)
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+
+  typedef typename get_pod_type<eT>::result T;
+
+  eT r_mean = eT(0);
+
+  const uword it_begin_pos = it.pos();
+
+  while (it != end)
+    {
+    r_mean += ((*it - r_mean) / T(n_zero + (it.pos() - it_begin_pos) + 1));
+    ++it;
+    }
+
+  return r_mean;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_min_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_min
+//! @{
+
+
+class spop_min
+  {
+  public:
+  
+  template<typename T1>
+  inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T1, spop_min>& in);
+  
+  template<typename T1>
+  inline static void apply_noalias(SpMat<typename T1::elem_type>& out, const SpProxy<T1>& p, const uword dim, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0);
+  
+  template<typename T1>
+  inline static void apply_noalias(SpMat<typename T1::elem_type>& out, const SpProxy<T1>& p, const uword dim, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0);
+  
+  
+  
+  template<typename T1>
+  inline static typename T1::elem_type vector_min(const T1& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0);
+  
+  template<typename T1>
+  inline static typename T1::elem_type vector_min(const T1& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = 0);
+  };
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_min_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,469 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_min
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+spop_min::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_min>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword dim = in.aux_uword_a;
+  arma_debug_check((dim > 1), "min(): incorrect usage. dim must be 0 or 1");
+  
+  const SpProxy<T1> p(in.m);
+  
+  if(p.is_alias(out) == false)
+    {
+    spop_min::apply_noalias(out, p, dim);
+    }
+  else
+    {
+    SpMat<eT> tmp;
+    
+    spop_min::apply_noalias(tmp, p, dim);
+    
+    out.steal_mem(tmp);
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+spop_min::apply_noalias
+  (
+        SpMat<typename T1::elem_type>& result,
+  const SpProxy<T1>&                   p,
+  const uword                          dim,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+
+  if(dim == 0)
+    {
+    // minimum in each column
+    result.set_size(1, p.get_n_cols());
+  
+    if(p.get_n_nonzero() == 0)
+      {
+      return;
+      }
+    
+    typename SpProxy<T1>::const_iterator_type it = p.begin();
+
+    uword cur_col = it.col();
+    uword elem_in_col = 1;
+    eT cur_min = (*it);
+    ++it;
+
+    while(it != p.end())
+      {
+      if(it.col() != cur_col)
+        {
+        // was the column full?
+        if(elem_in_col == p.get_n_rows())
+          {
+          result.at(0, cur_col) = cur_min;
+          }
+        else
+          {
+          result.at(0, cur_col) = std::min(eT(0), cur_min);
+          }
+
+        cur_col = it.col();
+        elem_in_col = 0;
+        cur_min = (*it);
+        }
+      else
+        {
+        cur_min = std::min(cur_min, *it);
+        }
+
+      ++elem_in_col;
+      ++it;
+      }
+
+    if(elem_in_col == p.get_n_rows())
+      {
+      result.at(0, cur_col) = cur_min;
+      }
+    else
+      {
+      result.at(0, cur_col) = std::min(eT(0), cur_min);
+      }
+    }
+  else
+    {
+    // minimum in each row
+    result.set_size(p.get_n_rows(), 1);
+  
+    if(p.get_n_nonzero() == 0)
+      {
+      return;
+      }
+
+    typename SpProxy<T1>::const_row_iterator_type it = p.begin_row();
+
+    uword cur_row = it.row();
+    uword elem_in_row = 1;
+    eT cur_min = (*it);
+    ++it;
+
+    while(it.pos() < p.get_n_nonzero())
+      {
+      if(it.row() != cur_row)
+        {
+        // was the row full?
+        if(elem_in_row == p.get_n_cols())
+          {
+          result.at(cur_row, 0) = cur_min;
+          }
+        else
+          {
+          result.at(cur_row, 0) = std::min(eT(0), cur_min);
+          }
+
+        cur_row = it.row();
+        elem_in_row = 0;
+        cur_min = (*it);
+        }
+      else
+        {
+        cur_min = std::min(cur_min, *it);
+        }
+
+      ++elem_in_row;
+      ++it;
+      }
+
+    if(elem_in_row == p.get_n_cols())
+      {
+      result.at(cur_row, 0) = cur_min;
+      }
+    else
+      {
+      result.at(cur_row, 0) = std::min(eT(0), cur_min);
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+spop_min::apply_noalias
+  (
+        SpMat<typename T1::elem_type>& result,
+  const SpProxy<T1>&                   p,
+  const uword                          dim,
+  const typename arma_cx_only<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type            eT;
+  typedef typename get_pod_type<eT>::result  T;
+  
+  if(dim == 0)
+    {
+    // minimum in each column
+    result.set_size(1, p.get_n_cols());
+    
+    if(p.get_n_nonzero() == 0)
+      {
+      return;
+      }
+
+    typename SpProxy<T1>::const_iterator_type it = p.begin();
+    
+    uword cur_col = it.col();
+    uword elem_in_col = 1;
+    
+    eT cur_min_orig = *it;
+     T cur_min_abs  = std::abs(cur_min_orig);
+    
+    ++it;
+    
+    while(it != p.end())
+      {
+      if(it.col() != cur_col)
+        {
+        // was the column full?
+        if(elem_in_col == p.get_n_rows())
+          {
+          result.at(0, cur_col) = cur_min_orig;
+          }
+        else
+          {
+          eT val1 = eT(0);
+          
+          result.at(0, cur_col) = ( std::abs(val1) < cur_min_abs ) ? val1 : cur_min_orig;
+          }
+        
+        cur_col = it.col();
+        elem_in_col = 0;
+        
+        cur_min_orig = *it;
+        cur_min_abs  = std::abs(cur_min_orig);
+        }
+      else
+        {
+        eT val1_orig = *it;
+         T val1_abs  = std::abs(val1_orig);
+        
+        if( val1_abs < cur_min_abs )
+          {
+          cur_min_abs  = val1_abs;
+          cur_min_orig = val1_orig;
+          }
+        }
+
+      ++elem_in_col;
+      ++it;
+      }
+
+    if(elem_in_col == p.get_n_rows())
+      {
+      result.at(0, cur_col) = cur_min_orig;
+      }
+    else
+      {
+      eT val1 = eT(0);
+      
+      result.at(0, cur_col) = ( std::abs(val1) < cur_min_abs ) ? val1 : cur_min_orig;
+      }
+    }
+  else
+    {
+    // minimum in each row
+    result.set_size(p.get_n_rows(), 1);
+    
+    if(p.get_n_nonzero() == 0)
+      {
+      return;
+      }
+
+    typename SpProxy<T1>::const_row_iterator_type it = p.begin_row();
+    
+    uword cur_row = it.row();
+    uword elem_in_row = 1;
+    
+    eT cur_min_orig = *it;
+     T cur_min_abs  = std::abs(cur_min_orig);
+    
+    ++it;
+    
+    while(it.pos() < p.get_n_nonzero())
+      {
+      if(it.row() != cur_row)
+        {
+        // was the row full?
+        if(elem_in_row == p.get_n_cols())
+          {
+          result.at(cur_row, 0) = cur_min_orig;
+          }
+        else
+          {
+          eT val1 = eT(0);
+          
+          result.at(cur_row, 0) = ( std::abs(val1) < cur_min_abs ) ? val1 : cur_min_orig;
+          }
+
+        cur_row = it.row();
+        elem_in_row = 0;
+        
+        cur_min_orig = *it;
+        cur_min_abs  = std::abs(cur_min_orig);
+        }
+      else
+        {
+        eT val1_orig = *it;
+         T val1_abs  = std::abs(val1_orig);
+        
+        if( val1_abs < cur_min_abs )
+          {
+          cur_min_abs  = val1_abs;
+          cur_min_orig = val1_orig;
+          }
+        }
+
+      ++elem_in_row;
+      ++it;
+      }
+
+    if(elem_in_row == p.get_n_cols())
+      {
+      result.at(cur_row, 0) = cur_min_orig;
+      }
+    else
+      {
+      eT val1 = eT(0);
+      
+      result.at(cur_row, 0) = ( std::abs(val1) < cur_min_abs ) ? val1 : cur_min_orig;
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::elem_type
+spop_min::vector_min
+  (
+  const T1& x,
+  const typename arma_not_cx<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type eT;
+  
+  const SpProxy<T1> p(x);
+  
+  if(p.get_n_nonzero() == 0)
+    {
+    return eT(0);
+    }
+  
+  if(SpProxy<T1>::must_use_iterator == false)
+    {
+    // direct access of values
+    if(p.get_n_nonzero() == p.get_n_elem())
+      {
+      return op_min::direct_min(p.get_values(), p.get_n_nonzero());
+      }
+    else
+      {
+      return std::min(eT(0), op_min::direct_min(p.get_values(), p.get_n_nonzero()));
+      }
+    }
+  else
+    {
+    // use iterator
+    typename SpProxy<T1>::const_iterator_type it = p.begin();
+
+    eT result = (*it);
+    ++it;
+
+    while(it != p.end())
+      {
+      if((*it) < result)
+        {
+        result = (*it);
+        }
+
+      ++it;
+      }
+
+    if(p.get_n_nonzero() == p.get_n_elem())
+      {
+      return result;
+      }
+    else
+      {
+      return std::min(eT(0), result);
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::elem_type
+spop_min::vector_min
+  (
+  const T1& x,
+  const typename arma_cx_only<typename T1::elem_type>::result* junk
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk);
+  
+  typedef typename T1::elem_type            eT;
+  typedef typename get_pod_type<eT>::result  T;
+
+  const SpProxy<T1> p(x);
+
+  if(p.get_n_nonzero() == 0)
+    {
+    return eT(0);
+    }
+
+  if(SpProxy<T1>::must_use_iterator == false)
+    {
+    // direct access of values
+    if(p.get_n_nonzero() == p.get_n_elem())
+      {
+      return op_min::direct_min(p.get_values(), p.get_n_nonzero());
+      }
+    else
+      {
+      const eT val1 = eT(0);
+      const eT val2 = op_min::direct_min(p.get_values(), p.get_n_nonzero());
+      
+      return ( std::abs(val1) < std::abs(val2) ) ? val1 : val2;
+      }
+    }
+  else
+    {
+    // use iterator
+    typename SpProxy<T1>::const_iterator_type it = p.begin();
+
+    eT best_val_orig = *it;
+     T best_val_abs  = std::abs(best_val_orig);
+    
+    ++it;
+    
+    while(it != p.end())
+      {
+      eT val_orig = *it;
+       T val_abs  = std::abs(val_orig);
+      
+      if(val_abs < best_val_abs)
+        {
+        best_val_abs  = val_abs;
+        best_val_orig = val_orig;
+        }
+
+      ++it;
+      }
+
+    if(p.get_n_nonzero() == p.get_n_elem())
+      {
+      return best_val_orig;
+      }
+    else
+      {
+      const eT val1 = eT(0);
+      
+      return ( std::abs(val1) < best_val_abs ) ? val1 : best_val_orig;
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_misc_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,62 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_misc
+//! @{
+
+
+class spop_scalar_times
+  {
+  public:
+  
+  template<typename T1>
+  arma_hot inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T1, spop_scalar_times>& in);
+  };
+
+
+
+class spop_square
+  {
+  public:
+  
+  template<typename T1>
+  arma_hot inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T1, spop_square>& in);
+  };
+
+
+
+class spop_sqrt
+  {
+  public:
+  
+  template<typename T1>
+  arma_hot inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T1, spop_sqrt>& in);
+  };
+
+
+
+class spop_abs
+  {
+  public:
+  
+  template<typename T1>
+  arma_hot inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T1, spop_abs>& in);
+  };
+
+
+
+class spop_cx_abs
+  {
+  public:
+  
+  template<typename T1>
+  arma_hot inline static void apply(SpMat<typename T1::pod_type>& out, const mtSpOp<typename T1::pod_type, T1, spop_cx_abs>& in);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_misc_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,134 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_misc
+//! @{
+
+
+
+namespace priv
+  {
+  template<typename eT>
+  struct functor_scalar_times
+    {
+    const eT k;
+    
+    functor_scalar_times(const eT in_k) : k(in_k) {}
+    
+    arma_inline eT operator()(const eT val) const { return val * k; }
+    };
+  }
+
+
+
+template<typename T1>
+inline
+void
+spop_scalar_times::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_scalar_times>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  out.init_xform(in.m, priv::functor_scalar_times<eT>(in.aux));
+  }
+
+
+
+namespace priv
+  {
+  struct functor_square
+    {
+    template<typename eT>
+    arma_inline eT operator()(const eT val) const { return val*val; }
+    };
+  }
+
+
+
+template<typename T1>
+inline
+void
+spop_square::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_square>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  out.init_xform(in.m, priv::functor_square());
+  }
+
+
+
+namespace priv
+  {
+  struct functor_sqrt
+    {
+    template<typename eT>
+    arma_inline eT operator()(const eT val) const { return eop_aux::sqrt(val); }
+    };
+  }
+
+
+
+template<typename T1>
+inline
+void
+spop_sqrt::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_sqrt>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  out.init_xform(in.m, priv::functor_sqrt());
+  }
+
+
+
+namespace priv
+  {
+  struct functor_abs
+    {
+    template<typename eT>
+    arma_inline eT operator()(const eT val) const { return eop_aux::arma_abs(val); }
+    };
+  }
+
+
+
+template<typename T1>
+inline
+void
+spop_abs::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_abs>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  out.init_xform(in.m, priv::functor_abs());
+  }
+
+
+
+namespace priv
+  {
+  struct functor_cx_abs
+    {
+    template<typename T>
+    arma_inline T operator()(const std::complex<T>& val) const { return std::abs(val); }
+    };
+  }
+
+
+
+template<typename T1>
+inline
+void
+spop_cx_abs::apply(SpMat<typename T1::pod_type>& out, const mtSpOp<typename T1::pod_type, T1, spop_cx_abs>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  out.init_xform_mt(in.m, priv::functor_cx_abs());
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_strans_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,27 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_strans
+//! @{
+
+
+//! 'matrix transpose' operation
+
+class spop_strans
+  {
+  public:
+  
+  template<typename T1>
+  arma_hot inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_strans>& in);
+  
+  template<typename T1>
+  arma_hot inline static void apply_proxy(SpMat<typename T1::elem_type>& out, const T1& X);
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_strans_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,93 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_strans
+//! @{
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+spop_strans::apply_proxy(SpMat<typename T1::elem_type>& out, const T1& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  const SpProxy<T1> p(X);
+  
+  if(p.is_alias(out) == false)
+    {
+    out.set_size( p.get_n_cols(), p.get_n_rows() );
+    
+    out.mem_resize(p.get_n_nonzero());
+    
+    typename SpProxy<T1>::const_row_iterator_type it = p.begin_row();
+    
+    while(it.pos() < p.get_n_nonzero())
+      {
+      access::rw(out.values[it.pos()]) = (*it);
+      access::rw(out.row_indices[it.pos()]) = it.col(); // transpose
+      ++access::rw(out.col_ptrs[it.row() + 1]);
+      
+      ++it;
+      }
+    
+    // Fix column pointers.
+    const uword out_n_cols = out.n_cols;
+    
+    for(uword c = 1; c <= out_n_cols; ++c)
+      {
+      access::rw(out.col_ptrs[c]) += out.col_ptrs[c - 1];
+      }
+    }
+  else
+    {
+    SpMat<typename T1::elem_type> result( p.get_n_cols(), p.get_n_rows() );
+    
+    result.mem_resize(p.get_n_nonzero());
+    
+    typename SpProxy<T1>::const_row_iterator_type it = p.begin_row();
+    
+    while(it.pos() < p.get_n_nonzero())
+      {
+      access::rw(result.values[it.pos()]) = (*it);
+      access::rw(result.row_indices[it.pos()]) = it.col(); // transpose
+      ++access::rw(result.col_ptrs[it.row() + 1]);
+      
+      ++it;
+      }
+    
+    // Fix column pointers.
+    const uword result_n_cols = result.n_cols;
+    
+    for(uword c = 1; c <= result_n_cols; ++c)
+      {
+      access::rw(result.col_ptrs[c]) += result.col_ptrs[c - 1];
+      }
+    
+    out.steal_mem(result);
+    }
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+spop_strans::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_strans>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  spop_strans::apply_proxy(out, in.m);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_sum_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,24 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_sum
+//! @{
+
+
+class spop_sum
+  {
+  public:
+  
+  template<typename T1>
+  arma_hot inline static void apply(SpMat<typename T1::elem_type>& out, const SpOp<T1, spop_sum>& in);
+  
+  template<typename T1>
+  arma_hot inline static void apply_noalias(SpMat<typename T1::elem_type>& out, const SpProxy<T1>& p, const uword dim);
+  };
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_sum_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,83 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_sum
+//! @{
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+spop_sum::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_sum>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  typedef typename T1::elem_type eT;
+  
+  const uword dim = in.aux_uword_a;
+  arma_debug_check((dim > 1), "sum(): incorrect usage. dim must be 0 or 1");
+  
+  const SpProxy<T1> p(in.m);
+  
+  if(p.is_alias(out) == false)
+    {
+    spop_sum::apply_noalias(out, p, dim);
+    }
+  else
+    {
+    SpMat<eT> tmp;
+    
+    spop_sum::apply_noalias(tmp, p, dim);
+    
+    out.steal_mem(tmp);
+    }
+  }
+
+
+
+template<typename T1>
+arma_hot
+inline
+void
+spop_sum::apply_noalias(SpMat<typename T1::elem_type>& out, const SpProxy<T1>& p, const uword dim)
+  {
+  arma_extra_debug_sigprint();
+  
+  if(dim == 0) // find the sum in each column
+    {
+    out.zeros(1, p.get_n_cols());
+    
+    typename SpProxy<T1>::const_iterator_type it     = p.begin();
+    typename SpProxy<T1>::const_iterator_type it_end = p.end();
+    
+    while(it != it_end)
+      {
+      out.at(0, it.col()) += (*it);
+      ++it;
+      }
+    }
+  else // find the sum in each row
+    {
+    out.zeros(p.get_n_rows(), 1);
+    
+    typename SpProxy<T1>::const_iterator_type it     = p.begin();
+    typename SpProxy<T1>::const_iterator_type it_end = p.end();
+    
+    while(it != it_end)
+      {
+      out.at(it.row(), 0) += (*it);
+      ++it;
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_var_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,53 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_var
+//! @{
+
+
+
+//! Class for finding variance values of a sparse matrix
+class spop_var
+  {
+  public:
+
+  template<typename T1>
+  inline static void apply(SpMat<typename T1::pod_type>& out, const mtSpOp<typename T1::pod_type, T1, spop_var>& in);
+
+  template<typename T1>
+  inline static void apply_noalias(SpMat<typename T1::pod_type>& out, const SpProxy<T1>& p, const uword norm_type, const uword dim);
+  
+  // Calculate variance of a sparse vector, where we can directly use the memory.
+  template<typename T1>
+  inline static typename T1::pod_type var_vec(const T1& X, const uword norm_type = 0);
+  
+  // Calculate the variance directly.  Because this is for sparse matrices, we
+  // specify both the number of elements in the array (the length of the array)
+  // as well as the actual number of elements when zeros are included.
+  template<typename eT>
+  inline static eT direct_var(const eT* const X, const uword length, const uword N, const uword norm_type = 0);
+
+  // For complex numbers.
+
+  template<typename T>
+  inline static T direct_var(const std::complex<T>* const X, const uword length, const uword N, const uword norm_type = 0);
+
+  // Calculate the variance using iterators, for non-complex numbers.
+  template<typename T1, typename eT>
+  inline static eT iterator_var(T1& it, const T1& end, const uword n_zero, const uword norm_type, const eT junk1, const typename arma_not_cx<eT>::result* junk2 = 0);
+
+  // Calculate the variance using iterators, for complex numbers.
+  template<typename T1, typename eT>
+  inline static typename get_pod_type<eT>::result iterator_var(T1& it, const T1& end, const uword n_zero, const uword norm_type, const eT junk1, const typename arma_cx_only<eT>::result* junk2 = 0);
+
+  };
+
+
+
+//! @}
+  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/spop_var_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,401 @@
+// Copyright (C) 2012 Ryan Curtin
+// Copyright (C) 2012 Conrad Sanderson
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup spop_var
+//! @{
+
+
+
+template<typename T1>
+inline
+void
+spop_var::apply(SpMat<typename T1::pod_type>& out, const mtSpOp<typename T1::pod_type, T1, spop_var>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  //typedef typename T1::elem_type  in_eT;
+  typedef typename T1::pod_type  out_eT;
+  
+  const uword norm_type = in.aux_uword_a;
+  const uword dim       = in.aux_uword_b;
+  
+  arma_debug_check((norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1");
+  arma_debug_check((dim > 1),       "var(): incorrect usage. dim must be 0 or 1");
+  
+  SpProxy<T1> p(in.m);
+  
+  if(p.is_alias(out) == false)
+    {
+    spop_var::apply_noalias(out, p, norm_type, dim);
+    }
+  else
+    {
+    SpMat<out_eT> tmp;
+    
+    spop_var::apply_noalias(tmp, p, norm_type, dim);
+    
+    out.steal_mem(tmp);
+    }
+  }
+
+
+
+template<typename T1>
+inline
+void
+spop_var::apply_noalias
+  (
+        SpMat<typename T1::pod_type>& out_ref,
+  const SpProxy<T1>&                  p,
+  const uword                         norm_type,
+  const uword                         dim
+  )
+  {
+  arma_extra_debug_sigprint();
+
+  typedef typename T1::elem_type  in_eT;
+  //typedef typename T1::pod_type  out_eT;
+
+  const uword p_n_rows = p.get_n_rows();
+  const uword p_n_cols = p.get_n_cols();
+
+  if(dim == 0)
+    {
+    arma_extra_debug_print("spop_var::apply(), dim = 0");
+
+    arma_debug_check((p_n_rows == 0), "var(): given object has zero rows");
+
+    out_ref.set_size(1, p_n_cols);
+
+    for(uword col = 0; col < p_n_cols; ++col)
+      {
+      if(SpProxy<T1>::must_use_iterator == true)
+        {
+        // We must use an iterator; we can't access memory directly.
+        typename SpProxy<T1>::const_iterator_type it  = p.begin_col(col);
+        typename SpProxy<T1>::const_iterator_type end = p.begin_col(col + 1);
+        
+        const uword n_zero = p.get_n_rows() - (end.pos() - it.pos());
+        
+        // in_eT is used just to get the specialization right (complex / noncomplex)
+        out_ref.at(col) = spop_var::iterator_var(it, end, n_zero, norm_type, in_eT(0));
+        }
+      else
+        {
+        // We can use direct memory access to calculate the variance.
+        out_ref.at(col) = spop_var::direct_var
+          (
+          &p.get_values()[p.get_col_ptrs()[col]],
+          p.get_col_ptrs()[col + 1] - p.get_col_ptrs()[col],
+          p.get_n_rows(),
+          norm_type
+          );
+        }
+      }
+    }
+  else if(dim == 1)
+    {
+    arma_extra_debug_print("spop_var::apply_noalias(), dim = 1");
+    
+    arma_debug_check((p_n_cols == 0), "var(): given object has zero columns");
+    
+    out_ref.set_size(p_n_rows, 1);
+    
+    for(uword row = 0; row < p_n_rows; ++row)
+      {
+      // We have to use an iterator here regardless of whether or not we can
+      // directly access memory.
+      typename SpProxy<T1>::const_row_iterator_type it  = p.begin_row(row);
+      typename SpProxy<T1>::const_row_iterator_type end = p.end_row(row);
+      
+      const uword n_zero = p.get_n_cols() - (end.pos() - it.pos());
+      
+      out_ref.at(row) = spop_var::iterator_var(it, end, n_zero, norm_type, in_eT(0));
+      }
+    }
+  }
+
+
+
+template<typename T1>
+inline
+typename T1::pod_type
+spop_var::var_vec
+  (
+  const T1& X,
+  const uword norm_type
+  )
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check((norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1.");
+  
+  // conditionally unwrap it into a temporary and then directly operate.
+  
+  const unwrap_spmat<T1> tmp(X);
+  
+  return direct_var(tmp.M.values, tmp.M.n_nonzero, tmp.M.n_elem, norm_type);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+spop_var::direct_var
+  (
+  const eT* const X,
+  const uword length,
+  const uword N,
+  const uword norm_type
+  )
+  {
+  arma_extra_debug_sigprint();
+
+  if(length >= 2 && N >= 2)
+    {
+    const eT acc1 = spop_mean::direct_mean(X, length, N);
+
+    eT acc2 = eT(0);
+    eT acc3 = eT(0);
+
+    uword i, j;
+
+    for(i = 0, j = 1; j < length; i += 2, j += 2)
+      {
+      const eT Xi = X[i];
+      const eT Xj = X[j];
+
+      const eT tmpi = acc1 - Xi;
+      const eT tmpj = acc1 - Xj;
+
+      acc2 += tmpi * tmpi + tmpj * tmpj;
+      acc3 += tmpi + tmpj;
+      }
+
+    if(i < length)
+      {
+      const eT Xi = X[i];
+
+      const eT tmpi = acc1 - Xi;
+
+      acc2 += tmpi * tmpi;
+      acc3 += tmpi;
+      }
+
+    // Now add in all zero elements.
+    acc2 += (N - length) * (acc1 * acc1);
+    acc3 += (N - length) * acc1;
+
+    const eT norm_val = (norm_type == 0) ? eT(N - 1) : eT(N);
+    const eT var_val  = (acc2 - (acc3 * acc3) / eT(N)) / norm_val;
+
+    return var_val;
+    }
+  else if(length == 1 && N > 1) // if N == 1, then variance is zero.
+    {
+    const eT mean = X[0] / eT(N);
+    const eT val = mean - X[0];
+
+    const eT acc2 = (val * val) + (N - length) * (mean * mean);
+    const eT acc3 = val + (N - length) * mean;
+
+    const eT norm_val = (norm_type == 0) ? eT(N - 1) : eT(N);
+    const eT var_val  = (acc2 - (acc3 * acc3) / eT(N)) / norm_val;
+
+    return var_val;
+    }
+  else
+    {
+    return eT(0);
+    }
+  }
+
+
+
+template<typename T>
+inline
+T
+spop_var::direct_var
+  (
+  const std::complex<T>* const X,
+  const uword length,
+  const uword N,
+  const uword norm_type
+  )
+  {
+  arma_extra_debug_sigprint();
+
+  typedef typename std::complex<T> eT;
+
+  if(length >= 2 && N >= 2)
+    {
+    const eT acc1 = spop_mean::direct_mean(X, length, N);
+
+     T acc2 =  T(0);
+    eT acc3 = eT(0);
+
+    for (uword i = 0; i < length; ++i)
+      {
+      const eT tmp = acc1 - X[i];
+
+      acc2 += std::norm(tmp);
+      acc3 += tmp;
+      }
+
+    // Add zero elements to sums
+    acc2 += std::norm(acc1) * T(N - length);
+    acc3 += acc1 * T(N - length);
+
+    const T norm_val = (norm_type == 0) ? T(N - 1) : T(N);
+    const T var_val  = (acc2 - std::norm(acc3) / T(N)) / norm_val;
+
+    return var_val;
+    }
+  else if(length == 1 && N > 1) // if N == 1, then variance is zero.
+    {
+    const eT mean = X[0] / T(N);
+    const eT val = mean - X[0];
+
+    const T acc2 = std::norm(val) + (N - length) * std::norm(mean);
+    const eT acc3 = val + T(N - length) * mean;
+
+    const T norm_val = (norm_type == 0) ? T(N - 1) : T(N);
+    const T var_val  = (acc2 - std::norm(acc3) / T(N)) / norm_val;
+
+    return var_val;
+    }
+  else
+    {
+    return T(0); // All elements are zero
+    }
+  }
+
+
+
+template<typename T1, typename eT>
+inline
+eT
+spop_var::iterator_var
+  (
+  T1& it,
+  const T1& end,
+  const uword n_zero,
+  const uword norm_type,
+  const eT junk1,
+  const typename arma_not_cx<eT>::result* junk2
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+
+  T1 new_it(it); // for mean
+  // T1 backup_it(it); // in case we have to call robust iterator_var
+  eT mean = spop_mean::iterator_mean(new_it, end, n_zero, eT(0));
+
+  eT acc2 = eT(0);
+  eT acc3 = eT(0);
+
+  const uword it_begin_pos = it.pos();
+
+  while (it != end)
+    {
+    const eT tmp = mean - (*it);
+
+    acc2 += (tmp * tmp);
+    acc3 += (tmp);
+
+    ++it;
+    }
+
+  const uword n_nonzero = (it.pos() - it_begin_pos);
+  if (n_nonzero == 0)
+    {
+    return eT(0);
+    }
+
+  if (n_nonzero + n_zero == 1)
+    {
+    return eT(0); // only one element
+    }
+
+  // Add in entries for zeros.
+  acc2 += eT(n_zero) * (mean * mean);
+  acc3 += eT(n_zero) * mean;
+
+  const eT norm_val = (norm_type == 0) ? eT(n_zero + n_nonzero - 1) : eT(n_zero + n_nonzero);
+  const eT var_val  = (acc2 - (acc3 * acc3) / eT(n_nonzero + n_zero)) / norm_val;
+
+  return var_val;
+  }
+
+
+
+template<typename T1, typename eT>
+inline
+typename get_pod_type<eT>::result
+spop_var::iterator_var
+  (
+  T1& it,
+  const T1& end,
+  const uword n_zero,
+  const uword norm_type,
+  const eT junk1,
+  const typename arma_cx_only<eT>::result* junk2
+  )
+  {
+  arma_extra_debug_sigprint();
+  arma_ignore(junk1);
+  arma_ignore(junk2);
+
+  typedef typename get_pod_type<eT>::result T;
+
+  T1 new_it(it); // for mean
+  // T1 backup_it(it); // in case we have to call robust iterator_var
+  eT mean = spop_mean::iterator_mean(new_it, end, n_zero, eT(0));
+
+   T acc2 =  T(0);
+  eT acc3 = eT(0);
+
+  const uword it_begin_pos = it.pos();
+
+  while (it != end)
+    {
+    eT tmp = mean - (*it);
+
+    acc2 += std::norm(tmp);
+    acc3 += (tmp);
+
+    ++it;
+    }
+
+  const uword n_nonzero = (it.pos() - it_begin_pos);
+  if (n_nonzero == 0)
+    {
+    return T(0);
+    }
+
+  if (n_nonzero + n_zero == 1)
+    {
+    return T(0); // only one element
+    }
+
+  // Add in entries for zero elements.
+  acc2 += T(n_zero) * std::norm(mean);
+  acc3 += T(n_zero) * mean;
+
+  const T norm_val = (norm_type == 0) ? T(n_zero + n_nonzero - 1) : T(n_zero + n_nonzero);
+  const T var_val  = (acc2 - std::norm(acc3) / T(n_nonzero + n_zero)) / norm_val;
+
+  return var_val;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/strip.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,93 @@
+// Copyright (C) 2010-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup strip
+//! @{
+
+
+
+template<typename T1>
+struct strip_diagmat
+  {
+  typedef T1 stored_type;
+  
+  arma_hot inline
+  strip_diagmat(const T1& X)
+    : M(X)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  static const bool do_diagmat = false;
+  
+  const T1& M;
+  };
+
+
+
+template<typename T1>
+struct strip_diagmat< Op<T1, op_diagmat> >
+  {
+  typedef T1 stored_type;
+  
+  arma_hot inline
+  strip_diagmat(const Op<T1, op_diagmat>& X)
+    : M(X.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  static const bool do_diagmat = true;
+  
+  const T1& M;
+  };
+
+
+
+template<typename T1>
+struct strip_inv
+  {
+  typedef T1 stored_type;
+  
+  arma_hot inline
+  strip_inv(const T1& X)
+    : M(X)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const T1& M;
+  
+  static const bool slow   = false;
+  static const bool do_inv = false;
+  };
+
+
+
+template<typename T1>
+struct strip_inv< Op<T1, op_inv> >
+  {
+  typedef T1 stored_type;
+  
+  arma_hot inline
+  strip_inv(const Op<T1, op_inv>& X)
+    : M(X.m)
+    , slow(X.aux_uword_a == 1)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const T1&  M;
+  const bool slow;
+  
+  static const bool do_inv = true;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/subview_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,369 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// Copyright (C)      2011 James Sanders
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup subview
+//! @{
+
+
+//! Class for storing data required to construct or apply operations to a submatrix
+//! (i.e. where the submatrix starts and ends as well as a reference/pointer to the original matrix),
+template<typename eT>
+class subview : public Base<eT, subview<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  arma_aligned const Mat<eT>& m;
+  
+  static const bool is_row = false;
+  static const bool is_col = false;
+  
+  const uword aux_row1;
+  const uword aux_col1;
+  
+  const uword n_rows;
+  const uword n_cols;
+  const uword n_elem;
+  
+  protected:
+  
+  arma_inline subview(const Mat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols);
+  
+  
+  public:
+  
+  inline ~subview();
+  
+  inline void operator+= (const eT val);
+  inline void operator-= (const eT val);
+  inline void operator*= (const eT val);
+  inline void operator/= (const eT val);
+  
+  // deliberately returning void
+  template<typename T1> inline void operator=  (const Base<eT,T1>& x);
+  template<typename T1> inline void operator+= (const Base<eT,T1>& x);
+  template<typename T1> inline void operator-= (const Base<eT,T1>& x);
+  template<typename T1> inline void operator%= (const Base<eT,T1>& x);
+  template<typename T1> inline void operator/= (const Base<eT,T1>& x);
+  
+  inline void operator=  (const subview& x);
+  inline void operator+= (const subview& x);
+  inline void operator-= (const subview& x);
+  inline void operator%= (const subview& x);
+  inline void operator/= (const subview& x);
+  
+  inline static void extract(Mat<eT>& out, const subview& in);
+  
+  inline static void  plus_inplace(Mat<eT>& out, const subview& in);
+  inline static void minus_inplace(Mat<eT>& out, const subview& in);
+  inline static void schur_inplace(Mat<eT>& out, const subview& in);
+  inline static void   div_inplace(Mat<eT>& out, const subview& in);
+  
+  template<typename functor> inline void transform(functor F);
+  template<typename functor> inline void     imbue(functor F);
+  
+  inline void fill(const eT val);
+  inline void zeros();
+  inline void ones();
+  inline void eye();
+  
+  inline eT  at_alt    (const uword ii) const;
+  
+  inline eT& operator[](const uword ii);
+  inline eT  operator[](const uword ii) const;
+  
+  inline eT& operator()(const uword ii);
+  inline eT  operator()(const uword ii) const;
+  
+  inline eT& operator()(const uword in_row, const uword in_col);
+  inline eT  operator()(const uword in_row, const uword in_col) const;
+  
+  inline eT&         at(const uword in_row, const uword in_col);
+  inline eT          at(const uword in_row, const uword in_col) const;
+  
+  arma_inline       eT* colptr(const uword in_col);
+  arma_inline const eT* colptr(const uword in_col) const;
+  
+  inline bool check_overlap(const subview& x) const;
+  
+  inline bool is_vec() const;
+  
+  inline       subview_row<eT> row(const uword row_num);
+  inline const subview_row<eT> row(const uword row_num) const;
+  
+  inline            subview_row<eT> operator()(const uword row_num, const span& col_span);
+  inline      const subview_row<eT> operator()(const uword row_num, const span& col_span) const;
+  
+  inline       subview_col<eT> col(const uword col_num);
+  inline const subview_col<eT> col(const uword col_num) const;
+  
+  inline            subview_col<eT> operator()(const span& row_span, const uword col_num);
+  inline      const subview_col<eT> operator()(const span& row_span, const uword col_num) const;
+  
+  inline            Col<eT>  unsafe_col(const uword col_num);
+  inline      const Col<eT>  unsafe_col(const uword col_num) const;
+  
+  inline       subview<eT> rows(const uword in_row1, const uword in_row2);
+  inline const subview<eT> rows(const uword in_row1, const uword in_row2) const;
+  
+  inline       subview<eT> cols(const uword in_col1, const uword in_col2);
+  inline const subview<eT> cols(const uword in_col1, const uword in_col2) const;
+  
+  inline       subview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2);
+  inline const subview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const;
+  
+  inline            subview<eT> submat    (const span& row_span, const span& col_span);
+  inline      const subview<eT> submat    (const span& row_span, const span& col_span) const;
+  
+  inline            subview<eT> operator()(const span& row_span, const span& col_span);
+  inline      const subview<eT> operator()(const span& row_span, const span& col_span) const;
+  
+  inline subview_each1< subview<eT>, 0 > each_col();
+  inline subview_each1< subview<eT>, 1 > each_row();
+  
+  template<typename T1> inline subview_each2< subview<eT>, 0, T1 > each_col(const Base<uword, T1>& indices);
+  template<typename T1> inline subview_each2< subview<eT>, 1, T1 > each_row(const Base<uword, T1>& indices);
+  
+  inline       diagview<eT> diag(const sword in_id = 0);
+  inline const diagview<eT> diag(const sword in_id = 0) const;
+  
+  inline void swap_rows(const uword in_row1, const uword in_row2);
+  inline void swap_cols(const uword in_col1, const uword in_col2);
+  
+  
+  // // primitive forward iterator
+  // class iter
+  //   {
+  //   public:
+  //   
+  //   inline iter(const subview<eT>& in_M);
+  //   
+  //   arma_inline eT operator* () const;
+  //   
+  //   inline void operator++();
+  //   inline void operator++(int);
+  //   
+  //   
+  //   private:
+  //   
+  //   arma_aligned const eT* mem;
+  //   
+  //   arma_aligned uword n_rows;
+  //   
+  //   arma_aligned uword row_start;
+  //   arma_aligned uword row_end_p1;
+  //   
+  //   arma_aligned uword row;
+  //   arma_aligned uword col;
+  //   arma_aligned uword i;
+  //   };
+  
+  
+  private:
+  
+  friend class Mat<eT>;
+  subview();
+  };
+
+
+
+template<typename eT>
+class subview_col : public subview<eT>
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  const eT* colmem;
+  
+  inline void operator= (const subview<eT>& x);
+  inline void operator= (const subview_col& x);
+  
+  template<typename T1>
+  inline void operator= (const Base<eT,T1>& x);
+  
+  arma_inline const Op<subview_col<eT>,op_htrans>  t() const;
+  arma_inline const Op<subview_col<eT>,op_htrans> ht() const;
+  arma_inline const Op<subview_col<eT>,op_strans> st() const;
+  
+  arma_inline eT  at_alt    (const uword i) const;
+  
+  arma_inline eT& operator[](const uword i);
+  arma_inline eT  operator[](const uword i) const;
+  
+  inline eT& operator()(const uword i);
+  inline eT  operator()(const uword i) const;
+  
+  inline eT& operator()(const uword in_row, const uword in_col);
+  inline eT  operator()(const uword in_row, const uword in_col) const;
+  
+  inline eT&         at(const uword in_row, const uword in_col);
+  inline eT          at(const uword in_row, const uword in_col) const;
+  
+  arma_inline       eT* colptr(const uword in_col);
+  arma_inline const eT* colptr(const uword in_col) const;
+  
+  inline       subview_col<eT> rows(const uword in_row1, const uword in_row2);
+  inline const subview_col<eT> rows(const uword in_row1, const uword in_row2) const;
+  
+  inline       subview_col<eT> subvec(const uword in_row1, const uword in_row2);
+  inline const subview_col<eT> subvec(const uword in_row1, const uword in_row2) const;
+  
+  // TODO: add operator()(span)
+  
+  protected:
+  
+  inline subview_col(const Mat<eT>& in_m, const uword in_col);
+  inline subview_col(const Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows);
+  
+  
+  private:
+  
+  friend class Mat<eT>;
+  friend class Col<eT>;
+  friend class subview<eT>;
+  
+  subview_col();
+  };
+
+
+
+template<typename eT>
+class subview_row : public subview<eT>
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool is_row = true;
+  static const bool is_col = false;
+  
+  inline void operator= (const subview<eT>& x);
+  inline void operator= (const subview_row& x);
+  
+  template<typename T1>
+  inline void operator= (const Base<eT,T1>& x);
+  
+  arma_inline const Op<subview_row<eT>,op_htrans>  t() const;
+  arma_inline const Op<subview_row<eT>,op_htrans> ht() const;
+  arma_inline const Op<subview_row<eT>,op_strans> st() const;
+  
+  inline eT  at_alt    (const uword i) const;
+  
+  inline eT& operator[](const uword i);
+  inline eT  operator[](const uword i) const;
+  
+  inline eT& operator()(const uword i);
+  inline eT  operator()(const uword i) const;
+  
+  inline eT& operator()(const uword in_row, const uword in_col);
+  inline eT  operator()(const uword in_row, const uword in_col) const;
+  
+  inline eT&         at(const uword in_row, const uword in_col);
+  inline eT          at(const uword in_row, const uword in_col) const;
+  
+  inline       subview_row<eT> cols(const uword in_col1, const uword in_col2);
+  inline const subview_row<eT> cols(const uword in_col1, const uword in_col2) const;
+  
+  inline       subview_row<eT> subvec(const uword in_col1, const uword in_col2);
+  inline const subview_row<eT> subvec(const uword in_col1, const uword in_col2) const;
+  
+  // TODO: add operator()(span)
+  
+  protected:
+  
+  inline subview_row(const Mat<eT>& in_m, const uword in_row);
+  inline subview_row(const Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols);
+  
+  
+  private:
+  
+  friend class Mat<eT>;
+  friend class Row<eT>;
+  friend class subview<eT>;
+  
+  subview_row();
+  };
+
+
+
+template<typename eT>
+class subview_row_strans : public Base<eT, subview_row_strans<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const subview_row<eT>& sv_row;
+  
+         const uword n_rows;     // equal to n_elem
+         const uword n_elem;
+  static const uword n_cols = 1;
+  
+  
+  inline explicit subview_row_strans(const subview_row<eT>& in_sv_row);
+  
+  inline void extract(Mat<eT>& out) const;
+  
+  inline eT  at_alt    (const uword i) const;
+  
+  inline eT  operator[](const uword i) const;
+  inline eT  operator()(const uword i) const;
+  
+  inline eT  operator()(const uword in_row, const uword in_col) const;
+  inline eT          at(const uword in_row, const uword in_col) const;
+  };
+
+
+
+template<typename eT>
+class subview_row_htrans : public Base<eT, subview_row_htrans<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const subview_row<eT>& sv_row;
+  
+         const uword n_rows;     // equal to n_elem
+         const uword n_elem;
+  static const uword n_cols = 1;
+  
+  
+  inline explicit subview_row_htrans(const subview_row<eT>& in_sv_row);
+  
+  inline void extract(Mat<eT>& out) const;
+  
+  inline eT  at_alt    (const uword i) const;
+  
+  inline eT  operator[](const uword i) const;
+  inline eT  operator()(const uword i) const;
+  
+  inline eT  operator()(const uword in_row, const uword in_col) const;
+  inline eT          at(const uword in_row, const uword in_col) const;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/subview_cube_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,119 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup subview_cube
+//! @{
+
+
+//! Class for storing data required to construct or apply operations to a subcube
+//! (i.e. where the subcube starts and ends as well as a reference/pointer to the original cube),
+template<typename eT>
+class subview_cube : public BaseCube<eT, subview_cube<eT> >
+  {
+  public:    
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  arma_aligned const Cube<eT>& m;
+  
+  const uword aux_row1;
+  const uword aux_col1;
+  const uword aux_slice1;
+  
+  const uword n_rows;
+  const uword n_cols;
+  const uword n_elem_slice;
+  const uword n_slices;
+  const uword n_elem;
+  
+  
+  protected:
+  
+  arma_inline subview_cube(const Cube<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_n_rows, const uword in_n_cols, const uword in_n_slices);
+  
+  
+  public:
+  
+  inline ~subview_cube();
+  
+  inline void operator+= (const eT val);
+  inline void operator-= (const eT val);
+  inline void operator*= (const eT val);
+  inline void operator/= (const eT val);
+  
+  // deliberately returning void
+  template<typename T1> inline void operator=  (const BaseCube<eT,T1>& x);
+  template<typename T1> inline void operator+= (const BaseCube<eT,T1>& x);
+  template<typename T1> inline void operator-= (const BaseCube<eT,T1>& x);
+  template<typename T1> inline void operator%= (const BaseCube<eT,T1>& x);
+  template<typename T1> inline void operator/= (const BaseCube<eT,T1>& x);
+  
+  inline void operator=  (const subview_cube& x);
+  inline void operator+= (const subview_cube& x);
+  inline void operator-= (const subview_cube& x);
+  inline void operator%= (const subview_cube& x);
+  inline void operator/= (const subview_cube& x);
+  
+  template<typename T1> inline void operator=  (const Base<eT,T1>& x);
+  template<typename T1> inline void operator+= (const Base<eT,T1>& x);
+  template<typename T1> inline void operator-= (const Base<eT,T1>& x);
+  template<typename T1> inline void operator%= (const Base<eT,T1>& x);
+  template<typename T1> inline void operator/= (const Base<eT,T1>& x);
+
+  inline static void       extract(Cube<eT>& out, const subview_cube& in);
+  inline static void  plus_inplace(Cube<eT>& out, const subview_cube& in);
+  inline static void minus_inplace(Cube<eT>& out, const subview_cube& in);
+  inline static void schur_inplace(Cube<eT>& out, const subview_cube& in);
+  inline static void   div_inplace(Cube<eT>& out, const subview_cube& in);
+  
+  inline static void       extract(Mat<eT>& out, const subview_cube& in);
+  inline static void  plus_inplace(Mat<eT>& out, const subview_cube& in);
+  inline static void minus_inplace(Mat<eT>& out, const subview_cube& in);
+  inline static void schur_inplace(Mat<eT>& out, const subview_cube& in);
+  inline static void   div_inplace(Mat<eT>& out, const subview_cube& in);
+  
+  template<typename functor> inline void transform(functor F);
+  template<typename functor> inline void     imbue(functor F);
+  
+  inline void fill(const eT val);
+  inline void zeros();
+  inline void ones();
+  
+  inline eT  at_alt    (const uword i) const;
+  
+  inline eT& operator[](const uword i);
+  inline eT  operator[](const uword i) const;
+  
+  inline eT& operator()(const uword i);
+  inline eT  operator()(const uword i) const;
+  
+  arma_inline eT& operator()(const uword in_row, const uword in_col, const uword in_slice);
+  arma_inline eT  operator()(const uword in_row, const uword in_col, const uword in_slice) const;
+  
+  arma_inline eT&         at(const uword in_row, const uword in_col, const uword in_slice);
+  arma_inline eT          at(const uword in_row, const uword in_col, const uword in_slice) const;
+  
+  arma_inline       eT* slice_colptr(const uword in_slice, const uword in_col);
+  arma_inline const eT* slice_colptr(const uword in_slice, const uword in_col) const;
+  
+  inline bool check_overlap(const subview_cube& x) const;
+  inline bool check_overlap(const Mat<eT>&      x) const;
+  
+  
+  private:
+  
+  friend class  Mat<eT>;
+  friend class Cube<eT>;
+  
+  subview_cube();
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/subview_cube_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,1787 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup subview_cube
+//! @{
+
+
+template<typename eT>
+inline
+subview_cube<eT>::~subview_cube()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+arma_inline
+subview_cube<eT>::subview_cube
+  (
+  const Cube<eT>& in_m,
+  const uword       in_row1,
+  const uword       in_col1,
+  const uword       in_slice1,
+  const uword       in_n_rows,
+  const uword       in_n_cols,
+  const uword       in_n_slices
+  )
+  : m           (in_m)
+  , aux_row1    (in_row1)
+  , aux_col1    (in_col1)
+  , aux_slice1  (in_slice1)
+  , n_rows      (in_n_rows)
+  , n_cols      (in_n_cols)
+  , n_elem_slice(in_n_rows * in_n_cols)
+  , n_slices    (in_n_slices)
+  , n_elem      (n_elem_slice * in_n_slices)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_cube<eT>::operator+= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword local_n_rows   = n_rows;
+  const uword local_n_cols   = n_cols;
+  const uword local_n_slices = n_slices;
+  
+  for(uword slice = 0; slice < local_n_slices; ++slice)
+    {
+    for(uword col = 0; col < local_n_cols; ++col)
+      {
+      arrayops::inplace_plus( slice_colptr(slice,col), val, local_n_rows );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_cube<eT>::operator-= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword local_n_rows   = n_rows;
+  const uword local_n_cols   = n_cols;
+  const uword local_n_slices = n_slices;
+  
+  for(uword slice = 0; slice < local_n_slices; ++slice)
+    {
+    for(uword col = 0; col < local_n_cols; ++col)
+      {
+      arrayops::inplace_minus( slice_colptr(slice,col), val, local_n_rows );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_cube<eT>::operator*= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword local_n_rows   = n_rows;
+  const uword local_n_cols   = n_cols;
+  const uword local_n_slices = n_slices;
+  
+  for(uword slice = 0; slice < local_n_slices; ++slice)
+    {
+    for(uword col = 0; col < local_n_cols; ++col)
+      {
+      arrayops::inplace_mul( slice_colptr(slice,col), val, local_n_rows );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_cube<eT>::operator/= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword local_n_rows   = n_rows;
+  const uword local_n_cols   = n_cols;
+  const uword local_n_slices = n_slices;
+  
+  for(uword slice = 0; slice < local_n_slices; ++slice)
+    {
+    for(uword col = 0; col < local_n_cols; ++col)
+      {
+      arrayops::inplace_div( slice_colptr(slice,col), val, local_n_rows );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview_cube<eT>::operator= (const BaseCube<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap_cube<T1> tmp(in.get_ref());
+  
+  const Cube<eT>&         x = tmp.M;
+        subview_cube<eT>& t = *this;
+  
+  arma_debug_assert_same_size(t, x, "copy into subcube");
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  for(uword slice = 0; slice < t_n_slices; ++slice)
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::copy( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview_cube<eT>::operator+= (const BaseCube<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap_cube<T1> tmp(in.get_ref());
+  
+  const Cube<eT>&         x = tmp.M;
+        subview_cube<eT>& t = *this;
+  
+  arma_debug_assert_same_size(t, x, "addition");
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  for(uword slice = 0; slice < t_n_slices; ++slice)
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::inplace_plus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview_cube<eT>::operator-= (const BaseCube<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap_cube<T1> tmp(in.get_ref());
+  
+  const Cube<eT>&         x = tmp.M;
+        subview_cube<eT>& t = *this;
+  
+  arma_debug_assert_same_size(t, x, "subtraction");
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  for(uword slice = 0; slice < t_n_slices; ++slice)
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::inplace_minus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview_cube<eT>::operator%= (const BaseCube<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap_cube<T1> tmp(in.get_ref());
+  
+  const Cube<eT>&         x = tmp.M;
+        subview_cube<eT>& t = *this;
+  
+  arma_debug_assert_same_size(t, x, "element-wise multiplication");
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  for(uword slice = 0; slice < t_n_slices; ++slice)
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::inplace_mul( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview_cube<eT>::operator/= (const BaseCube<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap_cube<T1> tmp(in.get_ref());
+  
+  const Cube<eT>&         x = tmp.M;
+        subview_cube<eT>& t = *this;
+  
+  arma_debug_assert_same_size(t, x, "element-wise division");
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  for(uword slice = 0; slice < t_n_slices; ++slice)
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
+      }
+    }
+  }
+
+
+
+//! x.subcube(...) = y.subcube(...)
+template<typename eT>
+inline
+void
+subview_cube<eT>::operator= (const subview_cube<eT>& x_in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool overlap = check_overlap(x_in);
+  
+        Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
+  const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
+  const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
+  
+  subview_cube<eT>& t = *this;
+  
+  arma_debug_assert_same_size(t, x, "copy into subcube");
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  for(uword slice = 0; slice < t_n_slices; ++slice)
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::copy( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
+      }
+    }
+    
+  if(overlap)
+    {
+    delete tmp_subview_cube;
+    delete tmp_cube;
+    }
+  
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_cube<eT>::operator+= (const subview_cube<eT>& x_in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool overlap = check_overlap(x_in);
+  
+        Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
+  const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
+  const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
+  
+  subview_cube<eT>& t = *this;
+  
+  arma_debug_assert_same_size(t, x, "addition");
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  for(uword slice = 0; slice < t_n_slices; ++slice)
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::inplace_plus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
+      }
+    }
+  
+  if(overlap)
+    {
+    delete tmp_subview_cube;
+    delete tmp_cube;
+    }
+  
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_cube<eT>::operator-= (const subview_cube<eT>& x_in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool overlap = check_overlap(x_in);
+  
+        Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
+  const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
+  const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
+  
+  subview_cube<eT>& t = *this;
+  
+  arma_debug_assert_same_size(t, x, "subtraction");
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  for(uword slice = 0; slice < t_n_slices; ++slice)
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::inplace_minus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
+      }
+    }
+  
+  if(overlap)
+    {
+    delete tmp_subview_cube;
+    delete tmp_cube;
+    }
+    
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_cube<eT>::operator%= (const subview_cube<eT>& x_in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool overlap = check_overlap(x_in);
+  
+        Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
+  const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
+  const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
+  
+  subview_cube<eT>& t = *this;
+  
+  arma_debug_assert_same_size(t, x, "element-wise multiplication");
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  for(uword slice = 0; slice < t_n_slices; ++slice)
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::inplace_mul( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
+      }
+    }
+  
+  if(overlap)
+    {
+    delete tmp_subview_cube;
+    delete tmp_cube;
+    }
+  
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_cube<eT>::operator/= (const subview_cube<eT>& x_in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool overlap = check_overlap(x_in);
+  
+        Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
+  const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
+  const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
+  
+  subview_cube<eT>& t = *this;
+  
+  arma_debug_assert_same_size(t, x, "element-wise division");
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  for(uword slice = 0; slice < t_n_slices; ++slice)
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
+      }
+    }
+  
+  if(overlap)
+    {
+    delete tmp_subview_cube;
+    delete tmp_cube;
+    }
+  
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview_cube<eT>::operator= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap<T1> tmp(in.get_ref());
+  
+  const Mat<eT>&          x = tmp.M;
+        subview_cube<eT>& t = *this;
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  const uword x_n_rows   = x.n_rows;
+  const uword x_n_cols   = x.n_cols;
+  
+  if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
+    {
+    // interpret the matrix as a cube with one slice
+    
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::copy( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
+      }
+    }
+  else
+  if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
+    {
+    for(uword i=0; i < t_n_slices; ++i)
+      {
+      arrayops::copy( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
+      }
+    }
+  else
+  if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
+    {
+    Cube<eT>& Q = const_cast< Cube<eT>& >(t.m);
+    
+    const uword t_aux_row1   = t.aux_row1;
+    const uword t_aux_col1   = t.aux_col1;
+    const uword t_aux_slice1 = t.aux_slice1;
+    
+    for(uword slice=0; slice < t_n_slices; ++slice)
+      {
+      const uword mod_slice = t_aux_slice1 + slice;
+      
+      const eT* x_colptr = x.colptr(slice);
+      
+      uword i,j;
+      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
+        {
+        const eT tmp_i = x_colptr[i];
+        const eT tmp_j = x_colptr[j];
+        
+        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) = tmp_i;
+        Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) = tmp_j;
+        }
+      
+      if(i < t_n_cols)
+        {
+        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) = x_colptr[i];
+        }
+      }
+    }
+  else
+    {
+    if(arma_config::debug == true)
+      {
+      arma_stop( arma_incompat_size_string(t, x, "copy into subcube") );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview_cube<eT>::operator+= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap<T1> tmp(in.get_ref());
+  
+  const Mat<eT>&          x = tmp.M;
+        subview_cube<eT>& t = *this;
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  const uword x_n_rows   = x.n_rows;
+  const uword x_n_cols   = x.n_cols;
+  
+  if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::inplace_plus( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
+      }
+    }
+  else
+  if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
+    {
+    for(uword i=0; i < t_n_slices; ++i)
+      {
+      arrayops::inplace_plus( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
+      }
+    }
+  else
+  if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
+    {
+    Cube<eT>& Q = const_cast< Cube<eT>& >(t.m);
+    
+    const uword t_aux_row1   = t.aux_row1;
+    const uword t_aux_col1   = t.aux_col1;
+    const uword t_aux_slice1 = t.aux_slice1;
+    
+    for(uword slice=0; slice < t_n_slices; ++slice)
+      {
+      const uword mod_slice = t_aux_slice1 + slice;
+      
+      const eT* x_colptr = x.colptr(slice);
+      
+      uword i,j;
+      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
+        {
+        const eT tmp_i = x_colptr[i];
+        const eT tmp_j = x_colptr[j];
+        
+        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) += tmp_i;
+        Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) += tmp_j;
+        }
+      
+      if(i < t_n_cols)
+        {
+        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) += x_colptr[i];
+        }
+      }
+    }
+  else
+    {
+    if(arma_config::debug == true)
+      {
+      arma_stop( arma_incompat_size_string(t, x, "addition") );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview_cube<eT>::operator-= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap<T1> tmp(in.get_ref());
+  
+  const Mat<eT>&          x = tmp.M;
+        subview_cube<eT>& t = *this;
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  const uword x_n_rows   = x.n_rows;
+  const uword x_n_cols   = x.n_cols;
+  
+  if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::inplace_minus( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
+      }
+    }
+  else
+  if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
+    {
+    for(uword i=0; i < t_n_slices; ++i)
+      {
+      arrayops::inplace_minus( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
+      }
+    }
+  else
+  if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
+    {
+    Cube<eT>& Q = const_cast< Cube<eT>& >(t.m);
+    
+    const uword t_aux_row1   = t.aux_row1;
+    const uword t_aux_col1   = t.aux_col1;
+    const uword t_aux_slice1 = t.aux_slice1;
+    
+    for(uword slice=0; slice < t_n_slices; ++slice)
+      {
+      const uword mod_slice = t_aux_slice1 + slice;
+      
+      const eT* x_colptr = x.colptr(slice);
+      
+      uword i,j;
+      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
+        {
+        const eT tmp_i = x_colptr[i];
+        const eT tmp_j = x_colptr[j];
+        
+        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) -= tmp_i;
+        Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) -= tmp_j;
+        }
+      
+      if(i < t_n_cols)
+        {
+        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) -= x_colptr[i];
+        }
+      }
+    }
+  else
+    {
+    if(arma_config::debug == true)
+      {
+      arma_stop( arma_incompat_size_string(t, x, "subtraction") );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview_cube<eT>::operator%= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap<T1> tmp(in.get_ref());
+  
+  const Mat<eT>&          x = tmp.M;
+        subview_cube<eT>& t = *this;
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  const uword x_n_rows   = x.n_rows;
+  const uword x_n_cols   = x.n_cols;
+  
+  if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::inplace_mul( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
+      }
+    }
+  else
+  if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
+    {
+    for(uword i=0; i < t_n_slices; ++i)
+      {
+      arrayops::inplace_mul( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
+      }
+    }
+  else
+  if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
+    {
+    Cube<eT>& Q = const_cast< Cube<eT>& >(t.m);
+    
+    const uword t_aux_row1   = t.aux_row1;
+    const uword t_aux_col1   = t.aux_col1;
+    const uword t_aux_slice1 = t.aux_slice1;
+    
+    for(uword slice=0; slice < t_n_slices; ++slice)
+      {
+      const uword mod_slice = t_aux_slice1 + slice;
+      
+      const eT* x_colptr = x.colptr(slice);
+      
+      uword i,j;
+      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
+        {
+        const eT tmp_i = x_colptr[i];
+        const eT tmp_j = x_colptr[j];
+        
+        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) *= tmp_i;
+        Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) *= tmp_j;
+        }
+      
+      if(i < t_n_cols)
+        {
+        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) *= x_colptr[i];
+        }
+      }
+    }
+  else
+    {
+    if(arma_config::debug == true)
+      {
+      arma_stop( arma_incompat_size_string(t, x, "element-wise multiplication") );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview_cube<eT>::operator/= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap<T1> tmp(in.get_ref());
+  
+  const Mat<eT>&          x = tmp.M;
+        subview_cube<eT>& t = *this;
+  
+  const uword t_n_rows   = t.n_rows;
+  const uword t_n_cols   = t.n_cols;
+  const uword t_n_slices = t.n_slices;
+  
+  const uword x_n_rows   = x.n_rows;
+  const uword x_n_cols   = x.n_cols;
+  
+  if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
+    {
+    for(uword col = 0; col < t_n_cols; ++col)
+      {
+      arrayops::inplace_div( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
+      }
+    }
+  else
+  if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
+    {
+    for(uword i=0; i < t_n_slices; ++i)
+      {
+      arrayops::inplace_div( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
+      }
+    }
+  else
+  if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
+    {
+    Cube<eT>& Q = const_cast< Cube<eT>& >(t.m);
+    
+    const uword t_aux_row1   = t.aux_row1;
+    const uword t_aux_col1   = t.aux_col1;
+    const uword t_aux_slice1 = t.aux_slice1;
+    
+    for(uword slice=0; slice < t_n_slices; ++slice)
+      {
+      const uword mod_slice = t_aux_slice1 + slice;
+      
+      const eT* x_colptr = x.colptr(slice);
+      
+      uword i,j;
+      for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
+        {
+        const eT tmp_i = x_colptr[i];
+        const eT tmp_j = x_colptr[j];
+        
+        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) /= tmp_i;
+        Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) /= tmp_j;
+        }
+      
+      if(i < t_n_cols)
+        {
+        Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) /= x_colptr[i];
+        }
+      }
+    }
+  else
+    {
+    if(arma_config::debug == true)
+      {
+      arma_stop( arma_incompat_size_string(t, x, "element-wise division") );
+      }
+    }
+  }
+
+
+
+//! transform each element in the subview using a functor
+template<typename eT>
+template<typename functor>
+inline
+void
+subview_cube<eT>::transform(functor F)
+  {
+  arma_extra_debug_sigprint();
+  
+  Cube<eT>& Q = const_cast< Cube<eT>& >(m);
+  
+  const uword start_col   = aux_col1;
+  const uword start_row   = aux_row1;
+  const uword start_slice = aux_slice1;
+  
+  const uword end_col_plus1   = start_col   + n_cols;
+  const uword end_row_plus1   = start_row   + n_rows;
+  const uword end_slice_plus1 = start_slice + n_slices;
+  
+  for(uword uslice = start_slice; uslice < end_slice_plus1; ++uslice)
+  for(uword ucol   = start_col;     ucol < end_col_plus1;   ++ucol  )
+  for(uword urow   = start_row;     urow < end_row_plus1;   ++urow  )
+    {
+    Q.at(urow, ucol, uslice) = eT( F( Q.at(urow, ucol, uslice) ) );
+    }
+  }
+
+
+
+//! imbue (fill) the subview with values provided by a functor
+template<typename eT>
+template<typename functor>
+inline
+void
+subview_cube<eT>::imbue(functor F)
+  {
+  arma_extra_debug_sigprint();
+  
+  Cube<eT>& Q = const_cast< Cube<eT>& >(m);
+  
+  const uword start_col   = aux_col1;
+  const uword start_row   = aux_row1;
+  const uword start_slice = aux_slice1;
+  
+  const uword end_col_plus1   = start_col   + n_cols;
+  const uword end_row_plus1   = start_row   + n_rows;
+  const uword end_slice_plus1 = start_slice + n_slices;
+  
+  for(uword uslice = start_slice; uslice < end_slice_plus1; ++uslice)
+  for(uword ucol   = start_col;     ucol < end_col_plus1;   ++ucol  )
+  for(uword urow   = start_row;     urow < end_row_plus1;   ++urow  )
+    {
+    Q.at(urow, ucol, uslice) = eT( F() );
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_cube<eT>::fill(const eT val)
+  {
+  arma_extra_debug_sigprint();
+
+  const uword local_n_rows   = n_rows;
+  const uword local_n_cols   = n_cols;
+  const uword local_n_slices = n_slices;
+  
+  for(uword slice = 0; slice < local_n_slices; ++slice)
+    {
+    for(uword col = 0; col < local_n_cols; ++col)
+      {
+      arrayops::inplace_set( slice_colptr(slice,col), val, local_n_rows );
+      }
+    }
+  
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_cube<eT>::zeros()
+  {
+  arma_extra_debug_sigprint();
+  
+  fill(eT(0));
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_cube<eT>::ones()
+  {
+  arma_extra_debug_sigprint();
+  
+  fill(eT(1));
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_cube<eT>::at_alt(const uword i) const
+  {
+  return operator[](i);
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+subview_cube<eT>::operator[](const uword i)
+  {
+  const uword in_slice = i / n_elem_slice;
+  const uword offset   = in_slice * n_elem_slice;
+  const uword j        = i - offset;
+  
+  const uword in_col   = j / n_rows;
+  const uword in_row   = j % n_rows;
+
+  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return access::rw( (const_cast< Cube<eT>& >(m)).mem[index] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_cube<eT>::operator[](const uword i) const
+  {
+  const uword in_slice = i / n_elem_slice;
+  const uword offset   = in_slice * n_elem_slice;
+  const uword j        = i - offset;
+  
+  const uword in_col   = j / n_rows;
+  const uword in_row   = j % n_rows;
+
+  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return m.mem[index];
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+subview_cube<eT>::operator()(const uword i)
+  {
+  arma_debug_check( (i >= n_elem), "subview_cube::operator(): index out of bounds");
+  
+  const uword in_slice = i / n_elem_slice;
+  const uword offset   = in_slice * n_elem_slice;
+  const uword j        = i - offset;
+  
+  const uword in_col   = j / n_rows;
+  const uword in_row   = j % n_rows;
+
+  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return access::rw( (const_cast< Cube<eT>& >(m)).mem[index] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_cube<eT>::operator()(const uword i) const
+  {
+  arma_debug_check( (i >= n_elem), "subview_cube::operator(): index out of bounds");
+  
+  const uword in_slice = i / n_elem_slice;
+  const uword offset   = in_slice * n_elem_slice;
+  const uword j        = i - offset;
+  
+  const uword in_col   = j / n_rows;
+  const uword in_row   = j % n_rows;
+
+  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return m.mem[index];
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT&
+subview_cube<eT>::operator()(const uword in_row, const uword in_col, const uword in_slice)
+  {
+  arma_debug_check( ( (in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices) ), "subview_cube::operator(): location out of bounds");
+  
+  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return access::rw( (const_cast< Cube<eT>& >(m)).mem[index] );
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+subview_cube<eT>::operator()(const uword in_row, const uword in_col, const uword in_slice) const
+  {
+  arma_debug_check( ( (in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices) ), "subview_cube::operator(): location out of bounds");
+  
+  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return m.mem[index];
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT&
+subview_cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice)
+  {
+  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return access::rw( (const_cast< Cube<eT>& >(m)).mem[index] );
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+subview_cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice) const
+  {
+  const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return m.mem[index];
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT*
+subview_cube<eT>::slice_colptr(const uword in_slice, const uword in_col)
+  {
+  return & access::rw((const_cast< Cube<eT>& >(m)).mem[  (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1  ]);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const eT*
+subview_cube<eT>::slice_colptr(const uword in_slice, const uword in_col) const
+  {
+  return & m.mem[ (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 ];
+  }
+
+
+
+template<typename eT>
+inline
+bool
+subview_cube<eT>::check_overlap(const subview_cube<eT>& x) const
+  {
+  const subview_cube<eT>& t = *this;
+  
+  if(&t.m != &x.m)
+    {
+    return false;
+    }
+  else
+    {
+    if( (t.n_elem == 0) || (x.n_elem == 0) )
+      {
+      return false;
+      }
+    else
+      {
+      const uword t_row_start  = t.aux_row1;
+      const uword t_row_end_p1 = t_row_start + t.n_rows;
+      
+      const uword t_col_start  = t.aux_col1;
+      const uword t_col_end_p1 = t_col_start + t.n_cols;
+      
+      const uword t_slice_start  = t.aux_slice1;
+      const uword t_slice_end_p1 = t_slice_start + t.n_slices;
+      
+      
+      const uword x_row_start  = x.aux_row1;
+      const uword x_row_end_p1 = x_row_start + x.n_rows;
+      
+      const uword x_col_start  = x.aux_col1;
+      const uword x_col_end_p1 = x_col_start + x.n_cols;
+      
+      const uword x_slice_start  = x.aux_slice1;
+      const uword x_slice_end_p1 = x_slice_start + x.n_slices;
+      
+      
+      const bool outside_rows   = ( (x_row_start   >= t_row_end_p1  ) || (t_row_start   >= x_row_end_p1  ) );
+      const bool outside_cols   = ( (x_col_start   >= t_col_end_p1  ) || (t_col_start   >= x_col_end_p1  ) );
+      const bool outside_slices = ( (x_slice_start >= t_slice_end_p1) || (t_slice_start >= x_slice_end_p1) );
+      
+      return ( (outside_rows == false) && (outside_cols == false) && (outside_slices == false) );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+subview_cube<eT>::check_overlap(const Mat<eT>& x) const
+  {
+  const subview_cube<eT>& t = *this;
+  
+  const uword t_aux_slice1        = t.aux_slice1;
+  const uword t_aux_slice2_plus_1 = t_aux_slice1 + t.n_slices;
+  
+  for(uword slice = t_aux_slice1; slice < t_aux_slice2_plus_1; ++slice)
+    {
+    const Mat<eT>& y = *(t.m.mat_ptrs[slice]);
+  
+    if( x.memptr() == y.memptr() )
+      {
+      return true;
+      }
+    }
+  
+  return false;
+  }
+
+
+
+//! cube X = Y.subcube(...)
+template<typename eT>
+inline
+void
+subview_cube<eT>::extract(Cube<eT>& out, const subview_cube<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+
+  // NOTE: we're assuming that the cube has already been set to the correct size and there is no aliasing;
+  // size setting and alias checking is done by either the Cube contructor or operator=()
+  
+  const uword n_rows   = in.n_rows;
+  const uword n_cols   = in.n_cols;
+  const uword n_slices = in.n_slices;
+  
+  arma_extra_debug_print(arma_boost::format("out.n_rows = %d   out.n_cols = %d    out.n_slices = %d    in.m.n_rows = %d   in.m.n_cols = %d   in.m.n_slices = %d") % out.n_rows % out.n_cols % out.n_slices % in.m.n_rows % in.m.n_cols % in.m.n_slices);
+  
+  
+  for(uword slice = 0; slice < n_slices; ++slice)
+    {
+    for(uword col = 0; col < n_cols; ++col)
+      {
+      arrayops::copy( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
+      }
+    }
+  }
+
+
+
+//! cube X += Y.subcube(...)
+template<typename eT>
+inline
+void
+subview_cube<eT>::plus_inplace(Cube<eT>& out, const subview_cube<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out, in, "addition");
+  
+  const uword n_rows   = out.n_rows;
+  const uword n_cols   = out.n_cols;
+  const uword n_slices = out.n_slices;
+  
+  for(uword slice = 0; slice<n_slices; ++slice)
+    {
+    for(uword col = 0; col<n_cols; ++col)
+      {
+      arrayops::inplace_plus( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
+      }
+    }
+  }
+
+
+
+//! cube X -= Y.subcube(...)
+template<typename eT>
+inline
+void
+subview_cube<eT>::minus_inplace(Cube<eT>& out, const subview_cube<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out, in, "subtraction");
+  
+  const uword n_rows   = out.n_rows;
+  const uword n_cols   = out.n_cols;
+  const uword n_slices = out.n_slices;
+  
+  for(uword slice = 0; slice<n_slices; ++slice)
+    {
+    for(uword col = 0; col<n_cols; ++col)
+      {
+      arrayops::inplace_minus( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
+      }
+    }
+  }
+
+
+
+//! cube X %= Y.subcube(...)
+template<typename eT>
+inline
+void
+subview_cube<eT>::schur_inplace(Cube<eT>& out, const subview_cube<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out, in, "element-wise multiplication");
+  
+  const uword n_rows   = out.n_rows;
+  const uword n_cols   = out.n_cols;
+  const uword n_slices = out.n_slices;
+  
+  for(uword slice = 0; slice<n_slices; ++slice)
+    {
+    for(uword col = 0; col<n_cols; ++col)
+      {
+      arrayops::inplace_mul( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
+      }
+    }
+  }
+
+
+
+//! cube X /= Y.subcube(...)
+template<typename eT>
+inline
+void
+subview_cube<eT>::div_inplace(Cube<eT>& out, const subview_cube<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out, in, "element-wise division");
+  
+  const uword n_rows   = out.n_rows;
+  const uword n_cols   = out.n_cols;
+  const uword n_slices = out.n_slices;
+  
+  for(uword slice = 0; slice<n_slices; ++slice)
+    {
+    for(uword col = 0; col<n_cols; ++col)
+      {
+      arrayops::inplace_div( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
+      }
+    }
+  }
+
+
+
+//! mat X = Y.subcube(...)
+template<typename eT>
+inline
+void
+subview_cube<eT>::extract(Mat<eT>& out, const subview_cube<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_cube_as_mat(out, in, "copy into matrix", false);
+  
+  const uword in_n_rows   = in.n_rows;
+  const uword in_n_cols   = in.n_cols;
+  const uword in_n_slices = in.n_slices;
+  
+  const uword out_vec_state = out.vec_state;
+  
+  if(in_n_slices == 1)
+    {
+    out.set_size(in_n_rows, in_n_cols);
+    
+    for(uword col=0; col < in_n_cols; ++col)
+      {
+      arrayops::copy( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
+      }
+    }
+  else
+    {
+    if(out_vec_state == 0)
+      {
+      if(in_n_cols == 1)
+        {
+        out.set_size(in_n_rows, in_n_slices);
+        
+        for(uword i=0; i < in_n_slices; ++i)
+          {
+          arrayops::copy( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
+          }
+        }
+      else
+      if(in_n_rows == 1)
+        {
+        const Cube<eT>& Q = in.m;
+        
+        const uword in_aux_row1   = in.aux_row1;
+        const uword in_aux_col1   = in.aux_col1;
+        const uword in_aux_slice1 = in.aux_slice1;
+        
+        out.set_size(in_n_cols, in_n_slices);
+        
+        for(uword slice=0; slice < in_n_slices; ++slice)
+          {
+          const uword mod_slice = in_aux_slice1 + slice;
+          
+          eT* out_colptr = out.colptr(slice);
+          
+          uword i,j;
+          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
+            {
+            const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
+            const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
+            
+            out_colptr[i] = tmp_i;
+            out_colptr[j] = tmp_j;
+            }
+          
+          if(i < in_n_cols)
+            {
+            out_colptr[i] = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
+            }
+          }
+        }
+      }
+    else
+      {
+      out.set_size(in_n_slices);
+      
+      eT* out_mem = out.memptr();
+      
+      const Cube<eT>& Q = in.m;
+      
+      const uword in_aux_row1   = in.aux_row1;
+      const uword in_aux_col1   = in.aux_col1;
+      const uword in_aux_slice1 = in.aux_slice1;
+      
+      for(uword i=0; i<in_n_slices; ++i)
+        {
+        out_mem[i] = Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
+        }
+      }
+    }
+  }
+
+
+
+//! mat X += Y.subcube(...)
+template<typename eT>
+inline
+void
+subview_cube<eT>::plus_inplace(Mat<eT>& out, const subview_cube<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_cube_as_mat(out, in, "addition", true);
+  
+  const uword in_n_rows   = in.n_rows;
+  const uword in_n_cols   = in.n_cols;
+  const uword in_n_slices = in.n_slices;
+  
+  const uword out_n_rows    = out.n_rows;
+  const uword out_n_cols    = out.n_cols;
+  const uword out_vec_state = out.vec_state;
+  
+  if(in_n_slices == 1)
+    {
+    for(uword col=0; col < in_n_cols; ++col)
+      {
+      arrayops::inplace_plus( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
+      }
+    }
+  else
+    {
+    if(out_vec_state == 0)
+      {
+      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
+        {
+        for(uword i=0; i < in_n_slices; ++i)
+          {
+          arrayops::inplace_plus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
+          }
+        }
+      else
+      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
+        {
+        const Cube<eT>& Q = in.m;
+        
+        const uword in_aux_row1   = in.aux_row1;
+        const uword in_aux_col1   = in.aux_col1;
+        const uword in_aux_slice1 = in.aux_slice1;
+        
+        for(uword slice=0; slice < in_n_slices; ++slice)
+          {
+          const uword mod_slice = in_aux_slice1 + slice;
+          
+          eT* out_colptr = out.colptr(slice);
+          
+          uword i,j;
+          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
+            {
+            const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
+            const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
+            
+            out_colptr[i] += tmp_i;
+            out_colptr[j] += tmp_j;
+            }
+          
+          if(i < in_n_cols)
+            {
+            out_colptr[i] += Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
+            }
+          }
+        }
+      }
+    else
+      {
+      eT* out_mem = out.memptr();
+      
+      const Cube<eT>& Q = in.m;
+      
+      const uword in_aux_row1   = in.aux_row1;
+      const uword in_aux_col1   = in.aux_col1;
+      const uword in_aux_slice1 = in.aux_slice1;
+      
+      for(uword i=0; i<in_n_slices; ++i)
+        {
+        out_mem[i] += Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
+        }
+      }
+    }
+  }
+
+
+
+//! mat X -= Y.subcube(...)
+template<typename eT>
+inline
+void
+subview_cube<eT>::minus_inplace(Mat<eT>& out, const subview_cube<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_cube_as_mat(out, in, "subtraction", true);
+  
+  const uword in_n_rows   = in.n_rows;
+  const uword in_n_cols   = in.n_cols;
+  const uword in_n_slices = in.n_slices;
+  
+  const uword out_n_rows    = out.n_rows;
+  const uword out_n_cols    = out.n_cols;
+  const uword out_vec_state = out.vec_state;
+  
+  if(in_n_slices == 1)
+    {
+    for(uword col=0; col < in_n_cols; ++col)
+      {
+      arrayops::inplace_minus( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
+      }
+    }
+  else
+    {
+    if(out_vec_state == 0)
+      {
+      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
+        {
+        for(uword i=0; i < in_n_slices; ++i)
+          {
+          arrayops::inplace_minus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
+          }
+        }
+      else
+      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
+        {
+        const Cube<eT>& Q = in.m;
+        
+        const uword in_aux_row1   = in.aux_row1;
+        const uword in_aux_col1   = in.aux_col1;
+        const uword in_aux_slice1 = in.aux_slice1;
+        
+        for(uword slice=0; slice < in_n_slices; ++slice)
+          {
+          const uword mod_slice = in_aux_slice1 + slice;
+          
+          eT* out_colptr = out.colptr(slice);
+          
+          uword i,j;
+          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
+            {
+            const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
+            const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
+            
+            out_colptr[i] -= tmp_i;
+            out_colptr[j] -= tmp_j;
+            }
+          
+          if(i < in_n_cols)
+            {
+            out_colptr[i] -= Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
+            }
+          }
+        }
+      }
+    else
+      {
+      eT* out_mem = out.memptr();
+      
+      const Cube<eT>& Q = in.m;
+      
+      const uword in_aux_row1   = in.aux_row1;
+      const uword in_aux_col1   = in.aux_col1;
+      const uword in_aux_slice1 = in.aux_slice1;
+      
+      for(uword i=0; i<in_n_slices; ++i)
+        {
+        out_mem[i] -= Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
+        }
+      }
+    }
+  }
+
+
+
+//! mat X %= Y.subcube(...)
+template<typename eT>
+inline
+void
+subview_cube<eT>::schur_inplace(Mat<eT>& out, const subview_cube<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_cube_as_mat(out, in, "element-wise multiplication", true);
+  
+  const uword in_n_rows   = in.n_rows;
+  const uword in_n_cols   = in.n_cols;
+  const uword in_n_slices = in.n_slices;
+  
+  const uword out_n_rows    = out.n_rows;
+  const uword out_n_cols    = out.n_cols;
+  const uword out_vec_state = out.vec_state;
+  
+  if(in_n_slices == 1)
+    {
+    for(uword col=0; col < in_n_cols; ++col)
+      {
+      arrayops::inplace_mul( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
+      }
+    }
+  else
+    {
+    if(out_vec_state == 0)
+      {
+      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
+        {
+        for(uword i=0; i < in_n_slices; ++i)
+          {
+          arrayops::inplace_mul( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
+          }
+        }
+      else
+      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
+        {
+        const Cube<eT>& Q = in.m;
+        
+        const uword in_aux_row1   = in.aux_row1;
+        const uword in_aux_col1   = in.aux_col1;
+        const uword in_aux_slice1 = in.aux_slice1;
+        
+        for(uword slice=0; slice < in_n_slices; ++slice)
+          {
+          const uword mod_slice = in_aux_slice1 + slice;
+          
+          eT* out_colptr = out.colptr(slice);
+          
+          uword i,j;
+          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
+            {
+            const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
+            const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
+            
+            out_colptr[i] *= tmp_i;
+            out_colptr[j] *= tmp_j;
+            }
+          
+          if(i < in_n_cols)
+            {
+            out_colptr[i] *= Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
+            }
+          }
+        }
+      }
+    else
+      {
+      eT* out_mem = out.memptr();
+      
+      const Cube<eT>& Q = in.m;
+      
+      const uword in_aux_row1   = in.aux_row1;
+      const uword in_aux_col1   = in.aux_col1;
+      const uword in_aux_slice1 = in.aux_slice1;
+      
+      for(uword i=0; i<in_n_slices; ++i)
+        {
+        out_mem[i] *= Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
+        }
+      }
+    }
+  }
+
+
+
+//! mat X /= Y.subcube(...)
+template<typename eT>
+inline
+void
+subview_cube<eT>::div_inplace(Mat<eT>& out, const subview_cube<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_cube_as_mat(out, in, "element-wise division", true);
+  
+  const uword in_n_rows   = in.n_rows;
+  const uword in_n_cols   = in.n_cols;
+  const uword in_n_slices = in.n_slices;
+  
+  const uword out_n_rows    = out.n_rows;
+  const uword out_n_cols    = out.n_cols;
+  const uword out_vec_state = out.vec_state;
+  
+  if(in_n_slices == 1)
+    {
+    for(uword col=0; col < in_n_cols; ++col)
+      {
+      arrayops::inplace_div( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
+      }
+    }
+  else
+    {
+    if(out_vec_state == 0)
+      {
+      if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
+        {
+        for(uword i=0; i < in_n_slices; ++i)
+          {
+          arrayops::inplace_div( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
+          }
+        }
+      else
+      if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
+        {
+        const Cube<eT>& Q = in.m;
+        
+        const uword in_aux_row1   = in.aux_row1;
+        const uword in_aux_col1   = in.aux_col1;
+        const uword in_aux_slice1 = in.aux_slice1;
+        
+        for(uword slice=0; slice < in_n_slices; ++slice)
+          {
+          const uword mod_slice = in_aux_slice1 + slice;
+          
+          eT* out_colptr = out.colptr(slice);
+          
+          uword i,j;
+          for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
+            {
+            const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
+            const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
+            
+            out_colptr[i] /= tmp_i;
+            out_colptr[j] /= tmp_j;
+            }
+          
+          if(i < in_n_cols)
+            {
+            out_colptr[i] /= Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
+            }
+          }
+        }
+      }
+    else
+      {
+      eT* out_mem = out.memptr();
+      
+      const Cube<eT>& Q = in.m;
+      
+      const uword in_aux_row1   = in.aux_row1;
+      const uword in_aux_col1   = in.aux_col1;
+      const uword in_aux_slice1 = in.aux_slice1;
+      
+      for(uword i=0; i<in_n_slices; ++i)
+        {
+        out_mem[i] /= Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
+        }
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/subview_each_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,115 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup subview_each
+//! @{
+
+
+
+template<typename parent, unsigned int mode>
+class subview_each_common
+  {
+  public:
+  
+  typedef typename parent::elem_type eT;
+  
+  
+  protected:
+  
+  parent& p;
+  
+  arma_inline subview_each_common(parent& in_p);
+  
+  arma_inline const Mat<typename parent::elem_type>& get_mat_ref_helper(const Mat    <typename parent::elem_type>& X) const;
+  arma_inline const Mat<typename parent::elem_type>& get_mat_ref_helper(const subview<typename parent::elem_type>& X) const;
+  
+  arma_inline const Mat<typename parent::elem_type>& get_mat_ref() const;
+  
+  inline void check_size(const Mat<typename parent::elem_type>& A) const;
+  
+  arma_cold inline const std::string incompat_size_string(const Mat<typename parent::elem_type>& A) const;
+  
+  
+  private:
+  
+  subview_each_common();
+  };
+
+
+
+
+template<typename parent, unsigned int mode>
+class subview_each1 : public subview_each_common<parent, mode>
+  {
+  protected:
+  
+  arma_inline subview_each1(parent& in_p);
+  
+  
+  public:
+  
+  typedef typename parent::elem_type eT;
+  
+  inline ~subview_each1();
+  
+  // deliberately returning void
+  template<typename T1> inline void operator=  (const Base<eT,T1>& x);
+  template<typename T1> inline void operator+= (const Base<eT,T1>& x);
+  template<typename T1> inline void operator-= (const Base<eT,T1>& x);
+  template<typename T1> inline void operator%= (const Base<eT,T1>& x);
+  template<typename T1> inline void operator/= (const Base<eT,T1>& x);
+  
+  
+  private:
+  
+  friend class Mat<eT>;
+  friend class subview<eT>;
+  
+  subview_each1();
+  };
+
+
+
+template<typename parent, unsigned int mode, typename TB>
+class subview_each2 : public subview_each_common<parent, mode>
+  {
+  protected:
+  
+  const Base<uword, TB>& base_indices;
+  
+  inline subview_each2(parent& in_p, const Base<uword, TB>& in_indices);
+  
+  inline void check_indices(const Mat<uword>& indices) const;
+  
+  
+  public:
+  
+  typedef typename parent::elem_type eT;
+  
+  inline ~subview_each2();
+  
+  // deliberately returning void
+  template<typename T1> inline void operator=  (const Base<eT,T1>& x);
+  template<typename T1> inline void operator+= (const Base<eT,T1>& x);
+  template<typename T1> inline void operator-= (const Base<eT,T1>& x);
+  template<typename T1> inline void operator%= (const Base<eT,T1>& x);
+  template<typename T1> inline void operator/= (const Base<eT,T1>& x);
+  
+  // TODO: add handling of scalars
+  
+  
+  private:
+  
+  friend class Mat<eT>;
+  friend class subview<eT>;
+  
+  subview_each2();
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/subview_each_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,637 @@
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup subview_each
+//! @{
+
+
+//
+//
+// subview_each_common
+
+template<typename parent, unsigned int mode>
+inline
+subview_each_common<parent,mode>::subview_each_common(parent& in_p)
+  : p(in_p)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename parent, unsigned int mode>
+arma_inline
+const Mat<typename parent::elem_type>&
+subview_each_common<parent,mode>::get_mat_ref_helper(const Mat<typename parent::elem_type>& X) const
+  {
+  return X;
+  }
+
+
+
+template<typename parent, unsigned int mode>
+arma_inline
+const Mat<typename parent::elem_type>&
+subview_each_common<parent,mode>::get_mat_ref_helper(const subview<typename parent::elem_type>& X) const
+  {
+  return X.m;
+  }
+
+
+
+template<typename parent, unsigned int mode>
+arma_inline
+const Mat<typename parent::elem_type>&
+subview_each_common<parent,mode>::get_mat_ref() const
+  {
+  return get_mat_ref_helper(p);
+  }
+
+
+
+template<typename parent, unsigned int mode>
+inline
+void
+subview_each_common<parent,mode>::check_size(const Mat<typename parent::elem_type>& A) const
+  {
+  if(arma_config::debug == true)
+    {
+    if(mode == 0)
+      {
+      if( (A.n_rows != p.n_rows) || (A.n_cols != 1) )
+        {
+        arma_stop( incompat_size_string(A) );
+        }
+      }
+    else
+      {
+      if( (A.n_rows != 1) || (A.n_cols != p.n_cols) )
+        {
+        arma_stop( incompat_size_string(A) );
+        }
+      }
+    }
+  }
+
+
+
+template<typename parent, unsigned int mode>
+arma_cold
+inline
+const std::string
+subview_each_common<parent,mode>::incompat_size_string(const Mat<typename parent::elem_type>& A) const
+  {
+  std::stringstream tmp;
+  
+  if(mode == 0)
+    {
+    tmp << "each_col(): incompatible size; expected " << p.n_rows << "x1" << ", got " << A.n_rows << 'x' << A.n_cols;
+    }
+  else
+    {
+    tmp << "each_row(): incompatible size; expected 1x" << p.n_cols << ", got " << A.n_rows << 'x' << A.n_cols;
+    }
+  
+  return tmp.str();
+  }
+  
+
+
+//
+//
+// subview_each1
+
+
+
+template<typename parent, unsigned int mode>
+inline
+subview_each1<parent,mode>::~subview_each1()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename parent, unsigned int mode>
+inline
+subview_each1<parent,mode>::subview_each1(parent& in_p)
+  : subview_each_common<parent,mode>::subview_each_common(in_p)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename parent, unsigned int mode>
+template<typename T1>
+inline
+void
+subview_each1<parent,mode>::operator= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  parent& p = subview_each_common<parent,mode>::p;
+  
+  const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
+  const Mat<eT>& A     = tmp.M;
+  
+  subview_each_common<parent,mode>::check_size(A);
+  
+  const eT*   A_mem    = A.memptr();
+  const uword p_n_rows = p.n_rows;
+  const uword p_n_cols = p.n_cols;
+  
+  if(mode == 0) // each column
+    {
+    for(uword i=0; i < p_n_cols; ++i)
+      {
+      arrayops::copy( p.colptr(i), A_mem, p_n_rows );
+      }
+    }
+  else // each row
+    {
+    for(uword i=0; i < p_n_cols; ++i)
+      {
+      arrayops::inplace_set( p.colptr(i), A_mem[i], p_n_rows);
+      }
+    }
+  }
+
+
+
+template<typename parent, unsigned int mode>
+template<typename T1>
+inline
+void
+subview_each1<parent,mode>::operator+= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  parent& p = subview_each_common<parent,mode>::p;
+  
+  const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
+  const Mat<eT>& A     = tmp.M;
+  
+  subview_each_common<parent,mode>::check_size(A);
+  
+  const eT*   A_mem    = A.memptr();
+  const uword p_n_rows = p.n_rows;
+  const uword p_n_cols = p.n_cols;
+    
+  if(mode == 0) // each column
+    {
+    for(uword i=0; i < p_n_cols; ++i)
+      {
+      arrayops::inplace_plus( p.colptr(i), A_mem, p_n_rows );
+      }
+    }
+  else // each row
+    {
+    for(uword i=0; i < p_n_cols; ++i)
+      {
+      arrayops::inplace_plus( p.colptr(i), A_mem[i], p_n_rows);
+      }
+    }
+  }
+
+
+
+template<typename parent, unsigned int mode>
+template<typename T1>
+inline
+void
+subview_each1<parent,mode>::operator-= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  parent& p = subview_each_common<parent,mode>::p;
+  
+  const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
+  const Mat<eT>& A     = tmp.M;
+  
+  subview_each_common<parent,mode>::check_size(A);
+  
+  const eT*   A_mem    = A.memptr();
+  const uword p_n_rows = p.n_rows;
+  const uword p_n_cols = p.n_cols;
+    
+  if(mode == 0) // each column
+    {
+    for(uword i=0; i < p_n_cols; ++i)
+      {
+      arrayops::inplace_minus( p.colptr(i), A_mem, p_n_rows );
+      }
+    }
+  else // each row
+    {
+    for(uword i=0; i < p_n_cols; ++i)
+      {
+      arrayops::inplace_minus( p.colptr(i), A_mem[i], p_n_rows);
+      }
+    }
+  }
+
+
+
+template<typename parent, unsigned int mode>
+template<typename T1>
+inline
+void
+subview_each1<parent,mode>::operator%= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  parent& p = subview_each_common<parent,mode>::p;
+  
+  const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
+  const Mat<eT>& A     = tmp.M;
+  
+  subview_each_common<parent,mode>::check_size(A);
+  
+  const eT*   A_mem    = A.memptr();
+  const uword p_n_rows = p.n_rows;
+  const uword p_n_cols = p.n_cols;
+  
+  if(mode == 0) // each column
+    {
+    for(uword i=0; i < p_n_cols; ++i)
+      {
+      arrayops::inplace_mul( p.colptr(i), A_mem, p_n_rows );
+      }
+    }
+  else // each row
+    {
+    for(uword i=0; i < p_n_cols; ++i)
+      {
+      arrayops::inplace_mul( p.colptr(i), A_mem[i], p_n_rows);
+      }
+    }
+  }
+
+
+
+template<typename parent, unsigned int mode>
+template<typename T1>
+inline
+void
+subview_each1<parent,mode>::operator/= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  parent& p = subview_each_common<parent,mode>::p;
+  
+  const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
+  const Mat<eT>& A     = tmp.M;
+  
+  subview_each_common<parent,mode>::check_size(A);
+  
+  const eT*   A_mem    = A.memptr();
+  const uword p_n_rows = p.n_rows;
+  const uword p_n_cols = p.n_cols;
+  
+  if(mode == 0) // each column
+    {
+    for(uword i=0; i < p_n_cols; ++i)
+      {
+      arrayops::inplace_div( p.colptr(i), A_mem, p_n_rows );
+      }
+    }
+  else // each row
+    {
+    for(uword i=0; i < p_n_cols; ++i)
+      {
+      arrayops::inplace_div( p.colptr(i), A_mem[i], p_n_rows);
+      }
+    }
+  }
+
+
+
+//
+//
+// subview_each2
+
+
+
+template<typename parent, unsigned int mode, typename TB>
+inline
+subview_each2<parent,mode,TB>::~subview_each2()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename parent, unsigned int mode, typename TB>
+inline
+subview_each2<parent,mode,TB>::subview_each2(parent& in_p, const Base<uword, TB>& in_indices)
+  : subview_each_common<parent,mode>::subview_each_common(in_p)
+  , base_indices(in_indices)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename parent, unsigned int mode, typename TB>
+inline
+void
+subview_each2<parent,mode,TB>::check_indices(const Mat<uword>& indices) const
+  {
+  if(mode == 0)
+    {
+    arma_debug_check( ((indices.is_vec() == false) && (indices.is_empty() == false)), "each_col(): list of indices must be a vector" );
+    }
+  else
+    {
+    arma_debug_check( ((indices.is_vec() == false) && (indices.is_empty() == false)), "each_row(): list of indices must be a vector" );
+    }
+  }
+
+
+
+template<typename parent, unsigned int mode, typename TB>
+template<typename T1>
+inline
+void
+subview_each2<parent,mode,TB>::operator= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  parent& p = subview_each_common<parent,mode>::p;
+  
+  const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
+  const Mat<eT>& A     = tmp.M;
+  
+  subview_each_common<parent,mode>::check_size(A);
+  
+  const unwrap_check_mixed<TB> tmp_indices( base_indices.get_ref(), (*this).get_mat_ref() );
+  const Mat<uword>& indices =  tmp_indices.M;
+  
+  check_indices(indices);
+  
+  const eT*   A_mem    = A.memptr();
+  const uword p_n_rows = p.n_rows;
+  const uword p_n_cols = p.n_cols;
+  
+  const uword* indices_mem = indices.memptr();
+  const uword  N           = indices.n_elem;
+  
+  if(mode == 0) // each column
+    {
+    for(uword i=0; i < N; ++i)
+      {
+      const uword col = indices_mem[i];
+      
+      arma_debug_check( (col > p_n_cols), "each_col(): index out of bounds" );
+      
+      arrayops::copy( p.colptr(col), A_mem, p_n_rows );
+      }
+    }
+  else // each row
+    {
+    for(uword i=0; i < N; ++i)
+      {
+      const uword row = indices_mem[i];
+      
+      arma_debug_check( (row > p_n_rows), "each_row(): index out of bounds" );
+      
+      for(uword col=0; col < p_n_cols; ++col)
+        {
+        p.at(row,col) = A_mem[col];
+        }
+      }
+    }
+  }
+
+
+
+template<typename parent, unsigned int mode, typename TB>
+template<typename T1>
+inline
+void
+subview_each2<parent,mode,TB>::operator+= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  parent& p = subview_each_common<parent,mode>::p;
+  
+  const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
+  const Mat<eT>& A     = tmp.M;
+  
+  subview_each_common<parent,mode>::check_size(A);
+  
+  const unwrap_check_mixed<TB> tmp_indices( base_indices.get_ref(), (*this).get_mat_ref() );
+  const Mat<uword>& indices =  tmp_indices.M;
+  
+  check_indices(indices);
+  
+  const eT*   A_mem    = A.memptr();
+  const uword p_n_rows = p.n_rows;
+  const uword p_n_cols = p.n_cols;
+  
+  const uword* indices_mem = indices.memptr();
+  const uword  N           = indices.n_elem;
+  
+  if(mode == 0) // each column
+    {
+    for(uword i=0; i < N; ++i)
+      {
+      const uword col = indices_mem[i];
+      
+      arma_debug_check( (col > p_n_cols), "each_col(): index out of bounds" );
+      
+      arrayops::inplace_plus( p.colptr(col), A_mem, p_n_rows );
+      }
+    }
+  else // each row
+    {
+    for(uword i=0; i < N; ++i)
+      {
+      const uword row = indices_mem[i];
+      
+      arma_debug_check( (row > p_n_rows), "each_row(): index out of bounds" );
+      
+      for(uword col=0; col < p_n_cols; ++col)
+        {
+        p.at(row,col) += A_mem[col];
+        }
+      }
+    }
+  }
+
+
+
+template<typename parent, unsigned int mode, typename TB>
+template<typename T1>
+inline
+void
+subview_each2<parent,mode,TB>::operator-= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  parent& p = subview_each_common<parent,mode>::p;
+  
+  const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
+  const Mat<eT>& A     = tmp.M;
+  
+  subview_each_common<parent,mode>::check_size(A);
+  
+  const unwrap_check_mixed<TB> tmp_indices( base_indices.get_ref(), (*this).get_mat_ref() );
+  const Mat<uword>& indices =  tmp_indices.M;
+  
+  check_indices(indices);
+  
+  const eT*   A_mem    = A.memptr();
+  const uword p_n_rows = p.n_rows;
+  const uword p_n_cols = p.n_cols;
+  
+  const uword* indices_mem = indices.memptr();
+  const uword  N           = indices.n_elem;
+  
+  if(mode == 0) // each column
+    {
+    for(uword i=0; i < N; ++i)
+      {
+      const uword col = indices_mem[i];
+      
+      arma_debug_check( (col > p_n_cols), "each_col(): index out of bounds" );
+      
+      arrayops::inplace_minus( p.colptr(col), A_mem, p_n_rows );
+      }
+    }
+  else // each row
+    {
+    for(uword i=0; i < N; ++i)
+      {
+      const uword row = indices_mem[i];
+      
+      arma_debug_check( (row > p_n_rows), "each_row(): index out of bounds" );
+      
+      for(uword col=0; col < p_n_cols; ++col)
+        {
+        p.at(row,col) -= A_mem[col];
+        }
+      }
+    }
+  }
+
+
+
+template<typename parent, unsigned int mode, typename TB>
+template<typename T1>
+inline
+void
+subview_each2<parent,mode,TB>::operator%= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  parent& p = subview_each_common<parent,mode>::p;
+  
+  const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
+  const Mat<eT>& A     = tmp.M;
+  
+  subview_each_common<parent,mode>::check_size(A);
+  
+  const unwrap_check_mixed<TB> tmp_indices( base_indices.get_ref(), (*this).get_mat_ref() );
+  const Mat<uword>& indices =  tmp_indices.M;
+  
+  check_indices(indices);
+  
+  const eT*   A_mem    = A.memptr();
+  const uword p_n_rows = p.n_rows;
+  const uword p_n_cols = p.n_cols;
+  
+  const uword* indices_mem = indices.memptr();
+  const uword  N           = indices.n_elem;
+  
+  if(mode == 0) // each column
+    {
+    for(uword i=0; i < N; ++i)
+      {
+      const uword col = indices_mem[i];
+      
+      arma_debug_check( (col > p_n_cols), "each_col(): index out of bounds" );
+      
+      arrayops::inplace_mul( p.colptr(col), A_mem, p_n_rows );
+      }
+    }
+  else // each row
+    {
+    for(uword i=0; i < N; ++i)
+      {
+      const uword row = indices_mem[i];
+      
+      arma_debug_check( (row > p_n_rows), "each_row(): index out of bounds" );
+      
+      for(uword col=0; col < p_n_cols; ++col)
+        {
+        p.at(row,col) *= A_mem[col];
+        }
+      }
+    }
+  }
+
+
+
+template<typename parent, unsigned int mode, typename TB>
+template<typename T1>
+inline
+void
+subview_each2<parent,mode,TB>::operator/= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  parent& p = subview_each_common<parent,mode>::p;
+  
+  const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() );
+  const Mat<eT>& A     = tmp.M;
+  
+  subview_each_common<parent,mode>::check_size(A);
+  
+  const unwrap_check_mixed<TB> tmp_indices( base_indices.get_ref(), (*this).get_mat_ref() );
+  const Mat<uword>& indices =  tmp_indices.M;
+  
+  check_indices(indices);
+  
+  const eT*   A_mem    = A.memptr();
+  const uword p_n_rows = p.n_rows;
+  const uword p_n_cols = p.n_cols;
+  
+  const uword* indices_mem = indices.memptr();
+  const uword  N           = indices.n_elem;
+  
+  if(mode == 0) // each column
+    {
+    for(uword i=0; i < N; ++i)
+      {
+      const uword col = indices_mem[i];
+      
+      arma_debug_check( (col > p_n_cols), "each_col(): index out of bounds" );
+      
+      arrayops::inplace_div( p.colptr(col), A_mem, p_n_rows );
+      }
+    }
+  else // each row
+    {
+    for(uword i=0; i < N; ++i)
+      {
+      const uword row = indices_mem[i];
+      
+      arma_debug_check( (row > p_n_rows), "each_row(): index out of bounds" );
+      
+      for(uword col=0; col < p_n_cols; ++col)
+        {
+        p.at(row,col) /= A_mem[col];
+        }
+      }
+    }
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/subview_elem1_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,90 @@
+// Copyright (C) 2010-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup subview_elem1
+//! @{
+
+
+
+template<typename eT, typename T1>
+class subview_elem1 : public Base<eT, subview_elem1<eT,T1> >
+  {
+  public:    
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool is_row = false;
+  static const bool is_col = true;
+  
+  arma_aligned const Mat<eT>&        m;
+  arma_aligned const Base<uword,T1>& a;
+  
+  
+  protected:
+  
+  arma_inline subview_elem1(const Mat<eT>& in_m, const Base<uword,T1>& in_a);
+  
+  
+  public:
+  
+  inline ~subview_elem1();
+  
+  template<typename op_type>              inline void inplace_op(const eT                    val);
+  template<typename op_type, typename T2> inline void inplace_op(const subview_elem1<eT,T2>& x  );
+  template<typename op_type, typename T2> inline void inplace_op(const Base<eT,T2>&          x  );
+  
+  arma_inline const Op<subview_elem1<eT,T1>,op_htrans>  t() const;
+  arma_inline const Op<subview_elem1<eT,T1>,op_htrans> ht() const;
+  arma_inline const Op<subview_elem1<eT,T1>,op_strans> st() const;
+  
+  inline void fill(const eT val);
+  inline void zeros();
+  inline void ones();
+  
+  inline void operator+= (const eT val);
+  inline void operator-= (const eT val);
+  inline void operator*= (const eT val);
+  inline void operator/= (const eT val);
+  
+  
+  // deliberately returning void
+  template<typename T2> inline void operator_equ(const subview_elem1<eT,T2>& x);
+  template<typename T2> inline void operator=   (const subview_elem1<eT,T2>& x);
+                        inline void operator=   (const subview_elem1<eT,T1>& x);
+  template<typename T2> inline void operator+=  (const subview_elem1<eT,T2>& x);
+  template<typename T2> inline void operator-=  (const subview_elem1<eT,T2>& x);
+  template<typename T2> inline void operator%=  (const subview_elem1<eT,T2>& x);
+  template<typename T2> inline void operator/=  (const subview_elem1<eT,T2>& x);
+  
+  template<typename T2> inline void operator=  (const Base<eT,T2>& x);
+  template<typename T2> inline void operator+= (const Base<eT,T2>& x);
+  template<typename T2> inline void operator-= (const Base<eT,T2>& x);
+  template<typename T2> inline void operator%= (const Base<eT,T2>& x);
+  template<typename T2> inline void operator/= (const Base<eT,T2>& x);
+  
+  inline static void extract(Mat<eT>& out, const subview_elem1& in);
+  
+  template<typename op_type> inline static void mat_inplace_op(Mat<eT>& out, const subview_elem1& in);
+  
+  inline static void  plus_inplace(Mat<eT>& out, const subview_elem1& in);
+  inline static void minus_inplace(Mat<eT>& out, const subview_elem1& in);
+  inline static void schur_inplace(Mat<eT>& out, const subview_elem1& in);
+  inline static void   div_inplace(Mat<eT>& out, const subview_elem1& in);
+  
+  
+  
+  private:
+  
+  friend class Mat<eT>;
+  subview_elem1();
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/subview_elem1_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,747 @@
+// Copyright (C) 2010-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2010-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup subview_elem1
+//! @{
+
+
+template<typename eT, typename T1>
+inline
+subview_elem1<eT,T1>::~subview_elem1()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+template<typename eT, typename T1>
+arma_inline
+subview_elem1<eT,T1>::subview_elem1(const Mat<eT>& in_m, const Base<uword,T1>& in_a)
+  : m(in_m)
+  , a(in_a)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT, typename T1>
+template<typename op_type>
+inline
+void
+subview_elem1<eT,T1>::inplace_op(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& m_local = const_cast< Mat<eT>& >(m);
+  
+        eT*   m_mem    = m_local.memptr();
+  const uword m_n_elem = m_local.n_elem;
+  
+  const unwrap_check_mixed<T1> tmp(a.get_ref(), m_local);
+  const umat& aa = tmp.M;
+  
+  arma_debug_check
+    (
+    ( (aa.is_vec() == false) && (aa.is_empty() == false) ),
+    "Mat::elem(): given object is not a vector"
+    );
+  
+  const uword* aa_mem    = aa.memptr();
+  const uword  aa_n_elem = aa.n_elem;
+  
+  uword iq,jq;
+  for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2)
+    {
+    const uword ii = aa_mem[iq];
+    const uword jj = aa_mem[jq];
+    
+    arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
+    
+         if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  val; m_mem[jj] =  val; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += val; m_mem[jj] += val; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= val; m_mem[jj] -= val; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= val; m_mem[jj] *= val; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= val; m_mem[jj] /= val; }
+    }
+  
+  if(iq < aa_n_elem)
+    {
+    const uword ii = aa_mem[iq];
+    
+    arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); 
+    
+         if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  val; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += val; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= val; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= val; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= val; }
+    }
+  }
+
+
+
+template<typename eT, typename T1>
+template<typename op_type, typename T2>
+inline
+void
+subview_elem1<eT,T1>::inplace_op(const subview_elem1<eT,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_elem1<eT,T1>& s = *this;
+  
+  if(&(s.m) == &(x.m))
+    {
+    arma_extra_debug_print("subview_elem1::inplace_op(): aliasing detected");
+    
+    const Mat<eT> tmp(x);
+    
+         if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { s.operator= (tmp); }
+    else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { s.operator+=(tmp); }
+    else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { s.operator-=(tmp); }
+    else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { s.operator%=(tmp); }
+    else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { s.operator/=(tmp); }
+    }
+  else
+    {
+          Mat<eT>& s_m_local = const_cast< Mat<eT>& >(s.m);
+    const Mat<eT>& x_m_local = x.m;
+    
+    const unwrap_check_mixed<T1> s_tmp(s.a.get_ref(), s_m_local);
+    const unwrap_check_mixed<T2> x_tmp(x.a.get_ref(), s_m_local);
+    
+    const umat& s_aa = s_tmp.M;
+    const umat& x_aa = x_tmp.M;
+    
+    arma_debug_check
+      (
+      ( ((s_aa.is_vec() == false) && (s_aa.is_empty() == false)) || ((x_aa.is_vec() == false) && (x_aa.is_empty() == false)) ),
+      "Mat::elem(): given object is not a vector"
+      );
+    
+    const uword* s_aa_mem = s_aa.memptr();
+    const uword* x_aa_mem = x_aa.memptr();
+    
+    const uword s_aa_n_elem = s_aa.n_elem;
+    
+    arma_debug_check( (s_aa_n_elem != x_aa.n_elem), "Mat::elem(): size mismatch" );
+    
+    
+          eT*   s_m_mem    = s_m_local.memptr();
+    const uword s_m_n_elem = s_m_local.n_elem;
+    
+    const eT*   x_m_mem    = x_m_local.memptr();
+    const uword x_m_n_elem = x_m_local.n_elem;
+    
+    uword iq,jq;
+    for(iq=0, jq=1; jq < s_aa_n_elem; iq+=2, jq+=2)
+      {
+      const uword s_ii = s_aa_mem[iq];
+      const uword s_jj = s_aa_mem[jq];
+      
+      const uword x_ii = x_aa_mem[iq];
+      const uword x_jj = x_aa_mem[jq];
+      
+      arma_debug_check
+        (
+        (s_ii >= s_m_n_elem) || (s_jj >= s_m_n_elem) || (x_ii >= x_m_n_elem) || (x_jj >= x_m_n_elem),
+        "Mat::elem(): index out of bounds"
+        );
+      
+           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { s_m_mem[s_ii]  = x_m_mem[x_ii]; s_m_mem[s_jj]  = x_m_mem[x_jj]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { s_m_mem[s_ii] += x_m_mem[x_ii]; s_m_mem[s_jj] += x_m_mem[x_jj]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { s_m_mem[s_ii] -= x_m_mem[x_ii]; s_m_mem[s_jj] -= x_m_mem[x_jj]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { s_m_mem[s_ii] *= x_m_mem[x_ii]; s_m_mem[s_jj] *= x_m_mem[x_jj]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { s_m_mem[s_ii] /= x_m_mem[x_ii]; s_m_mem[s_jj] /= x_m_mem[x_jj]; }
+      }
+    
+    if(iq < s_aa_n_elem)
+      {
+      const uword s_ii = s_aa_mem[iq];
+      const uword x_ii = x_aa_mem[iq];
+      
+      arma_debug_check
+        (
+        ( (s_ii >= s_m_n_elem) || (x_ii >= x_m_n_elem) ),
+        "Mat::elem(): index out of bounds"
+        );
+      
+           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { s_m_mem[s_ii]  = x_m_mem[x_ii]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { s_m_mem[s_ii] += x_m_mem[x_ii]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { s_m_mem[s_ii] -= x_m_mem[x_ii]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { s_m_mem[s_ii] *= x_m_mem[x_ii]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { s_m_mem[s_ii] /= x_m_mem[x_ii]; }
+      }
+    }
+  }
+
+
+
+template<typename eT, typename T1>
+template<typename op_type, typename T2>
+inline
+void
+subview_elem1<eT,T1>::inplace_op(const Base<eT,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& m_local = const_cast< Mat<eT>& >(m);
+  
+        eT*   m_mem    = m_local.memptr();
+  const uword m_n_elem = m_local.n_elem;
+  
+  const unwrap_check_mixed<T1> aa_tmp(a.get_ref(), m_local);
+  const umat& aa = aa_tmp.M;
+  
+  arma_debug_check
+    (
+    ( (aa.is_vec() == false) && (aa.is_empty() == false) ),
+    "Mat::elem(): given object is not a vector"
+    );
+  
+  const uword* aa_mem    = aa.memptr();
+  const uword  aa_n_elem = aa.n_elem;
+  
+  const Proxy<T2> P(x.get_ref());
+  
+  arma_debug_check( (aa_n_elem != P.get_n_elem()), "Mat::elem(): size mismatch" );
+  
+  const bool is_alias = P.is_alias(m);
+  
+  if( (is_alias == false) && (Proxy<T2>::prefer_at_accessor == false) )
+    {
+    typename Proxy<T2>::ea_type X = P.get_ea();
+    
+    uword iq,jq;
+    for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2)
+      {
+      const uword ii = aa_mem[iq];
+      const uword jj = aa_mem[jq];
+      
+      arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
+      
+           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  X[iq]; m_mem[jj]  = X[jq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[iq]; m_mem[jj] += X[jq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[iq]; m_mem[jj] -= X[jq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[iq]; m_mem[jj] *= X[jq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= X[iq]; m_mem[jj] /= X[jq]; }
+      }
+    
+    if(iq < aa_n_elem)
+      {
+      const uword ii = aa_mem[iq];
+      
+      arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
+      
+           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  X[iq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[iq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[iq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[iq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= X[iq]; }
+      }
+    }
+  else
+    {
+    arma_extra_debug_print("subview_elem1::inplace_op(): aliasing or prefer_at_accessor detected");
+    
+    const unwrap_check<typename Proxy<T2>::stored_type> tmp(P.Q, is_alias);
+    const Mat<eT>& M = tmp.M;
+    
+    const eT* X = M.memptr();
+    
+    uword iq,jq;
+    for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2)
+      {
+      const uword ii = aa_mem[iq];
+      const uword jj = aa_mem[jq];
+      
+      arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
+      
+           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  X[iq]; m_mem[jj]  = X[jq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[iq]; m_mem[jj] += X[jq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[iq]; m_mem[jj] -= X[jq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[iq]; m_mem[jj] *= X[jq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= X[iq]; m_mem[jj] /= X[jq]; }
+      }
+    
+    if(iq < aa_n_elem)
+      {
+      const uword ii = aa_mem[iq];
+      
+      arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
+      
+           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_mem[ii] =  X[iq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[iq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[iq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[iq]; }
+      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_mem[ii] /= X[iq]; }
+      }
+    }
+  }
+
+
+
+//
+//
+
+
+
+template<typename eT, typename T1>
+arma_inline
+const Op<subview_elem1<eT,T1>,op_htrans>
+subview_elem1<eT,T1>::t() const
+  {
+  return Op<subview_elem1<eT,T1>,op_htrans>(*this);
+  }
+
+
+
+template<typename eT, typename T1>
+arma_inline
+const Op<subview_elem1<eT,T1>,op_htrans>
+subview_elem1<eT,T1>::ht() const
+  {
+  return Op<subview_elem1<eT,T1>,op_htrans>(*this);
+  }
+
+
+
+template<typename eT, typename T1>
+arma_inline
+const Op<subview_elem1<eT,T1>,op_strans>
+subview_elem1<eT,T1>::st() const
+  {
+  return Op<subview_elem1<eT,T1>,op_strans>(*this);
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+subview_elem1<eT,T1>::fill(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_equ>(val);
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+subview_elem1<eT,T1>::zeros()
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_equ>(eT(0));
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+subview_elem1<eT,T1>::ones()
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_equ>(eT(1));
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+subview_elem1<eT,T1>::operator+= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_plus>(val);
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+subview_elem1<eT,T1>::operator-= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_minus>(val);
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+subview_elem1<eT,T1>::operator*= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_schur>(val);
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+subview_elem1<eT,T1>::operator/= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_div>(val);
+  }
+
+
+
+//
+//
+
+
+
+template<typename eT, typename T1>
+template<typename T2>
+inline
+void
+subview_elem1<eT,T1>::operator_equ(const subview_elem1<eT,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_equ>(x);
+  }
+
+
+
+
+template<typename eT, typename T1>
+template<typename T2>
+inline
+void
+subview_elem1<eT,T1>::operator= (const subview_elem1<eT,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  (*this).operator_equ(x);
+  }
+
+
+
+//! work around compiler bugs
+template<typename eT, typename T1>
+inline
+void
+subview_elem1<eT,T1>::operator= (const subview_elem1<eT,T1>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  (*this).operator_equ(x);
+  }
+
+
+
+template<typename eT, typename T1>
+template<typename T2>
+inline
+void
+subview_elem1<eT,T1>::operator+= (const subview_elem1<eT,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_plus>(x);
+  }
+
+
+
+template<typename eT, typename T1>
+template<typename T2>
+inline
+void
+subview_elem1<eT,T1>::operator-= (const subview_elem1<eT,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_minus>(x);
+  }
+
+
+
+template<typename eT, typename T1>
+template<typename T2>
+inline
+void
+subview_elem1<eT,T1>::operator%= (const subview_elem1<eT,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_schur>(x);
+  }
+
+
+
+template<typename eT, typename T1>
+template<typename T2>
+inline
+void
+subview_elem1<eT,T1>::operator/= (const subview_elem1<eT,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_div>(x);
+  }
+
+
+
+template<typename eT, typename T1>
+template<typename T2>
+inline
+void
+subview_elem1<eT,T1>::operator= (const Base<eT,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_equ>(x);
+  }
+
+
+
+template<typename eT, typename T1>
+template<typename T2>
+inline
+void
+subview_elem1<eT,T1>::operator+= (const Base<eT,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_plus>(x);
+  }
+
+
+
+template<typename eT, typename T1>
+template<typename T2>
+inline
+void
+subview_elem1<eT,T1>::operator-= (const Base<eT,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_minus>(x);
+  }
+
+
+
+template<typename eT, typename T1>
+template<typename T2>
+inline
+void
+subview_elem1<eT,T1>::operator%= (const Base<eT,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_schur>(x);
+  }
+
+
+
+template<typename eT, typename T1>
+template<typename T2>
+inline
+void
+subview_elem1<eT,T1>::operator/= (const Base<eT,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_div>(x);
+  }
+
+
+
+//
+//
+
+
+
+template<typename eT, typename T1>
+inline
+void
+subview_elem1<eT,T1>::extract(Mat<eT>& actual_out, const subview_elem1<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap_check_mixed<T1> tmp1(in.a.get_ref(), actual_out);
+  const umat& aa = tmp1.M;
+  
+  arma_debug_check
+    (
+    ( (aa.is_vec() == false) && (aa.is_empty() == false) ),
+    "Mat::elem(): given object is not a vector"
+    );
+  
+  const uword* aa_mem    = aa.memptr();
+  const uword  aa_n_elem = aa.n_elem;
+  
+  const Mat<eT>& m_local = in.m;
+  
+  const eT*   m_mem    = m_local.memptr();
+  const uword m_n_elem = m_local.n_elem;
+  
+  const bool alias = (&actual_out == &m_local);
+  
+  arma_extra_debug_warn(alias, "subview_elem1::extract(): aliasing detected");
+  
+  Mat<eT>* tmp_out = alias ? new Mat<eT>() : 0;
+  Mat<eT>& out     = alias ? *tmp_out      : actual_out;
+  
+  out.set_size(aa_n_elem, 1);
+  
+  eT* out_mem = out.memptr();
+  
+  uword i,j;
+  for(i=0, j=1; j<aa_n_elem; i+=2, j+=2)
+    {
+    const uword ii = aa_mem[i];
+    const uword jj = aa_mem[j];
+    
+    arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
+    
+    out_mem[i] = m_mem[ii];
+    out_mem[j] = m_mem[jj];
+    }
+  
+  if(i < aa_n_elem)
+    {
+    const uword ii = aa_mem[i];
+    
+    arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
+    
+    out_mem[i] = m_mem[ii];
+    }
+  
+  if(alias == true)
+    {
+    actual_out.steal_mem(out);
+    delete tmp_out;
+    }
+  }
+
+
+
+template<typename eT, typename T1>
+template<typename op_type>
+inline
+void
+subview_elem1<eT,T1>::mat_inplace_op(Mat<eT>& out, const subview_elem1& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const unwrap<T1> tmp1(in.a.get_ref());
+  const umat& aa = tmp1.M;
+  
+  arma_debug_check
+    (
+    ( (aa.is_vec() == false) && (aa.is_empty() == false) ),
+    "Mat::elem(): given object is not a vector"
+    );
+  
+  const uword* aa_mem    = aa.memptr();
+  const uword  aa_n_elem = aa.n_elem;
+  
+  const unwrap_check< Mat<eT> > tmp2(in.m, out);
+  const Mat<eT>& m_local      = tmp2.M;
+  
+  const eT*   m_mem    = m_local.memptr();
+  const uword m_n_elem = m_local.n_elem;
+  
+  arma_debug_check( (out.n_elem != aa_n_elem), "Mat::elem(): size mismatch" );
+  
+  eT* out_mem = out.memptr();
+  
+  uword i,j;
+  for(i=0, j=1; j<aa_n_elem; i+=2, j+=2)
+    {
+    const uword ii = aa_mem[i];
+    const uword jj = aa_mem[j];
+    
+    arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
+    
+         if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { out_mem[i] += m_mem[ii]; out_mem[j] += m_mem[jj]; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { out_mem[i] -= m_mem[ii]; out_mem[j] -= m_mem[jj]; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { out_mem[i] *= m_mem[ii]; out_mem[j] *= m_mem[jj]; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { out_mem[i] /= m_mem[ii]; out_mem[j] /= m_mem[jj]; }
+    }
+  
+  if(i < aa_n_elem)
+    {
+    const uword ii = aa_mem[i];
+    
+    arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
+    
+         if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { out_mem[i] += m_mem[ii]; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { out_mem[i] -= m_mem[ii]; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { out_mem[i] *= m_mem[ii]; }
+    else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { out_mem[i] /= m_mem[ii]; }
+    }
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+subview_elem1<eT,T1>::plus_inplace(Mat<eT>& out, const subview_elem1& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  mat_inplace_op<op_subview_elem_inplace_plus>(out, in);
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+subview_elem1<eT,T1>::minus_inplace(Mat<eT>& out, const subview_elem1& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  mat_inplace_op<op_subview_elem_inplace_minus>(out, in);
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+subview_elem1<eT,T1>::schur_inplace(Mat<eT>& out, const subview_elem1& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  mat_inplace_op<op_subview_elem_inplace_schur>(out, in);
+  }
+
+
+
+template<typename eT, typename T1>
+inline
+void
+subview_elem1<eT,T1>::div_inplace(Mat<eT>& out, const subview_elem1& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  mat_inplace_op<op_subview_elem_inplace_div>(out, in);
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/subview_elem2_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,92 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup subview_elem2
+//! @{
+
+
+
+template<typename eT, typename T1, typename T2>
+class subview_elem2 : public Base<eT, subview_elem2<eT,T1,T2> >
+  {
+  public:    
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool is_row = false;
+  static const bool is_col = false;
+  
+  arma_aligned const Mat<eT>& m;
+  
+  arma_aligned const Base<uword,T1>& base_ri;
+  arma_aligned const Base<uword,T2>& base_ci;
+  
+  const bool all_rows;
+  const bool all_cols;
+  
+  
+  protected:
+  
+  arma_inline subview_elem2(const Mat<eT>& in_m, const Base<uword,T1>& in_ri, const Base<uword,T2>& in_ci, const bool in_all_rows, const bool in_all_cols);
+  
+  
+  public:
+  
+  inline ~subview_elem2();
+  
+  template<typename op_type>
+  inline void inplace_op(const eT val);
+  
+  template<typename op_type, typename expr>
+  inline void inplace_op(const Base<eT,expr>& x);
+  
+  inline void fill(const eT val);
+  inline void zeros();
+  inline void ones();
+  
+  inline void operator+= (const eT val);
+  inline void operator-= (const eT val);
+  inline void operator*= (const eT val);
+  inline void operator/= (const eT val);
+  
+  
+  // deliberately returning void
+  template<typename T3, typename T4> inline void operator_equ(const subview_elem2<eT,T3,T4>& x);
+  template<typename T3, typename T4> inline void operator=   (const subview_elem2<eT,T3,T4>& x);
+                                     inline void operator=   (const subview_elem2<eT,T1,T2>& x);
+  
+  template<typename T3, typename T4> inline void operator+=  (const subview_elem2<eT,T3,T4>& x);
+  template<typename T3, typename T4> inline void operator-=  (const subview_elem2<eT,T3,T4>& x);
+  template<typename T3, typename T4> inline void operator%=  (const subview_elem2<eT,T3,T4>& x);
+  template<typename T3, typename T4> inline void operator/=  (const subview_elem2<eT,T3,T4>& x);
+  
+  template<typename expr> inline void operator=  (const Base<eT,expr>& x);
+  template<typename expr> inline void operator+= (const Base<eT,expr>& x);
+  template<typename expr> inline void operator-= (const Base<eT,expr>& x);
+  template<typename expr> inline void operator%= (const Base<eT,expr>& x);
+  template<typename expr> inline void operator/= (const Base<eT,expr>& x);
+  
+  inline static void extract(Mat<eT>& out, const subview_elem2& in);
+  
+  inline static void  plus_inplace(Mat<eT>& out, const subview_elem2& in);
+  inline static void minus_inplace(Mat<eT>& out, const subview_elem2& in);
+  inline static void schur_inplace(Mat<eT>& out, const subview_elem2& in);
+  inline static void   div_inplace(Mat<eT>& out, const subview_elem2& in);
+  
+  
+  
+  private:
+  
+  friend class Mat<eT>;
+  subview_elem2();
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/subview_elem2_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,735 @@
+// Copyright (C) 2012-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2012-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup subview_elem2
+//! @{
+
+
+template<typename eT, typename T1, typename T2>
+inline
+subview_elem2<eT,T1,T2>::~subview_elem2()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+template<typename eT, typename T1, typename T2>
+arma_inline
+subview_elem2<eT,T1,T2>::subview_elem2
+  (
+  const Mat<eT>&        in_m,
+  const Base<uword,T1>& in_ri,
+  const Base<uword,T2>& in_ci,
+  const bool            in_all_rows,
+  const bool            in_all_cols
+  )
+  : m        (in_m       )
+  , base_ri  (in_ri      )
+  , base_ci  (in_ci      )
+  , all_rows (in_all_rows)
+  , all_cols (in_all_cols)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+template<typename op_type>
+inline
+void
+subview_elem2<eT,T1,T2>::inplace_op(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& m_local = const_cast< Mat<eT>& >(m);
+  
+  const uword m_n_rows = m_local.n_rows;
+  const uword m_n_cols = m_local.n_cols;
+  
+  if( (all_rows == false) && (all_cols == false) )
+    {
+    const unwrap_check_mixed<T1> tmp1(base_ri.get_ref(), m_local);
+    const unwrap_check_mixed<T2> tmp2(base_ci.get_ref(), m_local);
+    
+    const umat& ri = tmp1.M;
+    const umat& ci = tmp2.M;
+    
+    arma_debug_check
+      (
+      ( ((ri.is_vec() == false) && (ri.is_empty() == false)) || ((ci.is_vec() == false) && (ci.is_empty() == false)) ),
+      "Mat::elem(): given object is not a vector"
+      );
+    
+    const uword* ri_mem    = ri.memptr();
+    const uword  ri_n_elem = ri.n_elem;
+    
+    const uword* ci_mem    = ci.memptr();
+    const uword  ci_n_elem = ci.n_elem;
+    
+    for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count)
+      {
+      const uword col = ci_mem[ci_count];
+      
+      arma_debug_check( (col > m_n_cols), "Mat::elem(): index out of bounds" );
+      
+      for(uword ri_count=0; ri_count < ri_n_elem; ++ri_count)
+        {
+        const uword row = ri_mem[ri_count];
+        
+        arma_debug_check( (row > m_n_rows), "Mat::elem(): index out of bounds" );
+        
+             if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_local.at(row,col)  = val; }
+        else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_local.at(row,col) += val; }
+        else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_local.at(row,col) -= val; }
+        else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_local.at(row,col) *= val; }
+        else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_local.at(row,col) /= val; }
+        }
+      }
+    }
+  else
+  if( (all_rows == true) && (all_cols == false) )
+    {
+    const unwrap_check_mixed<T2> tmp2(base_ci.get_ref(), m_local);
+    
+    const umat& ci = tmp2.M;
+    
+    arma_debug_check
+      (
+      ( (ci.is_vec() == false) && (ci.is_empty() == false) ),
+      "Mat::elem(): given object is not a vector"
+      );
+    
+    const uword* ci_mem    = ci.memptr();
+    const uword  ci_n_elem = ci.n_elem;
+    
+    for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count)
+      {
+      const uword col = ci_mem[ci_count];
+      
+      arma_debug_check( (col > m_n_cols), "Mat::elem(): index out of bounds" );
+      
+      eT* colptr = m_local.colptr(col);
+      
+           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { arrayops::inplace_set  (colptr, val, m_n_rows); }
+      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { arrayops::inplace_plus (colptr, val, m_n_rows); }
+      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { arrayops::inplace_minus(colptr, val, m_n_rows); }
+      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { arrayops::inplace_mul  (colptr, val, m_n_rows); }
+      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { arrayops::inplace_div  (colptr, val, m_n_rows); }
+      }
+    }
+  else
+  if( (all_rows == false) && (all_cols == true) )
+    {
+    const unwrap_check_mixed<T1> tmp1(base_ri.get_ref(), m_local);
+    
+    const umat& ri = tmp1.M;
+    
+    arma_debug_check
+      (
+      ( (ri.is_vec() == false) && (ri.is_empty() == false) ),
+      "Mat::elem(): given object is not a vector"
+      );
+    
+    const uword* ri_mem    = ri.memptr();
+    const uword  ri_n_elem = ri.n_elem;
+
+    for(uword col=0; col < m_n_cols; ++col)
+      {
+      for(uword ri_count=0; ri_count < ri_n_elem; ++ri_count)
+        {
+        const uword row = ri_mem[ri_count];
+        
+        arma_debug_check( (row > m_n_rows), "Mat::elem(): index out of bounds" );
+      
+             if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_local.at(row,col)  = val; }
+        else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_local.at(row,col) += val; }
+        else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_local.at(row,col) -= val; }
+        else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_local.at(row,col) *= val; }
+        else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_local.at(row,col) /= val; }
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+template<typename op_type, typename expr>
+inline
+void
+subview_elem2<eT,T1,T2>::inplace_op(const Base<eT,expr>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& m_local = const_cast< Mat<eT>& >(m);
+  
+  const uword m_n_rows = m_local.n_rows;
+  const uword m_n_cols = m_local.n_cols;
+  
+  const unwrap_check<expr> tmp(x.get_ref(), m_local);
+  const Mat<eT>& X       = tmp.M;
+  
+  if( (all_rows == false) && (all_cols == false) )
+    {
+    const unwrap_check_mixed<T1> tmp1(base_ri.get_ref(), m_local);
+    const unwrap_check_mixed<T2> tmp2(base_ci.get_ref(), m_local);
+    
+    const umat& ri = tmp1.M;
+    const umat& ci = tmp2.M;
+    
+    arma_debug_check
+      (
+      ( ((ri.is_vec() == false) && (ri.is_empty() == false)) || ((ci.is_vec() == false) && (ci.is_empty() == false)) ),
+      "Mat::elem(): given object is not a vector"
+      );
+    
+    const uword* ri_mem    = ri.memptr();
+    const uword  ri_n_elem = ri.n_elem;
+    
+    const uword* ci_mem    = ci.memptr();
+    const uword  ci_n_elem = ci.n_elem;
+    
+    arma_debug_assert_same_size( ri_n_elem, ci_n_elem, X.n_rows, X.n_cols, "Mat::elem()" );
+    
+    for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count)
+      {
+      const uword col = ci_mem[ci_count];
+      
+      arma_debug_check( (col > m_n_cols), "Mat::elem(): index out of bounds" );
+      
+      for(uword ri_count=0; ri_count < ri_n_elem; ++ri_count)
+        {
+        const uword row = ri_mem[ri_count];
+        
+        arma_debug_check( (row > m_n_rows), "Mat::elem(): index out of bounds" );
+        
+             if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_local.at(row,col)  = X.at(ri_count, ci_count); }
+        else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_local.at(row,col) += X.at(ri_count, ci_count); }
+        else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_local.at(row,col) -= X.at(ri_count, ci_count); }
+        else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_local.at(row,col) *= X.at(ri_count, ci_count); }
+        else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_local.at(row,col) /= X.at(ri_count, ci_count); }
+        }
+      }
+    }
+  else
+  if( (all_rows == true) && (all_cols == false) )
+    {
+    const unwrap_check_mixed<T2> tmp2(base_ci.get_ref(), m_local);
+    
+    const umat& ci = tmp2.M;
+    
+    arma_debug_check
+      (
+      ( (ci.is_vec() == false) && (ci.is_empty() == false) ),
+      "Mat::elem(): given object is not a vector"
+      );
+    
+    const uword* ci_mem    = ci.memptr();
+    const uword  ci_n_elem = ci.n_elem;
+    
+    arma_debug_assert_same_size( m_n_rows, ci_n_elem, X.n_rows, X.n_cols, "Mat::elem()" );
+    
+    for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count)
+      {
+      const uword col = ci_mem[ci_count];
+      
+      arma_debug_check( (col > m_n_cols), "Mat::elem(): index out of bounds" );
+      
+            eT* m_colptr = m_local.colptr(col);
+      const eT* X_colptr = X.colptr(ci_count);
+      
+           if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { arrayops::copy         (m_colptr, X_colptr, m_n_rows); }
+      else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { arrayops::inplace_plus (m_colptr, X_colptr, m_n_rows); }
+      else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { arrayops::inplace_minus(m_colptr, X_colptr, m_n_rows); }
+      else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { arrayops::inplace_mul  (m_colptr, X_colptr, m_n_rows); }
+      else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { arrayops::inplace_div  (m_colptr, X_colptr, m_n_rows); }
+      }
+    }
+  else
+  if( (all_rows == false) && (all_cols == true) )
+    {
+    const unwrap_check_mixed<T1> tmp1(base_ri.get_ref(), m_local);
+    
+    const umat& ri = tmp1.M;
+    
+    arma_debug_check
+      (
+      ( (ri.is_vec() == false) && (ri.is_empty() == false) ),
+      "Mat::elem(): given object is not a vector"
+      );
+    
+    const uword* ri_mem    = ri.memptr();
+    const uword  ri_n_elem = ri.n_elem;
+    
+    arma_debug_assert_same_size( ri_n_elem, m_n_cols, X.n_rows, X.n_cols, "Mat::elem()" );
+    
+    for(uword col=0; col < m_n_cols; ++col)
+      {
+      for(uword ri_count=0; ri_count < ri_n_elem; ++ri_count)
+        {
+        const uword row = ri_mem[ri_count];
+        
+        arma_debug_check( (row > m_n_rows), "Mat::elem(): index out of bounds" );
+      
+             if(is_same_type<op_type, op_subview_elem_equ          >::value == true) { m_local.at(row,col)  = X.at(ri_count, col); }
+        else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_local.at(row,col) += X.at(ri_count, col); }
+        else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_local.at(row,col) -= X.at(ri_count, col); }
+        else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_local.at(row,col) *= X.at(ri_count, col); }
+        else if(is_same_type<op_type, op_subview_elem_inplace_div  >::value == true) { m_local.at(row,col) /= X.at(ri_count, col); }
+        }
+      }
+    }
+  }
+
+
+
+//
+//
+
+
+
+template<typename eT, typename T1, typename T2>
+inline
+void
+subview_elem2<eT,T1,T2>::fill(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_equ>(val);
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+inline
+void
+subview_elem2<eT,T1,T2>::zeros()
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_equ>(eT(0));
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+inline
+void
+subview_elem2<eT,T1,T2>::ones()
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_equ>(eT(1));
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+inline
+void
+subview_elem2<eT,T1,T2>::operator+= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_plus>(val);
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+inline
+void
+subview_elem2<eT,T1,T2>::operator-= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_minus>(val);
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+inline
+void
+subview_elem2<eT,T1,T2>::operator*= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_schur>(val);
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+inline
+void
+subview_elem2<eT,T1,T2>::operator/= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_div>(val);
+  }
+
+
+
+//
+//
+
+
+
+template<typename eT, typename T1, typename T2>
+template<typename T3, typename T4>
+inline
+void
+subview_elem2<eT,T1,T2>::operator_equ(const subview_elem2<eT,T3,T4>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_equ>(x);
+  }
+
+
+
+
+template<typename eT, typename T1, typename T2>
+template<typename T3, typename T4>
+inline
+void
+subview_elem2<eT,T1,T2>::operator= (const subview_elem2<eT,T3,T4>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  (*this).operator_equ(x);
+  }
+
+
+
+//! work around compiler bugs
+template<typename eT, typename T1, typename T2>
+inline
+void
+subview_elem2<eT,T1,T2>::operator= (const subview_elem2<eT,T1,T2>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  (*this).operator_equ(x);
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+template<typename T3, typename T4>
+inline
+void
+subview_elem2<eT,T1,T2>::operator+= (const subview_elem2<eT,T3,T4>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_plus>(x);
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+template<typename T3, typename T4>
+inline
+void
+subview_elem2<eT,T1,T2>::operator-= (const subview_elem2<eT,T3,T4>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_minus>(x);
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+template<typename T3, typename T4>
+inline
+void
+subview_elem2<eT,T1,T2>::operator%= (const subview_elem2<eT,T3,T4>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_schur>(x);
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+template<typename T3, typename T4>
+inline
+void
+subview_elem2<eT,T1,T2>::operator/= (const subview_elem2<eT,T3,T4>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_div>(x);
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+template<typename expr>
+inline
+void
+subview_elem2<eT,T1,T2>::operator= (const Base<eT,expr>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_equ>(x);
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+template<typename expr>
+inline
+void
+subview_elem2<eT,T1,T2>::operator+= (const Base<eT,expr>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_plus>(x);
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+template<typename expr>
+inline
+void
+subview_elem2<eT,T1,T2>::operator-= (const Base<eT,expr>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_minus>(x);
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+template<typename expr>
+inline
+void
+subview_elem2<eT,T1,T2>::operator%= (const Base<eT,expr>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_schur>(x);
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+template<typename expr>
+inline
+void
+subview_elem2<eT,T1,T2>::operator/= (const Base<eT,expr>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  inplace_op<op_subview_elem_inplace_div>(x);
+  }
+
+
+
+//
+//
+
+
+
+template<typename eT, typename T1, typename T2>
+inline
+void
+subview_elem2<eT,T1,T2>::extract(Mat<eT>& actual_out, const subview_elem2<eT,T1,T2>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  Mat<eT>& m_local = const_cast< Mat<eT>& >(in.m);
+  
+  const uword m_n_rows = m_local.n_rows;
+  const uword m_n_cols = m_local.n_cols;
+  
+  const bool alias = (&actual_out == &m_local);
+  
+  arma_extra_debug_warn(alias, "subview_elem2::extract(): aliasing detected");
+  
+  Mat<eT>* tmp_out = alias ? new Mat<eT>() : 0;
+  Mat<eT>& out     = alias ? *tmp_out      : actual_out;
+  
+  if( (in.all_rows == false) && (in.all_cols == false) )
+    {
+    const unwrap_check_mixed<T1> tmp1(in.base_ri.get_ref(), actual_out);
+    const unwrap_check_mixed<T2> tmp2(in.base_ci.get_ref(), actual_out);
+    
+    const umat& ri = tmp1.M;
+    const umat& ci = tmp2.M;
+    
+    arma_debug_check
+      (
+      ( ((ri.is_vec() == false) && (ri.is_empty() == false)) || ((ci.is_vec() == false) && (ci.is_empty() == false)) ),
+      "Mat::elem(): given object is not a vector"
+      );
+    
+    const uword* ri_mem    = ri.memptr();
+    const uword  ri_n_elem = ri.n_elem;
+    
+    const uword* ci_mem    = ci.memptr();
+    const uword  ci_n_elem = ci.n_elem;
+    
+    out.set_size(ri_n_elem, ci_n_elem);
+    
+    eT*   out_mem   = out.memptr();
+    uword out_count = 0;
+    
+    for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count)
+      {
+      const uword col = ci_mem[ci_count];
+      
+      arma_debug_check( (col > m_n_cols), "Mat::elem(): index out of bounds" );
+      
+      for(uword ri_count=0; ri_count < ri_n_elem; ++ri_count)
+        {
+        const uword row = ri_mem[ri_count];
+        
+        arma_debug_check( (row > m_n_rows), "Mat::elem(): index out of bounds" );
+        
+        out_mem[out_count] = m_local.at(row,col);
+        ++out_count;
+        }
+      }
+    }
+  else
+  if( (in.all_rows == true) && (in.all_cols == false) )
+    {
+    const unwrap_check_mixed<T2> tmp2(in.base_ci.get_ref(), m_local);
+    
+    const umat& ci = tmp2.M;
+    
+    arma_debug_check
+      (
+      ( (ci.is_vec() == false) && (ci.is_empty() == false) ),
+      "Mat::elem(): given object is not a vector"
+      );
+    
+    const uword* ci_mem    = ci.memptr();
+    const uword  ci_n_elem = ci.n_elem;
+    
+    out.set_size(m_n_rows, ci_n_elem);
+    
+    for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count)
+      {
+      const uword col = ci_mem[ci_count];
+      
+      arma_debug_check( (col > m_n_cols), "Mat::elem(): index out of bounds" );
+      
+      arrayops::copy( out.colptr(ci_count), m_local.colptr(col), m_n_rows );
+      }
+    }
+  else
+  if( (in.all_rows == false) && (in.all_cols == true) )
+    {
+    const unwrap_check_mixed<T1> tmp1(in.base_ri.get_ref(), m_local);
+    
+    const umat& ri = tmp1.M;
+    
+    arma_debug_check
+      (
+      ( (ri.is_vec() == false) && (ri.is_empty() == false) ),
+      "Mat::elem(): given object is not a vector"
+      );
+    
+    const uword* ri_mem    = ri.memptr();
+    const uword  ri_n_elem = ri.n_elem;
+    
+    out.set_size(ri_n_elem, m_n_cols);
+    
+    for(uword col=0; col < m_n_cols; ++col)
+      {
+      for(uword ri_count=0; ri_count < ri_n_elem; ++ri_count)
+        {
+        const uword row = ri_mem[ri_count];
+        
+        arma_debug_check( (row > m_n_rows), "Mat::elem(): index out of bounds" );
+        
+        out.at(ri_count,col) = m_local.at(row,col);
+        }
+      }
+    }
+  
+  
+  if(alias)
+    {
+    actual_out.steal_mem(out);
+    
+    delete tmp_out;
+    }
+  }
+
+
+
+// TODO: implement a dedicated function instead of creating a temporary (but lots of potential aliasing issues)
+template<typename eT, typename T1, typename T2>
+inline
+void
+subview_elem2<eT,T1,T2>::plus_inplace(Mat<eT>& out, const subview_elem2& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> tmp(in);
+  
+  out += tmp;
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+inline
+void
+subview_elem2<eT,T1,T2>::minus_inplace(Mat<eT>& out, const subview_elem2& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> tmp(in);
+  
+  out -= tmp;
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+inline
+void
+subview_elem2<eT,T1,T2>::schur_inplace(Mat<eT>& out, const subview_elem2& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> tmp(in);
+  
+  out %= tmp;
+  }
+
+
+
+template<typename eT, typename T1, typename T2>
+inline
+void
+subview_elem2<eT,T1,T2>::div_inplace(Mat<eT>& out, const subview_elem2& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Mat<eT> tmp(in);
+  
+  out /= tmp;
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/subview_field_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,71 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup subview_field
+//! @{
+
+
+//! Class for storing data required to construct or apply operations to a subfield
+//! (i.e. where the subfield starts and ends as well as a reference/pointer to the original field),
+template<typename oT>
+class subview_field
+  {
+  public:  
+  
+  typedef oT object_type;
+  
+  const field<oT>& f;
+  
+  const uword aux_row1;
+  const uword aux_col1;
+  
+  const uword n_rows;
+  const uword n_cols;
+  const uword n_elem;
+  
+  
+  protected:
+  
+  arma_inline subview_field(const field<oT>& in_f, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols);
+  
+  
+  public:
+  
+  inline ~subview_field();
+  
+  inline void operator= (const field<oT>& x);
+  inline void operator= (const subview_field& x);
+  
+  arma_inline       oT& operator[](const uword i);
+  arma_inline const oT& operator[](const uword i) const;
+  
+  arma_inline       oT& operator()(const uword i);
+  arma_inline const oT& operator()(const uword i) const;
+  
+  arma_inline       oT&         at(const uword row, const uword col);
+  arma_inline const oT&         at(const uword row, const uword col) const;
+  
+  arma_inline       oT& operator()(const uword row, const uword col);
+  arma_inline const oT& operator()(const uword row, const uword col) const;
+  
+  inline bool check_overlap(const subview_field& x) const;
+  
+  inline static void extract(field<oT>& out, const subview_field& in);
+  
+  
+  private:
+  
+  friend class field<oT>;
+  
+  
+  subview_field();
+  //subview_field(const subview_field&);
+  };
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/subview_field_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,304 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup subview_field
+//! @{
+
+
+template<typename oT>
+inline
+subview_field<oT>::~subview_field()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename oT>
+arma_inline
+subview_field<oT>::subview_field
+  (
+  const field<oT>& in_f,
+  const uword      in_row1,
+  const uword      in_col1,
+  const uword      in_n_rows,
+  const uword      in_n_cols
+  )
+  : f(in_f)
+  , aux_row1(in_row1)
+  , aux_col1(in_col1)
+  , n_rows(in_n_rows)
+  , n_cols(in_n_cols)
+  , n_elem(in_n_rows*in_n_cols)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename oT>
+inline
+void
+subview_field<oT>::operator= (const field<oT>& x)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview_field<oT>& t = *this;
+  
+  arma_debug_check( (t.n_rows != x.n_rows) || (t.n_cols != x.n_cols), "incompatible field dimensions");
+  
+  for(uword col=0; col<t.n_cols; ++col)
+    {
+    for(uword row=0; row<t.n_rows; ++row)
+      {
+      t.at(row,col) = x.at(row,col);
+      }
+    }
+  }
+
+
+
+//! x.subfield(...) = y.subfield(...)
+template<typename oT>
+inline
+void
+subview_field<oT>::operator= (const subview_field<oT>& x_in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool overlap = check_overlap(x_in);
+        
+        field<oT>*         tmp_field   = overlap ? new field<oT>(x_in.f) : 0;
+  const subview_field<oT>* tmp_subview = overlap ? new subview_field<oT>(*tmp_field, x_in.aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
+  const subview_field<oT>& x           = overlap ? (*tmp_subview) : x_in;
+  
+  subview_field<oT>& t = *this;
+  
+  arma_debug_check( (t.n_rows != x.n_rows) || (t.n_cols != x.n_cols), "incompatible field dimensions");
+  
+  for(uword col=0; col<t.n_cols; ++col)
+    {
+    for(uword row=0; row<t.n_rows; ++row)
+      {
+      t.at(row,col) = x.at(row,col);
+      }
+    }
+    
+  if(overlap)
+    {
+    delete tmp_subview;
+    delete tmp_field;
+    }
+  }
+
+
+
+template<typename oT>
+arma_inline
+oT&
+subview_field<oT>::operator[](const uword i)
+  {
+  const uword in_col = i / n_rows;
+  const uword in_row = i % n_rows;
+    
+  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
+  
+  return *((const_cast< field<oT>& >(f)).mem[index]);
+  }
+
+
+
+template<typename oT>
+arma_inline
+const oT&
+subview_field<oT>::operator[](const uword i) const
+  {
+  const uword in_col = i / n_rows;
+  const uword in_row = i % n_rows;
+  
+  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
+  
+  return *(f.mem[index]);
+  }
+
+
+
+template<typename oT>
+arma_inline
+oT&
+subview_field<oT>::operator()(const uword i)
+  {
+  arma_debug_check( (i >= n_elem), "subview_field::operator(): index out of bounds");
+  
+  const uword in_col = i / n_rows;
+  const uword in_row = i % n_rows;
+  
+  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
+  
+  return *((const_cast< field<oT>& >(f)).mem[index]);
+  }
+
+
+
+template<typename oT>
+arma_inline
+const oT&
+subview_field<oT>::operator()(const uword i) const
+  {
+  arma_debug_check( (i >= n_elem), "subview_field::operator(): index out of bounds");
+  
+  const uword in_col = i / n_rows;
+  const uword in_row = i % n_rows;
+  
+  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
+  
+  return *(f.mem[index]);
+  }
+
+
+
+template<typename oT>
+arma_inline
+oT&
+subview_field<oT>::operator()(const uword in_row, const uword in_col)
+  {
+  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "subview_field::operator(): index out of bounds");
+  
+  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
+  
+  return *((const_cast< field<oT>& >(f)).mem[index]);
+  }
+
+
+
+template<typename oT>
+arma_inline
+const oT&
+subview_field<oT>::operator()(const uword in_row, const uword in_col) const
+  {
+  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "subview_field::operator(): index out of bounds");
+  
+  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
+  
+  return *(f.mem[index]);
+  }
+
+
+
+template<typename oT>
+arma_inline
+oT&
+subview_field<oT>::at(const uword in_row, const uword in_col)
+  {
+  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
+  
+  return *((const_cast< field<oT>& >(f)).mem[index]);
+  }
+
+
+
+template<typename oT>
+arma_inline
+const oT&
+subview_field<oT>::at(const uword in_row, const uword in_col) const
+  {
+  //arma_extra_debug_sigprint();
+  
+  const uword index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
+  
+  return *(f.mem[index]);
+  }
+
+
+
+template<typename oT>
+inline
+bool
+subview_field<oT>::check_overlap(const subview_field<oT>& x) const
+  {
+  const subview_field<oT>& t = *this;
+  
+  if(&t.f != &x.f)
+    {
+    return false;
+    }
+  else
+    {
+    if( (t.n_elem == 0) || (x.n_elem == 0) )
+      {
+      return false;
+      }
+    else
+      {
+      const uword t_row_start  = t.aux_row1;
+      const uword t_row_end_p1 = t_row_start + t.n_rows;
+      
+      const uword t_col_start  = t.aux_col1;
+      const uword t_col_end_p1 = t_col_start + t.n_cols;
+      
+      
+      const uword x_row_start  = x.aux_row1;
+      const uword x_row_end_p1 = x_row_start + x.n_rows;
+      
+      const uword x_col_start  = x.aux_col1;
+      const uword x_col_end_p1 = x_col_start + x.n_cols;
+      
+      
+      const bool outside_rows = ( (x_row_start >= t_row_end_p1) || (t_row_start >= x_row_end_p1) );
+      const bool outside_cols = ( (x_col_start >= t_col_end_p1) || (t_col_start >= x_col_end_p1) );
+      
+      return ( (outside_rows == false) && (outside_cols == false) );
+      }
+    }
+  }
+
+
+
+//! X = Y.subfield(...)
+template<typename oT>
+inline
+void
+subview_field<oT>::extract(field<oT>& actual_out, const subview_field<oT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  //
+  const bool alias = (&actual_out == &in.f);
+  
+  field<oT>* tmp = (alias) ? new field<oT> : 0;
+  field<oT>& out = (alias) ? (*tmp)        : actual_out;
+  
+  //
+  
+  const uword n_rows = in.n_rows;
+  const uword n_cols = in.n_cols;
+  
+  out.set_size(n_rows, n_cols);
+  
+  arma_extra_debug_print(arma_boost::format("out.n_rows = %d   out.n_cols = %d    in.m.n_rows = %d  in.m.n_cols = %d") % out.n_rows % out.n_cols % in.f.n_rows % in.f.n_cols );
+  
+  for(uword col = 0; col<n_cols; ++col)
+    {
+    for(uword row = 0; row<n_rows; ++row)
+      {
+      out.at(row,col) = in.at(row,col);
+      }
+    }
+  
+  
+  if(alias)
+    {
+    actual_out = out;
+    delete tmp;
+    }
+  
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/subview_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,3153 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// Copyright (C)      2011 James Sanders
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup subview
+//! @{
+
+
+template<typename eT>
+inline
+subview<eT>::~subview()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+template<typename eT>
+inline
+subview<eT>::subview(const Mat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols)
+  : m(in_m)
+  , aux_row1(in_row1)
+  , aux_col1(in_col1)
+  , n_rows(in_n_rows)
+  , n_cols(in_n_cols)
+  , n_elem(in_n_rows*in_n_cols)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::operator+= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword local_n_cols = n_cols;
+  const uword local_n_rows = n_rows;
+  
+  if(local_n_rows == 1)
+    {
+    Mat<eT>& X = const_cast< Mat<eT>& >(m);
+    
+    const uword urow          = aux_row1;
+    const uword start_col     = aux_col1;
+    const uword end_col_plus1 = start_col + local_n_cols;
+    
+    uword ii,jj;
+    for(ii=start_col, jj=start_col+1; jj < end_col_plus1; ii+=2, jj+=2)
+      {
+      X.at(urow, ii) += val;
+      X.at(urow, jj) += val;
+      }
+    
+    if(ii < end_col_plus1)
+      {
+      X.at(urow, ii) += val;
+      }
+    }
+  else
+    {
+    for(uword ucol=0; ucol < local_n_cols; ++ucol)
+      {
+      arrayops::inplace_plus( colptr(ucol), val, local_n_rows );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::operator-= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword local_n_cols = n_cols;
+  const uword local_n_rows = n_rows;
+  
+  if(local_n_rows == 1)
+    {
+    Mat<eT>& X = const_cast< Mat<eT>& >(m);
+    
+    const uword urow          = aux_row1;
+    const uword start_col     = aux_col1;
+    const uword end_col_plus1 = start_col + local_n_cols;
+    
+    uword ii,jj;
+    for(ii=start_col, jj=start_col+1; jj < end_col_plus1; ii+=2, jj+=2)
+      {
+      X.at(urow, ii) -= val;
+      X.at(urow, jj) -= val;
+      }
+    
+    if(ii < end_col_plus1)
+      {
+      X.at(urow, ii) -= val;
+      }
+    }
+  else
+    {
+    for(uword ucol=0; ucol < local_n_cols; ++ucol)
+      {
+      arrayops::inplace_minus( colptr(ucol), val, local_n_rows );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::operator*= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword local_n_cols = n_cols;
+  const uword local_n_rows = n_rows;
+  
+  if(local_n_rows == 1)
+    {
+    Mat<eT>& X = const_cast< Mat<eT>& >(m);
+    
+    const uword urow          = aux_row1;
+    const uword start_col     = aux_col1;
+    const uword end_col_plus1 = start_col + local_n_cols;
+    
+    uword ii,jj;
+    for(ii=start_col, jj=start_col+1; jj < end_col_plus1; ii+=2, jj+=2)
+      {
+      X.at(urow, ii) *= val;
+      X.at(urow, jj) *= val;
+      }
+    
+    if(ii < end_col_plus1)
+      {
+      X.at(urow, ii) *= val;
+      }
+    }
+  else
+    {
+    for(uword ucol=0; ucol < local_n_cols; ++ucol)
+      {
+      arrayops::inplace_mul( colptr(ucol), val, local_n_rows );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::operator/= (const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword local_n_cols = n_cols;
+  const uword local_n_rows = n_rows;
+  
+  if(local_n_rows == 1)
+    {
+    Mat<eT>& X = const_cast< Mat<eT>& >(m);
+    
+    const uword urow          = aux_row1;
+    const uword start_col     = aux_col1;
+    const uword end_col_plus1 = start_col + local_n_cols;
+    
+    uword ii,jj;
+    for(ii=start_col, jj=start_col+1; jj < end_col_plus1; ii+=2, jj+=2)
+      {
+      X.at(urow, ii) /= val;
+      X.at(urow, jj) /= val;
+      }
+    
+    if(ii < end_col_plus1)
+      {
+      X.at(urow, ii) /= val;
+      }
+    }
+  else
+    {
+    for(uword ucol=0; ucol < local_n_cols; ++ucol)
+      {
+      arrayops::inplace_div( colptr(ucol), val, local_n_rows );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview<eT>::operator= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Proxy<T1> P(in.get_ref());
+  
+  subview<eT>& s = *this;
+  
+  const uword s_n_rows = s.n_rows;
+  const uword s_n_cols = s.n_cols;
+    
+  arma_debug_assert_same_size(s, P, "copy into submatrix");
+  
+  const bool is_alias = P.is_alias(s.m);
+  
+  arma_extra_debug_warn(is_alias, "aliasing detected");
+  
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) || (is_alias == true) )
+    {
+    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
+    const Mat<eT>& x = tmp.M;
+    
+    if(s_n_rows == 1)
+      {
+      const eT* x_mem = x.memptr();
+      
+      Mat<eT>& A = const_cast< Mat<eT>& >(m);
+      
+      const uword urow      = aux_row1;
+      const uword start_col = aux_col1;
+      
+      uword ii,jj;
+      for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+        {
+        A.at(urow, start_col+ii) = x_mem[ii];
+        A.at(urow, start_col+jj) = x_mem[jj];
+        }
+      
+      if(ii < s_n_cols)
+        {
+        A.at(urow, start_col+ii) = x_mem[ii];
+        }
+      }
+    else
+      {
+      for(uword ucol=0; ucol < s_n_cols; ++ucol)
+        {
+        arrayops::copy( s.colptr(ucol), x.colptr(ucol), s_n_rows );
+        }
+      }
+    }
+  else
+    {
+    if(s_n_rows == 1)
+      {
+      Mat<eT>& A = const_cast< Mat<eT>& >(m);
+      
+      const uword urow      = aux_row1;
+      const uword start_col = aux_col1;
+      
+      uword ii,jj;
+      for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+        {
+        const eT tmp1 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,ii) : P[ii];
+        const eT tmp2 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,jj) : P[jj];
+        
+        A.at(urow, start_col+ii) = tmp1;
+        A.at(urow, start_col+jj) = tmp2;
+        }
+      
+      if(ii < s_n_cols)
+        {
+        A.at(urow, start_col+ii) = (Proxy<T1>::prefer_at_accessor) ? P.at(0,ii) : P[ii];
+        }
+      }
+    else
+      {
+      for(uword ucol=0; ucol < s_n_cols; ++ucol)
+        {
+        eT* s_col_data = s.colptr(ucol);
+        
+        uword ii,jj;
+        for(ii=0, jj=1; jj < s_n_rows; ii+=2, jj+=2)
+          {
+          const eT tmp1 = P.at(ii,ucol);
+          const eT tmp2 = P.at(jj,ucol);
+          
+          s_col_data[ii] = tmp1;
+          s_col_data[jj] = tmp2;
+          }
+        
+        if(ii < s_n_rows)
+          {
+          s_col_data[ii] = P.at(ii,ucol);
+          }
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview<eT>::operator+= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Proxy<T1> P(in.get_ref());
+  
+  subview<eT>& s = *this;
+  
+  const uword s_n_rows = s.n_rows;
+  const uword s_n_cols = s.n_cols;
+  
+  arma_debug_assert_same_size(s, P, "addition");
+  
+  const bool is_alias = P.is_alias(s.m);
+  
+  arma_extra_debug_warn(is_alias, "aliasing detected");
+  
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) || (is_alias == true) )
+    {
+    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
+    const Mat<eT>& x = tmp.M;
+    
+    if(s_n_rows == 1)
+      {
+      const eT* x_mem = x.memptr();
+      
+      Mat<eT>& A = const_cast< Mat<eT>& >(m);
+      
+      const uword urow      = aux_row1;
+      const uword start_col = aux_col1;
+      
+      uword ii,jj;
+      for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+        {
+        A.at(urow, start_col+ii) += x_mem[ii];
+        A.at(urow, start_col+jj) += x_mem[jj];
+        }
+      
+      if(ii < s_n_cols)
+        {
+        A.at(urow, start_col+ii) += x_mem[ii];
+        }
+      }
+    else
+      {
+      for(uword ucol=0; ucol < s_n_cols; ++ucol)
+        {
+        arrayops::inplace_plus( s.colptr(ucol), x.colptr(ucol), s_n_rows );
+        }
+      }
+    }
+  else
+    {
+    if(s_n_rows == 1)
+      {
+      Mat<eT>& A = const_cast< Mat<eT>& >(m);
+      
+      const uword urow      = aux_row1;
+      const uword start_col = aux_col1;
+      
+      uword ii,jj;
+      for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+        {
+        const eT tmp1 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,ii) : P[ii];
+        const eT tmp2 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,jj) : P[jj];
+        
+        A.at(urow, start_col+ii) += tmp1;
+        A.at(urow, start_col+jj) += tmp2;
+        }
+      
+      if(ii < s_n_cols)
+        {
+        A.at(urow, start_col+ii) += (Proxy<T1>::prefer_at_accessor) ? P.at(0,ii) : P[ii];
+        }
+      }
+    else
+      {
+      for(uword ucol=0; ucol < s_n_cols; ++ucol)
+        {
+        eT* s_col_data = s.colptr(ucol);
+        
+        uword ii,jj;
+        for(ii=0, jj=1; jj < s_n_rows; ii+=2, jj+=2)
+          {
+          const eT val1 = P.at(ii,ucol);
+          const eT val2 = P.at(jj,ucol);
+          
+          s_col_data[ii] += val1;
+          s_col_data[jj] += val2;
+          }
+        
+        if(ii < s_n_rows)
+          {
+          s_col_data[ii] += P.at(ii,ucol);
+          }
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview<eT>::operator-= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Proxy<T1> P(in.get_ref());
+  
+  subview<eT>& s = *this;
+  
+  const uword s_n_rows = s.n_rows;
+  const uword s_n_cols = s.n_cols;
+  
+  arma_debug_assert_same_size(s, P, "subtraction");
+  
+  const bool is_alias = P.is_alias(s.m);
+  
+  arma_extra_debug_warn(is_alias, "aliasing detected");
+  
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) || (is_alias == true) )
+    {
+    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
+    const Mat<eT>& x = tmp.M;
+    
+    if(s_n_rows == 1)
+      {
+      const eT* x_mem = x.memptr();
+      
+      Mat<eT>& A = const_cast< Mat<eT>& >(m);
+      
+      const uword urow      = aux_row1;
+      const uword start_col = aux_col1;
+      
+      uword ii,jj;
+      for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+        {
+        A.at(urow, start_col+ii) -= x_mem[ii];
+        A.at(urow, start_col+jj) -= x_mem[jj];
+        }
+      
+      if(ii < s_n_cols)
+        {
+        A.at(urow, start_col+ii) -= x_mem[ii];
+        }
+      }
+    else
+      {
+      for(uword ucol=0; ucol < s_n_cols; ++ucol)
+        {
+        arrayops::inplace_minus( s.colptr(ucol), x.colptr(ucol), s_n_rows );
+        }
+      }
+    }
+  else
+    {
+    if(s_n_rows == 1)
+      {
+      Mat<eT>& A = const_cast< Mat<eT>& >(m);
+      
+      const uword urow      = aux_row1;
+      const uword start_col = aux_col1;
+      
+      uword ii,jj;
+      for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+        {
+        const eT tmp1 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,ii) : P[ii];
+        const eT tmp2 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,jj) : P[jj];
+        
+        A.at(urow, start_col+ii) -= tmp1;
+        A.at(urow, start_col+jj) -= tmp2;
+        }
+      
+      if(ii < s_n_cols)
+        {
+        A.at(urow, start_col+ii) -= (Proxy<T1>::prefer_at_accessor) ? P.at(0,ii) : P[ii];
+        }
+      }
+    else
+      {
+      for(uword ucol=0; ucol < s_n_cols; ++ucol)
+        {
+        eT* s_col_data = s.colptr(ucol);
+        
+        uword ii,jj;
+        for(ii=0, jj=1; jj < s_n_rows; ii+=2, jj+=2)
+          {
+          const eT val1 = P.at(ii,ucol);
+          const eT val2 = P.at(jj,ucol);
+          
+          s_col_data[ii] -= val1;
+          s_col_data[jj] -= val2;
+          }
+        
+        if(ii < s_n_rows)
+          {
+          s_col_data[ii] -= P.at(ii,ucol);
+          }
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview<eT>::operator%= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Proxy<T1> P(in.get_ref());
+  
+  subview<eT>& s = *this;
+  
+  const uword s_n_rows = s.n_rows;
+  const uword s_n_cols = s.n_cols;
+  
+  arma_debug_assert_same_size(s, P, "element-wise multiplication");
+  
+  const bool is_alias = P.is_alias(s.m);
+  
+  arma_extra_debug_warn(is_alias, "aliasing detected");
+  
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) || (is_alias == true) )
+    {
+    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
+    const Mat<eT>& x = tmp.M;
+    
+    if(s_n_rows == 1)
+      {
+      const eT* x_mem = x.memptr();
+      
+      Mat<eT>& A = const_cast< Mat<eT>& >(m);
+      
+      const uword urow      = aux_row1;
+      const uword start_col = aux_col1;
+      
+      uword ii,jj;
+      for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+        {
+        A.at(urow, start_col+ii) *= x_mem[ii];
+        A.at(urow, start_col+jj) *= x_mem[jj];
+        }
+      
+      if(ii < s_n_cols)
+        {
+        A.at(urow, start_col+ii) *= x_mem[ii];
+        }
+      }
+    else
+      {
+      for(uword ucol=0; ucol < s_n_cols; ++ucol)
+        {
+        arrayops::inplace_mul( s.colptr(ucol), x.colptr(ucol), s_n_rows );
+        }
+      }
+    }
+  else
+    {
+    if(s_n_rows == 1)
+      {
+      Mat<eT>& A = const_cast< Mat<eT>& >(m);
+      
+      const uword urow      = aux_row1;
+      const uword start_col = aux_col1;
+      
+      uword ii,jj;
+      for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+        {
+        const eT tmp1 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,ii) : P[ii];
+        const eT tmp2 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,jj) : P[jj];
+        
+        A.at(urow, start_col+ii) *= tmp1;
+        A.at(urow, start_col+jj) *= tmp2;
+        }
+      
+      if(ii < s_n_cols)
+        {
+        A.at(urow, start_col+ii) *= (Proxy<T1>::prefer_at_accessor) ? P.at(0,ii) : P[ii];
+        }
+      }
+    else
+      {
+      for(uword ucol=0; ucol < s_n_cols; ++ucol)
+        {
+        eT* s_col_data = s.colptr(ucol);
+        
+        uword ii,jj;
+        for(ii=0, jj=1; jj < s_n_rows; ii+=2, jj+=2)
+          {
+          const eT val1 = P.at(ii,ucol);
+          const eT val2 = P.at(jj,ucol);
+          
+          s_col_data[ii] *= val1;
+          s_col_data[jj] *= val2;
+          }
+        
+        if(ii < s_n_rows)
+          {
+          s_col_data[ii] *= P.at(ii,ucol);
+          }
+        }
+      }
+    }
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview<eT>::operator/= (const Base<eT,T1>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const Proxy<T1> P(in.get_ref());
+  
+  subview<eT>& s = *this;
+  
+  const uword s_n_rows = s.n_rows;
+  const uword s_n_cols = s.n_cols;
+  
+  arma_debug_assert_same_size(s, P, "element-wise division");
+  
+  const bool is_alias = P.is_alias(s.m);
+  
+  arma_extra_debug_warn(is_alias, "aliasing detected");
+  
+  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) || (is_alias == true) )
+    {
+    const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
+    const Mat<eT>& x = tmp.M;
+    
+    if(s_n_rows == 1)
+      {
+      const eT* x_mem = x.memptr();
+      
+      Mat<eT>& A = const_cast< Mat<eT>& >(m);
+      
+      const uword urow      = aux_row1;
+      const uword start_col = aux_col1;
+      
+      uword ii,jj;
+      for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+        {
+        A.at(urow, start_col+ii) /= x_mem[ii];
+        A.at(urow, start_col+jj) /= x_mem[jj];
+        }
+      
+      if(ii < s_n_cols)
+        {
+        A.at(urow, start_col+ii) /= x_mem[ii];
+        }
+      }
+    else
+      {
+      for(uword ucol=0; ucol < s_n_cols; ++ucol)
+        {
+        arrayops::inplace_div( s.colptr(ucol), x.colptr(ucol), s_n_rows );
+        }
+      }
+    }
+  else
+    {
+    if(s_n_rows == 1)
+      {
+      Mat<eT>& A = const_cast< Mat<eT>& >(m);
+      
+      const uword urow      = aux_row1;
+      const uword start_col = aux_col1;
+      
+      uword ii,jj;
+      for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+        {
+        const eT tmp1 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,ii) : P[ii];
+        const eT tmp2 = (Proxy<T1>::prefer_at_accessor) ? P.at(0,jj) : P[jj];
+        
+        A.at(urow, start_col+ii) /= tmp1;
+        A.at(urow, start_col+jj) /= tmp2;
+        }
+      
+      if(ii < s_n_cols)
+        {
+        A.at(urow, start_col+ii) /= (Proxy<T1>::prefer_at_accessor) ? P.at(0,ii) : P[ii];
+        }
+      }
+    else
+      {
+      for(uword ucol=0; ucol < s_n_cols; ++ucol)
+        {
+        eT* s_col_data = s.colptr(ucol);
+        
+        uword ii,jj;
+        for(ii=0, jj=1; jj < s_n_rows; ii+=2, jj+=2)
+          {
+          const eT val1 = P.at(ii,ucol);
+          const eT val2 = P.at(jj,ucol);
+          
+          s_col_data[ii] /= val1;
+          s_col_data[jj] /= val2;
+          }
+        
+        if(ii < s_n_rows)
+          {
+          s_col_data[ii] /= P.at(ii,ucol);
+          }
+        }
+      }
+    }
+  }
+
+
+
+//! x.submat(...) = y.submat(...)
+template<typename eT>
+inline
+void
+subview<eT>::operator= (const subview<eT>& x_in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool overlap = check_overlap(x_in);
+  
+        Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
+  const subview<eT>* tmp_subview = overlap ? new subview<eT>(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
+  const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
+  
+  subview<eT>& s = *this;
+  
+  arma_debug_assert_same_size(s, x, "copy into submatrix");
+  
+  const uword s_n_cols = s.n_cols;
+  const uword s_n_rows = s.n_rows;
+  
+  if(s_n_rows == 1)
+    {
+          Mat<eT>& A = const_cast< Mat<eT>& >(s.m);
+    const Mat<eT>& B = x.m;
+    
+    const uword row_A = s.aux_row1;
+    const uword row_B = x.aux_row1;
+    
+    const uword start_col_A = s.aux_col1;
+    const uword start_col_B = x.aux_col1;
+    
+    uword ii,jj;
+    for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+      {
+      const eT tmp1 = B.at(row_B, start_col_B + ii);
+      const eT tmp2 = B.at(row_B, start_col_B + jj);
+      
+      A.at(row_A, start_col_A + ii) = tmp1;
+      A.at(row_A, start_col_A + jj) = tmp2;
+      }
+    
+    if(ii < s_n_cols)
+      {
+      A.at(row_A, start_col_A + ii) = B.at(row_B, start_col_B + ii);
+      }
+    }
+  else
+    {
+    for(uword ucol=0; ucol < s_n_cols; ++ucol)
+      {
+      arrayops::copy( s.colptr(ucol), x.colptr(ucol), s_n_rows );
+      }
+    }
+  
+  if(overlap)
+    {
+    delete tmp_subview;
+    delete tmp_mat;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::operator+= (const subview<eT>& x_in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool overlap = check_overlap(x_in);
+  
+        Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
+  const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
+  const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
+  
+  subview<eT>& s = *this;
+  
+  arma_debug_assert_same_size(s, x, "addition");
+  
+  const uword s_n_rows = s.n_rows;
+  const uword s_n_cols = s.n_cols;
+  
+  if(s_n_rows == 1)
+    {
+          Mat<eT>& A = const_cast< Mat<eT>& >(s.m);
+    const Mat<eT>& B = x.m;
+    
+    const uword row_A = s.aux_row1;
+    const uword row_B = x.aux_row1;
+    
+    const uword start_col_A = s.aux_col1;
+    const uword start_col_B = x.aux_col1;
+    
+    uword ii,jj;
+    
+    for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+      {
+      const eT tmp1 = B.at(row_B, start_col_B + ii);
+      const eT tmp2 = B.at(row_B, start_col_B + jj);
+      
+      A.at(row_A, start_col_A + ii) += tmp1;
+      A.at(row_A, start_col_A + jj) += tmp2;
+      }
+    
+    if(ii < s_n_cols)
+      {
+      A.at(row_A, start_col_A + ii) += B.at(row_B, start_col_B + ii);
+      }
+    }
+  else
+    {
+    for(uword ucol=0; ucol < s_n_cols; ++ucol)
+      {
+      arrayops::inplace_plus( s.colptr(ucol), x.colptr(ucol), s_n_rows );
+      }
+    }
+  
+  if(overlap)
+    {
+    delete tmp_subview;
+    delete tmp_mat;
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::operator-= (const subview<eT>& x_in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool overlap = check_overlap(x_in);
+  
+        Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
+  const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
+  const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
+  
+  subview<eT>& s = *this;
+  
+  arma_debug_assert_same_size(s, x, "subtraction");
+  
+  const uword s_n_rows = s.n_rows;
+  const uword s_n_cols = s.n_cols;
+  
+  if(s_n_rows == 1)
+    {
+          Mat<eT>& A = const_cast< Mat<eT>& >(s.m);
+    const Mat<eT>& B = x.m;
+    
+    const uword row_A = s.aux_row1;
+    const uword row_B = x.aux_row1;
+    
+    const uword start_col_A = s.aux_col1;
+    const uword start_col_B = x.aux_col1;
+    
+    uword ii,jj;
+    for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+      {
+      const eT tmp1 = B.at(row_B, start_col_B + ii);
+      const eT tmp2 = B.at(row_B, start_col_B + jj);
+      
+      A.at(row_A, start_col_A + ii) -= tmp1;
+      A.at(row_A, start_col_A + jj) -= tmp2;
+      }
+    
+    if(ii < s_n_cols)
+      {
+      A.at(row_A, start_col_A + ii) -= B.at(row_B, start_col_B + ii);
+      }
+    }
+  else
+    {
+    for(uword ucol=0; ucol < s_n_cols; ++ucol)
+      {
+      arrayops::inplace_minus( s.colptr(ucol), x.colptr(ucol), s_n_rows );
+      }
+    }
+    
+  if(overlap)
+    {
+    delete tmp_subview;
+    delete tmp_mat;
+    }
+  
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::operator%= (const subview& x_in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool overlap = check_overlap(x_in);
+  
+        Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
+  const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
+  const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
+  
+  subview<eT>& s = *this;
+  
+  arma_debug_assert_same_size(s, x, "element-wise multiplication");
+  
+  const uword s_n_rows = s.n_rows;
+  const uword s_n_cols = s.n_cols;
+  
+  if(s_n_rows == 1)
+    {
+          Mat<eT>& A = const_cast< Mat<eT>& >(s.m);
+    const Mat<eT>& B = x.m;
+    
+    const uword row_A = s.aux_row1;
+    const uword row_B = x.aux_row1;
+    
+    const uword start_col_A = s.aux_col1;
+    const uword start_col_B = x.aux_col1;
+    
+    uword ii,jj;
+    for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+      {
+      const eT tmp1 = B.at(row_B, start_col_B + ii);
+      const eT tmp2 = B.at(row_B, start_col_B + jj);
+      
+      A.at(row_A, start_col_A + ii) *= tmp1;
+      A.at(row_A, start_col_A + jj) *= tmp2;
+      }
+    
+    if(ii < s_n_cols)
+      {
+      A.at(row_A, start_col_A + ii) *= B.at(row_B, start_col_B + ii);
+      }
+    }
+  else
+    {
+    for(uword ucol=0; ucol < s_n_cols; ++ucol)
+      {
+      arrayops::inplace_mul( s.colptr(ucol), x.colptr(ucol), s_n_rows );
+      }
+    }
+  
+  if(overlap)
+    {
+    delete tmp_subview;
+    delete tmp_mat;
+    }
+  
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::operator/= (const subview& x_in)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool overlap = check_overlap(x_in);
+  
+        Mat<eT>*     tmp_mat     = overlap ? new Mat<eT>(x_in.m) : 0;
+  const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0;
+  const subview<eT>&           x = overlap ? (*tmp_subview) : x_in;
+  
+  subview<eT>& s = *this;
+  
+  arma_debug_assert_same_size(s, x, "element-wise division");
+  
+  const uword s_n_rows = s.n_rows;
+  const uword s_n_cols = s.n_cols;
+  
+  if(s_n_rows == 1)
+    {
+          Mat<eT>& A = const_cast< Mat<eT>& >(s.m);
+    const Mat<eT>& B = x.m;
+    
+    const uword row_A = s.aux_row1;
+    const uword row_B = x.aux_row1;
+    
+    const uword start_col_A = s.aux_col1;
+    const uword start_col_B = x.aux_col1;
+    
+    uword ii,jj;
+    for(ii=0, jj=1; jj < s_n_cols; ii+=2, jj+=2)
+      {
+      const eT tmp1 = B.at(row_B, start_col_B + ii);
+      const eT tmp2 = B.at(row_B, start_col_B + jj);
+      
+      A.at(row_A, start_col_A + ii) /= tmp1;
+      A.at(row_A, start_col_A + jj) /= tmp2;
+      }
+    
+    if(ii < s_n_cols)
+      {
+      A.at(row_A, start_col_A + ii) /= B.at(row_B, start_col_B + ii);
+      }
+    }
+  else
+    {
+    for(uword ucol=0; ucol < s_n_cols; ++ucol)
+      {
+      arrayops::inplace_div( s.colptr(ucol), x.colptr(ucol), s_n_rows );
+      }
+    }
+    
+  if(overlap)
+    {
+    delete tmp_subview;
+    delete tmp_mat;
+    }
+  
+  }
+
+
+
+//! transform each element in the subview using a functor
+template<typename eT>
+template<typename functor>
+inline
+void
+subview<eT>::transform(functor F)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword local_n_cols = n_cols;
+  const uword local_n_rows = n_rows;
+  
+  Mat<eT>& X = const_cast< Mat<eT>& >(m);
+  
+  if(local_n_rows == 1)
+    {
+    const uword urow          = aux_row1;
+    const uword start_col     = aux_col1;
+    const uword end_col_plus1 = start_col + local_n_cols;
+    
+    for(uword ucol = start_col; ucol < end_col_plus1; ++ucol)
+      {
+      X.at(urow, ucol) = eT( F( X.at(urow, ucol) ) );
+      }
+    }
+  else
+    {
+    const uword start_col = aux_col1;
+    const uword start_row = aux_row1;
+    
+    const uword end_col_plus1 = start_col + local_n_cols;
+    const uword end_row_plus1 = start_row + local_n_rows;
+    
+    for(uword ucol = start_col; ucol < end_col_plus1; ++ucol)
+    for(uword urow = start_row; urow < end_row_plus1; ++urow)
+      {
+      X.at(urow, ucol) = eT( F( X.at(urow, ucol) ) );
+      }
+    }
+  }
+
+
+
+//! imbue (fill) the subview with values provided by a functor
+template<typename eT>
+template<typename functor>
+inline
+void
+subview<eT>::imbue(functor F)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword local_n_cols = n_cols;
+  const uword local_n_rows = n_rows;
+  
+  Mat<eT>& X = const_cast< Mat<eT>& >(m);
+  
+  if(local_n_rows == 1)
+    {
+    const uword urow          = aux_row1;
+    const uword start_col     = aux_col1;
+    const uword end_col_plus1 = start_col + local_n_cols;
+    
+    for(uword ucol = start_col; ucol < end_col_plus1; ++ucol)
+      {
+      X.at(urow, ucol) = eT( F() );
+      }
+    }
+  else
+    {
+    const uword start_col = aux_col1;
+    const uword start_row = aux_row1;
+    
+    const uword end_col_plus1 = start_col + local_n_cols;
+    const uword end_row_plus1 = start_row + local_n_rows;
+    
+    for(uword ucol = start_col; ucol < end_col_plus1; ++ucol)
+    for(uword urow = start_row; urow < end_row_plus1; ++urow)
+      {
+      X.at(urow, ucol) = eT( F() );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::fill(const eT val)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword local_n_cols = n_cols;
+  const uword local_n_rows = n_rows;
+  
+  if(local_n_rows == 1)
+    {
+    Mat<eT>& X = const_cast< Mat<eT>& >(m);
+    
+    const uword urow          = aux_row1;
+    const uword start_col     = aux_col1;
+    const uword end_col_plus1 = start_col + local_n_cols;
+    
+    uword ii,jj;
+    for(ii=start_col, jj=start_col+1; jj < end_col_plus1; ii+=2, jj+=2)
+      {
+      X.at(urow, ii) = val;
+      X.at(urow, jj) = val;
+      }
+    
+    if(ii < end_col_plus1)
+      {
+      X.at(urow, ii) = val;
+      }
+    }
+  else
+    {
+    for(uword ucol=0; ucol < local_n_cols; ++ucol)
+      {
+      arrayops::inplace_set( colptr(ucol), val, local_n_rows );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::zeros()
+  {
+  arma_extra_debug_sigprint();
+  
+  (*this).fill(eT(0));
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::ones()
+  {
+  arma_extra_debug_sigprint();
+  
+  (*this).fill(eT(1));
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::eye()
+  {
+  arma_extra_debug_sigprint();
+  
+  fill(eT(0));
+  
+  const uword N = (std::min)(n_rows, n_cols);
+  
+  for(uword ii=0; ii < N; ++ii)
+    {
+    at(ii,ii) = eT(1);
+    }
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview<eT>::at_alt(const uword ii) const
+  {
+  return operator[](ii);
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+subview<eT>::operator[](const uword ii)
+  {
+  const uword in_col = ii / n_rows;
+  const uword in_row = ii % n_rows;
+  
+  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return access::rw( (const_cast< Mat<eT>& >(m)).mem[index] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview<eT>::operator[](const uword ii) const
+  {
+  const uword in_col = ii / n_rows;
+  const uword in_row = ii % n_rows;
+  
+  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return m.mem[index];
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+subview<eT>::operator()(const uword ii)
+  {
+  arma_debug_check( (ii >= n_elem), "subview::operator(): index out of bounds");
+    
+  const uword in_col = ii / n_rows;
+  const uword in_row = ii % n_rows;
+  
+  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return access::rw( (const_cast< Mat<eT>& >(m)).mem[index] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview<eT>::operator()(const uword ii) const
+  {
+  arma_debug_check( (ii >= n_elem), "subview::operator(): index out of bounds");
+  
+  const uword in_col = ii / n_rows;
+  const uword in_row = ii % n_rows;
+  
+  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return m.mem[index];
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+subview<eT>::operator()(const uword in_row, const uword in_col)
+  {
+  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "subview::operator(): index out of bounds");
+  
+  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return access::rw( (const_cast< Mat<eT>& >(m)).mem[index] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview<eT>::operator()(const uword in_row, const uword in_col) const
+  {
+  arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "subview::operator(): index out of bounds");
+  
+  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return m.mem[index];
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+subview<eT>::at(const uword in_row, const uword in_col)
+  {
+  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return access::rw( (const_cast< Mat<eT>& >(m)).mem[index] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview<eT>::at(const uword in_row, const uword in_col) const
+  {
+  const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
+  
+  return m.mem[index];
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT*
+subview<eT>::colptr(const uword in_col)
+  {
+  return & access::rw((const_cast< Mat<eT>& >(m)).mem[ (in_col + aux_col1)*m.n_rows + aux_row1 ]);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const eT*
+subview<eT>::colptr(const uword in_col) const
+  {
+  return & m.mem[ (in_col + aux_col1)*m.n_rows + aux_row1 ];
+  }
+
+
+
+template<typename eT>
+inline
+bool
+subview<eT>::check_overlap(const subview<eT>& x) const
+  {
+  const subview<eT>& s = *this;
+  
+  if(&s.m != &x.m)
+    {
+    return false;
+    }
+  else
+    {
+    if( (s.n_elem == 0) || (x.n_elem == 0) )
+      {
+      return false;
+      }
+    else
+      {
+      const uword s_row_start  = s.aux_row1;
+      const uword s_row_end_p1 = s_row_start + s.n_rows;
+      
+      const uword s_col_start  = s.aux_col1;
+      const uword s_col_end_p1 = s_col_start + s.n_cols;
+      
+      
+      const uword x_row_start  = x.aux_row1;
+      const uword x_row_end_p1 = x_row_start + x.n_rows;
+      
+      const uword x_col_start  = x.aux_col1;
+      const uword x_col_end_p1 = x_col_start + x.n_cols;
+      
+      
+      const bool outside_rows = ( (x_row_start >= s_row_end_p1) || (s_row_start >= x_row_end_p1) );
+      const bool outside_cols = ( (x_col_start >= s_col_end_p1) || (s_col_start >= x_col_end_p1) );
+      
+      return ( (outside_rows == false) && (outside_cols == false) );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+bool
+subview<eT>::is_vec() const
+  {
+  return ( (n_rows == 1) || (n_cols == 1) );
+  }
+
+
+
+//! X = Y.submat(...)
+template<typename eT>
+inline
+void
+subview<eT>::extract(Mat<eT>& out, const subview<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing;
+  // size setting and alias checking is done by either the Mat contructor or operator=()
+  
+  const uword n_rows = in.n_rows;  // number of rows in the subview
+  const uword n_cols = in.n_cols;  // number of columns in the subview
+  
+  arma_extra_debug_print(arma_boost::format("out.n_rows = %d   out.n_cols = %d    in.m.n_rows = %d  in.m.n_cols = %d") % out.n_rows % out.n_cols % in.m.n_rows % in.m.n_cols );
+  
+  
+  if(in.is_vec() == true)
+    {
+    if(n_cols == 1)   // a column vector
+      {
+      arma_extra_debug_print("subview::extract(): copying col (going across rows)");
+      
+      // in.colptr(0) the first column of the subview, taking into account any row offset
+      arrayops::copy( out.memptr(), in.colptr(0), n_rows );
+      }
+    else   // a row vector (possibly empty)
+      {
+      arma_extra_debug_print("subview::extract(): copying row (going across columns)");
+      
+      const Mat<eT>& X = in.m;
+      
+      eT* out_mem = out.memptr();
+      
+      const uword row       = in.aux_row1;
+      const uword start_col = in.aux_col1;
+      
+      uword i,j;
+      
+      for(i=0, j=1; j < n_cols; i+=2, j+=2)
+        {
+        const eT tmp1 = X.at(row, start_col+i);
+        const eT tmp2 = X.at(row, start_col+j);
+        
+        out_mem[i] = tmp1;
+        out_mem[j] = tmp2;
+        }
+      
+      if(i < n_cols)
+        {
+        out_mem[i] = X.at(row, start_col+i);
+        }
+      }
+    }
+  else   // general submatrix
+    {
+    arma_extra_debug_print("subview::extract(): general submatrix");
+    
+    for(uword col=0; col < n_cols; ++col)
+      {
+      arrayops::copy( out.colptr(col), in.colptr(col), n_rows );
+      }
+    }
+  }
+
+
+
+//! X += Y.submat(...)
+template<typename eT>
+inline
+void
+subview<eT>::plus_inplace(Mat<eT>& out, const subview<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out, in, "addition");
+  
+  const uword n_rows = in.n_rows;
+  const uword n_cols = in.n_cols;
+  
+  if(n_rows == 1)
+    {
+    eT* out_mem = out.memptr();
+    
+    const Mat<eT>& X = in.m;
+    
+    const uword row       = in.aux_row1;
+    const uword start_col = in.aux_col1;
+    
+    uword i,j;
+    for(i=0, j=1; j < n_cols; i+=2, j+=2)
+      {
+      const eT tmp1 = X.at(row, start_col+i);
+      const eT tmp2 = X.at(row, start_col+j);
+        
+      out_mem[i] += tmp1;
+      out_mem[j] += tmp2;
+      }
+    
+    if(i < n_cols)
+      {
+      out_mem[i] += X.at(row, start_col+i);
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+      {
+      arrayops::inplace_plus(out.colptr(col), in.colptr(col), n_rows);
+      }
+    }
+  }
+
+
+
+//! X -= Y.submat(...)
+template<typename eT>
+inline
+void
+subview<eT>::minus_inplace(Mat<eT>& out, const subview<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out, in, "subtraction");
+  
+  const uword n_rows = in.n_rows;
+  const uword n_cols = in.n_cols;
+  
+  if(n_rows == 1)
+    {
+    eT* out_mem = out.memptr();
+    
+    const Mat<eT>& X = in.m;
+    
+    const uword row       = in.aux_row1;
+    const uword start_col = in.aux_col1;
+    
+    uword i,j;
+    for(i=0, j=1; j < n_cols; i+=2, j+=2)
+      {
+      const eT tmp1 = X.at(row, start_col+i);
+      const eT tmp2 = X.at(row, start_col+j);
+        
+      out_mem[i] -= tmp1;
+      out_mem[j] -= tmp2;
+      }
+    
+    if(i < n_cols)
+      {
+      out_mem[i] -= X.at(row, start_col+i);
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+      {
+      arrayops::inplace_minus(out.colptr(col), in.colptr(col), n_rows);
+      }
+    }
+  }
+
+
+
+//! X %= Y.submat(...)
+template<typename eT>
+inline
+void
+subview<eT>::schur_inplace(Mat<eT>& out, const subview<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out, in, "element-wise multiplication");
+  
+  const uword n_rows = in.n_rows;
+  const uword n_cols = in.n_cols;
+  
+  if(n_rows == 1)
+    {
+    eT* out_mem = out.memptr();
+    
+    const Mat<eT>& X = in.m;
+    
+    const uword row       = in.aux_row1;
+    const uword start_col = in.aux_col1;
+    
+    uword i,j;
+    for(i=0, j=1; j < n_cols; i+=2, j+=2)
+      {
+      const eT tmp1 = X.at(row, start_col+i);
+      const eT tmp2 = X.at(row, start_col+j);
+        
+      out_mem[i] *= tmp1;
+      out_mem[j] *= tmp2;
+      }
+    
+    if(i < n_cols)
+      {
+      out_mem[i] *= X.at(row, start_col+i);
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+      {
+      arrayops::inplace_mul(out.colptr(col), in.colptr(col), n_rows);
+      }
+    }
+  }
+
+
+
+//! X /= Y.submat(...)
+template<typename eT>
+inline
+void
+subview<eT>::div_inplace(Mat<eT>& out, const subview<eT>& in)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_assert_same_size(out, in, "element-wise division");
+  
+  const uword n_rows = in.n_rows;
+  const uword n_cols = in.n_cols;
+  
+  if(n_rows == 1)
+    {
+    eT* out_mem = out.memptr();
+    
+    const Mat<eT>& X = in.m;
+    
+    const uword row       = in.aux_row1;
+    const uword start_col = in.aux_col1;
+    
+    uword i,j;
+    for(i=0, j=1; j < n_cols; i+=2, j+=2)
+      {
+      const eT tmp1 = X.at(row, start_col+i);
+      const eT tmp2 = X.at(row, start_col+j);
+        
+      out_mem[i] /= tmp1;
+      out_mem[j] /= tmp2;
+      }
+    
+    if(i < n_cols)
+      {
+      out_mem[i] /= X.at(row, start_col+i);
+      }
+    }
+  else
+    {
+    for(uword col=0; col < n_cols; ++col)
+      {
+      arrayops::inplace_div(out.colptr(col), in.colptr(col), n_rows);
+      }
+    }
+  }
+
+
+
+//! creation of subview (row vector)
+template<typename eT>
+inline
+subview_row<eT>
+subview<eT>::row(const uword row_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( row_num >= n_rows, "subview::row(): out of bounds" );
+  
+  const uword base_row = aux_row1 + row_num;
+  
+  return subview_row<eT>(m, base_row, aux_col1, n_cols);
+  }
+
+
+
+//! creation of subview (row vector)
+template<typename eT>
+inline
+const subview_row<eT>
+subview<eT>::row(const uword row_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( row_num >= n_rows, "subview::row(): out of bounds" );
+  
+  const uword base_row = aux_row1 + row_num;
+  
+  return subview_row<eT>(m, base_row, aux_col1, n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+subview_row<eT>
+subview<eT>::operator()(const uword row_num, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_cols = n_cols;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  const uword base_col1     = aux_col1 + in_col1;  
+  const uword base_row      = aux_row1 + row_num;
+  
+  arma_debug_check
+    (
+    (row_num >= n_rows)
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "subview::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview_row<eT>(m, base_row, base_col1, submat_n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+const subview_row<eT>
+subview<eT>::operator()(const uword row_num, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_cols = n_cols;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  const uword base_col1     = aux_col1 + in_col1;
+  const uword base_row      = aux_row1 + row_num;
+  
+  arma_debug_check
+    (
+    (row_num >= n_rows)
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "subview::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview_row<eT>(m, base_row, base_col1, submat_n_cols);
+  }
+
+
+
+//! creation of subview (column vector)
+template<typename eT>
+inline
+subview_col<eT>
+subview<eT>::col(const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( col_num >= n_cols, "subview::col(): out of bounds");
+  
+  const uword base_col = aux_col1 + col_num;
+  
+  return subview_col<eT>(m, base_col, aux_row1, n_rows);
+  }
+
+
+
+//! creation of subview (column vector)
+template<typename eT>
+inline
+const subview_col<eT>
+subview<eT>::col(const uword col_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( col_num >= n_cols, "subview::col(): out of bounds");
+  
+  const uword base_col = aux_col1 + col_num;
+  
+  return subview_col<eT>(m, base_col, aux_row1, n_rows);
+  }
+
+
+
+template<typename eT>
+inline
+subview_col<eT>
+subview<eT>::operator()(const span& row_span, const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  const uword base_row1       = aux_row1 + in_row1;  
+  const uword base_col        = aux_col1 + col_num;
+  
+  arma_debug_check
+    (
+    (col_num >= n_cols)
+    ||
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ,
+    "subview::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview_col<eT>(m, base_col, base_row1, submat_n_rows);
+  }
+
+
+
+template<typename eT>
+inline
+const subview_col<eT>
+subview<eT>::operator()(const span& row_span, const uword col_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  const uword base_row1       = aux_row1 + in_row1;
+  const uword base_col        = aux_col1 + col_num;
+  
+  arma_debug_check
+    (
+    (col_num >= n_cols)
+    ||
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ,
+    "subview::operator(): indices out of bounds or incorrectly used"
+    );
+  
+  return subview_col<eT>(m, base_col, base_row1, submat_n_rows);
+  }
+
+
+
+//! create a Col object which uses memory from an existing matrix object.
+//! this approach is currently not alias safe
+//! and does not take into account that the parent matrix object could be deleted.
+//! if deleted memory is accessed by the created Col object,
+//! it will cause memory corruption and/or a crash
+template<typename eT>
+inline
+Col<eT>
+subview<eT>::unsafe_col(const uword col_num)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( col_num >= n_cols, "subview::unsafe_col(): out of bounds");
+  
+  return Col<eT>(colptr(col_num), n_rows, false, true);
+  }
+
+
+
+//! create a Col object which uses memory from an existing matrix object.
+//! this approach is currently not alias safe
+//! and does not take into account that the parent matrix object could be deleted.
+//! if deleted memory is accessed by the created Col object,
+//! it will cause memory corruption and/or a crash
+template<typename eT>
+inline
+const Col<eT>
+subview<eT>::unsafe_col(const uword col_num) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( col_num >= n_cols, "subview::unsafe_col(): out of bounds");
+  
+  return Col<eT>(const_cast<eT*>(colptr(col_num)), n_rows, false, true);
+  }
+
+
+
+//! creation of subview (submatrix comprised of specified row vectors)
+template<typename eT>
+inline
+subview<eT>
+subview<eT>::rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_row2 >= n_rows),
+    "subview::rows(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  const uword base_row1 = aux_row1 + in_row1;
+  
+  return subview<eT>(m, base_row1, aux_col1, subview_n_rows, n_cols );
+  }
+
+
+
+//! creation of subview (submatrix comprised of specified row vectors)
+template<typename eT>
+inline
+const subview<eT>
+subview<eT>::rows(const uword in_row1, const uword in_row2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_row2 >= n_rows),
+    "subview::rows(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  const uword base_row1 = aux_row1 + in_row1;
+  
+  return subview<eT>(m, base_row1, aux_col1, subview_n_rows, n_cols );
+  }
+
+
+
+//! creation of subview (submatrix comprised of specified column vectors)
+template<typename eT>
+inline
+subview<eT>
+subview<eT>::cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_col1 > in_col2) || (in_col2 >= n_cols),
+    "subview::cols(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  const uword base_col1 = aux_col1 + in_col1;
+  
+  return subview<eT>(m, aux_row1, base_col1, n_rows, subview_n_cols);
+  }
+
+
+
+//! creation of subview (submatrix comprised of specified column vectors)
+template<typename eT>
+inline
+const subview<eT>
+subview<eT>::cols(const uword in_col1, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_col1 > in_col2) || (in_col2 >= n_cols),
+    "subview::cols(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  const uword base_col1 = aux_col1 + in_col1;
+  
+  return subview<eT>(m, aux_row1, base_col1, n_rows, subview_n_cols);
+  }
+
+
+
+//! creation of subview (submatrix)
+template<typename eT>
+inline
+subview<eT>
+subview<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
+    "subview::submat(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  const uword base_row1 = aux_row1 + in_row1;
+  const uword base_col1 = aux_col1 + in_col1;
+  
+  return subview<eT>(m, base_row1, base_col1, subview_n_rows, subview_n_cols);
+  }
+
+
+
+//! creation of subview (generic submatrix)
+template<typename eT>
+inline
+const subview<eT>
+subview<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 > in_row2) || (in_col1 >  in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
+    "subview::submat(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  const uword base_row1 = aux_row1 + in_row1;
+  const uword base_col1 = aux_col1 + in_col1;
+  
+  return subview<eT>(m, base_row1, base_col1, subview_n_rows, subview_n_cols);
+  }
+
+
+
+//! creation of subview (submatrix)
+template<typename eT>
+inline
+subview<eT>
+subview<eT>::submat(const span& row_span, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  const uword local_n_cols = n_cols;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  arma_debug_check
+    (
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "subview::submat(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword base_row1 = aux_row1 + in_row1;
+  const uword base_col1 = aux_col1 + in_col1;
+  
+  return subview<eT>(m, base_row1, base_col1, submat_n_rows, submat_n_cols);
+  }
+
+
+
+//! creation of subview (generic submatrix)
+template<typename eT>
+inline
+const subview<eT>
+subview<eT>::submat(const span& row_span, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const bool row_all = row_span.whole;
+  const bool col_all = col_span.whole;
+  
+  const uword local_n_rows = n_rows;
+  const uword local_n_cols = n_cols;
+  
+  const uword in_row1       = row_all ? 0            : row_span.a;
+  const uword in_row2       =                          row_span.b;
+  const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
+  
+  const uword in_col1       = col_all ? 0            : col_span.a;
+  const uword in_col2       =                          col_span.b;
+  const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
+  
+  arma_debug_check
+    (
+    ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
+    ||
+    ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
+    ,
+    "subview::submat(): indices out of bounds or incorrectly used"
+    );
+  
+  const uword base_row1 = aux_row1 + in_row1;
+  const uword base_col1 = aux_col1 + in_col1;
+  
+  return subview<eT>(m, base_row1, base_col1, submat_n_rows, submat_n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+subview<eT>
+subview<eT>::operator()(const span& row_span, const span& col_span)
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).submat(row_span, col_span);
+  }
+
+
+
+template<typename eT>
+inline
+const subview<eT>
+subview<eT>::operator()(const span& row_span, const span& col_span) const
+  {
+  arma_extra_debug_sigprint();
+  
+  return (*this).submat(row_span, col_span);
+  }
+
+
+
+template<typename eT>
+inline
+subview_each1< subview<eT>, 0 >
+subview<eT>::each_col()
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_each1< subview<eT>, 0 >(*this);
+  }
+
+
+
+template<typename eT>
+inline
+subview_each1< subview<eT>, 1 >
+subview<eT>::each_row()
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_each1< subview<eT>, 1 >(*this);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+subview_each2< subview<eT>, 0, T1 >
+subview<eT>::each_col(const Base<uword,T1>& indices)
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_each2< subview<eT>, 0, T1 >(*this, indices);
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+subview_each2< subview<eT>, 1, T1 >
+subview<eT>::each_row(const Base<uword,T1>& indices)
+  {
+  arma_extra_debug_sigprint();
+  
+  return subview_each2< subview<eT>, 1, T1 >(*this, indices);
+  }
+
+
+
+//! creation of diagview (diagonal)
+template<typename eT>
+inline
+diagview<eT>
+subview<eT>::diag(const sword in_id)
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword row_offset = (in_id < 0) ? uword(-in_id) : 0;
+  const uword col_offset = (in_id > 0) ? uword( in_id) : 0;
+  
+  arma_debug_check
+    (
+    ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
+    "subview::diag(): requested diagonal out of bounds"
+    );
+  
+  const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
+  
+  const uword base_row_offset = aux_row1 + row_offset;
+  const uword base_col_offset = aux_col1 + col_offset;
+  
+  return diagview<eT>(m, base_row_offset, base_col_offset, len);
+  }
+
+
+
+//! creation of diagview (diagonal)
+template<typename eT>
+inline
+const diagview<eT>
+subview<eT>::diag(const sword in_id) const
+  {
+  arma_extra_debug_sigprint();
+  
+  const uword row_offset = (in_id < 0) ? -in_id : 0;
+  const uword col_offset = (in_id > 0) ?  in_id : 0;
+  
+  arma_debug_check
+    (
+    ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
+    "subview::diag(): requested diagonal out of bounds"
+    );
+  
+  const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
+  
+  const uword base_row_offset = aux_row1 + row_offset;
+  const uword base_col_offset = aux_col1 + col_offset;
+  
+  return diagview<eT>(m, base_row_offset, base_col_offset, len);
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::swap_rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_row1 >= n_rows) || (in_row2 >= n_rows),
+    "subview::swap_rows(): out of bounds"
+    );
+  
+  eT* mem = (const_cast< Mat<eT>& >(m)).memptr();
+  
+  if(n_elem > 0)
+    {
+    const uword m_n_rows = m.n_rows;
+    
+    for(uword ucol=0; ucol < n_cols; ++ucol)
+      {
+      const uword offset = (aux_col1 + ucol) * m_n_rows;
+      const uword pos1   = aux_row1 + in_row1 + offset;
+      const uword pos2   = aux_row1 + in_row2 + offset;
+      
+      std::swap( access::rw(mem[pos1]), access::rw(mem[pos2]) );
+      }
+    }
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview<eT>::swap_cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check
+    (
+    (in_col1 >= n_cols) || (in_col2 >= n_cols),
+    "subview::swap_cols(): out of bounds"
+    );
+  
+  if(n_elem > 0)
+    {
+    eT* ptr1 = colptr(in_col1);
+    eT* ptr2 = colptr(in_col2);
+    
+    for(uword urow=0; urow < n_rows; ++urow)
+      {
+      std::swap( ptr1[urow], ptr2[urow] );
+      }
+    }
+  }
+
+
+
+// template<typename eT>
+// inline
+// subview<eT>::iter::iter(const subview<eT>& S)
+//   : mem       (S.m.mem)
+//   , n_rows    (S.m.n_rows)
+//   , row_start (S.aux_row1)
+//   , row_end_p1(row_start + S.n_rows)
+//   , row       (row_start)
+//   , col       (S.aux_col1)
+//   , i         (row + col*n_rows)
+//   {
+//   arma_extra_debug_sigprint();
+//   }
+// 
+// 
+// 
+// template<typename eT>
+// arma_inline
+// eT
+// subview<eT>::iter::operator*() const
+//   {
+//   return mem[i];
+//   }
+// 
+// 
+// 
+// template<typename eT>
+// inline
+// void
+// subview<eT>::iter::operator++()
+//   {
+//   ++row;
+//   
+//   if(row < row_end_p1)
+//     {
+//     ++i;
+//     }
+//   else
+//     {
+//     row = row_start;
+//     ++col;
+//     
+//     i = row + col*n_rows;
+//     }
+//   }
+// 
+// 
+// 
+// template<typename eT>
+// inline
+// void
+// subview<eT>::iter::operator++(int)
+//   {
+//   operator++();
+//   }
+
+
+
+//
+//
+//
+
+
+
+template<typename eT>
+inline
+subview_col<eT>::subview_col(const Mat<eT>& in_m, const uword in_col)
+  : subview<eT>(in_m, 0, in_col, in_m.n_rows, 1)
+  , colmem(subview<eT>::colptr(0)) 
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+subview_col<eT>::subview_col(const Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows)
+  : subview<eT>(in_m, in_row1, in_col, in_n_rows, 1)
+  , colmem(subview<eT>::colptr(0)) 
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_col<eT>::operator=(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview<eT>::operator=(X);
+  
+  access::rw(colmem) = subview<eT>::colptr(0);
+  
+  arma_debug_check( (subview<eT>::n_cols > 1), "subview_col(): incompatible dimensions" );
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_col<eT>::operator=(const subview_col<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview<eT>::operator=(X); // interprets 'subview_col' as 'subview'
+  
+  access::rw(colmem) = subview<eT>::colptr(0);
+  
+  arma_debug_check( (subview<eT>::n_cols > 1), "subview_col(): incompatible dimensions" );
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview_col<eT>::operator=(const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview<eT>::operator=(X);
+  
+  access::rw(colmem) = subview<eT>::colptr(0);
+
+  arma_debug_check( (subview<eT>::n_cols > 1), "subview_col(): incompatible dimensions" );
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<subview_col<eT>,op_htrans>
+subview_col<eT>::t() const
+  {
+  return Op<subview_col<eT>,op_htrans>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<subview_col<eT>,op_htrans>
+subview_col<eT>::ht() const
+  {
+  return Op<subview_col<eT>,op_htrans>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<subview_col<eT>,op_strans>
+subview_col<eT>::st() const
+  {
+  return Op<subview_col<eT>,op_strans>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+subview_col<eT>::at_alt(const uword ii) const
+  {
+  const eT* colmem_aligned = colmem;
+  memory::mark_as_aligned(colmem_aligned);
+  
+  return colmem_aligned[ii];
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT&
+subview_col<eT>::operator[](const uword ii)
+  {
+  return access::rw( colmem[ii] );
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT
+subview_col<eT>::operator[](const uword ii) const
+  {
+  return colmem[ii];
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+subview_col<eT>::operator()(const uword ii)
+  {
+  arma_debug_check( (ii >= subview<eT>::n_elem), "subview::operator(): index out of bounds");
+    
+  return access::rw( colmem[ii] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_col<eT>::operator()(const uword ii) const
+  {
+  arma_debug_check( (ii >= subview<eT>::n_elem), "subview::operator(): index out of bounds");
+  
+  return colmem[ii];
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+subview_col<eT>::operator()(const uword in_row, const uword in_col)
+  {
+  arma_debug_check( ((in_row >= subview<eT>::n_rows) || (in_col > 0)), "subview::operator(): index out of bounds");
+  
+  return access::rw( colmem[in_row] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_col<eT>::operator()(const uword in_row, const uword in_col) const
+  {
+  arma_debug_check( ((in_row >= subview<eT>::n_rows) || (in_col > 0)), "subview::operator(): index out of bounds");
+  
+  return colmem[in_row];
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+subview_col<eT>::at(const uword in_row, const uword)
+  {
+  return access::rw( colmem[in_row] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_col<eT>::at(const uword in_row, const uword) const
+  {
+  return colmem[in_row];
+  }
+
+
+
+template<typename eT>
+arma_inline
+eT*
+subview_col<eT>::colptr(const uword)
+  {
+  return const_cast<eT*>(colmem);
+  }
+  
+  
+template<typename eT>
+arma_inline
+const eT*
+subview_col<eT>::colptr(const uword) const
+  {
+  return colmem;
+  }
+
+
+template<typename eT>
+inline
+subview_col<eT>
+subview_col<eT>::rows(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= subview<eT>::n_rows) ), "subview_col::rows(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  const uword base_row1 = this->aux_row1 + in_row1;
+  
+  return subview_col<eT>(this->m, this->aux_col1, base_row1, subview_n_rows);
+  }
+
+
+
+template<typename eT>
+inline
+const subview_col<eT>
+subview_col<eT>::rows(const uword in_row1, const uword in_row2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= subview<eT>::n_rows) ), "subview_col::rows(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  const uword base_row1 = this->aux_row1 + in_row1;
+  
+  return subview_col<eT>(this->m, this->aux_col1, base_row1, subview_n_rows);
+  }
+
+
+
+template<typename eT>
+inline
+subview_col<eT>
+subview_col<eT>::subvec(const uword in_row1, const uword in_row2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= subview<eT>::n_rows) ), "subview_col::subvec(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  const uword base_row1 = this->aux_row1 + in_row1;
+  
+  return subview_col<eT>(this->m, this->aux_col1, base_row1, subview_n_rows);
+  }
+
+
+
+template<typename eT>
+inline
+const subview_col<eT>
+subview_col<eT>::subvec(const uword in_row1, const uword in_row2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= subview<eT>::n_rows) ), "subview_col::subvec(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_rows = in_row2 - in_row1 + 1;
+  
+  const uword base_row1 = this->aux_row1 + in_row1;
+  
+  return subview_col<eT>(this->m, this->aux_col1, base_row1, subview_n_rows);
+  }
+
+
+
+//
+//
+//
+
+
+
+template<typename eT>
+inline
+subview_row<eT>::subview_row(const Mat<eT>& in_m, const uword in_row)
+  : subview<eT>(in_m, in_row, 0, 1, in_m.n_cols)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+subview_row<eT>::subview_row(const Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols)
+  : subview<eT>(in_m, in_row, in_col1, 1, in_n_cols)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_row<eT>::operator=(const subview<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview<eT>::operator=(X);
+  arma_debug_check( (subview<eT>::n_rows > 1), "subview_row(): incompatible dimensions" );
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_row<eT>::operator=(const subview_row<eT>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview<eT>::operator=(X); // interprets 'subview_row' as 'subview'
+  arma_debug_check( (subview<eT>::n_rows > 1), "subview_row(): incompatible dimensions" );
+  }
+
+
+
+template<typename eT>
+template<typename T1>
+inline
+void
+subview_row<eT>::operator=(const Base<eT,T1>& X)
+  {
+  arma_extra_debug_sigprint();
+  
+  subview<eT>::operator=(X);
+  arma_debug_check( (subview<eT>::n_rows > 1), "subview_row(): incompatible dimensions" );
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<subview_row<eT>,op_htrans>
+subview_row<eT>::t() const
+  {
+  return Op<subview_row<eT>,op_htrans>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<subview_row<eT>,op_htrans>
+subview_row<eT>::ht() const
+  {
+  return Op<subview_row<eT>,op_htrans>(*this);
+  }
+
+
+
+template<typename eT>
+arma_inline
+const Op<subview_row<eT>,op_strans>
+subview_row<eT>::st() const
+  {
+  return Op<subview_row<eT>,op_strans>(*this);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row<eT>::at_alt(const uword ii) const
+  {
+  const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
+  
+  return subview<eT>::m.mem[index];
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+subview_row<eT>::operator[](const uword ii)
+  {
+  const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
+  
+  return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row<eT>::operator[](const uword ii) const
+  {
+  const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
+  
+  return subview<eT>::m.mem[index];
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+subview_row<eT>::operator()(const uword ii)
+  {
+  arma_debug_check( (ii >= subview<eT>::n_elem), "subview::operator(): index out of bounds");
+    
+  const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
+  
+  return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row<eT>::operator()(const uword ii) const
+  {
+  arma_debug_check( (ii >= subview<eT>::n_elem), "subview::operator(): index out of bounds");
+  
+  const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
+  
+  return subview<eT>::m.mem[index];
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+subview_row<eT>::operator()(const uword in_row, const uword in_col)
+  {
+  arma_debug_check( ((in_row > 0) || (in_col >= subview<eT>::n_cols)), "subview::operator(): index out of bounds");
+  
+  const uword index = (in_col + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
+  
+  return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row<eT>::operator()(const uword in_row, const uword in_col) const
+  {
+  arma_debug_check( ((in_row > 0) || (in_col >= subview<eT>::n_cols)), "subview::operator(): index out of bounds");
+  
+  const uword index = (in_col + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
+  
+  return subview<eT>::m.mem[index];
+  }
+
+
+
+template<typename eT>
+inline
+eT&
+subview_row<eT>::at(const uword, const uword in_col)
+  {
+  const uword index = (in_col + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
+  
+  return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row<eT>::at(const uword, const uword in_col) const
+  {
+  const uword index = (in_col + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
+  
+  return subview<eT>::m.mem[index];
+  }
+
+
+
+template<typename eT>
+inline
+subview_row<eT>
+subview_row<eT>::cols(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= subview<eT>::n_cols) ), "subview_row::cols(): indices out of bounds or incorrectly used" );
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  const uword base_col1 = this->aux_col1 + in_col1;
+  
+  return subview_row<eT>(this->m, this->aux_row1, base_col1, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+const subview_row<eT>
+subview_row<eT>::cols(const uword in_col1, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= subview<eT>::n_cols) ), "subview_row::cols(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  const uword base_col1 = this->aux_col1 + in_col1;
+  
+  return subview_row<eT>(this->m, this->aux_row1, base_col1, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+subview_row<eT>
+subview_row<eT>::subvec(const uword in_col1, const uword in_col2)
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= subview<eT>::n_cols) ), "subview_row::subvec(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  const uword base_col1 = this->aux_col1 + in_col1;
+  
+  return subview_row<eT>(this->m, this->aux_row1, base_col1, subview_n_cols);
+  }
+
+
+
+template<typename eT>
+inline
+const subview_row<eT>
+subview_row<eT>::subvec(const uword in_col1, const uword in_col2) const
+  {
+  arma_extra_debug_sigprint();
+  
+  arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= subview<eT>::n_cols) ), "subview_row::subvec(): indices out of bounds or incorrectly used");
+  
+  const uword subview_n_cols = in_col2 - in_col1 + 1;
+  
+  const uword base_col1 = this->aux_col1 + in_col1;
+  
+  return subview_row<eT>(this->m, this->aux_row1, base_col1, subview_n_cols);
+  }
+
+
+
+//
+//
+//
+
+
+
+template<typename eT>
+inline
+subview_row_strans<eT>::subview_row_strans(const subview_row<eT>& in_sv_row)
+  : sv_row(in_sv_row       )
+  , n_rows(in_sv_row.n_cols)
+  , n_elem(in_sv_row.n_elem)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_row_strans<eT>::extract(Mat<eT>& out) const
+  {
+  arma_extra_debug_sigprint();
+  
+  // NOTE: this function assumes that matrix 'out' has already been set to the correct size
+  
+  const Mat<eT>& X = sv_row.m;
+  
+  eT* out_mem = out.memptr();
+  
+  const uword row           = sv_row.aux_row1;
+  const uword start_col     = sv_row.aux_col1;
+  const uword sv_row_n_cols = sv_row.n_cols;
+  
+  uword ii,jj;
+  
+  for(ii=0, jj=1; jj < sv_row_n_cols; ii+=2, jj+=2)
+    {
+    const eT tmp1 = X.at(row, start_col+ii);
+    const eT tmp2 = X.at(row, start_col+jj);
+    
+    out_mem[ii] = tmp1;
+    out_mem[jj] = tmp2;
+    }
+  
+  if(ii < sv_row_n_cols)
+    {
+    out_mem[ii] = X.at(row, start_col+ii);
+    }
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row_strans<eT>::at_alt(const uword ii) const
+  {
+  return sv_row[ii];
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row_strans<eT>::operator[](const uword ii) const
+  {
+  return sv_row[ii];
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row_strans<eT>::operator()(const uword ii) const
+  {
+  return sv_row(ii);
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row_strans<eT>::operator()(const uword in_row, const uword in_col) const
+  {
+  return sv_row(in_col, in_row);  // deliberately swapped
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row_strans<eT>::at(const uword in_row, const uword) const
+  {
+  return sv_row.at(0, in_row);  // deliberately swapped
+  }
+
+
+
+//
+//
+//
+
+
+
+template<typename eT>
+inline
+subview_row_htrans<eT>::subview_row_htrans(const subview_row<eT>& in_sv_row)
+  : sv_row(in_sv_row       )
+  , n_rows(in_sv_row.n_cols)
+  , n_elem(in_sv_row.n_elem)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+void
+subview_row_htrans<eT>::extract(Mat<eT>& out) const
+  {
+  arma_extra_debug_sigprint();
+  
+  // NOTE: this function assumes that matrix 'out' has already been set to the correct size
+  
+  const Mat<eT>& X = sv_row.m;
+  
+  eT* out_mem = out.memptr();
+  
+  const uword row           = sv_row.aux_row1;
+  const uword start_col     = sv_row.aux_col1;
+  const uword sv_row_n_cols = sv_row.n_cols;
+  
+  for(uword ii=0; ii < sv_row_n_cols; ++ii)
+    {
+    out_mem[ii] = access::alt_conj( X.at(row, start_col+ii) );
+    }
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row_htrans<eT>::at_alt(const uword ii) const
+  {
+  return access::alt_conj( sv_row[ii] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row_htrans<eT>::operator[](const uword ii) const
+  {
+  return access::alt_conj( sv_row[ii] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row_htrans<eT>::operator()(const uword ii) const
+  {
+  return access::alt_conj( sv_row(ii) );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row_htrans<eT>::operator()(const uword in_row, const uword in_col) const
+  {
+  return access::alt_conj( sv_row(in_col, in_row) );  // deliberately swapped
+  }
+
+
+
+template<typename eT>
+inline
+eT
+subview_row_htrans<eT>::at(const uword in_row, const uword) const
+  {
+  return access::alt_conj( sv_row.at(0, in_row) );  // deliberately swapped
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/traits.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,1203 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup traits
+//! @{
+
+
+template<typename T1>
+struct get_pod_type
+  { typedef T1 result; };
+
+template<typename T2>
+struct get_pod_type< std::complex<T2> >
+  { typedef T2 result; };
+
+
+
+template<typename T>
+struct is_Mat_fixed_only
+  {
+  typedef char yes[1];
+  typedef char no[2];
+  
+  template<typename X> static yes& check(typename X::Mat_fixed_type*);
+  template<typename>   static no&  check(...);
+  
+  static const bool value = ( sizeof(check<T>(0)) == sizeof(yes) );
+  };
+
+
+
+template<typename T>
+struct is_Row_fixed_only
+  {
+  typedef char yes[1];
+  typedef char no[2];
+  
+  template<typename X> static yes& check(typename X::Row_fixed_type*);
+  template<typename>   static no&  check(...);
+  
+  static const bool value = ( sizeof(check<T>(0)) == sizeof(yes) );
+  };
+
+
+
+template<typename T>
+struct is_Col_fixed_only
+  {
+  typedef char yes[1];
+  typedef char no[2];
+  
+  template<typename X> static yes& check(typename X::Col_fixed_type*);
+  template<typename>   static no&  check(...);
+  
+  static const bool value = ( sizeof(check<T>(0)) == sizeof(yes) );
+  };
+
+
+
+template<typename T>
+struct is_Mat_fixed
+  { static const bool value = ( is_Mat_fixed_only<T>::value || is_Row_fixed_only<T>::value || is_Col_fixed_only<T>::value ); };
+
+
+
+template<typename T>
+struct is_Mat_only
+  { static const bool value = is_Mat_fixed_only<T>::value; };
+
+template<typename eT>
+struct is_Mat_only< Mat<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_Mat_only< const Mat<eT> >
+  { static const bool value = true; };
+
+
+
+template<typename T>
+struct is_Mat
+  { static const bool value = ( is_Mat_fixed_only<T>::value || is_Row_fixed_only<T>::value || is_Col_fixed_only<T>::value ); };
+
+template<typename eT>
+struct is_Mat< Mat<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_Mat< const Mat<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_Mat< Row<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_Mat< const Row<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_Mat< Col<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_Mat< const Col<eT> >
+  { static const bool value = true; };
+
+
+
+template<typename T>
+struct is_Row
+  { static const bool value = is_Row_fixed_only<T>::value; };
+
+template<typename eT>
+struct is_Row< Row<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_Row< const Row<eT> >
+  { static const bool value = true; };
+
+
+
+template<typename T>
+struct is_Col
+  { static const bool value = is_Col_fixed_only<T>::value; };
+
+template<typename eT>
+struct is_Col< Col<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_Col< const Col<eT> >
+  { static const bool value = true; };
+
+
+
+template<typename T>
+struct is_diagview
+  { static const bool value = false; };
+
+template<typename eT>
+struct is_diagview< diagview<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_diagview< const diagview<eT> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_subview
+  { static const bool value = false; };
+
+template<typename eT>
+struct is_subview< subview<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_subview< const subview<eT> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_subview_row
+  { static const bool value = false; };
+
+template<typename eT>
+struct is_subview_row< subview_row<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_subview_row< const subview_row<eT> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_subview_col
+  { static const bool value = false; };
+
+template<typename eT>
+struct is_subview_col< subview_col<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_subview_col< const subview_col<eT> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_subview_elem1
+  { static const bool value = false; };
+
+template<typename eT, typename T1>
+struct is_subview_elem1< subview_elem1<eT, T1> >
+  { static const bool value = true; };
+
+template<typename eT, typename T1>
+struct is_subview_elem1< const subview_elem1<eT, T1> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_subview_elem2
+  { static const bool value = false; };
+
+template<typename eT, typename T1, typename T2>
+struct is_subview_elem2< subview_elem2<eT, T1, T2> >
+  { static const bool value = true; };
+
+template<typename eT, typename T1, typename T2>
+struct is_subview_elem2< const subview_elem2<eT, T1, T2> >
+  { static const bool value = true; };
+
+
+
+//
+//
+//
+
+
+
+template<typename T>
+struct is_Cube
+  { static const bool value = false; };
+
+template<typename eT>
+struct is_Cube< Cube<eT> >
+  { static const bool value = true; };
+
+template<typename T>
+struct is_subview_cube
+  { static const bool value = false; };
+
+template<typename eT>
+struct is_subview_cube< subview_cube<eT> >
+  { static const bool value = true; };
+
+
+
+//
+//
+//
+
+
+template<typename T>
+struct is_Gen
+  { static const bool value = false; };
+ 
+template<typename T1, typename gen_type>
+struct is_Gen< Gen<T1,gen_type> >
+  { static const bool value = true; };
+ 
+template<typename T1, typename gen_type>
+struct is_Gen< const Gen<T1,gen_type> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_Op
+  { static const bool value = false; };
+ 
+template<typename T1, typename op_type>
+struct is_Op< Op<T1,op_type> >
+  { static const bool value = true; };
+ 
+template<typename T1, typename op_type>
+struct is_Op< const Op<T1,op_type> >
+  { static const bool value = true; };
+
+template<typename T>
+struct is_eOp
+  { static const bool value = false; };
+ 
+template<typename T1, typename eop_type>
+struct is_eOp< eOp<T1,eop_type> >
+  { static const bool value = true; };
+ 
+template<typename T1, typename eop_type>
+struct is_eOp< const eOp<T1,eop_type> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_mtOp
+  { static const bool value = false; };
+ 
+template<typename eT, typename T1, typename op_type>
+struct is_mtOp< mtOp<eT, T1, op_type> >
+  { static const bool value = true; };
+ 
+template<typename eT, typename T1, typename op_type>
+struct is_mtOp< const mtOp<eT, T1, op_type> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_Glue
+  { static const bool value = false; };
+ 
+template<typename T1, typename T2, typename glue_type>
+struct is_Glue< Glue<T1,T2,glue_type> >
+  { static const bool value = true; };
+
+template<typename T1, typename T2, typename glue_type>
+struct is_Glue< const Glue<T1,T2,glue_type> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_eGlue
+  { static const bool value = false; };
+ 
+template<typename T1, typename T2, typename eglue_type>
+struct is_eGlue< eGlue<T1,T2,eglue_type> >
+  { static const bool value = true; };
+
+template<typename T1, typename T2, typename eglue_type>
+struct is_eGlue< const eGlue<T1,T2,eglue_type> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_mtGlue
+  { static const bool value = false; };
+ 
+template<typename eT, typename T1, typename T2, typename glue_type>
+struct is_mtGlue< mtGlue<eT, T1, T2, glue_type> >
+  { static const bool value = true; };
+
+template<typename eT, typename T1, typename T2, typename glue_type>
+struct is_mtGlue< const mtGlue<eT, T1, T2, glue_type> >
+  { static const bool value = true; };
+
+
+//
+//
+
+
+template<typename T>
+struct is_glue_times
+  { static const bool value = false; };
+
+template<typename T1, typename T2>
+struct is_glue_times< Glue<T1,T2,glue_times> >
+  { static const bool value = true; };
+
+template<typename T1, typename T2>
+struct is_glue_times< const Glue<T1,T2,glue_times> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_glue_times_diag
+  { static const bool value = false; };
+
+template<typename T1, typename T2>
+struct is_glue_times_diag< Glue<T1,T2,glue_times_diag> >
+  { static const bool value = true; };
+
+template<typename T1, typename T2>
+struct is_glue_times_diag< const Glue<T1,T2,glue_times_diag> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_op_diagmat
+  { static const bool value = false; };
+ 
+template<typename T1>
+struct is_op_diagmat< Op<T1,op_diagmat> >
+  { static const bool value = true; };
+
+template<typename T1>
+struct is_op_diagmat< const Op<T1,op_diagmat> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_op_htrans2
+  { static const bool value = false; };
+ 
+template<typename T1>
+struct is_op_htrans2< Op<T1,op_htrans2> >
+  { static const bool value = true; };
+
+template<typename T1>
+struct is_op_htrans2< const Op<T1,op_htrans2> >
+  { static const bool value = true; };
+
+
+//
+//
+
+
+template<typename T>
+struct is_GenCube
+  { static const bool value = false; };
+ 
+template<typename eT, typename gen_type>
+struct is_GenCube< GenCube<eT,gen_type> >
+  { static const bool value = true; };
+ 
+
+template<typename T>
+struct is_OpCube
+  { static const bool value = false; };
+ 
+template<typename T1, typename op_type>
+struct is_OpCube< OpCube<T1,op_type> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_eOpCube
+  { static const bool value = false; };
+ 
+template<typename T1, typename eop_type>
+struct is_eOpCube< eOpCube<T1,eop_type> >
+  { static const bool value = true; };
+ 
+
+template<typename T>
+struct is_mtOpCube
+  { static const bool value = false; };
+ 
+template<typename eT, typename T1, typename op_type>
+struct is_mtOpCube< mtOpCube<eT, T1, op_type> >
+  { static const bool value = true; };
+ 
+
+template<typename T>
+struct is_GlueCube
+  { static const bool value = false; };
+ 
+template<typename T1, typename T2, typename glue_type>
+struct is_GlueCube< GlueCube<T1,T2,glue_type> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_eGlueCube
+  { static const bool value = false; };
+ 
+template<typename T1, typename T2, typename eglue_type>
+struct is_eGlueCube< eGlueCube<T1,T2,eglue_type> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_mtGlueCube
+  { static const bool value = false; };
+ 
+template<typename eT, typename T1, typename T2, typename glue_type>
+struct is_mtGlueCube< mtGlueCube<eT, T1, T2, glue_type> >
+  { static const bool value = true; };
+
+
+//
+//
+//
+
+
+template<typename T>
+struct is_op_rel
+  { static const bool value = false; };
+
+template<typename out_eT, typename T1>
+struct is_op_rel< mtOp<out_eT, T1, op_rel_lt_pre> >
+  { static const bool value = true; };
+
+template<typename out_eT, typename T1>
+struct is_op_rel< mtOp<out_eT, T1, op_rel_lt_post> >
+  { static const bool value = true; };
+
+template<typename out_eT, typename T1>
+struct is_op_rel< mtOp<out_eT, T1, op_rel_gt_pre> >
+  { static const bool value = true; };
+
+template<typename out_eT, typename T1>
+struct is_op_rel< mtOp<out_eT, T1, op_rel_gt_post> >
+  { static const bool value = true; };
+
+template<typename out_eT, typename T1>
+struct is_op_rel< mtOp<out_eT, T1, op_rel_lteq_pre> >
+  { static const bool value = true; };
+
+template<typename out_eT, typename T1>
+struct is_op_rel< mtOp<out_eT, T1, op_rel_lteq_post> >
+  { static const bool value = true; };
+
+template<typename out_eT, typename T1>
+struct is_op_rel< mtOp<out_eT, T1, op_rel_gteq_pre> >
+  { static const bool value = true; };
+
+template<typename out_eT, typename T1>
+struct is_op_rel< mtOp<out_eT, T1, op_rel_gteq_post> >
+  { static const bool value = true; };
+
+template<typename out_eT, typename T1>
+struct is_op_rel< mtOp<out_eT, T1, op_rel_eq> >
+  { static const bool value = true; };
+
+template<typename out_eT, typename T1>
+struct is_op_rel< mtOp<out_eT, T1, op_rel_noteq> >
+  { static const bool value = true; };
+
+
+
+//
+//
+//
+
+
+
+template<typename T>
+struct is_basevec
+  { static const bool value = ( is_Row_fixed_only<T>::value || is_Col_fixed_only<T>::value ); };
+
+template<typename eT>
+struct is_basevec< Row<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_basevec< const Row<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_basevec< Col<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_basevec< const Col<eT> >
+  { static const bool value = true; };
+  
+template<typename eT>
+struct is_basevec< subview_row<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_basevec< const subview_row<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_basevec< subview_col<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_basevec< const subview_col<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_basevec< diagview<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_basevec< const diagview<eT> >
+  { static const bool value = true; };
+  
+template<typename eT, typename T1>
+struct is_basevec< subview_elem1<eT,T1> >
+  { static const bool value = true; };
+
+template<typename eT, typename T1>
+struct is_basevec< const subview_elem1<eT,T1> >
+  { static const bool value = true; };
+
+
+//
+//
+//
+
+
+
+template<typename T1>
+struct is_arma_type
+  {
+  static const bool value
+  =  is_Mat<T1>::value
+  || is_Gen<T1>::value
+  || is_Op<T1>::value
+  || is_Glue<T1>::value
+  || is_eOp<T1>::value
+  || is_eGlue<T1>::value
+  || is_mtOp<T1>::value
+  || is_mtGlue<T1>::value
+  || is_diagview<T1>::value
+  || is_subview<T1>::value
+  || is_subview_row<T1>::value
+  || is_subview_col<T1>::value
+  || is_subview_elem1<T1>::value
+  || is_subview_elem2<T1>::value
+  ;
+  };
+
+
+
+template<typename T1>
+struct is_arma_cube_type
+  {
+  static const bool value
+  =  is_Cube<T1>::value
+  || is_GenCube<T1>::value
+  || is_OpCube<T1>::value
+  || is_eOpCube<T1>::value
+  || is_mtOpCube<T1>::value
+  || is_GlueCube<T1>::value
+  || is_eGlueCube<T1>::value
+  || is_mtGlueCube<T1>::value
+  || is_subview_cube<T1>::value
+  ;
+  };
+
+
+
+//
+//
+//
+
+
+
+template<typename T>
+struct is_SpMat
+  { static const bool value = false; };
+
+template<typename eT>
+struct is_SpMat< SpMat<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_SpMat< SpCol<eT> >
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_SpMat< SpRow<eT> >
+  { static const bool value = true; };
+
+
+
+template<typename T>
+struct is_SpRow
+  { static const bool value = false; };
+
+template<typename eT>
+struct is_SpRow< SpRow<eT> >
+  { static const bool value = true; };
+
+
+
+template<typename T>
+struct is_SpCol
+  { static const bool value = false; };
+
+template<typename eT>
+struct is_SpCol< SpCol<eT> >
+  { static const bool value = true; };
+
+
+
+template<typename T>
+struct is_SpSubview
+  { static const bool value = false; };
+
+template<typename eT>
+struct is_SpSubview< SpSubview<eT> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_SpOp
+  { static const bool value = false; };
+ 
+template<typename T1, typename op_type>
+struct is_SpOp< SpOp<T1,op_type> >
+  { static const bool value = true; };
+
+
+template<typename T>
+struct is_SpGlue
+  { static const bool value = false; };
+ 
+template<typename T1, typename T2, typename glue_type>
+struct is_SpGlue< SpGlue<T1,T2,glue_type> >
+  { static const bool value = true; };
+ 
+
+template<typename T>
+struct is_mtSpOp
+  { static const bool value = false; };
+ 
+template<typename eT, typename T1, typename spop_type>
+struct is_mtSpOp< mtSpOp<eT, T1, spop_type> >
+  { static const bool value = true; };
+ 
+
+
+template<typename T1>
+struct is_arma_sparse_type
+  {
+  static const bool value
+  =  is_SpMat<T1>::value
+  || is_SpSubview<T1>::value
+  || is_SpOp<T1>::value
+  || is_SpGlue<T1>::value
+  || is_mtSpOp<T1>::value
+  ;
+  };
+
+
+
+//
+//
+//
+
+
+template<typename T1, typename T2>
+struct is_same_type
+  { static const bool value = false; };
+
+
+template<typename T1>
+struct is_same_type<T1,T1>
+  { static const bool value = true; };
+
+
+
+//
+//
+//
+
+
+template<typename T1>
+struct is_u8
+  { static const bool value = false; };
+
+template<>
+struct is_u8<u8>
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_s8
+  { static const bool value = false; };
+
+template<>
+struct is_s8<s8>
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_u16
+  { static const bool value = false; };
+
+template<>
+struct is_u16<u16>
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_s16
+  { static const bool value = false; };
+
+template<>
+struct is_s16<s16>
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_u32
+  { static const bool value = false; };
+
+template<>
+struct is_u32<u32>
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_s32
+  { static const bool value = false; };
+
+template<>
+struct is_s32<s32>
+  { static const bool value = true; };
+
+
+
+#if defined(ARMA_USE_U64S64)
+  template<typename T1>
+  struct is_u64
+    { static const bool value = false; };
+
+  template<>
+  struct is_u64<u64>
+    { static const bool value = true; };
+  
+  
+  template<typename T1>
+  struct is_s64
+    { static const bool value = false; };
+
+  template<>
+  struct is_s64<s64>
+    { static const bool value = true; };
+#endif
+
+
+
+template<typename T1>
+struct is_ulng_t
+  { static const bool value = false; };
+
+template<>
+struct is_ulng_t<ulng_t>
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_slng_t
+  { static const bool value = false; };
+
+template<>
+struct is_slng_t<slng_t>
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_ulng_t_32
+  { static const bool value = false; };
+
+template<>
+struct is_ulng_t_32<ulng_t>
+  { static const bool value = (sizeof(ulng_t) == 4); };
+
+
+
+template<typename T1>
+struct is_slng_t_32
+  { static const bool value = false; };
+
+template<>
+struct is_slng_t_32<slng_t>
+  { static const bool value = (sizeof(slng_t) == 4); };
+
+
+
+template<typename T1>
+struct is_ulng_t_64
+  { static const bool value = false; };
+
+template<>
+struct is_ulng_t_64<ulng_t>
+  { static const bool value = (sizeof(ulng_t) == 8); };
+
+
+
+template<typename T1>
+struct is_slng_t_64
+  { static const bool value = false; };
+
+template<>
+struct is_slng_t_64<slng_t>
+  { static const bool value = (sizeof(slng_t) == 8); };
+
+
+
+template<typename T1>
+struct is_uword
+  { static const bool value = false; };
+
+template<>
+struct is_uword<uword>
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_sword
+  { static const bool value = false; };
+
+template<>
+struct is_sword<sword>
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_float
+  { static const bool value = false; };
+
+template<>
+struct is_float<float>
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_double
+  { static const bool value = false; };
+
+template<>
+struct is_double<double>
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_real
+  { static const bool value = false; };
+
+template<>
+struct is_real<float>
+  { static const bool value = true; };
+  
+template<>
+struct is_real<double>
+  { static const bool value = true; };
+
+
+
+
+template<typename T1>
+struct is_not_complex
+  { static const bool value = true; };
+
+template<typename eT>
+struct is_not_complex< std::complex<eT> >
+  { static const bool value = false; };
+
+
+
+template<typename T1>
+struct is_complex
+  { static const bool value = false; };
+
+// template<>
+template<typename eT>
+struct is_complex< std::complex<eT> >
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_complex_float
+  { static const bool value = false; };
+
+template<>
+struct is_complex_float< std::complex<float> >
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_complex_double
+  { static const bool value = false; };
+
+template<>
+struct is_complex_double< std::complex<double> >
+  { static const bool value = true; };
+
+
+
+template<typename T1>
+struct is_complex_strict
+  { static const bool value = false; };
+
+template<>
+struct is_complex_strict< std::complex<float> >
+  { static const bool value = true; };
+
+template<>
+struct is_complex_strict< std::complex<double> >
+  { static const bool value = true; };
+
+
+
+//! check for a weird implementation of the std::complex class
+template<typename T1>
+struct is_supported_complex
+  { static const bool value = false; };
+
+//template<>
+template<typename eT>
+struct is_supported_complex< std::complex<eT> >
+  { static const bool value = ( sizeof(std::complex<eT>) == 2*sizeof(eT) ); };
+
+
+
+template<typename T1>
+struct is_supported_complex_float
+  { static const bool value = false; };
+
+template<>
+struct is_supported_complex_float< std::complex<float> >
+  { static const bool value = ( sizeof(std::complex<float>) == 2*sizeof(float) ); };
+
+
+
+template<typename T1>
+struct is_supported_complex_double
+  { static const bool value = false; };
+
+template<>
+struct is_supported_complex_double< std::complex<double> >
+  { static const bool value = ( sizeof(std::complex<double>) == 2*sizeof(double) ); };
+
+
+
+template<typename T1>
+struct is_supported_elem_type
+  {
+  static const bool value = \
+    is_u8<T1>::value ||
+    is_s8<T1>::value ||
+    is_u16<T1>::value ||
+    is_s16<T1>::value ||
+    is_u32<T1>::value ||
+    is_s32<T1>::value ||
+#if defined(ARMA_USE_U64S64)
+    is_u64<T1>::value ||
+    is_s64<T1>::value ||
+#endif
+#if defined(ARMA_ALLOW_LONG)
+    is_ulng_t<T1>::value ||
+    is_slng_t<T1>::value ||
+#endif
+    is_float<T1>::value ||
+    is_double<T1>::value ||
+    is_supported_complex_float<T1>::value ||
+    is_supported_complex_double<T1>::value;
+  };
+
+
+
+template<typename T1>
+struct is_supported_blas_type
+  {
+  static const bool value = \
+    is_float<T1>::value ||
+    is_double<T1>::value ||
+    is_supported_complex_float<T1>::value ||
+    is_supported_complex_double<T1>::value;
+  };
+
+
+
+template<typename T>
+struct is_signed
+  {
+  static const bool value = true;
+  };
+
+
+template<> struct is_signed<u8>     { static const bool value = false; };
+template<> struct is_signed<u16>    { static const bool value = false; };
+template<> struct is_signed<u32>    { static const bool value = false; };
+#if defined(ARMA_USE_U64S64)
+template<> struct is_signed<u64>    { static const bool value = false; };
+#endif
+#if defined(ARMA_ALLOW_LONG)
+template<> struct is_signed<ulng_t> { static const bool value = false; };
+#endif
+
+
+template<typename T>
+struct is_non_integral
+  {
+  static const bool value = false;
+  };
+
+
+template<> struct is_non_integral<              float   > { static const bool value = true; };
+template<> struct is_non_integral<              double  > { static const bool value = true; };
+template<> struct is_non_integral< std::complex<float>  > { static const bool value = true; };
+template<> struct is_non_integral< std::complex<double> > { static const bool value = true; };
+
+
+
+
+//
+
+class arma_junk_class;
+
+template<typename T1, typename T2>
+struct force_different_type
+  {
+  typedef T1 T1_result;
+  typedef T2 T2_result;
+  };
+  
+
+template<typename T1>
+struct force_different_type<T1,T1>
+  {
+  typedef T1              T1_result;
+  typedef arma_junk_class T2_result;
+  };
+  
+  
+
+//
+
+
+template<typename T1>
+struct resolves_to_vector_default { static const bool value = false;                    };
+
+template<typename T1>
+struct resolves_to_vector_test    { static const bool value = T1::is_col || T1::is_row; };
+
+
+template<typename T1, bool condition>
+struct resolves_to_vector_redirect {};
+
+template<typename T1>
+struct resolves_to_vector_redirect<T1, false> { typedef resolves_to_vector_default<T1> result; };
+
+template<typename T1>
+struct resolves_to_vector_redirect<T1, true>  { typedef resolves_to_vector_test<T1>    result; };
+
+
+template<typename T1>
+struct resolves_to_vector : public resolves_to_vector_redirect<T1, is_arma_type<T1>::value>::result {};
+
+template<typename T1>
+struct resolves_to_sparse_vector : public resolves_to_vector_redirect<T1, is_arma_sparse_type<T1>::value>::result {};
+
+
+
+template<typename glue_type> struct is_glue_mixed_times                   { static const bool value = false; };
+template<>                   struct is_glue_mixed_times<glue_mixed_times> { static const bool value = true;  };
+
+
+
+template<typename glue_type> struct is_glue_mixed_elem { static const bool value = false; };
+
+template<>                   struct is_glue_mixed_elem<glue_mixed_plus>  { static const bool value = true;  };
+template<>                   struct is_glue_mixed_elem<glue_mixed_minus> { static const bool value = true;  };
+template<>                   struct is_glue_mixed_elem<glue_mixed_div>   { static const bool value = true;  };
+template<>                   struct is_glue_mixed_elem<glue_mixed_schur> { static const bool value = true;  };
+
+template<>                   struct is_glue_mixed_elem<glue_rel_lt>    { static const bool value = true; };
+template<>                   struct is_glue_mixed_elem<glue_rel_gt>    { static const bool value = true; };
+template<>                   struct is_glue_mixed_elem<glue_rel_lteq>  { static const bool value = true; };
+template<>                   struct is_glue_mixed_elem<glue_rel_gteq>  { static const bool value = true; };
+template<>                   struct is_glue_mixed_elem<glue_rel_eq>    { static const bool value = true; };
+template<>                   struct is_glue_mixed_elem<glue_rel_noteq> { static const bool value = true; };
+
+
+
+template<typename op_type> struct is_op_mixed_elem { static const bool value = false; };
+
+template<>                 struct is_op_mixed_elem<op_cx_scalar_times>      { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_cx_scalar_plus>       { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_cx_scalar_minus_pre>  { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_cx_scalar_minus_post> { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_cx_scalar_div_pre>    { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_cx_scalar_div_post>   { static const bool value = true; };
+
+template<>                 struct is_op_mixed_elem<op_rel_lt_pre>    { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_rel_lt_post>   { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_rel_gt_pre>    { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_rel_gt_post>   { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_rel_lteq_pre>  { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_rel_lteq_post> { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_rel_gteq_pre>  { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_rel_gteq_post> { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_rel_eq>        { static const bool value = true; };
+template<>                 struct is_op_mixed_elem<op_rel_noteq>     { static const bool value = true; };
+
+
+
+template<typename spop_type> struct is_spop_elem                    { static const bool value = false; };
+template<>                   struct is_spop_elem<spop_scalar_times> { static const bool value = true;  };
+
+
+template<typename spglue_type> struct is_spglue_elem                { static const bool value = false; };
+template<>                     struct is_spglue_elem<spglue_plus>   { static const bool value = true;  };
+template<>                     struct is_spglue_elem<spglue_plus2>  { static const bool value = true;  };
+template<>                     struct is_spglue_elem<spglue_minus>  { static const bool value = true;  };
+template<>                     struct is_spglue_elem<spglue_minus2> { static const bool value = true;  };
+
+
+template<typename spglue_type> struct is_spglue_times               { static const bool value = false; };
+template<>                     struct is_spglue_times<spglue_times> { static const bool value = true;  };
+
+
+template<typename spglue_type> struct is_spglue_times2               { static const bool value = false; };
+template<>                     struct is_spglue_times<spglue_times2> { static const bool value = true;  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/typedef.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,237 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup typedef
+//! @{
+
+
+#if   UCHAR_MAX >= 0xff
+  typedef unsigned char    u8;
+  typedef          char    s8;
+#elif defined(UINT8_MAX)
+  typedef          uint8_t u8;
+  typedef           int8_t s8;
+#else
+  #error "don't know how to typedef 'u8' on this system"
+#endif
+
+// NOTE:
+// "signed char" is not the same as "char". 
+// http://www.embedded.com/columns/programmingpointers/206107018
+// http://en.wikipedia.org/wiki/C_variable_types_and_declarations
+
+
+#if   USHRT_MAX >= 0xffff
+  typedef unsigned short    u16;
+  typedef          short    s16;
+#elif defined(UINT16_MAX)
+  typedef          uint16_t u16;
+  typedef           int16_t s16;
+#else
+  #error "don't know how to typedef 'u16' on this system"
+#endif
+
+
+#if   UINT_MAX  >= 0xffffffff
+  typedef unsigned int      u32;
+  typedef          int      s32;
+#elif defined(UINT32_MAX)
+  typedef          uint32_t u32;
+  typedef           int32_t s32;
+#else
+  #error "don't know how to typedef 'u32' on this system"
+#endif
+
+
+#if defined(ARMA_USE_U64S64)
+  #if   ULLONG_MAX >= 0xffffffffffffffff
+    typedef unsigned long long u64;
+    typedef          long long s64;
+  #elif ULONG_MAX  >= 0xffffffffffffffff
+    typedef unsigned long      u64;
+    typedef          long      s64;
+    #define ARMA_U64_IS_LONG
+  #elif defined(UINT64_MAX)
+    typedef          uint64_t  u64;
+    typedef           int64_t  s64;
+  #else
+      #error "don't know how to typedef 'u64' on this system; please disable ARMA_64BIT_WORD and/or ARMA_USE_U64S64"
+  #endif
+#endif
+
+
+#if !defined(ARMA_USE_U64S64) || (defined(ARMA_USE_U64S64) && !defined(ARMA_U64_IS_LONG))
+  #define ARMA_ALLOW_LONG
+#endif
+
+
+typedef unsigned long ulng_t;
+typedef          long slng_t;
+
+
+#if !defined(ARMA_64BIT_WORD)
+  typedef u32 uword;
+  typedef s32 sword;
+
+  typedef u16 uhword;
+  typedef s16 shword;
+  
+  #define ARMA_MAX_UWORD  0xffffffff
+  #define ARMA_MAX_UHWORD 0xffff
+#else
+  typedef u64 uword;
+  typedef s64 sword;
+  
+  typedef u32 uhword;
+  typedef s32 shword;
+
+  #define ARMA_MAX_UWORD  0xffffffffffffffff
+  #define ARMA_MAX_UHWORD 0xffffffff
+#endif
+
+
+
+typedef std::complex<float>  cx_float;
+typedef std::complex<double> cx_double;
+
+typedef Mat <unsigned char> uchar_mat;
+typedef Col <unsigned char> uchar_vec;
+typedef Col <unsigned char> uchar_colvec;
+typedef Row <unsigned char> uchar_rowvec;
+typedef Cube<unsigned char> uchar_cube;
+
+typedef Mat <u32> u32_mat;
+typedef Col <u32> u32_vec;
+typedef Col <u32> u32_colvec;
+typedef Row <u32> u32_rowvec;
+typedef Cube<u32> u32_cube;
+
+typedef Mat <s32> s32_mat;
+typedef Col <s32> s32_vec;
+typedef Col <s32> s32_colvec;
+typedef Row <s32> s32_rowvec;
+typedef Cube<s32> s32_cube;
+
+#if defined(ARMA_USE_U64S64)
+  typedef Mat <u64> u64_mat;
+  typedef Col <u64> u64_vec;
+  typedef Col <u64> u64_colvec;
+  typedef Row <u64> u64_rowvec;
+  typedef Cube<u64> u64_cube;
+
+  typedef Mat <s64> s64_mat;
+  typedef Col <s64> s64_vec;
+  typedef Col <s64> s64_colvec;
+  typedef Row <s64> s64_rowvec;
+  typedef Cube<s64> s64_cube;
+#endif
+
+typedef Mat <uword> umat;
+typedef Col <uword> uvec;
+typedef Col <uword> ucolvec;
+typedef Row <uword> urowvec;
+typedef Cube<uword> ucube;
+
+typedef Mat <sword> imat;
+typedef Col <sword> ivec;
+typedef Col <sword> icolvec;
+typedef Row <sword> irowvec;
+typedef Cube<sword> icube;
+
+typedef Mat <float> fmat;
+typedef Col <float> fvec;
+typedef Col <float> fcolvec;
+typedef Row <float> frowvec;
+typedef Cube<float> fcube;
+
+typedef Mat <double> mat;
+typedef Col <double> vec;
+typedef Col <double> colvec;
+typedef Row <double> rowvec;
+typedef Cube<double> cube;
+
+typedef Mat <cx_float> cx_fmat;
+typedef Col <cx_float> cx_fvec;
+typedef Col <cx_float> cx_fcolvec;
+typedef Row <cx_float> cx_frowvec;
+typedef Cube<cx_float> cx_fcube;
+
+typedef Mat <cx_double> cx_mat;
+typedef Col <cx_double> cx_vec;
+typedef Col <cx_double> cx_colvec;
+typedef Row <cx_double> cx_rowvec;
+typedef Cube<cx_double> cx_cube;
+
+
+
+typedef SpMat <uword> sp_umat;
+typedef SpCol <uword> sp_uvec;
+typedef SpCol <uword> sp_ucolvec;
+typedef SpRow <uword> sp_urowvec;
+
+typedef SpMat <sword> sp_imat;
+typedef SpCol <sword> sp_ivec;
+typedef SpCol <sword> sp_icolvec;
+typedef SpRow <sword> sp_irowvec;
+
+typedef SpMat <float> sp_fmat;
+typedef SpCol <float> sp_fvec;
+typedef SpCol <float> sp_fcolvec;
+typedef SpRow <float> sp_frowvec;
+
+typedef SpMat <double> sp_mat;
+typedef SpCol <double> sp_vec;
+typedef SpCol <double> sp_colvec;
+typedef SpRow <double> sp_rowvec;
+
+typedef SpMat <cx_float> sp_cx_fmat;
+typedef SpCol <cx_float> sp_cx_fvec;
+typedef SpCol <cx_float> sp_cx_fcolvec;
+typedef SpRow <cx_float> sp_cx_frowvec;
+
+typedef SpMat <cx_double> sp_cx_mat;
+typedef SpCol <cx_double> sp_cx_vec;
+typedef SpCol <cx_double> sp_cx_colvec;
+typedef SpRow <cx_double> sp_cx_rowvec;
+
+
+
+typedef void* void_ptr;
+
+
+
+namespace junk
+  {
+  struct arma_elem_size_test
+    {
+    
+    arma_static_check( (sizeof(u8) != 1), ERROR___TYPE_U8_HAS_UNSUPPORTED_SIZE );
+    arma_static_check( (sizeof(s8) != 1), ERROR___TYPE_S8_HAS_UNSUPPORTED_SIZE );
+    
+    arma_static_check( (sizeof(u16) != 2), ERROR___TYPE_U16_HAS_UNSUPPORTED_SIZE );
+    arma_static_check( (sizeof(s16) != 2), ERROR___TYPE_S16_HAS_UNSUPPORTED_SIZE );
+    
+    arma_static_check( (sizeof(u32) != 4), ERROR___TYPE_U32_HAS_UNSUPPORTED_SIZE );
+    arma_static_check( (sizeof(s32) != 4), ERROR___TYPE_S32_HAS_UNSUPPORTED_SIZE );
+    
+    #if defined(ARMA_USE_U64S64)
+      arma_static_check( (sizeof(u64) != 8), ERROR___TYPE_U64_HAS_UNSUPPORTED_SIZE );
+      arma_static_check( (sizeof(s64) != 8), ERROR___TYPE_S64_HAS_UNSUPPORTED_SIZE );
+    #endif
+    
+    arma_static_check( (sizeof(float)  != 4), ERROR___TYPE_FLOAT_HAS_UNSUPPORTED_SIZE );
+    arma_static_check( (sizeof(double) != 8), ERROR___TYPE_DOUBLE_HAS_UNSUPPORTED_SIZE );
+    
+    arma_static_check( (sizeof(std::complex<float>)  != 8),  ERROR___TYPE_COMPLEX_FLOAT_HAS_UNSUPPORTED_SIZE );
+    arma_static_check( (sizeof(std::complex<double>) != 16), ERROR___TYPE_COMPLEX_DOUBLE_HAS_UNSUPPORTED_SIZE );
+    
+    };
+  }
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/typedef_blas_int.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,22 @@
+// Copyright (C) 2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup typedef
+//! @{
+
+
+#if   defined(ARMA_BLAS_LONG_LONG)
+  typedef long long blas_int;
+#elif defined(ARMA_BLAS_LONG)
+  typedef long      blas_int;
+#else
+  typedef int       blas_int;
+#endif
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/typedef_fixed.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,244 @@
+// Copyright (C) 2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup typedef_fixed
+//! @{
+
+
+
+typedef umat::fixed<2,2> umat22;
+typedef umat::fixed<3,3> umat33;
+typedef umat::fixed<4,4> umat44;
+typedef umat::fixed<5,5> umat55;
+typedef umat::fixed<6,6> umat66;
+typedef umat::fixed<7,7> umat77;
+typedef umat::fixed<8,8> umat88;
+typedef umat::fixed<9,9> umat99;
+
+typedef imat::fixed<2,2> imat22;
+typedef imat::fixed<3,3> imat33;
+typedef imat::fixed<4,4> imat44;
+typedef imat::fixed<5,5> imat55;
+typedef imat::fixed<6,6> imat66;
+typedef imat::fixed<7,7> imat77;
+typedef imat::fixed<8,8> imat88;
+typedef imat::fixed<9,9> imat99;
+
+typedef fmat::fixed<2,2> fmat22;
+typedef fmat::fixed<3,3> fmat33;
+typedef fmat::fixed<4,4> fmat44;
+typedef fmat::fixed<5,5> fmat55;
+typedef fmat::fixed<6,6> fmat66;
+typedef fmat::fixed<7,7> fmat77;
+typedef fmat::fixed<8,8> fmat88;
+typedef fmat::fixed<9,9> fmat99;
+
+typedef mat::fixed<2,2> mat22;
+typedef mat::fixed<3,3> mat33;
+typedef mat::fixed<4,4> mat44;
+typedef mat::fixed<5,5> mat55;
+typedef mat::fixed<6,6> mat66;
+typedef mat::fixed<7,7> mat77;
+typedef mat::fixed<8,8> mat88;
+typedef mat::fixed<9,9> mat99;
+
+typedef cx_fmat::fixed<2,2> cx_fmat22;
+typedef cx_fmat::fixed<3,3> cx_fmat33;
+typedef cx_fmat::fixed<4,4> cx_fmat44;
+typedef cx_fmat::fixed<5,5> cx_fmat55;
+typedef cx_fmat::fixed<6,6> cx_fmat66;
+typedef cx_fmat::fixed<7,7> cx_fmat77;
+typedef cx_fmat::fixed<8,8> cx_fmat88;
+typedef cx_fmat::fixed<9,9> cx_fmat99;
+
+typedef cx_mat::fixed<2,2> cx_mat22;
+typedef cx_mat::fixed<3,3> cx_mat33;
+typedef cx_mat::fixed<4,4> cx_mat44;
+typedef cx_mat::fixed<5,5> cx_mat55;
+typedef cx_mat::fixed<6,6> cx_mat66;
+typedef cx_mat::fixed<7,7> cx_mat77;
+typedef cx_mat::fixed<8,8> cx_mat88;
+typedef cx_mat::fixed<9,9> cx_mat99;
+
+
+//
+
+
+typedef uvec::fixed<2> uvec2;
+typedef uvec::fixed<3> uvec3;
+typedef uvec::fixed<4> uvec4;
+typedef uvec::fixed<5> uvec5;
+typedef uvec::fixed<6> uvec6;
+typedef uvec::fixed<7> uvec7;
+typedef uvec::fixed<8> uvec8;
+typedef uvec::fixed<9> uvec9;
+
+typedef ivec::fixed<2> ivec2;
+typedef ivec::fixed<3> ivec3;
+typedef ivec::fixed<4> ivec4;
+typedef ivec::fixed<5> ivec5;
+typedef ivec::fixed<6> ivec6;
+typedef ivec::fixed<7> ivec7;
+typedef ivec::fixed<8> ivec8;
+typedef ivec::fixed<9> ivec9;
+
+typedef fvec::fixed<2> fvec2;
+typedef fvec::fixed<3> fvec3;
+typedef fvec::fixed<4> fvec4;
+typedef fvec::fixed<5> fvec5;
+typedef fvec::fixed<6> fvec6;
+typedef fvec::fixed<7> fvec7;
+typedef fvec::fixed<8> fvec8;
+typedef fvec::fixed<9> fvec9;
+
+typedef vec::fixed<2> vec2;
+typedef vec::fixed<3> vec3;
+typedef vec::fixed<4> vec4;
+typedef vec::fixed<5> vec5;
+typedef vec::fixed<6> vec6;
+typedef vec::fixed<7> vec7;
+typedef vec::fixed<8> vec8;
+typedef vec::fixed<9> vec9;
+
+typedef cx_fvec::fixed<2> cx_fvec2;
+typedef cx_fvec::fixed<3> cx_fvec3;
+typedef cx_fvec::fixed<4> cx_fvec4;
+typedef cx_fvec::fixed<5> cx_fvec5;
+typedef cx_fvec::fixed<6> cx_fvec6;
+typedef cx_fvec::fixed<7> cx_fvec7;
+typedef cx_fvec::fixed<8> cx_fvec8;
+typedef cx_fvec::fixed<9> cx_fvec9;
+
+typedef cx_vec::fixed<2> cx_vec2;
+typedef cx_vec::fixed<3> cx_vec3;
+typedef cx_vec::fixed<4> cx_vec4;
+typedef cx_vec::fixed<5> cx_vec5;
+typedef cx_vec::fixed<6> cx_vec6;
+typedef cx_vec::fixed<7> cx_vec7;
+typedef cx_vec::fixed<8> cx_vec8;
+typedef cx_vec::fixed<9> cx_vec9;
+
+
+//
+
+
+typedef ucolvec::fixed<2> ucolvec2;
+typedef ucolvec::fixed<3> ucolvec3;
+typedef ucolvec::fixed<4> ucolvec4;
+typedef ucolvec::fixed<5> ucolvec5;
+typedef ucolvec::fixed<6> ucolvec6;
+typedef ucolvec::fixed<7> ucolvec7;
+typedef ucolvec::fixed<8> ucolvec8;
+typedef ucolvec::fixed<9> ucolvec9;
+
+typedef icolvec::fixed<2> icolvec2;
+typedef icolvec::fixed<3> icolvec3;
+typedef icolvec::fixed<4> icolvec4;
+typedef icolvec::fixed<5> icolvec5;
+typedef icolvec::fixed<6> icolvec6;
+typedef icolvec::fixed<7> icolvec7;
+typedef icolvec::fixed<8> icolvec8;
+typedef icolvec::fixed<9> icolvec9;
+
+typedef fcolvec::fixed<2> fcolvec2;
+typedef fcolvec::fixed<3> fcolvec3;
+typedef fcolvec::fixed<4> fcolvec4;
+typedef fcolvec::fixed<5> fcolvec5;
+typedef fcolvec::fixed<6> fcolvec6;
+typedef fcolvec::fixed<7> fcolvec7;
+typedef fcolvec::fixed<8> fcolvec8;
+typedef fcolvec::fixed<9> fcolvec9;
+
+typedef colvec::fixed<2> colvec2;
+typedef colvec::fixed<3> colvec3;
+typedef colvec::fixed<4> colvec4;
+typedef colvec::fixed<5> colvec5;
+typedef colvec::fixed<6> colvec6;
+typedef colvec::fixed<7> colvec7;
+typedef colvec::fixed<8> colvec8;
+typedef colvec::fixed<9> colvec9;
+
+typedef cx_fcolvec::fixed<2> cx_fcolvec2;
+typedef cx_fcolvec::fixed<3> cx_fcolvec3;
+typedef cx_fcolvec::fixed<4> cx_fcolvec4;
+typedef cx_fcolvec::fixed<5> cx_fcolvec5;
+typedef cx_fcolvec::fixed<6> cx_fcolvec6;
+typedef cx_fcolvec::fixed<7> cx_fcolvec7;
+typedef cx_fcolvec::fixed<8> cx_fcolvec8;
+typedef cx_fcolvec::fixed<9> cx_fcolvec9;
+
+typedef cx_colvec::fixed<2> cx_colvec2;
+typedef cx_colvec::fixed<3> cx_colvec3;
+typedef cx_colvec::fixed<4> cx_colvec4;
+typedef cx_colvec::fixed<5> cx_colvec5;
+typedef cx_colvec::fixed<6> cx_colvec6;
+typedef cx_colvec::fixed<7> cx_colvec7;
+typedef cx_colvec::fixed<8> cx_colvec8;
+typedef cx_colvec::fixed<9> cx_colvec9;
+
+
+//
+
+
+typedef urowvec::fixed<2> urowvec2;
+typedef urowvec::fixed<3> urowvec3;
+typedef urowvec::fixed<4> urowvec4;
+typedef urowvec::fixed<5> urowvec5;
+typedef urowvec::fixed<6> urowvec6;
+typedef urowvec::fixed<7> urowvec7;
+typedef urowvec::fixed<8> urowvec8;
+typedef urowvec::fixed<9> urowvec9;
+
+typedef irowvec::fixed<2> irowvec2;
+typedef irowvec::fixed<3> irowvec3;
+typedef irowvec::fixed<4> irowvec4;
+typedef irowvec::fixed<5> irowvec5;
+typedef irowvec::fixed<6> irowvec6;
+typedef irowvec::fixed<7> irowvec7;
+typedef irowvec::fixed<8> irowvec8;
+typedef irowvec::fixed<9> irowvec9;
+
+typedef frowvec::fixed<2> frowvec2;
+typedef frowvec::fixed<3> frowvec3;
+typedef frowvec::fixed<4> frowvec4;
+typedef frowvec::fixed<5> frowvec5;
+typedef frowvec::fixed<6> frowvec6;
+typedef frowvec::fixed<7> frowvec7;
+typedef frowvec::fixed<8> frowvec8;
+typedef frowvec::fixed<9> frowvec9;
+
+typedef rowvec::fixed<2> rowvec2;
+typedef rowvec::fixed<3> rowvec3;
+typedef rowvec::fixed<4> rowvec4;
+typedef rowvec::fixed<5> rowvec5;
+typedef rowvec::fixed<6> rowvec6;
+typedef rowvec::fixed<7> rowvec7;
+typedef rowvec::fixed<8> rowvec8;
+typedef rowvec::fixed<9> rowvec9;
+
+typedef cx_frowvec::fixed<2> cx_frowvec2;
+typedef cx_frowvec::fixed<3> cx_frowvec3;
+typedef cx_frowvec::fixed<4> cx_frowvec4;
+typedef cx_frowvec::fixed<5> cx_frowvec5;
+typedef cx_frowvec::fixed<6> cx_frowvec6;
+typedef cx_frowvec::fixed<7> cx_frowvec7;
+typedef cx_frowvec::fixed<8> cx_frowvec8;
+typedef cx_frowvec::fixed<9> cx_frowvec9;
+
+typedef cx_rowvec::fixed<2> cx_rowvec2;
+typedef cx_rowvec::fixed<3> cx_rowvec3;
+typedef cx_rowvec::fixed<4> cx_rowvec4;
+typedef cx_rowvec::fixed<5> cx_rowvec5;
+typedef cx_rowvec::fixed<6> cx_rowvec6;
+typedef cx_rowvec::fixed<7> cx_rowvec7;
+typedef cx_rowvec::fixed<8> cx_rowvec8;
+typedef cx_rowvec::fixed<9> cx_rowvec9;
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/undefine_conflicts.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,44 @@
+// Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2011 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+
+#if defined(log2)
+  #undef log2
+  
+  #if defined(__GNUG__)
+    #warning         "detected 'log2' macro and undefined it"
+  #elif defined(_MSC_VER)
+    #pragma message ("detected 'log2' macro and undefined it")
+  #endif
+#endif
+
+
+
+// 
+// whoever defined macros with the names "min" and "max" should be permanently removed from the gene pool
+
+#if defined(min)
+  #undef min
+  
+  #if defined(__GNUG__)
+    #warning         "detected 'min' macro and undefined it; you may wish to define NOMINMAX before including any windows header"
+  #elif defined(_MSC_VER)
+    #pragma message ("detected 'min' macro and undefined it; you may wish to define NOMINMAX before including any windows header")
+  #endif
+#endif
+
+#if defined(max)
+  #undef max
+  
+  #if defined(__GNUG__)
+    #warning         "detected 'max' macro and undefined it; you may wish to define NOMINMAX before including any windows header"
+  #elif defined(_MSC_VER)
+    #pragma message ("detected 'max' macro and undefined it; you may wish to define NOMINMAX before including any windows header")
+  #endif
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/unwrap.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,2511 @@
+// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup unwrap
+//! @{
+
+
+
+template<typename T1>
+struct unwrap_default
+  {
+  typedef typename T1::elem_type eT;
+  typedef Mat<eT>                stored_type;
+  
+  inline
+  unwrap_default(const T1& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Mat<eT> M;
+  };
+
+
+
+template<typename T1>
+struct unwrap_fixed
+  {
+  typedef T1 stored_type;
+  
+  inline explicit
+  unwrap_fixed(const T1& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const T1& M;
+  };
+
+
+
+template<typename T1, bool condition>
+struct unwrap_redirect {};
+
+template<typename T1>
+struct unwrap_redirect<T1, false> { typedef unwrap_default<T1> result; };
+
+template<typename T1>
+struct unwrap_redirect<T1, true>  { typedef unwrap_fixed<T1>   result; };
+
+
+template<typename T1>
+struct unwrap : public unwrap_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  inline
+  unwrap(const T1& A)
+    : unwrap_redirect< T1, is_Mat_fixed<T1>::value >::result(A)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+struct unwrap< Mat<eT> >
+  {
+  typedef Mat<eT> stored_type;
+  
+  inline
+  unwrap(const Mat<eT>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Mat<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct unwrap< Row<eT> >
+  {
+  typedef Row<eT> stored_type;
+  
+  inline
+  unwrap(const Row<eT>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Row<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct unwrap< Col<eT> >
+  {
+  typedef Col<eT> stored_type;
+
+  inline
+  unwrap(const Col<eT>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Col<eT>& M;
+  };
+
+
+
+template<typename out_eT, typename T1, typename T2, typename glue_type>
+struct unwrap< mtGlue<out_eT, T1, T2, glue_type> >
+  {
+  typedef Mat<out_eT> stored_type;
+  
+  inline
+  unwrap(const mtGlue<out_eT, T1, T2, glue_type>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Mat<out_eT> M;
+  };
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+struct unwrap< mtOp<out_eT, T1, op_type> >
+  {
+  typedef Mat<out_eT> stored_type;
+  
+  inline
+  unwrap(const mtOp<out_eT, T1, op_type>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Mat<out_eT> M;
+  };
+
+
+
+//
+//
+//
+
+
+
+template<typename T1>
+struct quasi_unwrap_default
+  {
+  typedef typename T1::elem_type eT;
+  
+  static const bool has_subview = false;
+  
+  inline
+  quasi_unwrap_default(const T1& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  // NOTE: DO NOT DIRECTLY CHECK FOR ALIASING BY TAKING THE ADDRESS OF THE "M" OBJECT IN ANY quasi_unwrap CLASS !!!
+  const Mat<eT> M;
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
+  };
+
+
+
+template<typename T1>
+struct quasi_unwrap_fixed
+  {
+  typedef typename T1::elem_type eT;
+  
+  static const bool has_subview = false;
+  
+  inline explicit
+  quasi_unwrap_fixed(const T1& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Mat<eT>& M;
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&M) == void_ptr(&X)); }
+  };
+
+
+
+template<typename T1, bool condition>
+struct quasi_unwrap_redirect {};
+
+template<typename T1>
+struct quasi_unwrap_redirect<T1, false> { typedef quasi_unwrap_default<T1> result; };
+
+template<typename T1>
+struct quasi_unwrap_redirect<T1, true>  { typedef quasi_unwrap_fixed<T1>   result; };
+
+
+template<typename T1>
+struct quasi_unwrap : public quasi_unwrap_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  typedef typename quasi_unwrap_redirect<T1, is_Mat_fixed<T1>::value >::result quasi_unwrap_extra;
+  
+  static const bool has_subview = quasi_unwrap_extra::has_subview;
+  
+  inline
+  quasi_unwrap(const T1& A)
+    : quasi_unwrap_extra(A)
+    {
+    }
+  
+  using quasi_unwrap_extra::M;
+  using quasi_unwrap_extra::is_alias;
+  };
+
+
+
+template<typename eT>
+struct quasi_unwrap< Mat<eT> >
+  {
+  static const bool has_subview = false;
+  
+  inline
+  quasi_unwrap(const Mat<eT>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Mat<eT>& M;
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&M) == void_ptr(&X)); }
+  };
+
+
+
+template<typename eT>
+struct quasi_unwrap< Row<eT> >
+  {
+  static const bool has_subview = false;
+  
+  inline
+  quasi_unwrap(const Row<eT>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Row<eT>& M;
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&M) == void_ptr(&X)); }
+  };
+
+
+
+template<typename eT>
+struct quasi_unwrap< Col<eT> >
+  {
+  static const bool has_subview = false;
+  
+  inline
+  quasi_unwrap(const Col<eT>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Col<eT>& M;
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&M) == void_ptr(&X)); }
+  };
+
+
+
+template<typename eT>
+struct quasi_unwrap< subview_col<eT> >
+  {
+  static const bool has_subview = true;
+  
+  inline
+  quasi_unwrap(const subview_col<eT>& A)
+    : M  ( const_cast<eT*>( A.colptr(0) ), A.n_rows, 1, false, false )
+    , src( A.m )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Mat<eT>  M;
+  const Mat<eT>& src;
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&src) == void_ptr(&X)); }
+  };
+
+
+
+template<typename out_eT, typename T1, typename T2, typename glue_type>
+struct quasi_unwrap< mtGlue<out_eT, T1, T2, glue_type> >
+  {
+  static const bool has_subview = false;
+  
+  inline
+  quasi_unwrap(const mtGlue<out_eT, T1, T2, glue_type>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Mat<out_eT> M;
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
+  };
+
+
+
+template<typename out_eT, typename T1, typename op_type>
+struct quasi_unwrap< mtOp<out_eT, T1, op_type> >
+  {
+  static const bool has_subview = false;
+  
+  inline
+  quasi_unwrap(const mtOp<out_eT, T1, op_type>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Mat<out_eT> M;
+  
+  template<typename eT2>
+  arma_inline bool is_alias(const Mat<eT2>&) const { return false; }
+  };
+
+
+
+//
+//
+//
+
+
+
+template<typename T1>
+struct unwrap_check_default
+  {
+  typedef typename T1::elem_type eT;
+  typedef Mat<eT>                stored_type;
+  
+  inline
+  unwrap_check_default(const T1& A, const Mat<eT>&)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  unwrap_check_default(const T1& A, const bool)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Mat<eT> M;
+  };
+
+
+
+template<typename T1>
+struct unwrap_check_fixed
+  {
+  typedef typename T1::elem_type eT;
+  typedef T1                     stored_type;
+  
+  inline
+  unwrap_check_fixed(const T1& A, const Mat<eT>& B)
+    : M_local( (&A == &B) ? new T1(A) : 0 )
+    , M      ( (&A == &B) ? *M_local  : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  unwrap_check_fixed(const T1& A, const bool is_alias)
+    : M_local( is_alias ? new T1(A) : 0 )
+    , M      ( is_alias ? *M_local  : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~unwrap_check_fixed()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  
+  // the order below is important
+  const T1* M_local;
+  const T1& M;
+  };
+
+
+
+template<typename T1, bool condition>
+struct unwrap_check_redirect {};
+
+template<typename T1>
+struct unwrap_check_redirect<T1, false> { typedef unwrap_check_default<T1> result; };
+
+template<typename T1>
+struct unwrap_check_redirect<T1, true>  { typedef unwrap_check_fixed<T1>   result; };
+
+
+template<typename T1>
+struct unwrap_check : public unwrap_check_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  inline unwrap_check(const T1& A, const Mat<typename T1::elem_type>& B)
+    : unwrap_check_redirect< T1, is_Mat_fixed<T1>::value >::result(A, B)
+    {
+    }
+  
+  inline unwrap_check(const T1& A, const bool is_alias)
+    : unwrap_check_redirect< T1, is_Mat_fixed<T1>::value >::result(A, is_alias)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+struct unwrap_check< Mat<eT> >
+  {
+  typedef Mat<eT> stored_type;
+  
+  inline
+  unwrap_check(const Mat<eT>& A, const Mat<eT>& B)
+    : M_local( (&A == &B) ? new Mat<eT>(A) : 0 )
+    , M      ( (&A == &B) ? (*M_local)     : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  unwrap_check(const Mat<eT>& A, const bool is_alias)
+    : M_local( is_alias ? new Mat<eT>(A) : 0 )
+    , M      ( is_alias ? (*M_local)     : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  
+  // the order below is important
+  const Mat<eT>* M_local;
+  const Mat<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct unwrap_check< Row<eT> >
+  {
+  typedef Row<eT> stored_type;
+  
+  inline
+  unwrap_check(const Row<eT>& A, const Mat<eT>& B)
+    : M_local( (&A == &B) ? new Row<eT>(A) : 0 )
+    , M      ( (&A == &B) ? (*M_local)     : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  unwrap_check(const Row<eT>& A, const bool is_alias)
+    : M_local( is_alias ? new Row<eT>(A) : 0 )
+    , M      ( is_alias ? (*M_local)     : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  
+  // the order below is important
+  const Row<eT>* M_local;
+  const Row<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct unwrap_check< Col<eT> >
+  {
+  typedef Col<eT> stored_type;
+  
+  inline
+  unwrap_check(const Col<eT>& A, const Mat<eT>& B)
+    : M_local( (&A == &B) ? new Col<eT>(A) : 0 )
+    , M      ( (&A == &B) ? (*M_local)     : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  unwrap_check(const Col<eT>& A, const bool is_alias)
+    : M_local( is_alias ? new Col<eT>(A) : 0 )
+    , M      ( is_alias ? (*M_local)     : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  
+  // the order below is important
+  const Col<eT>* M_local;
+  const Col<eT>& M;
+  };
+
+
+
+//
+//
+//
+
+
+
+template<typename T1>
+struct unwrap_check_mixed
+  {
+  typedef typename T1::elem_type eT1;
+  
+  template<typename eT2>
+  inline
+  unwrap_check_mixed(const T1& A, const Mat<eT2>&)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  template<typename eT2>
+  inline
+  unwrap_check_mixed(const T1& A, const bool)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Mat<eT1> M;
+  };
+
+
+
+template<typename eT1>
+struct unwrap_check_mixed< Mat<eT1> >
+  {
+  template<typename eT2>
+  inline
+  unwrap_check_mixed(const Mat<eT1>& A, const Mat<eT2>& B)
+    : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Mat<eT1>(A) : 0 )
+    , M      ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local)      : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  template<typename eT2>
+  inline
+  unwrap_check_mixed(const Mat<eT1>& A, const bool is_alias)
+    : M_local( is_alias ? new Mat<eT1>(A) : 0 )
+    , M      ( is_alias ? (*M_local)      : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~unwrap_check_mixed()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  
+  // the order below is important
+  const Mat<eT1>* M_local;
+  const Mat<eT1>& M;
+  };
+
+
+
+template<typename eT1>
+struct unwrap_check_mixed< Row<eT1> >
+  {
+  template<typename eT2>
+  inline
+  unwrap_check_mixed(const Row<eT1>& A, const Mat<eT2>& B)
+    : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Row<eT1>(A) : 0 )
+    , M      ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local)      : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  
+  template<typename eT2>
+  inline
+  unwrap_check_mixed(const Row<eT1>& A, const bool is_alias)
+    : M_local( is_alias ? new Row<eT1>(A) : 0 )
+    , M      ( is_alias ? (*M_local)      : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~unwrap_check_mixed()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  
+  // the order below is important
+  const Row<eT1>* M_local;
+  const Row<eT1>& M;
+  };
+
+
+
+template<typename eT1>
+struct unwrap_check_mixed< Col<eT1> >
+  {
+  template<typename eT2>
+  inline
+  unwrap_check_mixed(const Col<eT1>& A, const Mat<eT2>& B)
+    : M_local( (void_ptr(&A) == void_ptr(&B)) ? new Col<eT1>(A) : 0 )
+    , M      ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local)      : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  template<typename eT2>
+  inline
+  unwrap_check_mixed(const Col<eT1>& A, const bool is_alias)
+    : M_local( is_alias ? new Col<eT1>(A) : 0 )
+    , M      ( is_alias ? (*M_local)      : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~unwrap_check_mixed()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  
+  // the order below is important
+  const Col<eT1>* M_local;
+  const Col<eT1>& M;
+  };
+
+
+
+//
+//
+//
+
+
+
+template<typename T1>
+struct partial_unwrap_default
+  {
+  typedef typename T1::elem_type eT;
+  typedef Mat<eT>                stored_type;
+  
+  inline
+  partial_unwrap_default(const T1& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = false;
+  
+  const Mat<eT> M;
+  };
+
+
+template<typename T1>
+struct partial_unwrap_fixed
+  {
+  typedef typename T1::elem_type eT;
+  typedef T1                     stored_type;
+  
+  inline explicit
+  partial_unwrap_fixed(const T1& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = false;
+  
+  const T1& M;
+  };
+
+
+
+template<typename T1, bool condition>
+struct partial_unwrap_redirect {};
+
+template<typename T1>
+struct partial_unwrap_redirect<T1, false> { typedef partial_unwrap_default<T1> result; };
+
+template<typename T1>
+struct partial_unwrap_redirect<T1, true>  { typedef partial_unwrap_fixed<T1>   result; };
+
+template<typename T1>
+struct partial_unwrap : public partial_unwrap_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  inline
+  partial_unwrap(const T1& A)
+    : partial_unwrap_redirect< T1, is_Mat_fixed<T1>::value >::result(A)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< Mat<eT> >
+  {
+  typedef Mat<eT> stored_type;
+  
+  inline
+  partial_unwrap(const Mat<eT>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = false;
+  
+  const Mat<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< Row<eT> >
+  {
+  typedef Row<eT> stored_type;
+  
+  inline
+  partial_unwrap(const Row<eT>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = false;
+  
+  const Row<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< Col<eT> >
+  {
+  typedef Col<eT> stored_type;
+  
+  inline
+  partial_unwrap(const Col<eT>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = false;
+  
+  const Col<eT>& M;
+  };
+
+
+
+// NOTE: we can get away with this shortcut as the partial_unwrap class is only used by as_scalar(),
+// NOTE: which doesn't need to check for aliasing (ie. it doesn't need to compare the address of M with another matrix)
+template<typename eT>
+struct partial_unwrap< subview_col<eT> >
+  {
+  typedef Col<eT> stored_type;
+  
+  inline
+  partial_unwrap(const subview_col<eT>& A)
+    : M  ( const_cast<eT*>( A.colptr(0) ), A.n_rows, false, false )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = false;
+  
+  const Col<eT> M;
+  };
+
+
+
+template<typename T1>
+struct partial_unwrap_htrans_default
+  {
+  typedef typename T1::elem_type eT;
+  typedef Mat<eT>                stored_type;
+  
+  inline
+  partial_unwrap_htrans_default(const Op<T1, op_htrans>& A)
+    : M(A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = true;
+  static const bool do_times = false;
+  
+  const Mat<eT> M;
+  };
+
+
+template<typename T1>
+struct partial_unwrap_htrans_fixed
+  {
+  typedef typename T1::elem_type eT;
+  typedef T1                     stored_type;
+  
+  inline explicit
+  partial_unwrap_htrans_fixed(const Op<T1, op_htrans>& A)
+    : M(A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = true;
+  static const bool do_times = false;
+  
+  const T1& M;
+  };
+
+
+
+template<typename T1, bool condition>
+struct partial_unwrap_htrans_redirect {};
+
+template<typename T1>
+struct partial_unwrap_htrans_redirect<T1, false> { typedef partial_unwrap_htrans_default<T1> result; };
+
+template<typename T1>
+struct partial_unwrap_htrans_redirect<T1, true>  { typedef partial_unwrap_htrans_fixed<T1>   result; };
+
+template<typename T1>
+struct partial_unwrap< Op<T1, op_htrans> > : public partial_unwrap_htrans_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  inline partial_unwrap(const Op<T1, op_htrans>& A)
+    : partial_unwrap_htrans_redirect< T1, is_Mat_fixed<T1>::value >::result(A)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< Op< Mat<eT>, op_htrans> >
+  {
+  typedef Mat<eT> stored_type;
+  
+  inline
+  partial_unwrap(const Op< Mat<eT>, op_htrans>& A)
+    : M(A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = true;
+  static const bool do_times = false;
+  
+  const Mat<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< Op< Row<eT>, op_htrans> >
+  {
+  typedef Row<eT> stored_type;
+  
+  inline
+  partial_unwrap(const Op< Row<eT>, op_htrans>& A)
+    : M(A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = true;
+  static const bool do_times = false;
+  
+  const Row<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< Op< Col<eT>, op_htrans> >
+  {
+  typedef Col<eT> stored_type;
+  
+  inline
+  partial_unwrap(const Op< Col<eT>, op_htrans>& A)
+    : M(A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = true;
+  static const bool do_times = false;
+  
+  const Col<eT>& M;
+  };
+
+
+
+// NOTE: we can get away with this shortcut as the partial_unwrap class is only used by as_scalar(),
+// NOTE: which doesn't need to check for aliasing (ie. it doesn't need to compare the address of M with another matrix)
+template<typename eT>
+struct partial_unwrap< Op< subview_col<eT>, op_htrans> >
+  {
+  typedef Col<eT> stored_type;
+  
+  inline
+  partial_unwrap(const Op< subview_col<eT>, op_htrans>& A)
+    : M  ( const_cast<eT*>( A.m.colptr(0) ), A.m.n_rows, false, false )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = true;
+  static const bool do_times = false;
+  
+  const Col<eT> M;
+  };
+
+
+
+template<typename T1>
+struct partial_unwrap_htrans2_default
+  {
+  typedef typename T1::elem_type eT;
+  typedef Mat<eT>                stored_type;
+  
+  inline
+  partial_unwrap_htrans2_default(const Op<T1, op_htrans2>& A)
+    : val(A.aux)
+    , M  (A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = true;
+  static const bool do_times = true;
+  
+  const eT      val;
+  const Mat<eT> M;
+  };
+
+
+template<typename T1>
+struct partial_unwrap_htrans2_fixed
+  {
+  typedef typename T1::elem_type eT;
+  typedef T1                     stored_type;
+  
+  inline explicit
+  partial_unwrap_htrans2_fixed(const Op<T1, op_htrans2>& A)
+    : val(A.aux)
+    , M  (A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = true;
+  static const bool do_times = true;
+  
+  const eT  val;
+  const T1& M;
+  };
+
+
+
+template<typename T1, bool condition>
+struct partial_unwrap_htrans2_redirect {};
+
+template<typename T1>
+struct partial_unwrap_htrans2_redirect<T1, false> { typedef partial_unwrap_htrans2_default<T1> result; };
+
+template<typename T1>
+struct partial_unwrap_htrans2_redirect<T1, true>  { typedef partial_unwrap_htrans2_fixed<T1>   result; };
+
+template<typename T1>
+struct partial_unwrap< Op<T1, op_htrans2> > : public partial_unwrap_htrans2_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  inline partial_unwrap(const Op<T1, op_htrans2>& A)
+    : partial_unwrap_htrans2_redirect< T1, is_Mat_fixed<T1>::value >::result(A)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< Op< Mat<eT>, op_htrans2> >
+  {
+  typedef Mat<eT> stored_type;
+  
+  inline
+  partial_unwrap(const Op< Mat<eT>, op_htrans2>& A)
+    : val(A.aux)
+    , M  (A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return val; }
+  
+  static const bool do_trans = true;
+  static const bool do_times = true;
+  
+  const eT       val;
+  const Mat<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< Op< Row<eT>, op_htrans2> >
+  {
+  typedef Row<eT> stored_type;
+  
+  inline
+  partial_unwrap(const Op< Row<eT>, op_htrans2>& A)
+    : val(A.aux)
+    , M  (A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return val; }
+  
+  static const bool do_trans = true;
+  static const bool do_times = true;
+  
+  const eT       val;
+  const Row<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< Op< Col<eT>, op_htrans2> >
+  {
+  typedef Col<eT> stored_type;
+  
+  inline
+  partial_unwrap(const Op< Col<eT>, op_htrans2>& A)
+    : val(A.aux)
+    , M  (A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return val; }
+  
+  static const bool do_trans = true;
+  static const bool do_times = true;
+  
+  const eT       val;
+  const Col<eT>& M;
+  };
+
+
+
+// NOTE: we can get away with this shortcut as the partial_unwrap class is only used by as_scalar(),
+// NOTE: which doesn't need to check for aliasing (ie. it doesn't need to compare the address of M with another matrix)
+template<typename eT>
+struct partial_unwrap< Op< subview_col<eT>, op_htrans2> >
+  {
+  typedef Col<eT> stored_type;
+  
+  inline
+  partial_unwrap(const Op< subview_col<eT>, op_htrans2>& A)
+    : val( A.aux )
+    , M  ( const_cast<eT*>( A.m.colptr(0) ), A.m.n_rows, false, false )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return val; }
+  
+  static const bool do_trans = true;
+  static const bool do_times = true;
+  
+  const eT      val;
+  const Col<eT> M;
+  };
+
+
+
+template<typename T1>
+struct partial_unwrap_scalar_times_default
+  {
+  typedef typename T1::elem_type eT;
+  typedef Mat<eT>                stored_type;
+  
+  inline
+  partial_unwrap_scalar_times_default(const eOp<T1, eop_scalar_times>& A)
+    : val(A.aux)
+    , M  (A.P.Q)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const eT      val;
+  const Mat<eT> M;
+  };
+
+
+
+template<typename T1>
+struct partial_unwrap_scalar_times_fixed
+  {
+  typedef typename T1::elem_type eT;
+  typedef T1                     stored_type;
+  
+  inline explicit
+  partial_unwrap_scalar_times_fixed(const eOp<T1, eop_scalar_times>& A)
+    : val(A.aux)
+    , M  (A.P.Q)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const eT  val;
+  const T1& M;
+  };
+
+
+
+template<typename T1, bool condition>
+struct partial_unwrap_scalar_times_redirect {};
+
+template<typename T1>
+struct partial_unwrap_scalar_times_redirect<T1, false> { typedef partial_unwrap_scalar_times_default<T1> result; };
+
+template<typename T1>
+struct partial_unwrap_scalar_times_redirect<T1, true>  { typedef partial_unwrap_scalar_times_fixed<T1>   result; };
+
+
+template<typename T1>
+struct partial_unwrap< eOp<T1, eop_scalar_times> > : public partial_unwrap_scalar_times_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  typedef typename T1::elem_type eT;
+  
+  inline
+  partial_unwrap(const eOp<T1, eop_scalar_times>& A)
+    : partial_unwrap_scalar_times_redirect< T1, is_Mat_fixed<T1>::value >::result(A)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< eOp<Mat<eT>, eop_scalar_times> >
+  {
+  typedef Mat<eT> stored_type;
+  
+  inline
+  partial_unwrap(const eOp<Mat<eT>,eop_scalar_times>& A)
+    : val(A.aux)
+    , M  (A.P.Q)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return val; }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const eT       val;
+  const Mat<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< eOp<Row<eT>, eop_scalar_times> >
+  {
+  typedef Row<eT> stored_type;
+  
+  inline
+  partial_unwrap(const eOp<Row<eT>,eop_scalar_times>& A)
+    : val(A.aux)
+    , M  (A.P.Q)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return val; }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const eT       val;
+  const Row<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< eOp<Col<eT>, eop_scalar_times> >
+  {
+  typedef Col<eT> stored_type;
+  
+  inline
+  partial_unwrap(const eOp<Col<eT>,eop_scalar_times>& A)
+    : val(A.aux)
+    , M  (A.P.Q)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return val; }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const eT       val;
+  const Col<eT>& M;
+  };
+
+
+
+// TODO: struct partial_unwrap< eOp<subview_col<eT>, eop_scalar_times> >
+
+
+
+template<typename T1>
+struct partial_unwrap_neg_default
+  {
+  typedef typename T1::elem_type eT;
+  typedef Mat<eT>                stored_type;
+  
+  inline
+  partial_unwrap_neg_default(const eOp<T1, eop_neg>& A)
+    : M(A.P.Q)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(-1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const Mat<eT> M;
+  };
+
+
+
+template<typename T1>
+struct partial_unwrap_neg_fixed
+  {
+  typedef typename T1::elem_type eT;
+  typedef T1                     stored_type;
+  
+  inline explicit
+  partial_unwrap_neg_fixed(const eOp<T1, eop_neg>& A)
+    : M(A.P.Q)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(-1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const T1& M;
+  };
+
+
+
+template<typename T1, bool condition>
+struct partial_unwrap_neg_redirect {};
+
+template<typename T1>
+struct partial_unwrap_neg_redirect<T1, false> { typedef partial_unwrap_neg_default<T1> result; };
+
+template<typename T1>
+struct partial_unwrap_neg_redirect<T1, true>  { typedef partial_unwrap_neg_fixed<T1>   result; };
+
+
+template<typename T1>
+struct partial_unwrap< eOp<T1, eop_neg> > : public partial_unwrap_neg_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  typedef typename T1::elem_type eT;
+  
+  inline
+  partial_unwrap(const eOp<T1, eop_neg>& A)
+    : partial_unwrap_neg_redirect< T1, is_Mat_fixed<T1>::value >::result(A)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< eOp<Mat<eT>, eop_neg> >
+  {
+  typedef Mat<eT> stored_type;
+  
+  inline
+  partial_unwrap(const eOp<Mat<eT>,eop_neg>& A)
+    : M(A.P.Q)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return eT(-1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const Mat<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< eOp<Row<eT>, eop_neg> >
+  {
+  typedef Row<eT> stored_type;
+  
+  inline
+  partial_unwrap(const eOp<Row<eT>,eop_neg>& A)
+    : M(A.P.Q)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return eT(-1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const Row<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap< eOp<Col<eT>, eop_neg> >
+  {
+  typedef Col<eT> stored_type;
+  
+  inline
+  partial_unwrap(const eOp<Col<eT>,eop_neg>& A)
+    : M(A.P.Q)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline eT get_val() const { return eT(-1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const Col<eT>& M;
+  };
+
+
+
+// TODO: struct partial_unwrap< eOp<subview_col<eT>, eop_neg> >
+
+
+
+//
+
+
+
+template<typename T1>
+struct partial_unwrap_check_default
+  {
+  typedef typename T1::elem_type eT;
+  typedef Mat<eT>                stored_type;
+  
+  inline
+  partial_unwrap_check_default(const T1& A, const Mat<eT>&)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = false;
+  
+  const Mat<eT> M;
+  };
+
+
+template<typename T1>
+struct partial_unwrap_check_fixed
+  {
+  typedef typename T1::elem_type eT;
+  typedef T1                     stored_type;
+  
+  inline explicit
+  partial_unwrap_check_fixed(const T1& A, const Mat<eT>& B)
+    : M_local( (&A == &B) ? new T1(A)  : 0 )
+    , M      ( (&A == &B) ? (*M_local) : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check_fixed()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = false;
+  
+  const T1* M_local;
+  const T1& M;
+  };
+
+
+
+template<typename T1, bool condition>
+struct partial_unwrap_check_redirect {};
+
+template<typename T1>
+struct partial_unwrap_check_redirect<T1, false> { typedef partial_unwrap_check_default<T1> result; };
+
+template<typename T1>
+struct partial_unwrap_check_redirect<T1, true>  { typedef partial_unwrap_check_fixed<T1>   result; };
+
+template<typename T1>
+struct partial_unwrap_check : public partial_unwrap_check_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  typedef typename T1::elem_type eT;
+  
+  inline partial_unwrap_check(const T1& A, const Mat<eT>& B)
+    : partial_unwrap_check_redirect< T1, is_Mat_fixed<T1>::value >::result(A, B)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< Mat<eT> >
+  {
+  typedef Mat<eT> stored_type;
+
+  arma_hot inline
+  partial_unwrap_check(const Mat<eT>& A, const Mat<eT>& B)
+    : M_local ( (&A == &B) ? new Mat<eT>(A) : 0 )
+    , M       ( (&A == &B) ? (*M_local)     : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = false;
+  
+  // the order below is important
+  const Mat<eT>* M_local;
+  const Mat<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< Row<eT> >
+  {
+  typedef Row<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const Row<eT>& A, const Mat<eT>& B)
+    : M_local ( (&A == &B) ? new Row<eT>(A) : 0 )
+    , M       ( (&A == &B) ? (*M_local)     : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = false;
+  
+  // the order below is important
+  const Row<eT>* M_local;
+  const Row<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< Col<eT> >
+  {
+  typedef Col<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const Col<eT>& A, const Mat<eT>& B)
+    : M_local ( (&A == &B) ? new Col<eT>(A) : 0 )
+    , M       ( (&A == &B) ? (*M_local)     : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = false;
+  
+  // the order below is important
+  const Col<eT>* M_local;
+  const Col<eT>& M;
+  };
+
+
+
+// NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class,
+// NOTE: which relies on partial_unwrap_check to check for aliasing
+template<typename eT>
+struct partial_unwrap_check< subview_col<eT> >
+  {
+  typedef Col<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const subview_col<eT>& A, const Mat<eT>& B)
+    : M  ( const_cast<eT*>( A.colptr(0) ), A.n_rows, (&(A.m) == &B), false )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = false;
+  
+  const Col<eT> M;
+  };
+
+
+
+template<typename T1>
+struct partial_unwrap_check_htrans_default
+  {
+  typedef typename T1::elem_type eT;
+  typedef Mat<eT>                stored_type;
+  
+  inline
+  partial_unwrap_check_htrans_default(const Op<T1, op_htrans>& A, const Mat<eT>&)
+    : M(A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = true;
+  static const bool do_times = false;
+  
+  const Mat<eT> M;
+  };
+
+
+template<typename T1>
+struct partial_unwrap_check_htrans_fixed
+  {
+  typedef typename T1::elem_type eT;
+  typedef T1                     stored_type;
+  
+  inline explicit
+  partial_unwrap_check_htrans_fixed(const Op<T1, op_htrans>& A, const Mat<eT>& B)
+    : M_local( (&(A.m) == &B) ? new T1(A.m) : 0   )
+    , M      ( (&(A.m) == &B) ? (*M_local)  : A.m )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check_htrans_fixed()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = true;
+  static const bool do_times = false;
+  
+  const T1* M_local;
+  const T1& M;
+  };
+
+
+
+template<typename T1, bool condition>
+struct partial_unwrap_check_htrans_redirect {};
+
+template<typename T1>
+struct partial_unwrap_check_htrans_redirect<T1, false> { typedef partial_unwrap_check_htrans_default<T1> result; };
+
+template<typename T1>
+struct partial_unwrap_check_htrans_redirect<T1, true>  { typedef partial_unwrap_check_htrans_fixed<T1>   result; };
+
+
+template<typename T1>
+struct partial_unwrap_check< Op<T1, op_htrans> > : public partial_unwrap_check_htrans_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  typedef typename T1::elem_type eT;
+  
+  inline partial_unwrap_check(const Op<T1, op_htrans>& A, const Mat<eT>& B)
+    : partial_unwrap_check_htrans_redirect< T1, is_Mat_fixed<T1>::value >::result(A, B)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< Op< Mat<eT>, op_htrans> >
+  {
+  typedef Mat<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const Op< Mat<eT>, op_htrans>& A, const Mat<eT>& B)
+    : M_local ( (&A.m == &B) ? new Mat<eT>(A.m) : 0   )
+    , M       ( (&A.m == &B) ? (*M_local)       : A.m )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = true;
+  static const bool do_times = false;
+  
+  // the order below is important
+  const Mat<eT>* M_local;
+  const Mat<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< Op< Row<eT>, op_htrans> >
+  {
+  typedef Row<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const Op< Row<eT>, op_htrans>& A, const Mat<eT>& B)
+    : M_local ( (&A.m == &B) ? new Row<eT>(A.m) : 0   )
+    , M       ( (&A.m == &B) ? (*M_local)       : A.m )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = true;
+  static const bool do_times = false;
+  
+  // the order below is important
+  const Row<eT>* M_local;
+  const Row<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< Op< Col<eT>, op_htrans> >
+  {
+  typedef Col<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const Op< Col<eT>, op_htrans>& A, const Mat<eT>& B)
+    : M_local ( (&A.m == &B) ? new Col<eT>(A.m) : 0   )
+    , M       ( (&A.m == &B) ? (*M_local)       : A.m )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = true;
+  static const bool do_times = false;
+  
+  // the order below is important
+  const Col<eT>* M_local;
+  const Col<eT>& M;
+  };
+
+
+
+// NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class,
+// NOTE: which relies on partial_unwrap_check to check for aliasing
+template<typename eT>
+struct partial_unwrap_check< Op< subview_col<eT>, op_htrans> >
+  {
+  typedef Col<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const Op< subview_col<eT>, op_htrans>& A, const Mat<eT>& B)
+    : M  ( const_cast<eT*>( A.m.colptr(0) ), A.m.n_rows, (&(A.m.m) == &B), false )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(1); }
+  
+  static const bool do_trans = true;
+  static const bool do_times = false;
+  
+  const Col<eT> M;
+  };
+
+
+
+template<typename T1>
+struct partial_unwrap_check_htrans2_default
+  {
+  typedef typename T1::elem_type eT;
+  typedef Mat<eT>                stored_type;
+  
+  inline
+  partial_unwrap_check_htrans2_default(const Op<T1, op_htrans2>& A, const Mat<eT>&)
+    : val(A.aux)
+    , M  (A.m)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = true;
+  static const bool do_times = true;
+  
+  const eT      val;
+  const Mat<eT> M;
+  };
+
+
+
+template<typename T1>
+struct partial_unwrap_check_htrans2_fixed
+  {
+  typedef typename T1::elem_type eT;
+  typedef T1                     stored_type;
+  
+  inline explicit
+  partial_unwrap_check_htrans2_fixed(const Op<T1, op_htrans2>& A, const Mat<eT>& B)
+    : val    (A.aux)
+    , M_local( (&(A.m) == &B) ? new T1(A.m) : 0   )
+    , M      ( (&(A.m) == &B) ? (*M_local)  : A.m )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check_htrans2_fixed()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = true;
+  static const bool do_times = true;
+  
+  const eT  val;
+  const T1* M_local;
+  const T1& M;
+  };
+
+
+
+template<typename T1, bool condition>
+struct partial_unwrap_check_htrans2_redirect {};
+
+template<typename T1>
+struct partial_unwrap_check_htrans2_redirect<T1, false> { typedef partial_unwrap_check_htrans2_default<T1> result; };
+
+template<typename T1>
+struct partial_unwrap_check_htrans2_redirect<T1, true>  { typedef partial_unwrap_check_htrans2_fixed<T1>   result; };
+
+
+template<typename T1>
+struct partial_unwrap_check< Op<T1, op_htrans2> > : public partial_unwrap_check_htrans2_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  typedef typename T1::elem_type eT;
+  
+  inline partial_unwrap_check(const Op<T1, op_htrans2>& A, const Mat<eT>& B)
+    : partial_unwrap_check_htrans2_redirect< T1, is_Mat_fixed<T1>::value >::result(A, B)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< Op< Mat<eT>, op_htrans2> >
+  {
+  typedef Mat<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const Op< Mat<eT>, op_htrans2>& A, const Mat<eT>& B)
+    : val     (A.aux)
+    , M_local ( (&A.m == &B) ? new Mat<eT>(A.m) : 0   )
+    , M       ( (&A.m == &B) ? (*M_local)       : A.m )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = true;
+  static const bool do_times = true;
+  
+  // the order below is important
+  const eT       val;
+  const Mat<eT>* M_local;
+  const Mat<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< Op< Row<eT>, op_htrans2> >
+  {
+  typedef Row<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const Op< Row<eT>, op_htrans2>& A, const Mat<eT>& B)
+    : val     (A.aux)
+    , M_local ( (&A.m == &B) ? new Row<eT>(A.m) : 0   )
+    , M       ( (&A.m == &B) ? (*M_local)       : A.m )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = true;
+  static const bool do_times = true;
+  
+  // the order below is important
+  const eT       val;
+  const Row<eT>* M_local;
+  const Row<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< Op< Col<eT>, op_htrans2> >
+  {
+  typedef Col<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const Op< Col<eT>, op_htrans2>& A, const Mat<eT>& B)
+    : val     (A.aux)
+    , M_local ( (&A.m == &B) ? new Col<eT>(A.m) : 0   )
+    , M       ( (&A.m == &B) ? (*M_local)       : A.m )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = true;
+  static const bool do_times = true;
+  
+  // the order below is important
+  const eT       val;
+  const Col<eT>* M_local;
+  const Col<eT>& M;
+  };
+
+
+
+// NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class,
+// NOTE: which relies on partial_unwrap_check to check for aliasing
+template<typename eT>
+struct partial_unwrap_check< Op< subview_col<eT>, op_htrans2> >
+  {
+  typedef Col<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const Op< subview_col<eT>, op_htrans2>& A, const Mat<eT>& B)
+    : val( A.aux )
+    , M  ( const_cast<eT*>( A.m.colptr(0) ), A.m.n_rows, (&(A.m.m) == &B), false )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = true;
+  static const bool do_times = true;
+  
+  const eT      val;
+  const Col<eT> M;
+  };
+
+
+
+template<typename T1>
+struct partial_unwrap_check_scalar_times_default
+  {
+  typedef typename T1::elem_type eT;
+  typedef Mat<eT>                stored_type;
+  
+  inline
+  partial_unwrap_check_scalar_times_default(const eOp<T1, eop_scalar_times>& A, const Mat<eT>&)
+    : val(A.aux)
+    , M  (A.P.Q)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const eT      val;
+  const Mat<eT> M;
+  };
+
+
+
+template<typename T1>
+struct partial_unwrap_check_scalar_times_fixed
+  {
+  typedef typename T1::elem_type eT;
+  typedef T1                     stored_type;
+  
+  inline explicit
+  partial_unwrap_check_scalar_times_fixed(const eOp<T1, eop_scalar_times>& A, const Mat<eT>& B)
+    : val    ( A.aux )
+    , M_local( (&(A.P.Q) == &B) ? new T1(A.P.Q) : 0     )
+    , M      ( (&(A.P.Q) == &B) ? (*M_local)    : A.P.Q )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check_scalar_times_fixed()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const eT  val;
+  const T1* M_local;
+  const T1& M;
+  };
+
+
+
+template<typename T1, bool condition>
+struct partial_unwrap_check_scalar_times_redirect {};
+
+template<typename T1>
+struct partial_unwrap_check_scalar_times_redirect<T1, false> { typedef partial_unwrap_check_scalar_times_default<T1> result; };
+
+template<typename T1>
+struct partial_unwrap_check_scalar_times_redirect<T1, true>  { typedef partial_unwrap_check_scalar_times_fixed<T1>   result; };
+
+
+template<typename T1>
+struct partial_unwrap_check< eOp<T1, eop_scalar_times> > : public partial_unwrap_check_scalar_times_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  typedef typename T1::elem_type eT;
+  
+  inline partial_unwrap_check(const eOp<T1, eop_scalar_times>& A, const Mat<eT>& B)
+    : partial_unwrap_check_scalar_times_redirect< T1, is_Mat_fixed<T1>::value >::result(A, B)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< eOp<Mat<eT>, eop_scalar_times> >
+  {
+  typedef Mat<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const eOp<Mat<eT>,eop_scalar_times>& A, const Mat<eT>& B)
+    : val    (A.aux)
+    , M_local( (&(A.P.Q) == &B) ? new Mat<eT>(A.P.Q) : 0     )
+    , M      ( (&(A.P.Q) == &B) ? *M_local           : A.P.Q )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const eT       val;
+  const Mat<eT>* M_local;
+  const Mat<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< eOp<Row<eT>, eop_scalar_times> >
+  {
+  typedef Row<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const eOp<Row<eT>,eop_scalar_times>& A, const Mat<eT>& B)
+    : val(A.aux)
+    , M_local( (&(A.P.Q) == &B) ? new Row<eT>(A.P.Q) : 0     )
+    , M      ( (&(A.P.Q) == &B) ? *M_local           : A.P.Q )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const eT       val;
+  const Row<eT>* M_local;
+  const Row<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< eOp<Col<eT>, eop_scalar_times> >
+  {
+  typedef Col<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const eOp<Col<eT>,eop_scalar_times>& A, const Mat<eT>& B)
+    : val    ( A.aux )
+    , M_local( (&(A.P.Q) == &B) ? new Col<eT>(A.P.Q) : 0     )
+    , M      ( (&(A.P.Q) == &B) ? *M_local           : A.P.Q )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const eT       val;
+  const Col<eT>* M_local;
+  const Col<eT>& M;
+  };
+
+
+
+// NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class,
+// NOTE: which relies on partial_unwrap_check to check for aliasing
+template<typename eT>
+struct partial_unwrap_check< eOp<subview_col<eT>, eop_scalar_times> >
+  {
+  typedef Col<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const eOp<subview_col<eT>,eop_scalar_times>& A, const Mat<eT>& B)
+    : val( A.aux )
+    , M  ( const_cast<eT*>( A.P.Q.colptr(0) ), A.P.Q.n_rows, (&(A.P.Q.m) == &B), false )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return val; }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const eT      val;
+  const Col<eT> M;
+  };
+
+
+
+template<typename T1>
+struct partial_unwrap_check_neg_default
+  {
+  typedef typename T1::elem_type eT;
+  typedef Mat<eT>                stored_type;
+  
+  inline
+  partial_unwrap_check_neg_default(const eOp<T1, eop_neg>& A, const Mat<eT>&)
+    : M(A.P.Q)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(-1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const Mat<eT> M;
+  };
+
+
+
+template<typename T1>
+struct partial_unwrap_check_neg_fixed
+  {
+  typedef typename T1::elem_type eT;
+  typedef T1                     stored_type;
+  
+  inline explicit
+  partial_unwrap_check_neg_fixed(const eOp<T1, eop_neg>& A, const Mat<eT>& B)
+    : M_local( (&(A.P.Q) == &B) ? new T1(A.P.Q) : 0     )
+    , M      ( (&(A.P.Q) == &B) ? (*M_local)    : A.P.Q )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check_neg_fixed()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(-1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const T1* M_local;
+  const T1& M;
+  };
+
+
+
+template<typename T1, bool condition>
+struct partial_unwrap_check_neg_redirect {};
+
+template<typename T1>
+struct partial_unwrap_check_neg_redirect<T1, false> { typedef partial_unwrap_check_neg_default<T1> result; };
+
+template<typename T1>
+struct partial_unwrap_check_neg_redirect<T1, true>  { typedef partial_unwrap_check_neg_fixed<T1>   result; };
+
+
+template<typename T1>
+struct partial_unwrap_check< eOp<T1, eop_neg> > : public partial_unwrap_check_neg_redirect<T1, is_Mat_fixed<T1>::value >::result
+  {
+  typedef typename T1::elem_type eT;
+  
+  inline partial_unwrap_check(const eOp<T1, eop_neg>& A, const Mat<eT>& B)
+    : partial_unwrap_check_neg_redirect< T1, is_Mat_fixed<T1>::value >::result(A, B)
+    {
+    }
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< eOp<Mat<eT>, eop_neg> >
+  {
+  typedef Mat<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const eOp<Mat<eT>,eop_neg>& A, const Mat<eT>& B)
+    : M_local( (&(A.P.Q) == &B) ? new Mat<eT>(A.P.Q) : 0     )
+    , M      ( (&(A.P.Q) == &B) ? *M_local           : A.P.Q )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(-1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const Mat<eT>* M_local;
+  const Mat<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< eOp<Row<eT>, eop_neg> >
+  {
+  typedef Row<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const eOp<Row<eT>,eop_neg>& A, const Mat<eT>& B)
+    : M_local( (&(A.P.Q) == &B) ? new Row<eT>(A.P.Q) : 0     )
+    , M      ( (&(A.P.Q) == &B) ? *M_local           : A.P.Q )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(-1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const Row<eT>* M_local;
+  const Row<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct partial_unwrap_check< eOp<Col<eT>, eop_neg> >
+  {
+  typedef Col<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const eOp<Col<eT>,eop_neg>& A, const Mat<eT>& B)
+    : M_local( (&(A.P.Q) == &B) ? new Col<eT>(A.P.Q) : 0     )
+    , M      ( (&(A.P.Q) == &B) ? *M_local           : A.P.Q )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  inline
+  ~partial_unwrap_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local) { delete M_local; }
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(-1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const Col<eT>* M_local;
+  const Col<eT>& M;
+  };
+
+
+
+// NOTE: we can get away with this shortcut as the partial_unwrap_check class is only used by the glue_times class,
+// NOTE: which relies on partial_unwrap_check to check for aliasing
+template<typename eT>
+struct partial_unwrap_check< eOp<subview_col<eT>, eop_neg> >
+  {
+  typedef Col<eT> stored_type;
+  
+  arma_hot inline
+  partial_unwrap_check(const eOp<subview_col<eT>,eop_neg>& A, const Mat<eT>& B)
+    : M  ( const_cast<eT*>( A.P.Q.colptr(0) ), A.P.Q.n_rows, (&(A.P.Q.m) == &B), false )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  arma_hot arma_inline eT get_val() const { return eT(-1); }
+  
+  static const bool do_trans = false;
+  static const bool do_times = true;
+  
+  const Col<eT> M;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/unwrap_cube.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,109 @@
+// Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup unwrap_cube
+//! @{
+
+
+
+template<typename T1>
+class unwrap_cube
+  {
+  public:
+  
+  typedef typename T1::elem_type eT;
+  
+  inline
+  unwrap_cube(const T1& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const Cube<eT> M;
+  };
+
+
+
+template<typename eT>
+class unwrap_cube< Cube<eT> >
+  {
+  public:
+
+  inline
+  unwrap_cube(const Cube<eT>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+
+  const Cube<eT>& M;
+  };
+
+
+
+//
+//
+//
+
+
+
+template<typename T1>
+class unwrap_cube_check
+  {
+  typedef typename T1::elem_type eT;
+  
+  inline
+  unwrap_cube_check(const T1& A, const Cube<eT>&)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    
+    arma_type_check(( is_arma_cube_type<T1>::value == false ));
+    }
+  
+  const Cube<eT> M;
+  };
+
+
+
+template<typename eT>
+class unwrap_cube_check< Cube<eT> >
+  {
+  public:
+
+  inline
+  unwrap_cube_check(const Cube<eT>& A, const Cube<eT>& B)
+    : M_local( (&A == &B) ? new Cube<eT>(A) : 0 )
+    , M      ( (&A == &B) ? (*M_local)      : A )
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  
+  inline
+  ~unwrap_cube_check()
+    {
+    arma_extra_debug_sigprint();
+    
+    if(M_local)
+      {
+      delete M_local;
+      }
+    }
+  
+  
+  // the order below is important
+  const Cube<eT>* M_local;
+  const Cube<eT>& M;
+  
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/unwrap_spmat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,125 @@
+// Copyright (C) 2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup unwrap_spmat
+//! @{
+
+
+
+template<typename T1>
+struct unwrap_spmat
+  {
+  typedef typename T1::elem_type eT;
+  
+  inline
+  unwrap_spmat(const T1& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const SpMat<eT> M;
+  };
+
+
+
+template<typename eT>
+struct unwrap_spmat< SpMat<eT> >
+  {
+  inline
+  unwrap_spmat(const SpMat<eT>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const SpMat<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct unwrap_spmat< SpRow<eT> >
+  {
+  inline
+  unwrap_spmat(const SpRow<eT>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const SpRow<eT>& M;
+  };
+
+
+
+template<typename eT>
+struct unwrap_spmat< SpCol<eT> >
+  {
+  inline
+  unwrap_spmat(const SpCol<eT>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const SpCol<eT>& M;
+  };
+
+
+
+template<typename T1, typename spop_type>
+struct unwrap_spmat< SpOp<T1, spop_type> >
+  {
+  typedef typename T1::elem_type eT;
+  
+  inline
+  unwrap_spmat(const SpOp<T1, spop_type>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const SpMat<eT> M;
+  };
+
+
+
+template<typename T1, typename T2, typename spglue_type>
+struct unwrap_spmat< SpGlue<T1, T2, spglue_type> >
+  {
+  typedef typename T1::elem_type eT;
+  
+  inline
+  unwrap_spmat(const SpGlue<T1, T2, spglue_type>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const SpMat<eT> M;
+  };
+
+
+
+template<typename out_eT, typename T1, typename spop_type>
+struct unwrap_spmat< mtSpOp<out_eT, T1, spop_type> >
+  {
+  inline
+  unwrap_spmat(const mtSpOp<out_eT, T1, spop_type>& A)
+    : M(A)
+    {
+    arma_extra_debug_sigprint();
+    }
+  
+  const SpMat<out_eT> M;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/upgrade_val.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,151 @@
+// Copyright (C) 2009-2010 NICTA (www.nicta.com.au)
+// Copyright (C) 2009-2010 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup upgrade_val
+//! @{
+
+
+
+//! upgrade_val is used to ensure an operation such as multiplication is possible between two types.
+//! values are upgraded only where necessary.
+
+template<typename T1, typename T2>
+struct upgrade_val
+  {
+  typedef typename promote_type<T1,T2>::result T1_result;
+  typedef typename promote_type<T1,T2>::result T2_result;
+  
+  arma_inline
+  static
+  typename promote_type<T1,T2>::result
+  apply(const T1 x)
+    {
+    typedef typename promote_type<T1,T2>::result out_type;
+    return out_type(x);
+    }
+  
+  arma_inline
+  static
+  typename promote_type<T1,T2>::result
+  apply(const T2 x)
+    {
+    typedef typename promote_type<T1,T2>::result out_type;
+    return out_type(x);
+    }
+  
+  };
+
+
+// template<>
+template<typename T>
+struct upgrade_val<T,T>
+  {
+  typedef T T1_result;
+  typedef T T2_result;
+  
+  arma_inline static const T& apply(const T& x) { return x; }
+  };
+
+
+//! upgrade a type to allow multiplication with a complex type
+//! e.g. the int in "int * complex<double>" is upgraded to a double
+// template<>
+template<typename T, typename T2>
+struct upgrade_val< std::complex<T>, T2 >
+  {
+  typedef std::complex<T> T1_result;
+  typedef T               T2_result;
+  
+  arma_inline static const std::complex<T>& apply(const std::complex<T>& x) { return x;    }
+  arma_inline static       T                apply(const T2 x)               { return T(x); }
+  };
+
+
+// template<>
+template<typename T1, typename T>
+struct upgrade_val< T1, std::complex<T> >
+  {
+  typedef T               T1_result;
+  typedef std::complex<T> T2_result;
+  
+  arma_inline static       T                apply(const T1 x)               { return T(x); }
+  arma_inline static const std::complex<T>& apply(const std::complex<T>& x) { return x;    }
+  };
+
+
+//! ensure we don't lose precision when multiplying a complex number with a higher precision real number
+template<>
+struct upgrade_val< std::complex<float>, double >
+  {
+  typedef std::complex<double> T1_result;
+  typedef double               T2_result;
+  
+  arma_inline static const std::complex<double> apply(const std::complex<float>& x) { return std::complex<double>(x); }
+  arma_inline static       double               apply(const double x)               { return x; }
+  };
+
+
+template<>
+struct upgrade_val< double, std::complex<float> >
+  {
+  typedef double              T1_result;
+  typedef std::complex<float> T2_result;
+  
+  arma_inline static       double               apply(const double x)               { return x; }
+  arma_inline static const std::complex<double> apply(const std::complex<float>& x) { return std::complex<double>(x); }
+  };
+
+
+//! ensure we don't lose precision when multiplying complex numbers with different underlying types
+template<>
+struct upgrade_val< std::complex<float>, std::complex<double> >
+  {
+  typedef std::complex<double> T1_result;
+  typedef std::complex<double> T2_result;
+  
+  arma_inline static const std::complex<double>  apply(const std::complex<float>&  x) { return std::complex<double>(x); }
+  arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
+  };
+
+
+template<>
+struct upgrade_val< std::complex<double>, std::complex<float> >
+  {
+  typedef std::complex<double> T1_result;
+  typedef std::complex<double> T2_result;
+  
+  arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
+  arma_inline static const std::complex<double>  apply(const std::complex<float>&  x) { return std::complex<double>(x); }
+  };
+
+
+//! work around limitations in the complex class (at least as present in gcc 4.1 & 4.3)
+template<>
+struct upgrade_val< std::complex<double>, float >
+  {
+  typedef std::complex<double> T1_result;
+  typedef double               T2_result;
+  
+  arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
+  arma_inline static       double                apply(const float x)                 { return double(x); }
+  };
+
+
+template<>
+struct upgrade_val< float, std::complex<double> >
+  {
+  typedef double               T1_result;
+  typedef std::complex<double> T2_result;
+  
+  arma_inline static       double                apply(const float x)                 { return double(x); }
+  arma_inline static const std::complex<double>& apply(const std::complex<double>& x) { return x; }
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/wall_clock_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,42 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup wall_clock
+//! @{
+
+
+//! Class for measuring time intervals
+class wall_clock
+  {
+  public:
+  
+  inline  wall_clock();
+  inline ~wall_clock();
+  
+  inline void   tic();  //!< start the timer
+  inline double toc();  //!< return the number of seconds since the last call to tic()
+  
+  
+  private:
+  
+  bool valid;
+  
+  #if defined(ARMA_USE_BOOST_DATE)
+    boost::posix_time::ptime         boost_time1;
+    boost::posix_time::time_duration boost_duration;
+  #elif defined(ARMA_HAVE_GETTIMEOFDAY)
+    struct timeval posix_time1;
+    struct timeval posix_time2;
+  #else
+    clock_t time1;
+  #endif
+  
+  };
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/wall_clock_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,97 @@
+// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
+// Copyright (C) 2008-2012 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup wall_clock
+//! @{
+
+
+inline
+wall_clock::wall_clock()
+  : valid(false)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+inline
+wall_clock::~wall_clock()
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+inline
+void
+wall_clock::tic()
+  {
+  arma_extra_debug_sigprint();
+  
+  #if defined(ARMA_USE_BOOST_DATE)
+    {
+    boost_time1 = boost::posix_time::microsec_clock::local_time();
+    valid = true;
+    }
+  #elif defined(ARMA_HAVE_GETTIMEOFDAY)
+    {
+    gettimeofday(&posix_time1, 0);
+    valid = true;
+    }
+  #else
+    {
+    time1 = clock();
+    valid = true;
+    }
+  #endif
+  }
+
+
+
+inline
+double
+wall_clock::toc()
+  {
+  arma_extra_debug_sigprint();
+  
+  if(valid)
+    {
+    #if defined(ARMA_USE_BOOST_DATE)
+      {
+      boost_duration = boost::posix_time::microsec_clock::local_time() - boost_time1;
+      return boost_duration.total_microseconds() * 1e-6;
+      }
+    #elif defined(ARMA_HAVE_GETTIMEOFDAY)
+      {
+      gettimeofday(&posix_time2, 0);
+      
+      const double tmp_time1 = posix_time1.tv_sec + posix_time1.tv_usec * 1.0e-6;
+      const double tmp_time2 = posix_time2.tv_sec + posix_time2.tv_usec * 1.0e-6;
+      
+      return tmp_time2 - tmp_time1;
+      }
+    #else
+      {
+      clock_t time2 = clock();
+      
+      clock_t diff = time2 - time1;
+      
+      return double(diff) / double(CLOCKS_PER_SEC);
+      }
+    #endif
+    }
+  else
+    {  
+    return 0.0;
+    }
+  }
+
+
+
+//! @}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/xvec_htrans_bones.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,42 @@
+// Copyright (C) 2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup xvec_htrans
+//! @{
+
+
+template<typename eT>
+class xvec_htrans : public Base<eT, xvec_htrans<eT> >
+  {
+  public:
+  
+  typedef eT                                       elem_type;
+  typedef typename get_pod_type<elem_type>::result pod_type;
+  
+  static const bool is_row = false;
+  static const bool is_col = false;
+  
+  arma_aligned const eT* const mem;
+  
+  const uword n_rows;
+  const uword n_cols;
+  const uword n_elem;
+  
+  
+  inline explicit xvec_htrans(const eT* const in_mem, const uword in_n_rows, const uword in_n_cols);
+  
+  inline void extract(Mat<eT>& out) const;
+  
+  inline eT operator[](const uword ii) const;
+  inline eT at_alt    (const uword ii) const;
+  
+  inline eT at        (const uword in_row, const uword in_col) const;
+  };
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/include/armadillo_bits/xvec_htrans_meat.hpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,79 @@
+// Copyright (C) 2013 Conrad Sanderson
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+//! \addtogroup xvec_htrans
+//! @{
+
+
+template<typename eT>
+inline
+xvec_htrans<eT>::xvec_htrans(const eT* const in_mem, const uword in_n_rows, const uword in_n_cols)
+  : mem   (in_mem             )
+  , n_rows(in_n_cols          )  // deliberately swapped
+  , n_cols(in_n_rows          )
+  , n_elem(in_n_rows*in_n_cols)
+  {
+  arma_extra_debug_sigprint();
+  }
+
+
+
+template<typename eT>
+inline
+void
+xvec_htrans<eT>::extract(Mat<eT>& out) const
+  {
+  arma_extra_debug_sigprint();
+  
+  // NOTE: this function assumes that matrix 'out' has already been set to the correct size
+  
+  const eT*  in_mem = mem;
+        eT* out_mem = out.memptr();
+  
+  const uword N = n_elem;
+  
+  for(uword ii=0; ii < N; ++ii)
+    {
+    out_mem[ii] = access::alt_conj( in_mem[ii] );
+    }
+  }
+
+
+
+template<typename eT>
+inline
+eT
+xvec_htrans<eT>::operator[](const uword ii) const
+  {
+  return access::alt_conj( mem[ii] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+xvec_htrans<eT>::at_alt(const uword ii) const
+  {
+  return access::alt_conj( mem[ii] );
+  }
+
+
+
+template<typename eT>
+inline
+eT
+xvec_htrans<eT>::at(const uword in_row, const uword in_col) const
+  {
+  //return (n_rows == 1) ? access::alt_conj( mem[in_col] ) : access::alt_conj( mem[in_row] );
+  
+  return access::alt_conj( mem[in_row + in_col] );  // either in_row or in_col must be zero, as we're storing a vector
+  }
+
+
+
+//! @}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/index.html	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,19 @@
+<html>
+<body>
+<br>
+<ul>
+<li><a href="README.txt">README.txt</a></li>
+<li><a href="LICENSE.txt">LICENSE.txt</a></li>
+</ul>
+<ul>
+<li>API Reference / Documentation: <a href="docs.html">docs.html</a>  (local copy)</li>
+<li>Technical Report: <a href="armadillo_nicta_2010.pdf">armadillo_nicta_2010.pdf</a> (local copy)</li>
+<li>Related paper: <a href="rcpp_armadillo_csda_2013.pdf">rcpp_armadillo_csda_2013.pdf</a>  (local copy)</li>
+</ul>
+<ul>
+<li>API Reference / Documentation: <a href="http://arma.sourceforge.net/docs.html">docs.html</a> (online copy)</li>
+<li>Technical Report: <a href="http://arma.sourceforge.net/armadillo_nicta_2010.pdf">armadillo_nicta_2010.pdf</a> (online copy)</li>
+<li>Related paper: <a href="http://arma.sourceforge.net/rcpp_armadillo_csda_2013.pdf">rcpp_armadillo_csda_2013.pdf</a> (online copy)</li>
+</ul>
+</body>
+</html>
Binary file armadillo-3.900.4/rcpp_armadillo_csda_2013.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/armadillo-3.900.4/src/wrap_libs.cpp	Thu Jun 13 10:25:24 2013 +0100
@@ -0,0 +1,671 @@
+#include "armadillo_bits/config.hpp"
+#include "armadillo_bits/typedef_blas_int.hpp"
+
+#undef ARMA_USE_WRAPPER
+#include "armadillo_bits/compiler_setup.hpp"
+
+#include "armadillo_bits/undefine_conflicts.hpp"
+#include "armadillo_bits/include_atlas.hpp"
+
+
+namespace arma
+{
+
+#include "armadillo_bits/blas_bones.hpp"
+#include "armadillo_bits/lapack_bones.hpp"
+
+// at this stage we have prototypes for the real blas, lapack and atlas functions
+
+// now we make the wrapper functions
+
+
+extern "C"
+  {
+  #if defined(ARMA_USE_BLAS)
+    
+    float arma_fortran_prefix(arma_sdot)(blas_int* n, const float*  x, blas_int* incx, const float*  y, blas_int* incy)
+      {
+      return arma_fortran_noprefix(arma_sdot)(n, x, incx, y, incy);
+      }
+    
+    double arma_fortran_prefix(arma_ddot)(blas_int* n, const double* x, blas_int* incx, const double* y, blas_int* incy)
+      {
+      return arma_fortran_noprefix(arma_ddot)(n, x, incx, y, incy);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_sgemv)(const char* transA, const blas_int* m, const blas_int* n, const float*  alpha, const float*  A, const blas_int* ldA, const float*  x, const blas_int* incx, const float*  beta, float*  y, const blas_int* incy)
+      {
+      arma_fortran_noprefix(arma_sgemv)(transA, m, n, alpha, A, ldA, x, incx, beta, y, incy);
+      }
+    
+    void arma_fortran_prefix(arma_dgemv)(const char* transA, const blas_int* m, const blas_int* n, const double* alpha, const double* A, const blas_int* ldA, const double* x, const blas_int* incx, const double* beta, double* y, const blas_int* incy)
+      {
+      arma_fortran_noprefix(arma_dgemv)(transA, m, n, alpha, A, ldA, x, incx, beta, y, incy);
+      }
+    
+    void arma_fortran_prefix(arma_cgemv)(const char* transA, const blas_int* m, const blas_int* n, const void*   alpha, const void*   A, const blas_int* ldA, const void*   x, const blas_int* incx, const void*   beta, void*   y, const blas_int* incy)
+      {
+      arma_fortran_noprefix(arma_cgemv)(transA, m, n, alpha, A, ldA, x, incx, beta, y, incy);
+      }
+    
+    void arma_fortran_prefix(arma_zgemv)(const char* transA, const blas_int* m, const blas_int* n, const void*   alpha, const void*   A, const blas_int* ldA, const void*   x, const blas_int* incx, const void*   beta, void*   y, const blas_int* incy)
+      {
+      arma_fortran_noprefix(arma_zgemv)(transA, m, n, alpha, A, ldA, x, incx, beta, y, incy);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_sgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const float*  alpha, const float*  A, const blas_int* ldA, const float*  B, const blas_int* ldB, const float*  beta, float*  C, const blas_int* ldC)
+      {
+      arma_fortran_noprefix(arma_sgemm)(transA, transB, m, n, k, alpha, A, ldA, B, ldB, beta, C, ldC);
+      }
+    
+    void arma_fortran_prefix(arma_dgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const double* alpha, const double* A, const blas_int* ldA, const double* B, const blas_int* ldB, const double* beta, double* C, const blas_int* ldC)
+      {
+      arma_fortran_noprefix(arma_dgemm)(transA, transB, m, n, k, alpha, A, ldA, B, ldB, beta, C, ldC);
+      }
+    
+    void arma_fortran_prefix(arma_cgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const void*   alpha, const void*   A, const blas_int* ldA, const void*   B, const blas_int* ldB, const void*   beta, void*   C, const blas_int* ldC)
+      {
+      arma_fortran_noprefix(arma_cgemm)(transA, transB, m, n, k, alpha, A, ldA, B, ldB, beta, C, ldC);
+      }
+    
+    void arma_fortran_prefix(arma_zgemm)(const char* transA, const char* transB, const blas_int* m, const blas_int* n, const blas_int* k, const void*   alpha, const void*   A, const blas_int* ldA, const void*   B, const blas_int* ldB, const void*   beta, void*   C, const blas_int* ldC)
+      {
+      arma_fortran_noprefix(arma_zgemm)(transA, transB, m, n, k, alpha, A, ldA, B, ldB, beta, C, ldC);
+      }
+    
+  #endif
+  
+  
+  
+  #if defined(ARMA_USE_LAPACK)
+    
+    void arma_fortran_prefix(arma_sgetrf)(blas_int* m, blas_int* n,  float* a, blas_int* lda, blas_int* ipiv, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_sgetrf)(m, n, a, lda, ipiv, info);
+      }
+    
+    void arma_fortran_prefix(arma_dgetrf)(blas_int* m, blas_int* n, double* a, blas_int* lda, blas_int* ipiv, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dgetrf)(m, n, a, lda, ipiv, info);
+      }
+
+    void arma_fortran_prefix(arma_cgetrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda, blas_int* ipiv, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cgetrf)(m, n, a, lda, ipiv, info);
+      }
+    
+    void arma_fortran_prefix(arma_zgetrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda, blas_int* ipiv, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zgetrf)(m, n, a, lda, ipiv, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_sgetri)(blas_int* n,  float* a, blas_int* lda, blas_int* ipiv,  float* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_sgetri)(n, a, lda, ipiv, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_dgetri)(blas_int* n, double* a, blas_int* lda, blas_int* ipiv, double* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dgetri)(n, a, lda, ipiv, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_cgetri)(blas_int* n,  void*  a, blas_int* lda, blas_int* ipiv,   void* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cgetri)(n, a, lda, ipiv, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_zgetri)(blas_int* n,  void*  a, blas_int* lda, blas_int* ipiv,   void* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zgetri)(n, a, lda, ipiv, work, lwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_strtri)(char* uplo, char* diag, blas_int* n,  float* a, blas_int* lda, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_strtri)(uplo, diag, n, a, lda, info);
+      }
+    
+    void arma_fortran_prefix(arma_dtrtri)(char* uplo, char* diag, blas_int* n, double* a, blas_int* lda, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dtrtri)(uplo, diag, n, a, lda, info);
+      }
+    
+    void arma_fortran_prefix(arma_ctrtri)(char* uplo, char* diag, blas_int* n,   void* a, blas_int* lda, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_ctrtri)(uplo, diag, n, a, lda, info);
+      }
+    
+    void arma_fortran_prefix(arma_ztrtri)(char* uplo, char* diag, blas_int* n,   void* a, blas_int* lda, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_ztrtri)(uplo, diag, n, a, lda, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_ssyev)(char* jobz, char* uplo, blas_int* n,  float* a, blas_int* lda,  float* w,  float* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_ssyev)(jobz, uplo, n, a, lda, w, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_dsyev)(char* jobz, char* uplo, blas_int* n, double* a, blas_int* lda, double* w, double* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dsyev)(jobz, uplo, n, a, lda, w, work, lwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_cheev)(char* jobz, char* uplo, blas_int* n,   void* a, blas_int* lda,  float* w,   void* work, blas_int* lwork,  float* rwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cheev)(jobz, uplo, n, a, lda, w, work, lwork, rwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_zheev)(char* jobz, char* uplo, blas_int* n,   void* a, blas_int* lda, double* w,   void* work, blas_int* lwork, double* rwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zheev)(jobz, uplo, n, a, lda, w, work, lwork, rwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_ssyevd)(char* jobz, char* uplo, blas_int* n,  float* a, blas_int* lda,  float* w,  float* work, blas_int* lwork, blas_int* iwork, blas_int* liwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_ssyevd)(jobz, uplo, n, a, lda, w, work, lwork, iwork, liwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_dsyevd)(char* jobz, char* uplo, blas_int* n, double* a, blas_int* lda, double* w, double* work, blas_int* lwork, blas_int* iwork, blas_int* liwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dsyevd)(jobz, uplo, n, a, lda, w, work, lwork, iwork, liwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_cheevd)(char* jobz, char* uplo, blas_int* n,   void* a, blas_int* lda,  float* w,   void* work, blas_int* lwork,  float* rwork, blas_int* lrwork, blas_int* iwork, blas_int* liwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cheevd)(jobz, uplo, n, a, lda, w, work, lwork, rwork, lrwork, iwork, liwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_zheevd)(char* jobz, char* uplo, blas_int* n,   void* a, blas_int* lda, double* w,   void* work, blas_int* lwork, double* rwork, blas_int* lrwork, blas_int* iwork, blas_int* liwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zheevd)(jobz, uplo, n, a, lda, w, work, lwork, rwork, lrwork, iwork, liwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_sgeev)(char* jobvl, char* jobvr, blas_int* n,  float* a, blas_int* lda,  float* wr,  float* wi,  float* vl, blas_int* ldvl,  float* vr, blas_int* ldvr,  float* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_sgeev)(jobvl, jobvr, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_dgeev)(char* jobvl, char* jobvr, blas_int* n, double* a, blas_int* lda, double* wr, double* wi, double* vl, blas_int* ldvl, double* vr, blas_int* ldvr, double* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dgeev)(jobvl, jobvr, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_cgeev)(char* jobvl, char* jobvr, blas_int* n, void* a, blas_int* lda, void* w, void* vl, blas_int* ldvl, void* vr, blas_int* ldvr, void* work, blas_int* lwork,  float* rwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cgeev)(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_zgeev)(char* jobvl, char* jobvr, blas_int* n, void* a, blas_int* lda, void* w, void* vl, blas_int* ldvl, void* vr, blas_int* ldvr, void* work, blas_int* lwork, double* rwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zgeev)(jobvl, jobvr, n, a, lda, w, vl, ldvl, vr, ldvr, work, lwork, rwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_spotrf)(char* uplo, blas_int* n,  float* a, blas_int* lda, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_spotrf)(uplo, n, a, lda, info);
+      }
+    
+    void arma_fortran_prefix(arma_dpotrf)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dpotrf)(uplo, n, a, lda, info);
+      }
+    
+    void arma_fortran_prefix(arma_cpotrf)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cpotrf)(uplo, n, a, lda, info);
+      }
+    
+    void arma_fortran_prefix(arma_zpotrf)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zpotrf)(uplo, n, a, lda, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_spotri)(char* uplo, blas_int* n,  float* a, blas_int* lda, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_spotri)(uplo, n, a, lda, info);
+      }
+    
+    void arma_fortran_prefix(arma_dpotri)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dpotri)(uplo, n, a, lda, info);
+      }
+    
+    void arma_fortran_prefix(arma_cpotri)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cpotri)(uplo, n, a, lda, info);
+      }
+    
+    void arma_fortran_prefix(arma_zpotri)(char* uplo, blas_int* n,   void* a, blas_int* lda, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zpotri)(uplo, n, a, lda, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_sgeqrf)(blas_int* m, blas_int* n,  float* a, blas_int* lda,  float* tau,  float* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_sgeqrf)(m, n, a, lda, tau, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_dgeqrf)(blas_int* m, blas_int* n, double* a, blas_int* lda, double* tau, double* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dgeqrf)(m, n, a, lda, tau, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_cgeqrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cgeqrf)(m, n, a, lda, tau, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_zgeqrf)(blas_int* m, blas_int* n,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zgeqrf)(m, n, a, lda, tau, work, lwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_sorgqr)(blas_int* m, blas_int* n, blas_int* k,  float* a, blas_int* lda,  float* tau,  float* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_sorgqr)(m, n, k, a, lda, tau, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_dorgqr)(blas_int* m, blas_int* n, blas_int* k, double* a, blas_int* lda, double* tau, double* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dorgqr)(m, n, k, a, lda, tau, work, lwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_cungqr)(blas_int* m, blas_int* n, blas_int* k,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cungqr)(m, n, k, a, lda, tau, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_zungqr)(blas_int* m, blas_int* n, blas_int* k,   void* a, blas_int* lda,   void* tau,   void* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zungqr)(m, n, k, a, lda, tau, work, lwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_sgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, float*  a, blas_int* lda, float*  s, float*  u, blas_int* ldu, float*  vt, blas_int* ldvt, float*  work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_sgesvd)(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_dgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, double* a, blas_int* lda, double* s, double* u, blas_int* ldu, double* vt, blas_int* ldvt, double* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dgesvd)(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_cgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, void*   a, blas_int* lda, float*  s, void*   u, blas_int* ldu, void*   vt, blas_int* ldvt, void*   work, blas_int* lwork, float*  rwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cgesvd)(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_zgesvd)(char* jobu, char* jobvt, blas_int* m, blas_int* n, void*   a, blas_int* lda, double* s, void*   u, blas_int* ldu, void*   vt, blas_int* ldvt, void*   work, blas_int* lwork, double* rwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zgesvd)(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_sgesdd)(char* jobz, blas_int* m, blas_int* n, float*  a, blas_int* lda, float*  s, float*  u, blas_int* ldu, float*  vt, blas_int* ldvt, float*  work, blas_int* lwork, blas_int* iwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_sgesdd)(jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, iwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_dgesdd)(char* jobz, blas_int* m, blas_int* n, double* a, blas_int* lda, double* s, double* u, blas_int* ldu, double* vt, blas_int* ldvt, double* work, blas_int* lwork, blas_int* iwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dgesdd)(jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, iwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_cgesdd)(char* jobz, blas_int* m, blas_int* n, void* a, blas_int* lda, float*  s, void* u, blas_int* ldu, void* vt, blas_int* ldvt, void* work, blas_int* lwork, float*  rwork, blas_int* iwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cgesdd)(jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, iwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_zgesdd)(char* jobz, blas_int* m, blas_int* n, void* a, blas_int* lda, double* s, void* u, blas_int* ldu, void* vt, blas_int* ldvt, void* work, blas_int* lwork, double* rwork, blas_int* iwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zgesdd)(jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, iwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_sgesv)(blas_int* n, blas_int* nrhs, float*  a, blas_int* lda, blas_int* ipiv, float*  b, blas_int* ldb, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_sgesv)(n, nrhs, a, lda, ipiv, b, ldb, info);
+      }
+    
+    void arma_fortran_prefix(arma_dgesv)(blas_int* n, blas_int* nrhs, double* a, blas_int* lda, blas_int* ipiv, double* b, blas_int* ldb, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dgesv)(n, nrhs, a, lda, ipiv, b, ldb, info);
+      }
+    
+    void arma_fortran_prefix(arma_cgesv)(blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, blas_int* ipiv, void*   b, blas_int* ldb, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cgesv)(n, nrhs, a, lda, ipiv, b, ldb, info);
+      }
+    
+    void arma_fortran_prefix(arma_zgesv)(blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, blas_int* ipiv, void*   b, blas_int* ldb, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zgesv)(n, nrhs, a, lda, ipiv, b, ldb, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_sgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, float*  a, blas_int* lda, float*  b, blas_int* ldb, float*  work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_sgels)(trans, m, n, nrhs, a, lda, b, ldb, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_dgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, double* a, blas_int* lda, double* b, blas_int* ldb, double* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dgels)(trans, m, n, nrhs, a, lda, b, ldb, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_cgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, void*   b, blas_int* ldb, void*   work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cgels)(trans, m, n, nrhs, a, lda, b, ldb, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_zgels)(char* trans, blas_int* m, blas_int* n, blas_int* nrhs, void*   a, blas_int* lda, void*   b, blas_int* ldb, void*   work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zgels)(trans, m, n, nrhs, a, lda, b, ldb, work, lwork, info);
+      }
+    
+    
+    
+    
+    void arma_fortran_prefix(arma_strtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const float*  a, blas_int* lda, float*  b, blas_int* ldb, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_strtrs)(uplo, trans, diag, n, nrhs, a, lda, b, ldb, info);
+      }
+    
+    void arma_fortran_prefix(arma_dtrtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const double* a, blas_int* lda, double* b, blas_int* ldb, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dtrtrs)(uplo, trans, diag, n, nrhs, a, lda, b, ldb, info);
+      }
+    
+    void arma_fortran_prefix(arma_ctrtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const void*   a, blas_int* lda, void*   b, blas_int* ldb, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_ctrtrs)(uplo, trans, diag, n, nrhs, a, lda, b, ldb, info);
+      }
+    
+    void arma_fortran_prefix(arma_ztrtrs)(char* uplo, char* trans, char* diag, blas_int* n, blas_int* nrhs, const void*   a, blas_int* lda, void*   b, blas_int* ldb, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_ztrtrs)(uplo, trans, diag, n, nrhs, a, lda, b, ldb, info);
+      }
+    
+    
+    
+    
+    void arma_fortran_prefix(arma_sgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, float*  a, blas_int* lda, blas_int* sdim, float*  wr, float*  wi, float*  vs, blas_int* ldvs, float*  work, blas_int* lwork, blas_int* bwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_sgees)(jobvs, sort, select, n, a, lda, sdim, wr, wi, vs, ldvs, work, lwork, bwork, info);
+      }
+      
+    void arma_fortran_prefix(arma_dgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, double* a, blas_int* lda, blas_int* sdim, double* wr, double* wi, double* vs, blas_int* ldvs, double* work, blas_int* lwork, blas_int* bwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dgees)(jobvs, sort, select, n, a, lda, sdim, wr, wi, vs, ldvs, work, lwork, bwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_cgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, void* a, blas_int* lda, blas_int* sdim, void* w, void* vs, blas_int* ldvs, void* work, blas_int* lwork, float*  rwork, blas_int* bwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_cgees)(jobvs, sort, select, n, a, lda, sdim, w, vs, ldvs, work, lwork, rwork, bwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_zgees)(char* jobvs, char* sort, blas_int* select, blas_int* n, void* a, blas_int* lda, blas_int* sdim, void* w, void* vs, blas_int* ldvs, void* work, blas_int* lwork, double* rwork, blas_int* bwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zgees)(jobvs, sort, select, n, a, lda, sdim, w, vs, ldvs, work, lwork, rwork, bwork, info);
+      }
+    
+    
+    
+    void arma_fortran_prefix(arma_strsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const float*  a, blas_int* lda, const float*  b, blas_int* ldb, float*  c, blas_int* ldc, float*  scale, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_strsyl)(transa, transb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, info);
+      }
+    
+    void arma_fortran_prefix(arma_dtrsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const double* a, blas_int* lda, const double* b, blas_int* ldb, double* c, blas_int* ldc, double* scale, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dtrsyl)(transa, transb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, info);
+      }
+    
+    void arma_fortran_prefix(arma_ctrsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const void*   a, blas_int* lda, const void*   b, blas_int* ldb, void*   c, blas_int* ldc, float*  scale, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_ctrsyl)(transa, transb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, info);
+      }
+    
+    void arma_fortran_prefix(arma_ztrsyl)(char* transa, char* transb, blas_int* isgn, blas_int* m, blas_int* n, const void*   a, blas_int* lda, const void*   b, blas_int* ldb, void*   c, blas_int* ldc, double* scale, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_ztrsyl)(transa, transb, isgn, m, n, a, lda, b, ldb, c, ldc, scale, info);
+      }
+    
+    
+    
+    
+    void arma_fortran_prefix(arma_ssytrf)(char* uplo, blas_int* n, float*  a, blas_int* lda, blas_int* ipiv, float*  work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_ssytrf)(uplo, n, a, lda, ipiv, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_dsytrf)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* ipiv, double* work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dsytrf)(uplo, n, a, lda, ipiv, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_csytrf)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_csytrf)(uplo, n, a, lda, ipiv, work, lwork, info);
+      }
+    
+    void arma_fortran_prefix(arma_zsytrf)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* lwork, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zsytrf)(uplo, n, a, lda, ipiv, work, lwork, info);
+      }
+    
+    
+    
+    
+    void arma_fortran_prefix(arma_ssytri)(char* uplo, blas_int* n, float*  a, blas_int* lda, blas_int* ipiv, float*  work, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_ssytri)(uplo, n, a, lda, ipiv, work, info);
+      }
+    
+    void arma_fortran_prefix(arma_dsytri)(char* uplo, blas_int* n, double* a, blas_int* lda, blas_int* ipiv, double* work, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_dsytri)(uplo, n, a, lda, ipiv, work, info);
+      }
+    
+    void arma_fortran_prefix(arma_csytri)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_csytri)(uplo, n, a, lda, ipiv, work, info);
+      }
+    
+    void arma_fortran_prefix(arma_zsytri)(char* uplo, blas_int* n, void*   a, blas_int* lda, blas_int* ipiv, void*   work, blas_int* info)
+      {
+      arma_fortran_noprefix(arma_zsytri)(uplo, n, a, lda, ipiv, work, info);
+      }
+    
+  #endif
+  
+  
+  
+  #if defined(ARMA_USE_ATLAS)
+    
+    float wrapper_cblas_sdot(const int N, const float  *X, const int incX, const float  *Y, const int incY)
+      {
+      return      cblas_sdot(N, X, incX, Y, incY);
+      }
+    
+    double wrapper_cblas_ddot(const int N, const double *X, const int incX, const double *Y, const int incY)
+      {
+      return       cblas_ddot(N, X, incX, Y, incY);
+      }
+    
+    void wrapper_cblas_cdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu)
+      {
+                 cblas_cdotu_sub(N, X, incX, Y, incY, dotu);
+      }
+    
+    void wrapper_cblas_zdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu)
+      {
+                 cblas_zdotu_sub(N, X, incX, Y, incY, dotu);
+      }
+    
+    
+    
+    void wrapper_cblas_sgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const float alpha,
+                             const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY)
+      {
+                 cblas_sgemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
+      }
+    
+    void wrapper_cblas_dgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const double alpha,
+                             const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY)
+      {
+                 cblas_dgemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
+      }
+    
+    void wrapper_cblas_cgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha,
+                             const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY)
+      {
+                 cblas_cgemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
+      }
+    
+    void wrapper_cblas_zgemv(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha,
+                             const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY)
+      {
+                 cblas_zgemv(Order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY);
+      }
+    
+    
+    
+    void wrapper_cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
+                             const int M, const int N, const int K, const float alpha,
+                             const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc)
+      {
+                 cblas_sgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
+      }
+    
+    void wrapper_cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
+                             const int M, const int N, const int K, const double alpha,
+                             const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc)
+      {
+                 cblas_dgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
+      }
+    
+    void wrapper_cblas_cgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
+                             const int M, const int N, const int K, const void *alpha,
+                             const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc)
+      {
+                 cblas_cgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
+      }
+    
+    void wrapper_cblas_zgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB,
+                             const int M, const int N, const int K, const void *alpha,
+                             const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc)
+      {
+                 cblas_zgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
+      }
+    
+    
+    
+    int wrapper_clapack_sgetrf(const enum CBLAS_ORDER Order, const int M, const int N, float  *A, const int lda, int *ipiv)
+      {
+      return    clapack_sgetrf(Order, M, N, A, lda, ipiv);
+      }
+    
+    int wrapper_clapack_dgetrf(const enum CBLAS_ORDER Order, const int M, const int N, double *A, const int lda, int *ipiv)
+      {
+      return    clapack_dgetrf(Order, M, N, A, lda, ipiv);
+      }
+    
+    int wrapper_clapack_cgetrf(const enum CBLAS_ORDER Order, const int M, const int N, void   *A, const int lda, int *ipiv)
+      {
+      return    clapack_cgetrf(Order, M, N, A, lda, ipiv);
+      }
+    
+    int wrapper_clapack_zgetrf(const enum CBLAS_ORDER Order, const int M, const int N, void   *A, const int lda, int *ipiv)
+      {
+      return    clapack_zgetrf(Order, M, N, A, lda, ipiv);
+      }
+    
+    
+    
+    int wrapper_clapack_sgetri(const enum CBLAS_ORDER Order, const int N, float  *A, const int lda, const int *ipiv)
+      {
+      return    clapack_sgetri(Order, N, A, lda, ipiv);
+      }
+    
+    int wrapper_clapack_dgetri(const enum CBLAS_ORDER Order, const int N, double *A, const int lda, const int *ipiv)
+      {
+      return    clapack_dgetri(Order, N, A, lda, ipiv);
+      }
+    
+    int wrapper_clapack_cgetri(const enum CBLAS_ORDER Order, const int N, void   *A, const int lda, const int *ipiv)
+      {
+      return    clapack_cgetri(Order, N, A, lda, ipiv);
+      }
+    
+    int wrapper_clapack_zgetri(const enum CBLAS_ORDER Order, const int N, void   *A, const int lda, const int *ipiv)
+      {
+      return    clapack_zgetri(Order, N, A, lda, ipiv);
+      }
+    
+    
+    
+    int wrapper_clapack_sgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, float  *A, const int lda, int *ipiv, float  *B, const int ldb)
+      {
+      return    clapack_sgesv(Order, N, NRHS, A, lda, ipiv, B, ldb);
+      }
+    
+    int wrapper_clapack_dgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, double *A, const int lda, int *ipiv, double *B, const int ldb)
+      {
+      return    clapack_dgesv(Order, N, NRHS, A, lda, ipiv, B, ldb);
+      }
+    
+    int wrapper_clapack_cgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, void   *A, const int lda, int *ipiv, void   *B, const int ldb)
+      {
+      return    clapack_cgesv(Order, N, NRHS, A, lda, ipiv, B, ldb);
+      }
+    
+    int wrapper_clapack_zgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS, void   *A, const int lda, int *ipiv, void   *B, const int ldb)
+      {
+      return    clapack_zgesv(Order, N, NRHS, A, lda, ipiv, B, ldb);
+      }
+    
+  #endif
+  }
+
+}
--- a/lib_win32/README.txt	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-The lib and dll files in this folder are for 32 bit Windows XP.
-They are compiled versions of the BLAS and LAPACK libraries,
-which are distributed under a BSD license.
-
-The compiled versions were downloaded from:
-http://www.fi.muni.cz/~xsvobod2/misc/lapack/
-
-Sources for BLAS and LAPACK can be found at:
-http://www.netlib.org/blas/
-http://www.netlib.org/lapack/
Binary file lib_win32/blas_win32_MT.dll has changed
Binary file lib_win32/blas_win32_MT.lib has changed
Binary file lib_win32/lapack_win32_MT.dll has changed
Binary file lib_win32/lapack_win32_MT.lib has changed
--- a/segmentino/Makefile.linux64	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-
-#CFLAGS := -O3 -fPIC -ftree-vectorize -I../armadillo-2.4.4/include -I../../vamp-plugin-sdk -I../../qm-dsp
-
-CFLAGS := -Wall -g -fPIC -I../armadillo-2.4.4/include -I../../vamp-plugin-sdk -I../../qm-dsp
-
-CXXFLAGS  := $(CFLAGS)
-
-LDFLAGS	  := -shared -Wl,-Bstatic -L../../qm-dsp -lqm-dsp -lvamp-sdk -Lbuild/linux/amd64 -llapack -lcblas -lf77blas -latlas -Wl,-Bdynamic 
-
-PLUGIN_EXT   := .so
-
-include build/general/Makefile.inc
-
--- a/segmentino/Makefile_ORIGINAL.osx	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-
-CFLAGS := -O3 -ftree-vectorize -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk -arch i386 -arch x86_64 -I../vamp-plugin-sdk -I/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/Headers/ -DUSE_PTHREADS
-
-CXXFLAGS  := $(CFLAGS)
-
-LDFLAGS	  := -isysroot /Developer/SDKs/MacOSX10.7.sdk -arch i386 -arch x86_64 -lqm-dsp ../vamp-plugin-sdk/libvamp-sdk.a -larmadillo -dynamiclib -framework Accelerate -lpthread -install_name qm-vamp-plugins.dylib
-
-PLUGIN_EXT   := .dylib
-
-include build/general/Makefile.inc
-
--- a/segmentino/Segmentino.cpp	Thu Jun 13 09:43:01 2013 +0100
+++ b/segmentino/Segmentino.cpp	Thu Jun 13 10:25:24 2013 +0100
@@ -17,18 +17,22 @@
 
 #include "Segmentino.h"
 
-#include <base/Window.h>
-#include <dsp/onsets/DetectionFunction.h>
-#include <dsp/onsets/PeakPicking.h>
-#include <dsp/transforms/FFT.h>
-#include <dsp/tempotracking/TempoTrackV2.h>
-#include <dsp/tempotracking/DownBeat.h>
-#include <chromamethods.h>
-#include <maths/MathUtilities.h>
+#include <qm-dsp/base/Window.h>
+#include <qm-dsp/dsp/onsets/DetectionFunction.h>
+#include <qm-dsp/dsp/onsets/PeakPicking.h>
+#include <qm-dsp/dsp/transforms/FFT.h>
+#include <qm-dsp/dsp/tempotracking/TempoTrackV2.h>
+#include <qm-dsp/dsp/tempotracking/DownBeat.h>
+#include <qm-dsp/maths/MathUtilities.h>
+
+#include <nnls-chroma/chromamethods.h>
+
 #include <boost/numeric/ublas/matrix.hpp>
 #include <boost/numeric/ublas/io.hpp>
 #include <boost/math/distributions/normal.hpp>
-#include "armadillo"
+
+#include <armadillo>
+
 #include <fstream>
 #include <sstream>
 #include <cmath>
@@ -770,7 +774,9 @@
     }
 
     FeatureSet masterFeatureset = beatTrack();
-    Vamp::RealTime last_beattime = masterFeatureset[m_beatOutputNumber][masterFeatureset[m_beatOutputNumber].size()-1].timestamp;
+    int beatcount = masterFeatureset[m_beatOutputNumber].size();
+    if (beatcount == 0) return Segmentino::FeatureSet();
+    Vamp::RealTime last_beattime = masterFeatureset[m_beatOutputNumber][beatcount-1].timestamp;
     masterFeatureset[m_beatOutputNumber].clear();
     Vamp::RealTime beattime = Vamp::RealTime::fromSeconds(1.0);
     while (beattime < last_beattime)
--- a/segmentino/SongParts/BeatTrackerData.cpp	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-
-/*
-    QM Vamp Plugin Set
-
-    Centre for Digital Music, Queen Mary, University of London.
-
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License as
-    published by the Free Software Foundation; either version 2 of the
-    License, or (at your option) any later version.  See the file
-    COPYING included with this distribution for more information.
-*/
-
-//#include "SongParts.h"
-
-#include "BeatTrackerData.h"
-
-//#include <base/Window.h>
-#include <dsp/onsets/DetectionFunction.h>
-//#include <dsp/onsets/PeakPicking.h>
-//#include <dsp/transforms/FFT.h>
-//#include <dsp/tempotracking/TempoTrackV2.h>
-//#include <dsp/tempotracking/DownBeat.h>
-//#include <chromamethods.h>
-//#include <maths/MathUtilities.h>
-
-// #include <vamp-sdk/Plugin.h>
-
-using std::string;
-using std::vector;
-using std::cerr;
-using std::endl;
-
-
-//#ifndef __GNUC__
-//#include <alloca.h>
-//#endif
-
-
-/* ------------------------------------ */
-/* ----- BEAT DETECTOR CLASS ---------- */
-/* ------------------------------------ */
-
-
-/* --- ATTRIBUTES --- */
-private:
-DFConfig dfConfig;
-DetectionFunction *df;
-DownBeat *downBeat;
-vector<double> dfOutput;
-Vamp::RealTime origin;
-
-
-/* --- METHODS --- */
-
-/* --- Constructor --- */
-public:
-BeatTrackerData(float rate, const DFConfig &config) : dfConfig(config) {
-
-    df = new DetectionFunction(config);
-    // decimation factor aims at resampling to c. 3KHz; must be power of 2
-    int factor = MathUtilities::nextPowerOfTwo(rate / 3000);
-    // std::cerr << "BeatTrackerData: factor = " << factor << std::endl;
-    downBeat = new DownBeat(rate, factor, config.stepSize);
-}
-
-/* --- Desctructor --- */
-~BeatTrackerData() {
-delete df;
-    delete downBeat;
-}
-
-void reset() {
-    delete df;
-    df = new DetectionFunction(dfConfig);
-    dfOutput.clear();
-    downBeat->resetAudioBuffer();
-    origin = Vamp::RealTime::zeroTime;
-}
-
-/* --- Getter Methods ---*/
-DFConfig getdfConfig(){
-return dfConfig;
-}
-
-
-
-
-
-
-
-
-
--- a/segmentino/SongParts/BeatTrackerData.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-
-/*
-    QM Vamp Plugin Set
-
-    Centre for Digital Music, Queen Mary, University of London.
-
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License as
-    published by the Free Software Foundation; either version 2 of the
-    License, or (at your option) any later version.  See the file
-    COPYING included with this distribution for more information.
-*/
-
-
-#include <dsp/onsets/DetectionFunction.h>
-
-
-class BeatTrackerData
-{
-public:
-    BeatTrackerData(float rate, const DFConfig &config);
-    virtual ~BeatTrackerData();
-    void reset();
-}
--- a/segmentino/build/general/Makefile.inc	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-
-PLUGIN_EXT	?= .so
-PLUGIN	?= segmentino$(PLUGIN_EXT)
-CXX	?= g++
-CC	?= gcc
-
-CFLAGS	:= $(CFLAGS) -I. -I../../qm-dsp -I../../nnls-chroma
-CXXFLAGS	:= $(CXXFLAGS) -I. -I../../qm-dsp -I../../nnls-chroma
-LDFLAGS		:= -L../../qm-dsp  $(LDFLAGS)
-
-HEADERS := Segmentino.h
-
-SOURCES := Segmentino.cpp \
-           libmain.cpp \
-	   g2cstubs.c \
-           ../../nnls-chroma/chromamethods.cpp \
-           ../../nnls-chroma/nnls.c
-
-OBJECTS := $(SOURCES:.cpp=.o)
-OBJECTS := $(OBJECTS:.c=.o)
-
-$(PLUGIN):	$(OBJECTS)
-		$(CXX) -o $@ $^ $(LDFLAGS)
-
-clean:		
-		rm $(OBJECTS)
-
-distclean:	clean
-		rm $(PLUGIN)
--- a/segmentino/build/linux/amd64/atlas/atlas_buildinfo.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-#ifndef ATL_INSTINFO_H
-   #define ATL_INSTINFO_H
-
-#define ATL_ARCH "Core2Duo64SSE3"
-#define ATL_INSTFLAGS "-1 0 -a 1"
-#define ATL_F2CDEFS "-DAdd__ -DF77_INTEGER=int -DStringSunStyle"
-#define ATL_ARCHDEFS "-DATL_OS_Linux -DATL_ARCH_Core2Duo -DATL_CPUMHZ=1500 -DATL_SSE3 -DATL_SSE2 -DATL_SSE1 -DATL_USE64BITS -DATL_GAS_x8664"
-#define ATL_DKCFLAGS "-fomit-frame-pointer -mfpmath=sse -msse3 -O2 -fPIC -m64"
-#define ATL_DKC "gcc"
-#define ATL_SKCFLAGS "-fomit-frame-pointer -mfpmath=sse -msse3 -O2 -fPIC -m64"
-#define ATL_SKC "gcc"
-#define ATL_DMCFLAGS "-fomit-frame-pointer -mfpmath=sse -msse3 -O2 -fPIC -m64"
-#define ATL_DMC "gcc"
-#define ATL_SMCFLAGS "-fomit-frame-pointer -mfpmath=sse -msse3 -O2 -fPIC -m64"
-#define ATL_SMC "gcc"
-#define ATL_ICCFLAGS "-DL2SIZE=4194304 -I/home/cannam/ATLAS/build/include -I/home/cannam/ATLAS/build/..//include -I/home/cannam/ATLAS/build/..//include/contrib -DAdd__ -DF77_INTEGER=int -DStringSunStyle -DATL_OS_Linux -DATL_ARCH_Core2Duo -DATL_CPUMHZ=1500 -DATL_SSE3 -DATL_SSE2 -DATL_SSE1 -DATL_USE64BITS -DATL_GAS_x8664 -DPentiumCPS=1000 -fomit-frame-pointer -mfpmath=sse -msse3 -O2 -fPIC -m64"
-#define ATL_ICC "gcc-4.2"
-#define ATL_F77FLAGS "-O -fPIC -m64"
-#define ATL_F77 "g77"
-#define ATL_DKCVERS "gcc (GCC) 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)"
-#define ATL_SKCVERS "gcc (GCC) 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)"
-#define ATL_DMCVERS "gcc (GCC) 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)"
-#define ATL_SMCVERS "gcc (GCC) 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)"
-#define ATL_ICCVERS "gcc-4.2 (GCC) 4.2.1 (Ubuntu 4.2.1-5ubuntu4)"
-#define ATL_F77VERS "GNU Fortran (GCC) 3.4.6 (Ubuntu 3.4.6-6ubuntu2)"
-#define ATL_SYSINFO "Linux yves-laptop 2.6.22-14-generic #1 SMP Thu Jan 31 23:33:13 UTC 2008 x86_64 GNU/Linux"
-#define ATL_DATE    "Wed Feb 13 11:25:06 GMT 2008"
-#define ATL_UNAM    "cannam"
-#define ATL_VERS    "3.8.0"
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_cNCmm.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef CMM_H
-   #define CMM_H
-
-   #define ATL_mmMULADD
-   #define ATL_mmLAT 1
-   #define ATL_mmMU  12
-   #define ATL_mmNU  1
-   #define ATL_mmKU  72
-   #define MB 48
-   #define NB 48
-   #define KB 48
-   #define NBNB 2304
-   #define MBNB 2304
-   #define MBKB 2304
-   #define NBKB 2304
-   #define NB2 96
-   #define NBNB2 4608
-
-   #define ATL_MulByNB(N_) ((N_) * 48)
-   #define ATL_DivByNB(N_) ((N_) / 48)
-   #define ATL_MulByNBNB(N_) ((N_) * 2304)
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_cacheedge.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-#ifndef ATLAS_CACHEEDGE_H
-   #define ATLAS_CACHEEDGE_H
-   #define CacheEdge 0
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_cmv.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#ifndef ATLAS_CMV_H
-#define ATLAS_CMV_H
-
-#define ATL_L1mvelts 3932
-#include "atlas_cmvN.h"
-#include "atlas_cmvT.h"
-#include "atlas_cmvS.h"
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_cmvN.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-#ifndef ATLAS_MVN_H
-#define ATLAS_MVN_H
-
-#include "atlas_misc.h"
-
-#define ATL_mvNMU 32
-#define ATL_mvNNU 1
-#ifndef ATL_L1mvelts
-   #define ATL_L1mvelts ((3*ATL_L1elts)>>2)
-#endif
-#define ATL_AXPYMV
-
-#define ATL_GetPartMVN(A_, lda_, mb_, nb_) \
-{ \
-   *(mb_) = (ATL_L1mvelts - (ATL_mvNNU<<1)) / ((ATL_mvNNU<<1)+1); \
-   if (*(mb_) > ATL_mvNMU) *(mb_) = ATL_mvNMU*( *(mb_)/ATL_mvNMU ); \
-   else *(mb_) = ATL_mvNMU; \
-   *(nb_) = ATL_mvNNU; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_cmvS.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef ATLAS_MVS_H
-#define ATLAS_MVS_H
-
-#include "atlas_misc.h"
-
-#define ATL_mvSMU 2
-#define ATL_mvSNU 32
-#ifndef ATL_L1mvelts
-   #define ATL_L1mvelts ((3*ATL_L1elts)>>2)
-#endif
-#ifndef ATL_mvNNU
-   #include "atlas_cmvN.h"
-#endif
-#ifndef ATL_mvTNU
-   #include "atlas_cmvT.h"
-#endif
-#define ATL_GetPartSYMV(A_, lda_, mb_, nb_) \
-{ \
-   *(nb_) = ATL_mvSMU; \
-   *(mb_) = 320; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_cmvT.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef ATLAS_MVT_H
-#define ATLAS_MVT_H
-
-#include "atlas_misc.h"
-
-#define ATL_mvTMU 2
-#define ATL_mvTNU 8
-#ifndef ATL_L1mvelts
-   #define ATL_L1mvelts ((3*ATL_L1elts)>>2)
-#endif
-#ifndef ATL_mvNNU
-   #include "atlas_cmvN.h"
-#endif
-
-#define ATL_GetPartMVT(A_, lda_, mb_, nb_) \
-{ \
-   *(mb_) = (ATL_L1mvelts - (ATL_mvTMU<<1)) / ((ATL_mvTMU<<1)+1); \
-   if (*(mb_) > ATL_mvTNU) *(mb_) = (*(mb_)/ATL_mvTNU)*ATL_mvTNU; \
-   else (*mb_) = ATL_mvTNU; \
-   *(nb_) = ATL_mvTMU; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_cr1.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-#ifndef ATLAS_CR1_H
-#define ATLAS_CR1_H
-
-#define ATL_L1r1elts 3809
-#define ATL_r1MU 16
-#define ATL_r1NU 1
-
-#define ATL_GetPartR1(A_, lda_, mb_, nb_) \
-{ \
-   (mb_) = (ATL_L1r1elts - (ATL_r1NU+ATL_r1NU)) / (ATL_r1NU+ATL_r1NU+1); \
-   if ((mb_) > ATL_r1MU) (mb_) = ATL_r1MU*((mb_)/ATL_r1MU); \
-   else (mb_) = ATL_r1MU; \
-   (nb_) = ATL_r1NU; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_csNKB.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-#ifndef ATLAS_CSNKB_H
-   #define ATLAS_CSNKB_H
-   #define ATL_CSNKB 0
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_csysinfo.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-#ifndef ATL_CSYSINFO_H
-   #define ATL_CSYSINFO_H
-
-#define ATL_MULADD
-#define ATL_L1elts 2048
-#define ATL_fplat  4
-#define ATL_lbnreg 16
-#define ATL_mmnreg 18
-#define ATL_nkflop 879334
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_dNCmm.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef DMM_H
-   #define DMM_H
-
-   #define ATL_mmNOMULADD
-   #define ATL_mmLAT 1
-   #define ATL_mmMU  12
-   #define ATL_mmNU  1
-   #define ATL_mmKU  56
-   #define MB 24
-   #define NB 24
-   #define KB 24
-   #define NBNB 576
-   #define MBNB 576
-   #define MBKB 576
-   #define NBKB 576
-   #define NB2 48
-   #define NBNB2 1152
-
-   #define ATL_MulByNB(N_) ((N_) * 24)
-   #define ATL_DivByNB(N_) ((N_) / 24)
-   #define ATL_MulByNBNB(N_) ((N_) * 576)
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_dmv.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#ifndef ATLAS_DMV_H
-#define ATLAS_DMV_H
-
-#define ATL_L1mvelts 3317
-#include "atlas_dmvN.h"
-#include "atlas_dmvT.h"
-#include "atlas_dmvS.h"
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_dmvN.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-#ifndef ATLAS_MVN_H
-#define ATLAS_MVN_H
-
-#include "atlas_misc.h"
-
-#define ATL_mvNMU 32
-#define ATL_mvNNU 1
-#ifndef ATL_L1mvelts
-   #define ATL_L1mvelts ((3*ATL_L1elts)>>2)
-#endif
-#define ATL_AXPYMV
-
-#define ATL_GetPartMVN(A_, lda_, mb_, nb_) \
-{ \
-   *(mb_) = (ATL_L1mvelts - (ATL_mvNNU<<1)) / ((ATL_mvNNU<<1)+1); \
-   if (*(mb_) > ATL_mvNMU) *(mb_) = ATL_mvNMU*( *(mb_)/ATL_mvNMU ); \
-   else *(mb_) = ATL_mvNMU; \
-   *(nb_) = ATL_mvNNU; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_dmvS.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef ATLAS_MVS_H
-#define ATLAS_MVS_H
-
-#include "atlas_misc.h"
-
-#define ATL_mvSMU 2
-#define ATL_mvSNU 32
-#ifndef ATL_L1mvelts
-   #define ATL_L1mvelts ((3*ATL_L1elts)>>2)
-#endif
-#ifndef ATL_mvNNU
-   #include "atlas_dmvN.h"
-#endif
-#ifndef ATL_mvTNU
-   #include "atlas_dmvT.h"
-#endif
-#define ATL_GetPartSYMV(A_, lda_, mb_, nb_) \
-{ \
-   *(nb_) = ATL_mvSMU; \
-   *(mb_) = 256; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_dmvT.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef ATLAS_MVT_H
-#define ATLAS_MVT_H
-
-#include "atlas_misc.h"
-
-#define ATL_mvTMU 2
-#define ATL_mvTNU 16
-#ifndef ATL_L1mvelts
-   #define ATL_L1mvelts ((3*ATL_L1elts)>>2)
-#endif
-#ifndef ATL_mvNNU
-   #include "atlas_dmvN.h"
-#endif
-
-#define ATL_GetPartMVT(A_, lda_, mb_, nb_) \
-{ \
-   *(mb_) = (ATL_L1mvelts - (ATL_mvTMU<<1)) / ((ATL_mvTMU<<1)+1); \
-   if (*(mb_) > ATL_mvTNU) *(mb_) = (*(mb_)/ATL_mvTNU)*ATL_mvTNU; \
-   else (*mb_) = ATL_mvTNU; \
-   *(nb_) = ATL_mvTMU; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_dr1.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-#ifndef ATLAS_DR1_H
-#define ATLAS_DR1_H
-
-#define ATL_L1r1elts 3809
-#define ATL_r1MU 16
-#define ATL_r1NU 1
-
-#define ATL_GetPartR1(A_, lda_, mb_, nb_) \
-{ \
-   (mb_) = (ATL_L1r1elts - (ATL_r1NU+ATL_r1NU)) / (ATL_r1NU+ATL_r1NU+1); \
-   if ((mb_) > ATL_r1MU) (mb_) = ATL_r1MU*((mb_)/ATL_r1MU); \
-   else (mb_) = ATL_r1MU; \
-   (nb_) = ATL_r1NU; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_dsysinfo.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-#ifndef ATL_DSYSINFO_H
-   #define ATL_DSYSINFO_H
-
-#define ATL_MULADD
-#define ATL_L1elts 4096
-#define ATL_fplat  12
-#define ATL_lbnreg 16
-#define ATL_mmnreg 18
-#define ATL_nkflop 2159859
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_sNCmm.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef SMM_H
-   #define SMM_H
-
-   #define ATL_mmMULADD
-   #define ATL_mmLAT 1
-   #define ATL_mmMU  12
-   #define ATL_mmNU  1
-   #define ATL_mmKU  80
-   #define MB 36
-   #define NB 36
-   #define KB 36
-   #define NBNB 1296
-   #define MBNB 1296
-   #define MBKB 1296
-   #define NBKB 1296
-   #define NB2 72
-   #define NBNB2 2592
-
-   #define ATL_MulByNB(N_) ((N_) * 36)
-   #define ATL_DivByNB(N_) ((N_) / 36)
-   #define ATL_MulByNBNB(N_) ((N_) * 1296)
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_smv.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#ifndef ATLAS_SMV_H
-#define ATLAS_SMV_H
-
-#define ATL_L1mvelts 7127
-#include "atlas_smvN.h"
-#include "atlas_smvT.h"
-#include "atlas_smvS.h"
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_smvN.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-#ifndef ATLAS_MVN_H
-#define ATLAS_MVN_H
-
-#include "atlas_misc.h"
-
-#define ATL_mvNMU 32
-#define ATL_mvNNU 1
-#ifndef ATL_L1mvelts
-   #define ATL_L1mvelts ((3*ATL_L1elts)>>2)
-#endif
-#define ATL_AXPYMV
-
-#define ATL_GetPartMVN(A_, lda_, mb_, nb_) \
-{ \
-   *(mb_) = (ATL_L1mvelts - (ATL_mvNNU<<1)) / ((ATL_mvNNU<<1)+1); \
-   if (*(mb_) > ATL_mvNMU) *(mb_) = ATL_mvNMU*( *(mb_)/ATL_mvNMU ); \
-   else *(mb_) = ATL_mvNMU; \
-   *(nb_) = ATL_mvNNU; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_smvS.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef ATLAS_MVS_H
-#define ATLAS_MVS_H
-
-#include "atlas_misc.h"
-
-#define ATL_mvSMU 2
-#define ATL_mvSNU 32
-#ifndef ATL_L1mvelts
-   #define ATL_L1mvelts ((3*ATL_L1elts)>>2)
-#endif
-#ifndef ATL_mvNNU
-   #include "atlas_smvN.h"
-#endif
-#ifndef ATL_mvTNU
-   #include "atlas_smvT.h"
-#endif
-#define ATL_GetPartSYMV(A_, lda_, mb_, nb_) \
-{ \
-   *(nb_) = ATL_mvSMU; \
-   *(mb_) = 576; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_smvT.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef ATLAS_MVT_H
-#define ATLAS_MVT_H
-
-#include "atlas_misc.h"
-
-#define ATL_mvTMU 2
-#define ATL_mvTNU 16
-#ifndef ATL_L1mvelts
-   #define ATL_L1mvelts ((3*ATL_L1elts)>>2)
-#endif
-#ifndef ATL_mvNNU
-   #include "atlas_smvN.h"
-#endif
-
-#define ATL_GetPartMVT(A_, lda_, mb_, nb_) \
-{ \
-   *(mb_) = (ATL_L1mvelts - (ATL_mvTMU<<1)) / ((ATL_mvTMU<<1)+1); \
-   if (*(mb_) > ATL_mvTNU) *(mb_) = (*(mb_)/ATL_mvTNU)*ATL_mvTNU; \
-   else (*mb_) = ATL_mvTNU; \
-   *(nb_) = ATL_mvTMU; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_sr1.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-#ifndef ATLAS_SR1_H
-#define ATLAS_SR1_H
-
-#define ATL_L1r1elts 7127
-#define ATL_r1MU 16
-#define ATL_r1NU 1
-
-#define ATL_GetPartR1(A_, lda_, mb_, nb_) \
-{ \
-   (mb_) = (ATL_L1r1elts - (ATL_r1NU+ATL_r1NU)) / (ATL_r1NU+ATL_r1NU+1); \
-   if ((mb_) > ATL_r1MU) (mb_) = ATL_r1MU*((mb_)/ATL_r1MU); \
-   else (mb_) = ATL_r1MU; \
-   (nb_) = ATL_r1NU; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_ssysinfo.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-#ifndef ATL_SSYSINFO_H
-   #define ATL_SSYSINFO_H
-
-#define ATL_MULADD
-#define ATL_L1elts 8192
-#define ATL_fplat  4
-#define ATL_lbnreg 16
-#define ATL_mmnreg 18
-#define ATL_nkflop 879334
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_trsmNB.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-#ifndef ATLAS_TRSMNB_H
-   #define ATLAS_TRSMNB_H
-
-   #ifdef SREAL
-      #define TRSM_NB 60
-   #elif defined(DREAL)
-      #define TRSM_NB 12
-   #else
-      #define TRSM_NB 4
-   #endif
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_type.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-#ifndef ATLAS_TYPE_H
-#define ATLAS_TYPE_H
-
-#define ATL_isize 4
-#define ATL_ssize 4
-#define ATL_dsize 8
-#define ATL_csize 8
-#define ATL_zsize 16
-#define ATL_iMulBySize(N_) ((((N_)) << 2))
-#define ATL_sMulBySize(N_) ((((N_)) << 2))
-#define ATL_dMulBySize(N_) ((((N_)) << 3))
-#define ATL_cMulBySize(N_) ((((N_)) << 3))
-#define ATL_zMulBySize(N_) ((((N_)) << 4))
-#define ATL_iDivBySize(N_) ((N_) >> 2)
-#define ATL_sDivBySize(N_) ((N_) >> 2)
-#define ATL_cDivBySize(N_) ((N_) >> 3)
-#define ATL_dDivBySize(N_) ((N_) >> 3)
-#define ATL_zDivBySize(N_) ((N_) >> 4)
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_zNCmm.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef ZMM_H
-   #define ZMM_H
-
-   #define ATL_mmMULADD
-   #define ATL_mmLAT 1
-   #define ATL_mmMU  12
-   #define ATL_mmNU  1
-   #define ATL_mmKU  48
-   #define MB 36
-   #define NB 36
-   #define KB 36
-   #define NBNB 1296
-   #define MBNB 1296
-   #define MBKB 1296
-   #define NBKB 1296
-   #define NB2 72
-   #define NBNB2 2592
-
-   #define ATL_MulByNB(N_) ((N_) * 36)
-   #define ATL_DivByNB(N_) ((N_) / 36)
-   #define ATL_MulByNBNB(N_) ((N_) * 1296)
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_zdNKB.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-#ifndef ATLAS_ZDNKB_H
-   #define ATLAS_ZDNKB_H
-   #define ATL_ZDNKB 0
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_zmv.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#ifndef ATLAS_ZMV_H
-#define ATLAS_ZMV_H
-
-#define ATL_L1mvelts 2048
-#include "atlas_zmvN.h"
-#include "atlas_zmvT.h"
-#include "atlas_zmvS.h"
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_zmvN.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-#ifndef ATLAS_MVN_H
-#define ATLAS_MVN_H
-
-#include "atlas_misc.h"
-
-#define ATL_mvNMU 32
-#define ATL_mvNNU 1
-#ifndef ATL_L1mvelts
-   #define ATL_L1mvelts ((3*ATL_L1elts)>>2)
-#endif
-#define ATL_AXPYMV
-
-#define ATL_GetPartMVN(A_, lda_, mb_, nb_) \
-{ \
-   *(mb_) = (ATL_L1mvelts - (ATL_mvNNU<<1)) / ((ATL_mvNNU<<1)+1); \
-   if (*(mb_) > ATL_mvNMU) *(mb_) = ATL_mvNMU*( *(mb_)/ATL_mvNMU ); \
-   else *(mb_) = ATL_mvNMU; \
-   *(nb_) = ATL_mvNNU; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_zmvS.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef ATLAS_MVS_H
-#define ATLAS_MVS_H
-
-#include "atlas_misc.h"
-
-#define ATL_mvSMU 2
-#define ATL_mvSNU 32
-#ifndef ATL_L1mvelts
-   #define ATL_L1mvelts ((3*ATL_L1elts)>>2)
-#endif
-#ifndef ATL_mvNNU
-   #include "atlas_zmvN.h"
-#endif
-#ifndef ATL_mvTNU
-   #include "atlas_zmvT.h"
-#endif
-#define ATL_GetPartSYMV(A_, lda_, mb_, nb_) \
-{ \
-   *(nb_) = ATL_mvSMU; \
-   *(mb_) = 160; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_zmvT.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef ATLAS_MVT_H
-#define ATLAS_MVT_H
-
-#include "atlas_misc.h"
-
-#define ATL_mvTMU 2
-#define ATL_mvTNU 8
-#ifndef ATL_L1mvelts
-   #define ATL_L1mvelts ((3*ATL_L1elts)>>2)
-#endif
-#ifndef ATL_mvNNU
-   #include "atlas_zmvN.h"
-#endif
-
-#define ATL_GetPartMVT(A_, lda_, mb_, nb_) \
-{ \
-   *(mb_) = (ATL_L1mvelts - (ATL_mvTMU<<1)) / ((ATL_mvTMU<<1)+1); \
-   if (*(mb_) > ATL_mvTNU) *(mb_) = (*(mb_)/ATL_mvTNU)*ATL_mvTNU; \
-   else (*mb_) = ATL_mvTNU; \
-   *(nb_) = ATL_mvTMU; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_zr1.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-#ifndef ATLAS_ZR1_H
-#define ATLAS_ZR1_H
-
-#define ATL_L1r1elts 2048
-#define ATL_r1MU 16
-#define ATL_r1NU 1
-
-#define ATL_GetPartR1(A_, lda_, mb_, nb_) \
-{ \
-   (mb_) = (ATL_L1r1elts - (ATL_r1NU+ATL_r1NU)) / (ATL_r1NU+ATL_r1NU+1); \
-   if ((mb_) > ATL_r1MU) (mb_) = ATL_r1MU*((mb_)/ATL_r1MU); \
-   else (mb_) = ATL_r1MU; \
-   (nb_) = ATL_r1NU; \
-}
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/atlas_zsysinfo.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-#ifndef ATL_ZSYSINFO_H
-   #define ATL_ZSYSINFO_H
-
-#define ATL_MULADD
-#define ATL_L1elts 4096
-#define ATL_fplat  12
-#define ATL_lbnreg 16
-#define ATL_mmnreg 18
-#define ATL_nkflop 2159859
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/cXover.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#ifndef CXOVER_H
-#define CXOVER_H
-
-#define ATL_3NB 216
-#define NN_MNK_M 7200
-#define NN_MNK_N 7200
-#define NN_MNK_MN 51840
-#define NN_MNK_K 16200
-#define NN_MNK_GE 1000
-#define NT_MNK_M 7200
-#define NT_MNK_N 7200
-#define NT_MNK_MN 51840
-#define NT_MNK_K 16200
-#define NT_MNK_GE 1000
-#define TN_MNK_M 7200
-#define TN_MNK_N 7200
-#define TN_MNK_MN 51840
-#define TN_MNK_K 41472
-#define TN_MNK_GE 3375
-#define TT_MNK_M 7200
-#define TT_MNK_N 7200
-#define TT_MNK_MN 51840
-#define TT_MNK_K 16200
-#define TT_MNK_GE 1000
-#define C2R_K 278
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/cmm.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-#ifndef CMM_H
-   #define CMM_H
-
-   #define ATL_mmMULADD
-   #define ATL_mmLAT 1
-   #define ATL_mmMU  12
-   #define ATL_mmNU  1
-   #define ATL_mmKU  72
-   #define MB 72
-   #define NB 72
-   #define KB 72
-   #define NBNB 5184
-   #define MBNB 5184
-   #define MBKB 5184
-   #define NBKB 5184
-   #define NB2 144
-   #define NBNB2 10368
-
-   #define ATL_MulByNB(N_) ((N_) * 72)
-   #define ATL_DivByNB(N_) ((N_) / 72)
-   #define ATL_MulByNBNB(N_) ((N_) * 5184)
-void ATL_cJIK72x72x72TN72x72x0_a1_b0(const int M, const int N, const int K, const TYPE alpha, const TYPE *A, const int lda, const TYPE *B, const int ldb, const TYPE beta, TYPE *C, const int ldc);
-void ATL_cJIK72x72x72TN72x72x0_a1_b1(const int M, const int N, const int K, const TYPE alpha, const TYPE *A, const int lda, const TYPE *B, const int ldb, const TYPE beta, TYPE *C, const int ldc);
-void ATL_cJIK72x72x72TN72x72x0_a1_bX(const int M, const int N, const int K, const TYPE alpha, const TYPE *A, const int lda, const TYPE *B, const int ldb, const TYPE beta, TYPE *C, const int ldc);
-
-   #define NBmm_b1(m_, n_, k_, al_, A_, lda_, B_, ldb_, be_, C_, ldc_) \
-{ \
-   ATL_cJIK72x72x72TN72x72x0_a1_bX(m_, n_, k_, al_, (A_), lda_, (B_), ldb_, ATL_rnone, C_, ldc_); \
-   ATL_cJIK72x72x72TN72x72x0_a1_b1(m_, n_, k_, al_, (A_), lda_, (B_)+NBNB, ldb_, ATL_rone, (C_)+1, ldc_); \
-   ATL_cJIK72x72x72TN72x72x0_a1_bX(m_, n_, k_, al_, (A_)+NBNB, lda_, (B_)+NBNB, ldb_, ATL_rnone, C_, ldc_); \
-   ATL_cJIK72x72x72TN72x72x0_a1_b1(m_, n_, k_, al_, (A_)+NBNB, lda_, (B_), ldb_, ATL_rone, (C_)+1, ldc_); \
-   }
-   #define NBmm_b0(m_, n_, k_, al_, A_, lda_, B_, ldb_, be_, C_, ldc_) \
-{ \
-   ATL_cJIK72x72x72TN72x72x0_a1_b0(m_, n_, k_, al_, (A_), lda_, (B_), ldb_, ATL_rzero, C_, ldc_); \
-   ATL_cJIK72x72x72TN72x72x0_a1_b0(m_, n_, k_, al_, (A_), lda_, (B_)+NBNB, ldb_, ATL_rzero, (C_)+1, ldc_); \
-   ATL_cJIK72x72x72TN72x72x0_a1_bX(m_, n_, k_, al_, (A_)+NBNB, lda_, (B_)+NBNB, ldb_, ATL_rnone, C_, ldc_); \
-   ATL_cJIK72x72x72TN72x72x0_a1_b1(m_, n_, k_, al_, (A_)+NBNB, lda_, (B_), ldb_, ATL_rone, (C_)+1, ldc_); \
-   }
-   #define NBmm_bX(m_, n_, k_, al_, A_, lda_, B_, ldb_, be_, C_, ldc_) \
-{ \
-   ATL_cJIK72x72x72TN72x72x0_a1_bX(m_, n_, k_, al_, (A_), lda_, (B_), ldb_, -(be_), C_, ldc_); \
-   ATL_cJIK72x72x72TN72x72x0_a1_bX(m_, n_, k_, al_, (A_), lda_, (B_)+NBNB, ldb_, be_, (C_)+1, ldc_); \
-   ATL_cJIK72x72x72TN72x72x0_a1_bX(m_, n_, k_, al_, (A_)+NBNB, lda_, (B_)+NBNB, ldb_, ATL_rnone, C_, ldc_); \
-   ATL_cJIK72x72x72TN72x72x0_a1_b1(m_, n_, k_, al_, (A_)+NBNB, lda_, (B_), ldb_, ATL_rone, (C_)+1, ldc_); \
-   }
-   #define rNBmm_b1 ATL_sJIK72x72x72TN72x72x0_a1_b1
-   #define rNBmm_b0 ATL_sJIK72x72x72TN72x72x0_a1_b0
-   #define rNBmm_bX ATL_sJIK72x72x72TN72x72x0_a1_bX
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/dXover.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-#ifndef DXOVER_H
-#define DXOVER_H
-
-#define ATL_3NB 168
-#define NN_MNK_M 5600
-#define NN_MNK_N 12600
-#define NN_MNK_MN 31360
-#define NN_MNK_K 80864
-#define NN_MNK_GE 13824
-#define NT_MNK_M 5600
-#define NT_MNK_N 5600
-#define NT_MNK_MN 31360
-#define NT_MNK_K 32256
-#define NT_MNK_GE 3375
-#define TN_MNK_M 5600
-#define TN_MNK_N 5600
-#define TN_MNK_MN 31360
-#define TN_MNK_K 80864
-#define TN_MNK_GE 13824
-#define TT_MNK_M 5600
-#define TT_MNK_N 12600
-#define TT_MNK_MN 31360
-#define TT_MNK_K 32256
-#define TT_MNK_GE 3375
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/dmm.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#ifndef DMM_H
-   #define DMM_H
-
-   #define ATL_mmNOMULADD
-   #define ATL_mmLAT 1
-   #define ATL_mmMU  12
-   #define ATL_mmNU  1
-   #define ATL_mmKU  56
-   #define MB 56
-   #define NB 56
-   #define KB 56
-   #define NBNB 3136
-   #define MBNB 3136
-   #define MBKB 3136
-   #define NBKB 3136
-   #define NB2 112
-   #define NBNB2 6272
-
-   #define ATL_MulByNB(N_) ((N_) * 56)
-   #define ATL_DivByNB(N_) ((N_) / 56)
-   #define ATL_MulByNBNB(N_) ((N_) * 3136)
-   #define NBmm ATL_dJIK56x56x56TN56x56x0_a1_b1
-   #define NBmm_b1 ATL_dJIK56x56x56TN56x56x0_a1_b1
-   #define NBmm_b0 ATL_dJIK56x56x56TN56x56x0_a1_b0
-   #define NBmm_bX ATL_dJIK56x56x56TN56x56x0_a1_bX
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/sXover.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-#ifndef SXOVER_H
-#define SXOVER_H
-
-#define ATL_3NB 216
-#define NN_MNK_M 7200
-#define NN_MNK_N 16200
-#define NN_MNK_MN 51840
-#define NN_MNK_K 41472
-#define NN_MNK_GE 13824
-#define NT_MNK_M 7200
-#define NT_MNK_N 7200
-#define NT_MNK_MN 51840
-#define NT_MNK_K 16200
-#define NT_MNK_GE 3375
-#define TN_MNK_M 7200
-#define TN_MNK_N 16200
-#define TN_MNK_MN 51840
-#define TN_MNK_K 352800
-#define TN_MNK_GE 27000
-#define TT_MNK_M 7200
-#define TT_MNK_N 7200
-#define TT_MNK_MN 51840
-#define TT_MNK_K 41472
-#define TT_MNK_GE 3375
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/smm.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#ifndef SMM_H
-   #define SMM_H
-
-   #define ATL_mmMULADD
-   #define ATL_mmLAT 1
-   #define ATL_mmMU  12
-   #define ATL_mmNU  1
-   #define ATL_mmKU  80
-   #define MB 80
-   #define NB 80
-   #define KB 80
-   #define NBNB 6400
-   #define MBNB 6400
-   #define MBKB 6400
-   #define NBKB 6400
-   #define NB2 160
-   #define NBNB2 12800
-
-   #define ATL_MulByNB(N_) ((N_) * 80)
-   #define ATL_DivByNB(N_) ((N_) / 80)
-   #define ATL_MulByNBNB(N_) ((N_) * 6400)
-   #define NBmm ATL_sJIK80x80x80TN80x80x0_a1_b1
-   #define NBmm_b1 ATL_sJIK80x80x80TN80x80x0_a1_b1
-   #define NBmm_b0 ATL_sJIK80x80x80TN80x80x0_a1_b0
-   #define NBmm_bX ATL_sJIK80x80x80TN80x80x0_a1_bX
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/zXover.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#ifndef ZXOVER_H
-#define ZXOVER_H
-
-#define ATL_3NB 144
-#define NN_MNK_M 4800
-#define NN_MNK_N 4800
-#define NN_MNK_MN 23040
-#define NN_MNK_K 4800
-#define NN_MNK_GE 1000
-#define NT_MNK_M 4800
-#define NT_MNK_N 4800
-#define NT_MNK_MN 23040
-#define NT_MNK_K 4800
-#define NT_MNK_GE 1000
-#define TN_MNK_M 4800
-#define TN_MNK_N 4800
-#define TN_MNK_MN 23040
-#define TN_MNK_K 10800
-#define TN_MNK_GE 1000
-#define TT_MNK_M 4800
-#define TT_MNK_N 4800
-#define TT_MNK_MN 23040
-#define TT_MNK_K 10800
-#define TT_MNK_GE 1000
-#define C2R_K 570
-
-#endif
--- a/segmentino/build/linux/amd64/atlas/zmm.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-#ifndef ZMM_H
-   #define ZMM_H
-
-   #define ATL_mmMULADD
-   #define ATL_mmLAT 1
-   #define ATL_mmMU  12
-   #define ATL_mmNU  1
-   #define ATL_mmKU  48
-   #define MB 48
-   #define NB 48
-   #define KB 48
-   #define NBNB 2304
-   #define MBNB 2304
-   #define MBKB 2304
-   #define NBKB 2304
-   #define NB2 96
-   #define NBNB2 4608
-
-   #define ATL_MulByNB(N_) ((N_) * 48)
-   #define ATL_DivByNB(N_) ((N_) / 48)
-   #define ATL_MulByNBNB(N_) ((N_) * 2304)
-void ATL_zJIK48x48x48TN48x48x0_a1_b0(const int M, const int N, const int K, const TYPE alpha, const TYPE *A, const int lda, const TYPE *B, const int ldb, const TYPE beta, TYPE *C, const int ldc);
-void ATL_zJIK48x48x48TN48x48x0_a1_b1(const int M, const int N, const int K, const TYPE alpha, const TYPE *A, const int lda, const TYPE *B, const int ldb, const TYPE beta, TYPE *C, const int ldc);
-void ATL_zJIK48x48x48TN48x48x0_a1_bX(const int M, const int N, const int K, const TYPE alpha, const TYPE *A, const int lda, const TYPE *B, const int ldb, const TYPE beta, TYPE *C, const int ldc);
-
-   #define NBmm_b1(m_, n_, k_, al_, A_, lda_, B_, ldb_, be_, C_, ldc_) \
-{ \
-   ATL_zJIK48x48x48TN48x48x0_a1_bX(m_, n_, k_, al_, (A_), lda_, (B_), ldb_, ATL_rnone, C_, ldc_); \
-   ATL_zJIK48x48x48TN48x48x0_a1_b1(m_, n_, k_, al_, (A_), lda_, (B_)+NBNB, ldb_, ATL_rone, (C_)+1, ldc_); \
-   ATL_zJIK48x48x48TN48x48x0_a1_bX(m_, n_, k_, al_, (A_)+NBNB, lda_, (B_)+NBNB, ldb_, ATL_rnone, C_, ldc_); \
-   ATL_zJIK48x48x48TN48x48x0_a1_b1(m_, n_, k_, al_, (A_)+NBNB, lda_, (B_), ldb_, ATL_rone, (C_)+1, ldc_); \
-   }
-   #define NBmm_b0(m_, n_, k_, al_, A_, lda_, B_, ldb_, be_, C_, ldc_) \
-{ \
-   ATL_zJIK48x48x48TN48x48x0_a1_b0(m_, n_, k_, al_, (A_), lda_, (B_), ldb_, ATL_rzero, C_, ldc_); \
-   ATL_zJIK48x48x48TN48x48x0_a1_b0(m_, n_, k_, al_, (A_), lda_, (B_)+NBNB, ldb_, ATL_rzero, (C_)+1, ldc_); \
-   ATL_zJIK48x48x48TN48x48x0_a1_bX(m_, n_, k_, al_, (A_)+NBNB, lda_, (B_)+NBNB, ldb_, ATL_rnone, C_, ldc_); \
-   ATL_zJIK48x48x48TN48x48x0_a1_b1(m_, n_, k_, al_, (A_)+NBNB, lda_, (B_), ldb_, ATL_rone, (C_)+1, ldc_); \
-   }
-   #define NBmm_bX(m_, n_, k_, al_, A_, lda_, B_, ldb_, be_, C_, ldc_) \
-{ \
-   ATL_zJIK48x48x48TN48x48x0_a1_bX(m_, n_, k_, al_, (A_), lda_, (B_), ldb_, -(be_), C_, ldc_); \
-   ATL_zJIK48x48x48TN48x48x0_a1_bX(m_, n_, k_, al_, (A_), lda_, (B_)+NBNB, ldb_, be_, (C_)+1, ldc_); \
-   ATL_zJIK48x48x48TN48x48x0_a1_bX(m_, n_, k_, al_, (A_)+NBNB, lda_, (B_)+NBNB, ldb_, ATL_rnone, C_, ldc_); \
-   ATL_zJIK48x48x48TN48x48x0_a1_b1(m_, n_, k_, al_, (A_)+NBNB, lda_, (B_), ldb_, ATL_rone, (C_)+1, ldc_); \
-   }
-   #define rNBmm_b1 ATL_dJIK48x48x48TN48x48x0_a1_b1
-   #define rNBmm_b0 ATL_dJIK48x48x48TN48x48x0_a1_b0
-   #define rNBmm_bX ATL_dJIK48x48x48TN48x48x0_a1_bX
-
-#endif
--- a/segmentino/build/linux/amd64/cblas.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,596 +0,0 @@
-#ifndef CBLAS_H
-
-#ifndef CBLAS_ENUM_DEFINED_H
-   #define CBLAS_ENUM_DEFINED_H
-   enum CBLAS_ORDER {CblasRowMajor=101, CblasColMajor=102 };
-   enum CBLAS_TRANSPOSE {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113,
-                         AtlasConj=114};
-   enum CBLAS_UPLO  {CblasUpper=121, CblasLower=122};
-   enum CBLAS_DIAG  {CblasNonUnit=131, CblasUnit=132};
-   enum CBLAS_SIDE  {CblasLeft=141, CblasRight=142};
-#endif
-
-#ifndef CBLAS_ENUM_ONLY
-#define CBLAS_H
-#define CBLAS_INDEX int
-
-int cblas_errprn(int ierr, int info, char *form, ...);
-
-/*
- * ===========================================================================
- * Prototypes for level 1 BLAS functions (complex are recast as routines)
- * ===========================================================================
- */
-float  cblas_sdsdot(const int N, const float alpha, const float *X,
-                    const int incX, const float *Y, const int incY);
-double cblas_dsdot(const int N, const float *X, const int incX, const float *Y,
-                   const int incY);
-float  cblas_sdot(const int N, const float  *X, const int incX,
-                  const float  *Y, const int incY);
-double cblas_ddot(const int N, const double *X, const int incX,
-                  const double *Y, const int incY);
-/*
- * Functions having prefixes Z and C only
- */
-void   cblas_cdotu_sub(const int N, const void *X, const int incX,
-                       const void *Y, const int incY, void *dotu);
-void   cblas_cdotc_sub(const int N, const void *X, const int incX,
-                       const void *Y, const int incY, void *dotc);
-
-void   cblas_zdotu_sub(const int N, const void *X, const int incX,
-                       const void *Y, const int incY, void *dotu);
-void   cblas_zdotc_sub(const int N, const void *X, const int incX,
-                       const void *Y, const int incY, void *dotc);
-
-
-/*
- * Functions having prefixes S D SC DZ
- */
-float  cblas_snrm2(const int N, const float *X, const int incX);
-float  cblas_sasum(const int N, const float *X, const int incX);
-
-double cblas_dnrm2(const int N, const double *X, const int incX);
-double cblas_dasum(const int N, const double *X, const int incX);
-
-float  cblas_scnrm2(const int N, const void *X, const int incX);
-float  cblas_scasum(const int N, const void *X, const int incX);
-
-double cblas_dznrm2(const int N, const void *X, const int incX);
-double cblas_dzasum(const int N, const void *X, const int incX);
-
-
-/*
- * Functions having standard 4 prefixes (S D C Z)
- */
-CBLAS_INDEX cblas_isamax(const int N, const float  *X, const int incX);
-CBLAS_INDEX cblas_idamax(const int N, const double *X, const int incX);
-CBLAS_INDEX cblas_icamax(const int N, const void   *X, const int incX);
-CBLAS_INDEX cblas_izamax(const int N, const void   *X, const int incX);
-
-/*
- * ===========================================================================
- * Prototypes for level 1 BLAS routines
- * ===========================================================================
- */
-
-/*
- * Routines with standard 4 prefixes (s, d, c, z)
- */
-void cblas_sswap(const int N, float *X, const int incX,
-                 float *Y, const int incY);
-void cblas_scopy(const int N, const float *X, const int incX,
-                 float *Y, const int incY);
-void cblas_saxpy(const int N, const float alpha, const float *X,
-                 const int incX, float *Y, const int incY);
-void catlas_saxpby(const int N, const float alpha, const float *X,
-                  const int incX, const float beta, float *Y, const int incY);
-void catlas_sset
-   (const int N, const float alpha, float *X, const int incX);
-
-void cblas_dswap(const int N, double *X, const int incX,
-                 double *Y, const int incY);
-void cblas_dcopy(const int N, const double *X, const int incX,
-                 double *Y, const int incY);
-void cblas_daxpy(const int N, const double alpha, const double *X,
-                 const int incX, double *Y, const int incY);
-void catlas_daxpby(const int N, const double alpha, const double *X,
-                  const int incX, const double beta, double *Y, const int incY);
-void catlas_dset
-   (const int N, const double alpha, double *X, const int incX);
-
-void cblas_cswap(const int N, void *X, const int incX,
-                 void *Y, const int incY);
-void cblas_ccopy(const int N, const void *X, const int incX,
-                 void *Y, const int incY);
-void cblas_caxpy(const int N, const void *alpha, const void *X,
-                 const int incX, void *Y, const int incY);
-void catlas_caxpby(const int N, const void *alpha, const void *X,
-                  const int incX, const void *beta, void *Y, const int incY);
-void catlas_cset
-   (const int N, const void *alpha, void *X, const int incX);
-
-void cblas_zswap(const int N, void *X, const int incX,
-                 void *Y, const int incY);
-void cblas_zcopy(const int N, const void *X, const int incX,
-                 void *Y, const int incY);
-void cblas_zaxpy(const int N, const void *alpha, const void *X,
-                 const int incX, void *Y, const int incY);
-void catlas_zaxpby(const int N, const void *alpha, const void *X,
-                  const int incX, const void *beta, void *Y, const int incY);
-void catlas_zset
-   (const int N, const void *alpha, void *X, const int incX);
-
-
-/*
- * Routines with S and D prefix only
- */
-void cblas_srotg(float *a, float *b, float *c, float *s);
-void cblas_srotmg(float *d1, float *d2, float *b1, const float b2, float *P);
-void cblas_srot(const int N, float *X, const int incX,
-                float *Y, const int incY, const float c, const float s);
-void cblas_srotm(const int N, float *X, const int incX,
-                float *Y, const int incY, const float *P);
-
-void cblas_drotg(double *a, double *b, double *c, double *s);
-void cblas_drotmg(double *d1, double *d2, double *b1, const double b2, double *P);
-void cblas_drot(const int N, double *X, const int incX,
-                double *Y, const int incY, const double c, const double s);
-void cblas_drotm(const int N, double *X, const int incX,
-                double *Y, const int incY, const double *P);
-
-
-/*
- * Routines with S D C Z CS and ZD prefixes
- */
-void cblas_sscal(const int N, const float alpha, float *X, const int incX);
-void cblas_dscal(const int N, const double alpha, double *X, const int incX);
-void cblas_cscal(const int N, const void *alpha, void *X, const int incX);
-void cblas_zscal(const int N, const void *alpha, void *X, const int incX);
-void cblas_csscal(const int N, const float alpha, void *X, const int incX);
-void cblas_zdscal(const int N, const double alpha, void *X, const int incX);
-
-/*
- * Extra reference routines provided by ATLAS, but not mandated by the standard
- */
-void cblas_crotg(void *a, void *b, void *c, void *s);
-void cblas_zrotg(void *a, void *b, void *c, void *s);
-void cblas_csrot(const int N, void *X, const int incX, void *Y, const int incY,
-                 const float c, const float s);
-void cblas_zdrot(const int N, void *X, const int incX, void *Y, const int incY,
-                 const double c, const double s);
-
-/*
- * ===========================================================================
- * Prototypes for level 2 BLAS
- * ===========================================================================
- */
-
-/*
- * Routines with standard 4 prefixes (S, D, C, Z)
- */
-void cblas_sgemv(const enum CBLAS_ORDER Order,
-                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
-                 const float alpha, const float *A, const int lda,
-                 const float *X, const int incX, const float beta,
-                 float *Y, const int incY);
-void cblas_sgbmv(const enum CBLAS_ORDER Order,
-                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
-                 const int KL, const int KU, const float alpha,
-                 const float *A, const int lda, const float *X,
-                 const int incX, const float beta, float *Y, const int incY);
-void cblas_strmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const float *A, const int lda,
-                 float *X, const int incX);
-void cblas_stbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const int K, const float *A, const int lda,
-                 float *X, const int incX);
-void cblas_stpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const float *Ap, float *X, const int incX);
-void cblas_strsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const float *A, const int lda, float *X,
-                 const int incX);
-void cblas_stbsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const int K, const float *A, const int lda,
-                 float *X, const int incX);
-void cblas_stpsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const float *Ap, float *X, const int incX);
-
-void cblas_dgemv(const enum CBLAS_ORDER Order,
-                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
-                 const double alpha, const double *A, const int lda,
-                 const double *X, const int incX, const double beta,
-                 double *Y, const int incY);
-void cblas_dgbmv(const enum CBLAS_ORDER Order,
-                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
-                 const int KL, const int KU, const double alpha,
-                 const double *A, const int lda, const double *X,
-                 const int incX, const double beta, double *Y, const int incY);
-void cblas_dtrmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const double *A, const int lda,
-                 double *X, const int incX);
-void cblas_dtbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const int K, const double *A, const int lda,
-                 double *X, const int incX);
-void cblas_dtpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const double *Ap, double *X, const int incX);
-void cblas_dtrsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const double *A, const int lda, double *X,
-                 const int incX);
-void cblas_dtbsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const int K, const double *A, const int lda,
-                 double *X, const int incX);
-void cblas_dtpsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const double *Ap, double *X, const int incX);
-
-void cblas_cgemv(const enum CBLAS_ORDER Order,
-                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
-                 const void *alpha, const void *A, const int lda,
-                 const void *X, const int incX, const void *beta,
-                 void *Y, const int incY);
-void cblas_cgbmv(const enum CBLAS_ORDER Order,
-                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
-                 const int KL, const int KU, const void *alpha,
-                 const void *A, const int lda, const void *X,
-                 const int incX, const void *beta, void *Y, const int incY);
-void cblas_ctrmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const void *A, const int lda,
-                 void *X, const int incX);
-void cblas_ctbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const int K, const void *A, const int lda,
-                 void *X, const int incX);
-void cblas_ctpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const void *Ap, void *X, const int incX);
-void cblas_ctrsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const void *A, const int lda, void *X,
-                 const int incX);
-void cblas_ctbsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const int K, const void *A, const int lda,
-                 void *X, const int incX);
-void cblas_ctpsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const void *Ap, void *X, const int incX);
-
-void cblas_zgemv(const enum CBLAS_ORDER Order,
-                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
-                 const void *alpha, const void *A, const int lda,
-                 const void *X, const int incX, const void *beta,
-                 void *Y, const int incY);
-void cblas_zgbmv(const enum CBLAS_ORDER Order,
-                 const enum CBLAS_TRANSPOSE TransA, const int M, const int N,
-                 const int KL, const int KU, const void *alpha,
-                 const void *A, const int lda, const void *X,
-                 const int incX, const void *beta, void *Y, const int incY);
-void cblas_ztrmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const void *A, const int lda,
-                 void *X, const int incX);
-void cblas_ztbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const int K, const void *A, const int lda,
-                 void *X, const int incX);
-void cblas_ztpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const void *Ap, void *X, const int incX);
-void cblas_ztrsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const void *A, const int lda, void *X,
-                 const int incX);
-void cblas_ztbsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const int K, const void *A, const int lda,
-                 void *X, const int incX);
-void cblas_ztpsv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag,
-                 const int N, const void *Ap, void *X, const int incX);
-
-
-/*
- * Routines with S and D prefixes only
- */
-void cblas_ssymv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const int N, const float alpha, const float *A,
-                 const int lda, const float *X, const int incX,
-                 const float beta, float *Y, const int incY);
-void cblas_ssbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const int N, const int K, const float alpha, const float *A,
-                 const int lda, const float *X, const int incX,
-                 const float beta, float *Y, const int incY);
-void cblas_sspmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const int N, const float alpha, const float *Ap,
-                 const float *X, const int incX,
-                 const float beta, float *Y, const int incY);
-void cblas_sger(const enum CBLAS_ORDER Order, const int M, const int N,
-                const float alpha, const float *X, const int incX,
-                const float *Y, const int incY, float *A, const int lda);
-void cblas_ssyr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                const int N, const float alpha, const float *X,
-                const int incX, float *A, const int lda);
-void cblas_sspr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                const int N, const float alpha, const float *X,
-                const int incX, float *Ap);
-void cblas_ssyr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                const int N, const float alpha, const float *X,
-                const int incX, const float *Y, const int incY, float *A,
-                const int lda);
-void cblas_sspr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                const int N, const float alpha, const float *X,
-                const int incX, const float *Y, const int incY, float *A);
-
-void cblas_dsymv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const int N, const double alpha, const double *A,
-                 const int lda, const double *X, const int incX,
-                 const double beta, double *Y, const int incY);
-void cblas_dsbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const int N, const int K, const double alpha, const double *A,
-                 const int lda, const double *X, const int incX,
-                 const double beta, double *Y, const int incY);
-void cblas_dspmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const int N, const double alpha, const double *Ap,
-                 const double *X, const int incX,
-                 const double beta, double *Y, const int incY);
-void cblas_dger(const enum CBLAS_ORDER Order, const int M, const int N,
-                const double alpha, const double *X, const int incX,
-                const double *Y, const int incY, double *A, const int lda);
-void cblas_dsyr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                const int N, const double alpha, const double *X,
-                const int incX, double *A, const int lda);
-void cblas_dspr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                const int N, const double alpha, const double *X,
-                const int incX, double *Ap);
-void cblas_dsyr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                const int N, const double alpha, const double *X,
-                const int incX, const double *Y, const int incY, double *A,
-                const int lda);
-void cblas_dspr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                const int N, const double alpha, const double *X,
-                const int incX, const double *Y, const int incY, double *A);
-
-
-/*
- * Routines with C and Z prefixes only
- */
-void cblas_chemv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const int N, const void *alpha, const void *A,
-                 const int lda, const void *X, const int incX,
-                 const void *beta, void *Y, const int incY);
-void cblas_chbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const int N, const int K, const void *alpha, const void *A,
-                 const int lda, const void *X, const int incX,
-                 const void *beta, void *Y, const int incY);
-void cblas_chpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const int N, const void *alpha, const void *Ap,
-                 const void *X, const int incX,
-                 const void *beta, void *Y, const int incY);
-void cblas_cgeru(const enum CBLAS_ORDER Order, const int M, const int N,
-                 const void *alpha, const void *X, const int incX,
-                 const void *Y, const int incY, void *A, const int lda);
-void cblas_cgerc(const enum CBLAS_ORDER Order, const int M, const int N,
-                 const void *alpha, const void *X, const int incX,
-                 const void *Y, const int incY, void *A, const int lda);
-void cblas_cher(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                const int N, const float alpha, const void *X, const int incX,
-                void *A, const int lda);
-void cblas_chpr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                const int N, const float alpha, const void *X,
-                const int incX, void *A);
-void cblas_cher2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N,
-                const void *alpha, const void *X, const int incX,
-                const void *Y, const int incY, void *A, const int lda);
-void cblas_chpr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N,
-                const void *alpha, const void *X, const int incX,
-                const void *Y, const int incY, void *Ap);
-
-void cblas_zhemv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const int N, const void *alpha, const void *A,
-                 const int lda, const void *X, const int incX,
-                 const void *beta, void *Y, const int incY);
-void cblas_zhbmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const int N, const int K, const void *alpha, const void *A,
-                 const int lda, const void *X, const int incX,
-                 const void *beta, void *Y, const int incY);
-void cblas_zhpmv(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const int N, const void *alpha, const void *Ap,
-                 const void *X, const int incX,
-                 const void *beta, void *Y, const int incY);
-void cblas_zgeru(const enum CBLAS_ORDER Order, const int M, const int N,
-                 const void *alpha, const void *X, const int incX,
-                 const void *Y, const int incY, void *A, const int lda);
-void cblas_zgerc(const enum CBLAS_ORDER Order, const int M, const int N,
-                 const void *alpha, const void *X, const int incX,
-                 const void *Y, const int incY, void *A, const int lda);
-void cblas_zher(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                const int N, const double alpha, const void *X, const int incX,
-                void *A, const int lda);
-void cblas_zhpr(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                const int N, const double alpha, const void *X,
-                const int incX, void *A);
-void cblas_zher2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N,
-                const void *alpha, const void *X, const int incX,
-                const void *Y, const int incY, void *A, const int lda);
-void cblas_zhpr2(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const int N,
-                const void *alpha, const void *X, const int incX,
-                const void *Y, const int incY, void *Ap);
-
-/*
- * ===========================================================================
- * Prototypes for level 3 BLAS
- * ===========================================================================
- */
-
-/*
- * Routines with standard 4 prefixes (S, D, C, Z)
- */
-void cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
-                 const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
-                 const int K, const float alpha, const float *A,
-                 const int lda, const float *B, const int ldb,
-                 const float beta, float *C, const int ldc);
-void cblas_ssymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const int M, const int N,
-                 const float alpha, const float *A, const int lda,
-                 const float *B, const int ldb, const float beta,
-                 float *C, const int ldc);
-void cblas_ssyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
-                 const float alpha, const float *A, const int lda,
-                 const float beta, float *C, const int ldc);
-void cblas_ssyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                  const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
-                  const float alpha, const float *A, const int lda,
-                  const float *B, const int ldb, const float beta,
-                  float *C, const int ldc);
-void cblas_strmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
-                 const enum CBLAS_DIAG Diag, const int M, const int N,
-                 const float alpha, const float *A, const int lda,
-                 float *B, const int ldb);
-void cblas_strsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
-                 const enum CBLAS_DIAG Diag, const int M, const int N,
-                 const float alpha, const float *A, const int lda,
-                 float *B, const int ldb);
-
-void cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
-                 const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
-                 const int K, const double alpha, const double *A,
-                 const int lda, const double *B, const int ldb,
-                 const double beta, double *C, const int ldc);
-void cblas_dsymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const int M, const int N,
-                 const double alpha, const double *A, const int lda,
-                 const double *B, const int ldb, const double beta,
-                 double *C, const int ldc);
-void cblas_dsyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
-                 const double alpha, const double *A, const int lda,
-                 const double beta, double *C, const int ldc);
-void cblas_dsyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                  const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
-                  const double alpha, const double *A, const int lda,
-                  const double *B, const int ldb, const double beta,
-                  double *C, const int ldc);
-void cblas_dtrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
-                 const enum CBLAS_DIAG Diag, const int M, const int N,
-                 const double alpha, const double *A, const int lda,
-                 double *B, const int ldb);
-void cblas_dtrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
-                 const enum CBLAS_DIAG Diag, const int M, const int N,
-                 const double alpha, const double *A, const int lda,
-                 double *B, const int ldb);
-
-void cblas_cgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
-                 const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
-                 const int K, const void *alpha, const void *A,
-                 const int lda, const void *B, const int ldb,
-                 const void *beta, void *C, const int ldc);
-void cblas_csymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const int M, const int N,
-                 const void *alpha, const void *A, const int lda,
-                 const void *B, const int ldb, const void *beta,
-                 void *C, const int ldc);
-void cblas_csyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
-                 const void *alpha, const void *A, const int lda,
-                 const void *beta, void *C, const int ldc);
-void cblas_csyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                  const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
-                  const void *alpha, const void *A, const int lda,
-                  const void *B, const int ldb, const void *beta,
-                  void *C, const int ldc);
-void cblas_ctrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
-                 const enum CBLAS_DIAG Diag, const int M, const int N,
-                 const void *alpha, const void *A, const int lda,
-                 void *B, const int ldb);
-void cblas_ctrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
-                 const enum CBLAS_DIAG Diag, const int M, const int N,
-                 const void *alpha, const void *A, const int lda,
-                 void *B, const int ldb);
-
-void cblas_zgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
-                 const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
-                 const int K, const void *alpha, const void *A,
-                 const int lda, const void *B, const int ldb,
-                 const void *beta, void *C, const int ldc);
-void cblas_zsymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const int M, const int N,
-                 const void *alpha, const void *A, const int lda,
-                 const void *B, const int ldb, const void *beta,
-                 void *C, const int ldc);
-void cblas_zsyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
-                 const void *alpha, const void *A, const int lda,
-                 const void *beta, void *C, const int ldc);
-void cblas_zsyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                  const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
-                  const void *alpha, const void *A, const int lda,
-                  const void *B, const int ldb, const void *beta,
-                  void *C, const int ldc);
-void cblas_ztrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
-                 const enum CBLAS_DIAG Diag, const int M, const int N,
-                 const void *alpha, const void *A, const int lda,
-                 void *B, const int ldb);
-void cblas_ztrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA,
-                 const enum CBLAS_DIAG Diag, const int M, const int N,
-                 const void *alpha, const void *A, const int lda,
-                 void *B, const int ldb);
-
-
-/*
- * Routines with prefixes C and Z only
- */
-void cblas_chemm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const int M, const int N,
-                 const void *alpha, const void *A, const int lda,
-                 const void *B, const int ldb, const void *beta,
-                 void *C, const int ldc);
-void cblas_cherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
-                 const float alpha, const void *A, const int lda,
-                 const float beta, void *C, const int ldc);
-void cblas_cher2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                  const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
-                  const void *alpha, const void *A, const int lda,
-                  const void *B, const int ldb, const float beta,
-                  void *C, const int ldc);
-void cblas_zhemm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side,
-                 const enum CBLAS_UPLO Uplo, const int M, const int N,
-                 const void *alpha, const void *A, const int lda,
-                 const void *B, const int ldb, const void *beta,
-                 void *C, const int ldc);
-void cblas_zherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                 const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
-                 const double alpha, const void *A, const int lda,
-                 const double beta, void *C, const int ldc);
-void cblas_zher2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                  const enum CBLAS_TRANSPOSE Trans, const int N, const int K,
-                  const void *alpha, const void *A, const int lda,
-                  const void *B, const int ldb, const double beta,
-                  void *C, const int ldc);
-
-int cblas_errprn(int ierr, int info, char *form, ...);
-
-#endif  /* end #ifdef CBLAS_ENUM_ONLY */
-#endif
--- a/segmentino/build/linux/amd64/clapack.h	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*
- *             Automatically Tuned Linear Algebra Software v3.8.0
- *                    (C) Copyright 1999 R. Clint Whaley
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions, and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *   3. The name of the ATLAS group or the names of its contributers may
- *      not be used to endorse or promote products derived from this
- *      software without specific written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ATLAS GROUP OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef CLAPACK_H
-
-#define CLAPACK_H
-#include "cblas.h"
-
-#ifndef ATLAS_ORDER
-   #define ATLAS_ORDER CBLAS_ORDER
-#endif
-#ifndef ATLAS_UPLO
-   #define ATLAS_UPLO CBLAS_UPLO
-#endif
-#ifndef ATLAS_DIAG
-   #define ATLAS_DIAG CBLAS_DIAG
-#endif
-int clapack_sgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS,
-                  float *A, const int lda, int *ipiv,
-                  float *B, const int ldb);
-int clapack_sgetrf(const enum CBLAS_ORDER Order, const int M, const int N,
-                   float *A, const int lda, int *ipiv);
-int clapack_sgetrs
-   (const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE Trans,
-    const int N, const int NRHS, const float *A, const int lda,
-    const int *ipiv, float *B, const int ldb);
-int clapack_sgetri(const enum CBLAS_ORDER Order, const int N, float *A,
-                   const int lda, const int *ipiv);
-int clapack_sposv(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                  const int N, const int NRHS, float *A, const int lda,
-                  float *B, const int ldb);
-int clapack_spotrf(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                   const int N, float *A, const int lda);
-int clapack_spotrs(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                   const int N, const int NRHS, const float *A, const int lda,
-                   float *B, const int ldb);
-int clapack_spotri(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                   const int N, float *A, const int lda);
-int clapack_slauum(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                   const int N, float *A, const int lda);
-int clapack_strtri(const enum ATLAS_ORDER Order,const enum ATLAS_UPLO Uplo,
-                  const enum ATLAS_DIAG Diag,const int N, float *A, const int lda);
-
-int clapack_dgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS,
-                  double *A, const int lda, int *ipiv,
-                  double *B, const int ldb);
-int clapack_dgetrf(const enum CBLAS_ORDER Order, const int M, const int N,
-                   double *A, const int lda, int *ipiv);
-int clapack_dgetrs
-   (const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE Trans,
-    const int N, const int NRHS, const double *A, const int lda,
-    const int *ipiv, double *B, const int ldb);
-int clapack_dgetri(const enum CBLAS_ORDER Order, const int N, double *A,
-                   const int lda, const int *ipiv);
-int clapack_dposv(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                  const int N, const int NRHS, double *A, const int lda,
-                  double *B, const int ldb);
-int clapack_dpotrf(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                   const int N, double *A, const int lda);
-int clapack_dpotrs(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                   const int N, const int NRHS, const double *A, const int lda,
-                   double *B, const int ldb);
-int clapack_dpotri(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                   const int N, double *A, const int lda);
-int clapack_dlauum(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                   const int N, double *A, const int lda);
-int clapack_dtrtri(const enum ATLAS_ORDER Order,const enum ATLAS_UPLO Uplo,
-                  const enum ATLAS_DIAG Diag,const int N, double *A, const int lda);
-
-int clapack_cgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS,
-                  void *A, const int lda, int *ipiv,
-                  void *B, const int ldb);
-int clapack_cgetrf(const enum CBLAS_ORDER Order, const int M, const int N,
-                   void *A, const int lda, int *ipiv);
-int clapack_cgetrs
-   (const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE Trans,
-    const int N, const int NRHS, const void *A, const int lda,
-    const int *ipiv, void *B, const int ldb);
-int clapack_cgetri(const enum CBLAS_ORDER Order, const int N, void *A,
-                   const int lda, const int *ipiv);
-int clapack_cposv(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                  const int N, const int NRHS, void *A, const int lda,
-                  void *B, const int ldb);
-int clapack_cpotrf(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                   const int N, void *A, const int lda);
-int clapack_cpotrs(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                   const int N, const int NRHS, const void *A, const int lda,
-                   void *B, const int ldb);
-int clapack_cpotri(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                   const int N, void *A, const int lda);
-int clapack_clauum(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                   const int N, void *A, const int lda);
-int clapack_ctrtri(const enum ATLAS_ORDER Order,const enum ATLAS_UPLO Uplo,
-                  const enum ATLAS_DIAG Diag,const int N, void *A, const int lda);
-
-int clapack_zgesv(const enum CBLAS_ORDER Order, const int N, const int NRHS,
-                  void *A, const int lda, int *ipiv,
-                  void *B, const int ldb);
-int clapack_zgetrf(const enum CBLAS_ORDER Order, const int M, const int N,
-                   void *A, const int lda, int *ipiv);
-int clapack_zgetrs
-   (const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE Trans,
-    const int N, const int NRHS, const void *A, const int lda,
-    const int *ipiv, void *B, const int ldb);
-int clapack_zgetri(const enum CBLAS_ORDER Order, const int N, void *A,
-                   const int lda, const int *ipiv);
-int clapack_zposv(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                  const int N, const int NRHS, void *A, const int lda,
-                  void *B, const int ldb);
-int clapack_zpotrf(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                   const int N, void *A, const int lda);
-int clapack_zpotrs(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo,
-                   const int N, const int NRHS, const void *A, const int lda,
-                   void *B, const int ldb);
-int clapack_zpotri(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                   const int N, void *A, const int lda);
-int clapack_zlauum(const enum ATLAS_ORDER Order, const enum ATLAS_UPLO Uplo,
-                   const int N, void *A, const int lda);
-int clapack_ztrtri(const enum ATLAS_ORDER Order,const enum ATLAS_UPLO Uplo,
-                  const enum ATLAS_DIAG Diag,const int N, void *A, const int lda);
-
-#endif
Binary file segmentino/build/linux/amd64/libatlas.a has changed
Binary file segmentino/build/linux/amd64/libcblas.a has changed
Binary file segmentino/build/linux/amd64/libf77blas.a has changed
Binary file segmentino/build/linux/amd64/liblapack.a has changed
Binary file segmentino/build/mingw32/atlas.lib has changed
Binary file segmentino/build/mingw32/cblas.lib has changed
Binary file segmentino/build/mingw32/f77blas.lib has changed
--- a/segmentino/build/mingw32/g2cstubs.c	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-
-void s_wsfe() { }
-void do_fio() { }
-void e_wsfe() { }
-void s_stop() { }
Binary file segmentino/build/mingw32/g2cstubs.lib has changed
Binary file segmentino/build/mingw32/lapack.lib has changed
--- a/segmentino/g2cstubs.c	Thu Jun 13 09:43:01 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-
-void s_wsfe() { }
-void do_fio() { }
-void e_wsfe() { }
-void s_stop() { }