From 3c2194bd73ead4c0f9ab0cb539250023d50b0355 Mon Sep 17 00:00:00 2001 From: Simon Praetorius <simon.praetorius@tu-dresden.de> Date: Fri, 29 Apr 2016 15:21:19 +0200 Subject: [PATCH] cleanup for updated dune-* modules --- dune/amdis/AMDiS.cpp | 10 +- dune/amdis/AMDiS.hpp | 3 +- dune/amdis/DirichletBC.inc.hpp | 7 +- dune/amdis/Log.hpp | 2 +- dune/amdis/Operator.inc.hpp | 2 +- dune/amdis/ProblemInstat.hpp | 2 +- dune/amdis/ProblemInstatBase.hpp | 2 +- dune/amdis/ProblemStat.hpp | 12 +- dune/amdis/ProblemStat.inc.hpp | 3 - .../linear_algebra/LinearAlgebraBase.hpp | 37 + .../linear_algebra/LinearSolverInterface.hpp | 2 +- dune/amdis/linear_algebra/RunnerInterface.hpp | 4 +- dune/amdis/linear_algebra/SolverInfo.hpp | 2 + .../linear_algebra/mtl/BlockMTLVector.hpp | 5 +- dune/amdis/linear_algebra/mtl/DOFVector.hpp | 6 +- .../amdis/linear_algebra/mtl/LinearSolver.hpp | 2 +- .../linear_algebra/mtl/MTLDenseVector.hpp | 49 + .../amdis/linear_algebra/mtl/SystemVector.hpp | 5 +- .../numeric/itl/iteration/basic_iteration.hpp | 151 ++ .../itl/iteration/cyclic_iteration.hpp | 96 + .../numeric/itl/iteration/noisy_iteration.hpp | 34 + install/MTL/include/boost/numeric/itl/itl.hpp | 62 + .../MTL/include/boost/numeric/itl/itl_fwd.hpp | 90 + .../include/boost/numeric/itl/krylov/bicg.hpp | 115 ++ .../boost/numeric/itl/krylov/bicgstab.hpp | 120 ++ .../boost/numeric/itl/krylov/bicgstab_2.hpp | 182 ++ .../boost/numeric/itl/krylov/bicgstab_ell.hpp | 177 ++ .../include/boost/numeric/itl/krylov/cg.hpp | 163 ++ .../include/boost/numeric/itl/krylov/cgs.hpp | 110 ++ .../include/boost/numeric/itl/krylov/fsm.hpp | 39 + .../boost/numeric/itl/krylov/gmres.hpp | 181 ++ .../boost/numeric/itl/krylov/idr_s.hpp | 144 ++ .../include/boost/numeric/itl/krylov/qmr.hpp | 150 ++ .../numeric/itl/krylov/repeating_solver.hpp | 52 + .../boost/numeric/itl/krylov/tfqmr.hpp | 135 ++ .../numeric/itl/minimization/quasi_newton.hpp | 61 + .../boost/numeric/itl/pc/binary_heap.hpp | 607 +++++++ .../boost/numeric/itl/pc/comparators.hpp | 64 + .../include/boost/numeric/itl/pc/concat.hpp | 117 ++ .../include/boost/numeric/itl/pc/diagonal.hpp | 108 ++ .../MTL/include/boost/numeric/itl/pc/ic_0.hpp | 278 +++ .../include/boost/numeric/itl/pc/identity.hpp | 76 + .../MTL/include/boost/numeric/itl/pc/ilu.hpp | 212 +++ .../include/boost/numeric/itl/pc/ilu_0.hpp | 99 ++ .../MTL/include/boost/numeric/itl/pc/ilut.hpp | 137 ++ .../boost/numeric/itl/pc/imf_algorithms.hpp | 821 +++++++++ .../numeric/itl/pc/imf_preconditioner.hpp | 169 ++ .../boost/numeric/itl/pc/is_identity.hpp | 41 + .../numeric/itl/pc/matrix_algorithms.hpp | 74 + .../include/boost/numeric/itl/pc/solver.hpp | 56 + .../include/boost/numeric/itl/pc/sorting.hpp | 307 ++++ .../boost/numeric/itl/pc/sub_matrix_pc.hpp | 198 +++ .../numeric/itl/smoother/gauss_seidel.hpp | 137 ++ .../boost/numeric/itl/smoother/jacobi.hpp | 139 ++ .../boost/numeric/itl/smoother/jor.hpp | 140 ++ .../itl/smoother/relaxation_parameter.hpp | 28 + .../boost/numeric/itl/smoother/repeated.hpp | 50 + .../boost/numeric/itl/smoother/sor.hpp | 138 ++ .../boost/numeric/itl/stepper/armijo.hpp | 53 + .../boost/numeric/itl/stepper/wolf.hpp | 55 + .../boost/numeric/itl/updater/bfgs.hpp | 44 + .../boost/numeric/itl/updater/broyden.hpp | 45 + .../include/boost/numeric/itl/updater/dfp.hpp | 46 + .../include/boost/numeric/itl/updater/psb.hpp | 44 + .../include/boost/numeric/itl/updater/sr1.hpp | 40 + .../boost/numeric/itl/utility/exception.hpp | 35 + .../numeric/linear_algebra/accumulate.hpp | 66 + .../linear_algebra/algebraic_concepts.hpp | 521 ++++++ .../numeric/linear_algebra/concept_maps.hpp | 87 + .../boost/numeric/linear_algebra/concepts.hpp | 602 +++++++ .../numeric/linear_algebra/ets_concepts.hpp | 47 + .../boost/numeric/linear_algebra/identity.hpp | 208 +++ .../linear_algebra/intrinsic_concept_maps.hpp | 116 ++ .../boost/numeric/linear_algebra/inverse.hpp | 65 + .../numeric/linear_algebra/is_invertible.hpp | 82 + .../linear_algebra/linear_operator.hpp | 247 +++ .../numeric/linear_algebra/new_concepts.hpp | 586 +++++++ .../numeric/linear_algebra/old_concepts.hpp | 1159 ++++++++++++ .../numeric/linear_algebra/operators.hpp | 156 ++ .../boost/numeric/linear_algebra/power.hpp | 198 +++ .../numeric/linear_algebra/pseudo_concept.hpp | 34 + .../linear_algebra/vector_concepts.hpp | 508 ++++++ .../include/boost/numeric/meta_math/abs.hpp | 27 + .../boost/numeric/meta_math/is_power_of_2.hpp | 28 + .../boost/numeric/meta_math/is_prime.hpp | 95 + .../meta_math/least_significant_one_bit.hpp | 27 + .../include/boost/numeric/meta_math/log_2.hpp | 43 + .../include/boost/numeric/meta_math/loop.hpp | 20 + .../include/boost/numeric/meta_math/loop1.hpp | 36 + .../include/boost/numeric/meta_math/loop2.hpp | 46 + .../include/boost/numeric/meta_math/loop3.hpp | 96 + .../include/boost/numeric/meta_math/max.hpp | 27 + .../include/boost/numeric/meta_math/min.hpp | 27 + .../boost/numeric/meta_math/power_of_2.hpp | 30 + .../include/boost/numeric/meta_math/sqrt.hpp | 59 + .../boost/numeric/mtl/concept/collection.hpp | 1457 +++++++++++++++ .../boost/numeric/mtl/concept/magnitude.hpp | 88 + .../boost/numeric/mtl/concept/matrix.hpp | 468 +++++ .../numeric/mtl/concept/static_functor.hpp | 76 + .../boost/numeric/mtl/concept/std_concept.hpp | 286 +++ .../boost/numeric/mtl/concept/vector.hpp | 142 ++ .../MTL/include/boost/numeric/mtl/config.hpp | 97 + .../boost/numeric/mtl/detail/base_cursor.hpp | 105 ++ .../mtl/detail/contiguous_memory_block.hpp | 493 ++++++ .../boost/numeric/mtl/detail/dilated_int.hpp | 255 +++ .../numeric/mtl/detail/dilation_table.hpp | 143 ++ .../boost/numeric/mtl/detail/index.hpp | 72 + .../mtl/detail/masked_dilation_tables.hpp | 290 +++ .../numeric/mtl/detail/range_generator.hpp | 307 ++++ .../mtl/detail/strided_base_cursor.hpp | 80 + .../numeric/mtl/detail/trivial_inserter.hpp | 103 ++ .../boost/numeric/mtl/interface/arprec.hpp | 61 + .../boost/numeric/mtl/interface/blas.hpp | 165 ++ .../boost/numeric/mtl/interface/lapack.hpp | 48 + .../numeric/mtl/interface/umfpack_solve.hpp | 570 ++++++ .../boost/numeric/mtl/interface/vpt.cpp | 443 +++++ .../boost/numeric/mtl/interface/vpt.hpp | 94 + .../include/boost/numeric/mtl/interfaces.hpp | 18 + .../boost/numeric/mtl/io/functor_symbol.hpp | 90 + .../boost/numeric/mtl/io/matrix_file.hpp | 41 + .../boost/numeric/mtl/io/matrix_market.hpp | 335 ++++ .../MTL/include/boost/numeric/mtl/io/path.hpp | 54 + .../boost/numeric/mtl/io/read_el_matrix.hpp | 165 ++ .../boost/numeric/mtl/io/read_filter.hpp | 42 + .../boost/numeric/mtl/io/test_ostream.hpp | 69 + .../boost/numeric/mtl/io/write_ast.hpp | 35 + .../numeric/mtl/io/write_ast_dispatch.hpp | 162 ++ .../include/boost/numeric/mtl/matrices.hpp | 49 + .../boost/numeric/mtl/matrix/all_mat_expr.hpp | 28 + .../boost/numeric/mtl/matrix/banded_view.hpp | 262 +++ .../boost/numeric/mtl/matrix/bands.hpp | 48 + .../boost/numeric/mtl/matrix/base_matrix.hpp | 190 ++ .../numeric/mtl/matrix/base_sub_matrix.hpp | 237 +++ .../numeric/mtl/matrix/block_diagonal2D.hpp | 255 +++ .../boost/numeric/mtl/matrix/compressed2D.hpp | 1340 ++++++++++++++ .../boost/numeric/mtl/matrix/coordinate2D.hpp | 495 ++++++ .../numeric/mtl/matrix/crtp_base_matrix.hpp | 737 ++++++++ .../boost/numeric/mtl/matrix/dense2D.hpp | 910 ++++++++++ .../numeric/mtl/matrix/diagonal_setup.hpp | 48 + .../boost/numeric/mtl/matrix/dimension.hpp | 117 ++ .../boost/numeric/mtl/matrix/element.hpp | 504 ++++++ .../numeric/mtl/matrix/element_array.hpp | 51 + .../numeric/mtl/matrix/element_matrix.hpp | 49 + .../numeric/mtl/matrix/element_structure.hpp | 300 ++++ .../boost/numeric/mtl/matrix/ell_matrix.hpp | 209 +++ .../numeric/mtl/matrix/hermitian_view.hpp | 127 ++ .../numeric/mtl/matrix/hessian_setup.hpp | 100 ++ .../boost/numeric/mtl/matrix/identity.hpp | 38 + .../boost/numeric/mtl/matrix/identity2D.hpp | 83 + .../numeric/mtl/matrix/implicit_dense.hpp | 279 +++ .../boost/numeric/mtl/matrix/indirect.hpp | 69 + .../boost/numeric/mtl/matrix/inserter.hpp | 90 + .../numeric/mtl/matrix/laplacian_setup.hpp | 47 + .../boost/numeric/mtl/matrix/lower.hpp | 38 + .../matrix/make_fast_multi_vector_expr.hpp | 70 + .../boost/numeric/mtl/matrix/map_view.hpp | 581 ++++++ .../numeric/mtl/matrix/mapped_inserter.hpp | 94 + .../boost/numeric/mtl/matrix/mat_expr.hpp | 46 + .../numeric/mtl/matrix/mat_mat_asgn_expr.hpp | 27 + .../mtl/matrix/mat_mat_ele_times_expr.hpp | 62 + .../numeric/mtl/matrix/mat_mat_minus_expr.hpp | 60 + .../numeric/mtl/matrix/mat_mat_op_expr.hpp | 100 ++ .../numeric/mtl/matrix/mat_mat_plus_expr.hpp | 73 + .../numeric/mtl/matrix/mat_mat_times_expr.hpp | 120 ++ .../numeric/mtl/matrix/mat_negate_expr.hpp | 30 + .../boost/numeric/mtl/matrix/morton_dense.hpp | 895 ++++++++++ .../boost/numeric/mtl/matrix/multi_vector.hpp | 227 +++ .../numeric/mtl/matrix/multi_vector_range.hpp | 53 + .../boost/numeric/mtl/matrix/operators.hpp | 100 ++ .../boost/numeric/mtl/matrix/parameter.hpp | 51 + .../boost/numeric/mtl/matrix/permutation.hpp | 59 + .../mtl/matrix/poisson2D_dirichlet.hpp | 104 ++ .../boost/numeric/mtl/matrix/reorder.hpp | 65 + .../mtl/matrix/reorder_matrix_rows.hpp | 51 + .../boost/numeric/mtl/matrix/reorder_ref.hpp | 53 + .../numeric/mtl/matrix/shifted_inserter.hpp | 74 + .../numeric/mtl/matrix/sparse_banded.hpp | 360 ++++ .../boost/numeric/mtl/matrix/strict_lower.hpp | 46 + .../boost/numeric/mtl/matrix/strict_upper.hpp | 48 + .../numeric/mtl/matrix/transposed_view.hpp | 298 ++++ .../boost/numeric/mtl/matrix/upper.hpp | 41 + .../boost/numeric/mtl/matrix/view_ref.hpp | 55 + install/MTL/include/boost/numeric/mtl/mtl.hpp | 20 + .../boost/numeric/mtl/mtl_conditional_fwd.hpp | 41 + .../MTL/include/boost/numeric/mtl/mtl_fwd.hpp | 450 +++++ .../boost/numeric/mtl/operation/adjoint.hpp | 43 + .../numeric/mtl/operation/adjust_cursor.hpp | 27 + .../mtl/operation/assign_each_nonzero.hpp | 59 + .../numeric/mtl/operation/assign_mode.hpp | 210 +++ .../numeric/mtl/operation/bin_op_expr.hpp | 37 + .../boost/numeric/mtl/operation/cholesky.hpp | 615 +++++++ .../boost/numeric/mtl/operation/clone.hpp | 68 + .../mtl/operation/column_in_matrix.hpp | 97 + .../numeric/mtl/operation/compute_factors.hpp | 92 + .../numeric/mtl/operation/compute_summand.hpp | 82 + .../boost/numeric/mtl/operation/conj.hpp | 146 ++ .../boost/numeric/mtl/operation/copy.hpp | 299 ++++ .../boost/numeric/mtl/operation/copysign.hpp | 86 + .../boost/numeric/mtl/operation/crop.hpp | 50 + .../boost/numeric/mtl/operation/cross.hpp | 69 + .../boost/numeric/mtl/operation/cuppen.hpp | 133 ++ .../mtl/operation/cursor_pseudo_dot.hpp | 90 + .../boost/numeric/mtl/operation/diagonal.hpp | 69 + .../numeric/mtl/operation/div_result.hpp | 52 + .../boost/numeric/mtl/operation/divide_by.hpp | 94 + .../mtl/operation/divide_by_inplace.hpp | 40 + .../numeric/mtl/operation/dmat_dmat_mult.hpp | 1067 +++++++++++ .../boost/numeric/mtl/operation/dot.hpp | 268 +++ .../numeric/mtl/operation/eigenvalue.hpp | 256 +++ .../mtl/operation/eigenvalue_symmetric.hpp | 177 ++ .../element_structure_algorithms.hpp | 256 +++ .../boost/numeric/mtl/operation/entry1D.hpp | 55 + .../numeric/mtl/operation/entry_similar.hpp | 70 + .../numeric/mtl/operation/evaluate_lazy.hpp | 37 + .../mtl/operation/extended_complex.hpp | 206 +++ .../boost/numeric/mtl/operation/fill.hpp | 35 + .../numeric/mtl/operation/frobenius_norm.hpp | 54 + .../boost/numeric/mtl/operation/fuse.hpp | 44 + .../numeric/mtl/operation/fused_expr.hpp | 153 ++ .../mtl/operation/fused_index_evaluator.hpp | 45 + .../boost/numeric/mtl/operation/givens.hpp | 129 ++ .../boost/numeric/mtl/operation/hermitian.hpp | 58 + .../numeric/mtl/operation/hessenberg.hpp | 194 ++ .../numeric/mtl/operation/householder.hpp | 90 + .../boost/numeric/mtl/operation/imag.hpp | 90 + .../numeric/mtl/operation/index_evaluator.hpp | 94 + .../numeric/mtl/operation/infinity_norm.hpp | 98 ++ .../boost/numeric/mtl/operation/inv.hpp | 171 ++ .../numeric/mtl/operation/invert_diagonal.hpp | 59 + .../boost/numeric/mtl/operation/iota.hpp | 32 + .../numeric/mtl/operation/is_negative.hpp | 31 + .../boost/numeric/mtl/operation/lazy.hpp | 55 + .../numeric/mtl/operation/lazy_assign.hpp | 35 + .../mtl/operation/left_scale_inplace.hpp | 76 + .../mtl/operation/look_at_each_nonzero.hpp | 96 + .../numeric/mtl/operation/lower_trisolve.hpp | 292 +++ .../boost/numeric/mtl/operation/lu.hpp | 241 +++ .../numeric/mtl/operation/make_sparse.hpp | 118 ++ .../numeric/mtl/operation/make_tag_vector.hpp | 34 + .../mtl/operation/mat_cvec_times_expr.hpp | 46 + .../numeric/mtl/operation/mat_vec_mult.hpp | 843 +++++++++ .../numeric/mtl/operation/matrix_bracket.hpp | 101 ++ .../boost/numeric/mtl/operation/max.hpp | 66 + .../numeric/mtl/operation/max_abs_pos.hpp | 90 + .../numeric/mtl/operation/max_of_sums.hpp | 74 + .../boost/numeric/mtl/operation/max_pos.hpp | 146 ++ .../mtl/operation/merge_complex_matrix.hpp | 23 + .../mtl/operation/merge_complex_vector.hpp | 44 + .../boost/numeric/mtl/operation/min.hpp | 64 + .../boost/numeric/mtl/operation/min_pos.hpp | 71 + .../mtl/operation/minimal_increase.hpp | 35 + .../boost/numeric/mtl/operation/misc.hpp | 28 + .../boost/numeric/mtl/operation/mult.hpp | 335 ++++ .../mtl/operation/mult_assign_mode.hpp | 148 ++ .../numeric/mtl/operation/mult_result.hpp | 156 ++ .../numeric/mtl/operation/mult_specialize.hpp | 54 + .../mtl/operation/multi_action_block.hpp | 80 + .../boost/numeric/mtl/operation/no_op.hpp | 22 + .../boost/numeric/mtl/operation/norms.hpp | 21 + .../boost/numeric/mtl/operation/num_cols.hpp | 63 + .../boost/numeric/mtl/operation/num_rows.hpp | 63 + .../boost/numeric/mtl/operation/one_norm.hpp | 96 + .../boost/numeric/mtl/operation/ones.hpp | 42 + .../boost/numeric/mtl/operation/operators.hpp | 125 ++ .../mtl/operation/opteron/matrix_mult.hpp | 1562 +++++++++++++++++ .../boost/numeric/mtl/operation/orth.hpp | 172 ++ .../boost/numeric/mtl/operation/print.hpp | 100 ++ .../numeric/mtl/operation/print_matrix.hpp | 52 + .../numeric/mtl/operation/print_size.hpp | 55 + .../numeric/mtl/operation/print_vector.hpp | 42 + .../boost/numeric/mtl/operation/product.hpp | 71 + .../boost/numeric/mtl/operation/qr.hpp | 110 ++ .../boost/numeric/mtl/operation/qr_givens.hpp | 159 ++ .../boost/numeric/mtl/operation/random.hpp | 117 ++ .../numeric/mtl/operation/rank_one_update.hpp | 56 + .../numeric/mtl/operation/rank_two_update.hpp | 32 + .../boost/numeric/mtl/operation/raw_copy.hpp | 35 + .../boost/numeric/mtl/operation/real.hpp | 93 + .../boost/numeric/mtl/operation/resource.hpp | 54 + .../mtl/operation/right_scale_inplace.hpp | 80 + .../numeric/mtl/operation/row_in_matrix.hpp | 105 ++ .../boost/numeric/mtl/operation/rscale.hpp | 112 ++ .../numeric/mtl/operation/rvec_mat_mult.hpp | 219 +++ .../boost/numeric/mtl/operation/scale.hpp | 108 ++ .../boost/numeric/mtl/operation/secular.hpp | 117 ++ .../numeric/mtl/operation/set_to_zero.hpp | 178 ++ .../boost/numeric/mtl/operation/sfunctor.hpp | 431 +++++ .../numeric/mtl/operation/shift_block.hpp | 41 + .../mtl/operation/shift_block_detail.hpp | 58 + .../boost/numeric/mtl/operation/signum.hpp | 63 + .../boost/numeric/mtl/operation/size.hpp | 68 + .../boost/numeric/mtl/operation/size1D.hpp | 70 + .../numeric/mtl/operation/smat_dmat_mult.hpp | 271 +++ .../numeric/mtl/operation/smat_smat_mult.hpp | 198 +++ .../boost/numeric/mtl/operation/solve.hpp | 55 + .../boost/numeric/mtl/operation/sort.hpp | 204 +++ .../mtl/operation/split_complex_matrix.hpp | 40 + .../mtl/operation/split_complex_vector.hpp | 46 + .../numeric/mtl/operation/squared_abs.hpp | 59 + .../numeric/mtl/operation/static_num_cols.hpp | 89 + .../numeric/mtl/operation/static_num_rows.hpp | 89 + .../numeric/mtl/operation/static_size.hpp | 33 + .../mtl/operation/std_output_operator.hpp | 64 + .../numeric/mtl/operation/sub_matrix.hpp | 83 + .../boost/numeric/mtl/operation/sum.hpp | 70 + .../boost/numeric/mtl/operation/svd.hpp | 99 ++ .../boost/numeric/mtl/operation/swap_row.hpp | 91 + .../boost/numeric/mtl/operation/tfunctor.hpp | 21 + .../numeric/mtl/operation/tfunctor_mixed.hpp | 154 ++ .../boost/numeric/mtl/operation/trace.hpp | 50 + .../boost/numeric/mtl/operation/trans.hpp | 124 ++ .../boost/numeric/mtl/operation/two_norm.hpp | 73 + .../boost/numeric/mtl/operation/unary_dot.hpp | 75 + .../boost/numeric/mtl/operation/unroll.hpp | 44 + .../boost/numeric/mtl/operation/update.hpp | 289 +++ .../numeric/mtl/operation/upper_trisolve.hpp | 281 +++ .../include/boost/numeric/mtl/operations.hpp | 113 ++ .../numeric/mtl/recursion/base_case_cast.hpp | 40 + .../mtl/recursion/base_case_matrix.hpp | 50 + .../numeric/mtl/recursion/base_case_test.hpp | 125 ++ .../numeric/mtl/recursion/bit_masking.hpp | 259 +++ .../numeric/mtl/recursion/dim_splitter.hpp | 154 ++ .../boost/numeric/mtl/recursion/for_each.hpp | 63 + .../mtl/recursion/matrix_recursator.hpp | 543 ++++++ .../mtl/recursion/predefined_masks.hpp | 90 + .../recursion/simplify_base_case_matrix.hpp | 98 ++ .../boost/numeric/mtl/recursion/utility.hpp | 66 + .../MTL/include/boost/numeric/mtl/types.hpp | 34 + .../boost/numeric/mtl/utility/add_const.hpp | 72 + .../mtl/utility/algebraic_category.hpp | 39 + .../boost/numeric/mtl/utility/ashape.hpp | 724 ++++++++ .../boost/numeric/mtl/utility/category.hpp | 304 ++++ .../numeric/mtl/utility/common_include.hpp | 37 + .../boost/numeric/mtl/utility/complexity.hpp | 193 ++ .../numeric/mtl/utility/compose_view.hpp | 65 + .../copy_expression_const_ref_container.hpp | 78 + .../numeric/mtl/utility/dense_el_cursor.hpp | 53 + .../mtl/utility/different_non_complex.hpp | 34 + .../boost/numeric/mtl/utility/domain.hpp | 40 + .../boost/numeric/mtl/utility/enable_if.hpp | 53 + .../boost/numeric/mtl/utility/eval.hpp | 173 ++ .../boost/numeric/mtl/utility/eval_dense.hpp | 109 ++ .../boost/numeric/mtl/utility/exception.hpp | 243 +++ .../numeric/mtl/utility/extended_complex.hpp | 44 + .../mtl/utility/fast_multi_vector_expr.hpp | 90 + .../boost/numeric/mtl/utility/flatcat.hpp | 166 ++ .../boost/numeric/mtl/utility/glas_tag.hpp | 42 + .../boost/numeric/mtl/utility/gradient.hpp | 36 + .../numeric/mtl/utility/index_evaluatable.hpp | 116 ++ .../numeric/mtl/utility/index_evaluator.hpp | 50 + .../boost/numeric/mtl/utility/irange.hpp | 124 ++ .../mtl/utility/is_composable_vector.hpp | 35 + .../numeric/mtl/utility/is_distributed.hpp | 31 + .../boost/numeric/mtl/utility/is_lazy.hpp | 36 + .../mtl/utility/is_multi_vector_expr.hpp | 111 ++ .../numeric/mtl/utility/is_row_major.hpp | 98 ++ .../boost/numeric/mtl/utility/is_static.hpp | 35 + .../mtl/utility/is_vector_reduction.hpp | 37 + .../boost/numeric/mtl/utility/is_what.hpp | 93 + .../boost/numeric/mtl/utility/iset.hpp | 102 ++ .../numeric/mtl/utility/iterator_adaptor.hpp | 64 + .../mtl/utility/iterator_adaptor_1D.hpp | 161 ++ .../mtl/utility/iterator_adaptor_detail.hpp | 121 ++ .../numeric/mtl/utility/linear_operator.hpp | 34 + .../numeric/mtl/utility/lu_matrix_type.hpp | 35 + .../mtl/utility/make_copy_or_reference.hpp | 94 + .../mtl/utility/matrix_type_generator.hpp | 185 ++ .../boost/numeric/mtl/utility/maybe.hpp | 61 + .../boost/numeric/mtl/utility/multi_tmp.hpp | 66 + .../numeric/mtl/utility/omp_size_type.hpp | 42 + .../boost/numeric/mtl/utility/papi.hpp | 200 +++ .../boost/numeric/mtl/utility/parameters.hpp | 57 + .../boost/numeric/mtl/utility/pos_type.hpp | 50 + .../numeric/mtl/utility/property_map.hpp | 410 +++++ .../numeric/mtl/utility/property_map_impl.hpp | 431 +++++ .../mtl/utility/push_back_comma_inserter.hpp | 38 + .../numeric/mtl/utility/range_generator.hpp | 224 +++ .../numeric/mtl/utility/range_wrapper.hpp | 120 ++ .../boost/numeric/mtl/utility/root.hpp | 249 +++ .../numeric/mtl/utility/shrink_stl_vector.hpp | 31 + .../numeric/mtl/utility/sometimes_data.hpp | 37 + .../boost/numeric/mtl/utility/srange.hpp | 69 + .../numeric/mtl/utility/static_assert.hpp | 28 + .../numeric/mtl/utility/static_vector.hpp | 74 + .../mtl/utility/strided_dense_el_cursor.hpp | 49 + .../mtl/utility/strided_dense_el_iterator.hpp | 87 + .../numeric/mtl/utility/string_to_enum.hpp | 39 + .../include/boost/numeric/mtl/utility/tag.hpp | 454 +++++ .../mtl/utility/transposed_matrix_type.hpp | 81 + .../mtl/utility/transposed_orientation.hpp | 36 + .../boost/numeric/mtl/utility/true_copy.hpp | 33 + .../numeric/mtl/utility/type_parameter.hpp | 98 ++ .../mtl/utility/type_parameter_common.hpp | 162 ++ .../mtl/utility/type_parameter_local.hpp | 43 + .../numeric/mtl/utility/unroll_size1.hpp | 36 + .../mtl/utility/updater_to_assigner.hpp | 45 + .../mtl/utility/vector_type_generator.hpp | 101 ++ .../boost/numeric/mtl/utility/view_code.hpp | 98 ++ .../numeric/mtl/utility/viewed_collection.hpp | 49 + .../numeric/mtl/utility/with_unroll1.hpp | 33 + .../numeric/mtl/utility/wrapped_object.hpp | 37 + .../boost/numeric/mtl/utility/zipped_sort.hpp | 212 +++ .../boost/numeric/mtl/vector/all_vec_expr.hpp | 34 + .../numeric/mtl/vector/assign_expression.hpp | 89 + .../boost/numeric/mtl/vector/assigner.hpp | 35 + .../numeric/mtl/vector/crtp_base_vector.hpp | 554 ++++++ .../boost/numeric/mtl/vector/decrementer.hpp | 35 + .../boost/numeric/mtl/vector/dense_vector.hpp | 432 +++++ .../boost/numeric/mtl/vector/dimension.hpp | 54 + .../mtl/vector/dot_index_evaluator.hpp | 56 + .../boost/numeric/mtl/vector/extracter.hpp | 78 + .../boost/numeric/mtl/vector/incrementer.hpp | 34 + .../boost/numeric/mtl/vector/inserter.hpp | 91 + .../numeric/mtl/vector/lazy_reduction.hpp | 34 + .../boost/numeric/mtl/vector/map_view.hpp | 340 ++++ .../numeric/mtl/vector/mapped_inserter.hpp | 55 + .../mtl/vector/mat_cvec_multiplier.hpp | 102 ++ .../boost/numeric/mtl/vector/parameter.hpp | 46 + .../boost/numeric/mtl/vector/reduction.hpp | 182 ++ .../numeric/mtl/vector/reduction_functors.hpp | 244 +++ .../mtl/vector/reduction_index_evaluator.hpp | 58 + .../vector/row_mat_cvec_index_evaluator.hpp | 78 + .../mtl/vector/rvec_mat_times_expr.hpp | 42 + .../numeric/mtl/vector/sparse_vector.hpp | 173 ++ .../numeric/mtl/vector/strided_vector_ref.hpp | 274 +++ .../boost/numeric/mtl/vector/unit_vector.hpp | 64 + .../boost/numeric/mtl/vector/unrolled1.hpp | 61 + .../numeric/mtl/vector/vec_const_ref_expr.hpp | 42 + .../boost/numeric/mtl/vector/vec_expr.hpp | 25 + .../numeric/mtl/vector/vec_negate_expr.hpp | 30 + .../numeric/mtl/vector/vec_scal_aop_expr.hpp | 124 ++ .../numeric/mtl/vector/vec_scal_asgn_expr.hpp | 39 + .../mtl/vector/vec_scal_div_asgn_expr.hpp | 34 + .../mtl/vector/vec_scal_minus_asgn_expr.hpp | 35 + .../mtl/vector/vec_scal_mixed_expr.hpp | 104 ++ .../mtl/vector/vec_scal_plus_asgn_expr.hpp | 35 + .../mtl/vector/vec_scal_times_asgn_expr.hpp | 37 + .../numeric/mtl/vector/vec_vec_aop_expr.hpp | 196 +++ .../numeric/mtl/vector/vec_vec_asgn_expr.hpp | 44 + .../mtl/vector/vec_vec_div_asgn_expr.hpp | 41 + .../mtl/vector/vec_vec_ele_prod_expr.hpp | 41 + .../mtl/vector/vec_vec_ele_quot_expr.hpp | 39 + .../mtl/vector/vec_vec_minus_asgn_expr.hpp | 41 + .../numeric/mtl/vector/vec_vec_minus_expr.hpp | 43 + .../numeric/mtl/vector/vec_vec_op_expr.hpp | 89 + .../mtl/vector/vec_vec_plus_asgn_expr.hpp | 41 + .../numeric/mtl/vector/vec_vec_plus_expr.hpp | 41 + .../numeric/mtl/vector/vec_vec_pmop_expr.hpp | 88 + .../mtl/vector/vec_vec_times_asgn_expr.hpp | 41 + .../MTL/include/boost/numeric/mtl/vectors.hpp | 35 + .../include/boost/numeric/mtl/version.hpp.in | 6 + install/MTL/share/mtl/MTLConfig.cmake | 6 + install/MTL/share/mtl/README | 118 ++ install/MTL/share/mtl/license.mtl.txt | 53 + .../MTL/share/mtl/tools/cmake/ARPREC.cmake | 9 + .../MTL/share/mtl/tools/cmake/AUTO_CHECK.cpp | 7 + .../share/mtl/tools/cmake/C++11Features.cmake | 52 + .../mtl/tools/cmake/DEFAULTIMPL_CHECK.cpp | 9 + .../share/mtl/tools/cmake/INITLIST_CHECK.cpp | 31 + .../MTL/share/mtl/tools/cmake/MOVE_CHECK.cpp | 9 + .../MTL/share/mtl/tools/cmake/MTLCommon.cmake | 136 ++ .../share/mtl/tools/cmake/RANGEDFOR_CHECK.cpp | 12 + .../mtl/tools/cmake/STATICASSERT_CHECK.cpp | 6 + .../mtl/tools/cmake/TEMPLATE_ALIAS_CHECK.cpp | 15 + .../MTL/share/mtl/tools/cmake/UMFPACK.cmake | 12 + .../tools/cmake/VARIADIC_TEMPLATE_CHECK.cpp | 20 + .../MTL/share/mtl/tools/cmake/Vampir.cmake | 150 ++ install/MTL/share/mtl/vpt.cpp | 443 +++++ 468 files changed, 61959 insertions(+), 35 deletions(-) create mode 100644 dune/amdis/linear_algebra/mtl/MTLDenseVector.hpp create mode 100644 install/MTL/include/boost/numeric/itl/iteration/basic_iteration.hpp create mode 100644 install/MTL/include/boost/numeric/itl/iteration/cyclic_iteration.hpp create mode 100644 install/MTL/include/boost/numeric/itl/iteration/noisy_iteration.hpp create mode 100644 install/MTL/include/boost/numeric/itl/itl.hpp create mode 100644 install/MTL/include/boost/numeric/itl/itl_fwd.hpp create mode 100644 install/MTL/include/boost/numeric/itl/krylov/bicg.hpp create mode 100644 install/MTL/include/boost/numeric/itl/krylov/bicgstab.hpp create mode 100644 install/MTL/include/boost/numeric/itl/krylov/bicgstab_2.hpp create mode 100644 install/MTL/include/boost/numeric/itl/krylov/bicgstab_ell.hpp create mode 100644 install/MTL/include/boost/numeric/itl/krylov/cg.hpp create mode 100644 install/MTL/include/boost/numeric/itl/krylov/cgs.hpp create mode 100644 install/MTL/include/boost/numeric/itl/krylov/fsm.hpp create mode 100644 install/MTL/include/boost/numeric/itl/krylov/gmres.hpp create mode 100644 install/MTL/include/boost/numeric/itl/krylov/idr_s.hpp create mode 100644 install/MTL/include/boost/numeric/itl/krylov/qmr.hpp create mode 100644 install/MTL/include/boost/numeric/itl/krylov/repeating_solver.hpp create mode 100644 install/MTL/include/boost/numeric/itl/krylov/tfqmr.hpp create mode 100644 install/MTL/include/boost/numeric/itl/minimization/quasi_newton.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/binary_heap.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/comparators.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/concat.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/diagonal.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/ic_0.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/identity.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/ilu.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/ilu_0.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/ilut.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/imf_algorithms.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/imf_preconditioner.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/is_identity.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/matrix_algorithms.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/solver.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/sorting.hpp create mode 100644 install/MTL/include/boost/numeric/itl/pc/sub_matrix_pc.hpp create mode 100644 install/MTL/include/boost/numeric/itl/smoother/gauss_seidel.hpp create mode 100644 install/MTL/include/boost/numeric/itl/smoother/jacobi.hpp create mode 100644 install/MTL/include/boost/numeric/itl/smoother/jor.hpp create mode 100644 install/MTL/include/boost/numeric/itl/smoother/relaxation_parameter.hpp create mode 100644 install/MTL/include/boost/numeric/itl/smoother/repeated.hpp create mode 100644 install/MTL/include/boost/numeric/itl/smoother/sor.hpp create mode 100644 install/MTL/include/boost/numeric/itl/stepper/armijo.hpp create mode 100644 install/MTL/include/boost/numeric/itl/stepper/wolf.hpp create mode 100644 install/MTL/include/boost/numeric/itl/updater/bfgs.hpp create mode 100644 install/MTL/include/boost/numeric/itl/updater/broyden.hpp create mode 100644 install/MTL/include/boost/numeric/itl/updater/dfp.hpp create mode 100644 install/MTL/include/boost/numeric/itl/updater/psb.hpp create mode 100644 install/MTL/include/boost/numeric/itl/updater/sr1.hpp create mode 100644 install/MTL/include/boost/numeric/itl/utility/exception.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/accumulate.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/algebraic_concepts.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/concept_maps.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/concepts.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/ets_concepts.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/identity.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/intrinsic_concept_maps.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/inverse.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/is_invertible.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/linear_operator.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/new_concepts.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/old_concepts.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/operators.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/power.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/pseudo_concept.hpp create mode 100644 install/MTL/include/boost/numeric/linear_algebra/vector_concepts.hpp create mode 100644 install/MTL/include/boost/numeric/meta_math/abs.hpp create mode 100644 install/MTL/include/boost/numeric/meta_math/is_power_of_2.hpp create mode 100644 install/MTL/include/boost/numeric/meta_math/is_prime.hpp create mode 100644 install/MTL/include/boost/numeric/meta_math/least_significant_one_bit.hpp create mode 100644 install/MTL/include/boost/numeric/meta_math/log_2.hpp create mode 100644 install/MTL/include/boost/numeric/meta_math/loop.hpp create mode 100644 install/MTL/include/boost/numeric/meta_math/loop1.hpp create mode 100644 install/MTL/include/boost/numeric/meta_math/loop2.hpp create mode 100644 install/MTL/include/boost/numeric/meta_math/loop3.hpp create mode 100644 install/MTL/include/boost/numeric/meta_math/max.hpp create mode 100644 install/MTL/include/boost/numeric/meta_math/min.hpp create mode 100644 install/MTL/include/boost/numeric/meta_math/power_of_2.hpp create mode 100644 install/MTL/include/boost/numeric/meta_math/sqrt.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/concept/collection.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/concept/magnitude.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/concept/matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/concept/static_functor.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/concept/std_concept.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/concept/vector.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/config.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/detail/base_cursor.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/detail/contiguous_memory_block.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/detail/dilated_int.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/detail/dilation_table.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/detail/index.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/detail/masked_dilation_tables.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/detail/range_generator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/detail/strided_base_cursor.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/detail/trivial_inserter.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/interface/arprec.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/interface/blas.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/interface/lapack.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/interface/umfpack_solve.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/interface/vpt.cpp create mode 100644 install/MTL/include/boost/numeric/mtl/interface/vpt.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/interfaces.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/io/functor_symbol.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/io/matrix_file.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/io/matrix_market.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/io/path.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/io/read_el_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/io/read_filter.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/io/test_ostream.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/io/write_ast.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/io/write_ast_dispatch.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrices.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/all_mat_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/banded_view.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/bands.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/base_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/base_sub_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/block_diagonal2D.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/compressed2D.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/coordinate2D.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/crtp_base_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/dense2D.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/diagonal_setup.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/dimension.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/element.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/element_array.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/element_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/element_structure.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/ell_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/hermitian_view.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/hessian_setup.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/identity.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/identity2D.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/implicit_dense.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/indirect.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/inserter.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/laplacian_setup.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/lower.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/make_fast_multi_vector_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/map_view.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/mapped_inserter.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/mat_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/mat_mat_asgn_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/mat_mat_ele_times_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/mat_mat_minus_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/mat_mat_op_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/mat_mat_plus_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/mat_mat_times_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/mat_negate_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/morton_dense.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/multi_vector.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/multi_vector_range.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/operators.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/parameter.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/permutation.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/poisson2D_dirichlet.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/reorder.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/reorder_matrix_rows.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/reorder_ref.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/shifted_inserter.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/sparse_banded.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/strict_lower.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/strict_upper.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/transposed_view.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/upper.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/matrix/view_ref.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/mtl.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/mtl_conditional_fwd.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/mtl_fwd.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/adjoint.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/adjust_cursor.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/assign_each_nonzero.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/assign_mode.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/bin_op_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/cholesky.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/clone.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/column_in_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/compute_factors.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/compute_summand.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/conj.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/copy.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/copysign.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/crop.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/cross.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/cuppen.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/cursor_pseudo_dot.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/diagonal.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/div_result.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/divide_by.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/divide_by_inplace.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/dmat_dmat_mult.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/dot.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/eigenvalue.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/eigenvalue_symmetric.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/element_structure_algorithms.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/entry1D.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/entry_similar.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/evaluate_lazy.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/extended_complex.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/fill.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/frobenius_norm.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/fuse.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/fused_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/fused_index_evaluator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/givens.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/hermitian.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/hessenberg.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/householder.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/imag.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/index_evaluator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/infinity_norm.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/inv.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/invert_diagonal.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/iota.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/is_negative.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/lazy.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/lazy_assign.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/left_scale_inplace.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/look_at_each_nonzero.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/lower_trisolve.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/lu.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/make_sparse.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/make_tag_vector.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/mat_cvec_times_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/mat_vec_mult.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/matrix_bracket.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/max.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/max_abs_pos.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/max_of_sums.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/max_pos.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/merge_complex_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/merge_complex_vector.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/min.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/min_pos.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/minimal_increase.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/misc.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/mult.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/mult_assign_mode.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/mult_result.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/mult_specialize.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/multi_action_block.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/no_op.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/norms.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/num_cols.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/num_rows.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/one_norm.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/ones.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/operators.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/opteron/matrix_mult.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/orth.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/print.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/print_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/print_size.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/print_vector.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/product.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/qr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/qr_givens.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/random.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/rank_one_update.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/rank_two_update.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/raw_copy.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/real.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/resource.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/right_scale_inplace.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/row_in_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/rscale.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/rvec_mat_mult.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/scale.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/secular.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/set_to_zero.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/sfunctor.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/shift_block.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/shift_block_detail.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/signum.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/size.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/size1D.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/smat_dmat_mult.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/smat_smat_mult.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/solve.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/sort.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/split_complex_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/split_complex_vector.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/squared_abs.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/static_num_cols.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/static_num_rows.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/static_size.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/std_output_operator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/sub_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/sum.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/svd.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/swap_row.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/tfunctor.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/tfunctor_mixed.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/trace.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/trans.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/two_norm.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/unary_dot.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/unroll.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/update.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operation/upper_trisolve.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/operations.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/recursion/base_case_cast.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/recursion/base_case_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/recursion/base_case_test.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/recursion/bit_masking.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/recursion/dim_splitter.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/recursion/for_each.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/recursion/matrix_recursator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/recursion/predefined_masks.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/recursion/simplify_base_case_matrix.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/recursion/utility.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/types.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/add_const.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/algebraic_category.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/ashape.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/category.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/common_include.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/complexity.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/compose_view.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/copy_expression_const_ref_container.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/dense_el_cursor.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/different_non_complex.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/domain.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/enable_if.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/eval.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/eval_dense.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/exception.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/extended_complex.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/fast_multi_vector_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/flatcat.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/glas_tag.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/gradient.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/index_evaluatable.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/index_evaluator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/irange.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/is_composable_vector.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/is_distributed.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/is_lazy.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/is_multi_vector_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/is_row_major.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/is_static.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/is_vector_reduction.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/is_what.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/iset.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/iterator_adaptor.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/iterator_adaptor_1D.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/iterator_adaptor_detail.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/linear_operator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/lu_matrix_type.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/make_copy_or_reference.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/matrix_type_generator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/maybe.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/multi_tmp.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/omp_size_type.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/papi.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/parameters.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/pos_type.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/property_map.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/property_map_impl.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/push_back_comma_inserter.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/range_generator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/range_wrapper.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/root.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/shrink_stl_vector.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/sometimes_data.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/srange.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/static_assert.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/static_vector.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/strided_dense_el_cursor.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/strided_dense_el_iterator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/string_to_enum.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/tag.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/transposed_matrix_type.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/transposed_orientation.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/true_copy.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/type_parameter.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/type_parameter_common.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/type_parameter_local.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/unroll_size1.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/updater_to_assigner.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/vector_type_generator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/view_code.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/viewed_collection.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/with_unroll1.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/wrapped_object.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/utility/zipped_sort.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/all_vec_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/assign_expression.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/assigner.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/crtp_base_vector.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/decrementer.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/dense_vector.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/dimension.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/dot_index_evaluator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/extracter.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/incrementer.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/inserter.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/lazy_reduction.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/map_view.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/mapped_inserter.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/mat_cvec_multiplier.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/parameter.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/reduction.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/reduction_functors.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/reduction_index_evaluator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/row_mat_cvec_index_evaluator.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/rvec_mat_times_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/sparse_vector.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/strided_vector_ref.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/unit_vector.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/unrolled1.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_const_ref_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_negate_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_scal_aop_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_scal_asgn_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_scal_div_asgn_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_scal_minus_asgn_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_scal_mixed_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_scal_plus_asgn_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_scal_times_asgn_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_vec_aop_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_vec_asgn_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_vec_div_asgn_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_vec_ele_prod_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_vec_ele_quot_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_vec_minus_asgn_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_vec_minus_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_vec_op_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_vec_plus_asgn_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_vec_plus_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_vec_pmop_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vector/vec_vec_times_asgn_expr.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/vectors.hpp create mode 100644 install/MTL/include/boost/numeric/mtl/version.hpp.in create mode 100644 install/MTL/share/mtl/MTLConfig.cmake create mode 100644 install/MTL/share/mtl/README create mode 100644 install/MTL/share/mtl/license.mtl.txt create mode 100644 install/MTL/share/mtl/tools/cmake/ARPREC.cmake create mode 100644 install/MTL/share/mtl/tools/cmake/AUTO_CHECK.cpp create mode 100644 install/MTL/share/mtl/tools/cmake/C++11Features.cmake create mode 100644 install/MTL/share/mtl/tools/cmake/DEFAULTIMPL_CHECK.cpp create mode 100644 install/MTL/share/mtl/tools/cmake/INITLIST_CHECK.cpp create mode 100644 install/MTL/share/mtl/tools/cmake/MOVE_CHECK.cpp create mode 100644 install/MTL/share/mtl/tools/cmake/MTLCommon.cmake create mode 100644 install/MTL/share/mtl/tools/cmake/RANGEDFOR_CHECK.cpp create mode 100644 install/MTL/share/mtl/tools/cmake/STATICASSERT_CHECK.cpp create mode 100644 install/MTL/share/mtl/tools/cmake/TEMPLATE_ALIAS_CHECK.cpp create mode 100644 install/MTL/share/mtl/tools/cmake/UMFPACK.cmake create mode 100644 install/MTL/share/mtl/tools/cmake/VARIADIC_TEMPLATE_CHECK.cpp create mode 100644 install/MTL/share/mtl/tools/cmake/Vampir.cmake create mode 100644 install/MTL/share/mtl/vpt.cpp diff --git a/dune/amdis/AMDiS.cpp b/dune/amdis/AMDiS.cpp index dcaebd33..d114a410 100644 --- a/dune/amdis/AMDiS.cpp +++ b/dune/amdis/AMDiS.cpp @@ -5,8 +5,6 @@ #include <boost/program_options.hpp> -#include <dune/common/parallel/mpihelper.hh> // An initializer of MPI - // AMDiS includes #include "Initfile.hpp" #include "Log.hpp" @@ -15,12 +13,10 @@ namespace AMDiS { // using namespace std; - void init(int& argc, char**& argv, std::string initFileName) + Dune::MPIHelper& init(int& argc, char**& argv, std::string initFileName) { // Maybe initialize MPI - std::cout << "call MPIHelper::instance..."; - Dune::MPIHelper& helper = Dune::MPIHelper::instance(argc, argv); - std::cout << " [ ok ]\n"; + Dune::MPIHelper& mpiHelper = Dune::MPIHelper::instance(argc, argv); Parameters::clearData(); @@ -82,6 +78,8 @@ namespace AMDiS // if (vm.count("parameters") && !ignoreCommandline) // Parameters::readArgv(vm["parameters"].as<std::string>(),0); // TODO: add command-line arguments again. + + return mpiHelper; } diff --git a/dune/amdis/AMDiS.hpp b/dune/amdis/AMDiS.hpp index cf4585b7..ae2f1a17 100644 --- a/dune/amdis/AMDiS.hpp +++ b/dune/amdis/AMDiS.hpp @@ -7,10 +7,11 @@ #include <string> #include <dune/common/exceptions.hh> // We use exceptions +#include <dune/common/parallel/mpihelper.hh> namespace AMDiS { - void init(int& argc, char**& argv, std::string initFileName = ""); + Dune::MPIHelper& init(int& argc, char**& argv, std::string initFileName = ""); void init(std::string initFileName); diff --git a/dune/amdis/DirichletBC.inc.hpp b/dune/amdis/DirichletBC.inc.hpp index 918d8fb0..90660cbd 100644 --- a/dune/amdis/DirichletBC.inc.hpp +++ b/dune/amdis/DirichletBC.inc.hpp @@ -1,6 +1,7 @@ #pragma once #include <dune/functions/functionspacebases/interpolate.hh> +#include <dune/amdis/LinearAlgebra.hpp> namespace AMDiS { @@ -14,7 +15,7 @@ namespace AMDiS using Dune::Functions::interpolate; if (!initialized) { -// interpolate(matrix.getRowFeSpace(), dirichletNodes, predicate); + interpolate(matrix.getRowFeSpace(), dirichletNodes, predicate); initialized = true; } } @@ -33,8 +34,8 @@ namespace AMDiS matrix.clearDirichletRows(dirichletNodes, apply); if (apply) { -// interpolate(matrix.getRowFeSpace(), rhs.getVector(), values, dirichletNodes); -// interpolate(matrix.getColFeSpace(), solution.getVector(), values, dirichletNodes); + interpolate(matrix.getRowFeSpace(), wrapper(rhs.getVector()), values, dirichletNodes); + interpolate(matrix.getColFeSpace(), wrapper(solution.getVector()), values, dirichletNodes); } } diff --git a/dune/amdis/Log.hpp b/dune/amdis/Log.hpp index cdabe9d7..8ef6d123 100644 --- a/dune/amdis/Log.hpp +++ b/dune/amdis/Log.hpp @@ -39,7 +39,7 @@ #ifdef NDEBUG #define AMDIS_FUNCNAME_DBG(nn) #else - #define AMDIS_FUNCNAME_DBG(nn) const char *funcName; funcName = nn; + #define AMDIS_FUNCNAME_DBG(nn) AMDIS_UNUSED(const char *funcName); funcName = nn; #endif diff --git a/dune/amdis/Operator.inc.hpp b/dune/amdis/Operator.inc.hpp index 2dcf4460..5e6859f4 100644 --- a/dune/amdis/Operator.inc.hpp +++ b/dune/amdis/Operator.inc.hpp @@ -388,7 +388,7 @@ namespace AMDiS auto geometry = element.geometry(); const auto& rowLocalBasis = rowView.tree().finiteElement().localBasis(); - const auto& colLocalBasis = colView.tree().finiteElement().localBasis(); +// const auto& colLocalBasis = colView.tree().finiteElement().localBasis(); int order = getQuadratureDegree(2); const auto& quad = Dune::QuadratureRules<double, dim>::rule(element.type(), order); diff --git a/dune/amdis/ProblemInstat.hpp b/dune/amdis/ProblemInstat.hpp index cb3a18df..7244e6f8 100644 --- a/dune/amdis/ProblemInstat.hpp +++ b/dune/amdis/ProblemInstat.hpp @@ -69,7 +69,7 @@ namespace AMDiS } /// Implementation of \ref ProblemTimeInterface::transferInitialSolution(). - virtual void transferInitialSolution(AdaptInfo& adaptInfo); + virtual void transferInitialSolution(AdaptInfo& adaptInfo) override; protected: /// Space problem solved in each timestep. diff --git a/dune/amdis/ProblemInstatBase.hpp b/dune/amdis/ProblemInstatBase.hpp index f575c647..fe1e9dc3 100644 --- a/dune/amdis/ProblemInstatBase.hpp +++ b/dune/amdis/ProblemInstatBase.hpp @@ -73,7 +73,7 @@ namespace AMDiS virtual void closeTimestep(AdaptInfo&) override { /* by default, do nothing */ } /// Implementation of \ref ProblemStatBase::getName(). - std::string getName() const + virtual std::string getName() const override { return name; } diff --git a/dune/amdis/ProblemStat.hpp b/dune/amdis/ProblemStat.hpp index a2d4b650..af42f9bb 100644 --- a/dune/amdis/ProblemStat.hpp +++ b/dune/amdis/ProblemStat.hpp @@ -150,7 +150,7 @@ namespace AMDiS /// Return the i'th \ref solution component template <size_t I = 0> - decltype(auto) getSolution(const index_<I> _i = index_<I>()) + decltype(auto) getSolution(const index_<I> _i = {}) { return (*solution)[_i]; } @@ -176,7 +176,7 @@ namespace AMDiS /// Return the I'th \ref feSpaces component template <size_t I = 0> - FeSpace<I> const& getFeSpace(const index_<I> = index_<I>()) const + FeSpace<I> const& getFeSpace(const index_<I> = {}) const { return std::get<I>(*feSpaces); } @@ -372,7 +372,7 @@ namespace AMDiS **/ virtual Flag oneIteration(AdaptInfo& adaptInfo, Flag toDo = FULL_ITERATION) override { - for (int i = 0; i < ProblemStatType::getNumComponents(); i++) + for (size_t i = 0; i < ProblemStatType::getNumComponents(); ++i) if (adaptInfo.spaceToleranceReached(i)) adaptInfo.allowRefinement(false, i); else @@ -391,13 +391,13 @@ namespace AMDiS virtual void estimate(AdaptInfo& adaptInfo) override { /* Does nothing. */ } /// Implementation of \ref ProblemStatBase::refineMesh. - virtual Flag refineMesh(AdaptInfo& adaptInfo) override { /* Does nothing. */ } + virtual Flag refineMesh(AdaptInfo& adaptInfo) override { return {0}; } /// Implementation of \ref ProblemStatBase::coarsenMesh. - virtual Flag coarsenMesh(AdaptInfo& adaptInfo) override { /* Does nothing. */ } + virtual Flag coarsenMesh(AdaptInfo& adaptInfo) override { return {0}; } /// Implementation of \ref ProblemStatBase::markElements. - virtual Flag markElements(AdaptInfo& adaptInfo) override { /* Does nothing. */ } + virtual Flag markElements(AdaptInfo& adaptInfo) override { return {0}; } }; } // end namespace Impl diff --git a/dune/amdis/ProblemStat.inc.hpp b/dune/amdis/ProblemStat.inc.hpp index 711b5d71..7102756a 100644 --- a/dune/amdis/ProblemStat.inc.hpp +++ b/dune/amdis/ProblemStat.inc.hpp @@ -222,9 +222,6 @@ namespace AMDiS For<0, nComponents>::loop([this, &nnz, asmMatrix, asmVector, _r](auto const _c) { - auto const& rowFeSpace = this->getFeSpace(_r); - auto const& colFeSpace = this->getFeSpace(_c); - // The DOFMatrix which should be assembled auto& dofmatrix = (*systemMatrix)(_r, _c); auto& solution_vec = (*solution)[_c]; diff --git a/dune/amdis/linear_algebra/LinearAlgebraBase.hpp b/dune/amdis/linear_algebra/LinearAlgebraBase.hpp index a07e379c..e9827f6e 100644 --- a/dune/amdis/linear_algebra/LinearAlgebraBase.hpp +++ b/dune/amdis/linear_algebra/LinearAlgebraBase.hpp @@ -12,4 +12,41 @@ namespace AMDiS template <class Vector> using BaseVector = typename Impl::BaseVector<Vector>::type; + + namespace Impl + { + template <class Vector> + class BaseWrapper + { + public: + using value_type = typename Vector::value_type; + using size_type = typename Vector::size_type; + + BaseWrapper(Vector& vec) : vec(vec) {} + + void resize(size_type s) + { + vec.resize(s); + } + + size_type size() const + { + return vec.size(); + } + + value_type& operator[](size_type i) { return vec[i]; } + value_type const& operator[](size_type i) const { return vec[i]; } + + protected: + Vector& vec; + }; + + } // end namespace Impl + + template <class Vector> + Impl::BaseWrapper<std::remove_reference_t<Vector>> wrapper(Vector&& vec) + { + return {std::forward<Vector>(vec)}; + } + } // end namespace AMDiS diff --git a/dune/amdis/linear_algebra/LinearSolverInterface.hpp b/dune/amdis/linear_algebra/LinearSolverInterface.hpp index fb188340..7860ba3e 100644 --- a/dune/amdis/linear_algebra/LinearSolverInterface.hpp +++ b/dune/amdis/linear_algebra/LinearSolverInterface.hpp @@ -48,7 +48,7 @@ namespace AMDiS } // return the runner/worker corresponding to this solver (optional) - virtual std::shared_ptr<RunnerBase> getRunner() { /* Does nothing */ }; + virtual std::shared_ptr<RunnerBase> getRunner() { return {}; }; private: /// main methods that all solvers must implement diff --git a/dune/amdis/linear_algebra/RunnerInterface.hpp b/dune/amdis/linear_algebra/RunnerInterface.hpp index 49bd2d53..52d5ed50 100644 --- a/dune/amdis/linear_algebra/RunnerInterface.hpp +++ b/dune/amdis/linear_algebra/RunnerInterface.hpp @@ -33,8 +33,8 @@ namespace AMDiS return 0; } - virtual std::shared_ptr<PreconBase> getLeftPrecon() {} - virtual std::shared_ptr<PreconBase> getRightPrecon() {} + virtual std::shared_ptr<PreconBase> getLeftPrecon() { return {}; } + virtual std::shared_ptr<PreconBase> getRightPrecon() { return {}; } }; } // end namespace AMDiS diff --git a/dune/amdis/linear_algebra/SolverInfo.hpp b/dune/amdis/linear_algebra/SolverInfo.hpp index 4295c808..941aae3b 100644 --- a/dune/amdis/linear_algebra/SolverInfo.hpp +++ b/dune/amdis/linear_algebra/SolverInfo.hpp @@ -2,6 +2,8 @@ #include <string> +#include <dune/amdis/Initfile.hpp> + namespace AMDiS { /// Class that stores information about the solution process, like tolerances diff --git a/dune/amdis/linear_algebra/mtl/BlockMTLVector.hpp b/dune/amdis/linear_algebra/mtl/BlockMTLVector.hpp index 15d3149a..1424221d 100644 --- a/dune/amdis/linear_algebra/mtl/BlockMTLVector.hpp +++ b/dune/amdis/linear_algebra/mtl/BlockMTLVector.hpp @@ -1,6 +1,9 @@ #pragma once +#include <boost/numeric/mtl/utility/irange.hpp> + #include <dune/amdis/linear_algebra/LinearAlgebraBase.hpp> +#include <dune/amdis/linear_algebra/mtl/MTLDenseVector.hpp> namespace AMDiS { @@ -134,7 +137,7 @@ namespace AMDiS }; - template <class BlockVector, class Vector = mtl::dense_vector<typename BlockVector::value_type>> + template <class BlockVector, class Vector = /**/MTLDenseVector<typename BlockVector::value_type>> BlockVectorWrapper<BlockVector, Vector> blockWrapper(BlockVector& bvec) { diff --git a/dune/amdis/linear_algebra/mtl/DOFVector.hpp b/dune/amdis/linear_algebra/mtl/DOFVector.hpp index 00a6c42c..9b5f4dd2 100644 --- a/dune/amdis/linear_algebra/mtl/DOFVector.hpp +++ b/dune/amdis/linear_algebra/mtl/DOFVector.hpp @@ -3,13 +3,11 @@ #include <string> #include <memory> - -#include <boost/numeric/mtl/vector/dense_vector.hpp> - #include <dune/functions/functionspacebases/interpolate.hh> #include <dune/amdis/ClonablePtr.hpp> #include <dune/amdis/Log.hpp> +#include <dune/amdis/linear_algebra/mtl/MTLDenseVector.hpp> namespace AMDiS { @@ -24,7 +22,7 @@ namespace AMDiS using FeSpace = FeSpaceType; /// The type of the base vector - using BaseVector = mtl::dense_vector<ValueType>; + using BaseVector = MTLDenseVector<ValueType>; /// The index/size - type using size_type = typename FeSpace::size_type; diff --git a/dune/amdis/linear_algebra/mtl/LinearSolver.hpp b/dune/amdis/linear_algebra/mtl/LinearSolver.hpp index 2c74ea72..57207f09 100644 --- a/dune/amdis/linear_algebra/mtl/LinearSolver.hpp +++ b/dune/amdis/linear_algebra/mtl/LinearSolver.hpp @@ -34,7 +34,7 @@ namespace AMDiS {} /// Implements \ref LinearSolverInterface::getRunner() - std::shared_ptr<RunnerBase> getRunner() + virtual std::shared_ptr<RunnerBase> getRunner() override { return runner; } diff --git a/dune/amdis/linear_algebra/mtl/MTLDenseVector.hpp b/dune/amdis/linear_algebra/mtl/MTLDenseVector.hpp new file mode 100644 index 00000000..d5cd8b7d --- /dev/null +++ b/dune/amdis/linear_algebra/mtl/MTLDenseVector.hpp @@ -0,0 +1,49 @@ +#pragma once + + +#include <boost/numeric/mtl/vector/dense_vector.hpp> + +#include <dune/amdis/linear_algebra/LinearAlgebraBase.hpp> + +namespace AMDiS +{ + template <class Value> + using MTLDenseVector = mtl::vec::dense_vector<Value>; + + namespace Impl + { + template <class Vector> + class MTLWrapper + : public BaseWrapper<Vector> + { + using Super = BaseWrapper<Vector>; + + public: + using value_type = typename Super::value_type; + using size_type = typename Super::size_type; + + template <class Vector_> + MTLWrapper(Vector_&& vec) + : Super(std::forward<Vector_>(vec)) + {} + + void resize(size_type s) + { + this->vec.change_dim(s); + } + + size_type size() const + { + return num_rows(this->vec); + } + }; + + } // end namespace Impl + + template <class Value> + Impl::MTLWrapper<MTLDenseVector<Value>> wrapper(MTLDenseVector<Value>& vec) + { + return {vec}; + } + +} diff --git a/dune/amdis/linear_algebra/mtl/SystemVector.hpp b/dune/amdis/linear_algebra/mtl/SystemVector.hpp index 604b5443..951fa819 100644 --- a/dune/amdis/linear_algebra/mtl/SystemVector.hpp +++ b/dune/amdis/linear_algebra/mtl/SystemVector.hpp @@ -5,8 +5,6 @@ #include <memory> #include <tuple> -#include <boost/numeric/mtl/vector/dense_vector.hpp> - #include <dune/amdis/Basic.hpp> #include <dune/amdis/Log.hpp> #include <dune/amdis/Loops.hpp> @@ -80,7 +78,8 @@ namespace AMDiS AMDIS_STATIC_ASSERT( nComponents > 0 ); /// The type of the block-vector - using MultiVector = BlockMTLVector<mtl::dense_vector<ValueType>, nComponents>; + using BaseVector = typename DOFVectorGenerator<std::tuple_element_t<0, FeSpaces>>::BaseVector; + using MultiVector = BlockMTLVector<BaseVector, nComponents>; /// The type of the vector of DOFVectors using DOFVectors = MakeTuple_t<DOFVectorGenerator, FeSpaces>; diff --git a/install/MTL/include/boost/numeric/itl/iteration/basic_iteration.hpp b/install/MTL/include/boost/numeric/itl/iteration/basic_iteration.hpp new file mode 100644 index 00000000..369995fd --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/iteration/basic_iteration.hpp @@ -0,0 +1,151 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_BASIC_ITERATION_INCLUDE +#define ITL_BASIC_ITERATION_INCLUDE + +#include <iostream> +#include <complex> +#include <string> + +namespace itl { + + +template <class Real> +class basic_iteration +{ + public: + typedef basic_iteration self; + typedef Real real; + + template <class Vector> + basic_iteration(const Vector& r0, int max_iter_, Real t, Real a = Real(0)) + : error(0), i(0), norm_r0(std::abs(two_norm(r0))), + max_iter(max_iter_), rtol_(t), atol_(a), is_finished(false), my_quite(false), my_suppress(false) { } + + basic_iteration(Real nb, int max_iter_, Real t, Real a = Real(0)) + : error(0), i(0), norm_r0(nb), max_iter(max_iter_), rtol_(t), atol_(a), is_finished(false), + my_quite(false), my_suppress(false) {} + + virtual ~basic_iteration() {} + + bool check_max() + { + if (i >= max_iter) + error= 1, is_finished= true, err_msg= "Too many iterations."; + return is_finished; + } + + template <class Vector> + bool finished(const Vector& r) + { + if (converged(two_norm(r))) + return is_finished= true; + return check_max(); + } + + bool finished(const Real& r) + { + if (converged(r)) + return is_finished= true; + return check_max(); + } + + template <typename T> + bool finished(const std::complex<T>& r) + { + if (converged(std::abs(r))) + return is_finished= true; + return check_max(); + } + + bool finished() const { return is_finished; } + + template <class T> + int terminate(const T& r) { finished(r); return error; } + + bool converged(const Real& r) { resid_= r; return converged(); } + + bool converged() const + { + if (norm_r0 == 0) + return resid_ <= atol_; // ignore relative tolerance if |r0| is zero + return resid_ <= rtol_ * norm_r0 || resid_ <= atol_; + } + + self& operator++() { ++i; return *this; } + + self& operator+=(int n) { i+= n; return *this; } + + bool first() const { return i <= 1; } + + virtual operator int() const { return error; } + + virtual int error_code() const { return error; } + + bool is_converged() const { return is_finished && error == 0; } + + int iterations() const { return i; } + + int max_iterations() const { return max_iter; } + + void set_max_iterations(int m) { max_iter= m; } + + Real resid() const { return resid_; } + + Real relresid() const { return resid_ / norm_r0; } + + Real normb() const { return norm_r0; } + + Real tol() const { return rtol_; } + Real atol() const { return atol_; } + + int fail(int err_code) { error = err_code; return error_code(); } + + int fail(int err_code, const std::string& msg) + { error = err_code; err_msg = msg; return error_code(); } + + void set(Real v) { norm_r0 = v; } + + void set_quite(bool q) { my_quite= q; } + + bool is_quite() const { return my_quite; } + + void suppress_resume(bool s) { my_suppress= s; } + + bool resume_suppressed() const { return my_suppress; } + + void update_progress(const basic_iteration& that) + { + i= that.i; + resid_= that.resid_; + if (that.error > 1) { // copy error except too many iterations + error= that.error; + err_msg= that.err_msg; + is_finished= true; + } else + finished(resid_); + } + + protected: + int error, i; + Real norm_r0; + int max_iter; + Real rtol_, atol_, resid_; + std::string err_msg; + bool is_finished, my_quite, my_suppress; +}; + + +} // namespace itl + +#endif // ITL_BASIC_ITERATION_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/iteration/cyclic_iteration.hpp b/install/MTL/include/boost/numeric/itl/iteration/cyclic_iteration.hpp new file mode 100644 index 00000000..a488a19e --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/iteration/cyclic_iteration.hpp @@ -0,0 +1,96 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library2 +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_CYCLIC_ITERATION_INCLUDE +#define ITL_CYCLIC_ITERATION_INCLUDE + +#include <iostream> +#include <boost/numeric/itl/iteration/basic_iteration.hpp> + +namespace itl { + + /// Class for iteration control that cyclically prints residual + template <class Real, class OStream = std::ostream> + class cyclic_iteration : public basic_iteration<Real> + { + typedef basic_iteration<Real> super; + typedef cyclic_iteration self; + + void print_resid() + { + if (!this->my_quite && this->i % cycle == 0) + if (multi_print || this->i != last_print) { // Avoid multiple print-outs in same iteration + out << "iteration " << this->i << ": resid " << this->resid() + // << " / " << this->norm_r0 << " = " << this->resid() / this->norm_r0 << " (rel. error)" + << std::endl; + last_print= this->i; + } + } + + public: + + template <class Vector> + cyclic_iteration(const Vector& r0, int max_iter_, Real tol_, Real atol_ = Real(0), int cycle_ = 100, + OStream& out = std::cout) + : super(r0, max_iter_, tol_, atol_), cycle(cycle_), last_print(-1), multi_print(false), out(out) + {} + + cyclic_iteration(Real r0, int max_iter_, Real tol_, Real atol_ = Real(0), int cycle_ = 100, + OStream& out = std::cout) + : super(r0, max_iter_, tol_, atol_), cycle(cycle_), last_print(-1), multi_print(false), out(out) + {} + + + bool finished() { return super::finished(); } + + template <typename T> + bool finished(const T& r) + { + bool ret= super::finished(r); + print_resid(); + return ret; + } + + inline self& operator++() { ++this->i; return *this; } + + inline self& operator+=(int n) { this->i+= n; return *this; } + + operator int() const { return error_code(); } + + /// Whether the residual is printed multiple times in iteration + bool is_multi_print() const { return multi_print; } + + /// Set whether the residual is printed multiple times in iteration + void set_multi_print(bool m) { multi_print= m; } + + int error_code() const + { + if (!this->my_suppress) + out << "finished! error code = " << this->error << '\n' + << this->iterations() << " iterations\n" + << this->resid() << " is actual final residual. \n" + << this->relresid() << " is actual relative tolerance achieved. \n" + << "Relative tol: " << this->rtol_ << " Absolute tol: " << this->atol_ << '\n' + << "Convergence: " << pow(this->relresid(), 1.0 / double(this->iterations())) << std::endl; + return this->error; + } + protected: + int cycle, last_print; + bool multi_print; + OStream& out; + }; + + + +} // namespace itl + +#endif // ITL_CYCLIC_ITERATION_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/iteration/noisy_iteration.hpp b/install/MTL/include/boost/numeric/itl/iteration/noisy_iteration.hpp new file mode 100644 index 00000000..73acbdf9 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/iteration/noisy_iteration.hpp @@ -0,0 +1,34 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_NOISY_ITERATION_INCLUDE +#define ITL_NOISY_ITERATION_INCLUDE + +#include <iostream> +#include <boost/numeric/itl/iteration/cyclic_iteration.hpp> + +namespace itl { + + template <class Real, class OStream = std::ostream> + class noisy_iteration : public cyclic_iteration<Real, OStream> + { + public: + template <class Vector> + noisy_iteration(const Vector& r0, int max_iter_, Real tol_, Real atol_ = Real(0), + OStream& out = std::cout) + : cyclic_iteration<Real, OStream>(r0, max_iter_, tol_, atol_, 1, out) + {} + }; + +} // namespace itl + +#endif // ITL_NOISY_ITERATION_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/itl.hpp b/install/MTL/include/boost/numeric/itl/itl.hpp new file mode 100644 index 00000000..d802660d --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/itl.hpp @@ -0,0 +1,62 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_ITL_INCLUDE +#define ITL_ITL_INCLUDE + + +#include <boost/numeric/itl/iteration/basic_iteration.hpp> +#include <boost/numeric/itl/iteration/cyclic_iteration.hpp> +#include <boost/numeric/itl/iteration/noisy_iteration.hpp> + +#include <boost/numeric/itl/krylov/cg.hpp> +#include <boost/numeric/itl/krylov/cgs.hpp> +#include <boost/numeric/itl/krylov/bicg.hpp> +#include <boost/numeric/itl/krylov/bicgstab.hpp> +#include <boost/numeric/itl/krylov/bicgstab_2.hpp> +#include <boost/numeric/itl/krylov/bicgstab_ell.hpp> +#include <boost/numeric/itl/krylov/fsm.hpp> +#include <boost/numeric/itl/krylov/idr_s.hpp> +#include <boost/numeric/itl/krylov/gmres.hpp> +#include <boost/numeric/itl/krylov/tfqmr.hpp> +#include <boost/numeric/itl/krylov/qmr.hpp> + +#include <boost/numeric/itl/krylov/repeating_solver.hpp> + +#include <boost/numeric/itl/minimization/quasi_newton.hpp> + +#include <boost/numeric/itl/pc/identity.hpp> +#include <boost/numeric/itl/pc/is_identity.hpp> +#include <boost/numeric/itl/pc/diagonal.hpp> +#include <boost/numeric/itl/pc/ilu.hpp> +#include <boost/numeric/itl/pc/ilu_0.hpp> +#include <boost/numeric/itl/pc/ilut.hpp> +#include <boost/numeric/itl/pc/ic_0.hpp> + +#include <boost/numeric/itl/pc/imf_preconditioner.hpp> +#include <boost/numeric/itl/pc/imf_algorithms.hpp> + +#include <boost/numeric/itl/pc/sub_matrix_pc.hpp> +#include <boost/numeric/itl/pc/concat.hpp> + +#include <boost/numeric/itl/smoother/gauss_seidel.hpp> + +#include <boost/numeric/itl/stepper/armijo.hpp> +#include <boost/numeric/itl/stepper/wolf.hpp> + +#include <boost/numeric/itl/updater/bfgs.hpp> +#include <boost/numeric/itl/updater/broyden.hpp> +#include <boost/numeric/itl/updater/dfp.hpp> +#include <boost/numeric/itl/updater/psb.hpp> +#include <boost/numeric/itl/updater/sr1.hpp> + +#endif // ITL_ITL_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/itl_fwd.hpp b/install/MTL/include/boost/numeric/itl/itl_fwd.hpp new file mode 100644 index 00000000..15ddadbd --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/itl_fwd.hpp @@ -0,0 +1,90 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_ITL_FWD_INCLUDE +#define ITL_ITL_FWD_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> + +namespace itl { + + template <class Real> class basic_iteration; + template <class Real, class OStream> class cyclic_iteration; + template <class Real, class OStream> class noisy_iteration; + + template <typename Solver, typename VectorIn, bool trans> class solver_proxy; + + namespace pc { + + template <typename PC, typename Vector, bool> struct solver; + template <typename Matrix, typename Value> class identity; + // template <typename Matrix, typename Value, typename Vector> Vector solve(const identity<Matrix>&, const Vector& x); + // template <typename Matrix, typename Vector> Vector adjoint_solve(const identity<Matrix>&, const Vector& x); + + template <typename Matrix, typename Value> class diagonal; + // template <typename Matrix, typename Vector> Vector solve(const diagonal<Matrix>& P, const Vector& x); + // template <typename Matrix, typename Vector> Vector adjoint_solve(const diagonal<Matrix>& P, const Vector& x); + + template <typename Matrix, typename Factorizer, typename Value> class ilu; + template <typename Matrix, typename Value> class ilu_0; // Maybe we should declare the default here??? + template <typename Matrix, typename Value> class ilut; // Maybe we should declare the default here??? + // template <typename Matrix, typename Vector> Vector solve(const ilu_0<Matrix>& P, const Vector& x); + // template <typename Matrix, typename Vector> Vector adjoint_solve(const ilu_0<Matrix>& P, const Vector& x); + + template <typename Matrix, typename Value> class ic_0; // Maybe we should declare the default here??? + // template <typename Matrix, typename Vector> Vector solve(const ic_0<Matrix>& P, const Vector& x); + // template <typename Matrix, typename Value, typename Vector> Vector adjoint_solve(const ic_0<Matrix, Value>& P, const Vector& x); + + } // namespace pc + + template < typename LinearOperator, typename HilbertSpaceX, typename HilbertSpaceB, + typename Preconditioner, typename Iteration > + int cg(const LinearOperator& A, HilbertSpaceX& x, const HilbertSpaceB& b, + const Preconditioner& M, Iteration& iter); + + template < typename LinearOperator, typename Preconditioner= pc::identity<LinearOperator, double>, + typename RightPreconditioner= pc::identity<LinearOperator, double> > + class cg_solver; + + + template < typename LinearOperator, typename Vector, + typename Preconditioner, typename Iteration > + int bicg(const LinearOperator &A, Vector &x, const Vector &b, + const Preconditioner &M, Iteration& iter); + + template < class LinearOperator, class HilbertSpaceX, class HilbertSpaceB, + class Preconditioner, class Iteration > + int bicgstab(const LinearOperator& A, HilbertSpaceX& x, const HilbertSpaceB& b, + const Preconditioner& M, Iteration& iter); + + template < class LinearOperator, class HilbertSpaceX, class HilbertSpaceB, + class Preconditioner, class Iteration > + int bicgstab_2(const LinearOperator& A, HilbertSpaceX& x, const HilbertSpaceB& b, + const Preconditioner& M, Iteration& iter); + + template < typename LinearOperator, typename Vector, + typename LeftPreconditioner, typename RightPreconditioner, + typename Iteration > + int bicgstab_ell(const LinearOperator &A, Vector &x, const Vector &b, + const LeftPreconditioner &L, const RightPreconditioner &R, + Iteration& iter, size_t l); + + template < typename LinearOperator, typename Preconditioner= pc::identity<LinearOperator, double>, + typename RightPreconditioner= pc::identity<LinearOperator, double> > + class bicgstab_ell_solver; + + template <typename Solver, unsigned N, bool Stored= false> + class repeating_solver; + +} // namespace itl + +#endif // ITL_ITL_FWD_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/krylov/bicg.hpp b/install/MTL/include/boost/numeric/itl/krylov/bicg.hpp new file mode 100644 index 00000000..9dde56bc --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/krylov/bicg.hpp @@ -0,0 +1,115 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_BICG_INCLUDE +#define ITL_BICG_INCLUDE + +#include <complex> +#include <boost/numeric/itl/itl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/conj.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace itl { + +/// Bi-Conjugate Gradient +template < typename LinearOperator, typename Vector, + typename Preconditioner, typename Iteration > +int bicg(const LinearOperator &A, Vector &x, const Vector &b, + const Preconditioner &M, Iteration& iter) +{ + mtl::vampir_trace<7003> tracer; + using mtl::conj; + typedef typename mtl::Collection<Vector>::value_type Scalar; + Scalar rho_1(0), rho_2(0), alpha(0), beta(0); + Vector r(b - A * x), z(resource(x)), p(resource(x)), q(resource(x)), + r_tilde(r), z_tilde(resource(x)), p_tilde(resource(x)), q_tilde(resource(x)); + + while ( ! iter.finished(r)) { + ++iter; + z= solve(M, r); + z_tilde= adjoint_solve(M, r_tilde); + rho_1= dot(z_tilde, z); + + if (rho_1 == 0.) return iter.fail(2, "bicg breakdown"); + if (iter.first()) { + p= z; + p_tilde= z_tilde; + } else { + beta= rho_1 / rho_2; + p= z + beta * p; + p_tilde= z_tilde + conj(beta) * p_tilde; + } + + q= A * p; + q_tilde= adjoint(A) * p_tilde; + alpha= rho_1 / dot(p_tilde, q); + + x+= alpha * p; + r-= alpha * q; + r_tilde-= conj(alpha) * q_tilde; + + rho_2= rho_1; + } + return iter; +} + +/// Solver class for BiCG method; right preconditioner ignored (prints warning if not identity) +template < typename LinearOperator, typename Preconditioner= pc::identity<LinearOperator>, + typename RightPreconditioner= pc::identity<LinearOperator> > +class bicg_solver +{ + public: + /// Construct solver from a linear operator; generate (left) preconditioner from it + explicit bicg_solver(const LinearOperator& A) : A(A), L(A) + { + if (!pc::static_is_identity<RightPreconditioner>::value) + std::cerr << "Right Preconditioner ignored!" << std::endl; + } + + /// Construct solver from a linear operator and (left) preconditioner + bicg_solver(const LinearOperator& A, const Preconditioner& L) : A(A), L(L) + { + if (!pc::static_is_identity<RightPreconditioner>::value) + std::cerr << "Right Preconditioner ignored!" << std::endl; + } + + /// Solve linear system approximately as specified by \p iter + template < typename HilbertSpaceB, typename HilbertSpaceX, typename Iteration > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x, Iteration& iter) const + { + return bicg(A, x, b, L, iter); + } + + /// Perform one bicg iteration on linear system + template < typename HilbertSpaceB, typename HilbertSpaceX > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x) const + { + itl::basic_iteration<double> iter(x, 1, 0, 0); + return bicg(A, x, b, L, iter); + } + + private: + const LinearOperator& A; + Preconditioner L; +}; + +} // namespace itl + +#endif // ITL_BICG_INCLUDE + + + + + + diff --git a/install/MTL/include/boost/numeric/itl/krylov/bicgstab.hpp b/install/MTL/include/boost/numeric/itl/krylov/bicgstab.hpp new file mode 100644 index 00000000..c61d4874 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/krylov/bicgstab.hpp @@ -0,0 +1,120 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_BICGSTAB_INCLUDE +#define ITL_BICGSTAB_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/itl/utility/exception.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace itl { + +/// Bi-Conjugate Gradient Stabilized +template < class LinearOperator, class HilbertSpaceX, class HilbertSpaceB, + class Preconditioner, class Iteration > +int bicgstab(const LinearOperator& A, HilbertSpaceX& x, const HilbertSpaceB& b, + const Preconditioner& M, Iteration& iter) +{ + typedef typename mtl::Collection<HilbertSpaceX>::value_type Scalar; + typedef HilbertSpaceX Vector; + mtl::vampir_trace<7004> tracer; + + Scalar rho_1(0), rho_2(0), alpha(0), beta(0), gamma, omega(0); + Vector p(resource(x)), phat(resource(x)), s(resource(x)), shat(resource(x)), + t(resource(x)), v(resource(x)), r(resource(x)), rtilde(resource(x)); + + r = b - A * x; + rtilde = r; + + while (! iter.finished(r)) { + ++iter; + rho_1 = dot(rtilde, r); + MTL_THROW_IF(rho_1 == 0.0, unexpected_orthogonality()); + + if (iter.first()) + p = r; + else { + MTL_THROW_IF(omega == 0.0, unexpected_orthogonality()); + beta = (rho_1 / rho_2) * (alpha / omega); + p = r + beta * (p - omega * v); + } + phat = solve(M, p); + v = A * phat; + + gamma = dot(rtilde, v); + MTL_THROW_IF(gamma == 0.0, unexpected_orthogonality()); + + alpha = rho_1 / gamma; + s = r - alpha * v; + + if (iter.finished(s)) { + x += alpha * phat; + break; + } + shat = solve(M, s); + t = A * shat; + omega = dot(t, s) / dot(t, t); + + x += omega * shat + alpha * phat; + r = s - omega * t; + + rho_2 = rho_1; + } + return iter; +} + +/// Solver class for BiCGStab method; right preconditioner ignored (prints warning if not identity) +template < typename LinearOperator, typename Preconditioner= pc::identity<LinearOperator>, + typename RightPreconditioner= pc::identity<LinearOperator> > +class bicgstab_solver +{ + public: + /// Construct solver from a linear operator; generate (left) preconditioner from it + explicit bicgstab_solver(const LinearOperator& A) : A(A), L(A) + { + if (!pc::static_is_identity<RightPreconditioner>::value) + std::cerr << "Right Preconditioner ignored!" << std::endl; + } + + /// Construct solver from a linear operator and (left) preconditioner + bicgstab_solver(const LinearOperator& A, const Preconditioner& L) : A(A), L(L) + { + if (!pc::static_is_identity<RightPreconditioner>::value) + std::cerr << "Right Preconditioner ignored!" << std::endl; + } + + /// Solve linear system approximately as specified by \p iter + template < typename HilbertSpaceB, typename HilbertSpaceX, typename Iteration > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x, Iteration& iter) const + { + return bicgstab(A, x, b, L, iter); + } + + /// Perform one BiCGStab iteration on linear system + template < typename HilbertSpaceB, typename HilbertSpaceX > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x) const + { + itl::basic_iteration<double> iter(x, 1, 0, 0); + return solve(b, x, iter); + } + + private: + const LinearOperator& A; + Preconditioner L; +}; + +} // namespace itl + +#endif // ITL_BICGSTAB_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/krylov/bicgstab_2.hpp b/install/MTL/include/boost/numeric/itl/krylov/bicgstab_2.hpp new file mode 100644 index 00000000..b25419c7 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/krylov/bicgstab_2.hpp @@ -0,0 +1,182 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_BICGSTAB_2_INCLUDE +#define ITL_BICGSTAB_2_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/mtl/operation/size.hpp> +#include <boost/numeric/itl/pc/identity.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/matrix/strict_upper.hpp> +#include <boost/numeric/mtl/matrix/dense2D.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/operation/orth.hpp> +#include <boost/numeric/mtl/operation/lazy.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace itl { + +/// Bi-Conjugate Gradient Stabilized(2) +template < typename LinearOperator, typename Vector, + typename Preconditioner, typename Iteration > +int bicgstab_2(const LinearOperator &A, Vector &x, const Vector &b, + const Preconditioner &L, Iteration& iter) +{ + mtl::vampir_trace<7005> tracer; + using mtl::size; using mtl::irange; using mtl::imax; using mtl::mat::strict_upper; using mtl::lazy; + typedef typename mtl::Collection<Vector>::value_type Scalar; + typedef typename mtl::Collection<Vector>::size_type Size; + + if (size(b) == 0) throw mtl::logic_error("empty rhs vector"); + + const size_t l= 2; + const Scalar zero= math::zero(Scalar()), one= math::one(Scalar()); + Vector x0(resource(x)), y(resource(x)); + mtl::dense_vector<Vector> r_hat(l+1,Vector(resource(x))), u_hat(l+1,Vector(resource(x))); + + // shift problem + x0= zero; + r_hat[0]= b; + if (two_norm(x) != zero) { + r_hat[0]-= A * x; + x0= x; + x= zero; + } + + Vector r0_tilde(r_hat[0]/two_norm(r_hat[0])); + y= solve(L, r_hat[0]); + r_hat[0]= y; + u_hat[0]= zero; + + Scalar rho_0(one), rho_1(zero), alpha(zero), Gamma(zero), beta(zero), omega(one); + mtl::mat::dense2D<Scalar> tau(l+1, l+1); + mtl::dense_vector<Scalar> sigma(l+1), gamma(l+1), gamma_a(l+1), gamma_aa(l+1); + + while (! iter.finished(r_hat[0])) { + ++iter; + rho_0= -omega * rho_0; + + for (Size j= 0; j < 2; ++j) { + rho_1= dot(r0_tilde, r_hat[j]); + beta= alpha * rho_1/rho_0; rho_0= rho_1; + + for (Size i= 0; i <= j; ++i) + u_hat[i]= r_hat[i] - beta * u_hat[i]; + + y= A * u_hat[j]; + u_hat[j+1]= solve(L, y); + Gamma= dot(r0_tilde, u_hat[j+1]); + alpha= rho_0 / Gamma; + + for (Size i= 0; i <= j; ++i) + r_hat[i]-= alpha * u_hat[i+1]; + + if (iter.finished(r_hat[j])) { + x+= x0; + return iter; + } + + y= A * r_hat[j]; + r_hat[j+1]= solve(L, y); + x+= alpha * u_hat[0]; + } + + // mod GS (MR part) + irange i1m(1, imax); + mtl::dense_vector<Vector> r_hat_tail(r_hat[i1m]); + tau[i1m][i1m]= orthogonalize_factors(r_hat_tail); + for (Size j= 1; j <= l; ++j) + gamma_a[j]= dot(r_hat[j], r_hat[0]) / tau[j][j]; + + gamma[l]= gamma_a[l]; omega= gamma[l]; + if (omega == zero) return iter.fail(3, "bicg breakdown #2"); + + // is this something like a tri-solve? + for (Size j= l-1; j > 0; --j) { + Scalar sum= zero; + for (Size i=j+1;i<=l;++i) + sum += tau[j][i] * gamma[i]; + gamma[j] = gamma_a[j] - sum; + } + + gamma_aa[irange(1, l)]= strict_upper(tau[irange(1, l)][irange(1, l)]) * gamma[irange(2, l+1)] + gamma[irange(2, l+1)]; + + x+= gamma[1] * r_hat[0]; + r_hat[0]-= gamma_a[l] * r_hat[l]; + u_hat[0]-= gamma[l] * u_hat[l]; + for (Size j=1; j < l; ++j) { + u_hat[0] -= gamma[j] * u_hat[j]; + x+= gamma_aa[j] * r_hat[j]; + r_hat[0] -= gamma_a[j] * r_hat[j]; + } + } + x+= x0; // convert to real solution and undo shift + return iter; +} + + + +/// Solver class for BiCGStab(2) method; right preconditioner ignored (prints warning if not identity) +template < typename LinearOperator, typename Preconditioner= pc::identity<LinearOperator>, + typename RightPreconditioner= pc::identity<LinearOperator> > +class bicgstab_2_solver +{ + public: + /// Construct solver from a linear operator; generate (left) preconditioner from it + explicit bicgstab_2_solver(const LinearOperator& A) : A(A), L(A) + { + if (!pc::static_is_identity<RightPreconditioner>::value) + std::cerr << "Right Preconditioner ignored!" << std::endl; + } + + /// Construct solver from a linear operator and (left) preconditioner + bicgstab_2_solver(const LinearOperator& A, const Preconditioner& L) : A(A), L(L) + { + if (!pc::static_is_identity<RightPreconditioner>::value) + std::cerr << "Right Preconditioner ignored!" << std::endl; + } + + /// Solve linear system approximately as specified by \p iter + template < typename HilbertSpaceB, typename HilbertSpaceX, typename Iteration > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x, Iteration& iter) const + { + return bicgstab_2(A, x, b, L, iter); + } + + /// Perform one BiCGStab(2) iteration on linear system + template < typename HilbertSpaceB, typename HilbertSpaceX > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x) const + { + itl::basic_iteration<double> iter(x, 1, 0, 0); + return bicgstab_2(A, x, b, L, iter); + } + + private: + const LinearOperator& A; + Preconditioner L; +}; + + + +} // namespace itl + +#endif // ITL_BICGSTAB_2_INCLUDE + + + + + + diff --git a/install/MTL/include/boost/numeric/itl/krylov/bicgstab_ell.hpp b/install/MTL/include/boost/numeric/itl/krylov/bicgstab_ell.hpp new file mode 100644 index 00000000..b85f4cb2 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/krylov/bicgstab_ell.hpp @@ -0,0 +1,177 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Written by Jan Bos +// Edited by Peter Gottschling + +#ifndef ITL_BICGSTAB_ELL_INCLUDE +#define ITL_BICGSTAB_ELL_INCLUDE + +#include <boost/numeric/itl/itl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/matrix/strict_upper.hpp> +#include <boost/numeric/mtl/matrix/dense2D.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/operation/orth.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/mtl/operation/size.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace itl { + +/// Bi-Conjugate Gradient Stabilized(ell) +template < typename LinearOperator, typename Vector, + typename LeftPreconditioner, typename RightPreconditioner, + typename Iteration > +int bicgstab_ell(const LinearOperator &A, Vector &x, const Vector &b, + const LeftPreconditioner &L, const RightPreconditioner &R, + Iteration& iter, size_t l) +{ + mtl::vampir_trace<7006> tracer; + using mtl::size; using mtl::irange; using mtl::imax; using mtl::mat::strict_upper; + typedef typename mtl::Collection<Vector>::value_type Scalar; + typedef typename mtl::Collection<Vector>::size_type Size; + + if (size(b) == 0) throw mtl::logic_error("empty rhs vector"); + + const Scalar zero= math::zero(Scalar()), one= math::one(Scalar()); + Vector x0(resource(x)), y(resource(x)); + mtl::dense_vector<Vector> r_hat(l+1,Vector(resource(x))), u_hat(l+1,Vector(resource(x))); + + // shift problem + x0= zero; + r_hat[0]= b; + if (two_norm(x) != zero) { + r_hat[0]-= A * x; + x0= x; + x= zero; + } + + Vector r0_tilde(r_hat[0]/two_norm(r_hat[0])); + y= solve(L, r_hat[0]); + r_hat[0]= y; + u_hat[0]= zero; + + Scalar rho_0(one), rho_1(zero), alpha(zero), Gamma(zero), beta(zero), omega(one); + mtl::mat::dense2D<Scalar> tau(l+1, l+1); + mtl::dense_vector<Scalar> sigma(l+1), gamma(l+1), gamma_a(l+1), gamma_aa(l+1); + + while (! iter.finished(r_hat[0])) { + ++iter; + rho_0= -omega * rho_0; + + for (Size j= 0; j < l; ++j) { + rho_1= dot(r0_tilde, r_hat[j]); + beta= alpha * rho_1/rho_0; rho_0= rho_1; + + for (Size i= 0; i <= j; ++i) + u_hat[i]= r_hat[i] - beta * u_hat[i]; + + y= A * Vector(solve(R, u_hat[j])); + u_hat[j+1]= solve(L, y); + Gamma= dot(r0_tilde, u_hat[j+1]); + alpha= rho_0 / Gamma; + + for (Size i= 0; i <= j; ++i) + r_hat[i]-= alpha * u_hat[i+1]; + + if (iter.finished(r_hat[j])) { + x= solve(R, x); + x+= x0; + return iter; + } + + r_hat[j+1]= solve(R, r_hat[j]); + y= A * r_hat[j+1]; + r_hat[j+1]= solve(L, y); + x+= alpha * u_hat[0]; + } + + // mod GS (MR part) + irange i1m(1, imax); + mtl::dense_vector<Vector> r_hat_tail(r_hat[i1m]); + tau[i1m][i1m]= orthogonalize_factors(r_hat_tail); + for (Size j= 1; j <= l; ++j) + gamma_a[j]= dot(r_hat[j], r_hat[0]) / tau[j][j]; + + gamma[l]= gamma_a[l]; omega= gamma[l]; + if (omega == zero) return iter.fail(3, "bicg breakdown #2"); + + // is this something like a tri-solve? + for (Size j= l-1; j > 0; --j) { + Scalar sum= zero; + for (Size i=j+1;i<=l;++i) + sum += tau[j][i] * gamma[i]; + gamma[j] = gamma_a[j] - sum; + } + + gamma_aa[irange(1, l)]= strict_upper(tau[irange(1, l)][irange(1, l)]) * gamma[irange(2, l+1)] + gamma[irange(2, l+1)]; + + x+= gamma[1] * r_hat[0]; + r_hat[0]-= gamma_a[l] * r_hat[l]; + u_hat[0]-= gamma[l] * u_hat[l]; + for (Size j=1; j < l; ++j) { + u_hat[0] -= gamma[j] * u_hat[j]; + x+= gamma_aa[j] * r_hat[j]; + r_hat[0] -= gamma_a[j] * r_hat[j]; + } + } + x= solve(R, x); x+= x0; // convert to real solution and undo shift + return iter; +} + + +/// Solver class for BiCGStab(ell) method; right preconditioner ignored (prints warning if not identity) +template < typename LinearOperator, typename Preconditioner, + typename RightPreconditioner> +class bicgstab_ell_solver +{ + public: + /// Construct solver from a linear operator; generate (left) preconditioner from it + explicit bicgstab_ell_solver(const LinearOperator& A, size_t l= 8) : A(A), l(l), L(A), R(A) {} + + /// Construct solver from a linear operator and left preconditioner + bicgstab_ell_solver(const LinearOperator& A, size_t l, const Preconditioner& L) : A(A), l(l), L(L), R(A) {} + + /// Construct solver from a linear operator and left preconditioner + bicgstab_ell_solver(const LinearOperator& A, size_t l, const Preconditioner& L, const RightPreconditioner& R) + : A(A), l(l), L(L), R(R) {} + + /// Solve linear system approximately as specified by \p iter + template < typename HilbertSpaceB, typename HilbertSpaceX, typename Iteration > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x, Iteration& iter) const + { + return bicgstab_ell(A, x, b, L, R, iter, l); + } + + /// Perform one BiCGStab(ell) iteration on linear system + template < typename HilbertSpaceB, typename HilbertSpaceX > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x) const + { + itl::basic_iteration<double> iter(x, 1, 0, 0); + return solve(b, x, iter); + } + + private: + const LinearOperator& A; + size_t l; + Preconditioner L; + RightPreconditioner R; +}; + + +} // namespace itl + +#endif // ITL_BICGSTAB_ELL_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/krylov/cg.hpp b/install/MTL/include/boost/numeric/itl/krylov/cg.hpp new file mode 100644 index 00000000..f1f2eeed --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/krylov/cg.hpp @@ -0,0 +1,163 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_CG_INCLUDE +#define ITL_CG_INCLUDE + +#include <cmath> +#include <cassert> +#include <iostream> +#include <boost/mpl/bool.hpp> + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/itl/itl_fwd.hpp> +#include <boost/numeric/itl/iteration/basic_iteration.hpp> +#include <boost/numeric/itl/pc/identity.hpp> +#include <boost/numeric/itl/pc/is_identity.hpp> +#include <boost/numeric/mtl/operation/dot.hpp> +#include <boost/numeric/mtl/operation/unary_dot.hpp> +#include <boost/numeric/mtl/operation/conj.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/mtl/operation/lazy.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace itl { + +/// Conjugate Gradients without preconditioning +template < typename LinearOperator, typename HilbertSpaceX, typename HilbertSpaceB, + typename Iteration > +int cg(const LinearOperator& A, HilbertSpaceX& x, const HilbertSpaceB& b, + Iteration& iter) +{ + mtl::vampir_trace<7001> tracer; + using std::abs; using mtl::conj; using mtl::lazy; + typedef HilbertSpaceX Vector; + typedef typename mtl::Collection<HilbertSpaceX>::value_type Scalar; + typedef typename Iteration::real Real; + + Scalar rho(0), rho_1(0), alpha(0), alpha_1(0); + Vector p(resource(x)), q(resource(x)), r(resource(x)), z(resource(x)); + + r = b - A*x; + rho = dot(r, r); + while (! iter.finished(Real(sqrt(abs(rho))))) { + ++iter; + if (iter.first()) + p = r; + else + p = r + (rho / rho_1) * p; + + // q = A * p; alpha = rho / dot(p, q); + (lazy(q)= A * p) || (lazy(alpha_1)= lazy_dot(p, q)); + alpha= rho / alpha_1; + + x += alpha * p; + rho_1 = rho; + (lazy(r) -= alpha * q) || (lazy(rho) = lazy_unary_dot(r)); + } + + return iter; +} + +/// Conjugate Gradients +template < typename LinearOperator, typename HilbertSpaceX, typename HilbertSpaceB, + typename Preconditioner, typename Iteration > +int cg(const LinearOperator& A, HilbertSpaceX& x, const HilbertSpaceB& b, + const Preconditioner& L, Iteration& iter) +{ + using pc::is_identity; + if (is_identity(L)) + return cg(A, x, b, iter); + + mtl::vampir_trace<7002> tracer; + using std::abs; using mtl::conj; using mtl::lazy; + typedef HilbertSpaceX Vector; + typedef typename mtl::Collection<HilbertSpaceX>::value_type Scalar; + typedef typename Iteration::real Real; + + Scalar rho(0), rho_1(0), rr, alpha(0), alpha_1; + Vector p(resource(x)), q(resource(x)), r(resource(x)), z(resource(x)); + + r = b - A*x; + rr = dot(r, r); + while (! iter.finished(Real(sqrt(abs(rr))))) { + ++iter; + (lazy(z)= solve(L, r)) || (lazy(rho)= lazy_dot(r, z)); + + if (iter.first()) + p = z; + else + p = z + (rho / rho_1) * p; + + (lazy(q)= A * p) || (lazy(alpha_1)= lazy_dot(p, q)); + alpha= rho / alpha_1; + + x += alpha * p; + rho_1 = rho; + (lazy(r) -= alpha * q) || (lazy(rr) = lazy_unary_dot(r)); + } + return iter; +} + +/// Conjugate Gradients with ignored right preconditioner to unify interface +template < typename LinearOperator, typename HilbertSpaceX, typename HilbertSpaceB, + typename Preconditioner, typename RightPreconditioner, typename Iteration > +int cg(const LinearOperator& A, HilbertSpaceX& x, const HilbertSpaceB& b, + const Preconditioner& L, const RightPreconditioner&, Iteration& iter) +{ + return cg(A, x, b, L, iter); +} + +/// Solver class for CG method; right preconditioner ignored (prints warning if not identity) +template < typename LinearOperator, typename Preconditioner, + typename RightPreconditioner> +class cg_solver +{ + public: + /// Construct solver from a linear operator; generate (left) preconditioner from it + explicit cg_solver(const LinearOperator& A) : A(A), L(A) + { + if (!pc::static_is_identity<RightPreconditioner>::value) + std::cerr << "Right Preconditioner ignored!" << std::endl; + } + + /// Construct solver from a linear operator and (left) preconditioner + cg_solver(const LinearOperator& A, const Preconditioner& L) : A(A), L(L) + { + if (!pc::static_is_identity<RightPreconditioner>::value) + std::cerr << "Right Preconditioner ignored!" << std::endl; + } + + /// Solve linear system approximately as specified by \p iter + template < typename HilbertSpaceB, typename HilbertSpaceX, typename Iteration > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x, Iteration& iter) const + { + return cg(A, x, b, L, iter); + } + + /// Perform one CG iteration on linear system + template < typename HilbertSpaceB, typename HilbertSpaceX > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x) const + { + itl::basic_iteration<double> iter(x, 1, 0, 0); + return solve(b, x, iter); + } + + private: + const LinearOperator& A; + Preconditioner L; +}; + + +} // namespace itl + +#endif // ITL_CG_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/krylov/cgs.hpp b/install/MTL/include/boost/numeric/itl/krylov/cgs.hpp new file mode 100644 index 00000000..0fc0705b --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/krylov/cgs.hpp @@ -0,0 +1,110 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_CGS_INCLUDE +#define ITL_CGS_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/mtl/operation/dot.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace itl { + +/// Conjugate Gradient Squared +template < typename LinearOperator, typename Vector, + typename Preconditioner, typename Iteration > +int cgs(const LinearOperator &A, Vector &x, const Vector &b, + const Preconditioner &M, Iteration& iter) +{ + mtl::vampir_trace<7007> tracer; + typedef typename mtl::Collection<Vector>::value_type Scalar; + Scalar rho_1(0), rho_2(0), alpha(0), beta(0); + Vector p(resource(x)), phat(resource(x)), q(resource(x)), qhat(resource(x)), vhat(resource(x)), + u(resource(x)), uhat(resource(x)), r(b - A * x), rtilde= r; + + while (! iter.finished(r)) { + ++iter; + rho_1= dot(rtilde, r); + + if (rho_1 == 0.) iter.fail(2, "cgs breakdown"); + + if (iter.first()) + p= u= r; + else { + beta = rho_1 / rho_2; + u= r + beta * q; + p= u + beta * (q + beta * p); + } + + vhat= A * Vector(solve(M, p)); + alpha = rho_1 / dot(rtilde, vhat); + q= u - alpha * vhat; + + u+= q; + uhat= solve(M, u); + + x+= alpha * uhat; + qhat= A * uhat; + r-= alpha * qhat; + + rho_2= rho_1; + } + return iter; +} + +/// Solver class for CGS method; right preconditioner ignored (prints warning if not identity) +template < typename LinearOperator, typename Preconditioner= pc::identity<LinearOperator>, + typename RightPreconditioner= pc::identity<LinearOperator> > +class cgs_solver +{ + public: + /// Construct solver from a linear operator; generate (left) preconditioner from it + explicit cgs_solver(const LinearOperator& A) : A(A), L(A) + { + if (!pc::static_is_identity<RightPreconditioner>::value) + std::cerr << "Right Preconditioner ignored!" << std::endl; + } + + /// Construct solver from a linear operator and (left) preconditioner + cgs_solver(const LinearOperator& A, const Preconditioner& L) : A(A), L(L) + { + if (!pc::static_is_identity<RightPreconditioner>::value) + std::cerr << "Right Preconditioner ignored!" << std::endl; + } + + /// Solve linear system approximately as specified by \p iter + template < typename HilbertSpaceB, typename HilbertSpaceX, typename Iteration > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x, Iteration& iter) const + { + return cgs(A, x, b, L, iter); + } + + /// Perform one CGS iteration on linear system + template < typename HilbertSpaceB, typename HilbertSpaceX > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x) const + { + itl::basic_iteration<double> iter(x, 1, 0, 0); + return solve(b, x, iter); + } + + private: + const LinearOperator& A; + Preconditioner L; +}; + +} // namespace itl + +#endif // ITL_CGS_INCLUDE + + + diff --git a/install/MTL/include/boost/numeric/itl/krylov/fsm.hpp b/install/MTL/include/boost/numeric/itl/krylov/fsm.hpp new file mode 100644 index 00000000..e398bcef --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/krylov/fsm.hpp @@ -0,0 +1,39 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_FSM_INCLUDE +#define ITL_FSM_INCLUDE + +#include <boost/numeric/mtl/operation/two_norm.hpp> + +namespace itl { + +/// Folded spectrum method +/** Computed and named as in http://en.wikipedia.org/wiki/Folded_spectrum_method **/ +template < typename LinearOperator, typename VectorSpace, typename EigenValue, + typename Damping, typename Iteration > +int fsm(const LinearOperator& H, VectorSpace& phi, EigenValue eps, Damping alpha, Iteration& iter) +{ + VectorSpace v1(H * phi - eps * phi); + for (; !iter.finished(v1); ++iter) { + VectorSpace v2(H * v1 - eps * v1); + phi-= alpha * v2; + phi/= two_norm(phi); + v1= H * phi - eps * phi; + } + return iter; +} + + +} // namespace itl + +#endif // ITL_FSM_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/krylov/gmres.hpp b/install/MTL/include/boost/numeric/itl/krylov/gmres.hpp new file mode 100644 index 00000000..4a2f4eab --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/krylov/gmres.hpp @@ -0,0 +1,181 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Written by Cornelius Steinhardt + + +#ifndef ITL_GMRES_INCLUDE +#define ITL_GMRES_INCLUDE + +#include <algorithm> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/matrix/dense2D.hpp> +#include <boost/numeric/mtl/matrix/multi_vector.hpp> +#include <boost/numeric/mtl/operation/givens.hpp> +#include <boost/numeric/mtl/operation/two_norm.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> + +namespace itl { + +/// Generalized Minimal Residual method (without restart) +/** It computes at most kmax_in iterations (or size(x) depending on what is smaller) + regardless on whether the termination criterion is reached or not. **/ +template < typename Matrix, typename Vector, typename LeftPreconditioner, typename RightPreconditioner, typename Iteration > +int gmres_full(const Matrix &A, Vector &x, const Vector &b, + LeftPreconditioner &L, RightPreconditioner &R, Iteration& iter) +{ + using mtl::size; using mtl::irange; using mtl::iall; using std::abs; using std::sqrt; + typedef typename mtl::Collection<Vector>::value_type Scalar; + typedef typename mtl::Collection<Vector>::size_type Size; + + if (size(b) == 0) throw mtl::logic_error("empty rhs vector"); + + const Scalar zero= math::zero(Scalar()); + Scalar rho, nu, hr; + Size k, kmax(std::min(size(x), Size(iter.max_iterations() - iter.iterations()))); + Vector r0(b - A *x), r(solve(L,r0)), va(resource(x)), va0(resource(x)), va00(resource(x)); + mtl::mat::multi_vector<Vector> V(Vector(resource(x), zero), kmax+1); + mtl::dense_vector<Scalar> s(kmax+1, zero), c(kmax+1, zero), g(kmax+1, zero), y(kmax, zero); // replicated in distributed solvers + mtl::mat::dense2D<Scalar> H(kmax+1, kmax); // dito + H= 0; + + rho= g[0]= two_norm(r); + if (iter.finished(rho)) + return iter; + V.vector(0)= r / rho; + H= zero; + + // GMRES iteration + for (k= 0; k < kmax ; ++k, ++iter) { + va0= A * Vector(solve(R, V.vector(k))); + V.vector(k+1)= va= solve(L,va0); + // orth(V, V[k+1], false); + // modified Gram Schmidt method + for (Size j= 0; j < k+1; j++) { + H[j][k]= dot(V.vector(j), V.vector(k+1)); + V.vector(k+1)-= H[j][k] * V.vector(j); + } + H[k+1][k]= two_norm(V.vector(k+1)); + //reorthogonalize + for(Size j= 0; j < k+1; j++) { + hr= dot(V.vector(k+1), V.vector(j)); + H[j][k]+= hr; + V.vector(k+1)-= hr * V.vector(j); + } + H[k+1][k]= two_norm(V.vector(k+1)); + if (H[k+1][k] != zero) // watch for breakdown + V.vector(k+1)*= 1. / H[k+1][k]; + + // k Given's rotations + for(Size i= 0; i < k; i++) + mtl::mat::givens<mtl::mat::dense2D<Scalar> >(H, H[i][k-1], H[i+1][k-1]).trafo(i); + + nu= sqrt(H[k][k]*H[k][k]+H[k+1][k]*H[k+1][k]); + if(nu != zero){ + c[k]= H[k][k]/nu; + s[k]= -H[k+1][k]/nu; + H[k][k]=c[k]*H[k][k]-s[k]*H[k+1][k]; + H[k+1][k]=0; + mtl::vec::givens<mtl::vec::dense_vector<Scalar> >(g, c[k], s[k]).trafo(k); + } + rho= abs(g[k+1]); + } + + //reduce k, to get regular matrix + while (k > 0 && abs(g[k-1]<= iter.atol())) k--; + + // iteration is finished -> compute x: solve H*y=g as far as rank of H allows + irange range(k); + for (; !range.empty(); --range) { + try { + y[range]= lu_solve(H[range][range], g[range]); + } catch (mtl::matrix_singular) { continue; } // if singular then try with sub-matrix + break; + } + + if (range.finish() < k) + std::cerr << "GMRES orhogonalized with " << k << " vectors but matrix singular, can only use " + << range.finish() << " vectors!\n"; + if (range.empty()) + return iter.fail(2, "GMRES did not find any direction to correct x"); + x+= Vector(solve(R, Vector(V.vector(range)*y[range]))); + + r= b - A*x; + return iter.terminate(r); +} + +/// Generalized Minimal Residual method with restart +template < typename Matrix, typename Vector, typename LeftPreconditioner, + typename RightPreconditioner, typename Iteration > +int gmres(const Matrix &A, Vector &x, const Vector &b, + LeftPreconditioner &L, RightPreconditioner &R, + Iteration& iter, typename mtl::Collection<Vector>::size_type restart) +{ + do { + Iteration inner(iter); + inner.set_max_iterations(std::min(int(iter.iterations()+restart), iter.max_iterations())); + inner.suppress_resume(true); + gmres_full(A, x, b, L, R, inner); + iter.update_progress(inner); + } while (!iter.finished()); + + return iter; +} + +/// Solver class for GMRES; right preconditioner ignored (prints warning if not identity) +template < typename LinearOperator, typename Preconditioner= pc::identity<LinearOperator>, + typename RightPreconditioner= pc::identity<LinearOperator> > +class gmres_solver +{ + public: + /// Construct solver from a linear operator; generate (left) preconditioner from it + explicit gmres_solver(const LinearOperator& A, size_t restart= 8) + : A(A), restart(restart), L(A), R(A) {} + + /// Construct solver from a linear operator and left preconditioner + gmres_solver(const LinearOperator& A, size_t restart, const Preconditioner& L) + : A(A), restart(restart), L(L), R(A) {} + + /// Construct solver from a linear operator and left preconditioner + gmres_solver(const LinearOperator& A, size_t restart, const Preconditioner& L, const RightPreconditioner& R) + : A(A), restart(restart), L(L), R(R) {} + + /// Solve linear system approximately as specified by \p iter + template < typename HilbertSpaceB, typename HilbertSpaceX, typename Iteration > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x, Iteration& iter) const + { + return gmres(A, x, b, L, R, iter, restart); + } + + /// Perform one GMRES iteration on linear system + template < typename HilbertSpaceB, typename HilbertSpaceX > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x) const + { + itl::basic_iteration<double> iter(x, 1, 0, 0); + return solve(b, x, iter); + } + + private: + const LinearOperator& A; + size_t restart; + Preconditioner L; + RightPreconditioner R; +}; + + +} // namespace itl + +#endif // ITL_GMRES_INCLUDE + + diff --git a/install/MTL/include/boost/numeric/itl/krylov/idr_s.hpp b/install/MTL/include/boost/numeric/itl/krylov/idr_s.hpp new file mode 100644 index 00000000..55a77db9 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/krylov/idr_s.hpp @@ -0,0 +1,144 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Peter Sonneveld and Martin B. van Gijzen, IDR(s): a family of simple and fast algorithms for solving large nonsymmetric linear systems. +// SIAM J. Sci. Comput. Vol. 31, No. 2, pp. 1035-1062 (2008). (copyright SIAM) + +#ifndef ITL_IDR_S_INCLUDE +#define ITL_IDR_S_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/operation/random.hpp> +#include <boost/numeric/mtl/operation/orth.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/mtl/matrix/strict_upper.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace itl { + +/// Induced Dimension Reduction on s dimensions (IDR(s)) +template < typename LinearOperator, typename Vector, + typename LeftPreconditioner, typename RightPreconditioner, + typename Iteration > +int idr_s(const LinearOperator &A, Vector &x, const Vector &b, + const LeftPreconditioner &, const RightPreconditioner &, + Iteration& iter, size_t s) +{ + mtl::vampir_trace<7010> tracer; + using mtl::size; using mtl::iall; using mtl::mat::strict_upper; + typedef typename mtl::Collection<Vector>::value_type Scalar; + typedef typename mtl::Collection<Vector>::size_type Size; + + if (size(b) == 0) throw mtl::logic_error("empty rhs vector"); + if (s < 1) s= 1; + + const Scalar zero= math::zero(Scalar()); + Scalar omega(zero); + Vector x0(x), y(resource(x)), v(resource(x)), t(resource(x)), q(resource(x)), r(b - A * x); + mtl::mat::multi_vector<Vector> dR(Vector(resource(x), zero), s), dX(Vector(resource(x), zero), s), P(Vector(resource(x), zero), s); + mtl::dense_vector<Scalar> m(s), c(s), dm(s); // replicated in distributed solvers + mtl::mat::dense2D<Scalar> M(s, s); // dito + + random(P); + P.vector(0)= r; + orth(P); + + for (size_t k= 0; k < s; k++) { + v= A * r; + omega= dot(v, r) / dot(v, v); + dX.vector(k)= omega * r; + dR.vector(k)= -omega * v; + x+= dX.vector(k); + r+= dR.vector(k); + if ((++iter).finished(r)) return iter; + M[iall][k]= trans(P) * dR.vector(k); + } + + Size oldest= 0; + m= trans(P) * r; + + while (! iter.finished(r)) { + + for (size_t k= 0; k < s; k++) { + c= lu_solve(M, m); + q= dR * -c; + v= r + q; + if (k == 0) { + t= A * v; + omega= dot(t, v) / dot(t, t); + dR.vector(oldest)= q - omega * t; + dX.vector(oldest)= omega * v - dX * c; + } else { + dX.vector(oldest)= omega * v - dX * c; + dR.vector(oldest)= A * -dX.vector(oldest); + } + r+= dR.vector(oldest); + x+= dX.vector(oldest); + + if ((++iter).finished(r)) + return iter; + + dm= trans(P) * dR.vector(oldest); + M[iall][oldest]= dm; + m+= dm; + oldest= (oldest + 1) % s; + } + } + return iter; +} + +/// Solver class for IDR(s) method; right preconditioner ignored (prints warning if not identity) +template < typename LinearOperator, typename Preconditioner= pc::identity<LinearOperator>, + typename RightPreconditioner= pc::identity<LinearOperator> > +class idr_s_solver +{ + public: + /// Construct solver from a linear operator; generate (left) preconditioner from it + explicit idr_s_solver(const LinearOperator& A, size_t s= 8) : A(A), s(s), L(A), R(A) {} + + /// Construct solver from a linear operator and left preconditioner + idr_s_solver(const LinearOperator& A, size_t s, const Preconditioner& L) : A(A), s(s), L(L), R(A) {} + + /// Construct solver from a linear operator and left preconditioner + idr_s_solver(const LinearOperator& A, size_t s, const Preconditioner& L, const RightPreconditioner& R) + : A(A), s(s), L(L), R(R) {} + + /// Solve linear system approximately as specified by \p iter + template < typename HilbertSpaceB, typename HilbertSpaceX, typename Iteration > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x, Iteration& iter) const + { + return idr_s(A, x, b, L, R, iter, s); + } + + /// Perform one IDR(s) iteration on linear system + template < typename HilbertSpaceB, typename HilbertSpaceX > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x) const + { + itl::basic_iteration<double> iter(x, 1, 0, 0); + return solve(b, x, iter); + } + + private: + const LinearOperator& A; + size_t s; + Preconditioner L; + RightPreconditioner R; +}; + + +} // namespace itl + +#endif // ITL_IDR_S_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/krylov/qmr.hpp b/install/MTL/include/boost/numeric/itl/krylov/qmr.hpp new file mode 100644 index 00000000..151c5eeb --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/krylov/qmr.hpp @@ -0,0 +1,150 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Written by Cornelius Steinhardt + + +#ifndef ITL_QMR_INCLUDE +#define ITL_QMR_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/trans.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace itl { + +/// Quasi-Minimal Residual method +template < typename Matrix, typename Vector,typename LeftPreconditioner, + typename RightPreconditioner, typename Iteration > +int qmr(const Matrix& A, Vector& x, const Vector& b, LeftPreconditioner& L, + const RightPreconditioner& R, Iteration& iter) +{ + mtl::vampir_trace<7008> tracer; + using mtl::size; + typedef typename mtl::Collection<Vector>::value_type Scalar; + if (size(b) == 0) throw mtl::logic_error("empty rhs vector"); + + const Scalar zero= math::zero(Scalar()), one= math::one(Scalar()); + Scalar beta, gamma(one), gamma_1, delta, eta(-one), ep(one), rho_1, theta(zero), theta_1; + Vector r(b - A * x), v_tld(r), y(solve(L, v_tld)), w_tld(r), z(adjoint_solve(R,w_tld)), v(resource(x)), w(resource(x)), + y_tld(resource(x)), z_tld(resource(x)), p(resource(x)), q(resource(x)), p_tld(resource(x)), d(resource(x)), s(resource(x)); + + if (iter.finished(r)) + return iter; + + Scalar rho = two_norm(y), xi = two_norm(z); + while(! iter.finished(rho)) { + ++iter; + if (rho == zero) + return iter.fail(1, "qmr breakdown #1, rho=0"); + if (xi == zero) + return iter.fail(2, "qmr breakdown #2, xi=0"); + + v= v_tld / rho; + y/= rho; + w= w_tld / xi; + z/= xi; + + delta = dot(z,y); + if (delta == zero) + return iter.fail(3, "qmr breakdown, delta=0 #3"); + + y_tld = solve(R,y); + z_tld = adjoint_solve(L,z); + + if (iter.first()) { + p = y_tld; + q = z_tld; + } else { + p = y_tld - ((xi * delta) / ep) * p; + q = z_tld - ((rho* delta) / ep) * q; + } + + p_tld = A * p; + ep = dot(q, p_tld); + if (ep == zero) + return iter.fail(4, "qmr breakdown ep=0 #4"); + beta= ep / delta; + if (beta == zero) + return iter.fail(5, "qmr breakdown beta=0 #5"); + v_tld = p_tld - beta * v; + y = solve(L,v_tld); + rho_1 = rho; + rho = two_norm(y); + w_tld= trans(A)*q - beta*w; + z = adjoint_solve(R, w_tld); + xi = two_norm(z); + gamma_1 = gamma; + theta_1 = theta; + theta = rho / (gamma_1 * beta); + gamma = one / (sqrt(one + theta * theta)); + + if (gamma == zero) + return iter.fail(6, "qmr breakdown gamma=0 #6"); + + eta= -eta * rho_1 * gamma * gamma / (beta * gamma_1 * gamma_1); + if (iter.first()) { + d= eta * p; + s= eta * p_tld; + } else { + d= eta * p + (theta_1 * theta_1 * gamma * gamma) * d; + s= eta * p_tld + (theta_1 * theta_1 * gamma * gamma) * s; + } + x += d; + r -= s; + } + return iter; +} + +/// Solver class for Quasi-minimal residual method; right preconditioner ignored (prints warning if not identity) +template < typename LinearOperator, typename Preconditioner= pc::identity<LinearOperator>, + typename RightPreconditioner= pc::identity<LinearOperator> > +class qmr_solver +{ + public: + /// Construct solver from a linear operator; generate (left) preconditioner from it + explicit qmr_solver(const LinearOperator& A) : A(A), L(A), R(A) {} + + /// Construct solver from a linear operator and left preconditioner + qmr_solver(const LinearOperator& A, const Preconditioner& L) : A(A), L(L), R(A) {} + + /// Construct solver from a linear operator and left preconditioner + qmr_solver(const LinearOperator& A, const Preconditioner& L, const RightPreconditioner& R) + : A(A), L(L), R(R) {} + + /// Solve linear system approximately as specified by \p iter + template < typename HilbertSpaceB, typename HilbertSpaceX, typename Iteration > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x, Iteration& iter) const + { + return qmr(A, x, b, L, R, iter); + } + + /// Perform one QMR iteration on linear system + template < typename HilbertSpaceB, typename HilbertSpaceX > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x) const + { + itl::basic_iteration<double> iter(x, 1, 0, 0); + return solve(b, x, iter); + } + + private: + const LinearOperator& A; + Preconditioner L; + RightPreconditioner R; +}; + + +} // namespace itl + +#endif // ITL_QMR_INCLUDE + diff --git a/install/MTL/include/boost/numeric/itl/krylov/repeating_solver.hpp b/install/MTL/include/boost/numeric/itl/krylov/repeating_solver.hpp new file mode 100644 index 00000000..9716cf26 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/krylov/repeating_solver.hpp @@ -0,0 +1,52 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef ITL_REPEATING_SOLVER_INCLUDE +#define ITL_REPEATING_SOLVER_INCLUDE + +#include <boost/mpl/if.hpp> +#include <boost/static_assert.hpp> +#include <boost/numeric/itl/itl_fwd.hpp> + +namespace itl { + +/// Class for calling \tparam N iterations of the given \tparam Solver +/** If \tparam Stored is true then the \tparam Solver object is stored (i.e. possibly copied) here. + Otherwise it is only referred and passing temporary objects to the constructor will cause errors. **/ +template <typename Solver, unsigned N, bool Stored> +class repeating_solver +{ + typedef typename boost::mpl::if_c<Stored, Solver, const Solver&>::type solver_type; + public: + explicit repeating_solver(const Solver& s) : s(s) {} + + template <typename Matrix> + explicit repeating_solver(const Matrix& A) : s(A) + { + BOOST_STATIC_ASSERT((Stored)); // if matrix is passed class must own solver + } + + /// Perform one GMRES iteration on linear system + template < typename VectorIn, typename VectorOut > + int solve(const VectorIn& b, VectorOut& x) const + { + itl::basic_iteration<double> iter(x, N, 0, 0); + return s.solve(b, x, iter); + } + + private: + solver_type s; +}; + +} // namespace itl + +#endif // ITL_REPEATING_SOLVER_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/krylov/tfqmr.hpp b/install/MTL/include/boost/numeric/itl/krylov/tfqmr.hpp new file mode 100644 index 00000000..eb2284bc --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/krylov/tfqmr.hpp @@ -0,0 +1,135 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Written by Cornelius Steinhardt + + +#ifndef ITL_TFQMR_INCLUDE +#define ITL_TFQMR_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/linear_algebra/inverse.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace itl { + +/// Transposed-free Quasi-minimal residual +template < typename Matrix, typename Vector, + typename LeftPreconditioner, typename RightPreconditioner, typename Iteration > +int tfqmr(const Matrix &A, Vector &x, const Vector &b, const LeftPreconditioner &L, + const RightPreconditioner &R, Iteration& iter) +{ + mtl::vampir_trace<7009> tracer; + using math::reciprocal; using mtl::size; + typedef typename mtl::Collection<Vector>::value_type Scalar; + + if (size(b) == 0) throw mtl::logic_error("empty rhs vector"); + + const Scalar zero= math::zero(Scalar()), one= math::one(Scalar()); + Scalar theta(zero), eta(zero), tau, rho, rhon, sigma, alpha, beta, c; + Vector rt(b - A*Vector(solve(R, x))) /* shift x= R*x */, r(solve(L, rt)), u1(resource(x)), u2(resource(x)), + y1(resource(x)), y2(resource(x)), w(resource(x)), d(resource(x), zero), v(resource(x)); + + if (iter.finished(rt)) + return iter; + y1= w= r; + rt= A * Vector(solve(R, y1)); + u1= v= solve(L,rt); + tau= two_norm(r); + rho= tau * tau; + + // TFQMR iteration + while (! iter.finished(tau)) { + ++iter; + sigma= dot(r,v); + if (sigma == zero) + return iter.fail(1, "tfgmr breakdown, sigma=0 #1"); + alpha= rho / sigma; + + // inner loop + for(int j=1; j < 3; j++) { + if (j == 1) { + w-= alpha * u1; + d= y1+ (theta * theta * eta / alpha) * d; + } else { + y2= y1 - alpha * v; + rt= A * Vector(solve(R, y2)); + u2= solve(L, rt); + w-= alpha * u2; + d= y2 + (theta * theta * eta / alpha) * d; + } + theta= two_norm(w) / tau; + c= reciprocal(sqrt(one + theta*theta)); + tau*= theta * c; + eta= c * c * alpha; + x+= eta * d; + } // end inner loop + if (rho == zero) + return iter.fail(1, "tfgmr breakdown, rho=0 #2"); + rhon= dot(r,w); + beta= rhon/rho; + rho= rhon; + y1= w + beta*y2; + rt= A * Vector(solve(R, y1)); + u1= solve(L, rt); + v= u1 + beta*(u2 + beta*v); + rt= A * x - b; + } + //shift back + x= solve(R, x); + return iter; +} + +/// Solver class for Transposed-free quasi-minimal residual method; right preconditioner ignored (prints warning if not identity) +template < typename LinearOperator, typename Preconditioner= pc::identity<LinearOperator>, + typename RightPreconditioner= pc::identity<LinearOperator> > +class tfqmr_solver +{ + public: + /// Construct solver from a linear operator; generate (left) preconditioner from it + explicit tfqmr_solver(const LinearOperator& A) : A(A), L(A), R(A) {} + + /// Construct solver from a linear operator and left preconditioner + tfqmr_solver(const LinearOperator& A, const Preconditioner& L) : A(A), L(L), R(A) {} + + /// Construct solver from a linear operator and left preconditioner + tfqmr_solver(const LinearOperator& A, const Preconditioner& L, const RightPreconditioner& R) + : A(A), L(L), R(R) {} + + /// Solve linear system approximately as specified by \p iter + template < typename HilbertSpaceB, typename HilbertSpaceX, typename Iteration > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x, Iteration& iter) const + { + return tfqmr(A, x, b, L, R, iter); + } + + /// Perform one TFQMR iteration on linear system + template < typename HilbertSpaceB, typename HilbertSpaceX > + int solve(const HilbertSpaceB& b, HilbertSpaceX& x) const + { + itl::basic_iteration<double> iter(x, 1, 0, 0); + return solve(b, x, iter); + } + + private: + const LinearOperator& A; + Preconditioner L; + RightPreconditioner R; +}; + +} // namespace itl + +#endif // ITL_TFQMR_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/minimization/quasi_newton.hpp b/install/MTL/include/boost/numeric/itl/minimization/quasi_newton.hpp new file mode 100644 index 00000000..2136952b --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/minimization/quasi_newton.hpp @@ -0,0 +1,61 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_QUASI_NEWTON_INCLUDE +#define ITL_QUASI_NEWTON_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/matrix/dense2D.hpp> +#include <boost/numeric/mtl/matrix/operators.hpp> +#include <boost/numeric/mtl/operation/operators.hpp> +#include <boost/numeric/mtl/operation/trans.hpp> +#include <boost/numeric/mtl/utility/gradient.hpp> + +// #include <iostream> + +namespace itl { + +/// Quasi-Newton method +template <typename Matrix, typename Vector, typename F, typename Grad, + typename Step, typename Update, typename Iter> +Vector quasi_newton(Vector& x, F f, Grad grad_f, Step step, Update update, Iter& iter) +{ + typedef typename mtl::Collection<Vector>::value_type value_type; + Vector d, y, x_k, s; + Matrix H(size(x), size(x)); + + H= 1; + for (; !iter.finished(two_norm(grad_f(x))); ++iter) { + d= H * -grad_f(x); // std::cout << "d is " << d << '\n'; + value_type alpha= step(x, d, f, grad_f); assert(alpha == alpha); + x_k= x + alpha * d; // std::cout << "x_k is " << x_k << '\n'; + s= alpha * d; // std::cout << "alpha is " << alpha << '\n'; + y= grad_f(x_k) - grad_f(x); + update(H, y, s); + x= x_k; + } + return x; +} + +/// Quasi-Newton method +template <typename Vector, typename F, typename Grad, typename Step, typename Update, typename Iter> +Vector inline quasi_newton(Vector& x, F f, Grad grad_f, Step step, Update update, Iter& iter) +{ + typedef typename mtl::traits::gradient<Vector>::type hessian_type; + // typedef typename mtl::Collection<Vector>::value_type value_type; + return quasi_newton<hessian_type>(x, f, grad_f, step, update, iter); +} + + +} // namespace itl + +#endif // ITL_QUASI_NEWTON_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/binary_heap.hpp b/install/MTL/include/boost/numeric/itl/pc/binary_heap.hpp new file mode 100644 index 00000000..399ae33d --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/binary_heap.hpp @@ -0,0 +1,607 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. +// +// Algorithm inspired by Nick Vannieuwenhoven, rewritten by Cornelius Steinhardt +// +// Created on: Jan 10, 2010 +// Author: heazk + + +#ifndef MTL_BINARY_HEAP_INCLUDE +#define MTL_BINARY_HEAP_INCLUDE + +namespace utils { + +/** + * An intrusive binary min-heap. + * + * KeyType: The type of the keys. Assumed to be a signed integer type. + * KeyComparator: A functor to compare values of the key type. Should be a + * total order. + */ +template< + class DirectAccessIterator, + class KeyType, + class KeyComparator, + class ValueType, + class GetKey, + class GetParent, + class GetLeft, + class GetRight +> +class binary_heap { + + +/******************************************************************************* + * Type Definitions + ******************************************************************************/ + + +public: + /** + * The value type. + */ + typedef ValueType value_type; + + /** + * The key type. + */ + typedef KeyType key_type; + + /** + * The type of this heap. + */ + typedef binary_heap< + DirectAccessIterator, + KeyType, + KeyComparator, + ValueType, + GetKey, + GetParent, + GetLeft, + GetRight + > heap_type; + + +/******************************************************************************* + * Constructors and Destructors + ******************************************************************************/ + + +public: + binary_heap( + DirectAccessIterator values_begin, + DirectAccessIterator values_end, + KeyComparator compare_keys, + GetKey get_key, + GetParent get_parent, + GetLeft get_left_child, + GetRight get_right_child + ) : + m_root(values_begin), + m_compare_keys(compare_keys), + m_key(get_key), + m_parent(get_parent), + m_left_child(get_left_child), + m_right_child(get_right_child) + { + build_heap(values_begin, values_end); + } + +public: + binary_heap( + KeyComparator compare_keys, + GetKey get_key, + GetParent get_parent, + GetLeft get_left_child, + GetRight get_right_child + ) : + m_root(0), + m_last(0), + m_compare_keys(compare_keys), + m_key(get_key), + m_parent(get_parent), + m_left_child(get_left_child), + m_right_child(get_right_child) + { + } + + /** + * Default destructor. + */ +public: + ~binary_heap() { + // Nothing here. + } + + /** + * Copying of heaps is disallowed. + */ +private: + binary_heap(const heap_type&); + void operator=(const heap_type&); + + +/******************************************************************************* + * Heap Construction and Maintaining + ******************************************************************************/ + + + /** + * Builds the min-heap. + */ +private: + void build_heap( + DirectAccessIterator values_begin, + DirectAccessIterator values_end + ) { + std::cout << "building heap ..." << std::endl; + // Construct heap connections. + const int size = values_end - values_begin; + m_parent(values_begin) = 0; + m_left_child(values_begin) = 1 < size ? values_begin+1 : 0; + m_right_child(values_begin) = 2 < size ? values_begin+2 : 0; + for(int i = 1; i < size; ++i) { + m_parent(values_begin+i) = values_begin+(((i+1)/2) - 1); + m_left_child(values_begin+i) = + 2*(i+1)-1 < size ? values_begin+(2*(i+1)-1) : 0; + m_right_child(values_begin+i) = + 2*(i+1) < size ? values_begin+(2*(i+1)) : 0; + } + + m_root = size > 0 ? values_begin : 0; + m_last = size > 0 ? values_end-1 : 0; + + build_heap_rec(m_root); + + } + + /** + * Applies the min-heapify procedure at each node in postfix style. + */ +private: + void build_heap_rec(value_type node) { + if(node) { +// dump(node); + build_heap_rec(m_left_child(node)); + build_heap_rec(m_right_child(node)); + min_heapify(node); + } + } + + /** + * The min-heapify operation to restore the min heap property at a given + * node. + */ +private: + void min_heapify(value_type node) { + +// std::cout << "heapify: " << m_key(node) << std::endl; + + value_type seek = node; + value_type smallest = seek; + do { + value_type left_child = m_left_child(seek); + value_type right_child = m_right_child(seek); + smallest = seek; + + if( + left_child && + m_compare_keys(left_child, seek) + ) { + smallest = left_child; + } + if( + right_child && + m_compare_keys(right_child, smallest) + ) { + smallest = right_child; + } + if(smallest != seek) { + exchange(smallest, seek); + } + } while(smallest != seek); + + } + + /** + * Exchanges two nodes. + */ +private: + inline void exchange(value_type fst, value_type snd) { + if(!fst && !snd) { + return; + } + if(!fst || !snd) { + assert(false); + } + if(fst == snd) { + return; + } + + // Update root and last pointers. + if(fst == m_root) { + m_root = snd; + } else if(snd == m_root) { + m_root = fst; + } + if(fst == m_last) { + m_last = snd; + } else if(snd == m_last) { + m_last = fst; + } + +// std::cout << "fst pre" << std::endl; +// dump(fst); +// std::cout << "snd pre" << std::endl; +// dump(snd); + + // Canonize the situation when fst and snd are directly connected such + // that fst is always the higher node. + if( m_parent(fst) == snd ) { + value_type tmp = fst; + fst = snd; + snd = tmp; + } + + // Set the new parent pointers for the children. + value_type left_child = m_left_child(fst); + value_type right_child = m_right_child(fst); + if(left_child) { + m_parent(left_child) = snd; + } + if(right_child) { + m_parent(right_child) = snd; + } + left_child = m_left_child(snd); + right_child = m_right_child(snd); + if(left_child) { + m_parent(left_child) = fst; + } + if(right_child) { + m_parent(right_child) = fst; + } + + // Set the new children pointers. + const value_type fst_left_child = m_left_child(fst); + const value_type fst_right_child = m_right_child(fst); + m_left_child(fst) = m_left_child(snd); + m_right_child(fst) = m_right_child(snd); + m_left_child(snd) = fst_left_child; + m_right_child(snd) = fst_right_child; + + // Set the new children pointers of the parents. + if(m_parent(fst)) { + if( m_left_child(m_parent(fst)) == fst ) { + m_left_child(m_parent(fst)) = snd; + } else { + m_right_child(m_parent(fst)) = snd; + } + } + if(m_parent(snd)) { + if( m_left_child(m_parent(snd)) == snd ) { + m_left_child(m_parent(snd)) = fst; + } else { + m_right_child(m_parent(snd)) = fst; + } + } + + // Set the new parent pointers. + const value_type fst_parent = m_parent(fst); + m_parent(fst) = m_parent(snd); + m_parent(snd) = fst_parent; + +// std::cout << "fst post" << std::endl; +// dump(snd); +// std::cout << "snd post" << std::endl; +// dump(fst); + +// if( m_parent(fst) == snd || m_parent(snd) == fst) { +// // Canonize the situation to this whereby fst is the higher node. +// if( m_parent(fst) == snd ) { +// value_type tmp = fst; +// fst = snd; +// snd = tmp; +// } +// +// // Update root and last pointers. +// if(fst == m_root) { +// m_root = snd; +// } +// if(snd == m_last) { +// m_last = fst; +// } +// +// // Get a hold on every value we need. +// value_type fst_parent = m_parent(fst); +// value_type fst_left_child = m_left_child(fst); +// value_type fst_right_child = m_right_child(fst); +// value_type snd_left_child = m_left_child(snd); +// value_type snd_right_child = m_right_child(snd); +// +// // Set up fst's new pointers. +// m_left_child(fst) = snd_left_child; +// m_right_child(fst) = snd_right_child; +// m_parent(snd_left_child) = fst; +// m_parent(snd_right_child) = fst; +// m_parent(fst) = snd; +// +// // Set up snd's new pointers. +// m_parent(snd) = fst_parent; +// if(fst_parent) { +// if( m_left_child(fst_parent) == fst ) { +// m_left_child(fst_parent) = snd; +// } else { +// m_right_child(fst_parent) = snd; +// } +// } +// +// if(fst_left_child == snd) { +// m_parent(fst_right_child) = snd; +// m_right_child(snd) = fst_right_child; +// m_left_child(snd) = fst; +// } else { +// m_parent(fst_left_child) = snd; +// m_left_child(snd) = fst_left_child; +// m_right_child(snd) = fst; +// } +// } + } + + +/******************************************************************************* + * Heap Operations + ******************************************************************************/ + + /** + * Checks whether the heap is empty. + */ +public: + bool empty() { + return m_root == 0; + } + + /** + * Returns a reference to the top of the heap. + */ +public: + value_type& top() { + return m_root; + } + + /** + * Pops the top of the heap. + */ +public: + void pop() { + assert(top()); + assert(m_last); + +// dump(m_root); +// dump(m_last); + + value_type new_last = m_last; + if(m_root != m_last) { + +// std::cout << "gonna exchange" << std::endl; + exchange(m_root, m_last); + + assert(m_root == new_last); + + new_last = m_last; +// std::cout << "donna exchange" << std::endl; + +// dump(m_root); +// dump(m_last); + + // Determine the new "last" node of the tree. + // The algorithm also works when the last node at the deepest level + // is removed. The algorithm will then continue from the rightmost + // node at the level one lower. + while( + m_parent(new_last) && + m_left_child(m_parent(new_last)) == new_last + ) { + new_last = m_parent(new_last); +// std::cout << "moving up ..." << std::endl; + } +// std::cout << "stopped moving up ..." << std::endl; + if(m_parent(new_last)) { + new_last = m_left_child(m_parent(new_last)); +// std::cout << "moved left ..." << std::endl; + } + while(m_right_child(new_last)) { + new_last = m_right_child(new_last); +// std::cout << "moving right ..." << std::endl; + } +// std::cout << "stopped moving right ..." << std::endl; + } + + if( m_parent(m_last) ) { + if( m_left_child(m_parent(m_last)) == m_last ) { + m_left_child(m_parent(m_last)) = 0; + } else { + m_right_child(m_parent(m_last)) = 0; + } + } + m_parent(m_last) = 0; + m_left_child(m_last) = 0; + m_right_child(m_last) = 0; +// m_key(m_last) = -1; + + if(m_root != m_last) { + m_last = new_last; + min_heapify(m_root); + } else { + m_root = m_last = 0; + } + } + + /** + * Updates the key of a given node. + */ +public: + void update_key(value_type node, key_type new_key) { + m_key(node) = new_key; + + value_type seek = node; + while( + m_parent(seek) && + m_compare_keys(seek, m_parent(seek)) + ) { + exchange(seek, m_parent(seek)); + } + } + + /** + * Inserts a new value into the binary heap with the given key. + */ +public: + void insert(value_type node, key_type key) { + + // Special case handling an empty heap. + if(m_last == m_root && m_last == 0) { + m_last = m_root = node; + m_parent(node) = 0; + m_left_child(node) = 0; + m_right_child(node) = 0; + m_key(node) = key; + return; + } + + // Search the new "last" position to insert the new node at. + value_type new_last = m_last; + + // While the current node is right w.r.t. its parent, move up the tree. + while( + m_parent(new_last) && + m_right_child(m_parent(new_last)) == new_last + ) { + new_last = m_parent(new_last); + } + // If there is a right sibling, go to it and descent to the left. + if(m_parent(new_last) && m_right_child(m_parent(new_last))) { + new_last = m_right_child(m_parent(new_last)); + while(m_left_child(new_last)) { + new_last = m_left_child(new_last); + } + } + // If there is a parent at this point, the right sibling does not exist, + // and the given node should be placed there. + if(m_parent(new_last)) { + // Add the node to the tree. + if(m_right_child(m_parent(new_last)) == 0) { + new_last = m_parent(new_last); + m_right_child(new_last) = node; + } else { + m_left_child(new_last) = node; + } + } else { + // We came from the very last node at the current level and hence + // must begin a new level. Descent to the left. + while( m_left_child(new_last) ) { + new_last = m_left_child(new_last); + } + + // Add the node to the tree. + m_left_child(new_last) = node; + } + + m_parent(node) = new_last; + m_left_child(node) = 0; + m_right_child(node) = 0; + m_key(node) = key; + m_last = node; + + // Update the key and force the heap to rebalance itself. + update_key(node, key); + } + + /** + * Removes the node. The operation can safely be applied to an element no + * longer in the heap. + */ +public: + void remove(value_type node) { + if( m_parent(node) == 0 && m_root != node) { + return; + } + + // Move the node up the tree. + value_type seek = node; + while(m_parent(seek)) { + exchange(seek, m_parent(seek)); + } + // Remove it. + pop(); + } + + +public: + void dump(value_type node) { + std::cout << "seq: " << node->get_sequence_number() << std::endl; + std::cout << "key: " << m_key(node) << std::endl; + std::cout << "par: " << (m_parent(node) ? (m_parent(node))->get_sequence_number() : -1) << std::endl; + std::cout << "lef: " << (m_left_child(node) ? (m_left_child(node))->get_sequence_number() : -1) << std::endl; + std::cout << "rig: " << (m_right_child(node) ? (m_right_child(node))->get_sequence_number() : -1) << std::endl; + + } + +/******************************************************************************* + * Data Members + ******************************************************************************/ + + +public: + /** + * The root of the binary heap. + */ + ValueType m_root; + + /** + * The "last" node of the binary heap. The last node is the node that can + * safely be removed such that the resulting tree is still a complete binary + * tree, with the additional constraint that the nodes in the last level are + * all in the "left" part of the tree. + */ + ValueType m_last; + + /** + * A functor to compare keys. + */ + KeyComparator m_compare_keys; + + /** + * A functor to obtain the key. + */ + GetKey m_key; + + /** + * A functor to obtain the parent. + */ + GetParent m_parent; + + /** + * A functor to obtain the left child. + */ + GetLeft m_left_child; + + /** + * A functor to obtain the right child. + */ + GetRight m_right_child; + +}; + +} + +#endif // MTL_BINARY_HEAP_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/comparators.hpp b/install/MTL/include/boost/numeric/itl/pc/comparators.hpp new file mode 100644 index 00000000..5d660c2b --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/comparators.hpp @@ -0,0 +1,64 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. +// +// Algorithm inspired by Nick Vannieuwenhoven, written by Cornelius Steinhardt + + + +/* + * + * Created on: Oct 14, 2010 + * Author: heazk + */ + + +#ifndef MTL_COMPARATORS_INCLUDE +#define MTL_COMPARATORS_INCLUDE + +#define POINTER long + +namespace compare { + +/** + * Compares two given pointers based on the address to which they point. + */ +template<class Type> +struct address_compare { + bool operator()(const Type *const a, const Type *const b) const { + return reinterpret_cast<POINTER>(a) < reinterpret_cast<POINTER>(b); + } +}; + +/** + * Compares two given pointers based on the address to which they point. + */ +template<class Type> +struct address_compare_equal { + bool operator()(const Type *const a, const Type *const b) const { + return reinterpret_cast<POINTER>(a) == reinterpret_cast<POINTER>(b); + } +}; + +/** + * Hashes a given pointer based on its address. + */ +template<class Type> +struct address_hasher { + POINTER operator()(const Type *const a) const { + return reinterpret_cast<POINTER>(a); + } +}; + +} // end namespace compare + + +#endif // MTL_COMPARATORS_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/concat.hpp b/install/MTL/include/boost/numeric/itl/pc/concat.hpp new file mode 100644 index 00000000..6fd880b4 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/concat.hpp @@ -0,0 +1,117 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef ITL_PC_CONCAT_INCLUDE +#define ITL_PC_CONCAT_INCLUDE + +#include <boost/mpl/if.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/itl/pc/solver.hpp> + +namespace itl { namespace pc { + +/// Class for concatenating \tparam PC1 and \tparam PC2 +template <typename PC1, typename PC2, typename Matrix, bool Store1= true, bool Store2= true> +class concat +{ + typedef typename boost::mpl::if_c<Store1, PC1, const PC1&>::type pc1_type; + typedef typename boost::mpl::if_c<Store2, PC2, const PC2&>::type pc2_type; + + public: + /// Construct both preconditioners from matrix \p A + explicit concat(const Matrix& A) : A(A), pc1(A), pc2(A) + { + BOOST_STATIC_ASSERT((Store1 && Store2)); + } + + /// Both preconditioners are already constructed and passed as arguments + /** If pc1 or pc2 is only constructed temporarily in the constructor call, + the according Store argument must be true; otherwise the preconditioner + will be a stale reference. + Conversely, if the preconditioner is already build outside the constructor call, + the according Store argument should be false for not storing the preconditioner twice. **/ + concat(const Matrix& A, const PC1& pc1, const PC2& pc2) : A(A), pc1(pc1), pc2(pc2) {} + + private: + template <typename VectorOut> + VectorOut& create_r(const VectorOut& y) const + { + static VectorOut r(resource(y)); + return r; + } + + template <typename VectorOut> + VectorOut& create_d(const VectorOut& y) const + { + static VectorOut d(resource(y)); + return d; + } + + public: + /// Concatenated preconditioning: pc2 is applied regularly and pc1 afterwards by defect correction + template <typename VectorIn, typename VectorOut> + void solve(const VectorIn& x, VectorOut& y) const + { + mtl::vampir_trace<5058> tracer; + y.checked_change_resource(x); + pc2.solve(x, y); + + VectorOut &r= create_r(y), &d= create_d(y); + r= x; + r-= A * y; + + pc1.solve(r, d); + y+= d; + } + + + /// Concatenated preconditioning: adjoint of pc1 is applied regularly and pc2's adjoint afterwards by defect correction + template <typename VectorIn, typename VectorOut> + void adjoint_solve(const VectorIn& x, VectorOut& y) const + { + mtl::vampir_trace<5059> tracer; + y.checked_change_resource(x); + pc1.adjoint_solve(x, y); + + VectorOut &r= create_r(y), &d= create_d(y); + r= x; + r-= adjoint(A) * y; + + pc2.adjoint_solve(r, d); + y+= d; + } + + private: + const Matrix& A; + pc1_type pc1; + pc2_type pc2; +}; + +template <typename PC1, typename PC2, typename Matrix, bool Store1, bool Store2, typename Vector> +solver<concat<PC1, PC2, Matrix, Store1, Store2>, Vector, false> +inline solve(const concat<PC1, PC2, Matrix, Store1, Store2>& P, const Vector& x) +{ + return solver<concat<PC1, PC2, Matrix, Store1, Store2>, Vector, false>(P, x); +} + +template <typename PC1, typename PC2, typename Matrix, bool Store1, bool Store2, typename Vector> +solver<concat<PC1, PC2, Matrix, Store1, Store2>, Vector, true> +inline adjoint_solve(const concat<PC1, PC2, Matrix, Store1, Store2>& P, const Vector& x) +{ + return solver<concat<PC1, PC2, Matrix, Store1, Store2>, Vector, true>(P, x); +} + + +}} // namespace itl::pc + +#endif // ITL_PC_CONCAT_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/diagonal.hpp b/install/MTL/include/boost/numeric/itl/pc/diagonal.hpp new file mode 100644 index 00000000..ce3b4ab1 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/diagonal.hpp @@ -0,0 +1,108 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_PC_DIAGONAL_INCLUDE +#define ITL_PC_DIAGONAL_INCLUDE + +#include <boost/numeric/linear_algebra/inverse.hpp> + +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/itl/pc/solver.hpp> + +namespace itl { namespace pc { + +/// Diagonal Preconditioner +template <typename Matrix, typename Value= typename mtl::Collection<Matrix>::value_type> +class diagonal +{ + public: + typedef Value value_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + typedef diagonal self; + + /// Constructor takes matrix reference + explicit diagonal(const Matrix& A) : inv_diag(num_rows(A)) + { + mtl::vampir_trace<5050> tracer; + MTL_THROW_IF(num_rows(A) != num_cols(A), mtl::matrix_not_square()); + using math::reciprocal; + + for (size_type i= 0; i < num_rows(A); ++i) + inv_diag[i]= reciprocal(A[i][i]); + } + + /// Member function solve, better use free function solve + template <typename Vector> + Vector solve(const Vector& x) const + { + Vector y(resource(x)); + solve(x, y); + return y; + } + + template <typename VectorIn, typename VectorOut> + void solve(const VectorIn& x, VectorOut& y) const + { + mtl::vampir_trace<5051> tracer; + y.checked_change_resource(x); + MTL_THROW_IF(size(x) != size(inv_diag), mtl::incompatible_size()); + for (size_type i= 0; i < size(inv_diag); ++i) + y[i]= inv_diag[i] * x[i]; + } + + /// Member function for solving adjoint problem, better use free function adjoint_solve + template <typename Vector> + Vector adjoint_solve(const Vector& x) const + { + Vector y(resource(x)); + adjoint_solve(x, y); + return y; + } + + template <typename VectorIn, typename VectorOut> + void adjoint_solve(const VectorIn& x, VectorOut& y) const + { + using mtl::conj; + y.checked_change_resource(x); + MTL_THROW_IF(size(x) != size(inv_diag), mtl::incompatible_size()); + for (size_type i= 0; i < size(inv_diag); ++i) + y[i]= conj(inv_diag[i]) * x[i]; + } + + protected: + mtl::dense_vector<value_type> inv_diag; +}; + +/// Solve approximately a sparse system in terms of inverse diagonal +template <typename Matrix, typename Vector> +solver<diagonal<Matrix>, Vector, false> +inline solve(const diagonal<Matrix>& P, const Vector& x) +{ + return solver<diagonal<Matrix>, Vector, false>(P, x); +} + +/// Solve approximately the adjoint of a sparse system in terms of inverse diagonal +template <typename Matrix, typename Vector> +solver<diagonal<Matrix>, Vector, true> +inline adjoint_solve(const diagonal<Matrix>& P, const Vector& x) +{ + return solver<diagonal<Matrix>, Vector, true>(P, x); +} + + +}} // namespace itl::pc + +#endif // ITL_PC_DIAGONAL_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/ic_0.hpp b/install/MTL/include/boost/numeric/itl/pc/ic_0.hpp new file mode 100644 index 00000000..3f47ce82 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/ic_0.hpp @@ -0,0 +1,278 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_PC_IC_0_INCLUDE +#define ITL_PC_IC_0_INCLUDE + +#include <boost/mpl/bool.hpp> + +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/linear_algebra/inverse.hpp> + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/operation/lower_trisolve.hpp> +#include <boost/numeric/mtl/operation/upper_trisolve.hpp> +#include <boost/numeric/mtl/matrix/upper.hpp> +#include <boost/numeric/mtl/matrix/strict_lower.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/matrix/transposed_view.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/itl/pc/solver.hpp> + + +namespace itl { namespace pc { + +template <typename Matrix, typename Value= typename mtl::Collection<Matrix>::value_type> +class ic_0 +{ + public: + typedef Value value_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + typedef ic_0 self; + + typedef mtl::mat::parameters<mtl::row_major, mtl::index::c_index, mtl::non_fixed::dimensions, false, size_type> para; + typedef mtl::mat::compressed2D<value_type, para> U_type; +#ifndef ITL_IC_0_ONE_MATRIX + typedef U_type L_type; +#else + typedef typename mtl::mat::transposed_view<U_type> L_type; +#endif + typedef mtl::mat::detail::lower_trisolve_t<L_type, mtl::tag::inverse_diagonal, true> lower_solver_t; + typedef mtl::mat::detail::upper_trisolve_t<U_type, mtl::tag::inverse_diagonal, true> upper_solver_t; + + ic_0(const Matrix& A) : f(A, U), L(trans(U)), lower_solver(L), upper_solver(U) {} + + + // solve x = U^* U y --> y= U^{-1} U^{-*} x + template <typename Vector> + Vector solve(const Vector& x) const + { + mtl::vampir_trace<5036> tracer; + return inverse_upper_trisolve(U, inverse_lower_trisolve(adjoint(U), x)); + } + + // solve x = U^* y --> y0= U^{-*} x + template <typename VectorIn, typename VectorOut> + const VectorOut& solve_lower(const VectorIn& x, VectorOut&) const + { + static VectorOut y0; + y0.change_resource(resource(x)); + lower_solver(x, y0); + return y0; + } + + // solve x = U^* U y --> y= U^{-1} U^{-*} x + template <typename VectorIn, typename VectorOut> + void solve(const VectorIn& x, VectorOut& y) const + { + mtl::vampir_trace<5037> tracer; + const VectorOut& y0= solve_lower(x, y); + + y.checked_change_resource(x); + upper_solver(y0, y); + } + + // solve x = (LU)^* y --> y= L^{-*} U^{-*} x + template <typename Vector> + Vector adjoint_solve(const Vector& x) const + { + mtl::vampir_trace<5044> tracer; + return solve(x); + } + + // solve x = (LU)^* y --> y= L^{-*} U^{-*} x + template <typename VectorIn, typename VectorOut> + void adjoint_solve(const VectorIn& x, VectorOut& y) const + { + mtl::vampir_trace<5044> tracer; + solve(x, y); + } + + + L_type get_L() { return L_type(L); } + U_type get_U() { return U; } + + protected: + template <typename VectorOut, typename Solver> friend struct ic_0_evaluator; + + // Dummy type to perform factorization in initializer list not in + struct factorizer + { + factorizer(const Matrix &A, U_type& U) + { factorize(A, U, mtl::traits::is_sparse<Matrix>(), boost::is_same<Value, typename mtl::Collection<Matrix>::value_type>()); } + + template <typename T> + void factorize(const Matrix&, U_type&, boost::mpl::false_, T) + { MTL_THROW_IF(true, mtl::logic_error("IC(0) is not suited for dense matrices")); } + + // When we change the value_type then the factorization is still performed with that of A + template <typename UF> + void factorize(const Matrix& A, UF& U, boost::mpl::true_, boost::mpl::false_) + { + typedef mtl::mat::compressed2D<typename mtl::Collection<Matrix>::value_type, para> tmp_type; + tmp_type U_tmp; + factorize(A, U_tmp, boost::mpl::true_(), boost::mpl::true_()); + U= U_tmp; + } + + // Factorization adapted from Saad + // Undefined (runtime) behavior if matrix is not symmetric + // UF is type for the factorization + template <typename UF> + void factorize(const Matrix& A, UF& U, boost::mpl::true_, boost::mpl::true_) + { + using namespace mtl; using namespace mtl::tag; using mtl::traits::range_generator; + using math::reciprocal; using mtl::mat::upper; + mtl::vampir_trace<5035> tracer; + + // For the factorization we take still the value_type of A and later we copy it maybe to another value_type + typedef typename mtl::Collection<Matrix>::value_type value_type; + typedef typename range_generator<row, UF>::type cur_type; + typedef typename range_generator<nz, cur_type>::type icur_type; + + MTL_THROW_IF(num_rows(A) != num_cols(A), mtl::matrix_not_square()); + U= upper(A); + + typename mtl::traits::col<UF>::type col(U); + typename mtl::traits::value<UF>::type value(U); + + cur_type kc= begin<row>(U), kend= end<row>(U); + for (size_type k= 0; kc != kend; ++kc, ++k) { + + icur_type ic= begin<nz>(kc), iend= end<nz>(kc); + MTL_DEBUG_THROW_IF(col(*ic) != k, mtl::missing_diagonal()); + + // U[k][k]= 1.0 / sqrt(U[k][k]); + value_type inv_dia= reciprocal(sqrt(value(*ic))); + value(*ic, inv_dia); + // icur_type jbegin= + ++ic; + for (; ic != iend; ++ic) { + // U[k][i] *= U[k][k] + value_type d= value(*ic) * inv_dia; + value(*ic, d); + size_type i= col(*ic); + + // find non-zeros U[j][i] below U[k][i] for j in (k, i] + // 1. Go to ith row in U (== ith column in U) + cur_type irow(i, U); // = begin<row>(U); irow+= i; + // 2. Find nonzeros with col() in (k, i] + icur_type jc= begin<nz>(irow), jend= end<nz>(irow); + while (col(*jc) <= k) ++jc; + while (col(*--jend) > i) ; + ++jend; + + for (; jc != jend; ++jc) { + size_type j= col(*jc); + U.lvalue(j, i)-= d * U[k][j]; + } + // std::cout << "U after eliminating U[" << i << "][" << k << "] =\n" << U; + } + } + } + }; + + U_type U; + factorizer f; + L_type L; + lower_solver_t lower_solver; + upper_solver_t upper_solver; +}; + +#if 0 +template <typename Matrix, typename Value, typename Vector> +struct ic_0_solver + : mtl::assigner<ic_0_solver<Matrix, Value, Vector> > +{ + typedef ic_0<Matrix, Value> pc_type; + + ic_0_solver(const ic_0<Matrix, Value>& P, const Vector& x) : P(P), x(x) {} + + template <typename VectorOut> + void assign_to(VectorOut& y) const + { P.solve(x, y); } + + const ic_0<Matrix, Value>& P; + const Vector& x; +}; +#endif + +template <typename VectorOut, typename Solver> +struct ic_0_evaluator +{ + typedef typename Solver::pc_type pc_type; + typedef typename pc_type::size_type size_type; + typedef typename mtl::Collection<VectorOut>::value_type out_value_type; + + + ic_0_evaluator(VectorOut& y, const Solver& s) + : y(y), s(s), U(s.P.U), y0(s.P.solve_lower(s.x, y)) { MTL_DEBUG_ARG(lr= 99999999); } + + + void operator()(size_type i) { at<0>(i); } + void operator[](size_type i) { at<0>(i); } + + template <unsigned Offset> + void at(size_type r) + { +#ifndef NDEBUG + MTL_THROW_IF(r+Offset >= lr, mtl::logic_error("Traversal must be backward")); lr= r+Offset; +#endif + size_type j0= U.ref_major()[r+Offset]; + const size_type cj1= U.ref_major()[r+Offset+1]; + MTL_DEBUG_THROW_IF(j0 == cj1 || U.ref_minor()[j0] != r+Offset, mtl::missing_diagonal()); + out_value_type rr= y0[r+Offset], dia= U.data[j0++]; + for (; j0 != cj1; ++j0) { + MTL_DEBUG_THROW_IF(U.ref_minor()[j0] <= r+Offset, mtl::logic_error("Matrix entries must be sorted for this.")); + rr-= U.data[j0] * y[U.ref_minor()[j0]]; + } + y[r+Offset]= rr * dia; + } + + VectorOut& y; + const Solver& s; + const typename pc_type::U_type& U; + const VectorOut& y0; + MTL_DEBUG_ARG(size_type lr;) +}; + +template <typename VectorOut, typename Solver> +inline std::size_t size(const ic_0_evaluator<VectorOut, Solver>& eval) +{ return size(eval.y); } + +template <typename Matrix, typename Value, typename Vector> +solver<ic_0<Matrix, Value>, Vector, false> +inline solve(const ic_0<Matrix, Value>& P, const Vector& x) +{ + return solver<ic_0<Matrix, Value>, Vector, false>(P, x); +} + +template <typename Matrix, typename Value, typename Vector> +solver<ic_0<Matrix, Value>, Vector, true> +inline adjoint_solve(const ic_0<Matrix, Value>& P, const Vector& x) +{ + return solver<ic_0<Matrix, Value>, Vector, true>(P, x); +} + + +}} // namespace itl::pc + +namespace mtl { namespace vec { + using itl::pc::size; +}} // namespace mtl::vector + +#endif // ITL_PC_IC_0_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/identity.hpp b/install/MTL/include/boost/numeric/itl/pc/identity.hpp new file mode 100644 index 00000000..22d46f02 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/identity.hpp @@ -0,0 +1,76 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_PC_IDENTITY_INCLUDE +#define ITL_PC_IDENTITY_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/itl/pc/solver.hpp> + +namespace itl { namespace pc { + +/// Identity preconditioner, i.e. no preconditioning and vector is just copied +/** Second template is just for a uniform interface with other preconditioners. **/ +template <typename Matrix, typename Value= double> +class identity +{ + public: + typedef typename mtl::Collection<Matrix>::value_type value_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + typedef identity self; + + identity(const Matrix&) {} + + template <typename Vector> + Vector solve(const Vector& x) const + { + mtl::vampir_trace<5032> tracer; + return x; + } + + template <typename VectorIn, typename VectorOut> + void solve(const VectorIn& b, VectorOut& x) const + { + mtl::vampir_trace<5032> tracer; + x= b; + } + + template <typename Vector> + Vector adjoint_solve(const Vector& x) const + { + mtl::vampir_trace<5034> tracer; + return x; + } + + template <typename VectorIn, typename VectorOut> + void adjoint_solve(const VectorIn& b, VectorOut& x) const + { + mtl::vampir_trace<5034> tracer; + x= b; + } +}; + +template <typename Matrix, typename Vector> +solver<identity<Matrix>, Vector, false> +inline solve(const identity<Matrix>& P, const Vector& x) +{ return solver<identity<Matrix>, Vector, false>(P, x); } + +template <typename Matrix, typename Vector> +solver<identity<Matrix>, Vector, true> +inline adjoint_solve(const identity<Matrix>& P, const Vector& x) +{ return solver<identity<Matrix>, Vector, true>(P, x); } + + +}} // namespace itl::pc + +#endif // ITL_PC_IDENTITY_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/ilu.hpp b/install/MTL/include/boost/numeric/itl/pc/ilu.hpp new file mode 100644 index 00000000..aaee8e48 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/ilu.hpp @@ -0,0 +1,212 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_PC_ILU_INCLUDE +#define ITL_PC_ILU_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/operation/adjoint.hpp> +#include <boost/numeric/mtl/operation/lower_trisolve.hpp> +#include <boost/numeric/mtl/operation/upper_trisolve.hpp> +#include <boost/numeric/mtl/operation/lu.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/mtl/matrix/dense2D.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/itl/pc/solver.hpp> + +namespace itl { namespace pc { + +/// Incomplete LU factorization of a \p Matrix into matrices of type \p Value using a \p Factorizer (e.g. ILU(0) or ILUT) +template <typename Matrix, typename Factorizer, typename Value= typename mtl::Collection<Matrix>::value_type> +class ilu +{ + public: + typedef Value value_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + typedef ilu self; + typedef Factorizer factorizer_type; + + typedef mtl::mat::parameters<mtl::row_major, mtl::index::c_index, mtl::non_fixed::dimensions, false, size_type> para; + typedef mtl::mat::compressed2D<value_type, para> L_type; + typedef mtl::mat::compressed2D<value_type, para> U_type; + typedef typename mtl::mat::traits::adjoint<L_type>::type adjoint_L_type; + typedef typename mtl::mat::traits::adjoint<U_type>::type adjoint_U_type; + + typedef mtl::mat::detail::lower_trisolve_t<L_type, mtl::tag::unit_diagonal, true> lower_solver_t; + typedef mtl::mat::detail::upper_trisolve_t<U_type, mtl::tag::inverse_diagonal, true> upper_solver_t; + + typedef mtl::mat::detail::lower_trisolve_t<adjoint_U_type, mtl::tag::inverse_diagonal, true> adjoint_lower_solver_t; + typedef mtl::mat::detail::upper_trisolve_t<adjoint_L_type, mtl::tag::unit_diagonal, true> adjoint_upper_solver_t; + + /// Factorization adapted from Saad + explicit ilu(const Matrix& A) + : f(A, L, U), lower_solver(L), upper_solver(U), adjoint_L(adjoint(L)), adjoint_U(adjoint(U)), + adjoint_lower_solver(adjoint_U), adjoint_upper_solver(adjoint_L) {} + + template <typename FactPara> + ilu(const Matrix& A, const FactPara& p) + : f(A, p, L, U), lower_solver(L), upper_solver(U), adjoint_L(adjoint(L)), adjoint_U(adjoint(U)), + adjoint_lower_solver(adjoint_U), adjoint_upper_solver(adjoint_L) {} + + /// Solve LU y = x --> y= U^{-1} L^{-1} x + template <typename Vector> + Vector solve(const Vector& x) const + { + Vector y; + solve(x, y); + return y; + } + + // solve x = L y --> y0= L^{-1} x + template <typename VectorIn, typename VectorOut> + const VectorOut& solve_lower(const VectorIn& x, VectorOut&) const + { + static VectorOut y0; + y0.change_resource(resource(x)); + lower_solver(x, y0); + return y0; + } + + // Solve LU y = x --> y= U^{-1} L^{-1} x + template <typename VectorIn, typename VectorOut> + void solve(const VectorIn& x, VectorOut& y) const + { + mtl::vampir_trace<5039> tracer; + const VectorOut& y0= solve_lower(x, y); + + y.checked_change_resource(x); + upper_solver(y0, y); + } + + + /// Solve (LU)^H y = x --> y= L^{-H} U^{-H} x + template <typename Vector> + Vector adjoint_solve(const Vector& x) const + { + mtl::vampir_trace<5040> tracer; + Vector y(resource(x)); + adjoint_solve(x, y); + return y; + } + + /// Solve (LU)^H y = x --> y= L^{-H} U^{-H} x + template <typename VectorIn, typename VectorOut> + void adjoint_solve(const VectorIn& x, VectorOut& y) const + { + mtl::vampir_trace<5040> tracer; + y.checked_change_resource(x); + // y= unit_upper_trisolve(adjoint(L), inverse_lower_trisolve(adjoint(U), x)); + static VectorOut y0; + y0.change_resource(resource(x)); + adjoint_lower_solver(x, y0); + adjoint_upper_solver(y0, y); + } + + + L_type get_L() { return L; } + U_type get_U() { return U; } + + public: + L_type L; + U_type U; + private: + Factorizer f; + lower_solver_t lower_solver; + upper_solver_t upper_solver; + adjoint_L_type adjoint_L; + adjoint_U_type adjoint_U; + adjoint_lower_solver_t adjoint_lower_solver; + adjoint_upper_solver_t adjoint_upper_solver; + +}; + +template <typename Value, typename Factorizer, typename V2> +class ilu<mtl::mat::dense2D<Value, mtl::mat::parameters<> >, Factorizer, V2> // last 2 arguments are dummies +{ + public: + typedef mtl::mat::dense2D<Value, mtl::mat::parameters<> > Matrix; + typedef typename mtl::Collection<Matrix>::value_type value_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + typedef ilu self; + typedef Matrix LU_type; + + ilu(const Matrix& A) : LU(A) { lu(LU, P); std::cout << "LU is\n" << LU << "P is " << P << "\n"; } + + // Solve P^{-1}LU x = b --> x= U^{-1} L^{-1} P b + template <typename Vector> + Vector solve(const Vector& b) const { return lu_apply(LU, P, b); } + + // Solve P^{-1}LU x = b --> x= U^{-1} L^{-1} P b + template <typename VectorIn, typename VectorOut> + void solve(const VectorIn& b, VectorOut& x) const { x= lu_apply(LU, P, b); } + + // Solve (P^{-1}LU)^H x = b --> x= P^{-1}L^{-H} U^{-H} b // P^{-1}^{-1}^H = P^{-1}) + template <typename Vector> + Vector adjoint_solve(const Vector& b) const { return lu_adjoint_apply(LU, P, b); } + + // Solve (P^{-1}LU)^H x = b --> x= P^{-1}L^{-H} U^{-H} b // P^{-1}^{-1}^H = P^{-1}) + template <typename VectorIn, typename VectorOut> + void adjoint_solve(const VectorIn& b, VectorOut& x) const { x= lu_adjoint_apply(LU, P, b); } + + private: + LU_type LU; + mtl::vec::dense_vector<size_type, mtl::vec::parameters<> > P; +}; + +#if 0 +template <typename Matrix, typename Factorizer, typename Value, typename Vector> +struct ilu_solver + : mtl::assigner<ilu_solver<Matrix, Factorizer, Value, Vector> > +{ + typedef ilu<Matrix, Factorizer, Value> pc_type; + + ilu_solver(const pc_type& P, const Vector& x) : P(P), x(x) {} + + template <typename VectorOut> + void assign_to(VectorOut& y) const + { P.solve(x, y); } + + const pc_type& P; + const Vector& x; +}; +#endif + + + +/// Solve LU x = b --> x= U^{-1} L^{-1} b +template <typename Matrix, typename Factorizer, typename Value, typename Vector> +// ilu_solver<Matrix, Factorizer, Value, Vector> +solver<ilu<Matrix, Factorizer, Value>, Vector, false> +inline solve(const ilu<Matrix, Factorizer, Value>& P, const Vector& x) +{ + return solver<ilu<Matrix, Factorizer, Value>, Vector, false>(P, x); +} + + +/// Solve (LU)^H x = b --> x= L^{-H} U^{-H} b +template <typename Matrix, typename Factorizer, typename Value, typename Vector> +// Vector +solver<ilu<Matrix, Factorizer, Value>, Vector, true> +inline adjoint_solve(const ilu<Matrix, Factorizer, Value>& P, const Vector& b) +{ + return solver<ilu<Matrix, Factorizer, Value>, Vector, true>(P, b); +} + +// ic_0_evaluator not needed IC(0) and ILU(0) do the same at the upper triangle ;-) + +}} // namespace itl::pc + + +#endif // ITL_PC_ILU_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/ilu_0.hpp b/install/MTL/include/boost/numeric/itl/pc/ilu_0.hpp new file mode 100644 index 00000000..2d4bcfe8 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/ilu_0.hpp @@ -0,0 +1,99 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_PC_ILU_0_INCLUDE +#define ITL_PC_ILU_0_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/invert_diagonal.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/matrix/strict_lower.hpp> +#include <boost/numeric/mtl/matrix/upper.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +#include <boost/numeric/itl/pc/ilu.hpp> + +namespace itl { namespace pc { + +// Dummy type to perform factorization in initializer list not in +struct ilu_0_factorizer +{ + template <typename Matrix, typename L_type, typename U_type> + ilu_0_factorizer(const Matrix &A, L_type& L, U_type& U) + { factorize(A, L, U, mtl::traits::is_sparse<Matrix>()); } + + template <typename Matrix, typename L_type, typename U_type> + void factorize(const Matrix&, L_type&, U_type&, boost::mpl::false_) + { MTL_THROW_IF(true, mtl::logic_error("ILU is not intended for dense matrices")); } + + template <typename Matrix, typename L_type, typename U_type> + void factorize(const Matrix& A, L_type& L, U_type& U, boost::mpl::true_) + { + using namespace mtl; using namespace mtl::tag; using mtl::traits::range_generator; + using math::reciprocal; + MTL_THROW_IF(num_rows(A) != num_cols(A), mtl::matrix_not_square()); + mtl::vampir_trace<5038> tracer; + + typedef typename mtl::Collection<Matrix>::value_type value_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + typedef mtl::mat::parameters<mtl::row_major, mtl::index::c_index, mtl::non_fixed::dimensions, false, size_type> para; + typedef mtl::mat::compressed2D<value_type, para> LU_type; + LU_type LU(A); + + typedef typename range_generator<row, LU_type>::type cur_type; + typedef typename range_generator<nz, cur_type>::type icur_type; + typename mtl::traits::col<LU_type>::type col(LU); + typename mtl::traits::value<LU_type>::type value(LU); + mtl::vec::dense_vector<value_type, mtl::vec::parameters<> > inv_dia(num_rows(A)); + cur_type ic= begin<row>(LU), iend= end<row>(LU); + for (size_type i= 0; ic != iend; ++ic, ++i) { + + for (icur_type kc= begin<nz>(ic), kend= end<nz>(ic); kc != kend; ++kc) { + size_type k= col(*kc); + if (k == i) break; + + value_type aik= value(*kc) * inv_dia[k]; + value(*kc, aik); + + for (icur_type jc= kc + 1; jc != kend; ++jc) + value(*jc, value(*jc) - aik * LU[k][col(*jc)]); + // std::cout << "LU after eliminating A[" << i << "][" << k << "] =\n" << LU; + } + inv_dia[i]= reciprocal(LU[i][i]); + } + invert_diagonal(LU); + L= strict_lower(LU); + U= upper(LU); + } +}; + +template <typename Matrix, typename Value= typename mtl::Collection<Matrix>::value_type> +class ilu_0 + : public ilu<Matrix, ilu_0_factorizer, Value> +{ + typedef ilu<Matrix, ilu_0_factorizer, Value> base; + public: + ilu_0(const Matrix& A) : base(A) {} +}; + +// ic_0_evaluator not needed IC(0) and ILU(0) do the same at the upper triangle ;-) + +}} // namespace itl::pc + + +#endif // ITL_PC_ILU_0_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/ilut.hpp b/install/MTL/include/boost/numeric/itl/pc/ilut.hpp new file mode 100644 index 00000000..85ee8c5f --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/ilut.hpp @@ -0,0 +1,137 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_PC_ILUT_INCLUDE +#define ITL_PC_ILUT_INCLUDE + +#include <boost/numeric/mtl/vector/sparse_vector.hpp> +#include <boost/numeric/mtl/operation/invert_diagonal.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace itl { namespace pc { + + +struct ilut_factorizer +{ + + template <typename Matrix, typename Para, typename L_type, typename U_type> + ilut_factorizer(const Matrix &A, const Para& p, L_type& L, U_type& U) + { factorize(A, p, L, U, mtl::traits::is_row_major<Matrix>()); } + + // column-major matrices are copied first + template <typename Matrix, typename Para, typename L_type, typename U_type, bool B> + void factorize(const Matrix &A, const Para& p, L_type& L, U_type& U, boost::mpl::bool_<B>) + { + typedef typename mtl::Collection<Matrix>::value_type value_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + typedef mtl::mat::parameters<mtl::row_major, mtl::index::c_index, mtl::non_fixed::dimensions, false, size_type> para; + typedef mtl::mat::compressed2D<value_type, para> LU_type; + LU_type LU(A); + factorize(LU, p, L, U, boost::mpl::true_()); + } + + // According Yousef Saad: ILUT, NLAA, Vol 1(4), 387-402 (1994) +#if 0 + template <typename Value, typename MPara, typename Para, typename L_type, typename U_type> + factorize(const mtl::mat::compressed2D<Value, MPara>& A, const Para& p, L_type& L, U_type& U, boost::mpl::true_) +#endif + + template <typename Matrix, typename Para, typename L_type, typename U_type> + void factorize(const Matrix& A, const Para& p, L_type& L, U_type& U, boost::mpl::true_) + + { + mtl::vampir_trace<5049> tracer; + using std::abs; using mtl::traits::range_generator; using mtl::begin; using mtl::end; + using namespace mtl::tag; + MTL_THROW_IF(num_rows(A) != num_cols(A), mtl::matrix_not_square()); + + typedef typename mtl::Collection<Matrix>::value_type value_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + typedef typename range_generator<row, Matrix>::type cur_type; + typedef typename range_generator<nz, cur_type>::type icur_type; + typename mtl::traits::col<Matrix>::type col(A); + typename mtl::traits::const_value<Matrix>::type value(A); + + size_type n= num_rows(A); + L.change_dim(n, n); + U.change_dim(n, n); + { + mtl::mat::inserter<L_type> L_ins(L, p.first); + mtl::mat::inserter<U_type> U_ins(U, p.first + 1); // plus one for diagonal + + mtl::sparse_vector<value_type> vec(n); // corr. row in paper + cur_type ic= begin<row>(A); // , iend= end<row>(A); + for (size_type i= 0; i < n; ++i, ++ic) { + + for (icur_type kc= begin<nz>(ic), kend= end<nz>(ic); kc != kend; ++kc) // row= A[i][*] + vec.insert(col(*kc), value(*kc)); + // std::cerr << "vec_" << i << " = " << vec << std::endl; + value_type tau_i= p.second * two_norm(vec); // threshold for i-th row + // loop over non-zeros in vec; changes in vec considered + for (size_type j= 0; j < vec.nnz() && vec.index(j) < i; j++) { + size_type k= vec.index(j); + value_type ukk= U_ins.value(k, k); + MTL_DEBUG_THROW_IF(ukk == value_type(0), mtl::missing_diagonal()); + value_type vec_k= vec.value(j)/= ukk; + // std::cout << "vec after updating from U[" << k << "][" << k << "] is " << vec << '\n'; + for (size_type j0= U_ins.ref_major()[k], j1= U_ins.ref_slot_ends()[k]; j0 < j1; j0++) { // U[k][k+1:n] + size_type k1= U_ins.ref_minor()[j0]; + if (k1 > k) + vec[k1]-= vec_k * U_ins.ref_elements()[j0]; + // std::cout << "vec after updating from U[" << k << "][" << k1 << "] is " << vec << '\n'; + } + // if (i > 1000 && i < 1010) std::cout << "vec before crop in row " << i << ", updating from row " << k << ": \n" << vec << "\n"; + vec.crop(tau_i); + // if (i > 1000 && i < 1010) std::cout << "vec after crop: \n" << vec << "\n"; + } + // std::cerr << "vec_" << i << " = " << vec << std::endl; + vec.sort_on_data(); + // std::cerr << "vec_" << i << " sorted on data = " << vec << std::endl; + + // std::cout << "vec at " << i << " is " << vec << '\n'; + // mtl::vampir_trace<9904> tracer2; + bool diag_found= false; + for (size_type cntu= 0, cntl= 0, j= 0; j < vec.nnz() && (cntu < p.first || cntl < p.first); j++) { + size_type k= vec.index(j); + value_type v= vec.value(j); + // if (abs(v) < tau_i) break; + if (i == k) { + U_ins[i][i] << v; diag_found= true; + } else if (i < k) { + if (cntu++ < p.first) + U_ins[i][k] << v; + } else // i > k + if (cntl++ < p.first) + L_ins[i][k] << v; + } + if (!diag_found) std::cerr << "Deleted diagonal!!!!\n"; + vec.make_empty(); + } + } // destroy inserters + invert_diagonal(U); + } +}; + +// Not usable yet !!!!! +template <typename Matrix, typename Value= typename mtl::Collection<Matrix>::value_type> +class ilut + : public ilu<Matrix, ilut_factorizer, Value> +{ + typedef ilu<Matrix, ilut_factorizer, Value> base; + public: + ilut(const Matrix& A, std::size_t p, typename mtl::Collection<Matrix>::value_type tau) + : base(A, std::make_pair(p, tau)) {} +}; + +}} // namespace itl::pc + +#endif // ITL_PC_ILUT_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/imf_algorithms.hpp b/install/MTL/include/boost/numeric/itl/pc/imf_algorithms.hpp new file mode 100644 index 00000000..893c9c49 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/imf_algorithms.hpp @@ -0,0 +1,821 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. +// +// Algorithm inspired by Nick Vannieuwenhoven, written by Cornelius Steinhardt + +/* + * Implementation of the IMF factorization and application routines. + */ + +#ifndef MTL_IMF_ALGORITHMS_INCLUDE +#define MTL_IMF_ALGORITHMS_INCLUDE + +#include <iostream> +#include <string.h> +#include <vector> +#include <map> +#include <set> +#include <complex> +#include <limits> + +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/mtl/matrix/coordinate2D.hpp> +#include <boost/numeric/mtl/operation/clone.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/utility/make_copy_or_reference.hpp> + +#include <boost/numeric/itl/pc/binary_heap.hpp> +#include <boost/numeric/itl/pc/sorting.hpp> + +#include "boost/unordered_map.hpp" +#include "boost/unordered_set.hpp" + + +namespace itl { namespace pc { +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// INTRUSIVE HEAP HELPER FUNCTORS +// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace heap { +/** + * An information extending structure for elements to support the reduction + * process. + */ +template<class Element, class Key> +struct HeapInformation { + Key m_key; + Element* m_parent; + Element* m_left_child; + Element* m_right_child; + + HeapInformation() : + m_key(0.0), m_parent(0), m_left_child(0), m_right_child(0) {} +}; + +/** + * A functor returning a reference to the degree of an element. + */ +template<class Element, class Key> +struct GetKey { + Key& operator()(Element* element) const { + return static_cast<HeapInformation<Element,Key>* >( + element->get_extra_pointer() + )->m_key; + } +}; + +/** + * A functor returning a reference to the parent of an element (in a heap). + */ +template<class Element, class Key> +struct GetParent { + Element*& operator()(Element* element) const { + return static_cast<HeapInformation<Element,Key>* >( + element->get_extra_pointer() + )->m_parent; + } +}; + +/** + * A functor returning a reference to the left child of an element (in a heap). + */ +template<class Element, class Key> +struct GetLeftChild { + Element*& operator()(Element* element) const { + return static_cast<HeapInformation<Element,Key>* >( + element->get_extra_pointer() + )->m_left_child; + } +}; + +/** + * A functor returning a reference to the right child of an element (in a heap). + */ +template<class Element, class Key> +struct GetRightChild { + Element*& operator()(Element* element) const { + return static_cast<HeapInformation<Element,Key>* >( + element->get_extra_pointer() + )->m_right_child; + } +}; + +/** + * Compares two elements based on their degrees. + */ +template<class Element, class Key> +struct DegreeCompare { + /** + * Compares two elements based on their degree. Ties are broken by the + * sequence numbers of the elements. + */ + inline bool operator()(Element* first, Element* second) const { + const int seq_fst = first->get_id(); + const int seq_snd = second->get_id(); + + const Key key_fst = static_cast<HeapInformation<Element,Key>* >( + first->get_extra_pointer() + )->m_key; + const Key key_snd = static_cast<HeapInformation<Element,Key>* >( + second->get_extra_pointer() + )->m_key; + + if (key_fst == key_snd) { + return seq_fst < seq_snd; + } + return key_fst < key_snd; + } +}; + +} // end namespace heap + + +enum Status { UNMARKED, DIAGONAL, MARKED_CURRENT, REMOVED, NON_DIAGONAL }; + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// DIAGONAL BLOCK SELECTION PRIORITY ESTIMATORS +// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +/** + * Estimates the priority based on the number of nodes the element is connected + * to for the purpose of the local Schur complement computation. A higher + * priority is given if the element is connected to fewer nodes. + */ +template< class Element, class NodeStatusVector, bool UseStatus = false > +struct MinConnectedNodesEstimation { + inline int operator()( + const Element& el, + const NodeStatusVector& status + ) const { + typedef typename Element::neighbor_collection_type neigh_type; + + // Determine set of all nodes. + std::vector<int> nodes; + const neigh_type& neighs = el.get_neighbors(); + for(int i = 0; i < el.get_nb_neighbors(); ++i) { + nodes.insert( + nodes.end(), + neighs[i]->get_indices().begin(), + neighs[i]->get_indices().end() + ); + } + +// radix_sort( &nodes[0], nodes.size() ); // TODO INCLUDE RADIX_SORT + std::sort( nodes.begin(), nodes.end() ); + + int degree = -el.nb_vars()+1; + for(unsigned int i = 1; i < nodes.size(); ++i) + if( nodes[i-1] != nodes[i] ) + if (!UseStatus || status[nodes[i]] == UNMARKED) + ++degree; + return degree; + } +}; + + + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// IMF Factorization +// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +template<class Type> +struct AddressHasher { + long operator()(const Type*& object) const { + return reinterpret_cast<long>( object ); + } +}; + +template<class Element, class StatusVector> +struct IsRemoved { + const StatusVector& m_status; + IsRemoved(const StatusVector& status) : m_status(status) { } + + bool operator()(const Element *const el) const { + return m_status[ el->get_id() ] == REMOVED; + } +}; + +/** + * Constructs the EBE-ML-ILU preconditioner from the given mesh. The mesh is + * altered in the process. + */ +template< typename ValType > +template< class Mesh > +void itl::pc::imf_preconditioner<ValType>::factor(const Mesh& mesh , const int maxlofi +) { + mtl::vampir_trace<5052> tracer; + typedef typename Mesh::element_type element_type; + typedef typename Mesh::element_iterator element_iterator; + typedef typename element_type::value_type value_type; + typedef typename element_type::neighbor_collection_type neigh_coll_type; + typedef typename element_type::neighbor_iterator neigh_iterator; + typedef typename element_type::neighbor_set_type neigh_set_type; + typedef typename element_type::neighbor_set_iterator_type neigh_set_iterator; + // typedef typename neigh_coll_type::const_iterator const_neigh_iterator; + typedef typename element_type::index_type index_type; + typedef typename element_type::matrix_type matrix_type; + + typedef typename mtl::mat::coordinate2D<value_type> coo_sparse_type_upper; + typedef typename mtl::mat::coordinate2D<value_type> coo_sparse_type_lower; + + + typedef std::map<int, int> cmap; + // typedef typename cmap::iterator cmap_iterator; + + typedef value_type key_type; + typedef utils::binary_heap< + element_iterator, + key_type, + heap::DegreeCompare<element_type, key_type>, + element_type*, + heap::GetKey<element_type, key_type>, + heap::GetParent<element_type, key_type>, + heap::GetLeftChild<element_type, key_type>, + heap::GetRightChild<element_type, key_type> + > my_heap; + + + // Constants. + const int nb_elements = mesh.get_total_elements(); + const int nb_vars = mesh.get_total_vars(); + const int UNPERMUTED = -1; + const value_type zero(0); + // A DS tracking the set of elements during the construction. + // Invariant: elements[i]->get_sequence_number() == i + // Invariant: elements[i] == 0 iff element[i] is removed + std::vector<element_type*> elements; + elements.reserve( nb_elements + (nb_elements >> 4) ); + element_iterator it = mesh.element_begin(); + for (int i = 0; i < nb_elements; ++i) { + elements.push_back( *&it ); + ++it; + } + + + // Data structures for the preconditioner. + std::vector<element_type*> block_diagonal; + std::vector<coo_sparse_type_upper*> upper_matrices; + std::vector<coo_sparse_type_lower*> lower_matrices; + std::vector<int> diagonal_offsets; + diagonal_offsets.push_back(0); + m_ordering = UNPERMUTED; + + //////////////////////////////////////////////////////////////////////////// + // Auxiliary data structures. + //////////////////////////////////////////////////////////////////////////// + + // Binary heap containing the dense elements that should still be + // considered for selection on the diagonal of the current level. + heap::DegreeCompare<element_type, key_type> key_compare; + heap::GetKey<element_type, key_type> get_key; + heap::GetParent<element_type, key_type> get_parent; + heap::GetLeftChild<element_type, key_type> get_left; + heap::GetRightChild<element_type, key_type> get_right; + my_heap unmarked_elements( + key_compare, + get_key, + get_parent, + get_left, + get_right + ); + std::vector< heap::HeapInformation<element_type, key_type>* > red_info( nb_elements ); + + // Another data structure for the elements that should be considered + // for the diagonal + std::vector<element_type*> unmarked_elements_srtd; + std::vector<int > unmarked_elements_degr; + unmarked_elements_srtd.reserve( nb_elements ); + unmarked_elements_degr.reserve( nb_elements ); + + // A DS to keep track of whether the element is on the diagonal, not + // on the diagonal or not yet marked. + std::vector<Status> el_status(nb_elements, UNMARKED); + + // A DS to keep track of the variables that have been forced into the + // reduced system. + std::vector<Status> in_reduced( mesh.get_total_vars(), UNMARKED ); + + //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + + // Degree estimators. + const MinConnectedNodesEstimation<element_type, std::vector<Status> > min_nodes_estimate = + MinConnectedNodesEstimation<element_type, std::vector<Status> >(); + + std::cout << mesh.get_total_vars() << " nodes remaining" << std::endl; + + int level = 1; + int perm_off = 0; + int perm_high = 0; + int block_diag_low = 0; + int max_sequence_number = nb_elements; + + do { + mtl::vampir_trace<9901> tb1; + + block_diag_low = block_diagonal.size(); + +/*************************************************************************** + * Phase 0: Determine priority of unmarked elements + **************************************************************************/ + + // Make sure the set of unmarked elements is empty again. + assert( unmarked_elements.empty() ); + unmarked_elements_degr.clear(); + unmarked_elements_srtd.clear(); + // Construct the set of available diagonal elements along with their + // degrees. + for( unsigned int i = 0; i < elements.size(); ++i ) { + // Skip the element if it no longer exists, or it is a diagonal + // element. + if( (el_status[i] == REMOVED) || (el_status[i] == DIAGONAL) ) { + continue; + } + + element_type& el = *(elements[i]); + // Reset the status. + el_status[i] = UNMARKED; + + int degree = min_nodes_estimate(el, in_reduced); + unmarked_elements_degr.push_back( degree ); + unmarked_elements_srtd.push_back( &el ); + } + +/*************************************************************************** + * Phase 1: Select the block diagonal elements + **************************************************************************/ +/********************************SKIP UPDATE***********************************/ + + // Sort the candidate diagonal elements by their degree in ascending + // order. + sort_along<int, element_type*>( + &*(unmarked_elements_degr.begin()), + &*(unmarked_elements_srtd.begin()), + unmarked_elements_degr.size() + ); + + // For each of the candidate diagonal elements ... + for(unsigned int i = 0; i < unmarked_elements_srtd.size(); ++i) { + // Select the minimum element. + element_type& el = *(unmarked_elements_srtd[i]); + // If the element is already marked, skip it. + if( el_status[el.get_id()] != UNMARKED ) { + continue; + } + + // If the element is unmarked, add it to the set of diagonal + // elements + block_diagonal.push_back(&el); + // Mark the element. + el_status[el.get_id()] = DIAGONAL; + + // Update permutation vector + for(int i = 0; i < el.nb_vars(); ++i) { + m_ordering( el.get_indices()(i) ) = perm_off; + ++perm_off; + assert(perm_off <= mesh.get_total_vars()); + } + + // Determine level-2 neighbors. + neigh_set_type lvl2_neighs = el.get_level_neighbors( 2 ); + + // Mark all level-2 neighbors. + for(neigh_set_iterator neigh_it = lvl2_neighs.begin(); neigh_it != lvl2_neighs.end(); ++neigh_it) { + element_type& neigh = **neigh_it; + assert( el_status[neigh.get_id()] != DIAGONAL ); + el_status[ neigh.get_id() ] = MARKED_CURRENT; + } + } + + +/*******************************UPDATE DEGREE**********************************/ + // Update diagonal block offset. + diagonal_offsets.push_back( perm_off ); + //save upperbound for number of L and U entrys + unsigned int upperbound(0); + for(unsigned int i=0;i< block_diagonal.size();i++){ + mtl::dense_vector<int> involve_node(block_diagonal[i]->get_indices()); + for(unsigned int j=0;j< block_diagonal[i]->get_neighbors().size();j++){ + mtl::dense_vector<int> involve_neigh(block_diagonal[i]->get_neighbors()[j]->get_indices()); + unsigned int c(0); + for(unsigned int a= 0; a < size(involve_node); a++){ + for(unsigned int b= 0; b < size(involve_neigh); b++){ + if(involve_node[a] == involve_neigh[b]) + c++; + } + } + upperbound+= c*(size(involve_neigh)-c); + } + } + + // Update permutation offsets. + perm_high = perm_off; + +/*************************************************************************** + * Phase 2: Compute the update matrices + **************************************************************************/ + mtl::vampir_trace<9902> tb2; + + + coo_sparse_type_lower* L=new coo_sparse_type_lower(nb_vars, nb_vars, upperbound); + coo_sparse_type_upper* U=new coo_sparse_type_lower(nb_vars, nb_vars, upperbound); + lower_matrices.push_back(L); + upper_matrices.push_back(U); + // For each diagonal block element ... (in parallel) + unsigned int ku= 0, kl= 0; + for(std::size_t b_i = block_diag_low; b_i < block_diagonal.size();++b_i ) { + element_type& diag_el = *block_diagonal[b_i]; + // Copy the level-1 neighbors. + neigh_coll_type& diag_neighs = diag_el.get_neighbors(); + + // Determine the set of incident nodes. + boost::unordered_set<int> diag_incident_nodes = + diag_el.get_incident_nodes(); + index_type& p = diag_el.get_indices(); + index_type q( + diag_incident_nodes.size() == 0 ? + 1 : diag_incident_nodes.size() + ); + typename boost::unordered_set<int>::const_iterator it = + diag_incident_nodes.begin(); + for(unsigned int i = 0; i < diag_incident_nodes.size(); ++i) { + q(i) = *it; + ++it; + } + const int n1 = size(p); + const int n2 = diag_incident_nodes.size(); + sort(q); + assert(n1 > 0); + + // Construct a mapping from global to local node numbers. + cmap to_local; + for(int i = 0; i < n1; ++i) { + to_local[p(i)] = i; + } + + for(int i = 0; i < n2; ++i) { + to_local[q(i)] = mtl::size(p) + i; + } + // Construct the frontal matrix. + block_type frontal( n1+n2, n1+n2 ); + frontal = zero; + + // For each connected neighbor, add their values to the frontal + // matrix. + for(neigh_iterator neigh_it = diag_neighs.begin(); neigh_it != diag_neighs.end(); ++neigh_it) { + element_type& neigh = **neigh_it; + assert( el_status[neigh.get_id()] != DIAGONAL ); + assert( el_status[neigh.get_id()] != REMOVED ); + + // Remap indices. + index_type local_idx( neigh.get_indices() ); + + for(int i = 0; i < neigh.nb_vars(); ++i) { + local_idx(i) = to_local[ local_idx(i) ]; + } + //insert connectet neighbor + { + mtl::mat::inserter<mtl::mat::dense2D<value_type>, mtl::operations::update_plus<value_type> > ins(frontal); + ins << element_matrix(neigh.get_values(), local_idx, local_idx); + } + neigh.get_values()= zero; + } + // Add the values of the diagonal element to the frontal matrix. + { + // Remap indices. + index_type local_idx( diag_el.get_indices() ); + for(int i = 0; i < diag_el.nb_vars(); ++i) { + local_idx(i) = to_local[ local_idx(i) ]; + } + //insert the diagonal element + { + mtl::mat::inserter<matrix_type, mtl::operations::update_plus<value_type> > ins(frontal); + ins << element_matrix( + diag_el.get_values(), local_idx, local_idx); + } + diag_el.get_values()= zero; + } + // + // Store the L and U part. + // + for(int i = 0; i < n1; ++i) { // p-part + for(int j = n1; j < n1+n2; ++j) { // q-part + // Assumption: structural symmetry. + if(frontal(i,j) != zero) { + U->insert(p(i),q(j-n1),frontal(i,j)); + ku++; + } + if(frontal(j,i) != zero){ + L->insert(q(j-n1),p(i),frontal(j,i)); + kl++; + } + } + } + + mtl::irange n0(0,n1); + diag_el.get_values() = inv(mtl::clone(frontal[n0][n0])); + frontal[n0][n0] = diag_el.get_values(); + + if( (level <= maxlofi) && (n2 > 0) ) { +//------------------------------------------------------------------------------ +// ELEMENT COALESCING APPROACH +//------------------------------------------------------------------------------ + // The lofi is below the user-requested level. Use Algorithm 2 + // in [1]. + // Compute the Schur complement. + mtl::irange n1r(0,n1), n2r(n1, mtl::imax); + frontal[n2r][n2r]-= frontal[n2r][n1r] * frontal[n1r][n1r] * frontal[n1r][n2r]; + mtl::irange nz(n1,n1+n2); + matrix_type Z( mtl::clone(frontal[nz][nz]) ); + // Construct the new element. + element_type* fill = new element_type(max_sequence_number, q, Z); + // Add processing information to the required DSs. + elements.push_back( fill ); + el_status.push_back( UNMARKED ); + + + // Determine the level-2 neighbors. + neigh_set_type lvl2_neighs = diag_el.get_level_neighbors( 2 ); + // Remove the level-1 neighbors of the diagonal element. + for(neigh_iterator it = diag_neighs.begin(); it != diag_neighs.end(); ++it) { + element_type& neigh = **it; + neigh.clear(); + el_status[neigh.get_id()] = REMOVED; + } + + // Update the neighborhood of the level-2 neighbors. + const IsRemoved<element_type, std::vector<Status> > is_removed( el_status ); + for(neigh_set_iterator it = lvl2_neighs.begin(); it != lvl2_neighs.end(); ++it) { + element_type& neigh = **it; + + // Skip the level-1 neighbors (removed) and the diagonal + // element. + if((el_status[neigh.get_id()] == DIAGONAL) || (el_status[neigh.get_id()] == REMOVED)) { + continue; + } + // The element is in the strict level-2 neighborhood. + // Remove the level-1 neighbors from its set of neighbors. + neigh_coll_type& neigh_neighs = neigh.get_neighbors(); + neigh_iterator new_end = std::remove_if(neigh_neighs.begin(), neigh_neighs.end(), is_removed); + neigh_neighs.erase(new_end, neigh_neighs.end()); + + // Add the newly generated element as neighbor, and vice + // versa. + neigh_neighs.push_back( fill ); + fill->get_neighbors().push_back( &neigh ); + + } + // Update sequence number. + ++max_sequence_number; + } else if (n2 > 0) { + +//------------------------------------------------------------------------------ +// ELEMENT DISTRIBUTION APPROACH +//------------------------------------------------------------------------------ + // The lofi is above the user-requested level. Use Algorithm 3 + // in [1] to compute the approximate Schur complement element- + // wise. + + // Distribute the values of the generalized element across the + // level-2 neighbors of the diagonal element. + + // Remove the nodes of the diagonal element from its + // neighbors. + for(neigh_iterator neigh_it = diag_neighs.begin(); neigh_it != diag_neighs.end(); ++neigh_it) + { + element_type& neigh = **neigh_it; + neigh.remove_nodes( diag_el.get_indices(), diag_el ); + + assert( el_status[neigh.get_id()] != DIAGONAL ); + assert( el_status[neigh.get_id()] != REMOVED ); + + // If the element is entirely removed, mark it as such. + if( neigh.nb_vars() == 0 ) { + el_status[neigh.get_id()] = REMOVED; + } + } + + // Compute the Schur complement. + mtl::irange n1r(0,n1), n2r(n1, mtl::imax); + frontal[n2r][n2r]-= frontal[n2r][n1r] * frontal[n1r][n1r] * frontal[n1r][n2r]; + // Distribute the values of the (modified) update matrix + // over the level-1 neighbors. + mtl::irange nz(n1,n1+n2); + matrix_type S( frontal[nz][nz] ); + for(neigh_iterator neigh_it = diag_neighs.begin(); neigh_it != diag_neighs.end();++neigh_it) { + element_type& el = **neigh_it; + if( el_status[el.get_id()] != REMOVED ) { + el.absorb(S, q); + } + } + // Do not distribute over the entire level-2 neighborhood. + // This is expensive, while not adding much in terms of quality + // of the approximation. + + } else { + // There are no more nodes in the Schur complement, but it could + // be that some elements other than the diagonal element overlap + // completely with said element. + + // In this case, simply remove all neighbors. + for(neigh_iterator neigh_it = diag_neighs.begin(); neigh_it != diag_neighs.end(); ++neigh_it) { + element_type& neigh = **neigh_it; + neigh.remove_nodes( diag_el.get_indices(), diag_el ); + assert( el_status[neigh.get_id()] != DIAGONAL ); + assert( el_status[neigh.get_id()] != REMOVED ); + // The element is now entirely removed, mark it as such. + assert( neigh.nb_vars() == 0 ); + el_status[neigh.get_id()] = REMOVED; + } + + } // END ELEMENT DISTRIBUTION + // Clear the neighborhood of the diagonal element. + diag_el.get_neighbors().clear(); + } + + std::cout << "level " << level << " complete: "; + std::cout << mesh.get_total_vars()-perm_high << " nodes remaining."<< "\n"; + + ++level; + } while( (mesh.get_total_vars() - perm_high > 0) ); // There are still variables to cover. + + + diagonal_offsets.push_back( mesh.get_total_vars() ); + assert( mesh.get_total_vars() - perm_high == 0 ); + assert( lower_matrices.size()+2 == diagonal_offsets.size() ); + /*************************************************************************** + * Phase 3: Apply permutation vector to lower and upper matrices + **************************************************************************/ + mtl::vampir_trace<9903> tb3; + + + mtl::mat::traits::permutation<>::type P(permutation(m_ordering)); + typedef typename coo_sparse_type_lower::size_type size_type; + + for( std::size_t k = 0; k < lower_matrices.size(); ++k ) { + coo_sparse_type_lower& L = *(lower_matrices[k]); + coo_sparse_type_upper& U = *(upper_matrices[k]); + if (nnz(L)> 0) { + std::vector<size_type> &L_row(L.row_index_array()), + &L_col(L.column_index_array()), + &U_row(U.row_index_array()), + &U_col(U.column_index_array()); + const int off_low = diagonal_offsets[k]; + for(unsigned int i = 0; i < nnz(L); ++i) { + L_row[i] = m_ordering( L_row[i] ); + L_col[i] = m_ordering( L_col[i] ) - off_low; + }; + for(unsigned int i = 0; i < nnz(U); ++i) { + U_row[i] = m_ordering( U_row[i] ) - off_low; + U_col[i] = m_ordering( U_col[i] ); + } + } + + m_lower.push_back(mtl::mat::compressed2D<value_type>(L)); + m_upper.push_back(mtl::mat::compressed2D<value_type>(U)); + } + /*************************************************************************** + * Phase 4: Construct the IMF preconditioner + **************************************************************************/ + // Copy the block diagonal values into a consecutive array. +// mtl::vampir_trace<9904> tb4; + + m_diagonal = new matrix_type[ block_diagonal.size() ]; + for(std::size_t i = 0; i < block_diagonal.size(); ++i) { + assert( el_status[block_diagonal[i]->get_id()] == DIAGONAL ); + unsigned int diarows(num_rows(block_diagonal[i]->get_values())); + m_diagonal[i].change_dim(diarows,diarows); + m_diagonal[i] = block_diagonal[i]->get_values(); + } + // Copy the diagonal offsets to a consecutive array. + int* diagonal_index = new int[ diagonal_offsets.size() ]; + memcpy( + diagonal_index, + &(diagonal_offsets[0]), + sizeof(int)*diagonal_offsets.size() + ); + assert( diagonal_offsets.back() == mesh.get_total_vars() ); + assert( lower_matrices.size()+2 == diagonal_offsets.size() ); + + m_levels = lower_matrices.size(); + m_nb_blocks = block_diagonal.size(); + m_diagonal_index = diagonal_index; + + // Todo: create element_structure from all elements + // Delete only elements that we generated; those at the beginning are just referred + for (unsigned i= nb_elements; i < elements.size(); i++) + delete elements[i]; + + for (unsigned i= 0; i < lower_matrices.size(); i++) + delete lower_matrices[i]; + for (unsigned i= 0; i < upper_matrices.size(); i++) + delete upper_matrices[i]; +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// IMF APPLICATION +// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +/** + * Applies the IMF preconditioner to a matrix. The contents of the rhs vector + * are overwritten. + * + * The algorithm is implemented without recursion, as was already suggested by + * Y. Saad in [2]. + */ + +template< class ValType > +template< class Vector > +Vector imf_preconditioner<ValType>::imf_apply(const Vector& rhs) const +{ + using namespace mtl; + Vector res(rhs); + ValType zero(0); + // Forward elimination. + { + mtl::vampir_trace<9901> tb1; + int b_off = 0; + for(int level = 0; level < m_levels; ++level) { + const int off_low = m_diagonal_index[level]; + const int off_high = m_diagonal_index[level+1]; + const int n1 = off_high - off_low; + assert(off_low <= off_high); + // Compute dy = inv(D)*y + vector_type dy(n1); + dy = zero; + for(int off = off_low; off < off_high; ++b_off ) { //parallel + const int block_size = num_rows( m_diagonal[b_off] ); + dy[mtl::irange(off-off_low, off-off_low+block_size)] = m_diagonal[b_off] * res[mtl::irange(off, off + block_size)]; + off += block_size; + } + // Compute x = x - E*dy + Vector big(num_cols(m_lower[level]), ValType(0)); + big[mtl::irange(0,n1)] = dy; + res -= m_lower[level] * big; + } + } + + // Backward elimination. + { + mtl::vampir_trace<9902> tb2; + int b_off = m_nb_blocks-1; + for(int level = m_levels-1; level >= 0; --level) { + + const int off_low = m_diagonal_index[level]; + const int off_high = m_diagonal_index[level+1]; + // y' = y - Fx +// assert( m_upper[level] ); + + vector_type yp(m_upper[level] * res); + res[mtl::irange(off_low, off_high) ] -= yp[mtl::irange(0, off_high-off_low) ]; + // y = inv(D)*y' + for(int off = off_high; off > off_low; --b_off ) { + const int block_size = num_rows(m_diagonal[b_off]); + assert(b_off >= 0); + assert(off-block_size >= off_low); + + vector_type dy(m_diagonal[b_off] * res[irange(off-block_size, off)] ); + res[irange(off-block_size, off)] = dy; + off -= block_size; + } + } + assert(b_off == -1); + } + return res; +} + + +} // end namespace pc +} // end namespace itl + + +#endif // MTL_IMF_ALGORITHMS_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/imf_preconditioner.hpp b/install/MTL/include/boost/numeric/itl/pc/imf_preconditioner.hpp new file mode 100644 index 00000000..0486fecf --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/imf_preconditioner.hpp @@ -0,0 +1,169 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. +// +// Algorithm inspired by Nick Vannieuwenhoven, written by Cornelius Steinhardt + +/* + * The IMF preconditioner. + * + * References + * [1] N. Vannieuwenhoven and K. Meerbergen, IMF: An incomplete multifron- + * tal LU-factorization for element-structured sparse linear systems, + * Tech. Rep. TW581, Department of Computer Science, KULeuven, + * December 2010. + */ + +#ifndef MTL_IMF_PRECONDITIONER_INCLUDE +#define MTL_IMF_PRECONDITIONER_INCLUDE + +#include <boost/numeric/itl/pc/matrix_algorithms.hpp> +#include <boost/numeric/itl/pc/solver.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/mtl/matrix/coordinate2D.hpp> +#include <boost/numeric/mtl/matrix/dense2D.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> + + +namespace itl { namespace pc { + +/// The IMF preconditioner, as described in [1]. +template<class ValType> +class imf_preconditioner { + +public: + /// The type of the values. + typedef ValType value_type; + + /// The type of the sparse data structure for the upper matrices. + typedef mtl::mat::coordinate2D<value_type> sparse_type_upper; + + /// The type of the sparse data structure for the lower matrices. + typedef mtl::mat::coordinate2D<value_type> sparse_type_lower; + + /// The type of the vectors. + typedef mtl::dense_vector<value_type> vector_type; + + ///The type of the permutation vector. + typedef mtl::dense_vector<int> index_type; + + /// The type of the matrices on the block diagonal. + typedef mtl::mat::dense2D<value_type> block_type; + + /// The type of the sequence of lower matrices. + typedef std::vector<mtl::mat::compressed2D<value_type> > lower_matrix_coll_type; + + /// The type of the sequence of upper matrices. + typedef std::vector<mtl::mat::compressed2D<value_type> > upper_matrix_coll_type; + + /// Constructor + template< class ElementStructure > + imf_preconditioner( + const ElementStructure& element_structure , + const int maxlofi=0, + const bool copy_on=true + ) + : m_nb_vars( element_structure.get_total_vars() ), + m_ordering( element_structure.get_total_vars() ), + m_diagonal_index(0), + m_diagonal(0) + { + mtl::vampir_trace<5053> tracer; + if(copy_on){ + ElementStructure es(element_structure); + factor(es, maxlofi); + } else { + factor(element_structure, maxlofi); + } + P= permutation(m_ordering); + } + + /// Destructor + ~imf_preconditioner() + { + delete[] m_diagonal_index; + delete[] m_diagonal; + } + +private: + /// Disallow the copy constructor and assignment. + imf_preconditioner(); + imf_preconditioner(const imf_preconditioner& other); + void operator=(const imf_preconditioner& other); + + /// Constructs the IMF preconditioner.Forward declaration + template< class ElementStructure > + void factor(const ElementStructure&, const int); + +public: + + /// Returns the number of levels (equals the number of lower and upper matrices. + int get_nb_levels() const { return m_levels; } + + /// Returns the number of blocks on the diagonal. + int get_nb_blocks() const { return m_nb_blocks; } + + + /// Applies the preconditioner to the given matrix. + template <typename VectorIn, typename VectorOut> + void solve(const VectorIn& b, VectorOut& x) const + { + VectorIn m(trans(P)*b), m_tmp(imf_apply(m)); + x= P * m_tmp; + } + +private: + /// Applies the preconditioner prototype + template< class Vector > + Vector imf_apply(const Vector&) const; + + /// The number of variables (also the size of the m_ordering vector). + unsigned int m_nb_vars; + + /// The number of blocks on the diagonal. + unsigned int m_nb_blocks; + + /// A vector containing the renumbering of IMF. + index_type m_ordering; + + /// A matrix containing the renumbering of IMF. + mtl::mat::traits::permutation<>::type P; + + /// The number of levels (equals the number of entries in the diagonal index array minus one). + int m_levels; + + /** The index array for the matrices on the block diagonal. The i^th entry + * indicates where the i^th level of block diagonal matrices starts in the + * right hand side vector. */ + int* m_diagonal_index; + + /// The matrices on the block diagonal. + block_type* m_diagonal; + + /// The sparse lower matrices of each level, sorted by level. + lower_matrix_coll_type m_lower; + + /// The sparse upper matrices of each level, sorted by level. + upper_matrix_coll_type m_upper; +}; + +/// Solve +template <typename Matrix, typename Vector> +solver<imf_preconditioner<Matrix>, Vector, false> +inline solve(const imf_preconditioner<Matrix>& P, const Vector& b) +{ + mtl::vpt::vampir_trace<5054> tracer; + return solver<imf_preconditioner<Matrix>, Vector, false>(P, b); +} +}//namespace pc +}//namespace itl +#endif // MTL_IMF_PRECONDITIONER_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/is_identity.hpp b/install/MTL/include/boost/numeric/itl/pc/is_identity.hpp new file mode 100644 index 00000000..5a5ce519 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/is_identity.hpp @@ -0,0 +1,41 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_PC_IS_IDENTITY_INCLUDE +#define ITL_PC_IS_IDENTITY_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/itl/itl_fwd.hpp> + +namespace itl { namespace pc { + +template <typename PC> +bool is_identity(const PC&) +{ return false; } + +template <typename Matrix, typename Value> +bool is_identity(const itl::pc::identity<Matrix, Value>&) +{ return true; } + +template <typename PC> +struct static_is_identity + : boost::mpl::false_ +{}; + +template <typename Matrix, typename Value> +struct static_is_identity<itl::pc::identity<Matrix, Value> > + : boost::mpl::true_ +{}; + +}} // namespace itl::pc + +#endif // ITL_PC_IS_IDENTITY_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/matrix_algorithms.hpp b/install/MTL/include/boost/numeric/itl/pc/matrix_algorithms.hpp new file mode 100644 index 00000000..5d0800bd --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/matrix_algorithms.hpp @@ -0,0 +1,74 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. +// +// Algorithm inspired by Nick Vannieuwenhoven, written by Cornelius Steinhardt + + + +#ifndef MTL_MATRIX_ALGORITHMS_INCLUDE +#define MTL_MATRIX_ALGORITHMS_INCLUDE + +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/mtl/mtl.hpp> +#include <boost/numeric/mtl/matrix/element.hpp> +#include <boost/numeric/mtl/matrix/element_structure.hpp> + +#include <iostream> + +namespace mtl { namespace mat { + +/// Construct the sparse data structure from an elementstructure +template< typename ElementStructure, typename Matrix, typename Vector> +void assemble_compressed(const ElementStructure& es, Matrix& A, Vector& order) +{ + + typedef typename ElementStructure::element_type::value_type value_type; + typedef typename ElementStructure::element_iterator iterator; + typedef typename ElementStructure::element_type element_type; + typedef typename element_type::index_type index_type; + typedef typename element_type::matrix_type matrix_type; + typedef typename matrix_type::size_type size_type; + A.change_dim(es.get_total_vars(), es.get_total_vars()); + set_to_zero(A); + value_type zero(0); + + {//start inserterblock + mtl::mat::inserter<Matrix, mtl::operations::update_plus<value_type> > ins(A); + for(iterator it = es.element_begin(); it != es.element_end(); ++it) { + element_type& element = *it; + const index_type& idx = element.get_indices(); + matrix_type& values = element.get_values(); + for(int i = 0; i < element.nb_vars(); ++i) { + for(int j = 0; j < element.nb_vars(); ++j) { + if(values(i,j) != zero) { + ins[size_type(order(idx(i)))][size_type(order(idx(j)))] << values(i,j); + } + } + } + } + }//end inserterblock +} + + +/// Construct the sparse data structure from an elementstructure +template< typename ElementStructure, typename Matrix> +void assemble_compressed(const ElementStructure& es, Matrix& A) +{ + typedef typename ElementStructure::element_type::matrix_type::size_type size_type; + mtl::dense_vector<size_type> ident(es.get_total_vars()); + iota(ident); + assemble_compressed(es, A, ident); +} + +}}//end namespace mtl + +#endif // MTL_MATRIX_ALGORITHMS_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/solver.hpp b/install/MTL/include/boost/numeric/itl/pc/solver.hpp new file mode 100644 index 00000000..c3a8f53d --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/solver.hpp @@ -0,0 +1,56 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_PC_SOLVER_INCLUDE +#define ITL_PC_SOLVER_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/vector/assigner.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace itl { namespace pc { + +/// Helper class for delayed (i.e. copy-free) evaluation of preconditioners +template <typename PC, typename Vector, bool adjoint= false> +struct solver + : mtl::vec::assigner<solver<PC, Vector> > +{ + typedef PC pc_type; + + /// Constructor taking preconditioner and source vector + solver(const pc_type& P, const Vector& x) : P(P), x(x) {} + + /// Assign result to vector \p y, if possible without copying + template <typename VectorOut> + void assign_to(VectorOut& y) const + { + mtl::vampir_trace<5055> tracer; + assign_to(y, boost::mpl::bool_<adjoint>()); + } + + protected: + + template <typename VectorOut> + void assign_to(VectorOut& y, boost::mpl::false_) const + { P.solve(x, y); } + + template <typename VectorOut> + void assign_to(VectorOut& y, boost::mpl::true_) const + { P.adjoint_solve(x, y); } + + const pc_type& P; + const Vector& x; +}; + +}} // namespace itl::pc + +#endif // ITL_PC_SOLVER_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/sorting.hpp b/install/MTL/include/boost/numeric/itl/pc/sorting.hpp new file mode 100644 index 00000000..a118f3ec --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/sorting.hpp @@ -0,0 +1,307 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. +// +// Algorithm inspired by Nick Vannieuwenhoven, written by Cornelius Steinhardt + +/* + * + * Created on: Nov 3, 2009 + * Author: heazk + */ + +#ifndef MTL_SORTING_INCLUDE +#define MTL_SORTING_INCLUDE + +#include <string.h> +#include <stdlib.h> + +#define BITS_PER_BYTE 8 + +//////////////////////////////////////////////////////////////////////////////// +// RADIX-SORT +//////////////////////////////////////////////////////////////////////////////// + +template< + class Type +> +void radix_sort( + Type* values, + const int size, + Type* tmp = 0 +) { + if(size < 2) { + return; + } + + Type *const orig_ptr = values; + if(tmp == 0) { + tmp = new Type[size]; + } + +#if VERBOSE_MODE > 10 + std::cout << "unsorted: "; + for(int i = 0; i < size; ++i) { + std::cout << values[i] << ", "; + } + std::cout << std::endl; +#endif + + // Determine the maximum number of bits needed. + int max = INT_MIN; + for(int i = 0; i < size; ++i) { + max = (values[i] <= max) ? max : values[i]; + } + int maxBits = 1; + for(; max; max >>= 1, ++maxBits){}; + for(max = 0; max < maxBits; max += BITS_PER_BYTE){}; + maxBits = max; + + const int groupBits = BITS_PER_BYTE; + const int intBits = maxBits; + const int groupSize = 1 << groupBits; + + const int nbIterations = intBits / groupBits; + const int mask = groupSize-1; + + // Counting and prefix arrays. + int* count = new int[groupSize]; + + for ( + int shift = 0, it = 0; + it < nbIterations; + ++it, shift += groupBits + ) { + // Reset count array. + memset(count, 0, groupSize*sizeof(int)); + + // Counting elements in the it-th group. + for (int i = 0; i < size; ++i) { + count[ (values[i] >> shift) & mask ]++; + } + + // Calculate prefixes. + int currIncrement = -1; + int prevCount = count[0]; + count[0] = 0; + for (int i = 1; i < groupSize; ++i) { + currIncrement = prevCount; + prevCount = count[i]; + count[i] = count[i-1] + currIncrement; + } + + // Sort elements in the it-th group. + for (int i = 0; i < size; ++i) { + int& index = count[( values[i] >> shift) & mask]; + tmp[ index ] = values[i]; + ++index; + } + + // Swap pointers. + Type* tmp_values = values; + values = tmp; + tmp = tmp_values; + } + + // Make sure the sorted keys and values reside in the input array. + if( values != orig_ptr ) { + memcpy( orig_ptr, values, sizeof(Type)*size ); + tmp = values; + } + +#if VERBOSE_MODE > 10 + std::cout << "sorted: "; + for(int i = 0; i < size; ++i) { + std::cout << values[i] << ", "; + } + std::cout << std::endl; +#endif + + if(count) { + delete[] count; + } + if(tmp) { + delete[] tmp; + } +} + +template< + class Key, class Val +> +void radix_sort( + Key* keys, Val* vals, + const int size, + Key* tmpKeys = 0, Val* tmpVals = 0 +) { + if(size < 2) { + return; + } + + // The pointers to the original data. + Key *const origKey = keys; + Val *const origVal = vals; + + // Helper arrays. + bool ownKeys = false; + bool ownVals = false; + if(!tmpKeys) { + tmpKeys = new Key[size]; + ownKeys = true; + } + if(!tmpVals) { + tmpVals = new Val[size]; + ownVals = true; + } + + // Determine the maximum number of bits needed. + int max = -(INT_MAX-1); + for(int i = 0; i < size; ++i) { + max = keys[i] <= max ? max : keys[i]; + } + int maxBits = 1; + for(; max; max >>= 1, ++maxBits){}; + for(max = 0; max < maxBits; max += BITS_PER_BYTE){}; + maxBits = max; + + const int groupBits = BITS_PER_BYTE; + const int intBits = maxBits; + const int groupSize = 1 << groupBits; + + const int nbIterations = intBits / groupBits; + const int mask = groupSize-1; + + // Counting and prefix arrays. + int* count = new int[groupSize]; + // Allocation of memory could fail! + + for ( + int shift = 0, it = 0; + it < nbIterations; + ++it, shift += groupBits + ) { + // Reset count array. + for(int i = 0; i < groupSize; ++i) { + count[i] = 0; + } + + // Counting elements in the it-th group. + for (int i = 0; i < size; ++i) { + count[ (keys[i] >> shift) & mask ]++; + } + + // Calculate prefixes. + int currIncrement = -1; + int prevCount = count[0]; + count[0] = 0; + for (int i = 1; i < groupSize; ++i) { + currIncrement = prevCount; + prevCount = count[i]; + count[i] = count[i-1] + currIncrement; + } + + // Sort elements in the it-th group. + for (int i = 0; i < size; ++i) { + int& index = count[( keys[i] >> shift) & mask]; + tmpKeys[ index ] = keys[i]; + tmpVals[ index ] = vals[i]; + ++index; + } + + // Swap pointers. + Key* tmpKeyPtr = tmpKeys; + Val* tmpValuePtr = tmpVals; + tmpKeys = keys; + tmpVals = vals; + keys = tmpKeyPtr; + vals = tmpValuePtr; + } + + // Make sure the sorted keys and values reside in the input array. + if(keys != origKey) { + memcpy( origKey, keys, sizeof(Key)*size ); + tmpKeys = keys; + } + if(vals != origVal) { + memcpy( origVal, vals, sizeof(Val)*size ); + tmpVals = vals; + } + + if(count) delete[] count; + if(ownKeys && tmpKeys) delete[] tmpKeys; + if(ownVals && tmpVals) delete[] tmpVals; + tmpKeys = 0; + tmpVals = 0; + count = 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// QUICK-SORT +//////////////////////////////////////////////////////////////////////////////// + +template<typename Key, typename Val> +inline void swap(Key& key0, Val& val0, Key& key1, Val& val1) { + Key tmp_key = key0; + Val tmp_val = val0; + key0 = key1; + val0 = val1; + key1 = tmp_key; + val1 = tmp_val; +} + +template<typename Key, typename Value> +inline void sort_along(Key* keys, Value* values, int size) { + + + if(size < 2) { + return; + } + if( size == 2 ) { + if(keys[0] > keys[1]) { + swap( + keys[0], values[0], + keys[1], values[1] + ); + } + return; + } + + int piv = std::rand() % size; + + + swap( + keys[0], values[0], + keys[piv], values[piv] + ); + int begin = 1; + int end = size-1; + while(begin < end) { + for(; (begin < end) && (keys[begin] <= keys[0]); ++begin){}; + for(; (begin <= end) && (keys[end] > keys[0]); --end){}; + + if(begin < end) { + swap( + keys[begin], values[begin], + keys[end], values[end] + ); + } + } + piv = end; + swap( + keys[0], values[0], + keys[piv], values[piv] + ); + + + sort_along( keys, values, piv ); + sort_along( keys+(piv+1), values+(piv+1), size-piv-1); +} + +#endif // MTL_SORTING_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/pc/sub_matrix_pc.hpp b/install/MTL/include/boost/numeric/itl/pc/sub_matrix_pc.hpp new file mode 100644 index 00000000..10d5130f --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/pc/sub_matrix_pc.hpp @@ -0,0 +1,198 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef ITL_PC_SUB_MATRIX_PC_INCLUDE +#define ITL_PC_SUB_MATRIX_PC_INCLUDE + +#include <boost/static_assert.hpp> +#include <boost/mpl/if.hpp> + +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/itl/pc/solver.hpp> + +namespace itl { namespace pc { + +/// Class for applying \tparam Preconditioner only on a sub-matrix +/** Other entries are just copied. + Optionally preconditioner can be referred from outside instead of storing it by setting + \tparam Store to true. +**/ +template <typename Preconditioner, typename Matrix, bool Store= true> +class sub_matrix_pc +{ + typedef mtl::dense_vector<bool> tag_type; + typedef typename boost::mpl::if_c<Store, Preconditioner, const Preconditioner&>::type pc_type; + + struct matrix_container + { + matrix_container() : Ap(0) {} + + matrix_container(const tag_type& tags, const Matrix& src) + { + using std::size_t; + using namespace mtl; + + mtl::dense_vector<size_t> perm(size(tags)); + size_t n= 0; + for (size_t i= 0; i < size(tags); ++i) { + perm[i]= n; + if (tags[i]) + ++n; + } + + Ap= new Matrix(n, n); + + typename traits::row<Matrix>::type row(src); + typename traits::col<Matrix>::type col(src); + typename traits::const_value<Matrix>::type value(src); + typedef typename traits::range_generator<tag::major, Matrix>::type cursor_type; + + mat::inserter<Matrix> ins(*Ap, Ap->nnz() / Ap->dim1()); + + for (cursor_type cursor = mtl::begin<tag::major>(src), cend = mtl::end<tag::major>(src); + cursor != cend; ++cursor) { + // std::cout << dest << '\n'; + + typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type; + for (icursor_type icursor = mtl::begin<tag::nz>(cursor), icend = mtl::end<tag::nz>(cursor); + icursor != icend; ++icursor) + if (tags[row(*icursor)] && tags[col(*icursor)]) + ins(perm[row(*icursor)], perm[col(*icursor)]) << value(*icursor); + } + } + + ~matrix_container() { delete Ap; } + + Matrix* Ap; + }; + + size_t count_entries() const + { + using mtl::size; + size_t n= 0; + for (size_t i= 0; i < size(tags); ++i) + if (tags[i]) ++n; + return n; + } + + public: + + sub_matrix_pc(const tag_type& tags, const Matrix& A) + : tags(tags), n(count_entries()), mc(tags, A), P(*mc.Ap) + { + BOOST_STATIC_ASSERT((Store)); + delete mc.Ap; + mc.Ap= 0; + } + +#if 0 // to do later + sub_matrix_pc(const tag_type& tags, const Preconditioner& P) + : tags(tags), P(P) + { + // check sizes + } +#endif + + private: + template <typename VectorIn> + VectorIn& create_x0(VectorIn) const + { + static VectorIn x0(n); + return x0; + } + + template <typename VectorOut> + VectorOut& create_y0(VectorOut) const + { + static VectorOut y0(n); + return y0; + } + + template <typename VectorIn> + void restrict(const VectorIn& x, VectorIn& x0) const + { + for (size_t i= 0, j= 0; i < size(tags); ++i) + if (tags[i]) + x0[j++]= x[i]; + } + + template <typename VectorIn, typename VectorOut> + void prolongate(const VectorIn& x, const VectorOut& y0, VectorOut& y) const + { + for (size_t i= 0, j= 0; i < size(tags); ++i) + if (tags[i]) + y[i]= y0[j++]; + else + y[i]= x[i]; + } + + public: + /// Solve Px = y approximately on according sub-system; remaining entries are copied + template <typename VectorIn, typename VectorOut> + void solve(const VectorIn& x, VectorOut& y) const + { + mtl::vampir_trace<5056> tracer; + y.checked_change_resource(x); + + VectorIn& x0= create_x0(x); + VectorOut& y0= create_y0(y); + + restrict(x, x0); + P.solve(x0, y0); + // y0= solve(P, x0); // doesn't compile yet for unknown reasons + prolongate(x, y0, y); + } + + /// Solve Px = y approximately on according sub-system; remaining entries are copied + template <typename VectorIn, typename VectorOut> + void adjoint_solve(const VectorIn& x, VectorOut& y) const + { + mtl::vampir_trace<5057> tracer; + y.checked_change_resource(x); + + VectorIn& x0= create_x0(x); + VectorOut& y0= create_y0(y); + + restrict(x, x0); + P.adjoint_solve(x0, y0); + // y0= adjoint_solve(P, x0); // doesn't compile yet for unknown reasons + prolongate(x, y0, y); + } + + private: + tag_type tags; + size_t n; + matrix_container mc; + pc_type P; +}; + +template <typename Preconditioner, typename Matrix, bool Store, typename Vector> +solver<sub_matrix_pc<Preconditioner, Matrix, Store>, Vector, false> +inline solve(const sub_matrix_pc<Preconditioner, Matrix, Store>& P, const Vector& x) +{ + return solver<sub_matrix_pc<Preconditioner, Matrix, Store>, Vector, false>(P, x); +} + +template <typename Preconditioner, typename Matrix, bool Store, typename Vector> +solver<sub_matrix_pc<Preconditioner, Matrix, Store>, Vector, true> +inline adjoint_solve(const sub_matrix_pc<Preconditioner, Matrix, Store>& P, const Vector& x) +{ + return solver<sub_matrix_pc<Preconditioner, Matrix, Store>, Vector, true>(P, x); +} + + +}} // namespace itl::pc + +#endif // ITL_PC_SUB_MATRIX_PC_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/smoother/gauss_seidel.hpp b/install/MTL/include/boost/numeric/itl/smoother/gauss_seidel.hpp new file mode 100644 index 00000000..c8f8ac40 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/smoother/gauss_seidel.hpp @@ -0,0 +1,137 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_GAUSS_SEIDEL_INCLUDE +#define ITL_GAUSS_SEIDEL_INCLUDE + +#include <boost/assert.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace itl { + +/// Gauss-Seidel smoother +/** Constructor takes references to a matrix and a right-hand side vector. + operator() is applied on a vector and changes it in place. + Matrix must be square, stored row-major and free of zero entries in the diagonal. + Vectors b and x must have the same number of rows as A. +**/ +template <typename Matrix> +class gauss_seidel +{ + typedef typename mtl::Collection<Matrix>::value_type Scalar; + typedef typename mtl::Collection<Matrix>::size_type size_type; + public: + /// Construct with constant references to matrix and RHS vector + gauss_seidel(const Matrix& A) : A(A), dia_inv(num_rows(A)) + { + BOOST_STATIC_ASSERT((mtl::traits::is_row_major<Matrix>::value)); // No CCS + assert(num_rows(A) == num_cols(A)); // Matrix must be square + for (size_type i= 0; i < num_rows(A); ++i) { + Scalar a= A[i][i]; + MTL_THROW_IF(a == 0, mtl::missing_diagonal()); + dia_inv[i]= 1.0 / a; + } + } + + /// Apply Gauss-Seidel on vector \p x, i.e. \p x is changed + template <typename Vector, typename RHSVector> + Vector& operator()(Vector& x, const RHSVector& b) const + { + mtl::vampir_trace<8551> tracer; + namespace tag= mtl::tag; using namespace mtl::traits; + using mtl::begin; using mtl::end; + + typedef typename range_generator<tag::row, Matrix>::type a_cur_type; + typedef typename range_generator<tag::nz, a_cur_type>::type a_icur_type; + typename col<Matrix>::type col_a(A); + typename const_value<Matrix>::type value_a(A); + + typedef typename mtl::Collection<Vector>::value_type value_type; + + a_cur_type ac= begin<tag::row>(A), aend= end<tag::row>(A); + for (unsigned i= 0; ac != aend; ++ac, ++i) { + value_type tmp= b[i]; + for (a_icur_type aic= begin<tag::nz>(ac), aiend= end<tag::nz>(ac); aic != aiend; ++aic) + if (col_a(*aic) != i) + tmp-= value_a(*aic) * x[col_a(*aic)]; + x[i]= dia_inv[i] * tmp; + } + return x; + } + + private: + const Matrix& A; + mtl::dense_vector<Scalar> dia_inv; +}; + + +template <typename Value, typename Parameters> +class gauss_seidel<mtl::mat::compressed2D<Value, Parameters> > +{ + typedef mtl::mat::compressed2D<Value, Parameters> Matrix; + typedef typename mtl::Collection<Matrix>::value_type Scalar; + typedef typename mtl::Collection<Matrix>::size_type size_type; + public: + /// Construct with constant references to matrix and RHS vector + gauss_seidel(const Matrix& A) + : A(A), dia_inv(num_rows(A)), dia_pos(num_rows(A)) + { + BOOST_STATIC_ASSERT((mtl::traits::is_row_major<Matrix>::value)); // No CCS + assert(num_rows(A) == num_cols(A)); // Matrix must be square + for (size_type i= 0; i < num_rows(A); ++i) { + mtl::utilities::maybe<size_type> pos = A.indexer(A, i, i); + MTL_THROW_IF(!pos, mtl::missing_diagonal()); + dia_inv[i]= 1.0 / A.value_from_offset(pos); + dia_pos[i]= pos; + } + } + + /// Apply Gauss-Seidel on vector \p x, i.e. \p x is changed + template <typename Vector, typename RHSVector> + Vector& operator()(Vector& x, const RHSVector& b) const + { + mtl::vampir_trace<8551> tracer; + typedef typename mtl::Collection<Vector>::value_type value_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + const size_type nr= num_rows(A); + size_type cj1= A.ref_major()[0]; + for (size_type i= 0; i < nr; ++i) { + value_type tmp= b[i]; + size_type cj0= cj1, cjm= dia_pos[i]; + cj1= A.ref_major()[i+1]; + for (; cj0 < cjm; cj0++) + tmp-= A.data[cj0] * x[A.ref_minor()[cj0]]; + for (size_type j= cjm+1; j < cj1; j++) + tmp-= A.data[j] * x[A.ref_minor()[j]]; + x[i]= dia_inv[i] * tmp; + } + return x; + } + + + private: + const Matrix& A; + mtl::dense_vector<Scalar> dia_inv; + mtl::dense_vector<size_type> dia_pos; +}; + + +} // namespace itl + +#endif // ITL_GAUSS_SEIDEL_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/smoother/jacobi.hpp b/install/MTL/include/boost/numeric/itl/smoother/jacobi.hpp new file mode 100644 index 00000000..6b5ea28d --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/smoother/jacobi.hpp @@ -0,0 +1,139 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_JACOBI_INCLUDE +#define ITL_JACOBI_INCLUDE + +#include <boost/assert.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operations.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> + +namespace itl { + +/// Jacobi smoother +/** Constructor takes references to a matrix and a right-hand side vector. + operator() is applied on a vector and changes it in place. + Matrix must be square, stored row-major and free of zero entries in the diagonal. + Vectors b and x must have the same number of rows as A. +**/ +template <typename Matrix> +class jacobi +{ + typedef typename mtl::Collection<Matrix>::value_type Scalar; + typedef typename mtl::Collection<Matrix>::size_type size_type; + public: + /// Construct with constant references to matrix and RHS vector + jacobi(const Matrix& A) : A(A), dia_inv(num_rows(A)) + { + BOOST_STATIC_ASSERT((mtl::traits::is_row_major<Matrix>::value)); // No CCS + assert(num_rows(A) == num_cols(A)); // Matrix must be square + for (size_type i= 0; i < num_rows(A); ++i) { + Scalar a= A[i][i]; + MTL_THROW_IF(a == 0, mtl::missing_diagonal()); + dia_inv[i]= 1.0 / a; + } + } + + /// Apply Jacobi on vector \p x, i.e. \p x is changed + template <typename Vector, typename RHSVector> + Vector& operator()(Vector& x, const RHSVector& b) const + { + namespace tag= mtl::tag; using namespace mtl::traits; + using mtl::begin; using mtl::end; using std::swap; + + typedef typename range_generator<tag::row, Matrix>::type a_cur_type; + typedef typename range_generator<tag::nz, a_cur_type>::type a_icur_type; + typename col<Matrix>::type col_a(A); + typename const_value<Matrix>::type value_a(A); + + typedef typename mtl::Collection<Vector>::value_type value_type; + + static Vector x0(resource(x)); + a_cur_type ac= begin<tag::row>(A), aend= end<tag::row>(A); + for (unsigned i= 0; ac != aend; ++ac, ++i) { + value_type tmp= b[i]; + for (a_icur_type aic= begin<tag::nz>(ac), aiend= end<tag::nz>(ac); aic != aiend; ++aic) + if (col_a(*aic) != i) + tmp-= value_a(*aic) * x[col_a(*aic)]; + x0[i]= dia_inv[i] * tmp; + } + swap(x0, x); + return x; + } + + private: + const Matrix& A; + mtl::dense_vector<Scalar> dia_inv; +}; + + +template <typename Value, typename Parameters> +class jacobi<mtl::mat::compressed2D<Value, Parameters> > +{ + typedef mtl::mat::compressed2D<Value, Parameters> Matrix; + typedef typename mtl::Collection<Matrix>::value_type Scalar; + typedef typename mtl::Collection<Matrix>::size_type size_type; + public: + /// Construct with constant references to matrix and RHS vector + jacobi(const Matrix& A) + : A(A), dia_inv(num_rows(A)), dia_pos(num_rows(A)) + { + BOOST_STATIC_ASSERT((mtl::traits::is_row_major<Matrix>::value)); // No CCS + assert(num_rows(A) == num_cols(A)); // Matrix must be square + for (size_type i= 0; i < num_rows(A); ++i) { + mtl::utilities::maybe<size_type> pos = A.indexer(A, i, i); + MTL_THROW_IF(!pos, mtl::missing_diagonal()); + dia_inv[i]= 1.0 / A.value_from_offset(pos); + dia_pos[i]= pos; + } + } + + /// Apply Jacobi on vector \p x, i.e. \p x is changed + template <typename Vector, typename RHSVector> + Vector& operator()(Vector& x, const RHSVector& b) const + { + typedef typename mtl::Collection<Vector>::value_type value_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + const size_type nr= num_rows(A); + static Vector x0(resource(x)); + size_type cj1= A.ref_major()[0]; + for (size_type i= 0; i < nr; ++i) { + value_type tmp= b[i]; + size_type cj0= cj1, cjm= dia_pos[i]; + cj1= A.ref_major()[i+1]; + for (; cj0 < cjm; cj0++) + tmp-= A.data[cj0] * x[A.ref_minor()[cj0]]; + for (size_type j= cjm+1; j < cj1; j++) + tmp-= A.data[j] * x[A.ref_minor()[j]]; + x0[i]= dia_inv[i] * tmp; + } + swap(x0, x); + return x; + } + + + private: + const Matrix& A; + mtl::dense_vector<Scalar> dia_inv; + mtl::dense_vector<size_type> dia_pos; +}; + + +} // namespace itl + +#endif // ITL_JACOBI_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/smoother/jor.hpp b/install/MTL/include/boost/numeric/itl/smoother/jor.hpp new file mode 100644 index 00000000..1b96b532 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/smoother/jor.hpp @@ -0,0 +1,140 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_JOR_INCLUDE +#define ITL_JOR_INCLUDE + +#include <boost/assert.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> + +#include "./relaxation_parameter.hpp" + +namespace itl { + +/// Jacobi smoother with relaxation +/** Constructor takes references to a matrix and a right-hand side vector. + operator() is applied on a vector and changes it in place. + Matrix must be square, stored row-major and free of zero entries in the diagonal. + Vectors b and x must have the same number of rows as A. +**/ +template <typename Matrix, typename Omega = default_omega> +class jor +{ + typedef typename mtl::Collection<Matrix>::value_type Scalar; + typedef typename mtl::Collection<Matrix>::size_type size_type; + public: + /// Construct with constant references to matrix and RHS vector + jor(const Matrix& A) : A(A), dia_inv(num_rows(A)) + { + BOOST_STATIC_ASSERT((mtl::traits::is_row_major<Matrix>::value)); // No CCS + assert(num_rows(A) == num_cols(A)); // Matrix must be square + for (size_type i= 0; i < num_rows(A); ++i) { + Scalar a= A[i][i]; + MTL_THROW_IF(a == 0, mtl::missing_diagonal()); + dia_inv[i]= 1.0 / a; + } + } + + /// Apply JOR on vector \p x, i.e. \p x is changed + template <typename Vector, typename RHSVector> + Vector& operator()(Vector& x, const RHSVector& b) const + { + namespace tag= mtl::tag; using namespace mtl::traits; + using mtl::begin; using mtl::end; using std::swap; + + typedef typename range_generator<tag::row, Matrix>::type a_cur_type; + typedef typename range_generator<tag::nz, a_cur_type>::type a_icur_type; + typename col<Matrix>::type col_a(A); + typename const_value<Matrix>::type value_a(A); + + typedef typename mtl::Collection<Vector>::value_type value_type; + + static Vector x0(resource(x)); + a_cur_type ac= begin<tag::row>(A), aend= end<tag::row>(A); + for (unsigned i= 0; ac != aend; ++ac, ++i) { + value_type tmp= b[i]; + for (a_icur_type aic= begin<tag::nz>(ac), aiend= end<tag::nz>(ac); aic != aiend; ++aic) + if (col_a(*aic) != i) + tmp-= value_a(*aic) * x[col_a(*aic)]; + x0[i]= Omega::value * (dia_inv[i] * tmp) + (1. - Omega::value)*x0[i]; + } + swap(x0, x); + return x; + } + + private: + const Matrix& A; + mtl::dense_vector<Scalar> dia_inv; +}; + + +template <typename Value, typename Parameters, typename Omega> +class jor<mtl::mat::compressed2D<Value, Parameters> , Omega> +{ + typedef mtl::mat::compressed2D<Value, Parameters> Matrix; + typedef typename mtl::Collection<Matrix>::value_type Scalar; + typedef typename mtl::Collection<Matrix>::size_type size_type; + public: + /// Construct with constant references to matrix and RHS vector + jor(const Matrix& A) + : A(A), dia_inv(num_rows(A)), dia_pos(num_rows(A)) + { + BOOST_STATIC_ASSERT((mtl::traits::is_row_major<Matrix>::value)); // No CCS + assert(num_rows(A) == num_cols(A)); // Matrix must be square + for (size_type i= 0; i < num_rows(A); ++i) { + mtl::utilities::maybe<size_type> pos = A.indexer(A, i, i); + MTL_THROW_IF(!pos, mtl::missing_diagonal()); + dia_inv[i]= 1.0 / A.value_from_offset(pos); + dia_pos[i]= pos; + } + } + + /// Apply JOR on vector \p x, i.e. \p x is changed + template <typename Vector, typename RHSVector> + Vector& operator()(Vector& x, const RHSVector& b) const + { + typedef typename mtl::Collection<Vector>::value_type value_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + const size_type nr= num_rows(A); + static Vector x0(resource(x)); + size_type cj1= A.ref_major()[0]; + for (size_type i= 0; i < nr; ++i) { + value_type tmp= b[i]; + size_type cj0= cj1, cjm= dia_pos[i]; + cj1= A.ref_major()[i+1]; + for (; cj0 < cjm; cj0++) + tmp-= A.data[cj0] * x[A.ref_minor()[cj0]]; + for (size_type j= cjm+1; j < cj1; j++) + tmp-= A.data[j] * x[A.ref_minor()[j]]; + x0[i] = Omega::value * (dia_inv[i] * tmp) + (1. - Omega::value)*x0[i]; + } + swap(x0, x); + return x; + } + + + private: + const Matrix& A; + mtl::dense_vector<Scalar> dia_inv; + mtl::dense_vector<size_type> dia_pos; +}; + + +} // namespace itl + +#endif // ITL_JOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/smoother/relaxation_parameter.hpp b/install/MTL/include/boost/numeric/itl/smoother/relaxation_parameter.hpp new file mode 100644 index 00000000..800d194f --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/smoother/relaxation_parameter.hpp @@ -0,0 +1,28 @@ +/* + * Marcel Schiffel, 13.10.11 + * + * definition of default relaxation parameter for iterative solvers + */ + + +#ifndef MTL_ITL_RELAXATION_PARAMETER_HPP +#define MTL_ITL_RELAXATION_PARAMETER_HPP + + +namespace itl { + + +/** + * default relaxation parameter for iterative solvers + */ +struct default_omega +{ + static const double value; +}; + +const double default_omega::value= 2./3.; + +} /* namespace itl */ + +#endif + diff --git a/install/MTL/include/boost/numeric/itl/smoother/repeated.hpp b/install/MTL/include/boost/numeric/itl/smoother/repeated.hpp new file mode 100644 index 00000000..e569ad4d --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/smoother/repeated.hpp @@ -0,0 +1,50 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_REPEATED_INCLUDE +#define ITL_REPEATED_INCLUDE + +namespace itl { + +/// Repeat the smoother +template <typename Smoother, std::size_t N= 1> +class repeated +{ + public: + + typedef Smoother smoother_type; + + /// Construct with \p smoother + repeated(const Smoother& smoother) : smoother(smoother) {} + + /// Construct with \p smoother and number of repetitions \p n + template <typename Matrix> + repeated(const Matrix& A) : smoother(A) {} + + /// Apply smoother n times on vector \p x, i.e. \p x is changed + template <typename Vector, typename RHSVector> + Vector& operator()(Vector& x, const RHSVector& b) const + { + for (std::size_t i= 0; i < N; i++) + smoother(x, b); + return x; + } + + private: + Smoother smoother; + std::size_t n; +}; + + +} // namespace itl + +#endif // ITL_REPEATED_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/smoother/sor.hpp b/install/MTL/include/boost/numeric/itl/smoother/sor.hpp new file mode 100644 index 00000000..f8d45826 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/smoother/sor.hpp @@ -0,0 +1,138 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_SOR_INCLUDE +#define ITL_SOR_INCLUDE + +#include <boost/assert.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> + +#include "./relaxation_parameter.hpp" + +namespace itl { + +/// Gauss-Seidel smoother with relaxation +/** Constructor takes references to a matrix and a right-hand side vector. + operator() is applied on a vector and changes it in place. + Matrix must be square, stored row-major and free of zero entries in the diagonal. + Vectors b and x must have the same number of rows as A. +**/ +template <typename Matrix, typename Omega = default_omega> +class sor +{ + typedef typename mtl::Collection<Matrix>::value_type Scalar; + typedef typename mtl::Collection<Matrix>::size_type size_type; + + public: + /// Construct with constant references to matrix and RHS vector + sor(const Matrix& A) : A(A), dia_inv(num_rows(A)) + { + BOOST_STATIC_ASSERT((mtl::traits::is_row_major<Matrix>::value)); // No CCS + assert(num_rows(A) == num_cols(A)); // Matrix must be square + for (size_type i= 0; i < num_rows(A); ++i) { + Scalar a= A[i][i]; + MTL_THROW_IF(a == 0, mtl::missing_diagonal()); + dia_inv[i]= 1.0 / a; + } + } + + /// Apply SOR on vector \p x, i.e. \p x is changed + template <typename Vector, typename RHSVector> + Vector& operator()(Vector& x, const RHSVector& b) const + { + namespace tag= mtl::tag; using namespace mtl::traits; + using mtl::begin; using mtl::end; + + typedef typename range_generator<tag::row, Matrix>::type a_cur_type; + typedef typename range_generator<tag::nz, a_cur_type>::type a_icur_type; + typename col<Matrix>::type col_a(A); + typename const_value<Matrix>::type value_a(A); + + typedef typename mtl::Collection<Vector>::value_type value_type; + + a_cur_type ac= begin<tag::row>(A), aend= end<tag::row>(A); + for (unsigned i= 0; ac != aend; ++ac, ++i) { + value_type tmp= b[i]; + for (a_icur_type aic= begin<tag::nz>(ac), aiend= end<tag::nz>(ac); aic != aiend; ++aic) + if (col_a(*aic) != i) + tmp-= value_a(*aic) * x[col_a(*aic)]; + x[i] = Omega::value * (dia_inv[i] * tmp) + (1. - Omega::value)*x[i]; + } + return x; + } + + private: + const Matrix& A; + mtl::dense_vector<Scalar> dia_inv; +}; + + +template <typename Value, typename Parameters, typename Omega> +class sor<mtl::mat::compressed2D<Value, Parameters> , Omega> +{ + typedef mtl::mat::compressed2D<Value, Parameters> Matrix; + typedef typename mtl::Collection<Matrix>::value_type Scalar; + typedef typename mtl::Collection<Matrix>::size_type size_type; + + public: + /// Construct with constant references to matrix and RHS vector + sor(const Matrix& A) + : A(A), dia_inv(num_rows(A)), dia_pos(num_rows(A)) + { + BOOST_STATIC_ASSERT((mtl::traits::is_row_major<Matrix>::value)); // No CCS + assert(num_rows(A) == num_cols(A)); // Matrix must be square + for (size_type i= 0; i < num_rows(A); ++i) { + mtl::utilities::maybe<size_type> pos = A.indexer(A, i, i); + MTL_THROW_IF(!pos, mtl::missing_diagonal()); + dia_inv[i]= 1.0 / A.value_from_offset(pos); + dia_pos[i]= pos; + } + } + + /// Apply SOR on vector \p x, i.e. \p x is changed + template <typename Vector, typename RHSVector> + Vector& operator()(Vector& x, const RHSVector& b) const + { + typedef typename mtl::Collection<Vector>::value_type value_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + const size_type nr= num_rows(A); + size_type cj1= A.ref_major()[0]; + for (size_type i= 0; i < nr; ++i) { + value_type tmp= b[i]; + size_type cj0= cj1, cjm= dia_pos[i]; + cj1= A.ref_major()[i+1]; + for (; cj0 < cjm; cj0++) + tmp-= A.data[cj0] * x[A.ref_minor()[cj0]]; + for (size_type j= cjm+1; j < cj1; j++) + tmp-= A.data[j] * x[A.ref_minor()[j]]; + x[i]= Omega::value * (dia_inv[i] * tmp) + (1. - Omega::value)*x[i]; + } + return x; + } + + + private: + const Matrix& A; + mtl::dense_vector<Scalar> dia_inv; + mtl::dense_vector<size_type> dia_pos; +}; + + +} // namespace itl + +#endif // ITL_GAUSS_SEIDEL_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/stepper/armijo.hpp b/install/MTL/include/boost/numeric/itl/stepper/armijo.hpp new file mode 100644 index 00000000..8f4aa41b --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/stepper/armijo.hpp @@ -0,0 +1,53 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling, Cornelius Steinhardt and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_ARMIJO_INCLUDE +#define ITL_ARMIJO_INCLUDE + +namespace itl { + +/// Step size control by Armijo +/** + **/ +template <typename Value= double> +class armijo +{ + public: + typedef Value value_type; + + // Defaults from Prof. Fischer's lecture + armijo(Value delta= 0.5, Value gamma= 0.5, Value beta1= 0.25, Value beta2= 0.5) + : delta(delta), gamma(gamma), beta1(beta1), beta((beta1 + beta2) / 2.0) {} + + /// + template <typename Vector, typename F, typename Grad> + typename mtl::Collection<Vector>::value_type + operator() (const Vector& x, const Vector& d, F f, Grad grad_f) const + { + // Star's step size + typename mtl::Collection<Vector>::value_type alpha= -gamma * dot(grad_f(x), d) / dot(d, d); + Vector x_k(x + alpha * d); + + while (f(x_k) > f(x) + (beta1 * alpha) * dot(grad_f(x), d)) { + alpha*= beta; + x_k= x+ alpha * d; + } + return alpha; + } + private: + Value delta, gamma, beta1, beta; +}; + + +} // namespace itl + +#endif // ITL_ARMIJO_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/stepper/wolf.hpp b/install/MTL/include/boost/numeric/itl/stepper/wolf.hpp new file mode 100644 index 00000000..fedf04f3 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/stepper/wolf.hpp @@ -0,0 +1,55 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling, Cornelius Steinhardt and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_WOLF_INCLUDE +#define ITL_WOLF_INCLUDE + +namespace itl { + +/// Step size control by Wolf +/** + **/ +template <typename Value= double> +class wolf +{ + public: + typedef Value value_type; + + // Defaults from Prof. Fischer's lecture + wolf(Value delta= 0.5, Value gamma= 0.5, Value beta1= 0.25, Value beta2= 0.5) + : delta(delta), gamma(gamma), beta1(beta1), beta2(beta2) {} + + /// + template <typename Vector, typename F, typename Grad> + typename mtl::Collection<Vector>::value_type + operator() (const Vector& x, const Vector& d, F f, Grad grad_f) const + { + // Star's step size + typename mtl::Collection<Vector>::value_type alpha= -gamma * dot(grad_f(x), d) / dot(d, d); + Vector x_k(x + alpha * d); + + Value beta= (beta1 + beta2) / 2; + while (f(x_k) > f(x) + (beta1 * alpha) * dot(grad_f(x), d) + && dot(grad_f(x_k), d) < beta2 * dot(grad_f(x), d)) { + alpha*= beta; + x_k= x+ alpha * d; + } + return alpha; + } + private: + Value delta, gamma, beta1, beta2; +}; + + +} // namespace itl + +#endif // ITL_WOLF_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/updater/bfgs.hpp b/install/MTL/include/boost/numeric/itl/updater/bfgs.hpp new file mode 100644 index 00000000..dde51839 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/updater/bfgs.hpp @@ -0,0 +1,44 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_BFGS_INCLUDE +#define ITL_BFGS_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/itl/utility/exception.hpp> + +namespace itl { + +/// Update of Hessian matrix for e.g. Quasi-Newton by Broyden, Fletcher, Goldfarb, and Shanno +struct bfgs +{ + /// \f$ H_{k+1}=B_{k+1}^{-1}=(I-\frac{y_k\cdot s_k^T}{y_k^T\cdot s_k})^T\cdot H_k \cdot (I-\frac{y_k\cdot s_k^T}{y_k^T\cdot s_k}) + \frac{s_k\cdot s_k^T}{y_k^T\cdot s_k}\f$ + template <typename Matrix, typename Vector> + void operator() (Matrix& H, const Vector& y, const Vector& s) + { + typedef typename mtl::Collection<Vector>::value_type value_type; + assert(num_rows(H) == num_cols(H)); + + value_type gamma= 1 / dot(y,s); + MTL_THROW_IF(gamma == 0.0, unexpected_orthogonality()); + Matrix A(math::one(H) - gamma * s * trans(y)), + H2(A * H * trans(A) + gamma * s * trans(s)); + swap(H2, H); // faster than H= H2 + } +}; + + + +} // namespace itl + +#endif // ITL_BFGS_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/updater/broyden.hpp b/install/MTL/include/boost/numeric/itl/updater/broyden.hpp new file mode 100644 index 00000000..40b34703 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/updater/broyden.hpp @@ -0,0 +1,45 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_BROYDEN_INCLUDE +#define ITL_BROYDEN_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/itl/utility/exception.hpp> + +namespace itl { + +/// Update of Hessian matrix for e.g. Quasi-Newton by Broyden formula +struct broyden +{ + /// \f$ H_{k+1}=B_{k+1}^{-1}=H_k+\frac{(s_k-H_k\cdot y_k)\cdot y_k^T\cdot H_k}{y_k^T\cdot H_k\cdot s_k} \f$ + template <typename Matrix, typename Vector> + void operator() (Matrix& H, const Vector& y, const Vector& s) + { + typedef typename mtl::Collection<Vector>::value_type value_type; + assert(num_rows(H) == num_cols(H)); + + Vector h(H * y), d(s - h); + value_type gamma= 1 / dot(y, h); + MTL_THROW_IF(gamma == 0.0, unexpected_orthogonality()); + Matrix A(gamma * d * trans(y)), + H2(H + A * H); + swap(H2, H); // faster than H= H2 + } +}; + + + +} // namespace itl + +#endif // ITL_BROYDEN_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/updater/dfp.hpp b/install/MTL/include/boost/numeric/itl/updater/dfp.hpp new file mode 100644 index 00000000..87150111 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/updater/dfp.hpp @@ -0,0 +1,46 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_DFP_INCLUDE +#define ITL_DFP_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/itl/utility/exception.hpp> + +namespace itl { + +/// Update of Hessian matrix for e.g. Quasi-Newton by Davidon, Fletcher and Powell formula +struct dfp +{ + /// \f$ H_{k+1}=B_{k+1}^{-1}=H_k+\frac{s_k\cdot s_k^T}{y_k^T\cdot s_k}- \frac{H_k\cdot y_k\cdot y_k^T\cdot H_k^T}{y_k^TH_k\cdot y_k}\f$ + template <typename Matrix, typename Vector> + void operator() (Matrix& H, const Vector& y, const Vector& s) + { + typedef typename mtl::Collection<Vector>::value_type value_type; + assert(num_rows(H) == num_cols(H)); + + Vector h(H*y); + value_type gamma= 1 / dot(y,s), alpha= 1 / dot(y,h); + MTL_THROW_IF(gamma == 0.0, unexpected_orthogonality()); + MTL_THROW_IF(alpha == 0.0, unexpected_orthogonality()); + Matrix A(alpha * y * trans(y)), + H2(H - H * A * H + gamma * s * trans(s)); + swap(H2, H); // faster than H= H2 + } +}; + + + +} // namespace itl + +#endif // ITL_DFP_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/updater/psb.hpp b/install/MTL/include/boost/numeric/itl/updater/psb.hpp new file mode 100644 index 00000000..304da779 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/updater/psb.hpp @@ -0,0 +1,44 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_PSB_INCLUDE +#define ITL_PSB_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/itl/utility/exception.hpp> + +namespace itl { + +/// Update of Hessian matrix for e.g. Quasi-Newton by Powell's symmetric Broyden formula +struct psb +{ + /// \f$ H_{k+1}=B_{k+1}^{-1}=H_k+\frac{(y_k-H_k\cdot s_k)s_k^T+s_k(y_k-H_k\cdot s_k)^T}{s_k^T\cdot s_k}-\frac{(y_k-H_k\cdot s_k)^T\cdot s_k}{(s_k^ts_k)^2}s_k\cdot s_k^T \f$ + template <typename Matrix, typename Vector> + void operator() (Matrix& H, const Vector& y, const Vector& s) + { + typedef typename mtl::Collection<Vector>::value_type value_type; + assert(num_rows(H) == num_cols(H)); + Vector a(s - H * y); + value_type gamma= 1 / dot (y, y); + MTL_THROW_IF(gamma == 0.0, unexpected_orthogonality()); + + H+= gamma * a * trans(y) + gamma * y * trans(a) - dot(a, y) * gamma * gamma * y * trans(y); + } +}; + + + +} // namespace itl + +#endif // ITL_PSB_INCLUDE + diff --git a/install/MTL/include/boost/numeric/itl/updater/sr1.hpp b/install/MTL/include/boost/numeric/itl/updater/sr1.hpp new file mode 100644 index 00000000..a8caaace --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/updater/sr1.hpp @@ -0,0 +1,40 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_SR1_INCLUDE +#define ITL_SR1_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/itl/utility/exception.hpp> + +namespace itl { + +/// Update of Hessian matrix for e.g. Quasi-Newton by SR1 formulas +struct sr1 +{ + /// \f$ H_{k+1}=B_{k+1}^{-1}=H_k+\frac{(s_k-H_k\cdot y_k)(s_k-H_k\cdot y_k)^T}{(s_k-H_k\cdot y_k)^T\cdot y_k} \f$ + template <typename Matrix, typename Vector> + void operator() (Matrix& H, const Vector& y, const Vector& s) + { + assert(num_rows(H) == num_cols(H)); + Vector d(s - H * y); + MTL_THROW_IF(dot(d, y) == 0.0, unexpected_orthogonality()); + H+= 1 / dot(d, y) * d * trans(d); + } +}; + + + +} // namespace itl + +#endif // ITL_SR1_INCLUDE diff --git a/install/MTL/include/boost/numeric/itl/utility/exception.hpp b/install/MTL/include/boost/numeric/itl/utility/exception.hpp new file mode 100644 index 00000000..4ce324c1 --- /dev/null +++ b/install/MTL/include/boost/numeric/itl/utility/exception.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef ITL_EXCEPTION_INCLUDE +#define ITL_EXCEPTION_INCLUDE + +#include <boost/numeric/mtl/utility/exception.hpp> + +namespace itl { + +/// Exception for iterative solvers that exhausted the search space, i.e. search direction(s) parallel to already visited Krylov subspace +/** Either your matrix is too badly conditioned or your termination criterion is too strict for the used arithmetic (maybe use Gnu Multi-precision library). **/ +struct search_space_exhaustion + : mtl::runtime_error +{ + /// Error can be specified more precisely in constructor if desired + explicit search_space_exhaustion(const char *s= "Iterative solvers that exhausted the search space, i.e. search direction(s) parallel to already visited Krylov subspace") + : mtl::runtime_error(s) {} +}; + +/// Vectors unexpectedly become orthogonal, special case of search_space_exhaustion. +struct unexpected_orthogonality : search_space_exhaustion {}; + +} // namespace itl + +#endif // ITL_EXCEPTION_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/accumulate.hpp b/install/MTL/include/boost/numeric/linear_algebra/accumulate.hpp new file mode 100644 index 00000000..05572bd0 --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/accumulate.hpp @@ -0,0 +1,66 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + + +#ifndef MATH_ACCUMULATE_INCLUDE +#define MATH_ACCUMULATE_INCLUDE + +#include <concepts> + +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/linear_algebra/new_concepts.hpp> + +namespace math { + +// Dispatching between simple and unrolled version +template <std::InputIterator Iter, std::CopyConstructible Value, typename Op> + requires std::Callable2<Op, Value, Value> + && std::CopyAssignable<Value, std::Callable2<Op, Value, Value>::result_type> +Value inline accumulate(Iter first, Iter last, Value init, Op op) +{ + // std::cout << "Simple accumulate\n"; + for (; first != last; ++first) + init= op(init, Value(*first)); + return init; +} + + +template <std::RandomAccessIterator Iter, std::CopyConstructible Value, typename Op> + requires std::Callable2<Op, Value, Value> + && std::CopyAssignable<Value, std::Callable2<Op, Value, Value>::result_type> + && Commutative<Op, Value> + && Monoid<Op, Value> + && std::Convertible<Monoid<Op, Value>::identity_result_type, Value> +Value inline accumulate(Iter first, Iter last, Value init, Op op) +{ + // std::cout << "Unrolled accumulate\n"; + typedef typename std::RandomAccessIterator<Iter>::difference_type difference_type; + Value t0= identity(op, init), t1= identity(op, init), + t2= identity(op, init), t3= init; + difference_type size= last - first, bsize= size >> 2 << 2, i; + + for (i= 0; i < bsize; i+= 4) { + t0= op(t0, Value(first[i])); + t1= op(t1, Value(first[i+1])); + t2= op(t2, Value(first[i+2])); + t3= op(t3, Value(first[i+3])); + } + for (; i < size; i++) + t0= op(t0, Value(first[i])); + + t0= op(t0, t1), t2= op(t2, t3), t0= op(t0, t2); + return t0; +} + +} // namespace math + +#endif // MATH_ACCUMULATE_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/algebraic_concepts.hpp b/install/MTL/include/boost/numeric/linear_algebra/algebraic_concepts.hpp new file mode 100644 index 00000000..6b881701 --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/algebraic_concepts.hpp @@ -0,0 +1,521 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef LA_ALGEBRAIC_CONCEPTS_DOC_INCLUDE +#define LA_ALGEBRAIC_CONCEPTS_DOC_INCLUDE + +#ifdef __GXX_CONCEPTS__ +# include <concepts> +#else +# include <boost/numeric/linear_algebra/pseudo_concept.hpp> +#endif + +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/linear_algebra/inverse.hpp> + +/// Namespace for purely algebraic concepts +namespace algebra { + +/** @addtogroup Concepts + * @{ + */ + +#ifndef __GXX_CONCEPTS__ + //! Concept Commutative + /*! + \param Operation A functor implementing a binary operation + \param Element The type upon the binary operation is defined + + \par Notation: + <table summary="notation"> + <tr> + <td>op</td> + <td>Object of type Operation</td> + </tr> + <tr> + <td>x, y</td> + <td>Objects of type Element</td> + </tr> + </table> + \invariant + <table summary="invariants"> + <tr> + <td>Commutativity</td> + <td>op(x, y) == op(y, x)</td> + </tr> + </table> + */ + template <typename Operation, typename Element> + struct Commutative + {}; +#else + concept Commutative<typename Operation, typename Element> + { + axiom Commutativity(Operation op, Element x, Element y) + { + op(x, y) == op(y, x); + } + }; +#endif + + +#ifndef __GXX_CONCEPTS__ + //! Concept Associative + /*! + \param Operation A functor implementing a binary operation + \param Element The type upon the binary operation is defined + + \par Notation: + <table summary="notation"> + <tr> + <td>op</td> + <td>Object of type Operation</td> + </tr> + <tr> + <td>x, y, z</td> + <td>Objects of type Element</td> + </tr> + </table> + \invariant + <table summary="invariants"> + <tr> + <td>Associativity</td> + <td>op(x, op(y, z)) == op(op(x, y), z)</td> + </tr> + </table> + */ + template <typename Operation, typename Element> + struct Associative + {}; +#else + concept Associative<typename Operation, typename Element> + { + axiom Associativity(Operation op, Element x, Element y, Element z) + { + op(x, op(y, z)) == op(op(x, y), z); + } + }; +#endif + + +#ifndef __GXX_CONCEPTS__ + //! Concept SemiGroup + /*! + \param Operation A functor implementing a binary operation + \param Element The type upon the binary operation is defined + + \note + -# The algebraic concept SemiGroup only requires associativity and is identical with the concept Associative. + */ + template <typename Operation, typename Element> + struct SemiGroup + : Associative<Operation, Element> + {}; +#else + auto concept SemiGroup<typename Operation, typename Element> + : Associative<Operation, Element> + {}; +#endif + + +#ifndef __GXX_CONCEPTS__ + //! Concept Monoid + /*! + \param Operation A functor implementing a binary operation + \param Element The type upon the binary operation is defined + + \par Refinement of: + - SemiGroup + \par Notation: + <table summary="notation"> + <tr> + <td>op</td> + <td>Object of type Operation</td> + </tr> + <tr> + <td>x</td> + <td>Object of type Element</td> + </tr> + </table> + \invariant + <table summary="invariants"> + <tr> + <td>Neutrality from right</td> + <td>op( x, identity(op, x) ) == x</td> + </tr> + <tr> + <td>Neutrality from left</td> + <td>op( identity(op, x), x ) == x</td> + </tr> + </table> + */ + template <typename Operation, typename Element> + struct Monoid + : SemiGroup<Operation, Element> + { + /// Associated type; if not defined in concept_map automatically detected as result of identity + typedef associated_type identity_result_type; + identity_result_type identity(Operation, Element); ///< Identity element of Operation + }; +#else + concept Monoid<typename Operation, typename Element> + : SemiGroup<Operation, Element> + { + typename identity_result_type; + identity_result_type identity(Operation, Element); + + axiom Neutrality(Operation op, Element x) + { + op( x, identity(op, x) ) == x; + op( identity(op, x), x ) == x; + } + }; +#endif + +#ifdef __GXX_CONCEPTS__ + auto concept Inversion<typename Operation, typename Element> + { + typename inverse_result_type; + inverse_result_type inverse(Operation, Element); + + }; +#else + //! Concept Inversion + /*! + \param Operation A functor implementing a binary operation + \param Element The type upon the binary operation is defined + + \par Associated Types: + - inverse_result_type + \par Valid Expressions: + - inverse(op, x); + */ + template <typename Operation, typename Element> + struct Inversion + { + /// Associated type; if not defined in concept_map automatically detected as result of inverse + typedef associated_type inverse_result_type; + + /// Returns inverse of \p x regarding operation \p op + inverse_result_type inverse(Operation op, Element x); + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept Group<typename Operation, typename Element> + : Monoid<Operation, Element>, Inversion<Operation, Element> + { + axiom Inversion(Operation op, Element x) + { + op( x, inverse(op, x) ) == identity(op, x); + op( inverse(op, x), x ) == identity(op, x); + } + }; +#else + //! Concept Group + /*! + \param Operation A functor implementing a binary operation + \param Element The type upon the binary operation is defined + + \par Refinement of: + - Monoid + - Inversion + \par Notation: + <table summary="notation"> + <tr> + <td>op</td> + <td>Object of type Operation</td> + </tr> + <tr> + <td>x</td> + <td>Object of type Element</td> + </tr> + </table> + \invariant + <table summary="invariants"> + <tr> + <td>Inverse from right</td> + <td>op( x, inverse(op, x) ) == identity(op, x)</td> + </tr> + <tr> + <td>Inverse from left</td> + <td>op( inverse(op, x), x ) == identity(op, x)</td> + </tr> + </table> + */ + template <typename Operation, typename Element> + struct Group + : Monoid<Operation, Element>, + Inversion<Operation, Element> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + auto concept AbelianGroup<typename Operation, typename Element> + : Group<Operation, Element>, Commutative<Operation, Element> + {}; +#else + //! Concept AbelianGroup + /*! + \param Operation A functor implementing a binary operation + \param Element The type upon the binary operation is defined + + \par Refinement of: + - Group + - Commutative + */ + template <typename Operation, typename Element> + struct AbelianGroup + : Group<Operation, Element>, + Commutative<Operation, Element> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept Distributive<typename AddOp, typename MultOp, typename Element> + { + axiom Distributivity(AddOp add, MultOp mult, Element x, Element y, Element z) + { + // From left + mult(x, add(y, z)) == add(mult(x, y), mult(x, z)); + // z right + mult(add(x, y), z) == add(mult(x, z), mult(y, z)); + } + }; +#else + //! Concept Distributive + /*! + \param AddOp A functor implementing a binary operation representing addition + \param MultOp A functor implementing a binary operation representing multiplication + \param Element The type upon the binary operation is defined + + \par Notation: + <table summary="notation"> + <tr> + <td>add</td> + <td>Object of type AddOp</td> + </tr> + <tr> + <td>mult</td> + <td>Object of type Multop</td> + </tr> + <tr> + <td>x, y, z</td> + <td>Objects of type Element</td> + </tr> + </table> + \invariant + <table summary="invariants"> + <tr> + <td>Distributivity from left</td> + <td>mult(x, add(y, z)) == add(mult(x, y), mult(x, z))</td> + </tr> + <tr> + <td>Distributivity from right</td> + <td>mult(add(x, y), z) == add(mult(x, z), mult(y, z))</td> + </tr> + </table> + */ + template <typename AddOp, typename MultOp, typename Element> + struct Distributive + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + auto concept Ring<typename AddOp, typename MultOp, typename Element> + : AbelianGroup<AddOp, Element>, + SemiGroup<MultOp, Element>, + Distributive<AddOp, MultOp, Element> + {}; +#else + //! Concept Ring + /*! + \param AddOp A functor implementing a binary operation representing addition + \param MultOp A functor implementing a binary operation representing multiplication + \param Element The type upon the binary operation is defined + + \par Refinement of: + - AbelianGroup <MultOp, Element> + - SemiGroup <MultOp, Element> + - Distributive <AddOp, MultOp, Element> + */ + template <typename AddOp, typename MultOp, typename Element> + struct Ring + : AbelianGroup<AddOp, Element>, + SemiGroup<MultOp, Element>, + Distributive<AddOp, MultOp, Element> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + auto concept RingWithIdentity<typename AddOp, typename MultOp, typename Element> + : Ring<AddOp, MultOp, Element>, + Monoid<MultOp, Element> + {}; +#else + //! Concept RingWithIdentity + /*! + \param AddOp A functor implementing a binary operation representing addition + \param MultOp A functor implementing a binary operation representing multiplication + \param Element The type upon the binary operation is defined + + \par Refinement of: + - Ring <AddOp, MultOp, Element> + - Monoid <MultOp, Element> + */ + template <typename AddOp, typename MultOp, typename Element> + struct RingWithIdentity + : Ring<AddOp, MultOp, Element>, + Monoid<MultOp, Element> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept DivisionRing<typename AddOp, typename MultOp, typename Element> + : RingWithIdentity<AddOp, MultOp, Element>, + Inversion<MultOp, Element> + { + // 0 != 1, otherwise trivial + axiom ZeroIsDifferentFromOne(AddOp add, MultOp mult, Element x) + { + identity(add, x) != identity(mult, x); + } + + // Non-zero divisibility from left and from right + axiom NonZeroDivisibility(AddOp add, MultOp mult, Element x) + { + if (x != identity(add, x)) + mult(inverse(mult, x), x) == identity(mult, x); + if (x != identity(add, x)) + mult(x, inverse(mult, x)) == identity(mult, x); + } + }; +#else + //! Concept DivisionRing + /*! + \param AddOp A functor implementing a binary operation representing addition + \param MultOp A functor implementing a binary operation representing multiplication + \param Element The type upon the binary operation is defined + + \par Refinement of: + - RingWithIdentity <AddOp, MultOp, Element> + - Inversion <MultOp, Element> + + \par Notation: + <table summary="notation"> + <tr> + <td>add</td> + <td>Object of type AddOp</td> + </tr> + <tr> + <td>mult</td> + <td>Object of type Multop</td> + </tr> + <tr> + <td>x, y, z</td> + <td>Objects of type Element</td> + </tr> + </table> + + \invariant + <table summary="invariants"> + <tr> + <td>Non-zero divisibility from left</td> + <td>mult(inverse(mult, x), x) == identity(mult, x)</td> + <td>if x != identity(add, x)</td> + </tr> + <tr> + <td>Non-zero divisibility from right</td> + <td>mult(x, inverse(mult, x)) == identity(mult, x)</td> + <td>if x != identity(add, x)</td> + </tr> + <tr> + <td>Zero is different from one</td> + <td>identity(add, x) != identity(mult, x)</td> + <td></td> + </tr> + </table> + + \note + -# Zero and one can be theoretically identical in a DivisionRing. However, + this implies that there is only one element x in the Ring with x + x = x and + x * x = x (which is actually even a Field). + Because this structure has no practical value we exclude it from + consideration. + */ + template <typename AddOp, typename MultOp, typename Element> + struct DivisionRing + : RingWithIdentity<AddOp, MultOp, Element>, + Inversion<MultOp, Element> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + // SkewField is defined as synonym for DivisionRing + auto concept SkewField<typename AddOp, typename MultOp, typename Element> + : DivisionRing<AddOp, MultOp, Element> + {}; +#else + //! Concept SkewField + /*! + \param AddOp A functor implementing a binary operation representing addition + \param MultOp A functor implementing a binary operation representing multiplication + \param Element The type upon the binary operation is defined + + \par Refinement of: + - DivisionRing <AddOp, MultOp, Element> + \note + - Because the refinement of DivisionRing to SkewField is automatic the two concepts + are identical. + */ + template <typename AddOp, typename MultOp, typename Element> + struct SkewField + : DivisionRing<AddOp, MultOp, Element> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + auto concept Field<typename AddOp, typename MultOp, typename Element> + : DivisionRing<AddOp, MultOp, Element>, + Commutative<MultOp, Element> + {}; +#else + //! Concept Field + /*! + \param AddOp A functor implementing a binary operation representing addition + \param MultOp A functor implementing a binary operation representing multiplication + \param Element The type upon the binary operation is defined + + \par Refinement of: + - DivisionRing <AddOp, MultOp, Element> + - Commutative <MultOp, Element> + */ + template <typename AddOp, typename MultOp, typename Element> + struct Field + : DivisionRing<AddOp, MultOp, Element>, + Commutative<MultOp, Element> + {}; +#endif + +/*@}*/ // end of group Concepts + +} // algebra + +#endif // LA_ALGEBRAIC_CONCEPTS_DOC_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/concept_maps.hpp b/install/MTL/include/boost/numeric/linear_algebra/concept_maps.hpp new file mode 100644 index 00000000..30c18049 --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/concept_maps.hpp @@ -0,0 +1,87 @@ +// $COPYRIGHT$ + +#ifndef MATH_CONCEPT_MAPS_INCLUDE +#define MATH_CONCEPT_MAPS_INCLUDE + +#include <boost/numeric/linear_algebra/intrinsic_concept_maps.hpp> +#include <boost/numeric/linear_algebra/new_concepts.hpp> + + +namespace math { + +#if 0 // Why this doesn't work??? + template <typename T> + requires IntrinsicUnsignedIntegral<T> + concept_map UnsignedIntegral<T> {} + + template <typename T> + requires IntrinsicSignedIntegral<T> + concept_map SignedIntegral<T> {} +#endif + + concept_map UnsignedIntegral<unsigned int> {} + concept_map AdditiveMonoid<unsigned int> {} + + concept_map SignedIntegral<int> {} + concept_map AdditiveSemiGroup<int> {} + + concept_map Commutative< add<int>, int > {} + concept_map Monoid< add<int>, int > {} + concept_map AbelianGroup< add<int>, int > {} + + concept_map Commutative< mult<int>, int > {} + concept_map Monoid< mult<int>, int > {} + concept_map PIMonoid< mult<int>, int > {} + + concept_map Commutative< min<int>, int > {} + concept_map Monoid< min<int>, int > {} + + concept_map Commutative< max<int>, int > {} + //concept_map Monoid< max<int>, int > {} + + + concept_map Commutative< add<float>, float > {} + concept_map Monoid< add<float>, float > {} + concept_map AbelianGroup< add<float>, float > {} + + concept_map Commutative< mult<float>, float > {} + concept_map Monoid< mult<float>, float > {} + concept_map PIMonoid< mult<float>, float > {} + + concept_map AdditiveMonoid< float > {} + // concept_map AdditiveAbelianGroup< float > {} + + // concept_map OperatorField<float> {} + + concept_map Commutative< min<float>, float > {} + concept_map Monoid< min<float>, float > {} + + concept_map Commutative< max<float>, float > {} + concept_map Monoid< max<float>, float > {} + + + + concept_map Commutative< add<double>, double > {} + concept_map Monoid< add<double>, double > {} + concept_map AbelianGroup< add<double>, double > {} + + concept_map Commutative< mult<double>, double > {} + concept_map Monoid< mult<double>, double > {} + concept_map PIMonoid< mult<double>, double > {} + + concept_map AdditiveMonoid< double > {} + // concept_map AdditiveAbelianGroup< double > {} + + // concept_map OperatorField<double> {} + + concept_map Commutative< min<double>, double > {} + concept_map Monoid< min<double>, double > {} + + concept_map Commutative< max<double>, double > {} + concept_map Monoid< max<double>, double > {} + + + +} // namespace math + +#endif // MATH_CONCEPT_MAPS_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/concepts.hpp b/install/MTL/include/boost/numeric/linear_algebra/concepts.hpp new file mode 100644 index 00000000..8fc6d529 --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/concepts.hpp @@ -0,0 +1,602 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_NEW_ALGEBRAIC_CONCEPTS_INCLUDE +#define MTL_NEW_ALGEBRAIC_CONCEPTS_INCLUDE + +#include <concepts> +#include <boost/numeric/linear_algebra/intrinsic_concept_maps.hpp> +#include <boost/numeric/linear_algebra/operators.hpp> + + +namespace math { + +concept Commutative<typename Operation, typename Element> + : std::Callable2<Op, Element, Element> +{ + axiom Commutativity(Operation op, Element x, Element y) + { + op(x, y) == op(y, x); + } +}; + + +concept SemiGroup<typename Operation, typename Element> + : std::Callable2<Op, Element, Element> +{ + axiom Associativity(Operation op, Element x, Element y, Element z) + { + op(x, op(y, z)) == op(op(x, y), z); + } +}; + + +concept Monoid<typename Operation, typename Element> + : SemiGroup<Operation, Element> +{ + typename identity_result_type; + identity_result_type identity(Operation, Element); + + axiom Neutrality(Operation op, Element x) + { + op( x, identity(op, x) ) == x; + op( identity(op, x), x ) == x; + } +}; + + +auto concept Inversion<typename Operation, typename Element> +{ + typename result_type; + result_type inverse(Operation, Element); + +}; + + +concept PIMonoid<typename Operation, typename Element> + : Monoid<Operation, Element>, + Inversion<Operation, Element> +{ + bool is_invertible(Operation, Element); + + requires std::Convertible<Inversion<Operation, Element>::result_type, Element>; + + axiom Invertibility(Operation op, Element x) + { + // Only for invertible elements: + if (is_invertible(op, x)) + op( x, inverse(op, x) ) == identity(op, x); + if ( is_invertible(op, x) ) + op( inverse(op, x), x ) == identity(op, x); + } +} + +#if 0 + // Alternative approach to convert the result of inversion to Element + // Unfortunately, this doesn't compile + template <typename Operation, typename Element> + requires PIMonoid<Operation, Element> + concept_map PIMonoid<Operation, Inversion<Operation, Element>::result_type> {} +#endif + + +concept Group<typename Operation, typename Element> + : PIMonoid<Operation, Element> +{ + bool is_invertible(Operation, Element) { return true; } + + // Just in case somebody redefines is_invertible + axiom AlwaysInvertible(Operation op, Element x) + { + is_invertible(op, x); + } + + // In fact this is implied by AlwaysInvertible and inherited Invertibility axiom + // Maybe remove + axiom GlobalInvertibility(Operation op, Element x) + { + op( x, inverse(op, x) ) == identity(op, x); + op( inverse(op, x), x ) == identity(op, x); + } +}; + + +auto concept AbelianGroup<typename Operation, typename Element> + : Group<Operation, Element>, Commutative<Operation, Element> +{}; + + +// ======================= +// Operator-based concepts +// ======================= + + +concept Additive<typename Element> + : std::HasPlus<Element> +{ + typename plus_assign_result_type; + plus_assign_result_type operator+=(Element& x, Element y) + { + x= x + y; return x; + } + + requires std::Convertible<plus_assign_result_type, Element&>; + + // Do we need the opposite conversion too? + // This line produces a compiler error + // requires std::Convertible<add<Element>::result_type, + // std::HasPlus<Element>::result_type>; + + axiom Consistency(add<Element> op, Element x, Element y) + { + op(x, y) == x + y; + op(x, y) == (x += y, x); + } +} + + +auto concept AdditiveCommutative<typename Element> + : Additive<Element>, + Commutative< add<Element>, Element > +{} + + +auto concept AdditiveSemiGroup<typename Element> + : Additive<Element>, + SemiGroup< add<Element>, Element > +{} + + +concept AdditiveMonoid<typename Element> + : AdditiveSemiGroup<Element>, + Monoid< add<Element>, Element > +{ + Element zero(Element x) + { + return identity(add<Element>(), x); + } + + // If we don't use the default definition + axiom IdentityConsistency (add<Element> op, Element x) + { + zero(x) == identity(op, x); + } +}; + +#ifndef CONCEPTS_WITHOUT_OVERLOADED_REQUIREMENTS // Uncompilable due to error in compiler +concept AdditivePIMonoid<typename Element> + : std::HasMinus<Element>, AdditiveMonoid<Element>, + PIMonoid< add<Element>, Element > +{ + typename minus_assign_result_type; + minus_assign_result_type operator-=(Element& x, Element y) + { + x= x - y; return x; + } + + requires std::Convertible<minus_assign_result_type, Element&>; + + typename unary_result_type; + unary_result_type operator-(Element x) + { + return zero(x) - x; + } + + axiom InverseConsistency(add<Element> op, Element x, Element y) + { + // consistency between additive and functor concept + if ( is_invertible(op, y) ) + op(x, inverse(op, y)) == x - y; + if ( is_invertible(op, y) ) + op(x, y) == (x -= y, x); + + // consistency of unary inversion + if ( is_invertible(op, y) ) + inverse(op, y) == -y; + + // consistency between unary and binary - + if ( is_invertible(op, x) ) + identity(op, x) - x == -x; + } +} + + +auto concept AdditiveGroup<typename Element> + : AdditivePIMonoid<Element>, + Group< add<Element>, Element > +{}; + + +auto concept AdditiveAbelianGroup<typename Element> + : AdditiveGroup<Element>, + Commutative< add<Element>, Element > +{} + +#endif + + +concept Multiplicative<typename Element> + : std::HasMultiply<Element> +{ + typename times_assign_result_type; + times_assign_result_type operator*=(Element& x, Element y) + { + x= x * y; return x; + } + + requires std::Convertible<times_assign_result_type, Element&>; + + // Do we need the opposite conversion too? + // This line produces a compiler error + // requires std::Convertible<mult<Element>::result_type, + // std::HasMultiply<Element>::result_type>; + + axiom Consistency(mult<Element> op, Element x, Element y) + { + op(x, y) == x * y; + op(x, y) == (x *= y, x); + } +} + + +auto concept MultiplicativeCommutative<typename Element> + : Multiplicative<Element>, + Commutative< mult<Element>, Element > +{} + + +auto concept MultiplicativeSemiGroup<typename Element> + : Multiplicative<Element>, + SemiGroup< mult<Element>, Element > +{} + + +concept MultiplicativeMonoid<typename Element> + : MultiplicativeSemiGroup<Element>, + Monoid< mult<Element>, Element > +{ + Element one(Element x) + { + return identity(mult<Element>(), x); + } + + // If we don't use the default definition + axiom IdentityConsistency (math::mult<Element> op, Element x) + { + one(x) == identity(op, x); + } +}; + +#ifndef CONCEPTS_WITHOUT_OVERLOADED_REQUIREMENTS // Uncompilable due to error in compiler +concept MultiplicativePIMonoid<typename Element> + : std::HasDivide<Element>, MultiplicativeMonoid<Element>, + PIMonoid< mult<Element>, Element > +{ + typename divide_assign_result_type; + divide_assign_result_type operator/=(Element& x, Element y) + { + x= x / y; return x; + } + + requires std::Convertible<divide_assign_result_type, Element&>; + + axiom InverseConsistency(mult<Element> op, Element x, Element y) + { + // consistency between multiplicative and functor concept + if ( is_invertible(op, y) ) + op(x, inverse(op, y)) == x / y; + if ( is_invertible(op, y) ) + op(x, y) == (x /= y, x); + } +} + + +auto concept MultiplicativeGroup<typename Element> + : MultiplicativePIMonoid<Element>, + Group< mult<Element>, Element > +{}; + + +auto concept MultiplicativeAbelianGroup<typename Element> + : MultiplicativeGroup<Element>, + Commutative< mult<Element>, Element > +{} + + +// ========================== +// Concepts with 2 operations +// ========================== + + + +concept Distributive<typename AddOp, typename MultOp, typename Element> +{ + axiom Distributivity(AddOp add, MultOp mult, Element x, Element y, Element z) + { + // From left + mult(x, add(y, z)) == add(mult(x, y), mult(x, z)); + // from right + mult(add(x, y), z) == add(mult(x, z), mult(y, z)); + } +} + + +auto concept Ring<typename AddOp, typename MultOp, typename Element> + : AbelianGroup<AddOp, Element>, + SemiGroup<MultOp, Element>, + Distributive<AddOp, MultOp, Element> +{} + + +auto concept RingWithIdentity<typename AddOp, typename MultOp, typename Element> + : Ring<AddOp, MultOp, Element>, + Monoid<MultOp, Element> +{} + + +concept DivisionRing<typename AddOp, typename MultOp, typename Element> + : RingWithIdentity<AddOp, MultOp, Element>, + Inversion<MultOp, Element> +{ + // 0 != 1, otherwise trivial + axiom ZeroIsDifferentFromOne(AddOp add, MultOp mult, Element x) + { + identity(add, x) != identity(mult, x); + } + + // Non-zero divisibility from left and from right + axiom NonZeroDivisibility(AddOp add, MultOp mult, Element x) + { + if (x != identity(add, x)) + mult(inverse(mult, x), x) == identity(mult, x); + if (x != identity(add, x)) + mult(x, inverse(mult, x)) == identity(mult, x); + } +} + + +auto concept Field<typename AddOp, typename MultOp, typename Element> + : DivisionRing<AddOp, MultOp, Element>, + Commutative<MultOp, Element> +{} + + +auto concept OperatorRing<typename Element> + : AdditiveAbelianGroup<Element>, + MultiplicativeSemiGroup<Element>, + Ring<add<Element>, mult<Element>, Element> +{} + + +auto concept OperatorRingWithIdentity<typename Element> + : OperatorRing<Element>, + MultiplicativeMonoid<Element>, + RingWithIdentity<add<Element>, mult<Element>, Element> +{} + + +auto concept OperatorDivisionRing<typename Element> + : OperatorRingWithIdentity<Element>, + MultiplicativePIMonoid<Element>, + DivisionRing<add<Element>, mult<Element>, Element> +{} + + +auto concept OperatorField<typename Element> + : OperatorDivisionRing<Element>, + Field<add<Element>, mult<Element>, Element> +{} + + + +#endif + +concept IntrinsicType<typename T> {} + +concept IntrinsicArithmetic<typename T> : IntrinsicType<T> {} + +concept IntrinsicIntegral<typename T> : IntrinsicArithmetic<T> {} + +concept IntrinsicSignedIntegral<typename T> + : std::SignedIntegralLike<T>, + IntrinsicIntegral<T> +{} + +concept IntrinsicUnsignedIntegral<typename T> + : std::UnsignedIntegralLike<T>, + IntrinsicIntegral<T> +{} + +concept IntrinsicFloatingPoint<typename T> + : std::FloatingPointLike<T>, + IntrinsicArithmetic<T> +{} + + +// Intrinsic types are chategorized: + +concept_map IntrinsicSignedIntegral<char> {} +concept_map IntrinsicSignedIntegral<signed char> {} +concept_map IntrinsicUnsignedIntegral<unsigned char> {} +concept_map IntrinsicSignedIntegral<short> {} +concept_map IntrinsicUnsignedIntegral<unsigned short> {} +concept_map IntrinsicSignedIntegral<int> {} +concept_map IntrinsicUnsignedIntegral<unsigned int> {} +concept_map IntrinsicSignedIntegral<long> {} +concept_map IntrinsicUnsignedIntegral<unsigned long> {} +concept_map IntrinsicSignedIntegral<long long> {} +concept_map IntrinsicUnsignedIntegral<unsigned long long> {} + +concept_map IntrinsicFloatingPoint<float> {} +concept_map IntrinsicFloatingPoint<double> {} + + +#ifndef CONCEPTS_WITHOUT_OVERLOADED_REQUIREMENTS + +// ==================== +// Default Concept Maps +// ==================== + +// ============== +// Arithmetic +// ============== + +// ---------------- +// Signed integrals +// ---------------- + +template <typename T> + requires IntrinsicSignedIntegral<T> +concept_map OperatorRingWithIdentity<T> {} + +template <typename T> + requires IntrinsicSignedIntegral<T> +concept_map MultiplicativeCommutative<T> {} + +// ------------------ +// Unsigned integrals +// ------------------ + + +template <typename T> + requires IntrinsicUnsignedIntegral<T> +concept_map AdditiveCommutative<T> {} + +template <typename T> + requires IntrinsicUnsignedIntegral<T> +concept_map AdditiveMonoid<T> {} + +template <typename T> + requires IntrinsicUnsignedIntegral<T> +concept_map MultiplicativeCommutative<T> {} + +template <typename T> + requires IntrinsicUnsignedIntegral<T> +concept_map MultiplicativeMonoid<T> {} + +// --------------- +// Floationg Point +// --------------- + + +template <typename T> + requires IntrinsicFloatingPoint<T> +concept_map Field<T> {} + +template <typename T> + requires IntrinsicFloatingPoint<T> +concept_map Field< std::complex<T> > {} + + +// =========== +// Min and Max +// =========== + + +template <typename T> + requires IntrinsicArithmetic<T> +concept_map Commutative< max<T>, T > {} + +template <typename T> + requires IntrinsicArithmetic<T> +concept_map Monoid< max<T>, T > {} + +template <typename T> + requires IntrinsicArithmetic<T> +concept_map Commutative< min<T>, T > {} + +template <typename T> + requires IntrinsicArithmetic<T> +concept_map Monoid< min<T>, T > {} + + +// ========== +// And and Or +// ========== + +template <typename T> + requires Intrinsic<T> && std::HasLogicalAnd<T> +concept_map Commutative< std::logical_and<T>, T > {} + +template <typename T> + requires Intrinsic<T> && std::HasLogicalAnd<T> +concept_map Monoid< std::logical_and<T>, T > {} + +template <typename T> + requires Intrinsic<T> && std::HasLogicalOr<T> +concept_map Commutative< std::logical_or<T>, T > {} + +template <typename T> + requires Intrinsic<T> && std::HasLogicalOr<T> +concept_map Monoid< std::logical_or<T>, T > {} + +template <typename T> + requires Intrinsic<T> && std::HasLogicalAnd<T> && std::HasLogicalOr<T> +concept_map Distributive<std::logical_and<T>, std::logical_or<T>, T> {} + +template <typename T> + requires Intrinsic<T> && std::HasLogicalAnd<T> && std::HasLogicalOr<T> +concept_map Distributive<std::logical_or<T>, std::logical_and<T>, T> {} + + +// ================== +// Bitwise operations +// ================== + +// not yet defined + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Commutative< bit_and<T>, T > {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Monoid< bit_and<T>, T > {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Commutative< bit_or<T>, T > {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Monoid< bit_or<T>, T > {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Distributive<bit_and<T>, bit_or<T>, T> {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Distributive<bit_or<T>, bit_and<T>, T> {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Commutative< bit_xor<T>, T > {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map SemiGroup< bit_xor<T>, T > {} + +// ==================== +// String concatenation +// ==================== + +concept_map AdditiveMonoid<std::string> {} + + +#endif + + + +} // namespace math + +#endif // MTL_NEW_ALGEBRAIC_CONCEPTS_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/ets_concepts.hpp b/install/MTL/include/boost/numeric/linear_algebra/ets_concepts.hpp new file mode 100644 index 00000000..f71ea48c --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/ets_concepts.hpp @@ -0,0 +1,47 @@ +// Copyright 2006. Peter Gottschling, Matthias Troyer, Rolf Bonderer + +#ifndef LA_ETS_CONCEPTS_INCLUDE +#define LA_ETS_CONCEPTS_INCLUDE + +#include <boost/numeric/linear_algebra/concepts.hpp> + +#ifdef __GXX_CONCEPTS__ + +//"Namespace ETS = Expression Templates Support": +// This file contains concepts that support the concepts defined in the namespace math. +// They are required since the math-concepts do not support ExpressionTemplates so far. +// The list of valid expressions is in fact infinite, so we just name some of them. +// Once ExpressionTemplates are supported by the math-concepts, the ets-concepts are no longer required. + +namespace ets { + + auto concept Field<typename Element> + { + requires std::Assignable<Element, math::AdditivePartiallyInvertibleMonoid<Element>::unary_result_type>; //"x=-y" valid + }; + + auto concept VectorSpace<typename Vector, typename Scalar> + { + // valid expression: "vector2 += scalar*vector1" + typename res_type_1; + res_type_1 operator+=(Vector&, math::Multiplicable<Scalar, Vector>::result_type); + + // valid expression: "vector2 -= scalar*vector1" + typename res_type_2; + res_type_2 operator-=(Vector&, math::Multiplicable<Scalar, Vector>::result_type); + + //valid expression: "vector *= -scalar" + typename res_type_3; + res_type_3 operator*=(Vector&, const math::AdditivePartiallyInvertibleMonoid<Scalar>::unary_result_type&); + + //valid expression: "vector3 = vector1 + scalar*vector2" + requires math::Addable<Vector, math::Multiplicable<Scalar, Vector>::result_type>; //"vector1+scalar*vector2" valid + requires std::Assignable<Vector, math::Addable<Vector, math::Multiplicable<Scalar, Vector>::result_type>::result_type>; //"vector3 = vector1 + scalar*vector2" valid + + }; + +} //namespace ets + +#endif //__GXX_CONCEPTS__ + +#endif //LA_ETS_CONCEPTS_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/identity.hpp b/install/MTL/include/boost/numeric/linear_algebra/identity.hpp new file mode 100644 index 00000000..b1756165 --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/identity.hpp @@ -0,0 +1,208 @@ +// Copyright 2006. Peter Gottschling, Matthias Troyer, Rolf Bonderer +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MATH_IDENTITY_INCLUDE +#define MATH_IDENTITY_INCLUDE + +#include <boost/math/tools/config.hpp> +#include <limits> +#include <string> +#include <functional> + +#include <boost/numeric/linear_algebra/operators.hpp> + +namespace math { + +template <typename Operation, typename Element> +struct identity_t {}; + +// TBD: Do we the case that the return type is different? Using std::unary_function? + +// Additive identity of Element type is by default a converted 0 +// However, for vectors one needs to know the dimension +// (and in parallel eventually also the distribution). +// Therefore, an element is passed as reference. +// It is strongly recommended to specialize this functor +// for better efficiency. +template <typename Element> +struct identity_t< add<Element>, Element > + : public std::binary_function<add<Element>, Element, Element> +{ + Element operator() (const add<Element>&, const Element& ref) const + { + Element tmp(ref); + tmp= 0; + return tmp; + } +}; + +template <> +struct identity_t< add<std::string>, std::string > + : public std::binary_function<add<std::string>, std::string, std::string> +{ + std::string operator() (const add<std::string>&, const std::string&) const + { + return std::string(); + } +}; + +// Multiplicative identity of Element type is by default a converted 1 +// Same comments as above. +// In contrast to additive identity, this default more likely to be wrong (e.g. matrices with all 1s) +template <typename Element> +struct identity_t< mult<Element>, Element > + : public std::binary_function<mult<Element>, Element, Element> +{ + Element operator() (const mult<Element>&, const Element& ref) const + { + Element tmp(ref); + tmp= 1; + return tmp; + } +}; + + +// Identity of max is minimal representable value, for standard types defined in numeric_limits +template <typename Element> +struct identity_t< max<Element>, Element > + : public std::binary_function<max<Element>, Element, Element> +{ + Element operator() (const max<Element>&, const Element& ) const + { + using std::numeric_limits; + return numeric_limits<Element>::min(); + } +}; + +template <> +struct identity_t< max<float>, float > + : public std::binary_function<max<float>, float, float> +{ + float operator() (const max<float>&, const float& ) const + { + using std::numeric_limits; + return -numeric_limits<float>::max(); + } +}; + +template <> +struct identity_t< max<double>, double > + : public std::binary_function<max<double>, double, double> +{ + double operator() (const max<double>&, const double& ) const + { + using std::numeric_limits; + return -numeric_limits<double>::max(); + } +}; + + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + +template <> +struct identity_t< max<long double>, long double > + : public std::binary_function<max<long double>, long double, long double> +{ + long double operator() (const max<long double>&, const long double& ) const + { + using std::numeric_limits; + return -numeric_limits<long double>::max(); + } +}; + +#endif + + + +// Identity of min is maximal representable value, for standard types defined in numeric_limits +template <typename Element> +struct identity_t< min<Element>, Element > + : public std::binary_function<min<Element>, Element, Element> +{ + Element operator() (const min<Element>&, const Element& ) const + { + using std::numeric_limits; + return numeric_limits<Element>::max(); + } +}; + +// Identity of bit-wise and +template <typename Element> +struct identity_t< bitwise_and<Element>, Element > + : public std::binary_function<bitwise_and<Element>, Element, Element> +{ + Element operator() (const bitwise_and<Element>&, const Element&) const + { + return 0; + } +}; + +// Identity of bit-wise or +template <typename Element> +struct identity_t< bitwise_or<Element>, Element > + : public std::binary_function<bitwise_or<Element>, Element, Element> +{ + Element operator() (const bitwise_or<Element>&, const Element&) const + { + return 0 - 1; + } +}; + +#if 0 // ambiguous specialization +template <template <typename> class Operation, typename First, typename Second> +struct identity_t< Operation<std::pair<First, Second> >, std::pair<First, Second> > +{ + typedef std::pair<First, Second> pt; + + pt operator()(const Operation<pt>&, const pt& ref) const + { + return std::make_pair(identity(Operation<First>(), ref.first), identity(Operation<Second>(), ref.second)); + } +}; +#endif + +// Function is shorter than typetrait-like functor +template <typename Operation, typename Element> +inline Element identity(const Operation& op, const Element& v) +{ + return identity_t<Operation, Element>() (op, v); +} + +#if 1 +// I shouldn't do this (but as functor I'd need too many specializations) +template <template <typename> class Operation, typename First, typename Second> +inline std::pair<First, Second> identity(const Operation<std::pair<First, Second> >&, const std::pair<First, Second>& v) +{ + return std::pair<First, Second>(math::identity(Operation<First>(), v.first), math::identity(Operation<Second>(), v.second)); +} +#endif + +// Short-cut for additive identity +template <typename Element> +inline Element zero(const Element& v) +{ + return identity_t<math::add<Element>, Element>() (math::add<Element>(), v); +} + + +// Short-cut for multiplicative identity +template <typename Element> +inline Element one(const Element& v) +{ + return identity_t<math::mult<Element>, Element>() (math::mult<Element>(), v); +} + + +} // namespace math + +#endif // MATH_IDENTITY_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/intrinsic_concept_maps.hpp b/install/MTL/include/boost/numeric/linear_algebra/intrinsic_concept_maps.hpp new file mode 100644 index 00000000..4bd754f4 --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/intrinsic_concept_maps.hpp @@ -0,0 +1,116 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MATH_INTRINSIC_CONCEPT_MAPS_INCLUDE +#define MATH_INTRINSIC_CONCEPT_MAPS_INCLUDE + +#include <concepts> + +namespace math { + + + // The following concepts are used to classify intrinsic arithmetic types. + // The standard concepts already define the syntactic requirements, + // i.e. the interface. + // However they sey nothing about the semantics. + // Therefore, user-defined types can model the syntactic/interface + // requirements while still having a different mathematical behavior. + // For that reason, we introduce concepts that are only used for intrinsic types. + // For them we can define concept_maps regarding semantic behavior as monoids. + + concept IntrinsicSignedIntegral<typename T> + : std::SignedIntegralLike<T> + {} + + concept IntrinsicUnsignedIntegral<typename T> + : std::UnsignedIntegralLike<T> + {} + + concept IntrinsicFloatingPoint<typename T> + : std::FloatingPointLike<T> + {} + + + // Intrinsic types are chategorized: + + // concept_map IntrinsicSignedIntegral<char> {}; ??? + concept_map IntrinsicSignedIntegral<signed char> {}; + concept_map IntrinsicUnsignedIntegral<unsigned char> {}; + concept_map IntrinsicSignedIntegral<short> {}; + concept_map IntrinsicUnsignedIntegral<unsigned short> {}; + concept_map IntrinsicSignedIntegral<int> {}; + concept_map IntrinsicUnsignedIntegral<unsigned int> {}; + concept_map IntrinsicSignedIntegral<long> {}; + concept_map IntrinsicUnsignedIntegral<unsigned long> {}; + concept_map IntrinsicSignedIntegral<long long> {}; + concept_map IntrinsicUnsignedIntegral<unsigned long long> {}; + + concept_map IntrinsicFloatingPoint<float> { } + concept_map IntrinsicFloatingPoint<double> { } + + concept Integral<typename T> : std::CopyAssignable<T> + { + requires std::HasPlus<T> && std::HasMinus<T> && std::HasMultiply<T> && std::HasDivide<T> + && std::HasUnaryPlus<T> && std::HasNegate<T>; + + + T& operator++(T&); + T operator++(T& t, int) { T tmp(t); ++t; return tmp; } + T& operator--(T&); + T operator--(T& t, int) { T tmp(t); --t; return tmp; } + + requires std::Convertible<std::HasUnaryPlus<T>::result_type, T> + && std::Convertible<std::HasNegate<T>::result_type, T> + && std::Convertible<std::HasPlus<T>::result_type, T> + && std::Convertible<std::HasMinus<T>::result_type, T> + && std::Convertible<std::HasMultiply<T>::result_type, T> + && std::Convertible<std::HasDivide<T>::result_type, T>; + + T& operator*=(T&, T); + T& operator/=(T&, T); + T& operator+=(T&, T); + T& operator-=(T&, T); + + requires std::HasComplement<T> && std::HasModulus<T> && std::HasBitAnd<T> + && std::HasBitOr<T> && std::HasBitXor<T> && std::HasLeftShift<T> + && std::HasRightShift<T>; + + requires std::Convertible<std::HasComplement<T>::result_type, T> + && std::Convertible<std::HasModulus<T>::result_type, T> + && std::Convertible<std::HasBitAnd<T>::result_type, T> + && std::Convertible<std::HasBitOr<T>::result_type, T> + && std::Convertible<std::HasBitXor<T>::result_type, T> + && std::Convertible<std::HasLeftShift<T>::result_type, T> + && std::Convertible<std::HasRightShift<T>::result_type, T>; + + requires std::LessThanComparable<T> && std::EqualityComparable<T>; + + T& operator%=(T&, T); + T& operator&=(T&, T); + T& operator|=(T&, T); + T& operator^=(T&, T); + T& operator<<=(T&, T); + T& operator>>=(T&, T); + } + + + template <typename T> + requires IntrinsicUnsignedIntegral<T> + concept_map Integral<T> {typedef T result_type;} + + template <IntrinsicSignedIntegral T> + concept_map Integral<T> {typedef T result_type;} + + +} // namespace math + +#endif // MATH_INTRINSIC_CONCEPT_MAPS_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/inverse.hpp b/install/MTL/include/boost/numeric/linear_algebra/inverse.hpp new file mode 100644 index 00000000..e6e252f0 --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/inverse.hpp @@ -0,0 +1,65 @@ +// Copyright 2006. Peter Gottschling, Matthias Troyer, Rolf Bonderer +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MATH_INVERSE_INCLUDE +#define MATH_INVERSE_INCLUDE + +#include <boost/numeric/linear_algebra/operators.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> + +namespace math { + +template <typename Operation, typename Element> +struct inverse_t {} ; + + +template <typename Element> +struct inverse_t< add<Element>, Element > + : public std::binary_function<add<Element>, Element, Element> +{ + Element operator()(const add<Element>&, const Element& v) const + { + return -v; + } +}; + + +template <typename Element> +struct inverse_t< mult<Element>, Element > + : public std::binary_function<mult<Element>, Element, Element> +{ + Element operator()(const mult<Element>&, const Element& v) const + { + return one(v) / v ; + } +}; + + +// Function is shorter than typetrait-like functor +template <typename Operation, typename Element> +inline Element inverse(const Operation& op, const Element& v) +{ + return inverse_t<Operation, Element>() (op, v); +} + + +// Short-cut for multiplicative inverse +template <typename Element> +inline Element reciprocal(const Element& v) +{ + return inverse(math::mult<Element>(), v); +} + +} // namespace math + +#endif // MATH_INVERSE_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/is_invertible.hpp b/install/MTL/include/boost/numeric/linear_algebra/is_invertible.hpp new file mode 100644 index 00000000..727df0e4 --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/is_invertible.hpp @@ -0,0 +1,82 @@ +// Copyright 2006. Peter Gottschling, Matthias Troyer, Rolf Bonderer +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MATH_IS_INVERTIBLE_INCLUDE +#define MATH_IS_INVERTIBLE_INCLUDE + +#include <boost/numeric/linear_algebra/operators.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> + +namespace math { + +template <typename Operation, typename Element> +struct is_invertible_t +{ + // bool operator()(const Operation&, const Element&) const; +}; + + +// By default all elements are invertible w.r.t. addition +// If only part of the elements are invertible it shall be handled by specialization of the type +// Whether invertibility is relevant at all shall be concrolled by the user with concept maps +template <typename Element> +struct is_invertible_t< add<Element>, Element > + : public std::binary_function<add<Element>, Element, Element> +{ + bool operator() (const add<Element>&, const Element&) const + { + return true; + } +}; + + +// By default all non-zero elements are invertible w.r.t. multiplication +// If another part of the elements or all elements are invertible it shall be handled by specialization of the type +// Whether invertibility is relevant at all shall be concrolled by the user with concept maps +template <typename Element> +struct is_invertible_t< mult<Element>, Element > + : public std::binary_function<mult<Element>, Element, Element> +{ + bool operator() (const mult<Element>&, const Element& v) const + { + return v != zero(v); + } +}; + + +// Function is shorter than typetrait-like functor +template <typename Operation, typename Element> +inline bool is_invertible(const Operation& op, const Element& v) +{ + return is_invertible_t<Operation, Element>() (op, v); +} + + +namespace detail { + + // Helper type whose operator returns true if v is not 0 + // 0 must be convertible into Element and Element must be EqualityComparable + template <typename Operation, typename Element> + struct non_zero_is_invertible_t + { + bool operator() (const Operation&, const Element& v) + { + return v != Element(0); + } + }; + +} // namespace detail + +} // namespace math + +#endif // MATH_IS_INVERTIBLE_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/linear_operator.hpp b/install/MTL/include/boost/numeric/linear_algebra/linear_operator.hpp new file mode 100644 index 00000000..43b95151 --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/linear_operator.hpp @@ -0,0 +1,247 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MATH_LINEAR_OPERATOR_INCLUDE +#define MATH_LINEAR_OPERATOR_INCLUDE + +#ifdef __GXX_CONCEPTS__ +# include <concepts> +#else +# include <boost/numeric/linear_algebra/pseudo_concept.hpp> +#endif + +namespace math { + +/** @addtogroup Concepts + * @{ + */ + +#ifdef __GXX_CONCEPTS__ + concept LinearOperator<typename Operator, typename VectorDomain, typename VectorImage> + { + requires VectorSpace<VectorDomain>; + requires VectorSpace<VectorImage>; + + typename result_type; + result_type operator* (Operator, VectorDomain); + + typename assign_type; + assign_type operator= (VectorImage, result_type); + + // The following two requirements are subject to discussion + typename plus_assign_type; + plus_assign_type operator+= (VectorImage, result_type); + + typename minus_assign_type; + minus_assign_type operator-= (VectorImage, result_type); + + axiom Addability(Operator A, VectorDomain x, VectorDomain y) + { + A * (x + y) == A*x + A*y; + } + + // The two vector spaces must be scalable with the same scalar types + axiom Scalability(Operator A, VectorSpace<VectorDomain>::scalar_type alpha, VectorDomain x) + { + A * (alpha * x) == alpha * (A * x); + } + }; +#else + //! Concept LinearOperator + /*! + Linear operator from one vector space into another one. + + \param Operator The type of the operator, e.g., some matrix type + \param VectorDomain The the type of a vector in the domain vector space + \param VectorImage The the type of a vector in the image vector space + + \par Associated Types: + - result_type + - assign_type + - plus_assign_type + - minus_assign_type + + \par Requires: + - VectorSpace < VectorDomain > + - VectorSpace < VectorImage > + + \par Notation: + <table summary="notation"> + <tr> + <td>A</td> + <td>Object of type Operation</td> + </tr> + <tr> + <td>x, y</td> + <td>Objects of type VectorDomain</td> + </tr> + <tr> + <td>u</td> + <td>Object of type VectorImage</td> + </tr> + </table> + + \par Valid Expressions: + <table> + <tr> + <td>Assign product:</td> + <td>u= A * x</td> + </tr> + <tr> + <td>Add product:</td> + <td>u+= A * x</td> + </tr> + <tr> + <td>Subtract product:</td> + <td>u-= A * x</td> + </tr> + </table> + + \invariant + <table summary="invariants"> + <tr> + <td>Addability</td> + <td>A * (x + y) == A*x + A*y</td> + </tr> + <tr> + <td>Scalability</td> + <td>alpha * (A * x) == A * (alpha * x)</td> + </tr> + </table> + + \note + -# Using matrix vector products in arbitrary expressions requires + storing it in temporary objects to avoid redundant computation. + On the other hand, it is not always obvious to choose an appropriate + type for such temporary depending on arbitrary operator and vector types. + Using the products directly in assignments allows implementation without + temporaries, e.g., by calling a function mult(A, x, u) internally. + */ + template <typename Operator, typename VectorDomain, typename VectorImage> + struct LinearOperator + { + /// Associated type: result of multiplication; automatically deducted + typedef associated_type result_type; + /// Multiplication of linear operator with vector + result_type operator* (Operator, VectorDomain); + + /// Associated type: return type of assigning product to vector. + /** Automatically deducted. Using expression templates it can be different from VectorImage& */ + typedef associated_type assign_type; + /// Product must be assignable + assign_type operator= (VectorImage, result_type); + + // The following two requirements are subject to discussion + /// Associated type: return type of incrementally assigning product to vector. + /** Automatically deducted. Using expression templates it can be different from VectorImage& */ + typedef associated_type plus_assign_type; + /// Product must be assignable with increment + plus_assign_type operator+= (VectorImage, result_type); + + // The following two requirements are subject to discussion + /// Associated type: return type of decrementally assigning product to vector. + /** Automatically deducted. Using expression templates it can be different from VectorImage& */ + typedef associated_type minus_assign_type; + /// Product must be assignable with decrement + minus_assign_type operator+= (VectorImage, result_type); + + /// Invariant: the linear projection of a sum is the sum of the linear projections + axiom Addability(Operator A, VectorDomain x, VectorDomain y) + { + A * (x + y) == A*x + A*y; + } + + /// Invariant: the linear projection of a scaled vector is the scaling of the vector's linear projections + axiom Scalability(Operator A, VectorSpace<VectorDomain>::scalar_type alpha, VectorDomain x) + { + A * (alpha * x) == alpha * (A * x); + } + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept SelfAdjointOperator<typename Operator, typename VectorDomain, typename VectorImage> + : LinearOperator<Operator, VectorDomain, VectorImage> + {}; +#else + //! Concept SelfAdjointOperator + /*! + + + \param Operator The type of the operator, e.g., some matrix type + \param VectorDomain The the type of a vector in the domain vector space + \param VectorImage The the type of a vector in the image vector space + + \par Refinement of: + - LinearOperator <Operator, VectorDomain, VectorImage> + */ + template <typename Operator, typename VectorDomain, typename VectorImage> + struct SelfAdjointOperator + : LinearOperator<Operator, VectorDomain, VectorImage> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept RealOperator<typename Operator, typename VectorDomain, typename VectorImage> + : LinearOperator<Operator, VectorDomain, VectorImage> + {}; +#else + //! Concept RealOperator + /*! + + + \param Operator The type of the operator, e.g., some matrix type + \param VectorDomain The the type of a vector in the domain vector space + \param VectorImage The the type of a vector in the image vector space + + \par Refinement of: + - LinearOperator <Operator, VectorDomain, VectorImage> + */ + template <typename Operator, typename VectorDomain, typename VectorImage> + struct RealOperator + : LinearOperator<Operator, VectorDomain, VectorImage> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept SymmetricOperator<typename Operator, typename VectorDomain, typename VectorImage> + : SelfAdjointOperator<Operator, VectorDomain, VectorImage>, + RealOperator<Operator, VectorDomain, VectorImage> + {}; +#else + //! Concept SymmetricOperator + /*! + + + \param Operator The type of the operator, e.g., some matrix type + \param VectorDomain The the type of a vector in the domain vector space + \param VectorImage The the type of a vector in the image vector space + + \par Refinement of: + - SelfAdjointOperator <Operator, VectorDomain, VectorImage> + - RealOperator <Operator, VectorDomain, VectorImage> + */ + template <typename Operator, typename VectorDomain, typename VectorImage> + struct SymmetricOperator + : SelfAdjointOperator<Operator, VectorDomain, VectorImage>, + RealOperator<Operator, VectorDomain, VectorImage> + {}; +#endif + +/*@}*/ // end of group Concepts + +} // namespace math + +#endif // MATH_LINEAR_OPERATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/new_concepts.hpp b/install/MTL/include/boost/numeric/linear_algebra/new_concepts.hpp new file mode 100644 index 00000000..3d955cff --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/new_concepts.hpp @@ -0,0 +1,586 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_NEW_ALGEBRAIC_CONCEPTS_INCLUDE +#define MTL_NEW_ALGEBRAIC_CONCEPTS_INCLUDE + +#include <concepts> +#include <boost/numeric/linear_algebra/intrinsic_concept_maps.hpp> +#include <boost/numeric/linear_algebra/operators.hpp> + + +namespace math { + +concept Commutative<typename Operation, typename Element> + : std::Callable2<Operation, Element, Element> +{ + axiom Commutativity(Operation op, Element x, Element y) + { + op(x, y) == op(y, x); + } +}; + + +concept SemiGroup<typename Operation, typename Element> + : std::Callable2<Operation, Element, Element> +{ + axiom Associativity(Operation op, Element x, Element y, Element z) + { + op(x, op(y, z)) == op(op(x, y), z); + } +}; + + +concept Monoid<typename Operation, typename Element> + : SemiGroup<Operation, Element> +{ + typename identity_result_type; + identity_result_type identity(Operation, Element); + + axiom Neutrality(Operation op, Element x) + { + op( x, identity(op, x) ) == x; + op( identity(op, x), x ) == x; + } +}; + + +auto concept Inversion<typename Operation, typename Element> +{ + typename result_type; + result_type inverse(Operation, Element); + +}; + + +concept PIMonoid<typename Operation, typename Element> + : Monoid<Operation, Element>, + Inversion<Operation, Element> +{ + bool is_invertible(Operation, Element); + + requires std::Convertible<Inversion<Operation, Element>::result_type, Element>; + + axiom Invertibility(Operation op, Element x) + { + // Only for invertible elements: + if (is_invertible(op, x)) + op( x, inverse(op, x) ) == identity(op, x); + if ( is_invertible(op, x) ) + op( inverse(op, x), x ) == identity(op, x); + } +} + +#if 0 + // Alternative approach to convert the result of inversion to Element + // Unfortunately, this doesn't compile + template <typename Operation, typename Element> + requires PIMonoid<Operation, Element> + concept_map PIMonoid<Operation, Inversion<Operation, Element>::result_type> {} +#endif + + +concept Group<typename Operation, typename Element> + : PIMonoid<Operation, Element> +{ + bool is_invertible(Operation, Element) { return true; } + + // Just in case somebody redefines is_invertible + axiom AlwaysInvertible(Operation op, Element x) + { + is_invertible(op, x); + } + + // In fact this is implied by AlwaysInvertible and inherited Invertibility axiom + // Maybe remove + axiom GlobalInvertibility(Operation op, Element x) + { + op( x, inverse(op, x) ) == identity(op, x); + op( inverse(op, x), x ) == identity(op, x); + } +}; + + +auto concept AbelianGroup<typename Operation, typename Element> + : Group<Operation, Element>, Commutative<Operation, Element> +{}; + + +// ======================= +// Operator-based concepts +// ======================= + + +concept Additive<typename Element> + : std::HasPlus<Element> +{ + typename plus_assign_result_type; + plus_assign_result_type operator+=(Element& x, Element y) + { + x= x + y; return x; + } + + requires std::Convertible<plus_assign_result_type, Element&>; + + // Do we need the opposite conversion too? + // This line produces a compiler error + // requires std::Convertible<add<Element>::result_type, + // std::HasPlus<Element>::result_type>; + + axiom Consistency(add<Element> op, Element x, Element y) + { + op(x, y) == x + y; + op(x, y) == (x += y, x); + } +} + + +auto concept AdditiveCommutative<typename Element> + : Additive<Element>, + Commutative< add<Element>, Element > +{} + + +auto concept AdditiveSemiGroup<typename Element> + : Additive<Element>, + SemiGroup< add<Element>, Element > +{} + + +#ifdef COMPILER_WITHOUT_OVERLOAD_ERROR // Uncompilable due to error in compiler +concept AdditiveMonoid<typename Element> + : AdditiveSemiGroup<Element>, + Monoid< add<Element>, Element > +{ + Element zero(Element x) + { + return identity(add<Element>(), x); + } + + // If we don't use the default definition + axiom IdentityConsistency (add<Element> op, Element x) + { + zero(x) == identity(op, x); + } +}; + +concept AdditivePIMonoid<typename Element> + : std::HasMinus<Element>, AdditiveMonoid<Element>, + PIMonoid< add<Element>, Element > +{ + typename minus_assign_result_type; + minus_assign_result_type operator-=(Element& x, Element y) + { + x= x - y; return x; + } + + requires std::Convertible<minus_assign_result_type, Element&>; + + typename unary_result_type; + unary_result_type operator-(Element x) + { + return zero(x) - x; + } + + axiom InverseConsistency(add<Element> op, Element x, Element y) + { + // consistency between additive and functor concept + if ( is_invertible(op, y) ) + op(x, inverse(op, y)) == x - y; + if ( is_invertible(op, y) ) + op(x, y) == (x -= y, x); + + // consistency of unary inversion + if ( is_invertible(op, y) ) + inverse(op, y) == -y; + + // consistency between unary and binary - + if ( is_invertible(op, x) ) + identity(op, x) - x == -x; + } +} + + +auto concept AdditiveGroup<typename Element> + : AdditivePIMonoid<Element>, + Group< add<Element>, Element > +{}; + + +auto concept AdditiveAbelianGroup<typename Element> + : AdditiveGroup<Element>, + Commutative< add<Element>, Element > +{} + +#endif + + +concept Multiplicative<typename Element> + : std::HasMultiply<Element> +{ + typename times_assign_result_type; + times_assign_result_type operator*=(Element& x, Element y) + { + x= x * y; return x; + } + + requires std::Convertible<times_assign_result_type, Element&>; + + // Do we need the opposite conversion too? + // This line produces a compiler error + // requires std::Convertible<mult<Element>::result_type, + // std::HasMultiply<Element>::result_type>; + + axiom Consistency(mult<Element> op, Element x, Element y) + { + op(x, y) == x * y; + op(x, y) == (x *= y, x); + } +} + + +auto concept MultiplicativeCommutative<typename Element> + : Multiplicative<Element>, + Commutative< mult<Element>, Element > +{} + + +auto concept MultiplicativeSemiGroup<typename Element> + : Multiplicative<Element>, + SemiGroup< mult<Element>, Element > +{} + + +#ifdef COMPILER_WITHOUT_OVERLOAD_ERROR // Uncompilable due to error in compiler +concept MultiplicativeMonoid<typename Element> + : MultiplicativeSemiGroup<Element>, + Monoid< mult<Element>, Element > +{ + Element one(Element x) + { + return identity(mult<Element>(), x); + } + + // If we don't use the default definition + axiom IdentityConsistency (math::mult<Element> op, Element x) + { + one(x) == identity(op, x); + } +}; + +concept MultiplicativePIMonoid<typename Element> + : std::HasDivide<Element>, MultiplicativeMonoid<Element>, + PIMonoid< mult<Element>, Element > +{ + typename divide_assign_result_type; + divide_assign_result_type operator/=(Element& x, Element y) + { + x= x / y; return x; + } + + requires std::Convertible<divide_assign_result_type, Element&>; + + axiom InverseConsistency(mult<Element> op, Element x, Element y) + { + // consistency between multiplicative and functor concept + if ( is_invertible(op, y) ) + op(x, inverse(op, y)) == x / y; + if ( is_invertible(op, y) ) + op(x, y) == (x /= y, x); + } +} + + +auto concept MultiplicativeGroup<typename Element> + : MultiplicativePIMonoid<Element>, + Group< mult<Element>, Element > +{}; + + +auto concept MultiplicativeAbelianGroup<typename Element> + : MultiplicativeGroup<Element>, + Commutative< mult<Element>, Element > +{} + + +// ========================== +// Concepts with 2 operations +// ========================== + + + +concept Distributive<typename AddOp, typename MultOp, typename Element> +{ + axiom Distributivity(AddOp add, MultOp mult, Element x, Element y, Element z) + { + // From left + mult(x, add(y, z)) == add(mult(x, y), mult(x, z)); + // from right + mult(add(x, y), z) == add(mult(x, z), mult(y, z)); + } +} + + +auto concept Ring<typename AddOp, typename MultOp, typename Element> + : AbelianGroup<AddOp, Element>, + SemiGroup<MultOp, Element>, + Distributive<AddOp, MultOp, Element> +{} + + +auto concept RingWithIdentity<typename AddOp, typename MultOp, typename Element> + : Ring<AddOp, MultOp, Element>, + Monoid<MultOp, Element> +{} + + +concept DivisionRing<typename AddOp, typename MultOp, typename Element> + : RingWithIdentity<AddOp, MultOp, Element>, + Inversion<MultOp, Element> +{ + // 0 != 1, otherwise trivial + axiom ZeroIsDifferentFromOne(AddOp add, MultOp mult, Element x) + { + identity(add, x) != identity(mult, x); + } + + // Non-zero divisibility from left and from right + axiom NonZeroDivisibility(AddOp add, MultOp mult, Element x) + { + if (x != identity(add, x)) + mult(inverse(mult, x), x) == identity(mult, x); + if (x != identity(add, x)) + mult(x, inverse(mult, x)) == identity(mult, x); + } +} + + +auto concept Field<typename AddOp, typename MultOp, typename Element> + : DivisionRing<AddOp, MultOp, Element>, + Commutative<MultOp, Element> +{} + + +auto concept OperatorRing<typename Element> + : AdditiveAbelianGroup<Element>, + MultiplicativeSemiGroup<Element>, + Ring<add<Element>, mult<Element>, Element> +{} + + +auto concept OperatorRingWithIdentity<typename Element> + : OperatorRing<Element>, + MultiplicativeMonoid<Element>, + RingWithIdentity<add<Element>, mult<Element>, Element> +{} + + +auto concept OperatorDivisionRing<typename Element> + : OperatorRingWithIdentity<Element>, + MultiplicativePIMonoid<Element>, + DivisionRing<add<Element>, mult<Element>, Element> +{} + + +auto concept OperatorField<typename Element> + : OperatorDivisionRing<Element>, + Field<add<Element>, mult<Element>, Element> +{} + + + +#endif + +concept IntrinsicType<typename T> {} + +concept IntrinsicArithmetic<typename T> : IntrinsicType<T> {} + +concept IntrinsicIntegral<typename T> : IntrinsicArithmetic<T> {} + +concept IntrinsicSignedIntegral<typename T> + : std::SignedIntegralLike<T>, + IntrinsicIntegral<T> +{} + +concept IntrinsicUnsignedIntegral<typename T> + : std::UnsignedIntegralLike<T>, + IntrinsicIntegral<T> +{} + +concept IntrinsicFloatingPoint<typename T> + : std::FloatingPointLike<T>, + IntrinsicArithmetic<T> +{} + + + + +#if 0 + +// ==================== +// Default Concept Maps +// ==================== + +// ============== +// Arithmetic +// ============== + +// ---------------- +// Signed integrals +// ---------------- + +template <typename T> + requires IntrinsicSignedIntegral<T> +concept_map OperatorRingWithIdentity<T> {} + +template <typename T> + requires IntrinsicSignedIntegral<T> +concept_map MultiplicativeCommutative<T> {} + +// ------------------ +// Unsigned integrals +// ------------------ + + +template <typename T> + requires IntrinsicUnsignedIntegral<T> +concept_map AdditiveCommutative<T> {} + +template <typename T> + requires IntrinsicUnsignedIntegral<T> +concept_map AdditiveMonoid<T> {} + +template <typename T> + requires IntrinsicUnsignedIntegral<T> +concept_map MultiplicativeCommutative<T> {} + +template <typename T> + requires IntrinsicUnsignedIntegral<T> +concept_map MultiplicativeMonoid<T> {} + +// --------------- +// Floationg Point +// --------------- + + +template <typename T> + requires IntrinsicFloatingPoint<T> +concept_map Field<T> {} + +template <typename T> + requires IntrinsicFloatingPoint<T> +concept_map Field< std::complex<T> > {} + + +// =========== +// Min and Max +// =========== + + +template <typename T> + requires IntrinsicArithmetic<T> +concept_map Commutative< max<T>, T > {} + +template <typename T> + requires IntrinsicArithmetic<T> +concept_map Monoid< max<T>, T > {} + +template <typename T> + requires IntrinsicArithmetic<T> +concept_map Commutative< min<T>, T > {} + +template <typename T> + requires IntrinsicArithmetic<T> +concept_map Monoid< min<T>, T > {} + + +// ========== +// And and Or +// ========== + +template <typename T> + requires Intrinsic<T> && std::HasLogicalAnd<T> +concept_map Commutative< std::logical_and<T>, T > {} + +template <typename T> + requires Intrinsic<T> && std::HasLogicalAnd<T> +concept_map Monoid< std::logical_and<T>, T > {} + +template <typename T> + requires Intrinsic<T> && std::HasLogicalOr<T> +concept_map Commutative< std::logical_or<T>, T > {} + +template <typename T> + requires Intrinsic<T> && std::HasLogicalOr<T> +concept_map Monoid< std::logical_or<T>, T > {} + +template <typename T> + requires Intrinsic<T> && std::HasLogicalAnd<T> && std::HasLogicalOr<T> +concept_map Distributive<std::logical_and<T>, std::logical_or<T>, T> {} + +template <typename T> + requires Intrinsic<T> && std::HasLogicalAnd<T> && std::HasLogicalOr<T> +concept_map Distributive<std::logical_or<T>, std::logical_and<T>, T> {} + + +// ================== +// Bitwise operations +// ================== + +// not yet defined + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Commutative< bit_and<T>, T > {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Monoid< bit_and<T>, T > {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Commutative< bit_or<T>, T > {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Monoid< bit_or<T>, T > {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Distributive<bit_and<T>, bit_or<T>, T> {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Distributive<bit_or<T>, bit_and<T>, T> {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map Commutative< bit_xor<T>, T > {} + +template <typename T> + requires IntrinsicIntegral<T> +concept_map SemiGroup< bit_xor<T>, T > {} + +// ==================== +// String concatenation +// ==================== + +concept_map AdditiveMonoid<std::string> {} + + +#endif + + + +} // namespace math + +#endif // MTL_NEW_ALGEBRAIC_CONCEPTS_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/old_concepts.hpp b/install/MTL/include/boost/numeric/linear_algebra/old_concepts.hpp new file mode 100644 index 00000000..128551e7 --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/old_concepts.hpp @@ -0,0 +1,1159 @@ +// Copyright 2006. Peter Gottschling, Matthias Troyer, Rolf Bonderer +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef LA_CONCEPTS_INCLUDE +#define LA_CONCEPTS_INCLUDE + +#include <boost/config/concept_macros.hpp> + +#ifdef __GXX_CONCEPTS__ +# include <concepts> +#else +# ifdef LA_SHOW_WARNINGS +# warning "Concepts are not used" +# endif +#endif + + +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/linear_algebra/is_invertible.hpp> +#include <boost/numeric/linear_algebra/inverse.hpp> +#include <boost/numeric/linear_algebra/operators.hpp> +#include <boost/numeric/linear_algebra/algebraic_concepts.hpp> +#include <complex> + +// If desired one can disable the default concept maps with LA_NO_CONCEPT_MAPS + +// We consider to change the namespace from math to numeric +// More precisely, the concepts may be moved into namespace numeric and the standard functions stay in math + +/// Namespace for mathematical concepts +/** In contrast to the ones in algebra the concepts can require + basic implementation concepts like std::CopyAssignable */ +namespace math { + +#ifdef __GXX_CONCEPTS__ + +// ================================== +// Classification of Arithmetic Types +// ================================== + +// We omit this now because it became part of the standard concepts + +#if 0 + +// In addtion to std::Integral +concept Float<typename T> + : std::DefaultConstructible<T>, std::CopyConstructible<T>, + std::LessThanComparable<T>, std::EqualityComparable<T> +{ + T operator+(T); + T operator+(T, T); + T& operator+=(T&, T); + T operator-(T, T); + T operator-(T); + T& operator-=(T&, T); + T operator*(T, T); + T& operator*=(T&, T); + T operator/(T, T); + T& operator/=(T&, T); + + requires std::CopyAssignable<T> + && std::SameType<std::CopyAssignable<T>::result_type, T&>; +} + +concept_map Float<float> {} +concept_map Float<double> {} +concept_map Float<long double> {} + +// The difference to Float is the lack of LessThanComparable +concept Complex<typename T> + : std::DefaultConstructible<T>, std::CopyConstructible<T>, + std::EqualityComparable<T> +{ + T operator+(T); + T operator+(T, T); + T& operator+=(T&, T); + T operator-(T, T); + T operator-(T); + T& operator-=(T&, T); + T operator*(T, T); + T& operator*=(T&, T); + T operator/(T, T); + T& operator/=(T&, T); + + requires std::CopyAssignable<T> + && std::SameType<std::CopyAssignable<T>::result_type, T&>; +} + +template <typename T> + requires Float<T> +concept_map Complex<std::complex<T> > {} + + +// TBD: Concept Arithmetic is useless like this, it should have operations and then be the base for +// Integral, Float and Complex +concept Arithmetic<typename T> {} + +template <typename T> + requires std::Integral<T> +concept_map Arithmetic<T> {} + +template <typename T> + requires Float<T> +concept_map Arithmetic<T> {} + +template <typename T> + requires Arithmetic<T> +concept_map Arithmetic< std::complex<T> > {} + +#endif + +// The following concepts are used to classify intrinsic arithmetic types. +// The standard concepts already define the syntactic requirements, +// i.e. the interface. +// However they sey nothing about the semantics. +// Therefore, user-defined types can model the syntactic/interface +// requirements while still having a different mathematical behavior. +// For that reason, we introduce concepts that are only used for intrinsic types. +// For them we can define concept_maps regarding semantic behavior as monoids. + +concept IntrinsicSignedIntegral<typename T> + : std::SignedIntegralLike<T> +{} + +concept IntrinsicUnsignedIntegral<typename T> + : std::UnsignedIntegralLike<T> +{} + +concept IntrinsicFloatingPoint<typename T> + : std::FloatingPointLike<T> +{} + + +// Intrinsic types are chategorized: + +concept_map IntrinsicSignedIntegral<char> {} +concept_map IntrinsicSignedIntegral<signed char> {} +concept_map IntrinsicUnsignedIntegral<unsigned char> {} +concept_map IntrinsicSignedIntegral<short> {} +concept_map IntrinsicUnsignedIntegral<unsigned short> {} +concept_map IntrinsicSignedIntegral<int> {} +concept_map IntrinsicUnsignedIntegral<unsigned int> {} +concept_map IntrinsicSignedIntegral<long> {} +concept_map IntrinsicUnsignedIntegral<unsigned long> {} +concept_map IntrinsicSignedIntegral<long long> {} +concept_map IntrinsicUnsignedIntegral<unsigned long long> {} + +concept_map IntrinsicFloatingPoint<float> {} +concept_map IntrinsicFloatingPoint<double> {} + + + +// ================ +// Utility Concepts +// ================ + +// Concepts for functions mapping to same type or convertible +auto concept UnaryIsoFunction<typename Operation, typename Element> +{ + requires std::Callable1<Operation, Element>; + requires std::Convertible<std::Callable1<Operation, Element>::result_type, Element>; + + typename result_type = std::Callable1<Operation, Element>::result_type; +}; + + +auto concept BinaryIsoFunction<typename Operation, typename Element> +{ + requires std::Callable2<Operation, Element, Element>; + requires std::Convertible<std::Callable2<Operation, Element, Element>::result_type, Element>; + + typename result_type = std::Callable2<Operation, Element, Element>::result_type; +}; + +#if 0 +auto concept CompatibleBinaryFunction<typename A1, typename A2, typename Result> +{ + typename result_type; + result_type F(A1, A2); + requires std::Convertible<result_type, Result>; +} +#endif + +// ================== +// Algebraic Concepts +// ================== + + +auto concept Magma<typename Operation, typename Element> + : BinaryIsoFunction<Operation, Element> +{ + requires std::CopyAssignable<Element> + && std::CopyAssignable<Element, BinaryIsoFunction<Operation, Element>::result_type>; +}; + + +// For algebraic structures that are commutative but not associative +// As an example floating point numbers are commutative but not associative +// w.r.t. addition and multiplication +auto concept CommutativeMagma<typename Operation, typename Element> + : Magma<Operation, Element>, + algebra::Commutative<Operation, Element> +{}; + + +// SemiGroup is a refinement which must be nominal +auto concept SemiGroup<typename Operation, typename Element> + : Magma<Operation, Element>, + algebra::SemiGroup<Operation, Element> +{}; + + +auto concept CommutativeSemiGroup<typename Operation, typename Element> + : SemiGroup<Operation, Element>, + CommutativeMagma<Operation, Element> +{}; + + +// Adding identity +// auto +concept Monoid<typename Operation, typename Element> + : SemiGroup<Operation, Element>, + algebra::Monoid<Operation, Element> +{ + requires std::Convertible<identity_result_type, Element>; +}; + + +auto concept CommutativeMonoid<typename Operation, typename Element> + : CommutativeSemiGroup<Operation, Element>, + Monoid<Operation, Element> +{}; + + +concept PartiallyInvertibleMonoid<typename Operation, typename Element> + : Monoid<Operation, Element>, + algebra::Inversion<Operation, Element> +{ + typename is_invertible_result_type; + is_invertible_result_type is_invertible(Operation, Element); + requires std::Convertible<is_invertible_result_type, bool>; + + requires std::Convertible<inverse_result_type, Element>; + + // Does it overwrites the axiom from algebra::Inversion + axiom Inversivity(Operation op, Element x) + { + // Only for invertible elements: + if (is_invertible(op, x)) + op( x, inverse(op, x) ) == identity(op, x); + if ( is_invertible(op, x) ) + op( inverse(op, x), x ) == identity(op, x); + } +}; + + +auto concept PartiallyInvertibleCommutativeMonoid<typename Operation, typename Element> + : PartiallyInvertibleMonoid<Operation, Element>, + CommutativeMonoid<Operation, Element> +{}; + + +concept Group<typename Operation, typename Element> + : PartiallyInvertibleMonoid<Operation, Element>, + algebra::Group<Operation, Element> +{ + axiom AlwaysInvertible(Operation op, Element x) + { + is_invertible(op, x); + } + + axiom GlobalInversivity(Operation op, Element x) + { + // In fact this is implied by AlwaysInvertible and inherited Inversion axiom + // However, we don't rely on the compiler to deduce this + op( x, inverse(op, x) ) == identity(op, x); + op( inverse(op, x), x ) == identity(op, x); + } +}; + + +auto concept AbelianGroup<typename Operation, typename Element> + : Group<Operation, Element>, + PartiallyInvertibleCommutativeMonoid<Operation, Element>, + algebra::AbelianGroup<Operation, Element> +{}; + + +// ======================== +// Additive scalar concepts +// ======================== + + +concept AdditiveMagma<typename Element> + : Magma< math::add<Element>, Element > +{ + typename plus_assign_result_type; + plus_assign_result_type operator+=(Element& x, Element y); + // requires std::Convertible<plus_assign_result_type, Element>; + + // Operator + is by default defined with += + typename addition_result_type; + addition_result_type operator+(Element x, Element y); +#if 0 + { + Element tmp(x); + return tmp += y; defaults NYS + } +#endif + requires std::Convertible<addition_result_type, Element>; + + // Type consistency with Magma + requires std::Convertible< addition_result_type, + Magma< math::add<Element>, Element >::result_type>; + + // SameType requires more rigorous specializations on pure algebraic functors + // requires std::SameType< addition_result_type, + // Magma< math::add<Element>, Element >::result_type>; + + axiom Consistency(math::add<Element> op, Element x, Element y) + { + op(x, y) == x + y; + + // Consistency definition between + and += might change later + x + y == x += y; + // Element tmp = x; tmp+= y; tmp == x + y; not proposal-compliant + } +} + + +auto concept AdditiveCommutativeMagma<typename Element> + : AdditiveMagma<Element>, + CommutativeMagma< math::add<Element>, Element > +{}; + + +auto concept AdditiveSemiGroup<typename Element> + : AdditiveMagma<Element>, + SemiGroup< math::add<Element>, Element > +{}; + + +// We really need only one of the additive concepts for the requirements, +// the requirements of the other would be implied. +// Vice versa, to derive concept maps of nested concepts from +// concept maps of refined concepts, they are needed all. +auto concept AdditiveCommutativeSemiGroup<typename Element> + : AdditiveSemiGroup<Element>, + AdditiveCommutativeMagma<Element>, + CommutativeSemiGroup< math::add<Element>, Element > +{}; + + +concept AdditiveMonoid<typename Element> + : AdditiveSemiGroup<Element>, + Monoid< math::add<Element>, Element > +{ + Element zero(Element v); + + axiom Consistency (math::add<Element> op, Element x) + { + zero(x) == identity(op, x); + } +}; + + +// We really need only one of the additive concepts for the requirements, +// the requirements of the other would be implied. +// Vice versa, to derive concept maps of nested concepts from +// concept maps of refined concepts, they are needed all. +auto concept AdditiveCommutativeMonoid<typename Element> + : AdditiveMonoid<Element>, + AdditiveCommutativeSemiGroup<Element>, + CommutativeMonoid< math::add<Element>, Element > +{}; + + +concept AdditivePartiallyInvertibleMonoid<typename Element> + : AdditiveMonoid<Element>, + PartiallyInvertibleMonoid< math::add<Element>, Element > +{ + typename minus_assign_result_type; + minus_assign_result_type operator-=(Element& x, Element y); + // requires std::Convertible<minus_assign_result_type, Element>; + + // Operator - by default defined with -= + typename subtraction_result_type; + subtraction_result_type operator-(Element& x, Element y); +#if 0 + { + Element tmp(x); + return tmp -= y; defaults NYS + } +#endif + requires std::Convertible<subtraction_result_type, Element>; + + + typename unary_result_type; + unary_result_type operator-(Element x); +#if 0 + { + return zero(x) - x; defaults NYS + } +#endif + requires std::Convertible<unary_result_type, Element>; + + axiom Consistency(math::add<Element> op, Element x, Element y) + { + // consistency between additive and pure algebraic concept + if ( is_invertible(op, y) ) + op(x, inverse(op, y)) == x - y; + if ( is_invertible(op, y) ) + inverse(op, y) == -y; + + // consistency between unary and binary - + if ( is_invertible(op, x) ) + identity(op, x) - x == -x; + + // Might change later + if ( is_invertible(op, y) ) + x - y == x -= y; + // Element tmp = x; tmp-= y; tmp == x - y; not proposal-compliant + } + +}; + + +auto concept AdditivePartiallyInvertibleCommutativeMonoid<typename Element> + : AdditivePartiallyInvertibleMonoid<Element>, + AdditiveCommutativeMonoid<Element>, + PartiallyInvertibleCommutativeMonoid< math::add<Element>, Element > +{}; + + + +auto concept AdditiveGroup<typename Element> + : AdditivePartiallyInvertibleMonoid<Element>, + Group< math::add<Element>, Element > +{}; + + +auto concept AdditiveAbelianGroup<typename Element> + : AdditiveGroup<Element>, + AdditiveCommutativeMonoid<Element>, + AbelianGroup< math::add<Element>, Element > +{}; + + +// ============================ +// Multiplitive scalar concepts +// ============================ + + +concept MultiplicativeMagma<typename Element> + : Magma< math::mult<Element>, Element > +{ + typename mult_assign_result_type; + mult_assign_result_type operator*=(Element& x, Element y); + // requires std::Convertible<mult_assign_result_type, Element>; + + // Operator * is by default defined with *= + typename mult_result_type; + mult_result_type operator*(Element x, Element y); +#if 0 + { + Element tmp(x); + return tmp *= y; defaults NYS + } +#endif + requires std::Convertible<mult_result_type, Element>; + + // Type consistency with Magma + requires std::Convertible< mult_result_type, + Magma< math::mult<Element>, Element >::result_type>; + + // SameType requires more rigorous specializations on pure algebraic functors + // requires std::SameType< mult_result_type, + // Magma< math::mult<Element>, Element >::result_type>; + + + axiom Consistency(math::mult<Element> op, Element x, Element y) + { + op(x, y) == x * y; + + // Consistency definition between * and *= might change later + x * y == x *= y; + // Element tmp = x; tmp*= y; tmp == x * y; not proposal-compliant + } + +} + + +auto concept MultiplicativeSemiGroup<typename Element> + : MultiplicativeMagma<Element>, + SemiGroup< math::mult<Element>, Element > +{}; + + +auto concept MultiplicativeCommutativeSemiGroup<typename Element> + : MultiplicativeSemiGroup<Element>, + CommutativeSemiGroup< math::mult<Element>, Element > +{}; + + +concept MultiplicativeMonoid<typename Element> + : MultiplicativeSemiGroup<Element>, + Monoid< math::mult<Element>, Element > +{ + Element one(Element v); + + axiom Consistency (math::mult<Element> op, Element x) + { + one(x) == identity(op, x); + } +}; + + +auto concept MultiplicativeCommutativeMonoid<typename Element> + : MultiplicativeMonoid<Element>, + MultiplicativeCommutativeSemiGroup<Element>, + CommutativeMonoid< math::mult<Element>, Element > +{}; + + +concept MultiplicativePartiallyInvertibleMonoid<typename Element> + : MultiplicativeMonoid<Element>, + PartiallyInvertibleMonoid< math::mult<Element>, Element > +{ + typename divide_assign_result_type; + divide_assign_result_type operator/=(Element& x, Element y); + // requires std::Convertible<divide_assign_result_type, Element>; + + // Operator / by default defined with /= + typename division_result_type = Element; + division_result_type operator/(Element x, Element y); +#if 0 + { + Element tmp(x); + return tmp /= y; defaults NYS + } +#endif + requires std::Convertible<division_result_type, Element>; + + axiom Consistency(math::mult<Element> op, Element x, Element y) + { + // consistency between multiplicative and pure algebraic concept + if ( is_invertible(op, y) ) + op(x, inverse(op, y)) == x / y; + + // Consistency between / and /=, might change later + if ( is_invertible(op, y) ) + x / y == x /= y; + // Element tmp = x; tmp/= y; tmp == x / y; not proposal-compliant + } +}; + + +auto concept MultiplicativePartiallyInvertibleCommutativeMonoid<typename Element> + : MultiplicativePartiallyInvertibleMonoid<Element>, + MultiplicativeCommutativeMonoid<Element>, + PartiallyInvertibleCommutativeMonoid< math::mult<Element>, Element > +{}; + + +auto concept MultiplicativeGroup<typename Element> + : MultiplicativeMonoid<Element>, + Group< math::mult<Element>, Element > +{}; + + +auto concept MultiplicativeAbelianGroup<typename Element> + : MultiplicativeGroup<Element>, + MultiplicativeCommutativeMonoid<Element>, + AbelianGroup< math::mult<Element>, Element > +{}; + + +// ====================================== +// Algebraic concepts with two connectors +// ====================================== + +// ----------------- +// Based on functors +// ----------------- + +// More generic, less handy to use + +auto concept GenericRing<typename AddOp, typename MultOp, typename Element> + : AbelianGroup<AddOp, Element>, + SemiGroup<MultOp, Element>, + algebra::Ring<AddOp, MultOp, Element> +{}; + + +auto concept GenericCommutativeRing<typename AddOp, typename MultOp, typename Element> + : GenericRing<AddOp, MultOp, Element>, + CommutativeSemiGroup<MultOp, Element> +{}; + + +auto concept GenericRingWithIdentity<typename AddOp, typename MultOp, typename Element> + : GenericRing<AddOp, MultOp, Element>, + Monoid<MultOp, Element>, + algebra::RingWithIdentity<AddOp, MultOp, Element> +{}; + + +auto concept GenericCommutativeRingWithIdentity<typename AddOp, typename MultOp, typename Element> + : GenericRingWithIdentity<AddOp, MultOp, Element>, + GenericCommutativeRing<AddOp, MultOp, Element>, + CommutativeMonoid<MultOp, Element> +{}; + + +// auto +concept GenericDivisionRing<typename AddOp, typename MultOp, typename Element> + : GenericRingWithIdentity<AddOp, MultOp, Element>, + algebra::DivisionRing<AddOp, MultOp, Element> +{ + requires std::Convertible<inverse_result_type, Element>; +}; + + +auto concept GenericField<typename AddOp, typename MultOp, typename Element> + : GenericDivisionRing<AddOp, MultOp, Element>, + GenericCommutativeRingWithIdentity<AddOp, MultOp, Element>, + algebra::Field<AddOp, MultOp, Element> +{}; + + +// ------------------ +// Based on operators +// ------------------ + +// Handier, less generic + +// Alternative definitions use MultiplicativeMonoid<Element> for Ring +// and call such concepts Pseudo-Ring + + +auto concept Ring<typename Element> + : AdditiveAbelianGroup<Element>, + MultiplicativeSemiGroup<Element>, + GenericRing<math::add<Element>, math::mult<Element>, Element> +{}; + + +auto concept CommutativeRing<typename Element> + : Ring<Element>, + MultiplicativeCommutativeSemiGroup<Element>, + GenericCommutativeRing<math::add<Element>, math::mult<Element>, Element> +{}; + + +auto concept RingWithIdentity<typename Element> + : Ring<Element>, + MultiplicativeMonoid<Element>, + GenericRingWithIdentity<math::add<Element>, math::mult<Element>, Element> +{}; + + +auto concept CommutativeRingWithIdentity<typename Element> + : RingWithIdentity<Element>, + CommutativeRing<Element>, + MultiplicativeCommutativeMonoid<Element>, + GenericCommutativeRingWithIdentity<math::add<Element>, math::mult<Element>, Element> +{}; + + +concept DivisionRing<typename Element> + : RingWithIdentity<Element>, + MultiplicativePartiallyInvertibleMonoid<Element>, + GenericDivisionRing<math::add<Element>, math::mult<Element>, Element> +{ + axiom NonZeroDivisibility(Element x) + { + if (x != zero(x)) + x / x == one(x); + } +}; + + +auto concept Field<typename Element> + : DivisionRing<Element>, + CommutativeRingWithIdentity<Element>, + GenericField<math::add<Element>, math::mult<Element>, Element> +{}; + + +// ====================== +// Miscellaneous concepts +// ====================== + +// that shall find a better place later + + +// EqualityComparable will have the != when defaults are supported +// At this point the following won't needed anymore +auto concept FullEqualityComparable<typename T, typename U = T> +{ + //requires std::EqualityComparable<T, U>; + + bool operator==(const T&, const U&); + bool operator!=(const T&, const U&); +}; + +// Closure of EqualityComparable under a binary operation: +// That is, the result of this binary operation is also EqualityComparable +// with itself and with the operand type. +auto concept Closed2EqualityComparable<typename Operation, typename Element> + : BinaryIsoFunction<Operation, Element> +{ + requires FullEqualityComparable<Element>; + requires FullEqualityComparable< BinaryIsoFunction<Operation, Element>::result_type >; + requires FullEqualityComparable< Element, BinaryIsoFunction<Operation, Element>::result_type >; + requires FullEqualityComparable< BinaryIsoFunction<Operation, Element>::result_type, Element >; +}; + + +// LessThanComparable will have the other operators when defaults are supported +// At this point the following won't needed anymore +auto concept FullLessThanComparable<typename T, typename U = T> +{ + bool operator<(const T&, const U&); + bool operator<=(const T&, const U&); + bool operator>(const T&, const U&); + bool operator>=(const T&, const U&); +}; + + +// Same for LessThanComparable +auto concept Closed2LessThanComparable<typename Operation, typename Element> + : BinaryIsoFunction<Operation, Element> +{ + requires FullLessThanComparable<Element>; + requires FullLessThanComparable< BinaryIsoFunction<Operation, Element>::result_type >; + requires FullLessThanComparable< Element, BinaryIsoFunction<Operation, Element>::result_type >; + requires FullLessThanComparable< BinaryIsoFunction<Operation, Element>::result_type, Element >; +}; + +#if 0 +auto concept NumericOperatorResultConvertible<typename T> + : AddableWithAssign<T>, + SubtractableWithAssign<T>, + MultiplicableWithAssign<T>, + DivisibleWithAssign<T> +{ + requires std::Convertible< AddableWithAssign<T>::result_type, T>; + requires std::Convertible< SubtractableWithAssign<T>::result_type, T>; + requires std::Convertible< MultiplicableWithAssign<T>::result_type, T>; + requires std::Convertible< DivisibleWithAssign<T>::result_type, T>; +} +#endif + +auto concept AdditionResultConvertible<typename T> +{ + typename result_type; + result_type operator+(T t, T u); + requires std::Convertible<result_type, T>; + + typename result_type; + result_type operator+=(T& t, T u); + requires std::Convertible<result_type, T>; +}; + + +auto concept SubtractionResultConvertible<typename T> +{ + typename result_type; + result_type operator-(T t, T u); + requires std::Convertible<result_type, T>; + + typename result_type; + result_type operator-=(T& t, T u); + requires std::Convertible<result_type, T>; +}; + +auto concept NumericOperatorResultConvertible<typename T> + : AdditionResultConvertible<T>, + SubtractionResultConvertible<T> +{}; + +// ==================== +// Default Concept Maps +// ==================== + +#ifndef LA_NO_CONCEPT_MAPS + +// ============== +// Integral Types +// ============== + +template <typename T> + requires IntrinsicSignedIntegral<T> +concept_map CommutativeRingWithIdentity<T> {} + + +template <typename T> + requires IntrinsicUnsignedIntegral<T> +concept_map AdditiveCommutativeMonoid<T> {} + +template <typename T> + requires IntrinsicUnsignedIntegral<T> +concept_map MultiplicativeCommutativeMonoid<T> {} + + +// ==================== +// Floating Point Types +// ==================== + +template <typename T> + requires IntrinsicFloatingPoint<T> +concept_map Field<T> {} + + +template <typename T> + requires IntrinsicFloatingPoint<T> +concept_map Field< std::complex<T> > {} + + +// =========== +// Min and Max +// =========== + +// Draft version: defined generously unless there will be problems with some types + +template <typename Element> +concept_map CommutativeMonoid< max<Element>, Element > +{ + // Why do we need this? + typedef Element identity_result_type; +} + +template <typename Element> +concept_map CommutativeMonoid< min<Element>, Element > +{ + // Why do we need this? + typedef Element identity_result_type; +} + +#endif // LA_NO_CONCEPT_MAPS + +// Here come some mathematical concepts to be defined later + +/// Specify the semantic Behavior of natural numbers (TBD) +/** Mathematic properties are in most cases only approximated + but not held exactly. Rigorous definition would impede + usage of real processors. **/ +concept NaturalNumber<typename T> {} + +/// Specify the semantic Behavior of integral numbers (TBD) +/** Mathematic properties are in most cases only approximated + but not held exactly. Rigorous definition would impede + usage of real processors. + It is arguable if this is really a refinement **/ +concept IntegralNumber<typename T> : NaturalNumber<T> {} + +/// Specify the semantic Behavior of complex numbers (TBD) +/** Mathematic properties are in most cases only approximated + but not held exactly. Rigorous definition would impede + usage of real processors. **/ +concept ComplexNumber<typename T> {} + +/// Specify the semantic Behavior of real numbers (TBD) +/** Mathematic properties are in most cases only approximated + but not held exactly. Rigorous definition would impede + usage of real processors. **/ +concept RealNumber<typename T> : ComplexNumber<T> {} + +#endif // __GXX_CONCEPTS__ + + + + +// ================================================= +// Concept to specify return type of abs (and norms) +// ================================================= + + +#ifdef __GXX_CONCEPTS__ + +// Concept to specify to specify projection of scalar value to comparable type +// For instance as return type of abs +// Minimalist definition for maximal applicability +auto concept Magnitude<typename T> +{ + typename type = T; +}; + +template <typename T> +concept_map Magnitude<std::complex<T> > +{ + typedef T type; +} + + +// Concept for norms etc., which are real values in mathematical definitions +auto concept RealMagnitude<typename T> + : Magnitude<T> +{ + requires FullEqualityComparable<type>; + requires FullLessThanComparable<type>; + + requires Field<type>; + + type sqrt(type); + // typename sqrt_result; + // sqrt_result sqrt(type); + // requires std::Convertible<sqrt_result, type>; + + // using std::abs; + type abs(T); +} + +#else // now without concepts + +template <typename T> +struct Magnitude +{ + typename type = T; +}; + +template <typename T> +struct Magnitude<std::complex<T> > +{ + typedef T type; +} + +template <typename T> struct RealMagnitude + : public Magnitude<T> +{} + +#endif // __GXX_CONCEPTS__ + +// Type trait version both available with and w/o concepts (TBD: Macro finally :-( ) +// For the moment everything is its own magnitude type, unless stated otherwise +template <typename T> +struct magnitude_type_trait +{ + typedef T type; +}; + +template <typename T> +struct magnitude_type_trait< std::complex<T> > +{ + typedef T type; +}; + + +// ========================================= +// Concepts for convenience (many from Rolf) +// ========================================= + + +#ifdef __GXX_CONCEPTS__ + +//The following concepts Addable, Subtractable etc. differ from std::Addable, std::Subtractable +//etc. in so far that no default for result_type is provided, thus allowing automated return type deduction + +auto concept Addable<typename T, typename U = T> +{ + typename result_type; + result_type operator+(const T& t, const U& u); +}; + + +// Usually + and += are both defined +// + can be efficiently derived from += but not vice versa +auto concept AddableWithAssign<typename T, typename U = T> +{ + typename assign_result_type; + assign_result_type operator+=(T& x, U y); + + // Operator + is by default defined with += + typename result_type; + result_type operator+(T x, U y); +#if 0 + { + // Default requires std::CopyConstructible, without default not needed + Element tmp(x); + return tmp += y; defaults NYS + } +#endif +}; + + +auto concept Subtractable<typename T, typename U = T> +{ + typename result_type; + result_type operator-(const T& t, const U& u); +}; + + +// Usually - and -= are both defined +// - can be efficiently derived from -= but not vice versa +auto concept SubtractableWithAssign<typename T, typename U = T> +{ + typename assign_result_type; + assign_result_type operator-=(T& x, U y); + + // Operator - is by default defined with -= + typename result_type; + result_type operator-(T x, U y); +#if 0 + { + // Default requires std::CopyConstructible, without default not needed + Element tmp(x); + return tmp -= y; defaults NYS + } +#endif +}; + + +auto concept Multiplicable<typename T, typename U = T> +{ + typename result_type; + result_type operator*(const T& t, const U& u); +}; + + +// Usually * and *= are both defined +// * can be efficiently derived from *= but not vice versa +auto concept MultiplicableWithAssign<typename T, typename U = T> +{ + typename assign_result_type; + assign_result_type operator*=(T& x, U y); + + // Operator * is by default defined with *= + typename result_type; + result_type operator*(T x, U y); +#if 0 + { + // Default requires std::CopyConstructible, without default not needed + Element tmp(x); + return tmp *= y; defaults NYS + } +#endif +}; + + +auto concept Divisible<typename T, typename U = T> +{ + typename result_type; + result_type operator / (const T&, const U&); +}; + + +// Usually * and *= are both defined +// * can be efficiently derived from *= but not vice versa +auto concept DivisibleWithAssign<typename T, typename U = T> +{ + typename assign_result_type; + assign_result_type operator*=(T& x, U y); + + // Operator * is by default defined with *= + typename result_type; + result_type operator*(T x, U y); +#if 0 + { + // Default requires std::CopyConstructible, without default not needed + Element tmp(x); + return tmp *= y; defaults NYS + } +#endif +}; + + +auto concept Transposable<typename T> +{ + typename result_type; + result_type trans(T&); +}; + + +// Unary Negation -> Any suggestions for better names?! Is there a word as "negatable"?! +auto concept Negatable<typename S> +{ + typename result_type = S; + result_type operator-(const S&); +}; + +// Or HasAbs? +using std::abs; +auto concept AbsApplicable<typename S> +{ + // There are better ways to define abs than the way it is done in std + // Likely we replace the using one day + typename result_type; + result_type abs(const S&); +}; + + +using std::conj; +auto concept HasConjugate<typename S> +{ + typename result_type; + result_type conj(const S&); +}; + + +// We need the following; might be placed somewhere else later +template <Float T> +concept_map HasConjugate<T> +{ + typedef T result_type; + result_type conj(const T& s) {return s;} +} + + + +// Dot product to be defined: +auto concept Dottable<typename T, typename U = T> +{ + typename result_type = T; + result_type dot(const T&t, const U& u); +}; + + +auto concept OneNormApplicable<typename V> +{ + typename result_type; + result_type one_norm(const V&); +}; + + +auto concept TwoNormApplicable<typename V> +{ + typename result_type; + result_type two_norm(const V&); +}; + + +auto concept InfinityNormApplicable<typename V> +{ + typename result_type; + result_type inf_norm(const V&); +}; + + + + +#endif // __GXX_CONCEPTS__ + + +} // namespace math + + + +#endif // LA_CONCEPTS_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/operators.hpp b/install/MTL/include/boost/numeric/linear_algebra/operators.hpp new file mode 100644 index 00000000..e58051f7 --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/operators.hpp @@ -0,0 +1,156 @@ +// Copyright 2006. Peter Gottschling, Matthias Troyer, Rolf Bonderer +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MATH_OPERATORS_INCLUDE +#define MATH_OPERATORS_INCLUDE + +#include <functional> + +#ifndef MATH_DEFAULT_FUNCTORS_WITH_CONCEPTS +namespace math { + +template <typename Element> +struct add : public std::binary_function<Element, Element, Element> +{ + Element operator() (const Element& x, const Element& y) + { + return x + y; + } +}; + + +// Heterogeneous addition, i.e. addends and result type may be different +template <typename A1, typename A2, typename R> +struct heterogeneous_add + : public std::binary_function<A1, A2, R> +{ + R operator() (const A1& x, const A2& y) + { + return x + y; + } +}; + + +// The results of char and short additions are int, dito unsigned +template <> struct add<char> : heterogeneous_add<char, char, int> {}; +template <> struct add<short> : heterogeneous_add<short, short, int> {}; +template <> struct add<unsigned char> : heterogeneous_add<unsigned char, unsigned char, unsigned int> {}; +template <> struct add<unsigned short> : heterogeneous_add<unsigned short, unsigned short, unsigned int> {}; + + +template <typename Element> +struct mult : public std::binary_function<Element, Element, Element> +{ + Element operator() (const Element& x, const Element& y) + { + return x * y; + } +}; + + +template <typename A1, typename A2, typename R> +struct heterogeneous_mult + : public std::binary_function<A1, A2, R> +{ + R operator() (const A1& x, const A2& y) + { + return x * y; + } +}; + + +// The results of char and short multiplications are int, dito unsigned +template <> struct mult<char> : heterogeneous_mult<char, char, int> {}; +template <> struct mult<short> : heterogeneous_mult<short, short, int> {}; +template <> struct mult<unsigned char> : heterogeneous_mult<unsigned char, unsigned char, unsigned int> {}; +template <> struct mult<unsigned short> : heterogeneous_mult<unsigned short, unsigned short, unsigned int> {}; + +#else + +// Now the same with concepts + +template <typename Element> + requires std::HasPlus<Element> +struct add : public std::binary_function<Element, Element, result_type> +{ + result_type operator() (const Element& x, const Element& y) + { + return x + y; + } +}; + +template <typename Element> + requires std::HasMultiply<Element> +struct mult : public std::binary_function<Element, Element, result_type> +{ + result_type operator() (const Element& x, const Element& y) + { + return x * y; + } +}; + + + + +#endif // MATH_DEFAULT_FUNCTORS_WITH_CONCEPTS + +template <typename Element> +struct min : public std::binary_function<Element, Element, Element> +{ + Element operator() (const Element& x, const Element& y) + { + return x <= y ? x : y; + } +}; + + +template <typename Element> +struct max : public std::binary_function<Element, Element, Element> +{ + Element operator() (const Element& x, const Element& y) + { + return x >= y ? x : y; + } +}; + +template <typename Element> +struct bitwise_and : public std::binary_function<Element, Element, Element> +{ + Element operator() (const Element& x, const Element& y) + { + return x & y; + } +}; + +template <typename Element> +struct bitwise_or : public std::binary_function<Element, Element, Element> +{ + Element operator() (const Element& x, const Element& y) + { + return x | y; + } +}; + +template <typename Element> +struct bitwise_xor : public std::binary_function<Element, Element, Element> +{ + Element operator() (const Element& x, const Element& y) + { + return x ^ y; + } +}; + + +} // namespace math + +#endif // MATH_OPERATORS_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/power.hpp b/install/MTL/include/boost/numeric/linear_algebra/power.hpp new file mode 100644 index 00000000..d3ee807e --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/power.hpp @@ -0,0 +1,198 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MATH_POWER_INCLUDE +#define MATH_POWER_INCLUDE + +#include <concepts> +#include <boost/numeric/linear_algebra/concepts.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <stdexcept> + + +namespace math { + + template <typename Op, std::Semiregular Element, Integral Exponent> + requires std::Callable2<Op, Element, Element> + && std::Convertible<std::Callable2<Op, Element, Element>::result_type, Element> + inline Element power(const Element& a, Exponent n, Op op) + { + std::cout << "[Magma] "; + if (n < 1) throw std::range_error("power [magma]: n must be > 0"); + + Element value= a; + for (; n > 1; --n) + value= op(value, a); + return value; + } + +#if 0 + template <typename Op, std::Semiregular Element, Integral Exponent> + requires SemiGroup<Op, Element> + && std::Callable2<Op, Element, Element> + && std::Convertible<std::Callable2<Op, Element, Element>::result_type, Element> + inline Element multiply_and_square_horner(const Element& a, Exponent n, Op op) + { + if (n < 1) throw std::range_error("mult&square Horner: n must be > 0"); + + // Set mask to highest bit + Exponent mask= 1 << (8 * sizeof(mask) - 1); + + // If this is a negative number right shift can insert 1s instead of 0s -> infinite loop + // Therefore we take the 2nd-highest bit + if (mask < 0) + mask= 1 << (8 * sizeof(mask) - 2); + + // Find highest 1 bit + while(!bool(mask & n)) mask>>= 1; + + Element value= a; + for (mask>>= 1; mask; mask>>= 1) { + value= op(value, value); + if (n & mask) + value= op(value, a); + } + return value; + } + + template <typename Op, std::Semiregular Element, Integral Exponent> + requires SemiGroup<Op, Element> + && std::Callable2<Op, Element, Element> + && std::Convertible<std::Callable2<Op, Element, Element>::result_type, Element> + inline Element power(const Element& a, Exponent n, Op op) + { + return multiply_and_square_horner(a, n, op); + } +#endif + + +#if 1 + // With Horner scheme we can avoid recursion + // This one is more intuitive (I believe) + template <typename Op, std::Semiregular Element, Integral Exponent> + requires SemiGroup<Op, Element> + && std::Callable2<Op, Element, Element> + && std::Convertible<std::Callable2<Op, Element, Element>::result_type, Element> + inline Element power(const Element& a, Exponent n, Op op) + { + std::cout << "[SemiGroup] "; + if (n < 1) throw std::range_error("power [SemiGroup]: n must be > 0"); + + Exponent half(n / 2); + // If half is 0 then n must be 1 and the result is a + if (half == 0) + return a; + + // Compute power of downward rounded exponent and "square" the result + Element value= power(a, half, op); + value= op(value, value); + + // If n is odd another operation with a is needed + if (n & 1) + value= op(value, a); + return value; + } +#endif + + + + template <typename Op, std::Semiregular Element, Integral Exponent> + requires Monoid<Op, Element> + && std::Callable2<Op, Element, Element> + && std::Convertible<std::Callable2<Op, Element, Element>::result_type, Element> + inline Element multiply_and_square(const Element& a, Exponent n, Op op) + { + // Same as the simpler form except that the first multiplication is made before + // the loop and one squaring is saved this way + if (n < 0) throw std::range_error("mult&square: n must be >= 0"); + + using math::identity; + Element value= bool(n & 1) ? Element(a) : Element(identity(op, a)), square= a; + + for (n>>= 1; n > 0; n>>= 1) { + square= op(square, square); + if (n & 1) + value= op(value, square); + } + return value; + } + + + template <typename Op, std::Semiregular Element, Integral Exponent> + requires Monoid<Op, Element> + && std::Callable2<Op, Element, Element> + && std::Convertible<std::Callable2<Op, Element, Element>::result_type, Element> + inline Element power(const Element& a, Exponent n, Op op) + { + std::cout << "[Monoid] "; + return multiply_and_square(a, n, op); + } + + + + + template <typename Op, std::Semiregular Element, Integral Exponent> + requires PIMonoid<Op, Element> + && std::Callable2<Op, Element, Element> + && std::Convertible<std::Callable2<Op, Element, Element>::result_type, Element> + inline Element power(const Element& a, Exponent n, Op op) + { + std::cout << "[PIMonoid] "; + if (n < 0 && !is_invertible(op, a)) + throw std::range_error("power [PIMonoid]: a must be invertible with n < 0"); + + return n < 0 ? multiply_and_square(Element(inverse(op, a)), Exponent(-n), op) + : multiply_and_square(a, n, op); + } + +#if 1 + template <typename Op, std::Semiregular Element, Integral Exponent> + requires Group<Op, Element> + && std::Callable2<Op, Element, Element> + && std::Convertible<std::Callable2<Op, Element, Element>::result_type, Element> + inline Element power(const Element& a, Exponent n, Op op) + { + std::cout << "[Group] "; + // For groups we don't need any range test + + return n < 0 ? multiply_and_square(Element(inverse(op, a)), Exponent(-n), op) + : multiply_and_square(a, n, op); + } +#endif + + +#if 0 + template <typename Op, typename Element, typename Exponent> + requires Group<Op, Element> + && Integral<Exponent> + && std::Semiregular<Element> + && std::Callable2<Op, Element, Element> + && std::Convertible<std::Callable2<Op, Element, Element>::result_type, Element> + && std::Semiregular<math::Inversion<Op, Element>::result_type> + && std::HasNegate<Exponent> + && math::Monoid<Op, math::Inversion<Op, Element>::result_type> + && Integral< std::HasNegate<Exponent>::result_type> + && std::Callable2<Op, math::Inversion<Op, Element>::result_type, + math::Inversion<Op, Element>::result_type> + && std::Convertible<std::Callable2<Op, math::Inversion<Op, Element>::result_type, + math::Inversion<Op, Element>::result_type>::result_type, + math::Inversion<Op, Element>::result_type> + inline Element power(const Element& a, Exponent n, Op op) + { + return n < 0 ? multiply_and_square(inverse(op, a), -n, op) + : multiply_and_square(a, n, op); + } +#endif + +} // namespace math + +#endif // MATH_POWER_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/pseudo_concept.hpp b/install/MTL/include/boost/numeric/linear_algebra/pseudo_concept.hpp new file mode 100644 index 00000000..5506a202 --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/pseudo_concept.hpp @@ -0,0 +1,34 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef PSEUDO_CONCEPT_INCLUDE +#define PSEUDO_CONCEPT_INCLUDE + +/** @addtogroup Concepts + * @{ + */ + +#ifndef __GXX_CONCEPTS__ + +//! Pseudo type for invariants in concepts +/// Pseudo type used to document invariants in concepts +struct axiom {}; + +//! Pseudo type used to document associated types in concepts +/// Pseudo type for associated types in concepts +struct associated_type {}; + +#endif // __GXX_CONCEPTS__ + +/*@}*/ // end of group Concepts + +#endif // PSEUDO_CONCEPT_INCLUDE diff --git a/install/MTL/include/boost/numeric/linear_algebra/vector_concepts.hpp b/install/MTL/include/boost/numeric/linear_algebra/vector_concepts.hpp new file mode 100644 index 00000000..0f37105c --- /dev/null +++ b/install/MTL/include/boost/numeric/linear_algebra/vector_concepts.hpp @@ -0,0 +1,508 @@ +// Copyright 2006. Peter Gottschling, Matthias Troyer, Rolf Bonderer +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef LA_VECTOR_CONCEPTS_INCLUDE +#define LA_VECTOR_CONCEPTS_INCLUDE + + +#include <boost/numeric/linear_algebra/concepts.hpp> +#include <boost/numeric/linear_algebra/ets_concepts.hpp> + +#ifdef __GXX_CONCEPTS__ +# include <concepts> +#else +# include <boost/numeric/linear_algebra/pseudo_concept.hpp> +#endif + + +namespace math { + +/** @addtogroup Concepts + * @{ + */ + +#ifdef __GXX_CONCEPTS__ +concept VectorSpace<typename Vector, typename Scalar = typename Vector::value_type> +: AdditiveAbelianGroup<Vector> +{ + requires Field<Scalar>; + requires Multiplicable<Scalar, Vector>; + requires MultiplicableWithAssign<Vector, Scalar>; + requires DivisibleWithAssign<Vector, Scalar>; + + requires std::Assignable<Vector, Multiplicable<Scalar, Vector>::result_type>; + requires std::Assignable<Vector, Multiplicable<Vector, Scalar>::result_type>; + requires std::Assignable<Vector, Divisible<Vector, Scalar>::result_type>; + + // Associated types of Field<Scalar> and AdditiveAbelianGroup<Vector> collide + // typename result_type = AdditiveAbelianGroup<Vector>::result_type; + // typename assign_result_type = AdditiveAbelianGroup<Vector>::assign_result_type; + + axiom Distributivity(Vector v, Vector w, Scalar a, Scalar b) + { + a * (v + w) == a * v + a * w; + (a + b) * v == a * v + b * v; + // The following properties are implied by the above, Field and Abelian group + // Can we be sure that compilers can deduce/interfere it? + (v + w) * a == v * a + w * a; + v * (a + b) == v * a + v * b; + } +} +#else + //! Concept VectorSpace + /*! + \param Vector The the type of a vector or a collection + \param Scalar The scalar over which the vector field is defined + + \par Requires: + - Field < Scalar >; + - Multiplicable <Scalar, Vector>; + - MultiplicableWithAssign <Vector, Scalar>; + - DivisibleWithAssign <Vector, Scalar>; + - std::Assignable <Vector, Multiplicable<Scalar, Vector>::result_type>; + - std::Assignable <Vector, Multiplicable<Vector, Scalar>::result_type>; + - std::Assignable <Vector, Divisible<Vector, Scalar>::result_type>; + + */ + template <typename Vector, typename Scalar = typename Vector::value_type> + struct VectorSpace + : AdditiveAbelianGroup<Vector> + { + /// Invariant: Distributivity of scalars and vectors from left and from right + axiom Distributivity(Vector v, Vector w, Scalar a, Scalar b) + { + /// a * (v + w) == a * v + a * w; // Scalar from left + + /// Vector from right: (a + b) * v == a * v + b * v; + + /// Scalar from right: (v + w) * a == v * a + w * a; + + /// Vector from left: v * (a + b) == v * a + v * b; + } + }; +#endif + +#ifdef __GXX_CONCEPTS__ +concept Norm<typename N, typename Vector, + typename Scalar = typename Vector::value_type> + : std::Callable1<N, Vector> +{ + requires VectorSpace<Vector, Scalar>; + requires RealMagnitude<Scalar>; + typename magnitude_type = MagnitudeType<Scalar>::type; + requires std::Convertible<magnitude_type, Scalar>; + + typename result_type_norm = std::Callable1<N, Vector>::result_type; + requires std::Convertible<result_type_norm, RealMagnitude<Scalar>::magnitude_type>; + requires std::Convertible<result_type_norm, Scalar>; + + // Version with function instead functor, as used by Rolf and Matthias + // Axioms there defined without norm functor and concept has only 2 types +#if 0 + typename result_type_norm; + result_type_norm norm(const Vector&); + requires std::Convertible<result_type_norm, magnitude_type>; + requires std::Convertible<result_type_norm, Scalar>; +#endif + + axiom Positivity(N norm, Vector v, magnitude_type ref) + { + norm(v) >= zero(ref); + } + + // The following is covered by RealMagnitude + // requires AbsApplicable<Scalar>; + // requires std::Convertible<AbsApplicable<Scalar>::result_type, magnitude_type>; + // requires Multiplicable<magnitude_type>; + + axiom PositiveHomogeneity(N norm, Vector v, Scalar a) + { + norm(a * v) == abs(a) * norm(v); + } + + axiom TriangleInequality(N norm, Vector u, Vector v) + { + norm(u + v) <= norm(u) + norm(v); + } +} +#else + //! Concept Norm + /*! + Semantic requirements of a norm + + \param N Norm functor + \param Vector The the type of a vector or a collection + \param Scalar The scalar over which the vector field is defined + + \par Refinement of: + - std::Callable1 <N, Vector> + + \par Associated types: + - magnitude_type + - result_type_norm + + \par Requires: + - VectorSpace <Vector, Scalar>; + - RealMagnitude < Scalar >; + - std::Convertible <magnitude_type, Scalar>; + - std::Convertible <result_type_norm, RealMagnitude<Scalar>::magnitude_type>; + - std::Convertible <result_type_norm, Scalar>; + + */ +template <typename N, typename Vector, + typename Scalar = typename Vector::value_type> +struct Norm + : std::Callable1<N, Vector> +{ + /// Associated type to represent real values in teh Field of scalar (with default) + /** By default MagnitudeType<Scalar>::type */ + typedef associated_type magnitude_type; + + /// Associated type for result of norm functor + /** Automatically detected */ + typedef associated_type result_type_norm; + + /// Invariant: norm of vector is larger than zero + axiom Positivity(N norm, Vector v, magnitude_type ref) + { + /// norm(v) >= zero(ref); + } + + /// Invariant: positive homogeneity with scalar + axiom PositiveHomogeneity(N norm, Vector v, Scalar a) + { + /// norm(a * v) == abs(a) * norm(v); + } + + /// Invariant: triangle inequality + axiom TriangleInequality(N norm, Vector u, Vector v) + { + /// norm(u + v) <= norm(u) + norm(v); + } +}; +#endif + + +#ifdef __GXX_CONCEPTS__ +concept SemiNorm<typename N, typename Vector, + typename Scalar = typename Vector::value_type> + : Norm<N, Vector, Scalar> +{ + axiom PositiveDefiniteness(N norm, Vector v, magnitude_type ref) + { + if (norm(v) == zero(ref)) + v == zero(v); + if (v == zero(v)) + norm(v) == zero(ref); + } +} +#else + //! Concept SemiNorm + /*! + Semantic requirements of a semi-norm + + \param N Norm functor + \param Vector The the type of a vector or a collection + \param Scalar The scalar over which the vector field is defined + + \par Refinement of: + - Norm <N, Vector, Scalar> + */ +template <typename N, typename Vector, + typename Scalar = typename Vector::value_type> +struct SemiNorm + : Norm<N, Vector, Scalar> +{ + /// The norm of a vector is zero if and only if the vector is the zero vector + axiom PositiveDefiniteness(N norm, Vector v, magnitude_type ref) + { + /// if (norm(v) == zero(ref)) v == zero(v); + + /// if (v == zero(v)) norm(v) == zero(ref); + } +}; +#endif + +#ifdef __GXX_CONCEPTS__ +concept BanachSpace<typename N, typename Vector, + typename Scalar = typename Vector::value_type> + : Norm<N, Vector, Scalar>, + VectorSpace<Vector, Scalar> +{}; +#else + //! Concept BanachSpace + /*! + A Banach space is a vector space with a norm + + \param N Norm functor + \param Vector The the type of a vector or a collection + \param Scalar The scalar over which the vector field is defined + + \par Refinement of: + - Norm <N, Vector, Scalar> + - VectorSpace <Vector, Scalar> + + \note + - The (expressible) requirements of Banach Space are already given in Norm. + - The difference between the requirements is the completeness of the + Banach space, i.e. that every Cauchy sequence w.r.t. norm(v-w) has a limit + in the space. Unfortunately, completeness is never satisfied for + finite precision arithmetic types. + - Another subtle difference is that Norm is not a refinement of Vectorspace + */ +template <typename N, typename Vector, + typename Scalar = typename Vector::value_type> +struct BanachSpace + : Norm<N, Vector, Scalar>, + VectorSpace<Vector, Scalar> +{}; +#endif + + +#ifdef __GXX_CONCEPTS__ +concept InnerProduct<typename I, typename Vector, + typename Scalar = typename Vector::value_type> + : std::Callable2<I, Vector, Vector> +{ + // Result of the inner product must be convertible to Scalar + requires std::Convertible<std::Callable2<I, Vector, Vector>::result_type, Scalar>; + + // Let's try without this + // requires ets::InnerProduct<I, Vector, Scalar>; + + requires HasConjugate<Scalar>; + + axiom ConjugateSymmetry(I inner, Vector v, Vector w) + { + inner(v, w) == conj(inner(w, v)); + } + + axiom SequiLinearity(I inner, Scalar a, Scalar b, Vector u, Vector v, Vector w) + { + inner(v, b * w) == b * inner(v, w); + inner(u, v + w) == inner(u, v) + inner(u, w); + // This implies the following (will compilers infere/deduce?) + inner(a * v, w) == conj(a) * inner(v, w); + inner(u + v, w) == inner(u, w) + inner(v, w); + } + + requires RealMagnitude<Scalar>; + typename magnitude_type = RealMagnitude<Scalar>::type; + // requires FullLessThanComparable<magnitude_type>; + + axiom NonNegativity(I inner, Vector v, MagnitudeType<Scalar>::type magnitude) + { + // inner(v, v) == conj(inner(v, v)) implies inner(v, v) is real + // ergo representable as magnitude type + magnitude_type(inner(v, v)) >= zero(magnitude) + } + + axiom NonDegeneracy(I inner, Vector v, Vector w, Scalar s) + { + if (v == zero(v)) + inner(v, w) == zero(s); + if (inner(v, w) == zero(s)) + v == zero(v); + } +}; +#else + //! Concept InnerProduct + /*! + Semantic requirements of a inner product + + \param I The inner product functor + \param Vector The the type of a vector or a collection + \param Scalar The scalar over which the vector field is defined + + \par Refinement of: + - std::Callable2 <I, Vector, Vector> + + \par Associated types: + - magnitude_type + + \par Requires: + - std::Convertible<std::Callable2 <I, Vector, Vector>::result_type, Scalar> ; + result of inner product convertible to scalar to be used in expressions + - HasConjugate < Scalar > + - RealMagnitude < Scalar > ; the scalar value needs a real magnitude type + */ +template <typename I, typename Vector, + typename Scalar = typename Vector::value_type> +struct InnerProduct + : std::Callable2<I, Vector, Vector> +{ + /// Associated type: the real magnitude type of the scalar + /** By default RealMagnitude<Scalar>::type */ + typename associated_type magnitude_type; + // requires FullLessThanComparable<magnitude_type>; + + /// The arguments can be changed and the result is then the complex conjugate + axiom ConjugateSymmetry(I inner, Vector v, Vector w) + { + /// inner(v, w) == conj(inner(w, v)); + } + + /// The inner product is linear in the second argument and conjugate linear in the first one + /** The equalities are partly redundant with ConjugateSymmetry */ + axiom SequiLinearity(I inner, Scalar a, Scalar b, Vector u, Vector v, Vector w) + { + /// inner(v, b * w) == b * inner(v, w); + + /// inner(u, v + w) == inner(u, v) + inner(u, w); + + /// inner(a * v, w) == conj(a) * inner(v, w); + + /// inner(u + v, w) == inner(u, w) + inner(v, w); + } + + /// The inner product of a vector with itself is not negative + /** inner(v, v) == conj(inner(v, v)) implies inner(v, v) is representable as real */ + axiom NonNegativity(I inner, Vector v, MagnitudeType<Scalar>::type magnitude) + { + /// magnitude_type(inner(v, v)) >= zero(magnitude); + } + + /// Non-degeneracy not representable with axiom + axiom NonDegeneracy(I inner, Vector v, Vector w, Scalar s) + { + /// \f$\langle v, w\rangle = 0 \forall w \Leftrightarrow v = \vec{0}\f$ + } +}; +#endif + + + + +#ifdef __GXX_CONCEPTS_ +// A dot product is only a semantically special case of an inner product +// Questionable if we want such a concept +concept DotProduct<typename I, typename Vector, + typename Scalar = typename Vector::value_type> + : InnerProduct<I, Vector, Scalar> +{}; +#else + //! Concept DotProduct + /*! + Semantic requirements of dot product. The dot product is a specific inner product. + + \param I Norm functor + \param Vector The the type of a vector or a collection + \param Scalar The scalar over which the vector field is defined + + \par Refinement of: + - InnerProduct <I, Vector, Scalar> + */ +template <typename I, typename Vector, + typename Scalar = typename Vector::value_type> +struct DotProduct + : InnerProduct<I, Vector, Scalar> +{}; +#endif + + + + +// Norm induced by inner product +// Might be moved to another place later +// Definition as class and function +// Conversion from scalar to magnitude_type is covered by norm concept +template <typename I, typename Vector, + typename Scalar = typename Vector::value_type> + _GLIBCXX_WHERE(InnerProduct<I, Vector, Scalar> + && RealMagnitude<Scalar>) +struct induced_norm_t +{ + // Return type evtl. with macro to use concept definition + typename magnitude_type_trait<Scalar>::type + operator() (const I& inner, const Vector& v) + { + // Check whether inner product is positive real + // assert(Scalar(abs(inner(v, v))) == inner(v, v)); + + // Similar check while accepting small imaginary values + // assert( (abs(inner(v, v)) - inner(v, v)) / abs(inner(v, v)) < 1e-6; ) + + // Could also be defined with abs but that might introduce extra ops + // typedef RealMagnitude<Scalar>::type magnitude_type; + + typedef typename magnitude_type_trait<Scalar>::type magnitude_type; + return sqrt(static_cast<magnitude_type> (inner(v, v))); + } +}; + + +#if 0 +template <typename I, typename Vector, + typename Scalar = typename Vector::value_type> + LA_WHERE( InnerProduct<I, Vector, Scalar> + && RealMagnitude<Scalar> ) +magnitude_type_trait<Scalar>::type +induced_norm(const I& inner, const Vector& v) +{ + return induced_norm_t<I, Vector, Scalar>() (inner, v); +} +#endif + +#ifdef __GXX_CONCEPTS__ + + +concept HilbertSpace<typename I, typename Vector, + typename Scalar = typename Vector::value_type, + typename N = induced_norm_t<I, Vector, Scalar> > + : InnerProduct<I, Vector, Scalar>, + BanachSpace<N, Vector, Scalar> +{ + axiom Consistency(Vector v) + { + math::induced_norm_t<I, Vector, Scalar>()(v) == N()(v); + } +}; +#else + //! Concept HilbertSpace + /*! + A Hilbert space is a vector space with an inner product that induces a norm + + \param I Inner product functor + \param Vector The the type of a vector or a collection + \param Scalar The scalar over which the vector field is defined + \param N Norm functor + + \par Refinement of: + - InnerProduct <I, Vector, Scalar> + - BanachSpace <N, Vector, Scalar> + + \note + - The (expressible) requirements of Banach Space are already given in InnerProduct + (besides consistency of the functors). + - A difference is that InnerProduct is not a refinement of Vectorspace + */ +template <typename I, typename Vector, + typename Scalar = typename Vector::value_type, + typename N = induced_norm_t<I, Vector, Scalar> > +struct HilbertSpace + : InnerProduct<I, Vector, Scalar>, + BanachSpace<N, Vector, Scalar> +{ + /// Consistency between norm and induced norm + axiom Consistency(Vector v) + { + /// math::induced_norm_t<I, Vector, Scalar>()(v) == N()(v); + } +}; +#endif // __GXX_CONCEPTS__ + +/*@}*/ // end of group Concepts + +} // namespace math + +#endif // LA_VECTOR_CONCEPTS_INCLUDE diff --git a/install/MTL/include/boost/numeric/meta_math/abs.hpp b/install/MTL/include/boost/numeric/meta_math/abs.hpp new file mode 100644 index 00000000..fdf5e9ed --- /dev/null +++ b/install/MTL/include/boost/numeric/meta_math/abs.hpp @@ -0,0 +1,27 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef META_MATH_ABS_INCLUDE +#define META_MATH_ABS_INCLUDE + +namespace meta_math { + +template <long int x> +struct abs +{ + static long int const value = x < 0 ? -x : x; +}; + + +} // namespace meta_math + +#endif // META_MATH_ABS_INCLUDE diff --git a/install/MTL/include/boost/numeric/meta_math/is_power_of_2.hpp b/install/MTL/include/boost/numeric/meta_math/is_power_of_2.hpp new file mode 100644 index 00000000..e629a6d3 --- /dev/null +++ b/install/MTL/include/boost/numeric/meta_math/is_power_of_2.hpp @@ -0,0 +1,28 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef META_MATH_IS_POWER_OF_2_INCLUDE +#define META_MATH_IS_POWER_OF_2_INCLUDE + +#include <boost/numeric/meta_math/least_significant_one_bit.hpp> + +namespace meta_math { + +template <unsigned long X> +struct is_power_of_2 +{ + static const bool value= X == least_significant_one_bit<X>::value; +}; + +} // namespace meta_math + +#endif // META_MATH_IS_POWER_OF_2_INCLUDE diff --git a/install/MTL/include/boost/numeric/meta_math/is_prime.hpp b/install/MTL/include/boost/numeric/meta_math/is_prime.hpp new file mode 100644 index 00000000..e6aa21de --- /dev/null +++ b/install/MTL/include/boost/numeric/meta_math/is_prime.hpp @@ -0,0 +1,95 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef META_MATH_IS_PRIME_INCLUDE +#define META_MATH_IS_PRIME_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/meta_math/sqrt.hpp> +// #include <boost/config/concept_macros.hpp> +#ifdef __GXX_CONCEPTS__ +# include <concepts> +#endif + + +namespace meta_math { + +namespace mpl = boost::mpl; + +namespace impl { + + // Checks if 'x' is divisible by some odd number >= max_odd, checking decreasingly + template <long int x, long int max_odd> + struct is_prime_to_max_odd + { + static bool const value = x % max_odd != 0 + && is_prime_to_max_odd<x, max_odd-2>::value; + }; + + // Once we reach 1, it's prime + template <long int x> struct is_prime_to_max_odd<x, 1> : mpl::true_ {}; + + + // Returns the largest number that x is tried to divided by. + // This is a odd number slightly larger than the approximated square root. + template <long int x> + struct max_prime_compare + { + static long int const tmp = sqrt<x>::value, + value = tmp % 2 == 0 ? tmp + 1 : tmp + 2; + }; + + + // Checks if there is an odd number between 3 and sqrt(x)+1 that divides x + // if there is no divisor found then x is prime (otherwise not) + // must be disabled when x is even + template <long int x, bool Disable> + struct check_odd + { + static bool const value = is_prime_to_max_odd<x, max_prime_compare<x>::value>::value; + }; + + // Intended for even numbers (> 2) which are always prime + template <long int x> + struct check_odd<x, true> + { + static bool const value = false; + }; + +} + +template <long int x> +struct is_prime +{ + static bool const value = impl::check_odd<x, x % 2 == 0>::value; +}; + +template <> struct is_prime<0> : mpl::false_ {}; +template <> struct is_prime<1> : mpl::false_ {}; +template <> struct is_prime<2> : mpl::true_ {}; +template <> struct is_prime<3> : mpl::true_ {}; +template <> struct is_prime<5> : mpl::true_ {}; + + +#ifdef __GXX_CONCEPTS__ + concept Prime<long int N> {} + + template <long int N> + where std::True<is_prime<N>::value> + concept_map Prime<N> {} +#endif + + + +} // namespace meta_math + +#endif // META_MATH_IS_PRIME_INCLUDE diff --git a/install/MTL/include/boost/numeric/meta_math/least_significant_one_bit.hpp b/install/MTL/include/boost/numeric/meta_math/least_significant_one_bit.hpp new file mode 100644 index 00000000..faf1e7f6 --- /dev/null +++ b/install/MTL/include/boost/numeric/meta_math/least_significant_one_bit.hpp @@ -0,0 +1,27 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef META_MATH_LEAST_SIGNIFICANT_ONE_BIT_INCLUDE +#define META_MATH_LEAST_SIGNIFICANT_ONE_BIT_INCLUDE + +namespace meta_math { + +template <unsigned long X> +struct least_significant_one_bit +{ + static const unsigned long value= ((X ^ (X-1)) + 1) >> 1; +}; + + +} // namespace meta_math + +#endif // META_MATH_LEAST_SIGNIFICANT_ONE_BIT_INCLUDE diff --git a/install/MTL/include/boost/numeric/meta_math/log_2.hpp b/install/MTL/include/boost/numeric/meta_math/log_2.hpp new file mode 100644 index 00000000..8f474a4a --- /dev/null +++ b/install/MTL/include/boost/numeric/meta_math/log_2.hpp @@ -0,0 +1,43 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef META_MATH_LOG_2_INCLUDE +#define META_MATH_LOG_2_INCLUDE + +#include <boost/numeric/meta_math/is_power_of_2.hpp> + +namespace meta_math { + +// Computes the logarithm to the basis 2 +// Without testing if power of 2 it rounds values down to next integer +template <unsigned long X> +struct log_2 +{ + // BOOST_STATIC_ASSERT(is_power_of_2_meta<X>::value); + static const unsigned long tmp= X >> 1, value= log_2<tmp>::value + 1; +}; + +template <> struct log_2<1> +{ + static const unsigned long value= 0; +}; + +template <> struct log_2<0> +{ + // #error "Logarithm of 0 is undefined" + BOOST_STATIC_ASSERT(true); // Logarithm of 0 is undefined +}; + + +} // namespace meta_math + +#endif // META_MATH_LOG_2_INCLUDE diff --git a/install/MTL/include/boost/numeric/meta_math/loop.hpp b/install/MTL/include/boost/numeric/meta_math/loop.hpp new file mode 100644 index 00000000..cb1b3538 --- /dev/null +++ b/install/MTL/include/boost/numeric/meta_math/loop.hpp @@ -0,0 +1,20 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef META_MATH_LOOP_INCLUDE +#define META_MATH_LOOP_INCLUDE + +#include <boost/numeric/meta_math/loop1.hpp> +#include <boost/numeric/meta_math/loop2.hpp> +#include <boost/numeric/meta_math/loop3.hpp> + +#endif // META_MATH_LOOP_INCLUDE diff --git a/install/MTL/include/boost/numeric/meta_math/loop1.hpp b/install/MTL/include/boost/numeric/meta_math/loop1.hpp new file mode 100644 index 00000000..49178153 --- /dev/null +++ b/install/MTL/include/boost/numeric/meta_math/loop1.hpp @@ -0,0 +1,36 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef META_MATH_LOOP1_INCLUDE +#define META_MATH_LOOP1_INCLUDE + +// See loop3.hpp for example + +namespace meta_math { + +template <std::size_t Index0, std::size_t Max0> +struct loop1 +{ + static std::size_t const index0= Index0 - 1, next_index0= Index0 + 1; +}; + + +template <std::size_t Max0> +struct loop1<Max0, Max0> +{ + static std::size_t const index0= Max0 - 1; +}; + + +} // namespace meta_math + +#endif // META_MATH_LOOP1_INCLUDE diff --git a/install/MTL/include/boost/numeric/meta_math/loop2.hpp b/install/MTL/include/boost/numeric/meta_math/loop2.hpp new file mode 100644 index 00000000..e00227b4 --- /dev/null +++ b/install/MTL/include/boost/numeric/meta_math/loop2.hpp @@ -0,0 +1,46 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef META_MATH_LOOP2_INCLUDE +#define META_MATH_LOOP2_INCLUDE + +// See loop3.hpp for example + +namespace meta_math { + +template <std::size_t Index0, std::size_t Max0, std::size_t Index1, std::size_t Max1> +struct loop2 +{ + static const std::size_t index0= Index0 - 1, next_index0= Index0, + index1= Index1 - 1, next_index1= Index1 + 1; +}; + + +template <std::size_t Index0, std::size_t Max0, std::size_t Max1> +struct loop2<Index0, Max0, Max1, Max1> +{ + static const std::size_t index0= Index0 - 1, next_index0= Index0 + 1, + index1= Max1 - 1, next_index1= 1; +}; + + +template <std::size_t Max0, std::size_t Max1> +struct loop2<Max0, Max0, Max1, Max1> +{ + static const std::size_t index0= Max0 - 1, + index1= Max1 - 1; +}; + + +} // namespace meta_math + +#endif // META_MATH_LOOP2_INCLUDE diff --git a/install/MTL/include/boost/numeric/meta_math/loop3.hpp b/install/MTL/include/boost/numeric/meta_math/loop3.hpp new file mode 100644 index 00000000..eaf4858d --- /dev/null +++ b/install/MTL/include/boost/numeric/meta_math/loop3.hpp @@ -0,0 +1,96 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef META_MATH_LOOP3_INCLUDE +#define META_MATH_LOOP3_INCLUDE + +// See below for example + +namespace meta_math { + +template <std::size_t Index0, std::size_t Max0, std::size_t Index1, std::size_t Max1, + std::size_t Index2, std::size_t Max2> +struct loop3 +{ + static std::size_t const index0= Index0 - 1, next_index0= Index0, + index1= Index1 - 1, next_index1= Index1, + index2= Index2 - 1, next_index2= Index2 + 1; +}; + + +template <std::size_t Index0, std::size_t Max0, std::size_t Index1, std::size_t Max1, + std::size_t Max2> +struct loop3<Index0, Max0, Index1, Max1, Max2, Max2> +{ + static std::size_t const index0= Index0 - 1, next_index0= Index0, + index1= Index1 - 1, next_index1= Index1 + 1, + index2= Max2 - 1, next_index2= 1; +}; + + +template <std::size_t Index0, std::size_t Max0, std::size_t Max1, std::size_t Max2> +struct loop3<Index0, Max0, Max1, Max1, Max2, Max2> +{ + static std::size_t const index0= Index0 - 1, next_index0= Index0 + 1, + index1= Max1 - 1, next_index1= 1, + index2= Max2 - 1, next_index2= 1; +}; + + +template <std::size_t Max0, std::size_t Max1, std::size_t Max2> +struct loop3<Max0, Max0, Max1, Max1, Max2, Max2> +{ + static std::size_t const index0= Max0 - 1, + index1= Max1 - 1, + index2= Max2 - 1; +}; + + + + +#if 0 + +// ============================ +// Use the meta loop like this: +// ============================ + + +template <std::size_t Index0, std::size_t Max0, std::size_t Index1, std::size_t Max1, + std::size_t Index2, std::size_t Max2> +struct loop3_trace : public loop3<Index0, Max0, Index1, Max1, Index2, Max2> +{ + typedef loop3<Index0, Max0, Index1, Max1, Index2, Max2> base; + typedef loop3_trace<base::next_index0, Max0, base::next_index1, Max1, base::next_index2, Max2> next_t; + + void operator() () + { + std::cout << this->index0 << " : " << this->index1 << " : " << this->index2 << "\n"; + next_t() (); + } +}; + + +template <std::size_t Max0, std::size_t Max1, std::size_t Max2> +struct loop3_trace<Max0, Max0, Max1, Max1, Max2, Max2> + : public loop3<Max0, Max0, Max1, Max1, Max2, Max2> +{ + void operator() () + { + std::cout << this->index0 << " : " << this->index1 << " : " << this->index2 << "\n"; + } +}; + +#endif + +} // namespace meta_math + +#endif // META_MATH_LOOP3_INCLUDE diff --git a/install/MTL/include/boost/numeric/meta_math/max.hpp b/install/MTL/include/boost/numeric/meta_math/max.hpp new file mode 100644 index 00000000..58356018 --- /dev/null +++ b/install/MTL/include/boost/numeric/meta_math/max.hpp @@ -0,0 +1,27 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef META_MATH_MAX_INCLUDE +#define META_MATH_MAX_INCLUDE + +namespace meta_math { + +template <long int x, long int y> +struct max +{ + typedef long int type; + static long int const value = x < y ? y : x; +}; + +} // namespace meta_math + +#endif // META_MATH_MAX_INCLUDE diff --git a/install/MTL/include/boost/numeric/meta_math/min.hpp b/install/MTL/include/boost/numeric/meta_math/min.hpp new file mode 100644 index 00000000..94156eb7 --- /dev/null +++ b/install/MTL/include/boost/numeric/meta_math/min.hpp @@ -0,0 +1,27 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef META_MATH_MIN_INCLUDE +#define META_MATH_MIN_INCLUDE + +namespace meta_math { + +template <long int x, long int y> +struct min +{ + typedef long int type; + static long int const value = x < y ? x : y; +}; + +} // namespace meta_math + +#endif // META_MATH_MIN_INCLUDE diff --git a/install/MTL/include/boost/numeric/meta_math/power_of_2.hpp b/install/MTL/include/boost/numeric/meta_math/power_of_2.hpp new file mode 100644 index 00000000..b0f460d6 --- /dev/null +++ b/install/MTL/include/boost/numeric/meta_math/power_of_2.hpp @@ -0,0 +1,30 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef META_MATH_POWER_OF_2_INCLUDE +#define META_MATH_POWER_OF_2_INCLUDE + +namespace meta_math { + + +// Computes the n-th power of 2 +// So simple, everybody could do it, it is only there for the sake of completeness +template <unsigned long N> +struct power_of_2 +{ + static const unsigned long value= 1 << N; +}; + + +} // namespace meta_math + +#endif // META_MATH_POWER_OF_2_INCLUDE diff --git a/install/MTL/include/boost/numeric/meta_math/sqrt.hpp b/install/MTL/include/boost/numeric/meta_math/sqrt.hpp new file mode 100644 index 00000000..dd9dc426 --- /dev/null +++ b/install/MTL/include/boost/numeric/meta_math/sqrt.hpp @@ -0,0 +1,59 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef META_MATH_SQRT_INCLUDE +#define META_MATH_SQRT_INCLUDE + +#include <boost/numeric/meta_math/abs.hpp> + +namespace meta_math { + +template <long int root, long int x> +struct sqrt_check +{ + static bool const value = root * root <= x && (root+1) * (root+1) > x; +}; + + +namespace impl { + + template <long int guess, long int x, bool Converged> + struct sqrt_impl + { + typedef long int type; + typedef sqrt_impl self; + static long int const quotient = x / guess, + new_value = (quotient + guess) / 2; + static bool const converging = abs<guess - quotient>::value < 2; + static long int const value = sqrt_impl<new_value, x, converging>::value; + }; + + // If the condition becomes true the guessed root will be the returned value + template <long int guess, long int x> + struct sqrt_impl<guess, x, true> + { + static long int const value = guess; + }; + +} + +template <long int x> +struct sqrt +{ + typedef long int type; + static long int const value = impl::sqrt_impl<1, x, false>::value; +}; + + +} // namespace meta_math + +#endif // META_MATH_SQRT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/concept/collection.hpp b/install/MTL/include/boost/numeric/mtl/concept/collection.hpp new file mode 100644 index 00000000..df51f9f6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/concept/collection.hpp @@ -0,0 +1,1457 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_COLLECTION_INCLUDE +#define MTL_COLLECTION_INCLUDE + +#include <boost/type_traits/remove_const.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <vector> + +#ifdef __GXX_CONCEPTS__ +# include <concepts> +#else +# include <boost/numeric/linear_algebra/pseudo_concept.hpp> +# include <boost/numeric/mtl/concept/std_concept.hpp> +#endif + +#include <boost/numeric/mtl/utility/transposed_orientation.hpp> + +namespace mtl { + +/** @addtogroup Concepts + * @{ + */ + +#ifdef __GXX_CONCEPTS__ + auto concept Collection<typename T> + { + typename value_type; + typename const_reference; + typename size_type; + }; +#else + /// Concept Collection + template <typename T> + struct Collection + { + /// Associated type: elements in the collection + typedef associated_type value_type; + + /// Associated type: return type of const element access (however implemented) + typedef associated_type const_reference; + + /// Associated type: size type used for indexing in collection + typedef associated_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + auto concept MutableCollection<typename T> + : Collection<T> + { + typename reference; + } +#else + /// Concept MutableCollection + template <typename T> + struct MutableCollection + : public Collection<T> + { + /// Associated type: return type of non-const element access (however implemented) + typedef associated_type reference; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept ConstantSizeCollection<typename T> + : Collection<T> + {}; +#else + /// Concept ConstantSizeCollection: size parameters of collection are completely given at compile time + /* Which parameters determine collection size depends on type of collection, e.g. different for vector and matrix + \par Refinement of: + - Collection < T > + */ + template <typename T> + struct ConstantSizeCollection + : Collection<T> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + auto concept AlgebraicCollection<typename T> + : Collection<T> + { + size_type num_rows(T); + size_type num_cols(T); + size_type size(T); + }; +#else + /// Concept AlgebraicCollection: common requirements of matrices, vectors, and scalars in computations + /** For more design clarity we consider them all as matrices (as Matlab does) and we regard + Scalar and Vector as special cases (see there). However, the implementation of vectors + is supposed to differ from the ones of matrices in order to provide efficient computations and storage. + \par Refinement of: + - Collection < T > + \par Notation: + - X is a type that models AlgebraicCollection + - x is an object of type X + \par Valid expressions: + - Number of rows: \n num_rows(x) \n Return Type: size_type + - Number of columns: \n num_cols(x) \n Return Type: size_type + - Number of elements: \n size(x) \n Return Type: size_type + \n Sematics: num_rows(x) * num_cols(x) (but possibly faster implemented) + */ + template <typename T> + struct AlgebraicCollection + : public Collection<T> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + auto concept ConstantSizeAlgebraicCollection<typename T> + : AlgebraicCollection<T>, + ConstantSizeCollection<T> + { +#if 0 + // Is there a way to require static members???? + static Collection<T>::size_type T::static_num_rows; + static Collection<T>::size_type T::static_num_cols; + static Collection<T>::size_type T::static_size; +#endif + }; +#else + /// Concept ConstantSizeAlgebraicCollection: extension of AlgebraicCollection with meta-functions + /** This concept is used for algebraic collections with sizes known at compile time. + The motivation is that if the size of the collection is + is small, arithmetic operations can be unrolled at compile time. + + \par Refinement of: + - Collection < T > + \par Notation: + - X is a type that models ConstantSizeAlgebraicCollection + - x is an object of type X + \par Valid expressions: + - Number of rows: \n static_num_rows<X>::value + - Number of columns: \n static_num_cols<X>::value + - Number of elements: \n static_size<X>::value + \n Sematics: static_num_rows<X>::value * static_size<X>::value + \note + -# For more design clarity we consider them all as matrices (as Matlab does) and we regard + Scalar and Vector as special cases (see there). However, the implementation of vectors + is supposed to differ from the ones of matrices in order to provide efficient computations and storage. + + */ + template <typename T> + struct ConstantSizeAlgebraicCollection + : public AlgebraicCollection<T>, + public ConstantSizeCollection<T> + { + /// Associated type: meta-function for number of rows + typedef associated_type static_num_rows; + /// Associated type: meta-function for number of columns + typedef associated_type static_num_cols; + /// Associated type: meta-function for number of elements + typedef associated_type static_size; + }; +#endif + + + +#ifdef __GXX_CONCEPTS__ + auto concept TraversableCollection<typename Tag, typename C> + : Collection<C> + { +#if 0 + // This might be impossible to declare with concepts + typename cursor_type; + + cursor_type begin<Tag>(const C& c); + cursor_type end<Tag>(const C& c); +#endif + + // Maybe we switch to this syntax for the sake of concepts + typename cursor_type; + + cursor_type begin(const C& c, Tag); + cursor_type end(const C& c, Tag); + } +#else + /// Concept TraversableCollection: collections that can be traversed by cursor or iterator + template <typename Tag, typename C> + struct TraversableCollection + : public Collection<C> + { + /// Associated type: return type of tagged begin and end function + typedef associated_type cursor_type; + + /// Tagged free function that returns a cursor or iterator at the begin of an interval + /** The interval is specified by the Tag, i.e. the function is called begin<Tag>(c); */ + cursor_type begin(const C& c); + + /// Tagged free function that returns a cursor or iterator at the end of an interval + /** The interval is specified by the Tag, i.e. the function is called end<Tag>(c); */ + cursor_type end(const C& c); + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + auto concept TraversableMutableCollection<typename Tag, typename C> + : MutableCollection<C> + { +#if 0 + typename cursor_type; + + cursor_type begin<Tag>(C& c); + cursor_type end<Tag>(C& c); +#endif + + // Maybe we switch to this syntax for the sake of concepts + typename cursor_type; + + cursor_type begin(C& c, Tag); + cursor_type end(C& c, Tag); + } +#else + /// Concept TraversableMutableCollection: collections that can be traversed by (mutable) iterator + template <typename Tag, typename C> + struct TraversableMutableCollection + : public MutableCollection<C> + { + /// Associated type: return type of tagged begin function + typedef associated_type cursor_type; + + /// Tagged free function that returns a cursor or iterator at the begin of an interval + /** The interval is specified by the Tag, i.e. the function is called begin<Tag>(c); */ + cursor_type begin(const C& c); + + /// Tagged free function that returns a cursor or iterator at the end of an interval + /** The interval is specified by the Tag, i.e. the function is called end<Tag>(c); */ + cursor_type end(const C& c); + }; +#endif + + + + +#ifdef __GXX_CONCEPTS__ +#if 0 + concept CategorizedType<typename T> + { + typedef associated_type type; + }; +#endif +#endif + + +#ifdef __GXX_CONCEPTS__ + concept OrientedCollection<typename T> + : Collection<T> + { + typename orientation; + + }; +#else + /// Concept OrientedCollection: collections with concept-awareness in terms of associated type + /** Concept-awareness is given for matrices as well as for vectors consistent to the unification in + AlgebraicCollection. The orientation of vectors determines whether it is a row or a column vector. + The orientation of matrices only characterizes the internal representation and has no semantic consequences. + \par Refinement of: + - Collection < T > + \par Associated type: + - orientation + */ + template <typename T> + struct OrientedCollection + : public Collection<T> + { + /// Associated type for orientation; by default identical with member type + typedef typename T::orientation orientation; + }; +#endif + + + + + + + +// ============================================ +// Concept maps (and emulations as type traits) +// ============================================ + +#ifdef __GXX_CONCEPTS__ + // Needs redefinition in refinements (at least in conceptg++) + // -> as a consequence we define it directly there +#else + template <typename Value, typename Parameters> + struct Collection<mtl::mat::dense2D<Value, Parameters> > + { + typedef Value value_type; + typedef const Value& const_reference; + // Alleged ambiguity with mtl::tag::dense2D on MSVC + typedef typename mtl::mat::dense2D<Value, Parameters>::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + +#else + template <typename Value, std::size_t Mask, typename Parameters> + struct Collection<mtl::mat::morton_dense<Value, Mask, Parameters> > + { + typedef Value value_type; + typedef const Value& const_reference; + typedef typename Parameters::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Value, typename Parameters> + concept_map Collection<mtl::mat::compressed2D<Value, Parameters> > + { + typedef Value value_type; + typedef Value const_reference; + typedef typename mtl::mat::compressed2D<Value, Parameters>::size_type size_type; + }; +#else + template <typename Value, typename Parameters> + struct Collection<mtl::mat::compressed2D<Value, Parameters> > + { + typedef Value value_type; + typedef Value const_reference; + typedef typename Parameters::size_type size_type; + }; + +#endif + + +#ifdef __GXX_CONCEPTS__ +#else + template <typename Value, typename Parameters> + struct Collection<mtl::mat::coordinate2D<Value, Parameters> > + { + typedef Value value_type; + typedef Value const_reference; + typedef typename Parameters::size_type size_type; + }; + +#endif + + +#ifdef __GXX_CONCEPTS__ +#else + template <typename Value, typename Parameters> + struct Collection<mtl::mat::sparse_banded<Value, Parameters> > + { + typedef Value value_type; + typedef Value const_reference; + typedef typename Parameters::size_type size_type; + }; + +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Vector> + concept_map Collection<mtl::mat::multi_vector<Vector> > + { + typedef typename mtl::mat::multi_vector<Vector>::value_type value_type; + typedef typename mtl::mat::multi_vector<Vector>::const_reference const_reference; + typedef typename mtl::mat::multi_vector<Vector>::size_type size_type; + }; +#else + template <typename Vector> + struct Collection<mtl::mat::multi_vector<Vector> > + { + typedef typename mtl::mat::multi_vector<Vector>::value_type value_type; + typedef typename mtl::mat::multi_vector<Vector>::const_reference const_reference; + typedef typename mtl::mat::multi_vector<Vector>::size_type size_type; + }; + +#endif + + + + +#ifdef __GXX_CONCEPTS__ + template <typename Vector> + concept_map Collection<mtl::mat::multi_vector_range<Vector> > + { + typedef typename mtl::mat::multi_vector_range<Vector>::value_type value_type; + typedef typename mtl::mat::multi_vector_range<Vector>::const_reference const_reference; + typedef typename mtl::mat::multi_vector_range<Vector>::size_type size_type; + }; +#else + template <typename Vector> + struct Collection<mtl::mat::multi_vector_range<Vector> > + { + typedef typename mtl::mat::multi_vector_range<Vector>::value_type value_type; + typedef typename mtl::mat::multi_vector_range<Vector>::const_reference const_reference; + typedef typename mtl::mat::multi_vector_range<Vector>::size_type size_type; + }; + +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <typename Value> + struct Collection<mat::element_structure<Value> > + { + typedef Value value_type; + // typedef Value const_reference; + // typedef typename mtl::mat::compressed2D<Value, Parameters>::size_type size_type; + }; + +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <typename Value, typename Parameters> + struct Collection<mat::ell_matrix<Value, Parameters> > + { + typedef Value value_type; + typedef Value const_reference; + typedef typename Parameters::size_type size_type; + }; + +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Scaling, typename Coll> + concept_map Collection<mat::scaled_view<Scaling, Coll> > + { + typedef typename mat::scaled_view<Scaling, Coll>::value_type value_type; + typedef typename mat::scaled_view<Scaling, Coll>::const_reference const_reference; + typedef typename mat::scaled_view<Scaling, Coll>::size_type size_type; + }; +#else + template <typename Scaling, typename Coll> + struct Collection<mat::scaled_view<Scaling, Coll> > + { + typedef typename mat::scaled_view<Scaling, Coll>::value_type value_type; + typedef typename mat::scaled_view<Scaling, Coll>::const_reference const_reference; + typedef typename mat::scaled_view<Scaling, Coll>::size_type size_type; + }; +#endif + +// added by Hui Li +#ifdef __GXX_CONCEPTS__ + template <typename Coll, typename RScaling> + concept_map Collection<mat::rscaled_view<Coll,RScaling> > + { + typedef typename mat::rscaled_view<Coll,RScaling>::value_type value_type; + typedef typename mat::rscaled_view<Coll,RScaling>::const_reference const_reference; + typedef typename mat::rscaled_view<Coll,RScaling>::size_type size_type; + }; +#else + template <typename Coll, typename RScaling> + struct Collection<mat::rscaled_view<Coll,RScaling> > + { + typedef typename mat::rscaled_view<Coll,RScaling>::value_type value_type; + typedef typename mat::rscaled_view<Coll,RScaling>::const_reference const_reference; + typedef typename mat::rscaled_view<Coll,RScaling>::size_type size_type; + }; +#endif + + + +#ifdef __GXX_CONCEPTS__ + // template <typename Functor, typename Coll> + // concept_map Collection< vec::map_view<Functor, Coll> > + // { + // typedef typename vec::map_view<Functor, Coll>::value_type value_type; + // typedef typename vec::map_view<Functor, Coll>::const_reference const_reference; + // typedef typename vec::map_view<Functor, Coll>::size_type size_type; + // }; +#else + template <typename Functor, typename Coll> + struct Collection< vec::map_view<Functor, Coll> > + { + // typedef typename Functor::result_type value_type; + // typedef typename Functor::result_type const_reference; + // typedef typename Collection<Coll>::size_type size_type; + + typedef typename vec::map_view<Functor, Coll>::value_type value_type; + typedef typename vec::map_view<Functor, Coll>::const_reference const_reference; + typedef typename vec::map_view<Functor, Coll>::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + +#else + template <typename Scaling, typename Coll> + struct Collection<vec::scaled_view<Scaling, Coll> > + : Collection< vec::map_view<tfunctor::rscale<typename Collection<Coll>::value_type, Scaling>, Coll> > + { + // typedef typename vec::scaled_view<Scaling, Coll>::value_type value_type; + // typedef typename vec::scaled_view<Scaling, Coll>::const_reference const_reference; + // typedef typename vec::scaled_view<Scaling, Coll>::size_type size_type; + }; +#endif + + + +// added by Hui Li +#ifdef __GXX_CONCEPTS__ + template <typename Coll, typename RScaling> + concept_map Collection<vec::rscaled_view<Coll,RScaling> > + { + typedef typename vec::rscaled_view<Coll,RScaling>::value_type value_type; + typedef typename vec::rscaled_view<Coll,RScaling>::const_reference const_reference; + typedef typename vec::rscaled_view<Coll,RScaling>::size_type size_type; + }; +#else + template <typename Coll, typename RScaling> + struct Collection<vec::rscaled_view<Coll,RScaling> > + : Collection< vec::map_view<tfunctor::rscale<typename Collection<Coll>::value_type, RScaling>, Coll> > + { + // typedef typename vec::rscaled_view<Coll,RScaling>::value_type value_type; + // typedef typename vec::rscaled_view<Coll,RScaling>::const_reference const_reference; + // typedef typename vec::rscaled_view<Coll,RScaling>::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Coll> + concept_map Collection<vec::conj_view<Coll> > + { + typedef typename vec::conj_view<Coll>::value_type value_type; + typedef typename vec::conj_view<Coll>::const_reference const_reference; + typedef typename vec::conj_view<Coll>::size_type size_type; + }; +#else + template <typename Coll> + struct Collection<vec::conj_view<Coll> > + { + typedef typename vec::conj_view<Coll>::value_type value_type; + typedef typename vec::conj_view<Coll>::const_reference const_reference; + typedef typename vec::conj_view<Coll>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <typename Coll> + struct Collection<vec::real_view<Coll> > + { + typedef typename vec::real_view<Coll>::value_type value_type; + typedef typename vec::real_view<Coll>::const_reference const_reference; + typedef typename vec::real_view<Coll>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <typename Coll> + struct Collection<vec::imag_view<Coll> > + { + typedef typename vec::imag_view<Coll>::value_type value_type; + typedef typename vec::imag_view<Coll>::const_reference const_reference; + typedef typename vec::imag_view<Coll>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ + template <typename Coll> + concept_map Collection<vec::negate_view<Coll> > + { + typedef typename vec::negate_view<Coll>::value_type value_type; + typedef typename vec::negate_view<Coll>::const_reference const_reference; + typedef typename vec::negate_view<Coll>::size_type size_type; + }; +#else + template <typename Coll> + struct Collection<vec::negate_view<Coll> > + { + typedef typename vec::negate_view<Coll>::value_type value_type; + typedef typename vec::negate_view<Coll>::const_reference const_reference; + typedef typename vec::negate_view<Coll>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <class E1, class E2, typename SFunctor> + struct Collection< vec::vec_scal_aop_expr<E1, E2, SFunctor> > + { + typedef typename Collection<E1>::value_type value_type; + typedef value_type const_reference; + typedef typename Collection<E1>::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ +#else + template <class E1, class E2> + struct Collection<vec::vec_scal_asgn_expr<E1, E2> > + : Collection< vec::vec_scal_aop_expr<E1, E2, mtl::sfunctor::assign<typename Collection<E1>::value_type, E2> > > + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ +#else + template <unsigned BSize, typename Vector> + struct Collection<vec::unrolled1<BSize, Vector> > + { + typedef typename Collection<Vector>::value_type value_type; + typedef value_type const_reference; + typedef typename Collection<Vector>::size_type size_type; + }; +#endif + + + + +#ifdef __GXX_CONCEPTS__ + template <typename Coll> + concept_map Collection<mat::conj_view<Coll> > + { + typedef typename mat::conj_view<Coll>::value_type value_type; + typedef typename mat::conj_view<Coll>::const_reference const_reference; + typedef typename mat::conj_view<Coll>::size_type size_type; + }; +#else + template <typename Coll> + struct Collection<mat::conj_view<Coll> > + { + typedef typename mat::conj_view<Coll>::value_type value_type; + typedef typename mat::conj_view<Coll>::const_reference const_reference; + typedef typename mat::conj_view<Coll>::size_type size_type; + }; +#endif + + + + +#ifdef __GXX_CONCEPTS__ + template <typename Coll> + concept_map Collection<mat::imag_view<Coll> > + { + typedef typename mat::imag_view<Coll>::value_type value_type; + typedef typename mat::imag_view<Coll>::const_reference const_reference; + typedef typename mat::imag_view<Coll>::size_type size_type; + }; +#else + template <typename Coll> + struct Collection<mat::imag_view<Coll> > + { + typedef typename mat::imag_view<Coll>::value_type value_type; + typedef typename mat::imag_view<Coll>::const_reference const_reference; + typedef typename mat::imag_view<Coll>::size_type size_type; + }; +#endif + + + + +#ifdef __GXX_CONCEPTS__ + template <typename Coll> + concept_map Collection<mat::negate_view<Coll> > + { + typedef typename mat::negate_view<Coll>::value_type value_type; + typedef typename mat::negate_view<Coll>::const_reference const_reference; + typedef typename mat::negate_view<Coll>::size_type size_type; + }; +#else + template <typename Coll> + struct Collection<mat::negate_view<Coll> > + { + typedef typename mat::negate_view<Coll>::value_type value_type; + typedef typename mat::negate_view<Coll>::const_reference const_reference; + typedef typename mat::negate_view<Coll>::size_type size_type; + }; +#endif + + + + +#ifdef __GXX_CONCEPTS__ + template <typename Coll> + concept_map Collection<mat::real_view<Coll> > + { + typedef typename mat::real_view<Coll>::value_type value_type; + typedef typename mat::real_view<Coll>::const_reference const_reference; + typedef typename mat::real_view<Coll>::size_type size_type; + }; +#else + template <typename Coll> + struct Collection<mat::real_view<Coll> > + { + typedef typename mat::real_view<Coll>::value_type value_type; + typedef typename mat::real_view<Coll>::const_reference const_reference; + typedef typename mat::real_view<Coll>::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Functor> + concept_map Collection<mat::implicit_dense<Functor> > + { + typedef typename mat::implicit_dense<Functor>::value_type value_type; + typedef typename mat::implicit_dense<Functor>::const_reference const_reference; + typedef typename mat::implicit_dense<Functor>::size_type size_type; + }; +#else + template <typename Functor> + struct Collection<mat::implicit_dense<Functor> > + { + typedef typename mat::implicit_dense<Functor>::value_type value_type; + typedef typename mat::implicit_dense<Functor>::const_reference const_reference; + typedef typename mat::implicit_dense<Functor>::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Value> + concept_map Collection<mat::ones_matrix<Value> > + { + typedef typename mat::ones_matrix<Value>::value_type value_type; + typedef typename mat::ones_matrix<Value>::const_reference const_reference; + typedef typename mat::ones_matrix<Value>::size_type size_type; + }; +#else + template <typename Value> + struct Collection<mat::ones_matrix<Value> > + { + typedef typename mat::ones_matrix<Value>::value_type value_type; + typedef typename mat::ones_matrix<Value>::const_reference const_reference; + typedef typename mat::ones_matrix<Value>::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Value> + concept_map Collection<mat::hilbert_matrix<Value> > + { + typedef typename mat::hilbert_matrix<Value>::value_type value_type; + typedef typename mat::hilbert_matrix<Value>::const_reference const_reference; + typedef typename mat::hilbert_matrix<Value>::size_type size_type; + }; +#else + template <typename Value> + struct Collection<mat::hilbert_matrix<Value> > + { + typedef typename mat::hilbert_matrix<Value>::value_type value_type; + typedef typename mat::hilbert_matrix<Value>::const_reference const_reference; + typedef typename mat::hilbert_matrix<Value>::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Vector1, typename Vector2> + concept_map Collection<mat::outer_product_matrix<Vector1, Vector2> > + { + typedef typename mat::outer_product_matrix<Vector1, Vector2>::value_type value_type; + typedef typename mat::outer_product_matrix<Vector1, Vector2>::const_reference const_reference; + typedef typename mat::outer_product_matrix<Vector1, Vector2>::size_type size_type; + }; +#else + template <typename Vector1, typename Vector2> + struct Collection<mat::outer_product_matrix<Vector1, Vector2> > + { + typedef typename mat::outer_product_matrix<Vector1, Vector2>::value_type value_type; + typedef typename mat::outer_product_matrix<Vector1, Vector2>::const_reference const_reference; + typedef typename mat::outer_product_matrix<Vector1, Vector2>::size_type size_type; + }; +#endif + + + + +#ifdef __GXX_CONCEPTS__ + template <typename Matrix> + concept_map Collection<mtl::mat::transposed_view<Matrix> > + { + typedef typename mtl::mat::transposed_view<Matrix>::value_type value_type; + typedef typename mtl::mat::transposed_view<Matrix>::const_reference const_reference; + typedef typename mtl::mat::transposed_view<Matrix>::size_type size_type; + }; +#else + template <typename Matrix> + struct Collection<mtl::mat::transposed_view<Matrix> > + { + typedef typename mtl::mat::transposed_view<Matrix>::value_type value_type; + typedef typename mtl::mat::transposed_view<Matrix>::const_reference const_reference; + typedef typename mtl::mat::transposed_view<Matrix>::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Matrix> + concept_map Collection<mat::hermitian_view<Matrix> > + { + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::const_reference const_reference; + typedef typename Collection<Matrix>::size_type size_type; + }; +#else + template <typename Matrix> + struct Collection<mat::hermitian_view<Matrix> > + { + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::const_reference const_reference; + typedef typename Collection<Matrix>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ + template <typename Coll> + concept_map Collection< mat::banded_view<Coll> > + { + typedef typename mat::banded_view<Coll>::value_type value_type; + typedef typename mat::banded_view<Coll>::const_reference const_reference; + typedef typename mat::banded_view<Coll>::size_type size_type; + }; +#else + template <typename Coll> + struct Collection< mat::banded_view<Coll> > + { + typedef typename mat::banded_view<Coll>::value_type value_type; + typedef typename mat::banded_view<Coll>::const_reference const_reference; + typedef typename mat::banded_view<Coll>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <typename Matrix> + struct Collection< mat::indirect<Matrix> > + { + typedef typename Collection<Matrix>::value_type value_type; + typedef value_type const_reference; // maybe change later + typedef typename Collection<Matrix>::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + +#else + template <typename Matrix, typename Tag, int level> + struct Collection<traits::detail::sub_matrix_cursor<Matrix, Tag, level> > + { + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::const_reference const_reference; + typedef typename Collection<Matrix>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ + +#else + template <typename E1, typename E2> + struct Collection<mat::mat_mat_times_expr<E1, E2> > + { + typedef typename Collection<E1>::value_type ft; + typedef typename Collection<E2>::value_type st; + + typedef typename Multiplicable<ft, st>::result_type value_type; + typedef const value_type& const_reference; + typedef typename Collection<E1>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ + +#else + template <typename E1, typename E2> + struct Collection<mat::mat_mat_plus_expr<E1, E2> > + { + typedef typename Collection<E1>::value_type ft; + typedef typename Collection<E2>::value_type st; + + typedef typename Addable<ft, st>::result_type value_type; + typedef const value_type& const_reference; + typedef typename Collection<E1>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ + +#else + template <typename E1, typename E2> + struct Collection<mat::mv_mv_plus_expr<E1, E2> > + : Collection<mat::mat_mat_plus_expr<E1, E2> > + {}; +#endif + +#ifdef __GXX_CONCECPTS__ + +#else + template< typename Matrix, typename Vector> + struct Collection<mtl::mat_cvec_times_expr<Matrix, Vector> > + { + typedef typename Collection< Matrix >::value_type value_type; + typedef const value_type& const_reference; + typedef typename Collection< Matrix >::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + +#else + template <typename Value, typename Parameters> + struct Collection<mtl::vec::dense_vector<Value, Parameters> > + { + typedef Value value_type; + typedef const Value& const_reference; + typedef typename Parameters::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ + +#else + template <typename Value, typename Parameters> + struct Collection<mtl::vec::strided_vector_ref<Value, Parameters> > + { + typedef typename boost::remove_const<Value>::type value_type; + typedef const Value& const_reference; + typedef typename mtl::vec::strided_vector_ref<Value, Parameters>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <typename Value, typename Parameters> + struct Collection<mtl::vec::sparse_vector<Value, Parameters> > + { + typedef Value value_type; + typedef value_type const_reference; + typedef typename Parameters::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ +#else + template <class E1, class E2, typename SFunctor> + struct Collection<mtl::vec::vec_vec_ele_prod_expr<E1, E2, SFunctor> > + { + typedef typename Multiplicable<typename Collection<E1>::value_type, + typename Collection<E2>::value_type>::result_type value_type; + typedef const value_type& const_reference; + typedef typename Collection<E1>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <class E1, class E2, typename SFunctor> + struct Collection<mtl::vec::vec_vec_pmop_expr<E1, E2, SFunctor> > + { + typedef typename Addable<typename Collection<E1>::value_type, + typename Collection<E2>::value_type>::result_type value_type; + typedef const value_type& const_reference; + typedef typename Collection<E1>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <class E1, class E2, typename SFunctor> + struct Collection<mtl::vec::vec_vec_op_expr<E1, E2, SFunctor> > + { + typedef typename SFunctor::result_type value_type; + typedef const value_type& const_reference; + typedef typename Collection<E1>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <class E1, class E2, typename SFunctor> + struct Collection<mtl::vec::vec_vec_aop_expr<E1, E2, SFunctor> > + { + typedef typename Collection<E1>::value_type value_type; + typedef const value_type& const_reference; + typedef typename Collection<E1>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <typename Matrix, typename VectorIn> + struct Collection<mtl::vec::mat_cvec_multiplier<Matrix, VectorIn> > + { + typedef typename Multiplicable<typename Collection<Matrix>::value_type, + typename Collection<VectorIn>::value_type>::result_type value_type; + typedef const value_type& const_reference; + typedef typename Collection<Matrix>::size_type size_type; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + +#else + // Dunno if this is really a good idea + template <typename T> + struct Collection<T const> + : Collection<T> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + +#else + template <typename Value> + struct Collection<std::vector<Value> > + { + typedef typename std::vector<Value>::value_type value_type; + typedef typename std::vector<Value>::const_reference const_reference; + typedef typename std::vector<Value>::size_type size_type; + }; +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <typename Vector, typename Functor> + struct Collection<mtl::vec::lazy_reduction<Vector, Functor> > + { + typedef std::size_t size_type; + }; +#endif + + + +#ifdef __GXX_CONCEPTS__ + template <typename Value, typename Parameters> + concept_map MutableCollection<mtl::mat::dense2D<Value, Parameters> > + { + typedef Value value_type; + typedef const Value& const_reference; + typedef typename mtl::mat::dense2D<Value, Parameters>::size_type size_type; + + typedef Value& reference; + }; +#else + template <typename Value, typename Parameters> + struct MutableCollection<mtl::mat::dense2D<Value, Parameters> > + : public Collection<mtl::mat::dense2D<Value, Parameters> > + { + typedef Value& reference; + }; +#endif + +#ifdef __GXX_CONCEPTS__ + + template <typename Value, unsigned long Mask, typename Parameters> + concept_map MutableCollection<mtl::mat::morton_dense<Value, Mask, Parameters> > + { + typedef Value value_type; + typedef const Value& const_reference; + typedef typename mtl::mat::morton_dense<Value, Mask, Parameters>::size_type size_type; + + typedef Value& reference; + }; + +#else + + template <typename Value, unsigned long Mask, typename Parameters> + struct MutableCollection<mtl::mat::morton_dense<Value, Mask, Parameters> > + : public Collection<mtl::mat::morton_dense<Value, Mask, Parameters> > + { + typedef Value& reference; + }; + +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Value, typename Parameters> + concept_map MutableCollection<mtl::vec::strided_vector_ref<Value, Parameters> > + { + typedef typename boost::remove_const<Value>::type value_type; + typedef const Value& const_reference; + typedef typename mtl::vec::strided_vector_ref<Value, Parameters>::size_type size_type; + + typedef Value& reference; + }; +#else + template <typename Value, typename Parameters> + struct MutableCollection<mtl::vec::strided_vector_ref<Value, Parameters> > + : public Collection<mtl::vec::strided_vector_ref<Value, Parameters> > + { + typedef Value& reference; + }; +#endif + + + +#ifdef __GXX_CONCEPTS__ + template <typename Value> + concept_map MutableCollection<<std::vector<Value> > + { + typedef typename std::vector<Value>::value_type value_type; + typedef typename std::vector<Value>::const_reference const_reference; + typedef typename std::vector<Value>::size_type size_type; + + typedef typename std::vector<Value>::reference reference; + }; +#else + template <typename Value> + struct MutableCollection<std::vector<Value> > + : public Collection<std::vector<Value> > + { + typedef typename std::vector<Value>::reference reference; + }; +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <typename T> + struct OrientedCollection<const T> + : OrientedCollection<T> + {}; +#endif + + + +#ifdef __GXX_CONCEPTS__ + template <typename Value, typename Parameters> + concept_map OrientedCollection<mtl::mat::dense2D<Value, Parameters> > + { + typedef Value value_type; + typedef const Value& const_reference; + typedef typename mtl::mat::dense2D<Value, Parameters>::size_type size_type; + + typedef typename mtl::mat::dense2D<Value, Parameters>::orientation orientation; + }; +#else + template <typename Value, typename Parameters> + struct OrientedCollection<mtl::mat::dense2D<Value, Parameters> > + : public Collection<mtl::mat::dense2D<Value, Parameters> > + { + typedef typename mtl::mat::dense2D<Value, Parameters>::orientation orientation; + }; +#endif + +#ifdef __GXX_CONCEPTS__ + + template <typename Value, unsigned long Mask, typename Parameters> + concept_map OrientedCollection<mtl::mat::morton_dense<Value, Mask, Parameters> > + { + typedef Value value_type; + typedef const Value& const_reference; + typedef typename mtl::mat::morton_dense<Value, Mask, Parameters>::size_type size_type; + + typedef typename mtl::mat::morton_dense<Value, Mask, Parameters>::orientation orientation; + }; + +#else + + template <typename Value, unsigned long Mask, typename Parameters> + struct OrientedCollection<mtl::mat::morton_dense<Value, Mask, Parameters> > + : public Collection<mtl::mat::morton_dense<Value, Mask, Parameters> > + { + typedef typename mtl::mat::morton_dense<Value, Mask, Parameters>::orientation orientation; + }; + +#endif + +#ifdef __GXX_CONCEPTS__ + template <typename Value, typename Parameters> + concept_map OrientedCollection<mtl::mat::compressed2D<Value, Parameters> > + { + typedef Value value_type; + typedef const Value& const_reference; + typedef typename mtl::mat::compressed2D<Value, Parameters>::size_type size_type; + + typedef typename mtl::mat::compressed2D<Value, Parameters>::orientation orientation; + }; +#else + template <typename Value, typename Parameters> + struct OrientedCollection<mtl::mat::compressed2D<Value, Parameters> > + : public Collection<mtl::mat::compressed2D<Value, Parameters> > + { + typedef typename mtl::mat::compressed2D<Value, Parameters>::orientation orientation; + }; +#endif + +#ifdef __GXX_CONCEPTS__ +#else + template <typename Matrix> + struct OrientedCollection<mtl::mat::indirect<Matrix> > + : public Collection<mtl::mat::indirect<Matrix> > + { + typedef row_major orientation; + }; +#endif + +#ifdef __GXX_CONCEPTS__ + template <typename Value, typename Parameters> + concept_map OrientedCollection<mtl::vec::dense_vector<Value, Parameters> > + { + typedef Value value_type; + typedef const Value& const_reference; + typedef typename mtl::vec::dense_vector<Value, Parameters>::size_type size_type; + + typedef typename mtl::vec::dense_vector<Value, Parameters>::orientation orientation; + }; +#else + template <typename Value, typename Parameters> + struct OrientedCollection<mtl::vec::dense_vector<Value, Parameters> > + : public Collection<mtl::vec::dense_vector<Value, Parameters> > + { + typedef typename mtl::vec::dense_vector<Value, Parameters>::orientation orientation; + }; +#endif + +#ifdef __GXX_CONCEPTS__ + template <typename Value, typename Parameters> + concept_map OrientedCollection<mtl::vec::strided_vector_ref<Value, Parameters> > + { + typedef typename boost::remove_const<Value>::type value_type; + typedef const Value& const_reference; + typedef typename mtl::vec::strided_vector_ref<Value, Parameters>::size_type size_type; + + typedef typename mtl::vec::strided_vector_ref<Value, Parameters>::orientation orientation; + }; +#else + template <typename Value, typename Parameters> + struct OrientedCollection<mtl::vec::strided_vector_ref<Value, Parameters> > + : public Collection<mtl::vec::strided_vector_ref<Value, Parameters> > + { + typedef typename mtl::vec::strided_vector_ref<Value, Parameters>::orientation orientation; + }; +#endif + + + +#ifdef __GXX_CONCEPTS__ + template <typename Value> + concept_map OrientedCollection<std::vector<Value> > + { + typedef Value value_type; + typedef const Value& const_reference; + typedef typename std::vector<Value>::size_type size_type; + + typedef mtl::tag::col_major orientation; + }; +#else + template <typename Value> + struct OrientedCollection<std::vector<Value> > + : public Collection<std::vector<Value> > + { + typedef mtl::tag::col_major orientation; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Scaling, typename Coll> + concept_map OrientedCollection< mat::scaled_view<Scaling, Coll> > + { + typedef typename mat::scaled_view<Scaling, Coll>::value_type value_type; + typedef typename mat::scaled_view<Scaling, Coll>::const_reference const_reference; + typedef typename mat::scaled_view<Scaling, Coll>::size_type size_type; + + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#else + template <typename Scaling, typename Coll> + struct OrientedCollection< mat::scaled_view<Scaling, Coll> > + : public Collection< mat::scaled_view<Scaling, Coll> > + { + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#endif + +// added by Hui Li +#ifdef __GXX_CONCEPTS__ + template <typename Coll, typename RScaling> + concept_map OrientedCollection< mat::rscaled_view<Coll,RScaling> > + { + typedef typename mat::rscaled_view<Coll,RScaling>::value_type value_type; + typedef typename mat::rscaled_view<Coll,RScaling>::const_reference const_reference; + typedef typename mat::rscaled_view<Coll,RScaling>::size_type size_type; + + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#else + template <typename Coll, typename RScaling> + struct OrientedCollection< mat::rscaled_view<Coll,RScaling> > + : public Collection< mat::rscaled_view<Coll,RScaling> > + { + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Scaling, typename Coll> + concept_map OrientedCollection< mtl::vec::scaled_view<Scaling, Coll> > + { + typedef typename mtl::vec::scaled_view<Scaling, Coll>::value_type value_type; + typedef typename mtl::vec::scaled_view<Scaling, Coll>::const_reference const_reference; + typedef typename mtl::vec::scaled_view<Scaling, Coll>::size_type size_type; + + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#else + template <typename Scaling, typename Coll> + struct OrientedCollection< mtl::vec::scaled_view<Scaling, Coll> > + : public Collection< mtl::vec::scaled_view<Scaling, Coll> > + { + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#endif + +//added by Hui Li +#ifdef __GXX_CONCEPTS__ + template <typename Coll, typename RScaling> + concept_map OrientedCollection< mtl::vec::rscaled_view<Coll,RScaling> > + { + typedef typename mtl::vec::rscaled_view<Coll,RScaling>::value_type value_type; + typedef typename mtl::vec::rscaled_view<Coll,RScaling>::const_reference const_reference; + typedef typename mtl::vec::rscaled_view<Coll,RScaling>::size_type size_type; + + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#else + template <typename Coll, typename RScaling> + struct OrientedCollection< mtl::vec::rscaled_view<Coll,RScaling> > + : public Collection< mtl::vec::rscaled_view<Coll,RScaling> > + { + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Coll> + concept_map OrientedCollection<mat::conj_view<Coll> > + { + typedef typename mat::conj_view<Coll>::value_type value_type; + typedef typename mat::conj_view<Coll>::const_reference const_reference; + typedef typename mat::conj_view<Coll>::size_type size_type; + + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#else + template <typename Coll> + struct OrientedCollection<mat::conj_view<Coll> > + : public Collection<mat::conj_view<Coll> > + { + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Coll> + concept_map OrientedCollection<mtl::vec::conj_view<Coll> > + { + typedef typename mtl::vec::conj_view<Coll>::value_type value_type; + typedef typename mtl::vec::conj_view<Coll>::const_reference const_reference; + typedef typename mtl::vec::conj_view<Coll>::size_type size_type; + + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#else + template <typename Coll> + struct OrientedCollection<mtl::vec::conj_view<Coll> > + : public Collection<mtl::vec::conj_view<Coll> > + { + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Functor, typename Coll> + concept_map OrientedCollection< mtl::vec::map_view<Functor, Coll> > + { + typedef typename mtl::vec::map_view<Functor, Coll>::value_type value_type; + typedef typename mtl::vec::map_view<Functor, Coll>::const_reference const_reference; + typedef typename mtl::vec::map_view<Functor, Coll>::size_type size_type; + + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#else + template <typename Functor, typename Coll> + struct OrientedCollection< mtl::vec::map_view<Functor, Coll> > + : public Collection< mtl::vec::map_view<Functor, Coll> > + { + typedef typename OrientedCollection<Coll>::orientation orientation; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + template <typename Coll> + concept_map OrientedCollection<mtl::mat::transposed_view<Coll> > + { + typedef typename mtl::mat::transposed_view<Coll>::value_type value_type; + typedef typename mtl::mat::transposed_view<Coll>::const_reference const_reference; + typedef typename mtl::mat::transposed_view<Coll>::size_type size_type; + + typedef typename mtl::traits::transposed_orientation<typename OrientedCollection<Coll>::orientation>::type orientation; + }; +#else + template <typename Coll> + struct OrientedCollection<mtl::mat::transposed_view<Coll> > + : public Collection<mtl::mat::transposed_view<Coll> > + { + typedef typename mtl::traits::transposed_orientation<typename OrientedCollection<Coll>::orientation>::type orientation; + }; +#endif + +#ifdef __GXX_CONCEPTS__ + template <typename Coll> + concept_map OrientedCollection<mat::hermitian_view<Coll> > + { + typedef typename mat::hermitian_view<Coll>::value_type value_type; + typedef typename mat::hermitian_view<Coll>::const_reference const_reference; + typedef typename mat::hermitian_view<Coll>::size_type size_type; + + typedef typename mtl::traits::transposed_orientation<typename OrientedCollection<Coll>::orientation>::type orientation; + }; +#else + template <typename Coll> + struct OrientedCollection<mat::hermitian_view<Coll> > + : public Collection<mat::hermitian_view<Coll> > + { + typedef typename mtl::traits::transposed_orientation<typename OrientedCollection<Coll>::orientation>::type orientation; + }; +#endif + + + +/*@}*/ // end of group Concepts + +} // namespace mtl + +#endif // MTL_COLLECTION_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/concept/magnitude.hpp b/install/MTL/include/boost/numeric/mtl/concept/magnitude.hpp new file mode 100644 index 00000000..ba432ca1 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/concept/magnitude.hpp @@ -0,0 +1,88 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAGNITUDE_INCLUDE +#define MTL_MAGNITUDE_INCLUDE + +#include <complex> + +namespace mtl { + +// ================================================= +// Concept to specify return type of abs (and norms) +// ================================================= + + +#ifdef __GXX_CONCEPTS__ + +// Concept to specify to specify projection of scalar value to comparable type +// For instance as return type of abs +// Minimalist definition for maximal applicability +auto concept Magnitude<typename T> +{ + typename type = T; +}; + +template <typename T> +concept_map Magnitude<std::complex<T> > +{ + typedef T type; +} + + +// Concept for norms etc., which are real values in mathematical definitions +auto concept RealMagnitude<typename T> + : Magnitude<T> +{ + requires std::EqualityComparable<type>; + requires std::LessThanComparable<type>; + +#ifndef CONCEPTS_WITHOUT_OVERLOADED_REQUIREMENTS + requires Field<type>; +#endif + + type sqrt(type); + + type abs(T); +} + +#else // now without concepts + +/// Concept/Type-trait for magnitudes of scalar values +/** This name is overloaded: when MTL4 is compiled with a concept-compiler + Magnitude is a concept otherwise a type-trait. + It is used for instance in norms. +**/ +template <typename T> +struct Magnitude +{ + /// Associated type; the default is T; must be specialized appropriately + typedef T type; +}; + +/// Specialization for complex numbers +template <typename T> +struct Magnitude<std::complex<T> > +{ + /// The associated type is defined to the complex's value type + typedef T type; +}; + +template <typename T> struct RealMagnitude + : public Magnitude<T> +{}; + +#endif // __GXX_CONCEPTS__ + +} // namespace mtl + +#endif // MTL_MAGNITUDE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/concept/matrix.hpp b/install/MTL/include/boost/numeric/mtl/concept/matrix.hpp new file mode 100644 index 00000000..028331cb --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/concept/matrix.hpp @@ -0,0 +1,468 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_CONCEPT_INCLUDE +#define MTL_MATRIX_CONCEPT_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> + +#ifdef __GXX_CONCEPTS__ +# include <concepts> +#else +# include <boost/numeric/linear_algebra/pseudo_concept.hpp> +#endif + +namespace mtl { + +/** @addtogroup Concepts + * @{ + */ + +#ifdef __GXX_CONCEPTS__ + concept Matrix<typename T> + : AlgebraicCollection<T> + { + const_reference T::operator() (size_type row, size_type col) const; + + size_type nnz(T); + + // A[r][c] equivalent to A(r, c) + }; +#else + /// Concept Matrix + /** + \par Refinement of: + - AlgebraicCollection < T > + \par Notation: + - X is a type that models Matrix + - A is an object of type X + - r, c are objects of size_type + \par Valid expressions: + - Element access: \n A(r, c) \n Return Type: const_reference + \n Semantics: Element in row \p r and column \p c + - Element access: \n A[r][c] \n Equivalent to A(r, c) + \par Models: + - dense2D + - morton_dense + - compressed2D + \note + -# The access via A[r][c] is supposed to be implemented by means of A(r, c) (typically via CRTP and proxies). + If it would become (extremely) important to support 2D C arrays, it might be necessary to drop the requirement + of element access by A(r, c). + -# The name const_reference does not imply that the return type is necessarily referrable. For instance compressed2D + returns value_type. + */ + template <typename T> + struct Matrix + : public AlgebraicCollection<T> + { + /// Element access + const_reference T::operator() (size_type row, size_type col) const; + }; +#endif + + + +#ifdef __GXX_CONCEPTS__ + concept MatrixInserter<typename T> + { + typename matrix_type; + // typename T::matrix_type; + + requires Matrix<matrix_type>; + + typename proxy_type; + proxy_type operator() (Matrix<matrix_type>::size_type row, Matrix<matrix_type>::size_type col); + + T operator<< (proxy_type, Matrix<matrix_type>::value_type>); + }; +#else + /// Concept MatrixInserter: classes that enable efficient insertion into matrices, esp. compressed sparse. + /** + Used to fill non-mutable matrices like compressed2D. Matrix inserters might be parametrizable with + update functor. This allow to perform different operations when entry already exist, e.g. overwriting, + incrementing, minimum, ... The most important updates are certainly overwrite and increment (add). + + \par Associated types + - matrix_type + + \par Requires: + - Matrix<matrix_type> + + \par Notation: + - X is a type that models MatrixInserter + - A is an object of type X + - r, c are objects of type Matrix<matrix_type>::size_type + - v is an object of type Matrix<matrix_type>::value_type + + \par Valid expressions: + - Insertion with shift operator: \n + A(r, c) << v \n + Return type: T + \par Models: + - mtl::mat::inserter < T > + \note + -# Used in concept InsertableMatrix + */ + template <typename T> + struct MatrixInserter + { + /// Type of matrix into which is inserted + typedef associated_type matrix_type; + + /// Return type of element access; only proxy + typedef associated_type proxy_type; + /// Element access; returns a proxy that handles insertion + proxy_type operator() (Matrix<matrix_type>::size_type row, Matrix<matrix_type>::size_type col); + }; +#endif + +#ifdef __GXX_CONCEPTS__ + concept InsertableMatrix<typename T> + : Matrix<T> + { + requires MatrixInserter<mtl::mat::inserter<T> >; + }; +#else + /// Concept InsertableMatrix: %matrix that can be filled by means of inserter + /** + \par Requires: + - MatrixInserter < mtl::mat::inserter< T > > + \par Models: + - dense2D + - morton_dense + - compressed2D + \note + -# All matrices in MTL model this concept in order and all future matrices are supposed to. + */ + template <typename T> + struct InsertableMatrix + : Matrix < T > + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept MutableMatrix<typename T> + : Matrix<T>, + MutableCollection<T> + { + reference T::operator() (size_type row, size_type col); + + // A[r][c] equivalent to A(r, c) + }; +#else + /// Concept MutableMatrix + /** + \par Refinement of: + - Matrix < T > + - MutableCollection < T > + \par Notation: + - X is a type that models MutableMatrix + - A is an object of type X + - r, c are objects of size_type + \par Valid expressions: + - Element access: \n A(r, c) \n Return Type: reference + \n Semantics: Element in row \p r and column \p c + - Element access: \n A[r][c] \n Equivalent to A(r, c) + \par Models: + - dense2D + - morton_dense + \note + -# The access via A[r][c] is supposed to be implemented by means of A(r, c) (typically via CRTP and proxies). + If it would become (extremely) important to support 2D C arrays, it might be necessary to drop the requirement + of element access by A(r, c). + */ + template <typename T> + struct MutableMatrix + : public Matrix<T>, + public MutableCollection<T> + { + /// Element access (in addition to const access) + reference T::operator() (size_type row, size_type col); + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept ConstantSizeMatrix<typename T> + : Matrix<T>, + ConstantSizeAlgebraicCollection<T> + {}; +#else + /// Concept ConstantSizeMatrix + /** + \par Refinement of: + - Matrix < T > + - ConstantSizeAlgebraicCollection < T > + */ + template <typename T> + struct ConstantSizeMatrix + : public Matrix<T>, + public ConstantSizeAlgebraicCollection<T> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept ResizeableMatrix<typename T> + : Matrix<T> + { + void T::resize(size_type r, size_type c); + }; +#else + /// Concept ResizeableMatrix + /** + \par Refinement of: + - Matrix < T > + */ + template <typename T> + struct ResizeableMatrix + : public Matrix<T> + { + /// Resize function + /** If new memory should be allocated only if total size changes */ + void resize(size_type r, size_type c); + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept RowTraversableMatrix<typename M> + : Matrix<M>, + TraversableCollection<mtl::tag::row, M> + {}; +#else + /// Concept RowTraversableMatrix: provides begin and end cursor to traverse rows + /** + \par Refinement of: + - Matrix < M > + - TraversableCollection <mtl::tag::row, M> + */ + template <typename M> + struct RowTraversableMatrix + : public Matrix<M>, + public TraversableCollection<mtl::tag::row, M> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept ColumnTraversableMatrix<typename M> + : Matrix<M>, + TraversableCollection<mtl::tag::col, M> + {}; +#else + /// Concept ColumnTraversableMatrix: provides begin and end cursor to traverse columns + /** + \par Refinement of: + - Matrix < M > + - TraversableCollection <mtl::tag::col, M> + */ + template <typename M> + struct ColumnTraversableMatrix + : public Matrix<M>, + public TraversableCollection<mtl::tag::col, M> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept MajorTraversableMatrix<typename M> + : Matrix<M>, + TraversableCollection<mtl::tag::major, M> + {}; +#else + /// Concept MajorTraversableMatrix: traversable on major dimension + /** + Concept for matrices that are traversable along the major dimension, i.e. + traversing the rows of a row-major matrix and the columns of a column-major matrices. + The cursors begin and end are provided. + \par Refinement of: + - Matrix < M > + - TraversableCollection <mtl::tag::major, M> + \note + -# This traversal corresponds to the iterator design in MTL 2. + */ + template <typename M> + struct MajorTraversableMatrix + : public Matrix<M>, + public TraversableCollection<mtl::tag::major, M> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept MinorTraversableMatrix<typename M> + : Matrix<M>, + TraversableCollection<mtl::tag::minor, M> + {}; +#else + /// Concept MinorTraversableMatrix: traversable on minor dimension + /** + Concept for matrices that are traversable along the minor dimension, i.e. + traversing the columns of a row-major matrix and the rows of a column-major matrices. + The cursors begin and end are provided. + \par Refinement of: + - Matrix < M > + - TraversableCollection <mtl::tag::minor, M> + \note + -# This traversal corresponds to the iterator design in MTL 2. + */ + template <typename M> + struct MinorTraversableMatrix + : public Matrix<M>, + public TraversableCollection<mtl::tag::minor, M> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept AllTraversableMatrix<typename M> + : Matrix<M>, + TraversableCollection<mtl::tag::all, M> + {}; +#else + /// Concept AllTraversableMatrix: provides traversion over all elements + /** + All elements of a matrix are traversed, including structural zeros. Can be used, e.g., + for printing. + The cursors begin and end are provided. + \par Refinement of: + - Matrix < M > + - TraversableCollection <mtl::tag::all, M> + \note + -# For dense matrices the concept is equivalent to NonZeroTraversableMatrix. + */ + template <typename M> + struct AllTraversableMatrix + : public Matrix<M>, + public TraversableCollection<mtl::tag::all, M> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept NonZeroTraversableMatrix<typename M> + : Matrix<M>, + TraversableCollection<mtl::tag::nz, M> + {}; +#else + /// Concept NonZeroTraversableMatrix: provides traversion over all structural non-zeros + /** + All structural non-zero elements of a matrix are traversed. Can be used, e.g., + for copying. + The cursors begin and end are provided. + \par Refinement of: + - Matrix < M > + - TraversableCollection <mtl::tag::all, M> + \note + -# For dense matrices the concept is equivalent to AllTraversableMatrix. + */ + template <typename M> + struct AllTraversableMatrix + : public Matrix<M>, + public TraversableCollection<mtl::tag::all, M> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept AllTraversableSubMatrix<typename Tag, typename M> + : Matrix<M>, + TraversableCollection<Tag, M>, + TraversableCollection<mtl::tag::all, TraversableCollection<Tag, M>::result_type> + {}; +#else + /// Concept AllTraversableSubMatrix: provides traversion of rows, columns of matrices + /** + All elements of a row or a column, according to the Tag, are traversed. + The cursors begin and end are provided. + \par Refinement of: + - Matrix < M > + - TraversableCollection<Tag, M>, + - TraversableCollection<mtl::tag::all, TraversableCollection<Tag, M>::result_type> + */ + template <typename Tag, typename M> + struct AllTraversableMatrix + : public Matrix<M>, + public TraversableCollection<Tag, M>, + public TraversableCollection<mtl::tag::all, TraversableCollection<Tag, M>::result_type> + {}; +#endif + + + +#ifdef __GXX_CONCEPTS__ + concept NonZeroTraversableSubMatrix<typename Tag, typename M> + : Matrix<M>, + TraversableCollection<Tag, M>, + TraversableCollection<mtl::tag::nz, TraversableCollection<Tag, M>::result_type> + {}; +#else + /// Concept NonZeroTraversableSubMatrix: provides traversion of non-zero in rows or columns of matrices + /** + All structural non-zero elements of a row or a column, according to the Tag, are traversed. + The cursors begin and end are provided. + \par Refinement of: + - Matrix < M > + - TraversableCollection<Tag, M>, + - TraversableCollection<mtl::tag::nz, TraversableCollection<Tag, M>::result_type> + */ + template <typename Tag, typename M> + struct NonZeroTraversableSubMatrix + : public Matrix<M>, + public TraversableCollection<Tag, M>, + public TraversableCollection<mtl::tag::nz, TraversableCollection<Tag, M>::result_type> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept IteratableSubMatrix<typename Tag, typename ITag, typename M> + : Matrix<M>, + TraversableCollection<Tag, M>, + TraversableCollection<ITag, TraversableCollection<Tag, M>::result_type> + {}; +#else + /// Concept IteratableSubMatrix: provides iteration over elements within rows or columns of matrices + /** + This concepts actually combines four sub-concepts. The iteration can be either performed over + all elements or only over structural non-zero elements whereby the iterator can be a const-iterator + or a mutable iterator. These four combinations are specified by the tags mtl::tag::iter::all, + mtl::tag::iter::nz, mtl::tag::const_iter::all, and + mtl::tag::const_iter::nz for ITag. The template parameter Tag can be mtl::tag::major or mtl::tag::column. + The cursors begin and end are provided. + \par Refinement of: + - Matrix < M > + - TraversableCollection<Tag, M>, + - TraversableCollection<ITag, TraversableCollection<Tag, M>::result_type> + */ + template <typename Tag, typename ITag, typename M> + struct IteratableSubMatrix + : public Matrix<M>, + public TraversableCollection<Tag, M>, + public TraversableCollection<ITag, TraversableCollection<Tag, M>::result_type> + {}; +#endif + + + + + + +/*@}*/ // end of group Concepts + +} // namespace mtl + +#endif // MTL_MATRIX_CONCEPT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/concept/static_functor.hpp b/install/MTL/include/boost/numeric/mtl/concept/static_functor.hpp new file mode 100644 index 00000000..e1a549f6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/concept/static_functor.hpp @@ -0,0 +1,76 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_STATIC_FUNCTOR_INCLUDE +#define MTL_STATIC_FUNCTOR_INCLUDE + +#include <complex> + +namespace mtl { + +#ifdef __GXX_CONCEPTS__ + +// Concept to specify static unary functors +auto concept StaticUnaryFunctor<typename T> +{ + typename argument_type = T::argument_type; + typename result_type = T::result_type; + + static result_type apply(argument_type); + result_type T::operator()(argument_type); +}; + +auto concept StaticBinaryFunctor<typename T> +{ + typename first_argument_type = T::first_argument_type; + typename second_argument_type = T::second_argument_type; + typename result_type = T::result_type; + + static result_type apply(first_argument_type, second_argument_type); + result_type T::operator()(first_argument_type, second_argument_type); +}; + +#else // now without concepts + +/// Concept/Type-trait for static unary functors +/** This name is overloaded: when MTL4 is compiled with a concept-compiler + StaticUnaryFunctor is a concept otherwise a type-trait. +**/ +template <typename T> +struct StaticUnaryFunctor +{ + /// Associated type for argument, by default set to class's internal typedef (specialize if not present) + typedef typename T::argument_type argument_type; + /// Associated type for result, by default set to class's internal typedef (specialize if not present) + typedef typename T::result_type result_type; +}; + +/// Concept/Type-trait for static binary functors +/** This name is overloaded: when MTL4 is compiled with a concept-compiler + StaticBinaryFunctor is a concept otherwise a type-trait. +**/ +template <typename T> +struct StaticBinaryFunctor +{ + /// Associated type for 1st argument, by default set to class's internal typedef (specialize if not present) + typedef typename T::first_argument_type first_argument_type; + /// Associated type for 2nd argument, by default set to class's internal typedef (specialize if not present) + typedef typename T::second_argument_type second_argument_type; + /// Associated type for result, by default set to class's internal typedef (specialize if not present) + typedef typename T::result_type result_type; +}; + +#endif // __GXX_CONCEPTS__ + +} // namespace mtl + +#endif // MTL_STATIC_FUNCTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/concept/std_concept.hpp b/install/MTL/include/boost/numeric/mtl/concept/std_concept.hpp new file mode 100644 index 00000000..0a8f091f --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/concept/std_concept.hpp @@ -0,0 +1,286 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_STD_CONCEPT_INCLUDE +#define MTL_STD_CONCEPT_INCLUDE + +#ifdef __GXX_CONCEPTS__ +# include <concepts> +#else +// Use Joel de Guzman's return type deduction +# include <boost/numeric/ublas/detail/returntype_deduction.hpp> +# include <boost/mpl/at.hpp> +# include <boost/numeric/linear_algebra/pseudo_concept.hpp> +#endif + +// #include <boost/numeric/mtl/utility/is_what.hpp> -> leads to cyclic inclusions +// #include <boost/numeric/mtl/operation/mult_result.hpp> + +namespace mtl { + +/** + * \defgroup Concepts Concepts + */ +/*@{*/ + +#ifdef __GXX_CONCEPTS__ + + // Stay with the old names (for the moment) + + auto concept Addable<typename T, typename U = T> : std::HasPlus<T, U> {} + auto concept Subtractable<typename T, typename U = T> : std::HasMinus<T, U> {} + auto concept Multiplicable<typename T, typename U = T> : std::HasMultiply<T, U> {} + auto concept Divisible<typename T, typename U = T> : std::HasDivide<T, U> {} + +#if 0 + using std::Addable; + using std::Subtractable; + using std::Multiplicable; + + auto concept Divisible<typename T, typename U = T> + { + typename result_type; + result_type operator/(const T& t, const U& u); + }; +#endif + +#else // without concepts + + // Use Joel de Guzman's return type deduction + // Adapted from uBLAS + // Differences: + // - Separate types for all operations + // - result_type like in concept + + /// Concept Addable: Binary operation + /** In concept-free compilations also used for return type deduction */ + template<class X, class Y> + class Addable + { + typedef boost::numeric::ublas::type_deduction_detail::base_result_of<X, Y> base_type; + static typename base_type::x_type x; + static typename base_type::y_type y; + static const std::size_t size = sizeof ( + boost::numeric::ublas::type_deduction_detail::test< + typename base_type::x_type + , typename base_type::y_type + >(x + y) + ); + + static const std::size_t index = (size / sizeof (char)) - 1; + typedef typename boost::mpl::at_c< + typename base_type::types, index>::type id; + public: + /// Result of addition + typedef typename id::type result_type; + }; + + + /// Concept Subtractable: Binary operation + /** In concept-free compilations also used for return type deduction */ + template<class X, class Y> + class Subtractable + { + typedef boost::numeric::ublas::type_deduction_detail::base_result_of<X, Y> base_type; + static typename base_type::x_type x; + static typename base_type::y_type y; + static const std::size_t size = sizeof ( + boost::numeric::ublas::type_deduction_detail::test< + typename base_type::x_type + , typename base_type::y_type + >(x - y) + ); + + static const std::size_t index = (size / sizeof (char)) - 1; + typedef typename boost::mpl::at_c< + typename base_type::types, index>::type id; + public: + /// Result of subtraction + typedef typename id::type result_type; + }; + +#if 0 // doesn't work + template<class X, class Y> + class Multiplicable_aux<X, Y, true> + { + typedef typename mtl::traits::mult_result<X, Y>::type type; + }; + + /// Concept Multiplicable: Binary operation + /** In concept-free compilations also used for return type deduction */ + template<class X, class Y, bool B> + class Multiplicable_aux + { + typedef boost::numeric::ublas::type_deduction_detail::base_result_of<X, Y> base_type; + static typename base_type::x_type x; + static typename base_type::y_type y; + static const std::size_t size = sizeof ( + boost::numeric::ublas::type_deduction_detail::test< + typename base_type::x_type + , typename base_type::y_type + >(x * y) + ); + + static const std::size_t index = (size / sizeof (char)) - 1; + typedef typename boost::mpl::at_c< + typename base_type::types, index>::type id; + public: + /// Result of multiplication + typedef typename id::type result_type; + }; + + /// Concept Multiplicable: Binary operation + /** In concept-free compilations also used for return type deduction */ + template<class X, class Y> + class Multiplicable + : Multiplicable_aux<X, Y, mtl::traits::is_scalar<X>::value && mtl::traits::is_scalar<Y>::value> + {}; +#endif + + /// Concept Multiplicable: Binary operation + /** In concept-free compilations also used for return type deduction */ + template<class X, class Y> + class Multiplicable + { + typedef boost::numeric::ublas::type_deduction_detail::base_result_of<X, Y> base_type; + static typename base_type::x_type x; + static typename base_type::y_type y; + static const std::size_t size = sizeof ( + boost::numeric::ublas::type_deduction_detail::test< + typename base_type::x_type + , typename base_type::y_type + >(x * y) + ); + + static const std::size_t index = (size / sizeof (char)) - 1; + typedef typename boost::mpl::at_c< + typename base_type::types, index>::type id; + public: + /// Result of multiplication + typedef typename id::type result_type; + }; + + /// Concept Divisible: Binary operation + /** In concept-free compilations also used for return type deduction */ + template<class X, class Y> + class Divisible + { + typedef boost::numeric::ublas::type_deduction_detail::base_result_of<X, Y> base_type; + static typename base_type::x_type x; + static typename base_type::y_type y; + static const std::size_t size = sizeof ( + boost::numeric::ublas::type_deduction_detail::test< + typename base_type::x_type + , typename base_type::y_type + >(x * y) + ); + + static const std::size_t index = (size / sizeof (char)) - 1; + typedef typename boost::mpl::at_c< + typename base_type::types, index>::type id; + public: + /// Result of division + typedef typename id::type result_type; + }; + +#endif + + +#ifdef __GXX_CONCEPTS__ + concept UnaryStaticFunctor<typename F, typename T> + : std::Callable1<F, T> + { + typename result_type; + + static result_type F::apply(T); + }; +#else + /// Concept UnaryFunctor + /** With concept corresponds to std::Callable1 */ + template <typename T> + struct UnaryFunctor + { + /// Result type of operator() + typedef associated_type result_type; + + /// The unary function + result_type operator()(T); + }; + + + /// Concept UnaryStaticFunctor + /** + \par Refinement of: + - std::Callable1 < T > + */ + template <typename T> + struct UnaryStaticFunctor + : public UnaryFunctor<T> + { + /// Result type of apply + typedef associated_type result_type; + + /// The unary static function + static result_type apply(T); + + /// The application operator behaves like apply. Exists for compatibility with UnaryFunctor + result_type operator()(T); + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + auto concept BinaryStaticFunctor<typename F, typename T, typename U> + : std::Callable2<F, T, U> + { + typename result_type; + + static result_type F::apply(T, U); + }; +#else + /// Concept BinaryFunctor + /** With concept corresponds to std::Callable2 */ + template <typename T, typename U> + struct BinaryFunctor + { + /// Result type of operator() + typedef associated_type result_type; + + /// The unary function + result_type operator()(T, U); + }; + + /// Concept BinaryStaticFunctor + /** + \par Refinement of: + - BinaryFunctor <T, U> + */ + template <typename T, typename U> + struct BinaryStaticFunctor + : public BinaryFunctor <T, U> + { + /// Result type of apply + typedef associated_type result_type; + + /// The unary static function + static result_type apply(T, U); + + /// The application operator behaves like apply. Exists for compatibility with BinaryFunctor + result_type operator()(T, U); + }; +#endif + +/*@}*/ // end of group Concepts + +} // namespace mtl + +#endif // MTL_STD_CONCEPT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/concept/vector.hpp b/install/MTL/include/boost/numeric/mtl/concept/vector.hpp new file mode 100644 index 00000000..a9c63209 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/concept/vector.hpp @@ -0,0 +1,142 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_CONCEPTS_INCLUDE +#define MTL_VECTOR_CONCEPTS_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> + +#ifdef __GXX_CONCEPTS__ +# include <concepts> +#else +# include <boost/numeric/linear_algebra/pseudo_concept.hpp> +#endif + +namespace mtl { + +/** @addtogroup Concepts + * @{ + */ + +#ifdef __GXX_CONCEPTS__ + concept Vector<typename T> + : AlgebraicCollection<T> + { + const_reference T::operator() (size_type index) const; + + const_reference T::operator[] (size_type index) const; + + size_type nnz(T); // maybe into AlgebraicCollection? + }; +#else + /// Concept Vector + /** + \par Refinement of: + - AlgebraicCollection < T > + \par Notation: + - X is a type that models Vector + - v is an object of type X + - r are objects of size_type + \par Valid expressions: + - Element access: \n v(r) \n Return Type: const_reference + \n Semantics: Element in row \p r and column \p c + - Element access: \n v[r] \n Equivalent to v(r) + \invariant + - Either num_cols(v), in case of a column vector, or num_rows(v), + in case of a row vector, must be 1! Otherwise it would be + a matrix. + \par Models: + - dense_vector + \note + -# If it would become (extremely) important to support 1D C arrays as Vector, + it might be necessary to drop the requirement + of element access by v(r). + */ + template <typename T> + struct Vector + : public AlgebraicCollection<T> + { + /// Element access + const_reference T::operator() (size_type index) const; + + /// Element access + const_reference T::operator[] (size_type index) const; + }; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept MutableVector<typename T> + : Vector<T>, + MutableCollection<T> + { + reference T::operator() (size_type index); + + reference T::operator[] (size_type index); + }; +#else + /// Concept MutableVector + /** + \par Refinement of: + - Vector < T > + - MutableCollection < T > + \par Notation: + - X is a type that models Vector + - v is an object of type X + - r are objects of size_type + \par Valid expressions: + - Element access: \n v(r) \n Return Type: reference + \n Semantics: Element in row \p r for a column vector or in column \p c for a row vector + - Element access: \n v[r] \n Equivalent to v(r) + \par Models: + - dense_vector + \note + -# If it would become (extremely) important to support 1D C arrays as Vector, + it might be necessary to drop the requirement + of element access by v(r). + */ + template <typename T> + struct MutableVector + : public Vector<T>, + public MutableCollection<T> + {}; +#endif + + +#ifdef __GXX_CONCEPTS__ + concept ConstantSizeVector<typename T> + : Vector<T>, + ConstantSizeAlgebraicCollection<T> + {}; +#else + /// Concept ConstantSizeVector + /** + \par Refinement of: + - Vector < T > + - ConstantSizeAlgebraicCollection < T > + */ + template <typename T> + struct ConstantSizeVector + : public Vector<T>, + public ConstantSizeAlgebraicCollection<T> + {}; +#endif + + + +/*@}*/ // end of group Concepts + + +} // namespace mtl + +#endif // MTL_VECTOR_CONCEPTS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/config.hpp b/install/MTL/include/boost/numeric/mtl/config.hpp new file mode 100644 index 00000000..3ace5289 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/config.hpp @@ -0,0 +1,97 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_CONFIG_INCLUDE +#define MTL_CONFIG_INCLUDE + +namespace mtl { + + + namespace mat { + + // parameters for dense operations + + +# ifdef MTL_MATRIX_DENSE_NON_RECURSIVE_PRODUCT_LIMIT + const std::size_t dense_non_recursive_product_limit= MTL_MATRIX_DENSE_NON_RECURSIVE_PRODUCT_LIMIT; +# else + /// Maximal matrix size of dense matrices that is multiplied without recursion + /** Can be reset with a macro definition or corresponding compiler flag, + e.g. {-D|/D}MTL_MATRIX_DENSE_NON_RECURSIVE_PRODUCT_LIMIT=4000 **/ + const std::size_t dense_non_recursive_product_limit= 10000; +# endif + + +# ifdef MTL_STRAIGHT_DMAT_DMAT_MULT_LIMIT + const std::size_t straight_dmat_dmat_mult_limit= MTL_STRAIGHT_DMAT_DMAT_MULT_LIMIT; +# else + /// Defines the maximal number of entries in each matrix for which the dense matrix product is computed in C++. + /** Above this limit the computation is performed with BLAS if available. + Can be reset with a macro definition or corresponding compiler flag, + e.g. {-D|/D}MTL_STRAIGHT_DMAT_DMAT_MULT_LIMIT=4000 **/ + const std::size_t straight_dmat_dmat_mult_limit= 1000; +# endif + +# ifdef MTL_FULLY_UNROLL_DMAT_DMAT_MULT_LIMIT + const std::size_t fully_unroll_dmat_dmat_mult_limit= MTL_FULLY_UNROLL_DMAT_DMAT_MULT_LIMIT; +# else + /// Defines the maximal number of entries in each matrix for which the dense matrix product is fully unrolled. + /** Above this limit the computation is performed with a tiled loop implementation. + Applies only to statically sized matrices. + Can be reset with a macro definition or corresponding compiler flag, + e.g. {-D|/D}MTL_FULLY_UNROLL_DMAT_DMAT_MULT_LIMIT=40 **/ + const std::size_t fully_unroll_dmat_dmat_mult_limit= 10; +# endif + + // parameters for sparse operations + +# ifdef MTL_MATRIX_COMPRESSED_LINEAR_SEARCH_LIMIT + const std::size_t compressed_linear_search_limit= MTL_MATRIX_COMPRESSED_LINEAR_SEARCH_LIMIT; +# else + /// Maximal number of entries that is searched linearly within a row/column of a CRS/CCS matrix + /** Above this std::lower_bound is used. + Can be reset with a macro definition or corresponding compiler flag, + e.g. {-D|/D}MTL_MATRIX_COMPRESSED_LINEAR_SEARCH_LIMIT=16 **/ + const std::size_t compressed_linear_search_limit= 10; +# endif + +# ifdef MTL_SORTED_BLOCK_INSERTION_LIMIT + const std::size_t sorted_block_insertion_limit= MTL_SORTED_BLOCK_INSERTION_LIMIT; +# else + /// Maximal number of columns in block that is inserted separately; above this the block is presorted (only row-major sparse matrices). + /** Can be reset with a macro definition or corresponding compiler flag, + e.g. {-D|/D}MTL_SORTED_BLOCK_INSERTION_LIMIT=8 + Default is 5. **/ + const std::size_t sorted_block_insertion_limit= 5; +# endif + +# ifdef MTL_CRS_CVEC_MULT_BLOCK_SIZE + const std::size_t crs_cvec_mult_block_size= MTL_CRS_CVEC_MULT_BLOCK_SIZE; +# else + /// Number of rows that are handled independently in each iteration of CRS times vector product + /** The independent treatment of multiple matrix rows enables concurrency + (although we do not explicit parallelize the matrix product here). + The default is treating 4 rows in each iteration. + This default can be changed with a macro definition or corresponding compiler flag, + e.g. {-D|/D}MTL_CRS_CVEC_MULT_BLOCK_SIZE=8 + At the same the macro MTL_CRS_CVEC_MULT_TUNING must be defined. **/ + const std::size_t crs_cvec_mult_block_size= 4; +# endif + + + } + + + +} // namespace mtl + +#endif // MTL_CONFIG_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/detail/base_cursor.hpp b/install/MTL/include/boost/numeric/mtl/detail/base_cursor.hpp new file mode 100644 index 00000000..11cc95e9 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/detail/base_cursor.hpp @@ -0,0 +1,105 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_BASE_CURSOR_INCLUDE +#define MTL_BASE_CURSOR_INCLUDE + +namespace mtl { namespace detail { + +// base class for different cursors, works with pointers and integers +template <class Key> class base_cursor +{ + public: + typedef Key key_type; + typedef base_cursor self; + + base_cursor () {} + base_cursor (key_type key) : key(key) {} + + key_type operator*() const + { + return key; + } + + key_type value() const + { + return key; + } + + self& operator++ () + { + ++key; return *this; + } + self operator++ (int) + { + self tmp = *this; + ++key; + return tmp; + } + self& operator-- () + { + --key; + return *this; + } + self operator-- (int) + { + self tmp = *this; + --key; + return tmp; + } + self& operator+=(int n) + { + key += n; + return *this; + } + + self operator+(int n) const + { + self tmp = *this; + tmp+= n; + return tmp; + } + + self& operator-=(int n) + { + key -= n; + return *this; + } + + int operator-(const self& cc) const + { + return this->key - cc.key; + } + + bool operator==(const self& cc) const + { + return key == cc.key; + } + + bool operator!=(const self& cc) const + { + return !(*this == cc); + } + + + + + key_type key; +}; // base_cursor + + + +}} // namespace mtl::detail + +#endif // MTL_BASE_CURSOR_INCLUDE + + diff --git a/install/MTL/include/boost/numeric/mtl/detail/contiguous_memory_block.hpp b/install/MTL/include/boost/numeric/mtl/detail/contiguous_memory_block.hpp new file mode 100644 index 00000000..c458b405 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/detail/contiguous_memory_block.hpp @@ -0,0 +1,493 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_CONTIGUOUS_MEMORY_BLOCK_INCLUDE +#define MTL_CONTIGUOUS_MEMORY_BLOCK_INCLUDE + +#include <cassert> +#include <algorithm> +#include <boost/static_assert.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/matrix/dimension.hpp> +#include <boost/numeric/mtl/detail/index.hpp> +#include <boost/numeric/mtl/operation/clone.hpp> + + + +namespace mtl { namespace detail { +using std::size_t; + +// Macro MTL_ENABLE_ALIGNMENT is by default not set + +// Minimal size of memory allocation using alignment +#ifndef MTL_ALIGNMENT_LIMIT +# define MTL_ALIGNMENT_LIMIT 1024 +#endif + +// Alignment in memory +#ifndef MTL_ALIGNMENT +# define MTL_ALIGNMENT 128 +#endif + + +// Size helper for static size +template <unsigned Size> +struct size_helper +{ + typedef size_helper self; + + size_helper() {} + explicit size_helper(std::size_t size) + { + set_size(size); + } + +# ifndef MTL_IGNORE_STATIC_SIZE_VIOLATION + void set_size(std::size_t MTL_DEBUG_ARG(size)) + { MTL_DEBUG_THROW_IF(Size != size, change_static_size()); } +# else + void set_size(std::size_t) {} +# endif + + std::size_t used_memory() const { return Size; } + friend void swap(self&, self&) {} +}; + +// Manage size only if template parameter is 0, i.e. dynamic size +template <> +struct size_helper<0> +{ + typedef size_helper self; + + size_helper(std::size_t size= 0) : my_used_memory(size) {} + + void set_size(std::size_t size) + { + my_used_memory= size; + } + + std::size_t used_memory() const + { + return my_used_memory; + } + + friend void swap(self& x, self& y) + { + std::swap(x.my_used_memory, y.my_used_memory); + } + + protected: + std::size_t my_used_memory; +}; + + +// Encapsulate behavior of alignment + +# ifdef MTL_ENABLE_ALIGNMENT + + template <typename Value> + struct alignment_helper + { + typedef alignment_helper self; + + alignment_helper() : malloc_address(0) {} + + Value* alligned_alloc(std::size_t size) + { + if (size == 0) + return 0; + + bool align= size * sizeof(value_type) >= MTL_ALIGNMENT_LIMIT; + std::size_t bytes= size * sizeof(value_type); + + if (align) + bytes+= MTL_ALIGNMENT - 1; + + char* p= malloc_address= new char[bytes]; + if (align) + while ((long int)(p) % MTL_ALIGNMENT) p++; + // p+= MTL_ALIGNMENT - (long int)(p) % MTL_ALIGNMENT; + + return reinterpret_cast<value_type*>(p); + } + + void aligned_delete(bool is_own, Value*& data) + { + if (is_own && malloc_address) delete[] malloc_address; + data= 0; + } + + friend void swap(self& x, self& y) + { + using std::swap + swap(x.malloc_address, y.malloc_address); + } + + private: + char* malloc_address; + }; + +# else + + template <typename Value> + struct alignment_helper + { + typedef alignment_helper self; + + Value* alligned_alloc(std::size_t size) { return size > 0 ? new Value[size] : (Value*)(0); } + + void aligned_delete(bool is_own, Value*& data) + { + if (is_own && data != 0) // std::cout << "Delete " << data << '\n', + delete[] data, data= 0; + } + + friend void swap(self&, self&) {} + }; + +# endif + + +template <typename Value, bool OnStack, unsigned Size> +struct memory_crtp +// : public contiguous_memory_block<Value, OnStack, Size> +{ + typedef contiguous_memory_block<Value, OnStack, Size> base; + + static bool const on_stack= OnStack; + + typedef Value value_type; + typedef value_type* pointer_type; + typedef const value_type* const_pointer_type; + + // offset of key (pointer) w.r.t. data + // values must be stored consecutively + size_t offset(const Value* p) const + { + return p - static_cast<const base&>(*this).data; + } + + // returns pointer to data + pointer_type elements() + { + return static_cast<base&>(*this).data; + } + + // returns const pointer to data + const_pointer_type elements() const + { + return static_cast<const base&>(*this).data; + } + + // returns n-th value in consecutive memory + // (whatever this means in the corr. matrix format) + value_type& value_n(size_t offset) + { + return static_cast<base&>(*this).data[offset]; + } + + // returns n-th value in consecutive memory + // (whatever this means in the corr. matrix format) + const value_type& value_n(size_t offset) const + { + return static_cast<const base&>(*this).data[offset]; + } + +}; + +// OnStack == false -> data on heap +template <typename Value, bool OnStack, unsigned Size> +struct contiguous_memory_block + : public size_helper<Size>, + public alignment_helper<Value>, + public memory_crtp<Value, OnStack, Size> +{ + typedef Value value_type; + typedef contiguous_memory_block self; + typedef size_helper<Size> size_base; + typedef alignment_helper<Value> alignment_base; + typedef memory_crtp<Value, OnStack, Size> crtp_base; + + /// Category of memory, determines behaviour + enum c_t {own, //< My own memory: allocate and free it + external, //< Memory, complete memory block of other item, only reference + view //< View of other's memory (e.g. sub-matrix), different construction than external + }; + + private: + + void alloc(std::size_t size) + { + category= own; + this->set_size(size); + data= this->alligned_alloc(this->used_memory()); + } + + void delete_it() + { + this->aligned_delete(category == own, data); + } + + template <typename Other> + void copy_construction(const Other& other) + { + using std::copy; + category= own; + // std::cout << "Copied in copy constructor.\n"; + alloc(other.used_memory()); + // std::cout << "My address: " << data << ", other address: " << other.data << '\n'; + copy(other.data, other.data + other.used_memory(), data); + } + + void move_construction(self& other) + { + // std::cout << "Data moved in constructor.\n"; + category= own; data= 0; + swap(*this, other); + } + + // Copy the arguments of a view (shallowly) and leave original as it is + void copy_view(const self& other) + { + // std::cout << "View copied (shallowly).\n"; + assert(other.category == view); + category= view; + this->set_size(other.used_memory()); + data= other.data; + } + + template <typename Other> + void copy_assignment(const Other& other) + { + // std::cout << "Copied in assignment.\n"; + if (this->used_memory() == 0) + alloc(other.used_memory()); + MTL_DEBUG_THROW_IF(this->used_memory() != other.used_memory(), incompatible_size()); + std::copy(other.data, other.data + other.used_memory(), data); + } + + public: + contiguous_memory_block() : category(own), data(0) {} + + explicit contiguous_memory_block(Value *data, std::size_t size, bool is_view= false) + : size_base(size), category(is_view ? view : external), data(data) + {} + + explicit contiguous_memory_block(std::size_t size) : category(own) + { + // std::cout << "Constructor with size.\n"; + alloc(size); + // std::cout << "New block at " << data << '\n'; + } + + // Default copy constructor + contiguous_memory_block(const self& other) : size_base(other) + { + // std::cout << "Copy constructor (same type).\n"; + if (other.category == view) + copy_view(other); + else + copy_construction(other); + } + + // Force copy construction + contiguous_memory_block(const self& other, clone_ctor) + { + // std::cout << "(Forced) Copy constructor (same type).\n"; + copy_construction(other); + } + + // Other types must be copied always + template<typename Value2, bool OnStack2, unsigned Size2> + explicit contiguous_memory_block(const contiguous_memory_block<Value2, OnStack2, Size2>& other) + { + // std::cout << "Copy constructor (different type).\n"; + copy_construction(other); + } + +#ifdef MTL_WITH_MOVE + self& operator=(self&& other) + { + move_assignment(other); + return *this; + } + + self& operator=(const self& other) + { + copy_assignment(other); + return *this; + } +#elif defined(MTL_MEMORY_BLOCK_MOVE_EMULATION) + // Operator takes parameter by value and consumes it + self& operator=(self other) + { + move_assignment(other); + return *this; + } +#else + self& operator=(self other) + { + copy_assignment(other); + return *this; + } +#endif + + // Same behavior as consuming assignment, to be used by derived classes +protected: + void move_assignment(self& other) + { + // std::cout << "Consuming assignment operator (if same type).\n"; + if (category == own && other.category == own) + swap(*this, other); + else + copy_assignment(other); + } + +public: + template<typename Value2, bool OnStack2, unsigned Size2> + self& operator=(const contiguous_memory_block<Value2, OnStack2, Size2>& other) + { + // std::cout << "Assignment from different array type -> Copy.\n"; + copy_assignment(other); + return *this; + } + + + void set_view() { category= view; } + + void realloc(std::size_t size) + { + if (Size == 0) { + + // If already have memory of the right size we can keep it + if (size == this->used_memory()) + return; + MTL_DEBUG_THROW_IF(category != own, + logic_error("Can't change the size of collections with external memory")); + delete_it(); + alloc(size); + } else { + MTL_DEBUG_THROW_IF(size != Size, logic_error("Can't change static size")); + } + } + + ~contiguous_memory_block() + { + //std::cout << "Delete block with address " << data << '\n'; + delete_it(); + } + + friend void swap(self& x, self& y) + { + using std::swap; + swap(x.category, y.category); + std::swap(x.data, y.data); + swap(static_cast<size_base&>(x), static_cast<size_base&>(y)); + swap(static_cast<alignment_base&>(x), static_cast<alignment_base&>(y)); + } + +protected: + enum c_t category; +public: + Value *data; +}; + +// OnStack == true +template <typename Value, unsigned Size> +struct contiguous_memory_block<Value, true, Size> + : public alignment_helper<Value>, + public memory_crtp<Value, true, Size> +{ + typedef Value value_type; + typedef contiguous_memory_block self; + //static bool const on_stack= true; + + Value data[Size]; + +# ifdef NDEBUG + contiguous_memory_block() {} // default constructor in release mode + explicit contiguous_memory_block(std::size_t) {} +# else + explicit contiguous_memory_block(std::size_t size= Size) + { + MTL_DEBUG_THROW_IF(Size != size, incompatible_size()); + } +# endif + + // Move-semantics ignored for arrays on stack + contiguous_memory_block(const self& other) + { + // std::cout << "Copied in copy constructor (same type).\n"; + std::copy(other.data, other.data+Size, data); + } + + + template<typename Value2, bool OnStack2, unsigned Size2> + explicit contiguous_memory_block(const contiguous_memory_block<Value2, OnStack2, Size2>& other) + { + // std::cout << "Copied in copy constructor (different type).\n"; + MTL_DEBUG_THROW_IF(Size != other.used_memory(), incompatible_size()); + std::copy(other.data, other.data + other.used_memory(), data); + } + + self& operator=(const self& other) + { + // std::cout << "Assignment from same type.\n"; + std::copy(other.data, other.data+Size, data); + return *this; + } + + // For consistency with non-static blocks, to be used by derived classes +protected: + void move_assignment(self& other) + { + std::copy(other.data, other.data+Size, data); + } + +public: + template<typename Value2, bool OnStack2, unsigned Size2> + self& operator=(const contiguous_memory_block<Value2, OnStack2, Size2>& other) + { + // std::cout << "Assignment from different type.\n"; + MTL_DEBUG_THROW_IF(Size != other.used_memory(), incompatible_size()); + std::copy(other.data, other.data + other.used_memory(), data); + return *this; + } + + + void realloc(std::size_t MTL_DEBUG_ARG(s)) + { + // Arrays on stack cannot be reallocated but if the size isn't changed we are fine + assert(s == Size); + } + + std::size_t used_memory() const + { + return Size; + } + + protected: + enum c_t {own}; + static const c_t category= own; +}; + + +}} // namespace mtl::detail + +namespace mtl { + template <typename Value, bool OnStack, unsigned Size> + struct is_clonable< detail::contiguous_memory_block<Value, OnStack, Size> > : boost::mpl::bool_<!OnStack> {}; +} + +#endif // MTL_CONTIGUOUS_MEMORY_BLOCK_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/detail/dilated_int.hpp b/install/MTL/include/boost/numeric/mtl/detail/dilated_int.hpp new file mode 100644 index 00000000..dff44a1e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/detail/dilated_int.hpp @@ -0,0 +1,255 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. +// +// Written by Jiahu Deng and Peter Gottschling + +#ifndef MTL_DILATED_INT_INCLUDE +#define MTL_DILATED_INT_INCLUDE + +#include <boost/numeric/mtl/detail/masked_dilation_tables.hpp> +#include <iostream> + +namespace mtl { namespace dilated { + +template <typename T> +struct even_bits +{ + static T const value = T(-1) / T(3); +}; + +template <typename T> +struct odd_bits +{ + static T const value = ~even_bits<T>::value; +}; + +// And is mostly used with original mask +template <typename T, T BitMask, bool Normalized> +struct masking +{ + inline void operator() (T& x) const + { + x &= BitMask; + } +}; + +// Or is mostly used with complementary mask +template <typename T, T BitMask> +struct masking<T, BitMask, false> +{ + inline void operator() (T& x) const + { + static T const anti_mask = ~BitMask; + x |= anti_mask; + } +}; + +template <typename T, T BitMask> +struct last_bit; + +template <typename T, T BitMask, bool IsZero> +struct last_bit_helper { + static T const tmp = BitMask >> 1; + static T const value = BitMask & 1 ? 1 : last_bit_helper<T, tmp, tmp == 0>::value << 1; +}; + +template <typename T, T BitMask> +struct last_bit_helper<T, BitMask, true> { + static T const value = 0; +}; + +template <typename T, T BitMask> +struct last_bit +{ + static T const value = last_bit_helper<T, BitMask, BitMask == 0>::value; +}; + + +template <typename T, T BitMask, bool Normalized> +struct dilated_int +{ + typedef T value_type; + typedef dilated_int<T, BitMask, Normalized> self; + + typedef masking<T, BitMask, Normalized> clean_carry; + typedef masking<T, BitMask, !Normalized> init_carry; + + static T const bit_mask = BitMask, + anti_mask = ~BitMask, + dilated_zero = Normalized ? 0 : anti_mask, + dilated_one = dilated_zero + last_bit<T, bit_mask>::value; +protected: + // masked_dilation_tables<T, bit_mask> mask_tables; + // masked_dilation_tables<T, anti_mask> anti_tables; probably not needed + +// will be protected later +public: + T i; + + void dilate(T x) + { + static const T to_switch_on = Normalized ? 0 : anti_mask; + i = mask<bit_mask>(x) | to_switch_on; + } + +public: + + // Default constructor + dilated_int() + { + i = Normalized ? 0 : anti_mask; + } + + // Only works for odd and even bits and 4-byte-int at this point !!!!!!!!!!!!!!!!!!! + explicit dilated_int(T x) + { + dilate(x); + } + + // Only works for odd and even bits and 4-byte-int at this point !!!!!!!!!!!!!!!!!!! + T undilate() + { + return unmask<bit_mask>(i); + } + + T dilated_value() const + { + return i; + } + + self& operator= (self const& x) + { + i = x.i; + return *this; + } + + self& operator= (T x) + { + dilate(x); + return *this; + } + + self& operator++ () + { + static T const x = Normalized ? bit_mask : T(-1); + i -= x; + clean_carry()(i); + return *this; + } + + self operator++ (int) + { + self tmp(*this); + ++*this; + return tmp; + } + + self& operator+= (self const& x) + { + init_carry()(i); + i+= x.i; + clean_carry()(i); + return *this; + } + + self operator+ (self const& x) + { + self tmp(*this); + return tmp += x; + } + + self& operator-- () + { + i -= dilated_one; + clean_carry()(i); + return *this; + } + + self operator-- (int) + { + self tmp(*this); + --*this; + return tmp; + } + + self& operator-= (self const& x) + { + i -= x.i; + clean_carry()(i); + return *this; + } + + self operator- (self const& x) const + { + self tmp(*this); + return tmp -= x; + } + + // advance in both directions, special care is needed for negative values + self& advance(int inc) + { + value_type incv(inc >= 0 ? inc : -inc); + self incd(incv); + if (inc >= 0) + operator+=(incd); + else + operator-=(incd); + return *this; + } + + bool operator== (self const& x) const + { + return i == x.i; + } + + bool operator!= (self const& x) const + { + return i != x.i; + } + + bool operator<= (self const& x) const + { + return i <= x.i; + } + + bool operator< (self const& x) const + { + return i < x.i; + } + + bool operator>= (self const& x) const + { + return i >= x.i; + } + + bool operator> (self const& x) const + { + return i > x.i; + } + + +}; + +} // namespace mtl::dilated + +using dilated::dilated_int; + +} // namespace mtl + +template <typename T, T BitMask, bool Normalized> +inline std::ostream& operator<< (std::ostream& os, mtl::dilated::dilated_int<T, BitMask, Normalized> d) +{ + os.setf(std::ios_base::hex, std::ios_base::basefield); + return os << d.i; +} + +#endif // MTL_DILATED_INT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/detail/dilation_table.hpp b/install/MTL/include/boost/numeric/mtl/detail/dilation_table.hpp new file mode 100644 index 00000000..cffe40be --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/detail/dilation_table.hpp @@ -0,0 +1,143 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. +// +// Written by Jiahu Deng and Peter Gottschling + +/* This is designed for 16-bit undilated integers and 32-bit dilated + * integers. If we want to scale that up, it's an easy change but you will + * need to make it. - Greg 00/05/12 + */ + +/* Rewrote by Jiahu Deng 06/08/2005 + modified the undilated-lookup table, use the algorithms from + Prof.Wise's paper, Converting to and from Dilated Integers. + Added supports for anti-dilated integers. +*/ + +#ifndef MTL_DILATION_TABLE_INCLUDE +#define MTL_DILATION_TABLE_INCLUDE + +namespace mtl { namespace dilated { + + +static const unsigned short int dilate_lut[256] = { + 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, + 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, + 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, + 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, + 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, + 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, + 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, + 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, + 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, + 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, + 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, + 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, + 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, + 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, + 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, + 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, + 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, + 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, + 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, + 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, + 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, + 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, + 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, + 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, + 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, + 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, + 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, + 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, + 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, + 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, + 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, + 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555, +}; + + +static const unsigned short int anti_dilate_lut[256] = { + 0xaaaa,0xaaab,0xaaae,0xaaaf,0xaaba,0xaabb,0xaabe,0xaabf, + 0xaaea,0xaaeb,0xaaee,0xaaef,0xaafa,0xaafb,0xaafe,0xaaff, + 0xabaa,0xabab,0xabae,0xabaf,0xabba,0xabbb,0xabbe,0xabbf, + 0xabea,0xabeb,0xabee,0xabef,0xabfa,0xabfb,0xabfe,0xabff, + 0xaeaa,0xaeab,0xaeae,0xaeaf,0xaeba,0xaebb,0xaebe,0xaebf, + 0xaeea,0xaeeb,0xaeee,0xaeef,0xaefa,0xaefb,0xaefe,0xaeff, + 0xafaa,0xafab,0xafae,0xafaf,0xafba,0xafbb,0xafbe,0xafbf, + 0xafea,0xafeb,0xafee,0xafef,0xaffa,0xaffb,0xaffe,0xafff, + 0xbaaa,0xbaab,0xbaae,0xbaaf,0xbaba,0xbabb,0xbabe,0xbabf, + 0xbaea,0xbaeb,0xbaee,0xbaef,0xbafa,0xbafb,0xbafe,0xbaff, + 0xbbaa,0xbbab,0xbbae,0xbbaf,0xbbba,0xbbbb,0xbbbe,0xbbbf, + 0xbbea,0xbbeb,0xbbee,0xbbef,0xbbfa,0xbbfb,0xbbfe,0xbbff, + 0xbeaa,0xbeab,0xbeae,0xbeaf,0xbeba,0xbebb,0xbebe,0xbebf, + 0xbeea,0xbeeb,0xbeee,0xbeef,0xbefa,0xbefb,0xbefe,0xbeff, + 0xbfaa,0xbfab,0xbfae,0xbfaf,0xbfba,0xbfbb,0xbfbe,0xbfbf, + 0xbfea,0xbfeb,0xbfee,0xbfef,0xbffa,0xbffb,0xbffe,0xbfff, + 0xeaaa,0xeaab,0xeaae,0xeaaf,0xeaba,0xeabb,0xeabe,0xeabf, + 0xeaea,0xeaeb,0xeaee,0xeaef,0xeafa,0xeafb,0xeafe,0xeaff, + 0xebaa,0xebab,0xebae,0xebaf,0xebba,0xebbb,0xebbe,0xebbf, + 0xebea,0xebeb,0xebee,0xebef,0xebfa,0xebfb,0xebfe,0xebff, + 0xeeaa,0xeeab,0xeeae,0xeeaf,0xeeba,0xeebb,0xeebe,0xeebf, + 0xeeea,0xeeeb,0xeeee,0xeeef,0xeefa,0xeefb,0xeefe,0xeeff, + 0xefaa,0xefab,0xefae,0xefaf,0xefba,0xefbb,0xefbe,0xefbf, + 0xefea,0xefeb,0xefee,0xefef,0xeffa,0xeffb,0xeffe,0xefff, + 0xfaaa,0xfaab,0xfaae,0xfaaf,0xfaba,0xfabb,0xfabe,0xfabf, + 0xfaea,0xfaeb,0xfaee,0xfaef,0xfafa,0xfafb,0xfafe,0xfaff, + 0xfbaa,0xfbab,0xfbae,0xfbaf,0xfbba,0xfbbb,0xfbbe,0xfbbf, + 0xfbea,0xfbeb,0xfbee,0xfbef,0xfbfa,0xfbfb,0xfbfe,0xfbff, + 0xfeaa,0xfeab,0xfeae,0xfeaf,0xfeba,0xfebb,0xfebe,0xfebf, + 0xfeea,0xfeeb,0xfeee,0xfeef,0xfefa,0xfefb,0xfefe,0xfeff, + 0xffaa,0xffab,0xffae,0xffaf,0xffba,0xffbb,0xffbe,0xffbf, + 0xffea,0xffeb,0xffee,0xffef,0xfffa,0xfffb,0xfffe,0xffff, + +}; + +static const unsigned short int undilate_lut[256] = { + 0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13, + 0x20, 0x21, 0x30, 0x31, 0x22, 0x23, 0x32, 0x33, + 0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17, + 0x24, 0x25, 0x34, 0x35, 0x26, 0x27, 0x36, 0x37, + 0x40, 0x41, 0x50, 0x51, 0x42, 0x43, 0x52, 0x53, + 0x60, 0x61, 0x70, 0x71, 0x62, 0x63, 0x72, 0x73, + 0x44, 0x45, 0x54, 0x55, 0x46, 0x47, 0x56, 0x57, + 0x64, 0x65, 0x74, 0x75, 0x66, 0x67, 0x76, 0x77, + 0x08, 0x09, 0x18, 0x19, 0x0a, 0x0b, 0x1a, 0x1b, + 0x28, 0x29, 0x38, 0x39, 0x2a, 0x2b, 0x3a, 0x3b, + 0x0c, 0x0d, 0x1c, 0x1d, 0x0e, 0x0f, 0x1e, 0x1f, + 0x2c, 0x2d, 0x3c, 0x3d, 0x2e, 0x2f, 0x3e, 0x3f, + 0x48, 0x49, 0x58, 0x59, 0x4a, 0x4b, 0x5a, 0x5b, + 0x68, 0x69, 0x78, 0x79, 0x6a, 0x6b, 0x7a, 0x7b, + 0x4c, 0x4d, 0x5c, 0x5d, 0x4e, 0x4f, 0x5e, 0x5f, + 0x6c, 0x6d, 0x7c, 0x7d, 0x6e, 0x6f, 0x7e, 0x7f, + 0x80, 0x81, 0x90, 0x91, 0x82, 0x83, 0x92, 0x93, + 0xa0, 0xa1, 0xb0, 0xb1, 0xa2, 0xa3, 0xb2, 0xb3, + 0x84, 0x85, 0x94, 0x95, 0x86, 0x87, 0x96, 0x97, + 0xa4, 0xa5, 0xb4, 0xb5, 0xa6, 0xa7, 0xb6, 0xb7, + 0xc0, 0xc1, 0xd0, 0xd1, 0xc2, 0xc3, 0xd2, 0xd3, + 0xe0, 0xe1, 0xf0, 0xf1, 0xe2, 0xe3, 0xf2, 0xf3, + 0xc4, 0xc5, 0xd4, 0xd5, 0xc6, 0xc7, 0xd6, 0xd7, + 0xe4, 0xe5, 0xf4, 0xf5, 0xe6, 0xe7, 0xf6, 0xf7, + 0x88, 0x89, 0x98, 0x99, 0x8a, 0x8b, 0x9a, 0x9b, + 0xa8, 0xa9, 0xb8, 0xb9, 0xaa, 0xab, 0xba, 0xbb, + 0x8c, 0x8d, 0x9c, 0x9d, 0x8e, 0x8f, 0x9e, 0x9f, + 0xac, 0xad, 0xbc, 0xbd, 0xae, 0xaf, 0xbe, 0xbf, + 0xc8, 0xc9, 0xd8, 0xd9, 0xca, 0xcb, 0xda, 0xdb, + 0xe8, 0xe9, 0xf8, 0xf9, 0xea, 0xeb, 0xfa, 0xfb, + 0xcc, 0xcd, 0xdc, 0xdd, 0xce, 0xcf, 0xde, 0xdf, + 0xec, 0xed, 0xfc, 0xfd, 0xee, 0xef, 0xfe, 0xff, +}; + + + +}} // namespace mtl::dilated + +#endif // MTL_DILATION_TABLE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/detail/index.hpp b/install/MTL/include/boost/numeric/mtl/detail/index.hpp new file mode 100644 index 00000000..62de2d71 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/detail/index.hpp @@ -0,0 +1,72 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_INDEX_INCLUDE +#define MTL_INDEX_INCLUDE + +// The whole idea of changing indices is insane! +// Thus, the file shouldn't exist at all. + +#include <boost/mpl/if.hpp> + +namespace mtl { namespace index { + +// Index like in C (identical with internal representation) +struct c_index {}; + +// Index like Fortran +struct f_index {}; + + +#if 0 +// Which index has type T +template <class T> struct which_index +{ + typedef typename boost::mpl::if_c< + traits::is_mtl_type<T>::value + , typename T::index_type // mtl data shall know their type + , c_index // others are by default c + >::type type; +}; +#endif + + +template <class T> struct which_index +{ + typedef typename T::index_type type; +}; + +// Change from internal representation to requested index type +template <class T> inline T change_to(c_index, T i) +{ + return i; +} + +template <class T> inline T change_to(f_index, T i) +{ + return i + 1; +} + +// Change from requested index type to internal representation +template <class T> inline T change_from(c_index, T i) +{ + return i; +} + +template <class T> inline T change_from(f_index, T i) +{ + return i - 1; +} + +}} // namespace mtl::index + +#endif // MTL_INDEX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/detail/masked_dilation_tables.hpp b/install/MTL/include/boost/numeric/mtl/detail/masked_dilation_tables.hpp new file mode 100644 index 00000000..ef693c63 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/detail/masked_dilation_tables.hpp @@ -0,0 +1,290 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MASKED_DILATION_TABLES_INCLUDE +#define MTL_MASKED_DILATION_TABLES_INCLUDE + +#include <iostream> +#include <iomanip> +#include <cassert> + +namespace mtl { namespace dilated { + +template <class T, T Mask> +struct masked_dilation_tables +{ + typedef masked_dilation_tables self; + typedef T value_type; + const static T mask= Mask; + + static const T n_bytes= sizeof(T); // number of bytes of the unmasked value of this type + typedef T lookup_type[n_bytes][256]; + typedef T mp_type[n_bytes]; + typedef T it_type[n_bytes]; // why int ??? switch to T + + protected: + static lookup_type* my_mask_lut, *my_unmask_lut; + static mp_type* my_mask_piece; + static it_type* my_mask_size, *my_mask_shift_table, *my_unmask_shift_table; + static int n_valid_table, instances; + public: + + masked_dilation_tables() + { + if (instances++ == 0) + compute_tables(); + } + + ~masked_dilation_tables() + { + if (--instances == 0) { + delete[] my_mask_lut; + delete[] my_unmask_lut; + delete[] my_mask_piece; + delete[] my_mask_size; + delete[] my_mask_shift_table; + delete[] my_unmask_shift_table; + } + } + + lookup_type& mask_lut() { return *my_mask_lut; } + lookup_type& unmask_lut() { return *my_unmask_lut; } + mp_type& mask_piece() { return *my_mask_piece; } + it_type& mask_size() { return *my_mask_size; } + it_type& mask_shift_table() { return *my_mask_shift_table; } + it_type& unmask_shift_table() { return *my_unmask_shift_table; } + +private: + + // get mask of the style 0xfff... + static T get_f_mask(int n_bits) { return (1 << n_bits) - 1; } + + T inc(T i, T mask) { return ((i - mask) & mask); } + + void compute_tables() + { + // std::cout << "computing tables! " << std::endl; + init(); + + // compute the mask table + for (int j = 0; j < n_valid_table; ++j) { + T f_mask = get_f_mask(mask_size()[j]), i, ii; + for (i = 0, ii = 0; i < 256; ++i, ii = inc(ii, mask_piece()[j])) + mask_lut()[j][i] = (ii & f_mask) << mask_shift_table()[j]; // need to shift + } + + // compute the unmask table + T f_mask = get_f_mask(8); + for (T j = 0; j < sizeof(T); ++j) { + T t_mask = (Mask >> (8*j)) & f_mask, i, ii; + for(i = 0, ii = 0; ii < t_mask; ii = inc(ii, t_mask), ++i) + unmask_lut()[j][ii] = i << unmask_shift_table()[j]; + // set the value for the last one + unmask_lut()[j][t_mask] = i << unmask_shift_table()[j]; + } + } + + void allocate() + { + my_mask_lut= new lookup_type[1]; + my_unmask_lut= new lookup_type[1]; + my_mask_piece= new mp_type[1]; + my_mask_size= new it_type[1]; + my_mask_shift_table= new it_type[1]; + my_unmask_shift_table= new it_type[1]; + } + + + // initialize needed parameters + void init() + { + allocate(); + assert(count_n_ones(Mask) > 0); + n_valid_table= (count_n_ones(Mask) + 7) / 8; // calculate the number of valid table + set_mask(); + } + + // return the number of 1's in the mask + int count_n_ones(T t) + { + int n_ones = 0; + for (; t; t>>= 1) + if(t & 1) ++n_ones; + return n_ones; + } + + // return the number of valid bits in the mask + int count_bits(T t) + { + int bits = 0; + for (; t; t>>= 1) + ++bits; + return bits; + } + + + // set mask pieces + void set_mask() + { + // set the unmask shift table + unmask_shift_table()[0] = 0; + T t_mask = Mask, tmp, count; + for (T i = 1; i < n_bytes; ++i) { + tmp = t_mask & get_f_mask(8); + count = count_n_ones(tmp); + unmask_shift_table()[i] = count + unmask_shift_table()[i - 1]; + t_mask >>= 8; + } + + mask_shift_table()[0] = 0; // don't need shift for the first table + // if there is only 8 or less 1's in the mask, + // only one table is needed + if (n_valid_table == 1) { + mask_piece()[0] = Mask; + mask_size()[0] = count_bits(Mask); + return; + } + + t_mask = Mask; + for (int i = 0; i < n_valid_table - 1; ++i) { + T n_bits = 0, tmp = t_mask; + for (T n_ones= 0; n_ones < 8; ++n_bits) { + if ((t_mask & 0x01) == 1) ++n_ones; + t_mask = t_mask >>1; + } + // set the ith piece of mask, which must contains 8 1's + mask_piece()[i] = get_f_mask(n_bits) & tmp; + + // set the mask size table + mask_size()[i] = n_bits; + + // set shift table + mask_shift_table()[i + 1] = n_bits + mask_shift_table()[i]; + } + + // set the last piece of mask, which may contain less than 8 1's + // set the number of bits of the last mask + mask_piece()[n_valid_table - 1 ] = t_mask; + mask_size()[n_valid_table - 1] = count_bits(t_mask); + } + +public: + + // convert to masked integer + T to_masked(T x) + { + T result = 0; + for (int i = 0; i < n_valid_table; ++i) + result += mask_lut()[i][0xff & (x >> (8*i)) ]; + return result; + } + + + // convert to unmasked integer + T to_unmasked(T x) + { + T result = 0; + x &= Mask; + for (T i = 0; i < n_bytes; ++i) { + result += unmask_lut()[i][0xff & (x >> (8*i)) ]; + } + return result; + } +}; + +template <class T, T Mask> +typename masked_dilation_tables<T, Mask>::lookup_type* masked_dilation_tables<T, Mask>::my_mask_lut= 0; + +template <class T, T Mask> +typename masked_dilation_tables<T, Mask>::lookup_type* masked_dilation_tables<T, Mask>::my_unmask_lut= 0; + +template <class T, T Mask> +typename masked_dilation_tables<T, Mask>::mp_type* masked_dilation_tables<T, Mask>::my_mask_piece= 0; + +template <class T, T Mask> +typename masked_dilation_tables<T, Mask>::it_type* masked_dilation_tables<T, Mask>::my_mask_size= 0; + +template <class T, T Mask> +typename masked_dilation_tables<T, Mask>::it_type* masked_dilation_tables<T, Mask>::my_mask_shift_table= 0; + +template <class T, T Mask> +typename masked_dilation_tables<T, Mask>::it_type* masked_dilation_tables<T, Mask>::my_unmask_shift_table= 0; + +template <class T, T Mask> +int masked_dilation_tables<T, Mask>::n_valid_table= 0; + +template <class T, T Mask> +int masked_dilation_tables<T, Mask>::instances= 0; + + +// Masking: syntax e.g. mask<0x55555555>(7); +// Mask must be in front of T -> need casting :-( +template <long unsigned Mask, typename T> +inline T mask(T const& value) +{ + static masked_dilation_tables<T, T(Mask)> tables; + return tables.to_masked(value); +} + + +// Masking: syntax e.g. mask(7, table_object); +template <typename T, T Mask> +inline T mask(T const& value, masked_dilation_tables<T, Mask> tables) +{ + return tables.to_masked(value); +} + + +// Unmasking: syntax e.g. unmask<0x55555555>(7); +// Mask must be in front of T -> need casting :-( +template <long unsigned Mask, typename T> +inline T unmask(T const& value) +{ + static masked_dilation_tables<T, T(Mask)> tables; + return tables.to_unmasked(value); +} + + +// Unmasking: syntax e.g. unmask(7, table_object); +template <typename T, T Mask> +inline T unmask(T const& value, masked_dilation_tables<T, Mask> tables) +{ + return tables.to_unmasked(value); +} + + +// Conversion from Mask1 to Mask2 +// syntax e.g. from Morton to Doppler convert<0x55555555, 0x5555ff00>(7); +// Mask must be in front of T -> need casting :-( +template <long unsigned Mask1, long unsigned Mask2, typename T> +inline T convert(T const& value) +{ + return mask<Mask2>(unmask<Mask1>(value)); +} + +// Conversion from Mask1 to Mask2 +template <long unsigned Mask1, long unsigned Mask2, typename T> +inline T convert(T const& value, masked_dilation_tables<T, Mask1> const& tables1, + masked_dilation_tables<T, Mask2> const& tables2) +{ + return tables2.to_masked(tables1.to_unmasked(value)); +} + + + +} // namespace mtl::dilated + + //using dilated::dilated_int; + +} // namespace mtl + +#endif // MTL_MASKED_DILATION_TABLES_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/detail/range_generator.hpp b/install/MTL/include/boost/numeric/mtl/detail/range_generator.hpp new file mode 100644 index 00000000..97881455 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/detail/range_generator.hpp @@ -0,0 +1,307 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_DETAIL_RANGE_GENERATOR_INCLUDE +#define MTL_DETAIL_RANGE_GENERATOR_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/glas_tag.hpp> +#include <boost/numeric/mtl/utility/complexity.hpp> +#include <boost/numeric/mtl/detail/base_cursor.hpp> +#include <boost/mpl/less.hpp> + +namespace mtl { namespace traits { namespace detail { + + /// Range generator that traverses all elements of some densely stored collection + /** - Or contiguous parts of such collection + - Works for matrices and vectors when derived from contiguous_memory_block + **/ + template <typename Collection, typename Cursor, typename Complexity> + struct dense_element_range_generator + { + typedef Complexity complexity; + typedef Cursor type; + static int const level = 1; + + type begin(Collection const& collection) + { + return collection.elements(); + } + type end(Collection const& collection) + { + return collection.elements() + collection.used_memory(); + } + }; + + /// Range generator that traverses all elements of some collection stored in strides + template <typename Collection, typename Ref, typename Traversor> + struct strided_element_range_generator + { + typedef complexity_classes::linear complexity; + typedef Traversor type; + static int const level = 1; + + type begin(Ref& c) + { + return type(c.address_data(), c.stride()); + } + type end(Ref& c) + { + using mtl::size; + return type(c.address_data() + size(c) + c.stride(), c.stride()); + } + }; + + + // Like above over all elements but in terms of offsets + // Also with reference to collection in cursor + template <typename Matrix, typename Cursor, typename Complexity> + struct all_offsets_range_generator + { + typedef Complexity complexity; + typedef Cursor type; + static int const level = 1; + + type begin(Matrix const& matrix) const + { + return type(matrix, 0); + } + type end(Matrix const& matrix) const + { + return type(matrix, matrix.nnz()); + } + }; + + + // Cursor to some submatrix (e.g. row, column, block matrix, block row) + // This cursor is intended to be used by range generators to iterate + // over subsets of the submatrix this cursor refers to. + // For instance if this cursor refers to a row then a range + // can iterate over the elements in this row. + // If this cursor refers to a block then a range can iterate over the rows in this block. + // The level of a generated cursor must be of course at least one level less + // The tag serves to dispatching between row and column cursors + template <typename Matrix, typename Tag, int Level> + struct sub_matrix_cursor + : mtl::detail::base_cursor<int> + { + typedef sub_matrix_cursor self; + typedef mtl::detail::base_cursor<int> base; + typedef Matrix ref_type; + static int const level = Level; + + sub_matrix_cursor(int i, Matrix const& c) + : base(i), ref(c) + {} + + self operator+(int offset) const + { + return self(key + offset, ref); + } + + // otherwise base_cursor returns an int and ranged for doesn't work + // for getting the key of base_cursor use this->value() + self operator*() const { return *this; } + + Matrix const& ref; + }; + + // Key for canonically referring to its elements with row and column index + template <typename Matrix> + struct matrix_element_key + { + typedef typename Collection<Matrix>::size_type size_type; + typedef matrix_element_key self; + + matrix_element_key(Matrix const& ref, size_type r, size_type c) : ref(ref) + { + indices[0]= r; indices[1]= c; + } + + bool operator==(const self& cc) const { return &ref == &cc.ref && indices[0] == cc.indices[0] && indices[1] == cc.indices[1]; } + bool operator!=(const self& cc) const { return !(*this == cc); } + + size_type indices[2]; + Matrix const& ref; + }; + + // Cursor for canonically referring to its elements with row and column index + // Increments row for pos==0 and column for pos==1 + // Referring operator returns matrix_element_key + template <typename Matrix, int pos> + struct matrix_element_cursor + { + typedef typename Collection<Matrix>::size_type size_type; + typedef matrix_element_cursor self; + typedef matrix_element_key<Matrix> key_type; + static int const level = 2; + + matrix_element_cursor(Matrix const& ref, size_type r, size_type c) : ref(ref) + { + indices[0]= r; indices[1]= c; + } + + key_type operator*() const { return key_type(ref, indices[0], indices[1]); } + + self& operator++() { ++indices[pos]; return *this; } + self operator++(int) { self tmp(*this); ++indices[pos]; return tmp; } + self& operator+=(int n) { indices[pos]+= n; return *this; } + self& operator+(int n) const { self tmp = *this; tmp+= n; return tmp; } + + self& operator--() { indices[pos]--; return *this; } + self operator--(int) { self tmp(*this); indices[pos]--; return tmp; } + self& operator-=(int n) { indices[pos]-= n; return *this; } + self& operator-(int n) const { self tmp = *this; tmp-= n; return tmp; } + + bool operator==(const self& cc) const { return &ref == &cc.ref && indices[0] == cc.indices[0] && indices[1] == cc.indices[1]; } + bool operator!=(const self& cc) const { return !(*this == cc); } + + size_type indices[2]; + Matrix const& ref; + }; + + + template <typename Matrix, typename Complexity, int Level> + struct all_rows_range_generator + { + typedef Complexity complexity; + static int const level = Level; + typedef Matrix ref_type; + typedef sub_matrix_cursor<Matrix, glas::tag::row, Level> type; + typedef typename Collection<Matrix>::size_type size_type; + + type begin(Matrix const& c) const + { + return type(0, c); // return type(c.begin_row(), c); get rid of obsolete stuff + } + type end(Matrix const& c) const + { + using mtl::num_rows; using mtl::mat::num_rows; + return type(num_rows(c), c); //return type(c.end_row(), c); + } + type lower_bound(Matrix const& c, size_type position) const + { + using mtl::num_rows; + return type(std::min(num_rows(c), position), c); + } + }; + + template <typename Cursor> + struct all_cols_in_row_range_generator + { + typedef complexity_classes::linear complexity; + static int const level = 1; + typedef typename Cursor::ref_type ref_type; + typedef typename Collection<ref_type>::size_type size_type; + + + typedef matrix_element_cursor<ref_type, 1> type; + + type begin(Cursor const& c) const { return type(c.ref, c.value(), size_type(0)); } + type end(Cursor const& c) const { using mtl::num_cols; return type(c.ref, c.value(), num_cols(c.ref)); } + type lower_bound(Cursor const& c, size_type position) const + { + using mtl::num_cols; + return type(c.ref, c.value, std::min(num_cols(c.ref), position)); + } + }; + + + template <typename Matrix, typename Complexity, int Level> + struct all_cols_range_generator + { + typedef Complexity complexity; + static int const level = Level; + typedef sub_matrix_cursor<Matrix, glas::tag::col, Level> type; + typedef typename Collection<Matrix>::size_type size_type; + + type begin(Matrix const& c) const + { + return type(0, c); // return type(c.begin_col(), c); + } + type end(Matrix const& c) const + { + using mtl::num_cols; + return type(num_cols(c), c); // return type(c.end_col(), c); + } + type lower_bound(Matrix const& c, size_type position) const + { + using mtl::num_cols; + return type(std::min(num_cols(c), position), c); + } + }; + + template <typename Cursor> + struct all_rows_in_col_range_generator + { + typedef complexity_classes::linear complexity; + static int const level = 1; + typedef typename Cursor::ref_type ref_type; + typedef typename Collection<ref_type>::size_type size_type; + + + typedef matrix_element_cursor<ref_type, 0> type; + + type begin(Cursor const& c) const { return type(c.ref, 0, c.value()); } + type end(Cursor const& c) const { using mtl::num_rows; return type(c.ref, num_rows(c.ref), c.value()); } + type lower_bound(Cursor const& c, size_type position) const + { + using mtl::num_rows; + return type(c.ref, std::min(num_rows(c.ref), position), c.value()); + } + }; + + + // Use RangeGenerator for Collection by applying to .ref + template <typename Coll, typename RangeGenerator> + struct referred_range_generator + { + typedef typename RangeGenerator::complexity complexity; + static int const level = RangeGenerator::level; + typedef typename RangeGenerator::type type; + typedef typename Collection<Coll>::size_type size_type; + + type begin(const Coll& c) + { + return RangeGenerator().begin(c.ref); + } + + type end(const Coll& c) + { + return RangeGenerator().end(c.ref); + } + type lower_bound(const Coll& c, size_type position) + { + return RangeGenerator().lower_bound(c.ref, position); + } + }; + +} // namespace detail + + namespace range { + + template <typename Range1, typename Range2> + struct min + : public boost::mpl::if_< + boost::mpl::less< + typename Range1::complexity, + typename Range2::complexity> + , Range1 + , Range2 + > + {}; + } + +}} // namespace mtl::traits + +#endif // MTL_DETAIL_RANGE_GENERATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/detail/strided_base_cursor.hpp b/install/MTL/include/boost/numeric/mtl/detail/strided_base_cursor.hpp new file mode 100644 index 00000000..0465e9ee --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/detail/strided_base_cursor.hpp @@ -0,0 +1,80 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_STRIDED_BASE_CURSOR_INCLUDE +#define MTL_STRIDED_BASE_CURSOR_INCLUDE + +#include <boost/numeric/mtl/detail/base_cursor.hpp> + +namespace mtl { namespace detail { + +template <class Key> struct strided_base_cursor + : base_cursor<Key> +{ + typedef Key key_type; + typedef base_cursor<Key> base; + typedef strided_base_cursor self; + + strided_base_cursor () {} + strided_base_cursor (key_type key, std::size_t stride) + : base(key), stride(stride) + {} + + self& operator++ () + { + this->key+= stride; return *this; + } + self operator++ (int) + { + self tmp = *this; + this->key+= stride; + return tmp; + } + self& operator-- () + { + this->key-= stride; + return *this; + } + self operator-- (int) + { + self tmp = *this; + this->key-= stride; + return tmp; + } + self& operator+=(int n) + { + this->key += stride * n; + return *this; + } + self operator+(int n) const + { + self tmp(*this); + tmp+= n; + return tmp; + } + self& operator-=(int n) + { + this->key -= stride * n; + return *this; + } + + int operator-(const self& cc) const + { + return (this->key - cc.key) / stride; + } + + std::size_t stride; +}; + +}} // namespace mtl::detail + +#endif // MTL_STRIDED_BASE_CURSOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/detail/trivial_inserter.hpp b/install/MTL/include/boost/numeric/mtl/detail/trivial_inserter.hpp new file mode 100644 index 00000000..1ba93887 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/detail/trivial_inserter.hpp @@ -0,0 +1,103 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRIVIAL_INSERTER_INCLUDE +#define MTL_TRIVIAL_INSERTER_INCLUDE + +#include <boost/numeric/mtl/operation/update.hpp> +#include <boost/numeric/mtl/operation/size.hpp> +#include <boost/numeric/mtl/matrix/element_matrix.hpp> +#include <boost/numeric/mtl/matrix/element_array.hpp> + +namespace mtl { namespace detail { + + +// Matrix must have direct write access, i.e. matrix(row, col) must return a non-const reference +template <typename Matrix, typename Updater = mtl::operations::update_store<typename Matrix::value_type> > +struct trivial_inserter +{ + typedef trivial_inserter self; + typedef Matrix matrix_type; + typedef typename matrix_type::size_type size_type; + typedef typename matrix_type::value_type value_type; + typedef operations::update_proxy<self, size_type> proxy_type; + + explicit trivial_inserter(matrix_type& matrix, size_type) : matrix(matrix) {} + + proxy_type operator() (size_type row, size_type col) + { + return proxy_type(*this, row, col); + } + + + private: + + struct bracket_proxy + { + bracket_proxy(self& ref, size_type row) : ref(ref), row(row) {} + + proxy_type operator[](size_type col) + { + return proxy_type(ref, row, col); + } + + self& ref; + size_type row; + }; + + public: + + bracket_proxy operator[] (size_type row) + { + return bracket_proxy(*this, row); + } + + template <typename Value> + void update(size_type row, size_type col, Value val) + { + Updater() (matrix(row, col), val); + } + + template <typename Modifier, typename Value> + void modify(size_type row, size_type col, Value val) + { + Modifier() (matrix(row, col), val); + } + + + template <typename EMatrix, typename Rows, typename Cols> + self& operator<< (const mat::element_matrix_t<EMatrix, Rows, Cols>& elements) + { + using mtl::size; + for (unsigned ri= 0; ri < size(elements.rows); ri++) + for (unsigned ci= 0; ci < size(elements.cols); ci++) + update (elements.rows[ri], elements.cols[ci], elements.matrix(ri, ci)); + return *this; + } + + template <typename EMatrix, typename Rows, typename Cols> + self& operator<< (const mat::element_array_t<EMatrix, Rows, Cols>& elements) + { + using mtl::size; + for (unsigned ri= 0; ri < size(elements.rows); ri++) + for (unsigned ci= 0; ci < size(elements.cols); ci++) + update (elements.rows[ri], elements.cols[ci], elements.array[ri][ci]); + return *this; + } + + protected: + matrix_type& matrix; +}; + +}} // namespace mtl::detail + +#endif // MTL_TRIVIAL_INSERTER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/interface/arprec.hpp b/install/MTL/include/boost/numeric/mtl/interface/arprec.hpp new file mode 100644 index 00000000..dd172611 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/interface/arprec.hpp @@ -0,0 +1,61 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ARPREC_INCLUDE +#define MTL_ARPREC_INCLUDE + +#ifdef MTL_HAS_ARPREC + +#include <arprec/mp_real.h> +#include <arprec/mp_complex.h> + +#include <boost/numeric/mtl/concept/magnitude.hpp> +#include <boost/numeric/mtl/utility/true_copy.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> + +namespace mtl { + + /// Specialization for ARPREC complex numbers + template <> + struct Magnitude<mp_complex> + { + /// The associated type is ARPREC real + typedef mp_real type; + }; + + namespace traits { + + template <> + struct true_copy<mp_real_temp> + { + typedef mp_real type; + }; + } +} // namespace mtl + +namespace math { + + template <> + struct identity_t< add<mp_complex>, mp_complex > + : public std::binary_function<add<mp_complex>, mp_complex, mp_complex> + { + mp_complex operator() (const add<mp_complex>&, const mp_complex& /*ref*/) const + { + return mp_complex("0", "0"); + } + }; + +} // math + +#endif // MTL_HAS_ARPREC + +#endif // MTL_ARPREC_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/interface/blas.hpp b/install/MTL/include/boost/numeric/mtl/interface/blas.hpp new file mode 100644 index 00000000..13e8222a --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/interface/blas.hpp @@ -0,0 +1,165 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + + +#ifndef MTL_BLAS_INCLUDE +#define MTL_BLAS_INCLUDE + + +#ifdef MTL_HAS_BLAS + +// #include "mtl/mtl_config.h" + +#if 0 +#include "mtl/mtl_complex.h" +using std::complex; +#endif + +/*-------------------------------------------------------- + Basic Linear Algebra Subprograms for C/C++ + Version 1.0 + Matthew E. Gaston + May 6, 1998 +----------------------------------------------------------*/ + +#define MTL_BLAS_NAME(name) name##_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------- + Level 1 BLAS +-----------------------------------------------------------*/ + +/* +// Dot product functions +*/ +float MTL_BLAS_NAME(sdot)(int*, float*, int*, float*, int*); +double MTL_BLAS_NAME(dsdot)(int*, float*, int*, float*, int*); +float MTL_BLAS_NAME(sdsdot)(int*, float*, float*, int*, float*, int*); +double MTL_BLAS_NAME(ddot)(int*, double*, int*, double*, int*); + +/* + AXPY +*/ +void MTL_BLAS_NAME(saxpy)(int*, float*, float*, int*, float*, int*); +void MTL_BLAS_NAME(daxpy)(int*, double*, double*, int*, double*, int*); + +/* + Copy +*/ +void MTL_BLAS_NAME(scopy)(int*, float*, int*, float*, int*); +void MTL_BLAS_NAME(dcopy)(int*, double*, int*, double*, int*); + +/* + Swap +*/ +void MTL_BLAS_NAME(sswap)(int*, float*, int*, float*, int*); +void MTL_BLAS_NAME(dswap)(int*, double*, int*, double*, int*); + +/* + 2 Norm +*/ +float MTL_BLAS_NAME(snrm2)(int *, float*, int*); +double MTL_BLAS_NAME(dnrm2)(int *, double*, int*); + +/* + Sum of Absolute Values +*/ +float MTL_BLAS_NAME(sasum)(int *, float*, int*); +double MTL_BLAS_NAME(dasum)(int *, double*, int*); + +/* + Scale +*/ +void MTL_BLAS_NAME(sscal)(int*, float*, float*, int*); +void MTL_BLAS_NAME(dscal)(int*, double*, double*, int*); + +/* + Maximum absolute value +*/ +int MTL_BLAS_NAME(isamax)(int *, float*, int*); +int MTL_BLAS_NAME(idamax)(int *, double*, int*); + + +/* + Givens Plane Rotation +*/ +void MTL_BLAS_NAME(srotg)(float*, float*, float*, float*); +void MTL_BLAS_NAME(drotg)(double*, double*, double*, double*); +#if 0 +void MTL_BLAS_NAME(crotg)(complex<float>*,complex<float>*,float*,complex<float>*); +void MTL_BLAS_NAME(zrotg)(complex<double>*,complex<double>*,double*,complex<double>*); +#endif +void MTL_BLAS_NAME(srot)(int*, float*, int*, float*, int*, float*, float*); +void MTL_BLAS_NAME(drot)(int*, double*, int*, double*, int*, double*, double*); +#if 0 +/* MTL implements ccrot and zzrot */ +void MTL_BLAS_NAME(csrot)(int*, complex<float>*, int*, complex<float>*, int*, + complex<float>*, complex<float>*); +void MTL_BLAS_NAME(zdrot)(int*, complex<double>*, int*, complex<double>*, int*, + double*, double*); +#endif + +/*--------------------------------------------------------- + Level 2 BLAS +-----------------------------------------------------------*/ + +void MTL_BLAS_NAME(dgemv)(char*, int*, int*, double*, double*, int*, + double*, int*, double*, double*, int*); + +void MTL_BLAS_NAME(dger)(int*, int*, double*, double*, int*, double*, + int*, double*, int*); + +void MTL_BLAS_NAME(dgbmv)(char*, int*, int*, int*, int*, double*, double*, int*, + double*, int*, double*, double*, int*); + + +void MTL_BLAS_NAME(dtrsv)(char* uplo, char* trans, char* diag, int* n, double *da, + int* lda, double *dx, int* incx); + +/*--------------------------------------------------------- + Level 3 BLAS +-----------------------------------------------------------*/ + +void MTL_BLAS_NAME(sgemm)(const char* transa, const char* transb, + const int* m, const int* n, const int* k, + const float* alpha, const float *da, const int* lda, + const float *db, const int* ldb, const float* dbeta, + float *dc, const int* ldc); + +void MTL_BLAS_NAME(dgemm)(const char* transa, const char* transb, + const int* m, const int* n, const int* k, + const double* alpha, const double *da, const int* lda, + const double *db, const int* ldb, const double* dbeta, + double *dc, const int* ldc); + +void MTL_BLAS_NAME(cgemm)(const char* transa, const char* transb, + const int* m, const int* n, const int* k, + const std::complex<float>* alpha, const std::complex<float> *da, const int* lda, + const std::complex<float> *db, const int* ldb, const std::complex<float>* dbeta, + std::complex<float> *dc, const int* ldc); + +void MTL_BLAS_NAME(zgemm)(const char* transa, const char* transb, + const int* m, const int* n, const int* k, + const std::complex<double>* alpha, const std::complex<double> *da, const int* lda, + const std::complex<double> *db, const int* ldb, const std::complex<double>* dbeta, + std::complex<double> *dc, const int* ldc); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // MTL_HAS_BLAS + +#endif // MTL_BLAS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/interface/lapack.hpp b/install/MTL/include/boost/numeric/mtl/interface/lapack.hpp new file mode 100644 index 00000000..502314f4 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/interface/lapack.hpp @@ -0,0 +1,48 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_LAPACK_INCLUDE +#define MTL_LAPACK_INCLUDE + +#include <complex> + + +#ifdef __cplusplus +extern "C" { +#endif + + + // Cholesky Factorization + void spotrf_(const char* uplo, const int* n, float *a, const int* ld, int* info); + void dpotrf_(const char* uplo, const int* n, double *a, const int* ld, int* info); + void cpotrf_(const char* uplo, const int* n, std::complex<float> *a, const int* ld, int* info); + void zpotrf_(const char* uplo, const int* n, std::complex<double> *a, const int* ld, int* info); + + + + + + + + + + + + + + +#ifdef __cplusplus +} // extern "C" +#endif + + +#endif // MTL_LAPACK_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/interface/umfpack_solve.hpp b/install/MTL/include/boost/numeric/mtl/interface/umfpack_solve.hpp new file mode 100644 index 00000000..984e414e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/interface/umfpack_solve.hpp @@ -0,0 +1,570 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_UMFPACK_SOLVE_INCLUDE +#define MTL_MATRIX_UMFPACK_SOLVE_INCLUDE + +#ifdef MTL_HAS_UMFPACK + +#include <iostream> + + +#include <cassert> +#include <algorithm> +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/make_copy_or_reference.hpp> +#include <boost/numeric/mtl/operation/merge_complex_vector.hpp> +#include <boost/numeric/mtl/operation/split_complex_vector.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +extern "C" { +# include <umfpack.h> +} + +namespace mtl { namespace mat { + + /// Namespace for Umfpack solver + namespace umfpack { + + // conversion for value_type needed if not double or complex<double> (where possible) + template <typename Value> struct value {}; + template<> struct value<long double> { typedef double type; }; + template<> struct value<double> { typedef double type; }; + template<> struct value<float> { typedef double type; }; + template<> struct value<std::complex<long double> > { typedef std::complex<double> type; }; + template<> struct value<std::complex<double> > { typedef std::complex<double> type; }; + template<> struct value<std::complex<float> > { typedef std::complex<double> type; }; + + template <typename Value> struct use_long { static const bool value= sizeof(Value) > sizeof(int); }; + + template <bool Larger> struct index_aux { typedef int type; }; +# ifdef UF_long + template<> struct index_aux<true> { typedef UF_long type; }; +# else + template<> struct index_aux<true> { typedef long type; }; +# endif + + template <typename Value> struct index + : index_aux<use_long<Value>::value> {}; + + template <typename Matrix, typename Value, typename Orientation> + struct matrix_copy {}; + + // If arbitrary compressed matrix -> copy + template <typename Value, typename Parameters, typename Orientation> + struct matrix_copy<compressed2D<Value, Parameters>, Value, Orientation> + { + typedef typename value<Value>::type value_type; + typedef compressed2D<value_type, parameters<col_major> > matrix_type; + typedef compressed2D<Value, Parameters> in_matrix_type; + + matrix_copy(const in_matrix_type& A) : matrix(A) {} + matrix_type matrix; + }; + + struct error : public domain_error + { + error(const char *s, int code) : domain_error(s), code(code) {} + int code; + }; + + inline void check(int res, + const char* +# ifndef MTL_ASSERT_FOR_THROW + s +# endif + ) + { + MTL_THROW_IF(res != UMFPACK_OK, error(s, res)); + } + + /// Class for repeated Umfpack solutions + /** Keeps symbolic and numeric preprocessing. Numeric part can be updated. + Only defined for compressed2D<double> and compressed2D<complex<double> >. **/ + template <typename T> + class solver { + public: + /// Constructor referring to matrix \p A (not changed) and optionally Umfpack's strategy and alloc_init (look for the specializations) + // \ref solver<compressed2D<double, Parameters> > and \ref solver<compressed2D<std::complex<double>, Parameters> >) + explicit solver(const T& A) {} + + /// Update numeric part, for matrices that kept the sparsity and changed the values + void update_numeric() {} + + /// Update symbolic and numeric part + void update() {} + + /// Solve system A*x == b with matrix passed in constructor + /** Please note that the order of b and x is different than in solve() !!! **/ + template <typename VectorX, typename VectorB> + int operator()(VectorX& x, const VectorB& b) const {return 0;} + + /// Solve system A*x == b with matrix passed in constructor + /** Please note that the order of b and x is different than in operator() !!! **/ + template <typename VectorB, typename VectorX> + int operator()(const VectorB& b, VectorX& x) const {return 0;} + }; + + /// Speciatization of solver for \ref mat::compressed2D with double values + template <typename Parameters> + class solver<compressed2D<double, Parameters> > + { + typedef double value_type; + typedef compressed2D<value_type, Parameters> matrix_type; + typedef typename matrix_type::size_type size_type; + typedef typename index<size_type>::type index_type; + + static const bool copy_indices= sizeof(index_type) != sizeof(size_type), + long_indices= use_long<size_type>::value; + typedef boost::mpl::bool_<long_indices> blong; + typedef boost::mpl::true_ true_; + typedef boost::mpl::false_ false_; + + // typedef parameters<col_major> Parameters; + + void assign_pointers() + { + if (copy_indices) { + if (Apc == 0) Apc= new index_type[n + 1]; + if (my_nnz != A.nnz() && Aic) { delete[] Aic; Aic= 0; } + if (Aic == 0) Aic= new index_type[A.nnz()]; + std::copy(A.address_major(), A.address_major() + n + 1, Apc); + std::copy(A.address_minor(), A.address_minor() + A.nnz(), Aic); + Ap= Apc; + Ai= Aic; + } else { + Ap= reinterpret_cast<const index_type*>(A.address_major()); + Ai= reinterpret_cast<const index_type*>(A.address_minor()); + } + Ax= A.address_data(); + } + + void init_aux(true_) + { + check(umfpack_dl_symbolic(n, n, Ap, Ai, Ax, &Symbolic, Control, Info), "Error in dl_symbolic"); + check(umfpack_dl_numeric(Ap, Ai, Ax, Symbolic, &Numeric, Control, Info), "Error in dl_numeric"); + } + + void init_aux(false_) + { + check(umfpack_di_symbolic(n, n, Ap, Ai, Ax, &Symbolic, Control, Info), "Error in di_symbolic"); +#if 0 + std::cout << "=== INFO of umfpack_*_symbolic ===\n"; + std::cout << " UMFPACK_STATUS: " << (Info[UMFPACK_STATUS] == UMFPACK_OK ? "OK" : "ERROR") << "\n"; + std::cout << " UMFPACK_NROW: " << Info[UMFPACK_NROW] << "\n"; + std::cout << " UMFPACK_NCOL: " << Info[UMFPACK_NCOL] << "\n"; + std::cout << " UMFPACK_NZ: " << Info[UMFPACK_NZ] << "\n"; + std::cout << " UMFPACK_SIZE_OF_UNIT: " << Info[UMFPACK_SIZE_OF_UNIT] << "\n"; + std::cout << " UMFPACK_NDENSE_ROW: " << Info[UMFPACK_NDENSE_ROW] << "\n"; + std::cout << " UMFPACK_NEMPTY_ROW: " << Info[UMFPACK_NEMPTY_ROW] << "\n"; + std::cout << " UMFPACK_NDENSE_COL: " << Info[UMFPACK_NDENSE_COL] << "\n"; + std::cout << " UMFPACK_NEMPTY_COL: " << Info[UMFPACK_NEMPTY_COL] << "\n"; + std::cout << " UMFPACK_SYMBOLIC_DEFRAG: " << Info[UMFPACK_SYMBOLIC_DEFRAG] << "\n"; + std::cout << " UMFPACK_SYMBOLIC_PEAK_MEMORY: " << Info[UMFPACK_SYMBOLIC_PEAK_MEMORY] << "\n"; + std::cout << " UMFPACK_SYMBOLIC_SIZE: " << Info[UMFPACK_SYMBOLIC_SIZE] << "\n"; + std::cout << " UMFPACK_VARIABLE_PEAK_ESTIMATE: " << Info[UMFPACK_VARIABLE_PEAK_ESTIMATE] << "\n"; + std::cout << " UMFPACK_NUMERIC_SIZE_ESTIMATE: " << Info[UMFPACK_NUMERIC_SIZE_ESTIMATE] << "\n"; + std::cout << " UMFPACK_PEAK_MEMORY_ESTIMATE: " << Info[UMFPACK_PEAK_MEMORY_ESTIMATE] << "\n"; + std::cout << " UMFPACK_FLOPS_ESTIMATE: " << Info[UMFPACK_FLOPS_ESTIMATE] << "\n"; + std::cout << " UMFPACK_LNZ_ESTIMATE: " << Info[UMFPACK_LNZ_ESTIMATE] << "\n"; + std::cout << " UMFPACK_UNZ_ESTIMATE: " << Info[UMFPACK_UNZ_ESTIMATE] << "\n"; + std::cout << " UMFPACK_MAX_FRONT_SIZE_ESTIMATE: " << Info[UMFPACK_MAX_FRONT_SIZE_ESTIMATE] << "\n"; + std::cout << " UMFPACK_SYMBOLIC_TIME: " << Info[UMFPACK_SYMBOLIC_TIME] << "\n"; + std::cout << " UMFPACK_SYMBOLIC_WALLTIME: " << Info[UMFPACK_SYMBOLIC_WALLTIME] << "\n"; + + if (Info[UMFPACK_STRATEGY_USED] == UMFPACK_STRATEGY_SYMMETRIC) + std::cout << " UMFPACK_STRATEGY_USED: SYMMETRIC\n"; + else { + if(Info[UMFPACK_STRATEGY_USED] == UMFPACK_STRATEGY_UNSYMMETRIC) + std::cout << " UMFPACK_STRATEGY_USED: UNSYMMETRIC\n"; + else { + if (Info[UMFPACK_STRATEGY_USED] == UMFPACK_STRATEGY_2BY2) + std::cout << " UMFPACK_STRATEGY_USED: 2BY2\n"; + else + std::cout << " UMFPACK_STRATEGY_USED: UNKOWN STRATEGY " << Info[UMFPACK_STRATEGY_USED] << "\n"; + } + } + + std::cout << " UMFPACK_ORDERING_USED: " << Info[UMFPACK_ORDERING_USED] << "\n"; + std::cout << " UMFPACK_QFIXED: " << Info[UMFPACK_QFIXED] << "\n"; + std::cout << " UMFPACK_DIAG_PREFERRED: " << Info[UMFPACK_DIAG_PREFERRED] << "\n"; + std::cout << " UMFPACK_ROW_SINGLETONS: " << Info[UMFPACK_ROW_SINGLETONS] << "\n"; + std::cout << " UMFPACK_COL_SINGLETONS: " << Info[UMFPACK_COL_SINGLETONS] << "\n"; + std::cout << " UMFPACK_PATTERN_SYMMETRY: " << Info[UMFPACK_PATTERN_SYMMETRY] << "\n"; + std::cout << " UMFPACK_NZ_A_PLUS_AT: " << Info[UMFPACK_NZ_A_PLUS_AT] << "\n"; + std::cout << " UMFPACK_NZDIAG: " << Info[UMFPACK_NZDIAG] << "\n"; + std::cout << " UMFPACK_N2: " << Info[UMFPACK_N2] << "\n"; + std::cout << " UMFPACK_S_SYMMETRIC: " << Info[UMFPACK_S_SYMMETRIC] << "\n"; + std::cout << " UMFPACK_MAX_FRONT_NROWS_ESTIMATE: " << Info[UMFPACK_MAX_FRONT_NROWS_ESTIMATE] << "\n"; + std::cout << " UMFPACK_MAX_FRONT_NCOLS_ESTIMATE: " << Info[UMFPACK_MAX_FRONT_NCOLS_ESTIMATE] << "\n"; + std::cout << " UMFPACK_SYMMETRIC_LUNZ: " << Info[UMFPACK_SYMMETRIC_LUNZ] << "\n"; + std::cout << " UMFPACK_SYMMETRIC_FLOPS: " << Info[UMFPACK_SYMMETRIC_FLOPS] << "\n"; + std::cout << " UMFPACK_SYMMETRIC_NDENSE: " << Info[UMFPACK_SYMMETRIC_NDENSE] << "\n"; + std::cout << " UMFPACK_SYMMETRIC_DMAX: " << Info[UMFPACK_SYMMETRIC_DMAX] << "\n"; +#endif + + check(umfpack_di_numeric(Ap, Ai, Ax, Symbolic, &Numeric, Control, Info), "Error in di_numeric"); + +#if 0 + std::cout << "=== INFO of umfpack_*_numeric ===\n"; + std::cout << " UMFPACK_STATUS: " << (Info[UMFPACK_STATUS] == UMFPACK_OK ? "OK" : "ERROR") << "\n"; + std::cout << " UMFPACK_VARIABLE_PEAK: " << Info[UMFPACK_VARIABLE_PEAK] << "\n"; + std::cout << " UMFPACK_PEAK_MEMORY: " << Info[UMFPACK_PEAK_MEMORY] << "\n"; + std::cout << " UMFPACK_FLOPS: " << Info[UMFPACK_FLOPS] << "\n"; + std::cout << " UMFPACK_LNZ: " << Info[UMFPACK_LNZ] << "\n"; + std::cout << " UMFPACK_UNZ: " << Info[UMFPACK_UNZ] << "\n"; + std::cout << " UMFPACK_NUMERIC_DEFRAG: " << Info[UMFPACK_NUMERIC_DEFRAG] << "\n"; + std::cout << " UMFPACK_NUMERIC_REALLOC: " << Info[UMFPACK_NUMERIC_REALLOC] << "\n"; + std::cout << " UMFPACK_NUMERIC_COSTLY_REALLOC: " << Info[UMFPACK_NUMERIC_COSTLY_REALLOC] << "\n"; + std::cout << " UMFPACK_COMPRESSED_PATTERN: " << Info[UMFPACK_COMPRESSED_PATTERN] << "\n"; + std::cout << " UMFPACK_LU_ENTRIES: " << Info[UMFPACK_LU_ENTRIES] << "\n"; + std::cout << " UMFPACK_NUMERIC_TIME: " << Info[UMFPACK_NUMERIC_TIME] << "\n"; + std::cout << " UMFPACK_RCOND: " << Info[UMFPACK_RCOND] << "\n"; + std::cout << " UMFPACK_UDIAG_NZ: " << Info[UMFPACK_UDIAG_NZ] << "\n"; + std::cout << " UMFPACK_UMIN: " << Info[UMFPACK_UMIN] << "\n"; + std::cout << " UMFPACK_UMAX: " << Info[UMFPACK_UMAX] << "\n"; + std::cout << " UMFPACK_MAX_FRONT_NROWS: " << Info[UMFPACK_MAX_FRONT_NROWS] << "\n"; + std::cout << " UMFPACK_MAX_FRONT_NCOLS: " << Info[UMFPACK_MAX_FRONT_NCOLS] << "\n"; + std::cout << " UMFPACK_ALL_LNZ: " << Info[UMFPACK_ALL_LNZ] << "\n"; + std::cout << " UMFPACK_ALL_UNZ: " << Info[UMFPACK_ALL_UNZ] << "\n"; +#endif + } + + void init() + { + MTL_THROW_IF(num_rows(A) != num_cols(A), matrix_not_square()); + n= num_rows(A); + assign_pointers(); + init_aux(blong()); + } + + + + public: + /// Constructor referring to matrix \p A (not changed) and optionally Umfpack's strategy and alloc_init + solver(const matrix_type& A, int strategy = UMFPACK_STRATEGY_AUTO, double alloc_init = 0.7) + : A(A), Apc(0), Aic(0), my_nnz(0), Symbolic(0), Numeric(0) + { + vampir_trace<5060> trace; + // Use default setings. + if (long_indices) + umfpack_dl_defaults(Control); + else + umfpack_di_defaults(Control); + + Control[UMFPACK_STRATEGY] = strategy; + Control[UMFPACK_ALLOC_INIT] = alloc_init; + init(); + } + + ~solver() + { + vampir_trace<5061> trace; + if (long_indices) { + umfpack_dl_free_numeric(&Numeric); + umfpack_dl_free_symbolic(&Symbolic); + } else { + umfpack_di_free_numeric(&Numeric); + umfpack_di_free_symbolic(&Symbolic); + } + if (Apc) delete[] Apc; + if (Aic) delete[] Aic; + } + + void update_numeric_aux(true_) + { + umfpack_dl_free_numeric(&Numeric); + check(umfpack_dl_numeric(Ap, Ai, Ax, Symbolic, &Numeric, Control, Info), "Error in dl_numeric"); + } + + void update_numeric_aux(false_) + { + umfpack_di_free_numeric(&Numeric); + check(umfpack_di_numeric(Ap, Ai, Ax, Symbolic, &Numeric, Control, Info), "Error in di_numeric"); + } + + /// Update numeric part, for matrices that kept the sparsity and changed the values + void update_numeric() + { + assign_pointers(); + update_numeric_aux(blong()); + } + + /// Update symbolic and numeric part + void update() + { + if (long_indices) { + umfpack_dl_free_numeric(&Numeric); + umfpack_dl_free_symbolic(&Symbolic); + } else { + umfpack_di_free_numeric(&Numeric); + umfpack_di_free_symbolic(&Symbolic); + } + init(); + } + + template <typename VectorX, typename VectorB> + void solve_aux(int sys, VectorX& xx, const VectorB& bb, true_) + { + check(umfpack_dl_solve(sys, Ap, Ai, Ax, &xx.value[0], &bb.value[0], Numeric, Control, Info), "Error in dl_solve"); + } + + template <typename VectorX, typename VectorB> + void solve_aux(int sys, VectorX& xx, const VectorB& bb, false_) + { + check(umfpack_di_solve(sys, Ap, Ai, Ax, &xx.value[0], &bb.value[0], Numeric, Control, Info), "Error in di_solve"); + } + + /// Solve double system + template <typename VectorX, typename VectorB> + int operator()(VectorX& x, const VectorB& b) + { + vampir_trace<5062> trace; + MTL_THROW_IF(num_rows(A) != size(x) || num_rows(A) != size(b), incompatible_size()); + make_in_out_copy_or_reference<dense_vector<value_type>, VectorX> xx(x); + make_in_copy_or_reference<dense_vector<value_type>, VectorB> bb(b); + int sys= mtl::traits::is_row_major<Parameters>::value ? UMFPACK_At : UMFPACK_A; + solve_aux(sys, xx, bb, blong()); + return UMFPACK_OK; + } + + /// Solve double system + template <typename VectorB, typename VectorX> + int solve(const VectorB& b, VectorX& x) const + { + // return (*this)(x, b); + return const_cast<solver&>(*this)(x, b); // evil hack because Umfpack has no const + } + + private: + const matrix_type& A; + int n; + const index_type *Ap, *Ai; + index_type *Apc, *Aic; + size_type my_nnz; + const double *Ax; + double Control[UMFPACK_CONTROL], Info[UMFPACK_INFO]; + void *Symbolic, *Numeric; + }; + + /// Speciatization of solver for \ref mat::compressed2D with double values + template <typename Parameters> + class solver<compressed2D<std::complex<double>, Parameters> > + { + typedef std::complex<double> value_type; + typedef compressed2D<value_type, Parameters> matrix_type; + typedef typename matrix_type::size_type size_type; + typedef typename index<size_type>::type index_type; + + static const bool copy_indices= sizeof(index_type) != sizeof(size_type), + long_indices= use_long<size_type>::value; + + typedef boost::mpl::bool_<long_indices> blong; + typedef boost::mpl::true_ true_; + typedef boost::mpl::false_ false_; + + + void assign_pointers() + { + if (copy_indices) { + if (Apc == 0) Apc= new index_type[n + 1]; + if (Aic == 0) Aic= new index_type[A.nnz()]; + std::copy(A.address_major(), A.address_major() + n + 1, Apc); + std::copy(A.address_minor(), A.address_minor() + A.nnz(), Aic); + Ap= Apc; + Ai= Aic; + } else { + Ap= reinterpret_cast<const index_type*>(A.address_major()); + Ai= reinterpret_cast<const index_type*>(A.address_minor()); + } + split_complex_vector(A.data, Ax, Az); + } + + void init_aux(true_) + { + check(umfpack_zl_symbolic(n, n, Ap, Ai, &Ax[0], &Az[0], &Symbolic, Control, Info), "Error in zl_symbolic"); + check(umfpack_zl_numeric(Ap, Ai, &Ax[0], &Az[0], Symbolic, &Numeric, Control, Info), "Error in zl_numeric"); + } + + void init_aux(false_) + { + check(umfpack_zi_symbolic(n, n, Ap, Ai, &Ax[0], &Az[0], &Symbolic, Control, Info), "Error in zi_symbolic"); + check(umfpack_zi_numeric(Ap, Ai, &Ax[0], &Az[0], Symbolic, &Numeric, Control, Info), "Error in zi_numeric"); + } + + void initialize() + { + MTL_THROW_IF(num_rows(A) != num_cols(A), matrix_not_square()); + n= num_rows(A); + assign_pointers(); + init_aux(blong()); + } + public: + /// Constructor referring to matrix \p A (not changed) and optionally Umfpack's strategy and alloc_init (look for the specializations) + explicit solver(const compressed2D<value_type, Parameters>& A, int strategy = UMFPACK_STRATEGY_AUTO, double alloc_init = 0.7) + : A(A), Apc(0), Aic(0) + { + vampir_trace<5060> trace; + // Use default setings. + if (long_indices) + umfpack_zl_defaults(Control); + else + umfpack_zi_defaults(Control); + // umfpack_zi_defaults(Control); + + Control[UMFPACK_STRATEGY] = strategy; + Control[UMFPACK_ALLOC_INIT] = alloc_init; + initialize(); + } + + ~solver() + { + vampir_trace<5061> trace; + if (long_indices) { + umfpack_zl_free_numeric(&Numeric); + umfpack_zl_free_symbolic(&Symbolic); + } else { + umfpack_zi_free_numeric(&Numeric); + umfpack_zi_free_symbolic(&Symbolic); + } + if (Apc) delete[] Apc; + if (Aic) delete[] Aic; + } + + void update_numeric_aux(true_) + { + umfpack_zl_free_numeric(&Numeric); + check(umfpack_zl_numeric(Ap, Ai, &Ax[0], &Az[0], Symbolic, &Numeric, Control, Info), "Error in dl_numeric D"); + } + + void update_numeric_aux(false_) + { + umfpack_zi_free_numeric(&Numeric); + check(umfpack_zi_numeric(Ap, Ai, &Ax[0], &Az[0], Symbolic, &Numeric, Control, Info), "Error in di_numeric"); + } + + /// Update numeric part, for matrices that kept the sparsity and changed the values + void update_numeric() + { + assign_pointers(); + update_numeric_aux(blong()); + } + + /// Update symbolic and numeric part + void update() + { + Ax.change_dim(0); Az.change_dim(0); + if (long_indices) { + umfpack_zl_free_numeric(&Numeric); + umfpack_zl_free_symbolic(&Symbolic); + } else { + umfpack_zi_free_numeric(&Numeric); + umfpack_zi_free_symbolic(&Symbolic); + } + initialize(); + } + + template <typename VectorX, typename VectorB> + void solve_aux(int sys, VectorX& Xx, VectorX& Xz, const VectorB& Bx, const VectorB& Bz, true_) + { + check(umfpack_zl_solve(sys, Ap, Ai, &Ax[0], &Az[0], &Xx[0], &Xz[0], &Bx[0], &Bz[0], Numeric, Control, Info), + "Error in zi_solve"); + } + + template <typename VectorX, typename VectorB> + void solve_aux(int sys, VectorX& Xx, VectorX& Xz, const VectorB& Bx, const VectorB& Bz, false_) + { + check(umfpack_zi_solve(sys, Ap, Ai, &Ax[0], &Az[0], &Xx[0], &Xz[0], &Bx[0], &Bz[0], Numeric, Control, Info), + "Error in zi_solve"); + } + + /// Solve complex system + template <typename VectorX, typename VectorB> + int operator()(VectorX& x, const VectorB& b) + { + vampir_trace<5062> trace; + MTL_THROW_IF(num_rows(A) != size(x) || num_rows(A) != size(b), incompatible_size()); + dense_vector<double> Xx(size(x)), Xz(size(x)), Bx, Bz; + split_complex_vector(b, Bx, Bz); + int sys= mtl::traits::is_row_major<Parameters>::value ? UMFPACK_Aat : UMFPACK_A; + solve_aux(sys, Xx, Xz, Bx, Bz, blong()); + merge_complex_vector(Xx, Xz, x); + return UMFPACK_OK; + } + + /// Solve complex system + template <typename VectorB, typename VectorX> + int solve(const VectorB& b, VectorX& x) + { + return (*this)(x, b); + } + + private: + const matrix_type& A; + int n; + const index_type *Ap, *Ai; + index_type *Apc, *Aic; + dense_vector<double> Ax, Az; + double Control[UMFPACK_CONTROL], Info[UMFPACK_INFO]; + void *Symbolic, *Numeric; + }; + + template <typename Value, typename Parameters> + class solver<compressed2D<Value, Parameters> > + : matrix_copy<compressed2D<Value, Parameters>, Value, typename Parameters::orientation>, + public solver<typename matrix_copy<compressed2D<Value, Parameters>, Value, typename Parameters::orientation>::matrix_type > + { + typedef matrix_copy<compressed2D<Value, Parameters>, Value, typename Parameters::orientation> copy_type; + typedef solver<typename matrix_copy<compressed2D<Value, Parameters>, Value, typename Parameters::orientation>::matrix_type > solver_type; + public: + explicit solver(const compressed2D<Value, Parameters>& A) + : copy_type(A), solver_type(copy_type::matrix), A(A) + {} + + void update() + { + copy_type::matrix= A; + solver_type::update(); + } + + void update_numeric() + { + copy_type::matrix= A; + solver_type::update_numeric(); + } + private: + const compressed2D<Value, Parameters>& A; + }; + } // umfpack + +/// Solve A*x == b with umfpack +/** Only available when compiled with enabled macro MTL_HAS_UMFPACK. + Uses classes umfpack::solver internally. + If you want more control on single operations or to keep umfpack's + internal factorization, use this class. + **/ +template <typename Value, typename Parameters, typename VectorX, typename VectorB> +int umfpack_solve(const compressed2D<Value, Parameters>& A, VectorX& x, const VectorB& b) +{ + umfpack::solver<compressed2D<Value, Parameters> > solver(A); + return solver(x, b); +} + +}} // namespace mtl::mat + +#endif + +#endif // MTL_MATRIX_UMFPACK_SOLVE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/interface/vpt.cpp b/install/MTL/include/boost/numeric/mtl/interface/vpt.cpp new file mode 100644 index 00000000..de9bf722 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/interface/vpt.cpp @@ -0,0 +1,443 @@ +#include <boost/numeric/mtl/interface/vpt.hpp> + +#ifdef MTL_HAS_VPT +namespace mtl { + +/// Namespace for Vampir Trace interface +namespace vpt { + +// Categories: +// Utilities + very small functions: 0000 +// Static size operations: 1000 +// Vector operations: 2000 +// Matrix Vector & single matrix: 3000 +// Matrix matrix operations: 4000 +// Factorizations, preconditioners: 5000 +// Fused operations: 6000 +// Iterative solvers: 7000 +// Multigrid: 8000 + + +// Utilities: < 1000 +template <> std::string vampir_trace<1>::name("copysign"); +template <> std::string vampir_trace<2>::name("Elem_raw_copy"); +template <> std::string vampir_trace<3>::name("Get_real_part"); +template <> std::string vampir_trace<4>::name("Info_contruct_vector"); +template <> std::string vampir_trace<5>::name("right_scale_inplace"); +template <> std::string vampir_trace<6>::name("sign_real_part_of_complex"); +template <> std::string vampir_trace<7>::name("unrolling_expresion"); +template <> std::string vampir_trace<8>::name(""); +template <> std::string vampir_trace<9>::name(""); +template <> std::string vampir_trace<10>::name("squared_abs_magnitudes"); +template <> std::string vampir_trace<11>::name("squared_abs_complex"); +template <> std::string vampir_trace<12>::name("squared_abs_magnitudes_template"); +template <> std::string vampir_trace<13>::name("update_store"); +template <> std::string vampir_trace<14>::name("update_plus"); +template <> std::string vampir_trace<15>::name("update_minus"); +template <> std::string vampir_trace<16>::name("update_times"); +template <> std::string vampir_trace<17>::name("update_adapter"); +template <> std::string vampir_trace<18>::name(""); +template <> std::string vampir_trace<19>::name(""); +template <> std::string vampir_trace<20>::name("update_proxy_<<"); +template <> std::string vampir_trace<21>::name("update_proxy_="); +template <> std::string vampir_trace<22>::name("update_proxy_+="); +template <> std::string vampir_trace<23>::name("sfunctor::plus"); +template <> std::string vampir_trace<24>::name("sfunctor::minus"); +template <> std::string vampir_trace<25>::name("sfunctor::times"); +template <> std::string vampir_trace<26>::name("sfunctor::divide"); +template <> std::string vampir_trace<27>::name("sfunctor::assign"); +template <> std::string vampir_trace<28>::name("sfunctor::plus_assign"); +template <> std::string vampir_trace<29>::name("sfunctor::minus_assign"); +template <> std::string vampir_trace<30>::name("sfunctor::times_assign"); +template <> std::string vampir_trace<31>::name("sfunctor::divide_assign"); +template <> std::string vampir_trace<32>::name("sfunctor::identity"); +template <> std::string vampir_trace<33>::name("sfunctor::abs"); +template <> std::string vampir_trace<34>::name("sfunctor::sqrt"); +template <> std::string vampir_trace<35>::name("sfunctor::square"); +template <> std::string vampir_trace<36>::name("sfunctor::negate"); +template <> std::string vampir_trace<37>::name("sfunctor::compose"); +template <> std::string vampir_trace<38>::name("sfunctor::compose_first"); +template <> std::string vampir_trace<39>::name("sfunctor::compose_second"); +template <> std::string vampir_trace<40>::name("sfunctor::compose_both"); +template <> std::string vampir_trace<41>::name("sfunctor::compose_binary"); +template <> std::string vampir_trace<42>::name(""); +template <> std::string vampir_trace<43>::name(""); +template <> std::string vampir_trace<44>::name(""); +template <> std::string vampir_trace<45>::name(""); + +// Fine-grained vector operations +template <> std::string vampir_trace<236>::name("Vector_swapped_row"); + + +// Static size operations: 1000 +template <> std::string vampir_trace<1001>::name("stat_vec_expr"); +template <> std::string vampir_trace<1002>::name("fsize_dmat_dmat_mult"); +template <> std::string vampir_trace<1003>::name("vector_size_static"); +template <> std::string vampir_trace<1004>::name("static_dispatch"); // ?? row_in_matrix.hpp:74 +template <> std::string vampir_trace<1005>::name("copy_blocks_forward"); +template <> std::string vampir_trace<1006>::name("copy_blocks_backward"); +template <> std::string vampir_trace<1007>::name("Static_Size"); +template <> std::string vampir_trace<1008>::name("fsize_mat_vect_mult"); +template <> std::string vampir_trace<1009>::name(""); +template <> std::string vampir_trace<1010>::name(""); +template <> std::string vampir_trace<1011>::name(""); +template <> std::string vampir_trace<1012>::name(""); +template <> std::string vampir_trace<1013>::name(""); +template <> std::string vampir_trace<1014>::name(""); +template <> std::string vampir_trace<1015>::name(""); +template <> std::string vampir_trace<1016>::name(""); +template <> std::string vampir_trace<1017>::name(""); +template <> std::string vampir_trace<1018>::name(""); +template <> std::string vampir_trace<1019>::name(""); +template <> std::string vampir_trace<1020>::name(""); + + + + + +// Vector operations: 2000 +template <> std::string vampir_trace<2001>::name("gen_vector_copy"); +template <> std::string vampir_trace<2002>::name("cross"); +template <> std::string vampir_trace<2003>::name("dot"); +template <> std::string vampir_trace<2004>::name("householder"); +template <> std::string vampir_trace<2005>::name("householder_s"); +template <> std::string vampir_trace<2006>::name("infinity_norm"); +template <> std::string vampir_trace<2007>::name("look_at_each_nonzero"); +template <> std::string vampir_trace<2008>::name("look_at_each_nonzero_pos"); +template <> std::string vampir_trace<2009>::name("reduction"); +template <> std::string vampir_trace<2010>::name("max"); +template <> std::string vampir_trace<2011>::name("max_abs_pos"); +template <> std::string vampir_trace<2012>::name("max_of_sums"); +template <> std::string vampir_trace<2013>::name("max_pos"); +template <> std::string vampir_trace<2014>::name("merge_complex_vector"); +template <> std::string vampir_trace<2015>::name("one_norm"); +template <> std::string vampir_trace<2016>::name("diagonal"); +template <> std::string vampir_trace<2017>::name("dyn_vec_expr"); +template <> std::string vampir_trace<2018>::name("Orthogonalize_Vectors"); +template <> std::string vampir_trace<2019>::name("Orthogonalize_Factors"); +template <> std::string vampir_trace<2020>::name("Vector_product"); +template <> std::string vampir_trace<2021>::name("Vector_random"); +template <> std::string vampir_trace<2022>::name("Vec_Vec_rank_update"); +template <> std::string vampir_trace<2023>::name("Vector_dispatch"); +template <> std::string vampir_trace<2024>::name("Vector_rscale"); +template <> std::string vampir_trace<2025>::name("Multi-vector_mult"); +template <> std::string vampir_trace<2026>::name("Transp_Multi-vector_mult"); +template <> std::string vampir_trace<2027>::name("Hermitian_Multi-vector_mult"); +template <> std::string vampir_trace<2028>::name("Vector_scal"); +template <> std::string vampir_trace<2029>::name("Vector_set_zero"); +template <> std::string vampir_trace<2030>::name("Vector_size1D"); +template <> std::string vampir_trace<2031>::name("Vector_size_runtime"); +template <> std::string vampir_trace<2032>::name("Vect_quicksort_lo_to_hi"); +template <> std::string vampir_trace<2033>::name("Vect_quicksort_permutaion_lo_to_hi"); +template <> std::string vampir_trace<2034>::name("split_complex_vector"); +template <> std::string vampir_trace<2035>::name("Vect_entries_sum"); +template <> std::string vampir_trace<2037>::name("Vector_const_trans"); +template <> std::string vampir_trace<2038>::name("Vector_trans"); +template <> std::string vampir_trace<2039>::name("two_norm"); +template <> std::string vampir_trace<2040>::name("dot_simple"); +template <> std::string vampir_trace<2041>::name("unary_dot"); +template <> std::string vampir_trace<2042>::name("dense_copy_ctor"); +template <> std::string vampir_trace<2043>::name("dense_tpl_copy_ctor"); +template <> std::string vampir_trace<2044>::name(""); +template <> std::string vampir_trace<2045>::name(""); +template <> std::string vampir_trace<2046>::name(""); +template <> std::string vampir_trace<2047>::name(""); +template <> std::string vampir_trace<2048>::name(""); +template <> std::string vampir_trace<2049>::name(""); +template <> std::string vampir_trace<2050>::name(""); +template <> std::string vampir_trace<2051>::name(""); +template <> std::string vampir_trace<2052>::name(""); + + +// Matrix Vector & single matrix: 3000 +template <> std::string vampir_trace<3001>::name("matrix_copy_ele_times"); +template <> std::string vampir_trace<3002>::name("gen_matrix_copy"); +template <> std::string vampir_trace<3003>::name("copy"); +template <> std::string vampir_trace<3004>::name("clone"); +template <> std::string vampir_trace<3005>::name("compute_summand"); +template <> std::string vampir_trace<3006>::name("crop"); +template <> std::string vampir_trace<3007>::name("mat::diagonal"); +template <> std::string vampir_trace<3008>::name("assign_each_nonzero"); +template <> std::string vampir_trace<3009>::name("fill"); +template <> std::string vampir_trace<3010>::name("frobenius_norm"); +template <> std::string vampir_trace<3011>::name("mat::infinity_norm"); +template <> std::string vampir_trace<3012>::name("invert_diagonal"); +template <> std::string vampir_trace<3013>::name("iota"); +template <> std::string vampir_trace<3014>::name("left_scale_inplace"); +template <> std::string vampir_trace<3015>::name("mat::look_at_each_nonzero"); +template <> std::string vampir_trace<3016>::name("mat::look_at_each_nonzero_pos"); +template <> std::string vampir_trace<3017>::name("fsize_dense_mat_cvec_mult"); +template <> std::string vampir_trace<3018>::name("dense_mat_cvec_mult"); +template <> std::string vampir_trace<3019>::name("mvec_cvec_mult"); +template <> std::string vampir_trace<3020>::name("trans_mvec_cvec_mult"); +template <> std::string vampir_trace<3021>::name("herm_mvec_cvec_mult"); +template <> std::string vampir_trace<3022>::name("sparse_row_cvec_mult"); // generic row-major sparse +template <> std::string vampir_trace<3023>::name("ccs_cvec_mult"); +template <> std::string vampir_trace<3024>::name("mat::max_abs_pos"); +template <> std::string vampir_trace<3025>::name("mat::one_norm"); +template <> std::string vampir_trace<3026>::name("invert_diagonal(compressed)"); +template <> std::string vampir_trace<3027>::name("mat_vect_mult"); +template <> std::string vampir_trace<3028>::name("Vect_sparse_mat_mult"); +template <> std::string vampir_trace<3029>::name("Matrix_scal"); +template <> std::string vampir_trace<3030>::name("Vector_Secular_Equation"); +template <> std::string vampir_trace<3031>::name("Matrix_set_zero"); +template <> std::string vampir_trace<3032>::name("Matrix_size1D"); +template <> std::string vampir_trace<3033>::name("Matrix_size_runtime"); +template <> std::string vampir_trace<3034>::name("Matrix_LU"); +template <> std::string vampir_trace<3035>::name("Vector_Matrix_LU"); +template <> std::string vampir_trace<3036>::name("Sub_matrix_indices"); +template <> std::string vampir_trace<3037>::name("Matrix_svd_reference"); +template <> std::string vampir_trace<3038>::name("Matrix_svd_triplet"); +template <> std::string vampir_trace<3039>::name("Matrix_swapped"); +template <> std::string vampir_trace<3040>::name("Matrix_Trace"); +template <> std::string vampir_trace<3041>::name("Matrix_const_trans"); +template <> std::string vampir_trace<3042>::name("Matrix_trans"); +template <> std::string vampir_trace<3043>::name("Matrix_upper_trisolve"); +template <> std::string vampir_trace<3044>::name("Matrix_upper_trisolve_diagonal"); +template <> std::string vampir_trace<3045>::name("Matrix_upper_trisolve_invers_diag"); +template <> std::string vampir_trace<3046>::name("Matrix_upper_trisolve_DiaTag"); +template <> std::string vampir_trace<3047>::name("scalar_assign"); +template <> std::string vampir_trace<3048>::name("elest_cvec_mult"); +template <> std::string vampir_trace<3049>::name("crs_cvec_mult"); +template <> std::string vampir_trace<3050>::name("sparse_ins::ctor"); +template <> std::string vampir_trace<3051>::name("sparse_ins::dtor"); +template <> std::string vampir_trace<3052>::name("sparse_ins::stretch"); +template <> std::string vampir_trace<3053>::name("sparse_ins::final_place"); +template <> std::string vampir_trace<3054>::name("sparse_ins::insert_spare"); +template <> std::string vampir_trace<3055>::name("mat_crtp_scal_assign"); +template <> std::string vampir_trace<3056>::name("mat_crtp_mat_assign"); +template <> std::string vampir_trace<3057>::name("mat_crtp_sum_assign"); +template <> std::string vampir_trace<3058>::name("mat_crtp_diff_assign"); +template <> std::string vampir_trace<3059>::name("mat_crtp_array_assign"); +template <> std::string vampir_trace<3060>::name("mat_crtp_mvec_assign"); +template <> std::string vampir_trace<3061>::name("copy_band_to_sparse"); +template <> std::string vampir_trace<3062>::name("block_dia_times_cvec"); +template <> std::string vampir_trace<3063>::name("laplacian_setup"); +template <> std::string vampir_trace<3064>::name("vsmat_cvec_mult"); +template <> std::string vampir_trace<3065>::name("adapt_crs_cvec_mult"); +template <> std::string vampir_trace<3066>::name("dense2D_cvec_mult"); +template <> std::string vampir_trace<3067>::name("square_cvec_mult"); +template <> std::string vampir_trace<3068>::name("mat_crtp_mult_assign"); +template <> std::string vampir_trace<3069>::name("sbanded_cvec_mult"); +template <> std::string vampir_trace<3070>::name("mat_cvec_multiplier"); +template <> std::string vampir_trace<3071>::name(""); +template <> std::string vampir_trace<3072>::name(""); +template <> std::string vampir_trace<3073>::name(""); +template <> std::string vampir_trace<3074>::name(""); +template <> std::string vampir_trace<3075>::name(""); +template <> std::string vampir_trace<3076>::name(""); +template <> std::string vampir_trace<3077>::name(""); +template <> std::string vampir_trace<3078>::name(""); +template <> std::string vampir_trace<3079>::name(""); + + +// Matrix matrix operations: 4000 +template <> std::string vampir_trace<4001>::name("cursor_dmat_dmat_mult"); +template <> std::string vampir_trace<4002>::name("dmat_dmat_mult"); +template <> std::string vampir_trace<4003>::name("tiling_dmat_dmat_mult"); +template <> std::string vampir_trace<4004>::name("tiling_44_dmat_dmat_mult"); +template <> std::string vampir_trace<4005>::name("tiling_22_dmat_dmat_mult"); +template <> std::string vampir_trace<4006>::name("wrec_dmat_dmat_mult"); +template <> std::string vampir_trace<4007>::name("recursive_dmat_dmat_mult"); +template <> std::string vampir_trace<4008>::name("xgemm"); +template <> std::string vampir_trace<4009>::name(""); +template <> std::string vampir_trace<4010>::name("mult"); +template <> std::string vampir_trace<4011>::name("gen_mult"); +template <> std::string vampir_trace<4012>::name("mat_mat_mult"); +template <> std::string vampir_trace<4013>::name("matrix_qr"); +template <> std::string vampir_trace<4014>::name("matrix_qr_factors"); +template <> std::string vampir_trace<4015>::name("matrix_random"); +template <> std::string vampir_trace<4016>::name("matrix_scale_inplace"); +template <> std::string vampir_trace<4017>::name("matrix_rscale"); +template <> std::string vampir_trace<4018>::name("matrix_gen_smat_dmat_mult"); +template <> std::string vampir_trace<4019>::name("matrix_gen_tiling_smat_dmat_mult"); +template <> std::string vampir_trace<4020>::name("matrix_smat_smat_mult"); +template <> std::string vampir_trace<4021>::name(""); +template <> std::string vampir_trace<4022>::name(""); +template <> std::string vampir_trace<4023>::name(""); +template <> std::string vampir_trace<4024>::name(""); +template <> std::string vampir_trace<4025>::name(""); +template <> std::string vampir_trace<4026>::name(""); +template <> std::string vampir_trace<4027>::name(""); +template <> std::string vampir_trace<4028>::name(""); +template <> std::string vampir_trace<4029>::name(""); +template <> std::string vampir_trace<4030>::name(""); +template <> std::string vampir_trace<4031>::name(""); +template <> std::string vampir_trace<4032>::name(""); +template <> std::string vampir_trace<4033>::name(""); +template <> std::string vampir_trace<4034>::name(""); +template <> std::string vampir_trace<4035>::name(""); +template <> std::string vampir_trace<4036>::name("read_el_matrix"); +template <> std::string vampir_trace<4037>::name(""); +template <> std::string vampir_trace<4038>::name(""); +template <> std::string vampir_trace<4039>::name(""); +template <> std::string vampir_trace<4040>::name(""); +template <> std::string vampir_trace<4041>::name(""); + + +// Factorizations, preconditioners: 5000 +template <> std::string vampir_trace<5001>::name("cholesky_base"); +template <> std::string vampir_trace<5002>::name("cholesky_solve_base"); +template <> std::string vampir_trace<5003>::name("cholesky_schur_base"); +template <> std::string vampir_trace<5004>::name("cholesky_update_base"); +template <> std::string vampir_trace<5005>::name("cholesky_schur_update"); +template <> std::string vampir_trace<5006>::name("cholesky_tri_solve"); +template <> std::string vampir_trace<5007>::name("cholesky_tri_schur"); +template <> std::string vampir_trace<5008>::name("recursive cholesky"); +template <> std::string vampir_trace<5009>::name("fill_matrix_for_cholesky"); +template <> std::string vampir_trace<5010>::name("qr_sym_imp"); +template <> std::string vampir_trace<5011>::name("qr_algo"); +template <> std::string vampir_trace<5012>::name("eigenvalue_symmetric"); +template <> std::string vampir_trace<5013>::name("hessenberg_q"); +template <> std::string vampir_trace<5014>::name("hessenberg_factors"); +template <> std::string vampir_trace<5015>::name("extract_householder_hessenberg"); +template <> std::string vampir_trace<5016>::name("householder_hessenberg"); +template <> std::string vampir_trace<5017>::name("extract_hessenberg"); +template <> std::string vampir_trace<5018>::name("hessenberg"); +template <> std::string vampir_trace<5019>::name("inv_upper"); +template <> std::string vampir_trace<5020>::name("inv_lower"); +template <> std::string vampir_trace<5021>::name("inv"); +template <> std::string vampir_trace<5022>::name("lower_trisolve"); +template <> std::string vampir_trace<5023>::name("lu"); +template <> std::string vampir_trace<5024>::name("lu(pivot)"); +template <> std::string vampir_trace<5025>::name("lu_f"); +template <> std::string vampir_trace<5026>::name("lu_solve_straight"); +template <> std::string vampir_trace<5027>::name("lu_apply"); +template <> std::string vampir_trace<5028>::name("lu_solve"); +template <> std::string vampir_trace<5029>::name("lu_adjoint_apply"); +template <> std::string vampir_trace<5030>::name("lu_adjoint_solve"); +template <> std::string vampir_trace<5031>::name("pc::id::solve"); +template <> std::string vampir_trace<5032>::name("pc::id.solve"); +template <> std::string vampir_trace<5033>::name("pc::id::adjoint_solve"); +template <> std::string vampir_trace<5034>::name("pc::id.adjoint_solve"); +template <> std::string vampir_trace<5035>::name("ic_0::factorize"); +template <> std::string vampir_trace<5036>::name("ic_0::solve"); +template <> std::string vampir_trace<5037>::name("ic_0::solve_nocopy"); +template <> std::string vampir_trace<5038>::name("ilu_0::factorize"); +template <> std::string vampir_trace<5039>::name("ilu_0::solve"); +template <> std::string vampir_trace<5040>::name("ilu_0::adjoint_solve"); +template <> std::string vampir_trace<5041>::name("lower_trisolve_kernel"); +template <> std::string vampir_trace<5042>::name("upper_trisolve_row"); +template <> std::string vampir_trace<5043>::name("upper_trisolve_col"); +template <> std::string vampir_trace<5044>::name("ic_0::adjoint_solve"); +template <> std::string vampir_trace<5045>::name("ic_0::adjoint_solve_nocopy"); +template <> std::string vampir_trace<5046>::name("upper_trisolve_crs_compact"); +template <> std::string vampir_trace<5047>::name("lower_trisolve_crs_compact"); +template <> std::string vampir_trace<5048>::name("lower_unit_trisolve_crs_compact"); +template <> std::string vampir_trace<5049>::name("ilut::factorize"); +template <> std::string vampir_trace<5050>::name("diagonal::setup"); +template <> std::string vampir_trace<5051>::name("diagonal::solve"); +template <> std::string vampir_trace<5052>::name("imf::factor"); +template <> std::string vampir_trace<5053>::name("imf::ctor"); +template <> std::string vampir_trace<5054>::name("imf::solve"); +template <> std::string vampir_trace<5055>::name("pc::solver::assign_to"); +template <> std::string vampir_trace<5056>::name("sub_matrix_pc::solve"); +template <> std::string vampir_trace<5057>::name("sub_matrix_pc::adjoint_solve"); +template <> std::string vampir_trace<5058>::name("pc::concat::solve"); +template <> std::string vampir_trace<5059>::name("pc::concat::adjoint_solve"); +template <> std::string vampir_trace<5060>::name("umfpack::solver::ctor"); +template <> std::string vampir_trace<5061>::name("umfpack::solver::dtor"); +template <> std::string vampir_trace<5062>::name("umfpack::solve"); + + +// Fused operations: 6000 +template <> std::string vampir_trace<6001>::name("fused::fwd_eval_loop"); +template <> std::string vampir_trace<6002>::name("fused::fwd_eval_loop_unrolled"); +template <> std::string vampir_trace<6003>::name("fused::bwd_eval_loop"); +template <> std::string vampir_trace<6004>::name("fused::bwd_eval_loop_unrolled"); + + + +// Iterative solvers: 7000 +template <> std::string vampir_trace<7001>::name("cg_without_pc"); +template <> std::string vampir_trace<7002>::name("cg"); +template <> std::string vampir_trace<7003>::name("bicg"); +template <> std::string vampir_trace<7004>::name("bicgstab"); +template <> std::string vampir_trace<7005>::name("bicgstab_2"); +template <> std::string vampir_trace<7006>::name("bicgstab_ell"); +template <> std::string vampir_trace<7007>::name("cgs"); +template <> std::string vampir_trace<7008>::name("qmr"); +template <> std::string vampir_trace<7009>::name("tfqmr"); +template <> std::string vampir_trace<7010>::name("idr_s"); + + +// OpenMP +template <> std::string vampir_trace<8001>::name("omp::dot"); +template <> std::string vampir_trace<8002>::name("omp::reduction"); +template <> std::string vampir_trace<8003>::name("omp::dyn_vec_expr"); +template <> std::string vampir_trace<8004>::name("omp::crs_cvec_mult"); + + + +// multigrid +template <> std::string vampir_trace<8501>::name("mtl::mg::v_cycle"); +template <> std::string vampir_trace<8502>::name("mtl::mg::w_cycle"); +template <> std::string vampir_trace<8503>::name("mtl::mg::fmg"); +template <> std::string vampir_trace<8504>::name("mtl::mg::two_grid_cycle"); + +template <> std::string vampir_trace<8510>::name("mtl::mg::geometric_multigrid_solver_impl"); +template <> std::string vampir_trace<8511>::name("mtl::mg::geometric_multigrid_solver_solve1"); +template <> std::string vampir_trace<8512>::name("mtl::mg::geometric_multigrid_solver_solve2"); + +template <> std::string vampir_trace<8515>::name("mtl::mg::algebraic_multigrid_solver"); +template <> std::string vampir_trace<8516>::name("amg_pc::solve"); + +template <> std::string vampir_trace<8520>::name("mtl::mg::linear_restriction"); +template <> std::string vampir_trace<8521>::name("mtl::mg::linear_prolongation"); + +template <> std::string vampir_trace<8530>::name("mtl::mg::gauss_elimination"); +template <> std::string vampir_trace<8531>::name("mtl::mg::back_substitution"); + +template <> std::string vampir_trace<8550>::name("mtl::mg::jacobi"); +template <> std::string vampir_trace<8551>::name("mtl::mg::gauss_seidel"); +template <> std::string vampir_trace<8552>::name("mtl::mg::jor"); +template <> std::string vampir_trace<8553>::name("mtl::mg::sor"); + +template <> std::string vampir_trace<8572>::name("boundaries"); +template <> std::string vampir_trace<8573>::name("viscosity"); +template <> std::string vampir_trace<8574>::name("pressure_correction"); + +template <> std::string vampir_trace<8590>::name("mtl::mg::util::vtk_exporter"); +template <> std::string vampir_trace<8591>::name("mtl::mg::util::csv_exporter"); + +template <> std::string vampir_trace<8610>::name("amg::amg_matrix_hierarchy"); +template <> std::string vampir_trace<8611>::name("amg::compute_influence"); +template <> std::string vampir_trace<8612>::name("amg::default_coarse_grid_detection::compute_C"); +template <> std::string vampir_trace<8614>::name("amg::utils::compute_potentials"); +template <> std::string vampir_trace<8615>::name("amg::utils::find_max_pos"); + +template <> std::string vampir_trace<8617>::name("amg::amg_prolongation"); +template <> std::string vampir_trace<8618>::name("amg::compute_weight"); +template <> std::string vampir_trace<8619>::name("amg::compute_mfactors"); + +template <> std::string vampir_trace<8620>::name("amg::strongly_influenced_points"); +template <> std::string vampir_trace<8621>::name("amg::is_strongly_influenced"); +template <> std::string vampir_trace<8622>::name("amg::strongly_influencing_points"); + +template <> std::string vampir_trace<8630>::name("amg::amg_operators::amg_restriction"); +template <> std::string vampir_trace<8631>::name("amg::amg_operators::amg_prolongation"); +template <> std::string vampir_trace<8635>::name("amg::amg_operators::amg_weight"); + +template <> std::string vampir_trace<8900>::name("NaSto::solve()"); +template <> std::string vampir_trace<8910>::name("NaSto::computeGamma()"); +template <> std::string vampir_trace<8920>::name("NaSto::computeBoundaries()"); +template <> std::string vampir_trace<8930>::name("NaSto::computeImplViscosity()"); +template <> std::string vampir_trace<8940>::name("NaSto::computePressureCorr()"); + +// Test blocks for performance debugging +template <> std::string vampir_trace<9901>::name("tb1"); +template <> std::string vampir_trace<9902>::name("tb2"); +template <> std::string vampir_trace<9903>::name("tb3"); +template <> std::string vampir_trace<9904>::name("tb4"); +template <> std::string vampir_trace<9999>::name("main"); + + +// Only for testing +template <> std::string vampir_trace<9990>::name("helper_function"); +template <> std::string vampir_trace<9991>::name("function"); + + + +}} //mtl::vpt + +#endif //MTL_HAS_VPT diff --git a/install/MTL/include/boost/numeric/mtl/interface/vpt.hpp b/install/MTL/include/boost/numeric/mtl/interface/vpt.hpp new file mode 100644 index 00000000..a1838bcc --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/interface/vpt.hpp @@ -0,0 +1,94 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VPT_VPT_INCLUDE +#define MTL_VPT_VPT_INCLUDE + +#ifdef MTL_HAS_VPT + #include <vt_user.h> + #include <boost/mpl/bool.hpp> +#endif + +#include <math.h> +#include <string> + +namespace mtl { + +/// Namespace for Vampir Trace interface +namespace vpt { + +#ifdef MTL_HAS_VPT + +#ifndef MTL_VPT_LEVEL +# define MTL_VPT_LEVEL 2 +#endif + +/// Class for Vampir Trace +template <int N> +class vampir_trace +{ + // Statically determine whether the event is traced; just in case you wanted to know how. + typedef boost::mpl::bool_<(MTL_VPT_LEVEL * 1000 < N)> to_print; + public: + /// Default constructor defines the start point of a trace + vampir_trace() { entry(to_print()); } + + void entry(boost::mpl::false_) {} + void entry(boost::mpl::true_) + { + VT_USER_START(name.c_str()); + // std::cout << "vpt_entry(" << N << ")\n"; + } + + /// Destructor defines the end point of a trace + ~vampir_trace() { end(to_print()); } + + void end(boost::mpl::false_) {} + void end(boost::mpl::true_) + { + VT_USER_END(name.c_str()); + // std::cout << "vpt_end(" << N << ")\n"; + } + + /// Function to check whether this event is traced with the current setting + bool is_traced() { return to_print::value; } + + private: + static std::string name; +}; + + +#else + +// Dummy when Vampir Trace is not supported +template <int N> +class vampir_trace +{ + public: + vampir_trace() {} + void show_vpt_level() {} + bool is_traced() { return false; } + private: + static std::string name; +}; +#endif + + // names defined in vpt.cpp !!! + +} // namespace vpt + +/// Import of vpt::vampir_trace +using vpt::vampir_trace; + +} // namespace mtl + +#endif // MTL_VPT_VPT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/interfaces.hpp b/install/MTL/include/boost/numeric/mtl/interfaces.hpp new file mode 100644 index 00000000..b709dda9 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/interfaces.hpp @@ -0,0 +1,18 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_INTERFACES_INCLUDE +#define MTL_INTERFACES_INCLUDE + +#include <boost/numeric/mtl/interface/vpt.hpp> + +#endif // MTL_INTERFACES_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/io/functor_symbol.hpp b/install/MTL/include/boost/numeric/mtl/io/functor_symbol.hpp new file mode 100644 index 00000000..b66fe3a6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/io/functor_symbol.hpp @@ -0,0 +1,90 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_IO_FUNCTOR_SYMBOL_INCLUDE +#define MTL_IO_FUNCTOR_SYMBOL_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace io { + +template <typename Value> +std::string functor_symbol(const sfunctor::conj<Value>&) +{ return "conj"; } + +template <typename Value> +std::string functor_symbol(const sfunctor::imag<Value>&) +{ return "imag"; } + +template <typename Value> +std::string functor_symbol(const sfunctor::real<Value>&) +{ return "real"; } + +template <typename Value> +std::string functor_symbol(const sfunctor::identity<Value>&) +{ return "identity"; } + +template <typename Value> +std::string functor_symbol(const sfunctor::abs<Value>&) +{ return "abs"; } + +template <typename Value> +std::string functor_symbol(const sfunctor::sqrt<Value>&) +{ return "sqrt"; } + +template <typename Value> +std::string functor_symbol(const sfunctor::square<Value>&) +{ return "square"; } + +template <typename Value> +std::string functor_symbol(const sfunctor::negate<Value>&) +{ return "-"; } + +template <typename Value1, typename Value2> +std::string functor_symbol(const sfunctor::minus<Value1, Value2>&) +{ return "-"; } + +template <typename Value1, typename Value2> +std::string functor_symbol(const sfunctor::plus<Value1, Value2>&) +{ return "+"; } + +template <typename Value1, typename Value2> +std::string functor_symbol(const sfunctor::times<Value1, Value2>&) +{ return "*"; } + +template <typename Value1, typename Value2> +std::string functor_symbol(const sfunctor::divide<Value1, Value2>&) +{ return "/"; } + +template <typename Value1, typename Value2> +std::string functor_symbol(const sfunctor::assign<Value1, Value2>&) +{ return "="; } + +template <typename Value1, typename Value2> +std::string functor_symbol(const sfunctor::plus_assign<Value1, Value2>&) +{ return "+="; } + +template <typename Value1, typename Value2> +std::string functor_symbol(const sfunctor::minus_assign<Value1, Value2>&) +{ return "-="; } + +template <typename Value1, typename Value2> +std::string functor_symbol(const sfunctor::times_assign<Value1, Value2>&) +{ return "*="; } + +template <typename Value1, typename Value2> +std::string functor_symbol(const sfunctor::divide_assign<Value1, Value2>&) +{ return "/="; } + +}} // namespace mtl::io + +#endif // MTL_IO_FUNCTOR_SYMBOL_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/io/matrix_file.hpp b/install/MTL/include/boost/numeric/mtl/io/matrix_file.hpp new file mode 100644 index 00000000..cd0b2763 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/io/matrix_file.hpp @@ -0,0 +1,41 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_IO_MATRIX_FILE_INCLUDE +#define MTL_IO_MATRIX_FILE_INCLUDE + +namespace mtl { namespace io { + +template <typename MatrixIFStream, typename MatrixOFStream> +class matrix_file +{ + public: + explicit matrix_file(const std::string& fname) : fname(fname) {} + explicit matrix_file(const char* fname) : fname(fname) {} + + std::string file_name() const { return fname; } + + template <typename Collection> + matrix_file& operator=(const Collection& c) + { + MatrixOFStream stream(fname); + stream << c; + return *this; + } + + protected: + std::string fname; +}; + +}} // namespace mtl::io + +#endif // MTL_IO_MATRIX_FILE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/io/matrix_market.hpp b/install/MTL/include/boost/numeric/mtl/io/matrix_market.hpp new file mode 100644 index 00000000..847f6245 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/io/matrix_market.hpp @@ -0,0 +1,335 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_IO_MATRIX_MARKET_INCLUDE +#define MTL_IO_MATRIX_MARKET_INCLUDE + +#include <string> +#include <fstream> +#include <iostream> +#include <limits> +#include <locale> +#include <complex> + +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_floating_point.hpp> +#include <boost/type_traits/is_integral.hpp> +// #include <boost/algorithm/string/case_conv.hpp> +#include <boost/numeric/conversion/cast.hpp> + +#include <boost/numeric/mtl/io/matrix_file.hpp> +#include <boost/numeric/mtl/io/read_filter.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/string_to_enum.hpp> +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/mtl/operation/set_to_zero.hpp> + +namespace mtl { namespace io { + + +/// Input file stream for files in matrix market format +class matrix_market_istream +{ + class pattern_type {}; + typedef matrix_market_istream self; + void check_stream(const std::string& file_name= std::string()) // not const to delete new_stream + { + if (!my_stream.good()) { + std::string message("matrix_market_istream: Error in input stream!\n"); + if (file_name != std::string()) + message+= "Probably file " + file_name + " not found.\n"; + std::cerr << message; + if (new_stream) + delete new_stream, new_stream= 0; // To get valgrind quite + throw(file_not_found(message.c_str())); + } + } + + public: + explicit matrix_market_istream(const char* p) : new_stream(new std::ifstream(p)), my_stream(*new_stream) { check_stream(p); } + explicit matrix_market_istream(const std::string& s) : new_stream(new std::ifstream(s.c_str())), my_stream(*new_stream) { check_stream(s); } + explicit matrix_market_istream(std::istream& s= std::cin) : new_stream(0), my_stream(s) { check_stream(); } + + ~matrix_market_istream() + { if (new_stream) delete new_stream; } + + template <typename Coll> + self& operator>>(Coll& c) + { return read(c, typename mtl::traits::category<Coll>::type()); } + + /// Close only my own file, i.e. if filename and not stream is passed in constructor + void close() { if (new_stream) new_stream->close(); } + + protected: + template <typename Matrix> self& read(Matrix& A, tag::matrix); + + void to_lower(std::string& s) const + { + using namespace std; + for (unsigned i= 0; i < s.size(); i++) + s[i]= tolower(s[i]); + } + + void set_symmetry(std::string& symmetry_text) + { + to_lower(symmetry_text); + const char* symmetry_options[]= {"general", "symmetric", "skew-symmetric", "hermitian"}; + my_symmetry= string_to_enum(symmetry_text, symmetry_options, symmetry()); + } + + void set_sparsity(std::string& sparsity_text) + { + to_lower(sparsity_text); + const char* sparsity_options[]= {"coordinate", "array"}; + my_sparsity= string_to_enum(sparsity_text, sparsity_options, sparsity()); + } + + template <typename Inserter, typename Value> + void read_matrix(Inserter& ins, Value) + { + typedef typename Collection<typename Inserter::matrix_type>::size_type size_type; + read_filter<Inserter> filter(ins); + if (my_sparsity == coordinate) // sparse + // while (my_stream) { // sometimes does an extra erroneous loop + for (std::size_t i= 0; i < nnz; i++) { + size_type r, c; + my_stream >> r >> c; + if (!my_stream) break; // in case while(my_stream) caught an empty line at the end + insert_value(ins, r-1, c-1, filter, Value()); + } + else // dense + for (std::size_t c= 0; c < ncols; c++) + for (std::size_t r= 0; r < nrows; r++) + insert_value(ins, r, c, filter, Value()); + } + + template <typename Inserter, typename Filter, typename Value> + void insert_value(Inserter& ins, std::size_t r, std::size_t c, const Filter& filter, Value) + { + using mtl::conj; + typedef typename Collection<typename Inserter::matrix_type>::value_type mvt; + Value v; + read_value(v); + // std::cout << "Going to insert at [" << r << "][" << c << "] value " << which_value(v, mvt()) << "\n"; + if (filter(r, c)) + ins[r][c] << which_value(v, mvt()); + if (r != c && filter(c, r)) + switch(my_symmetry) { + case symmetric: ins[c][r] << which_value(v, mvt()); break; + case skew: ins[c][r] << -which_value(v, mvt()); break; + case Hermitian: ins[c][r] << conj(which_value(v, mvt())); break; + default: ; // do nothing + } + } + + void read_value(pattern_type) {} + void read_value(double& v) { my_stream >> v;} + void read_value(long& v) { my_stream >> v;} + void read_value(std::complex<double>& v) + { + double r, i; my_stream >> r >> i; v= std::complex<double>(r, i); + } + + // Which value to be inserted? Itself if exist and 0 for pattern; complex are + template <typename Value, typename MValue> MValue which_value(Value v, MValue) { return boost::numeric_cast<MValue>(v); } + template <typename MValue> MValue which_value(pattern_type, MValue) { return boost::numeric_cast<MValue>(0.0); } + template <typename MValue> MValue which_value(std::complex<double>, MValue) { MTL_THROW(runtime_error("Cannot convert complex value in real\n")); return 1; } + std::complex<long double> which_value(std::complex<double> v, std::complex<long double>) { return boost::numeric_cast<std::complex<long double> >(v); } + std::complex<double> which_value(std::complex<double> v, std::complex<double>) { return v; } + std::complex<float> which_value(std::complex<double> v, std::complex<float>) { return std::complex<float>(float(real(v)), float(imag(v))); } + + std::ifstream *new_stream; + std::istream &my_stream; + enum symmetry {general, symmetric, skew, Hermitian} my_symmetry; + enum sparsity {coordinate, array} my_sparsity; + std::size_t nrows, ncols, nnz; +}; + + + +// Matrix version +template <typename Matrix> +matrix_market_istream& matrix_market_istream::read(Matrix& A, tag::matrix) +{ + std::string marker, type, sparsity_text, value_format, symmetry_text; + my_stream >> marker >> type >> sparsity_text >> value_format >> symmetry_text; +#if 0 + std::cout << marker << ", " << type << ", " << sparsity_text << ", " + << value_format << ", " << symmetry_text << "\n"; +#endif + MTL_THROW_IF(marker != std::string("%%MatrixMarket"), + runtime_error("File not in Matrix Market format")); + MTL_THROW_IF(type != std::string("matrix"), + runtime_error("Try to read matrix from non-matrix file")); + + set_symmetry(symmetry_text); + set_sparsity(sparsity_text); + + char first, comment[80]; + do { + my_stream >> first; + if (first == '%') // comments start with % -> ignore them + my_stream.getline(comment, 80, '\n'); // read rest of line + else + my_stream.putback(first); // if not commment we still need it + } while (first == '%'); + + my_stream >> nrows >> ncols; + // std::cout << nrows << "x" << ncols << ", " << nnz << " non-zeros\n"; + A.change_dim(nrows, ncols); + set_to_zero(A); + + std::size_t slot_size; + if (sparsity_text == std::string("coordinate")) { + my_stream >> nnz; slot_size= std::max(std::size_t(double(nnz) / double(A.dim1()) * 1.25), std::size_t(1)); + } else + slot_size= A.dim2(); // maximal value (if A is dense it does not matter anyway) + + // Create enough space in sparse matrices + mat::inserter<Matrix> ins(A, slot_size); + + if (value_format == std::string("real")) + read_matrix(ins, double()); + else if (value_format == std::string("integer")) + read_matrix(ins, long()); + else if (value_format == std::string("complex")) + read_matrix(ins, std::complex<double>()); + else if (value_format == std::string("pattern")) + read_matrix(ins, pattern_type()); + else + MTL_THROW(runtime_error("Unknown tag for matrix value type in file")); + + return *this; +} + + +class matrix_market_ostream +{ + typedef matrix_market_ostream self; +public: + explicit matrix_market_ostream(const char* p) : new_stream(new std::ofstream(p)), my_stream(*new_stream) {} + explicit matrix_market_ostream(const std::string& s) : new_stream(new std::ofstream(s.c_str())), my_stream(*new_stream) {} + explicit matrix_market_ostream(std::ostream& s= std::cout) : new_stream(0), my_stream(s) {} + + ~matrix_market_ostream() { if (new_stream) delete new_stream; } + + template <typename Coll> + self& operator<<(const Coll& c) + { + return write(c, typename mtl::traits::category<Coll>::type()); + } + + /// Close only my own file, i.e. if filename and not stream is passed in constructor + void close() { if (new_stream) new_stream->close(); } + +private: + template <typename Matrix> self& write(const Matrix& A, tag::matrix) + { + matrix_status_line(A); + if (sparsity(A) == std::string("coordinate ")) + return write_sparse_matrix(A); + else + return write_dense_matrix(A); + } + + template <typename Matrix> self& write_sparse_matrix(const Matrix& A) + { + my_stream << num_rows(A) << " " << num_cols(A) << " " << A.nnz() << "\n"; + + typename mtl::traits::row<Matrix>::type row(A); + typename mtl::traits::col<Matrix>::type col(A); + typename mtl::traits::const_value<Matrix>::type value(A); + typedef typename mtl::traits::range_generator<tag::major, Matrix>::type cursor_type; + typedef typename mtl::traits::range_generator<tag::nz, cursor_type>::type icursor_type; + + for (cursor_type cursor = begin<tag::major>(A), cend = end<tag::major>(A); cursor != cend; ++cursor) + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) + my_stream << row(*icursor)+1 << " " << col(*icursor)+1 << " ", write_value(value(*icursor)), my_stream << "\n"; + return *this; + } + + template <typename Matrix> self& write_dense_matrix(const Matrix& A) + { + my_stream << num_rows(A) << " " << num_cols(A) << "\n"; + for (std::size_t c = 0; c < num_cols(A); ++c) + for (std::size_t r = 0; r < num_rows(A); ++r) { + write_value(A[r][c]), my_stream << " "; + my_stream << "\n"; + } + return *this; + } + + template <typename Value> + typename boost::enable_if<boost::is_integral<Value> >::type + write_value(const Value& v) { my_stream << v; } + + template <typename Value> + typename boost::enable_if<boost::is_floating_point<Value> >::type + write_value(const Value& v) + { + my_stream.precision(std::numeric_limits<Value>::digits10 + 1); + my_stream.setf(std::ios::scientific); + my_stream << v; + my_stream.unsetf(std::ios::scientific); + } + + template <typename Value> + void write_value(const std::complex<Value>& v) + { + my_stream.precision(std::numeric_limits<Value>::digits10 + 1); + my_stream.setf(std::ios::scientific); + my_stream << real(v) << " " << imag(v); + my_stream.unsetf(std::ios::scientific); + } + + // Will be generalized via traits::is_symmetric and alike + template <typename Matrix> + std::string symmetry(const Matrix&) const { return std::string("general\n"); } + + template <typename Matrix> + std::string sparsity(const Matrix&) const + { + return std::string( mtl::traits::is_sparse<Matrix>::value ? "coordinate " : "array " ); + } + + template <typename Value> + typename boost::enable_if<boost::is_integral<Value>, std::string>::type + value(const Value&) const { return std::string("integer "); } + + template <typename Value> + typename boost::enable_if<boost::is_floating_point<Value>, std::string>::type + value(const Value&) const { return std::string("real "); } + + template <typename Value> + std::string value(const std::complex<Value>&) const { return std::string("complex "); } + + template <typename Matrix> + void matrix_status_line(const Matrix& A) const + { + typedef typename Collection<Matrix>::value_type value_type; + std::string st(std::string("%%MatrixMarket matrix ") + sparsity(A) + value(value_type()) + symmetry(A)); + my_stream << st; + } + +protected: + std::ofstream *new_stream; + std::ostream &my_stream; +}; + + +}} // namespace mtl::io + +#endif // MTL_IO_MATRIX_MARKET_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/io/path.hpp b/install/MTL/include/boost/numeric/mtl/io/path.hpp new file mode 100644 index 00000000..d0bedc07 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/io/path.hpp @@ -0,0 +1,54 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_IO_PATH_INCLUDE +#define MTL_IO_PATH_INCLUDE + +namespace mtl { namespace io { + +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + const static char delim = '\\'; +#else + const static char delim = '/'; +#endif + +/// Join the directory and file +/** It concatenates both with the os-specific slash unless directory is empty, then only file is returned **/ +std::string inline join(std::string directory, std::string file) +{ + return directory.empty() ? file : directory + delim + file; +} + +/// Directory name in s that is everything before last slash +std::string inline directory_name(std::string s) +{ + for (int i= s.size() - 1; i >= 0; i--) + if (s[i] == delim) + return s.substr(0, i); + return std::string(); +} + +/// File name in s that is everything after last slash +std::string inline file_name(std::string s) +{ + for (int i= s.size() - 1; i >= 0; i--) + if (s[i] == delim) + return s.substr(i + 1); + return s; +} + + + + +}} // namespace mtl::io + +#endif // MTL_IO_PATH_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/io/read_el_matrix.hpp b/install/MTL/include/boost/numeric/mtl/io/read_el_matrix.hpp new file mode 100644 index 00000000..b6b1c302 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/io/read_el_matrix.hpp @@ -0,0 +1,165 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. +// +// Algorithm inspired by Nick Vannieuwenhoven, written by Cornelius Steinhardt + +#ifndef MTL_MATRIX_READ_EL_MATRIX +#define MTL_MATRIX_READ_EL_MATRIX + +#include <string> + +#include <iostream> +#include <istream> +#include <set> +#include <vector> +#include <valarray> + +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/mtl/matrix/element.hpp> +#include <boost/numeric/mtl/matrix/element_structure.hpp> + +namespace mtl { namespace mat { + +// Read a value from the stream. The stream is advanced. +template <class T, class StreamType> +inline T read_value(StreamType& stream) +{ + T value; + stream >> value; + return value; +} + +// Reads the element structure from a given file. +// +// It is assumed the nodes are numbered consecutively, i.e. there are no unused +// node numbers. +template < typename StreamType, typename ValueType> +void read_el_matrix(StreamType& file, element_structure<ValueType>& A) +{ + // Type definitions + typedef element<ValueType> element_type; + // typedef typename element_type::value_type value_type; + typedef typename element_type::index_type indices; + typedef typename element_type::matrix_type matrix; + vampir_trace<4036> trace; + + // Read element type information. + int nb_elements = 0; + file >> nb_elements; + file.ignore(500,'\n'); + std::cout << "nb elements: " << nb_elements << "\n"; + + // Compatibility with older files + file.ignore(500,'\n'); + + assert(nb_elements >= 0); + + element_type* elements = new element_type[nb_elements]; + + // Read elements from file. + int el_nbr = 0; + int nb_total_vars = 0; + while( el_nbr < nb_elements ) { + + // Read the node numbers. + std::string line; + getline(file, line, '\n'); + std::stringstream node_line(line), read_node_line(line); + + int read_num=0, i=0; + while( !read_node_line.eof() ) { + int idx = 0; + read_node_line >> idx; + ++read_num; + } + read_num--; + mtl::dense_vector<int> nodes(read_num, 0); + while( !node_line.eof() ) { + int idx = 0; + node_line >> idx; + if (i<read_num) + nodes[i]=idx; + if(idx > nb_total_vars) + nb_total_vars = idx; + i++; + } + indices index(nodes); + // Read the values. + const int nb_vars = int(size(nodes)); + matrix vals(nb_vars, nb_vars); + for(int i = 0; i < nb_vars*nb_vars; ++i) + vals(i / nb_vars, i % nb_vars) = read_value<ValueType>(file); + file.ignore(500,'\n'); + file.ignore(500,'\n'); + element_type elem(el_nbr, index, vals); + elements[el_nbr] = elem; + if(el_nbr == 0){ + std::cout<< "elem=" << elem << "\n"; + } + ++el_nbr; + } + + // Construct mapping. + ++nb_total_vars; + assert(nb_total_vars >= 0); + std::vector<int>* node_element_map = new std::vector<int>[nb_total_vars]; + for( int i = 0; i < nb_elements; ++i ) { + element_type& el = elements[i]; + indices& idx = el.get_indices(); + for(int j = 0; j < el.nb_vars(); ++j) + node_element_map[ idx(j) ].push_back(el.get_id()); + } + + // Construct neighborhood information. + for( int i = 0; i < nb_elements; ++i ) { + element_type& el = elements[i]; + indices& idx = el.get_indices(); + std::set<int> neighs; + for(int j = 0; j < el.nb_vars(); ++j) + neighs.insert(node_element_map[ idx(j) ].begin(), + node_element_map[ idx(j) ].end()); + + for(std::set<int>::iterator it = neighs.begin(); it != neighs.end(); ++it) + if( *it != el.get_id() ) + el.get_neighbors().push_back( elements+(*it) ); + + + // Sort data. + el.sort_indices(); + } + + delete[] node_element_map; + A.consume(nb_elements, nb_total_vars, elements); +} + +template <typename ValueType> +inline void read_el_matrix(std::string& mat_file, element_structure<ValueType>& A) +{ read_el_matrix(mat_file.c_str(), A); } + +template <typename ValueType> +void read_el_matrix(const char* mat_file, element_structure<ValueType>& A) +{ + std::ifstream file; + file.open( mat_file ); + if( !file.is_open() ) { + std::cout << "The file \"" << mat_file << "\" could not be opened." << + std::endl; + throw "File could not be opened"; + } + read_el_matrix(file, A); + + file.close(); +} + +}} // end namespace mtl::matrix + +#endif // MTL_MATRIX_READ_EL_MATRIX diff --git a/install/MTL/include/boost/numeric/mtl/io/read_filter.hpp b/install/MTL/include/boost/numeric/mtl/io/read_filter.hpp new file mode 100644 index 00000000..960bc052 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/io/read_filter.hpp @@ -0,0 +1,42 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_IO_READ_FILTER_INCLUDE +#define MTL_IO_READ_FILTER_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> + +namespace mtl { namespace io { + +/// Utility to filter entries in the read process +/** Depending on type only certain entries are considered for insertion. + Particularly interesting for distributed collections (inserters). **/ +template <typename Inserter> +class read_filter +{ + public: + explicit read_filter(const Inserter& inserter) : inserter(inserter) {} + + /// Default for vectors is to consider every entry + bool operator()(std::size_t) const { return true; } + + /// Default for matrices is to consider every entry + bool operator()(std::size_t, std::size_t) const { return true; } + + private: + const Inserter& inserter; +}; + + +}} // namespace mtl::io + +#endif // MTL_IO_READ_FILTER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/io/test_ostream.hpp b/install/MTL/include/boost/numeric/mtl/io/test_ostream.hpp new file mode 100644 index 00000000..ec2b57ec --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/io/test_ostream.hpp @@ -0,0 +1,69 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TEST_OSTREAM_INCLUDE +#define MTL_TEST_OSTREAM_INCLUDE + +#include <ostream> + +namespace mtl { namespace io { + +/// ostream class whose objects only write if MTL_VERBOSE_TEST is defined +struct test_ostream +{ +#ifdef MTL_VERBOSE_TEST + + /// Constructor for out or std::cout + test_ostream(std::ostream& out = std::cout) : out(out) {} + + + template <typename T> + test_ostream& operator<<(const T& v) + { + out << v; + return *this; + } + + test_ostream& operator<<(test_ostream& (*pf)(test_ostream&)) + { return pf(*this); } + + void flush() { out.flush(); } + +private: + std::ostream& out; + +#else + test_ostream() {} + test_ostream(std::ostream&) {} + + /// Print on outstream + template <typename T> test_ostream& operator<<(const T&) { return *this; } + + /// Interface for manipulators + test_ostream& operator<<(test_ostream& (*)(test_ostream&)) { return *this; } + + /// Flush output + void flush() {} +#endif +}; + +/// Output stream that writes if MTL_VERBOSE_TEST is defined +static test_ostream tout; + +}} // namespace mtl::io + +namespace std { + inline mtl::io::test_ostream& endl(mtl::io::test_ostream& os) { os << '\n'; os.flush(); return os; } +} + + +#endif // MTL_TEST_OSTREAM_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/io/write_ast.hpp b/install/MTL/include/boost/numeric/mtl/io/write_ast.hpp new file mode 100644 index 00000000..6b30c89c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/io/write_ast.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_IO_WRITE_AST_INCLUDE +#define MTL_IO_WRITE_AST_INCLUDE + +#include <fstream> +#include <boost/numeric/mtl/io/write_ast_dispatch.hpp> + +namespace mtl { namespace io { + +/// write the abstract syntax tree (AST) to file name \p fname +template <typename Expr> +void write_ast(const Expr& expr, const char* fname) +{ + std::ofstream f(fname); + f << "digraph G {\n ordering = out;\n edge [arrowhead=none];\n\n"; + write_ast_dispatch(expr, "t", f); + + f << "}\n"; +} + + +}} // namespace mtl::io + +#endif // MTL_IO_WRITE_AST_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/io/write_ast_dispatch.hpp b/install/MTL/include/boost/numeric/mtl/io/write_ast_dispatch.hpp new file mode 100644 index 00000000..e39dd29b --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/io/write_ast_dispatch.hpp @@ -0,0 +1,162 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_IO_WRITE_AST_DISPATCH_INCLUDE +#define MTL_IO_WRITE_AST_DISPATCH_INCLUDE + +#include <string> +#include <sstream> +#include <fstream> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/type_traits/is_floating_point.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/io/functor_symbol.hpp> +#include <boost/numeric/mtl/vector/vec_vec_aop_expr.hpp> + +namespace mtl { namespace io { + +template <typename Value, typename Parameters> +void write_ast_dispatch(const mtl::dense_vector<Value, Parameters>& v, std::string s, std::ofstream& f); +template <typename E1, typename E2, typename SFunctor> +void write_ast_dispatch(const mtl::vec_vec_aop_expr<E1, E2, SFunctor>& expr, std::string s, std::ofstream& f); +template <class E1, class E2, typename SFunctor> +void write_ast_dispatch(const mtl::vec_vec_pmop_expr<E1, E2, SFunctor>& expr, std::string s, std::ofstream& f); +template <typename Functor, typename Vector> +void write_ast_dispatch(const mtl::map_view<Functor, Vector>& expr, std::string s, std::ofstream& f); +template <typename Scaling, typename Vector> +void write_ast_dispatch(const mtl::scaled_view<Scaling, Vector>& expr, std::string s, std::ofstream& f); +template <typename Matrix, typename Vector> +void write_ast_dispatch(const mtl::mat_cvec_times_expr<Matrix, Vector>& expr, std::string s, std::ofstream& f); +template <typename Expr> +void write_ast_dispatch(const mtl::operation::compute_summand<Expr>& expr, std::string s, std::ofstream& f); +template <typename Matrix, typename Vector> +void write_ast_dispatch(const mtl::operation::compute_summand<mtl::mat_cvec_times_expr<Matrix, Vector> >& expr, std::string s, std::ofstream& f); +template <typename Vector1, typename Vector2> +void write_ast_dispatch(const mtl::mat::outer_product_matrix<Vector1, Vector2>& expr, std::string s, std::ofstream& f); + + + +template <typename Value> +typename boost::enable_if_c<boost::is_floating_point<Value>::value || boost::is_integral<Value>::value>::type +write_ast_dispatch(const Value& v, std::string s, std::ofstream& f) +{ + f << " " << s << "[shape=box,label=\"scalar\\n" << v << "\"]\n"; +} + + +template <typename Value, typename Parameters> +void write_ast_dispatch(const mtl::dense_vector<Value, Parameters>& v, std::string s, std::ofstream& f) +{ + f << " " << s << "[shape=box,label=\"vector\\n" << &v << "\"]\n"; +} + +template <typename E1, typename E2, typename SFunctor> +void write_ast_dispatch(const mtl::vec_vec_aop_expr<E1, E2, SFunctor>& expr, std::string s, std::ofstream& f) +{ + f << " " << s << "[label=\"" << functor_symbol(SFunctor()) << "\"]\n"; + std::string target= s + "t", source= s + "s"; + write_ast_dispatch(expr.first_argument(), target, f); + write_ast_dispatch(expr.second_argument(), source, f); + f << " " << s << "->" << target << '\n'; + f << " " << s << "->" << source << '\n'; +} + +template <class E1, class E2, typename SFunctor> +void write_ast_dispatch(const mtl::vec_vec_pmop_expr<E1, E2, SFunctor>& expr, std::string s, std::ofstream& f) +{ + f << " " << s << "[label=\"" << functor_symbol(SFunctor()) << "\"]\n"; + std::string first= s + "f", second= s + "s"; + write_ast_dispatch(expr.first_argument(), first, f); + write_ast_dispatch(expr.second_argument(), second, f); + f << " " << s << "->" << first << '\n'; + f << " " << s << "->" << second << '\n'; +} + +template <typename Scaling, typename Vector> +void write_ast_dispatch(const mtl::scaled_view<Scaling, Vector>& expr, std::string s, std::ofstream& f) +{ + f << " " << s << "[label=\"scaled_view\"]\n"; + std::string functor= s + "f", ref= s + "r"; + + write_ast_dispatch(expr.functor.value, functor, f); + write_ast_dispatch(expr.ref, ref, f); + + f << " " << s << "->" << functor << '\n'; + f << " " << s << "->" << ref << '\n'; +} + +template <typename Value1, typename Value2> +void write_ast_dispatch(const mtl::tfunctor::scale<Value1, Value2, mtl::tag::scalar>& expr, std::string s, std::ofstream& f) +{ + f << " " << s << "[label=\"scale\"]\n"; + std::string factor= s + "f", ref= s + "r"; + write_ast_dispatch(expr.value(), factor, f); + f << " " << ref << "[label=\".\"]\n"; + + f << " " << s << "->" << factor << '\n'; + f << " " << s << "->" << ref << '\n'; +} + +template <typename Functor, typename Vector> +void write_ast_dispatch(const mtl::map_view<Functor, Vector>& expr, std::string s, std::ofstream& f) +{ + f << " " << s << "[label=\"map\"]\n"; + std::string functor= s + "f", ref= s + "r"; + + write_ast_dispatch(expr.functor, functor, f); + write_ast_dispatch(expr.ref, ref, f); + + f << " " << s << "->" << functor << '\n'; + f << " " << s << "->" << ref << '\n'; +} + +// template <typename Matrix, typename Vector> +// void write_ast_dispatch(const mtl::mat_cvec_times_expr<Matrix, Vector>& expr, std::string s, std::ofstream& f) +// { +// } + +template <typename Expr> +void write_ast_dispatch(const mtl::operation::compute_summand<Expr>& expr, std::string s, std::ofstream& f) +{ + write_ast_dispatch(expr.value, s, f); +} + +template <typename Matrix, typename Vector> +void write_ast_dispatch(const mtl::operation::compute_summand<mtl::mat_cvec_times_expr<Matrix, Vector> >& expr, std::string s, std::ofstream& f) +{ +# ifdef NDEBUG + write_ast_dispatch(expr.value, s, f); +# else + f << " " << s << "[label=\"*\"]\n"; + std::string first= s + "f", second= s + "s"; + write_ast_dispatch(expr.first, first, f); + write_ast_dispatch(expr.second, second, f); + f << " " << s << "->" << first << '\n'; + f << " " << s << "->" << second << '\n'; +# endif +} + +template <typename Vector1, typename Vector2> +void write_ast_dispatch(const mtl::mat::outer_product_matrix<Vector1, Vector2>& expr, std::string s, std::ofstream& f) +{ + f << " " << s << "[label=\"outer product\"]\n"; + std::string first= s + "f", second= s + "s"; + write_ast_dispatch(expr.v1(), first, f); + write_ast_dispatch(expr.v2(), second, f); + f << " " << s << "->" << first << '\n'; + f << " " << s << "->" << second << '\n'; +} + +}} // namespace mtl::io + +#endif // MTL_IO_WRITE_AST_DISPATCH_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrices.hpp b/install/MTL/include/boost/numeric/mtl/matrices.hpp new file mode 100644 index 00000000..c9e3cbd5 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrices.hpp @@ -0,0 +1,49 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRICES_INCLUDE +#define MTL_MATRICES_INCLUDE + +#include <boost/numeric/mtl/matrix/dense2D.hpp> +#include <boost/numeric/mtl/matrix/morton_dense.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/mtl/matrix/sparse_banded.hpp> +#include <boost/numeric/mtl/matrix/multi_vector.hpp> +#include <boost/numeric/mtl/matrix/multi_vector_range.hpp> +#include <boost/numeric/mtl/matrix/element_matrix.hpp> +#include <boost/numeric/mtl/matrix/element.hpp> +#include <boost/numeric/mtl/matrix/implicit_dense.hpp> +#include <boost/numeric/mtl/matrix/block_diagonal2D.hpp> +#include <boost/numeric/mtl/matrix/ell_matrix.hpp> +#include <boost/numeric/mtl/matrix/coordinate2D.hpp> + +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/mtl/matrix/shifted_inserter.hpp> +#include <boost/numeric/mtl/matrix/mapped_inserter.hpp> + +#include <boost/numeric/mtl/matrix/map_view.hpp> +#include <boost/numeric/mtl/matrix/transposed_view.hpp> +#include <boost/numeric/mtl/matrix/hermitian_view.hpp> +#include <boost/numeric/mtl/matrix/banded_view.hpp> +#include <boost/numeric/mtl/matrix/indirect.hpp> + +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/matrix/laplacian_setup.hpp> +#include <boost/numeric/mtl/matrix/hessian_setup.hpp> +#include <boost/numeric/mtl/matrix/poisson2D_dirichlet.hpp> +#include <boost/numeric/mtl/matrix/identity2D.hpp> + +#include <boost/numeric/mtl/recursion/predefined_masks.hpp> + +#include <boost/numeric/mtl/utility/matrix_type_generator.hpp> + +#endif // MTL_MATRICES_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/all_mat_expr.hpp b/install/MTL/include/boost/numeric/mtl/matrix/all_mat_expr.hpp new file mode 100644 index 00000000..6677d89b --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/all_mat_expr.hpp @@ -0,0 +1,28 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ALL_MAT_EXPR_INCLUDE +#define MTL_ALL_MAT_EXPR_INCLUDE + +#include <boost/numeric/mtl/matrix/mat_expr.hpp> +#include <boost/numeric/mtl/matrix/mat_mat_minus_expr.hpp> +#include <boost/numeric/mtl/matrix/mat_mat_plus_expr.hpp> +#include <boost/numeric/mtl/matrix/mat_mat_times_expr.hpp> +#include <boost/numeric/mtl/matrix/mat_mat_ele_times_expr.hpp> +#include <boost/numeric/mtl/matrix/mat_mat_asgn_expr.hpp> +#include <boost/numeric/mtl/matrix/mat_negate_expr.hpp> + +#if 0 +#include <boost/numeric/mtl/matrix/mat_mat_plus_asgn_expr.hpp> +#endif + +#endif // MTL_ALL_MAT_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/banded_view.hpp b/install/MTL/include/boost/numeric/mtl/matrix/banded_view.hpp new file mode 100644 index 00000000..03a215f2 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/banded_view.hpp @@ -0,0 +1,262 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_BANDED_VIEW_INCLUDE +#define MTL_MATRIX_BANDED_VIEW_INCLUDE + +#include <utility> +#include <boost/shared_ptr.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/parameters.hpp> +#include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp> +#include <boost/numeric/mtl/matrix/base_matrix.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> +#include <boost/numeric/mtl/matrix/mat_expr.hpp> +#include <boost/numeric/mtl/matrix/map_view.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> + + +// Is not mutable because masking out some values forbids returning references +// +// Arbitrary combinations with other views (using shared_ptr) is planned + +namespace mtl { namespace mat { + +// Forward +namespace detail { + template <typename> struct banded_value; + template <typename, typename> struct mapped_value; +} + + +template <typename Matrix> +struct banded_view + : public const_crtp_base_matrix< banded_view<Matrix>, + typename Matrix::value_type, typename Matrix::size_type >, + public mat_expr< banded_view<Matrix> >, + public base_matrix<typename Matrix::value_type, + typename mtl::traits::parameters<Matrix>::type> +{ + typedef banded_view self; + typedef mat_expr< self > expr_base; + typedef typename mtl::traits::parameters<Matrix>::type parameters; + + typedef base_matrix<typename Matrix::value_type, parameters> base; + + typedef Matrix other; + typedef typename Matrix::orientation orientation; + typedef typename Matrix::index_type index_type; + // typedef typename Matrix::parameters parameters; + + typedef typename Matrix::value_type value_type; + typedef typename Matrix::const_reference const_reference; + + typedef typename Matrix::key_type key_type; + typedef typename Matrix::size_type size_type; + typedef typename Matrix::dim_type dim_type; + + typedef long int bsize_type; + + banded_view(const other& ref, bsize_type begin, bsize_type end) + : base(dim_type(mtl::mat::num_rows(ref), mtl::mat::num_cols(ref)), ref.nnz()), + ref(ref), begin(begin), end(end) + {} + + banded_view(const boost::shared_ptr<Matrix>& p, bsize_type begin, bsize_type end) + : base(dim_type(mtl::mat::num_rows(*p), mtl::mat::num_cols(*p)), p->nnz()), + my_copy(p), ref(*p), begin(begin), end(end) + {} + +#ifdef MTL_WITH_CPP11_MOVE + banded_view (self&& that) : my_copy(std::move(that.my_copy)), ref(that.ref), begin(that.begin), end(that.end) {} + banded_view (const self& that) : ref(that.ref), begin(that.begin), end(that.end) { assert(that.my_copy.use_count() == 0); } +#endif + + value_type operator() (size_type r, size_type c) const + { + using math::zero; + bsize_type bc= static_cast<bsize_type>(c), br= static_cast<bsize_type>(r), + band= bc - br; + // Need value to return correct zero as well (i.e. matrices itself) + value_type v= ref(r, c); + return begin <= band && band < end ? v : zero(v); + } + + // need const functions + bsize_type get_begin() const { return begin; } + bsize_type get_end() const { return end; } + + template <typename> friend struct detail::banded_value; + template <typename, typename> friend struct detail::map_value; + //template <typename> friend struct ::mtl::sub_matrix_t<self>; + + friend size_type inline num_rows(const self& A) + { using mtl::mat::num_rows; return num_rows(A.ref); } + friend size_type inline num_cols(const self& A) + { using mtl::mat::num_cols; return num_cols(A.ref); } + + protected: + boost::shared_ptr<Matrix> my_copy; + public: + const other& ref; + bsize_type begin, end; +}; + +template <typename Matrix> +inline std::size_t size(const banded_view<Matrix>& A) +{ + return num_rows(A) * num_rows(A); +} + +// ========== +// Sub matrix +// ========== + +template <typename Matrix> +struct sub_matrix_t< mtl::mat::banded_view<Matrix> > +{ + typedef mtl::mat::banded_view<Matrix> view_type; + + // Mapping of sub-matrix type + typedef typename sub_matrix_t<Matrix>::sub_matrix_type ref_sub_type; + typedef mtl::mat::banded_view<ref_sub_type> const_sub_matrix_type; + typedef mtl::mat::banded_view<ref_sub_type> sub_matrix_type; + typedef typename view_type::size_type size_type; + + sub_matrix_type operator()(view_type const& view, size_type begin_r, size_type end_r, + size_type begin_c, size_type end_c) + { + typedef boost::shared_ptr<ref_sub_type> pointer_type; + + // Submatrix of referred matrix (or view) + // Create a submatrix, whos address will be kept by banded_view + pointer_type p(new ref_sub_type(sub_matrix(view.ref, begin_r, end_r, begin_c, end_c))); + return sub_matrix_type(p, view.begin, view.end); + } +}; + + +}} // namespace mtl::matrix + + + + +namespace mtl { namespace traits { + + using mtl::mat::banded_view; + + template <typename Matrix> + struct row<banded_view<Matrix> > + { + // from map_view + typedef detail::mapped_row<sfunctor::identity<typename Matrix::value_type>, Matrix> type; + }; + + template <typename Matrix> + struct col<banded_view<Matrix> > + { + // from map_view + typedef detail::mapped_col<sfunctor::identity<typename Matrix::value_type>, Matrix> type; + }; + + namespace detail { + + template <typename Matrix> + struct banded_value + { + typedef typename Matrix::key_type key_type; + typedef typename Matrix::value_type value_type; + typedef banded_view<Matrix> view_type; + + banded_value(view_type const& view) + : view(view), its_row(view.ref), its_col(view.ref), its_value(view.ref) + {} + + value_type operator() (key_type const& key) const + { + using math::zero; + typedef typename view_type::bsize_type bsize_type; + + bsize_type br= static_cast<bsize_type>(its_row(key)), + bc= static_cast<bsize_type>(its_col(key)), + band= bc - br; + // Need value to return correct zero as well (i.e. matrices itself) + const value_type v= its_value(key); + + return view.get_begin() <= band && band < view.get_end() ? v : zero(v); + } + + protected: + view_type const& view; + typename row<Matrix>::type its_row; + typename col<Matrix>::type its_col; + typename const_value<Matrix>::type its_value; + }; + + } // detail + + template <typename Matrix> + struct const_value<banded_view<Matrix> > + { + typedef detail::banded_value<Matrix> type; + }; + + // ================ + // Range generators + // ================ + + // Use range_generator of original matrix + template <typename Tag, typename Matrix> + struct range_generator<Tag, banded_view<Matrix> > + : public detail::referred_range_generator<banded_view<Matrix>, range_generator<Tag, Matrix> > + {}; + +#if 0 // It is more complicated than this because referred_range_generator returns Matrix's cursor and we + // cannot dispatch on this anymore + template <typename Matrix> + struct range_generator<glas::tag::nz, + typename detail::referred_range_generator<banded_view<Matrix>, range_generator<Tag, Matrix> >::type> + + detail::sub_matrix_cursor<banded_view<Matrix>, glas::tag::row, 2> > + { + typedef range_generator<glas::tag::row, banded_view<Matrix> > collection_type; + typedef range_generator<glas::tag::nz, range_generator<glas::tag::row, Matrix> > other_generator; + static int const level = other_generator::level; + typedef typename other_generator::type type; + + type begin(const collection_type& c) + { + return + + // + typedef typename range_generator<glas::tag::nz, detail::sub_matrix_cursor<Matrix>, glas::tag::row, 2>::type type; +#endif + + + // To disambiguate + template <typename Matrix> + struct range_generator<tag::major, banded_view<Matrix> > + : public detail::referred_range_generator<banded_view<Matrix>, range_generator<tag::major, Matrix> > + {}; + + + + + + +}} // mtl::traits + + +#endif // MTL_MATRIX_BANDED_VIEW_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/bands.hpp b/install/MTL/include/boost/numeric/mtl/matrix/bands.hpp new file mode 100644 index 00000000..e3978bbf --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/bands.hpp @@ -0,0 +1,48 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_BANDS_INCLUDE +#define MTL_MATRIX_BANDS_INCLUDE + +#include <boost/numeric/mtl/matrix/banded_view.hpp> + +namespace mtl { namespace mat { + +namespace traits { + + template <typename Matrix> + struct bands + { + typedef banded_view<Matrix> type; + }; +} + +/// Returns a view of a matrix \p A from diagonal \p begin to \p end +/** The main diagonal is numbered 0; the off-diagonal below the main one is -1. + Accordingly, the off-diagonal above the main is 1. + The parameters \p begin and \p end specify a right-open interval. + For, instance bands(A, -1, 2) yields a tridiagonal matrix. **/ +template <typename Matrix> +typename traits::bands<Matrix>::type +inline bands(const Matrix& A, long begin, long end) +{ + typedef typename traits::bands<Matrix>::type result; + return result(A, begin, end); +} + +} // namespace matrix + + using mat::bands; + +} // namespace mtl + +#endif // MTL_MATRIX_BANDS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/base_matrix.hpp b/install/MTL/include/boost/numeric/mtl/matrix/base_matrix.hpp new file mode 100644 index 00000000..5c48ee98 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/base_matrix.hpp @@ -0,0 +1,190 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_BASE_MATRIX_INCLUDE +#define MTL_BASE_MATRIX_INCLUDE + +#include <algorithm> +#include <boost/static_assert.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/matrix/dimension.hpp> +#include <boost/numeric/mtl/detail/index.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/is_static.hpp> + +namespace mtl { namespace mat { + +/// Base class for other matrices, contains only very simple functionality that is used in all matrices. +template <class Elt, class Parameters> +struct base_matrix +{ + typedef base_matrix self; + typedef Elt value_type; + typedef typename Parameters::orientation orientation; + typedef typename Parameters::index index_type; + typedef typename Parameters::dimensions dim_type; + static bool const on_stack= Parameters::on_stack; + typedef typename Parameters::size_type size_type; + protected: + dim_type dim; ///< # of rows and columns + size_type my_nnz; ///< # of non-zeros, to be set by derived matrix + typedef mtl::traits::is_static<dim_type> static_bool; + + public: + base_matrix(size_type n= 0) : my_nnz(n) {} + + /// Setting dimension + explicit base_matrix(mtl::non_fixed::dimensions d, size_type n= 0) : dim(d), my_nnz(n) {} + + /// Swap base matrix + friend void swap(self& x, self& y) + { + using std::swap; + swap(x.my_nnz, y.my_nnz); + swap(x.dim, y.dim); + } + + /// Either matrix to be changed is uninitialized (i.e. 0x0) or dimensions are equal + /** The matrices with dimension 0 x 0 are considered like stem cells: they can still + change into an arbitrary dimension and are compatible with any other matrix. Once a matrix has a non-trivial dimension + it can be only changed explicitly and is only compatible with matrices of the same dimensionality. **/ + void check_dim(size_type MTL_DEBUG_ARG(num_rows), size_type MTL_DEBUG_ARG(num_cols)) const + { + MTL_DEBUG_THROW_IF(this->num_rows() * this->num_cols() != 0 + && (this->num_rows() != num_rows || this->num_cols() != num_cols), + incompatible_size()); + } + +#if 0 + /** Will fail for fixed::dimension **/ + void change_dim(mtl::non_fixed::dimensions d) { dim= d; } + + template <std::size_t Rows, std::size_t Cols> + void change_dim(mtl::fixed::dimensions<Rows, Cols> d) {} +#endif + + void change_dim(size_type r, size_type c, boost::mpl::false_) { dim= dim_type(r, c); } + void change_dim(size_type r, size_type c, boost::mpl::true_) { check_dim(r, c); } + + void change_dim(size_type r, size_type c) { change_dim(r, c, static_bool()); } + +public: + /// Number of rows + size_type num_rows() const + { + return dim.num_rows(); + } + /// First row taking indexing into account + size_type begin_row() const + { + return index::change_to(index_type(), 0); + } + /// Past-end row taking indexing into account + size_type end_row() const + { + return index::change_to(index_type(), num_rows()); + } + + /// number of colums + size_type num_cols() const + { + return dim.num_cols(); + } + /// First column taking indexing into account + size_type begin_col() const + { + return index::change_to(index_type(), 0); + } + /// Past-end column taking indexing into account + size_type end_col() const + { + return index::change_to(index_type(), num_cols()); + } + + /// Number of non-zeros + size_type nnz() const + { + return my_nnz; + } + + protected: + // dispatched functions for major dimension + size_type dim1(row_major) const + { + return num_rows(); + } + size_type dim1(col_major) const + { + return num_cols(); + } + + // dispatched functions for minor dimension + size_type dim2(row_major) const + { + return num_cols(); + } + size_type dim2(col_major) const + { + return num_rows(); + } + + // Dispatched functions for major + // Trailing _ due to conflicts with macro major + size_type major_(size_type r, size_type, row_major) const + { + return r; + } + size_type major_(size_type, size_type c, col_major) const + { + return c; + } + + public: + /// Major dimension + size_type dim1() const + { + return dim1(orientation()); + } + + /// Minor dimension + size_type dim2() const + { + return dim2(orientation()); + } + + // Returns the row for row_major otherwise the column + // Trailing _ due to conflicts with macro major + size_type major_(size_type r, size_type c) const + { + return major_(r, c, orientation()); + } + + // Returns the row for col_major otherwise the column + // Trailing _ for consistency with major + size_type minor_(size_type r, size_type c) const + { + return major_(c, r, orientation()); + } + + // returns copy of dim + dim_type get_dimensions() const + { + return dim; + } +}; + + + +}} // namespace mtl::matrix + +#endif // MTL_BASE_MATRIX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/base_sub_matrix.hpp b/install/MTL/include/boost/numeric/mtl/matrix/base_sub_matrix.hpp new file mode 100644 index 00000000..bedb9327 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/base_sub_matrix.hpp @@ -0,0 +1,237 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_BASE_SUB_MATRIX_INCLUDE +#define MTL_BASE_SUB_MATRIX_INCLUDE + +#include <algorithm> +#include <boost/static_assert.hpp> +#include <boost/numeric/mtl/matrix/dimension.hpp> +#include <boost/numeric/mtl/detail/index.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> + +namespace mtl { namespace mat { + +// Base class for sub-matrices +// Contains only very simple functionality that is used in all sub-matrices +// But also used in some complete matrices +template <class Elt, class Parameters> +struct base_sub_matrix +{ + typedef Elt value_type; + typedef typename Parameters::orientation orientation; + typedef typename Parameters::index index_type; + typedef typename Parameters::dimensions dim_type; + static bool const on_stack= Parameters::on_stack; + typedef std::size_t size_type; + typedef base_sub_matrix self; + + protected: + size_type my_nnz, // # of non-zeros, to be set by derived matrix (drop maybe?) + my_begin_row, my_end_row, + my_begin_col, my_end_col; + + void constructor_helper(const dim_type& dim) + { + my_begin_row= index::change_to(index_type(), 0); + my_end_row= index::change_to(index_type(), dim.num_rows()); + my_begin_col= index::change_to(index_type(), 0); + my_end_col= index::change_to(index_type(), dim.num_cols()); + my_nnz= 0; + } + + public: + // base_sub_matrix() : my_nnz(0), my_begin_row(0), my_end_row(0), my_begin_col(0), my_end_col(0) {} + + base_sub_matrix() + { + // With no static dimension information, it is by default 0 + constructor_helper(dim_type()); + } + + explicit base_sub_matrix(const dim_type& d) + //explicit base_sub_matrix(mtl::non_fixed::dimensions d) + { + constructor_helper(d); + } + + friend void swap(self& x, self& y) + { + std::swap(x.my_nnz, y.my_nnz); + std::swap(x.my_begin_row, y.my_begin_row); + std::swap(x.my_end_row, y.my_end_row); + std::swap(x.my_begin_col, y.my_begin_col); + std::swap(x.my_end_col, y.my_end_col); + } + + // Either changed matrix is uninitialized (i.e. 0x0) or dimensions are equal + void check_dim(size_type MTL_DEBUG_ARG(num_rows), size_type MTL_DEBUG_ARG(num_cols) ) const + { + MTL_DEBUG_THROW_IF(this->num_rows() * this->num_cols() != 0 + && (this->num_rows() != num_rows || this->num_cols() != num_cols), + incompatible_size()); + } + +protected: + void change_dim(non_fixed::dimensions d) { constructor_helper(d); } + template <std::size_t Rows, std::size_t Cols> + void change_dim(fixed::dimensions<Rows, Cols> d) { check_dim(d.num_rows(), d.num_cols()); } + + + + void change_dim(size_type r, size_type c) { change_dim(dim_type(r, c)); } + + void set_ranges(size_type br, size_type er, size_type bc, size_type ec) + { + MTL_DEBUG_THROW_IF(br > er, range_error("begin row > end row")); + MTL_DEBUG_THROW_IF(bc > ec, range_error("begin column > end column")); + my_begin_row= br; my_end_row= er; my_begin_col= bc; my_end_col= ec; + } + +public: + void check_ranges(size_type MTL_DEBUG_ARG(begin_r), size_type MTL_DEBUG_ARG(end_r), + size_type MTL_DEBUG_ARG(begin_c), size_type MTL_DEBUG_ARG(end_c) ) const + { + MTL_DEBUG_THROW_IF(begin_r < begin_row(), range_error("begin_row out of range")); + // if (end_r > end_row()) std::cout << "end_row out of range\n"; + MTL_DEBUG_THROW_IF(end_r > end_row(), range_error("end_row out of range")); + + MTL_DEBUG_THROW_IF(begin_c < begin_col(), range_error("begin_col out of range")); + MTL_DEBUG_THROW_IF(end_c > end_col(), range_error("end_col out of range")); + } + + explicit base_sub_matrix(size_type br, size_type er, size_type bc, size_type ec) : my_nnz(0) + { + set_ranges(br, er, bc, ec); + } + + // Number of rows + size_type num_rows() const + { + return my_end_row - my_begin_row; + } + + // First row taking indexing into account (already stored as such) + size_type begin_row() const + { + return my_begin_row; + } + + // Past-end row taking indexing into account (already stored as such) + size_type end_row() const + { + return my_end_row; + } + + // Number of columns + size_type num_cols() const + { + return my_end_col - my_begin_col; + } + + // First column taking indexing into account (already stored as such) + size_type begin_col() const + { + return my_begin_col; + } + + // Past-end column taking indexing into account (already stored as such) + size_type end_col() const + { + return my_end_col; + } + + // Number of non-zeros + size_type nnz() const + { + return my_nnz; + } + + protected: + // dispatched functions for major dimension + size_type dim1(row_major) const + { + return num_rows(); + } + + size_type dim1(col_major) const + { + return num_cols(); + } + + // dispatched functions for minor dimension + size_type dim2(row_major) const + { + return num_cols(); + } + + size_type dim2(col_major) const + { + return num_rows(); + } + + // Dispatched functions for major + // Trailing _ due to conflicts with macro major + size_type major_(size_type r, size_type, row_major) const + { + return r; + } + + size_type major_(size_type, size_type c, col_major) const + { + return c; + } + + public: + // return major dimension + size_type dim1() const + { + return dim1(orientation()); + } + + // return minor dimension + size_type dim2() const + { + return dim2(orientation()); + } + + // Returns the row for row_major otherwise the column + // Trailing _ due to conflicts with macro major + size_type major_(size_type r, size_type c) const + { + return major_(r, c, orientation()); + } + + // Returns the row for col_major otherwise the column + // Trailing _ for consistency with major + size_type minor_(size_type r, size_type c) const + { + return major_(c, r, orientation()); + } + + dim_type get_dimensions() const + { + return dim_type(num_rows(), num_cols()); + } + +}; + + +}} // namespace mtl::matrix + +#endif // MTL_BASE_SUB_MATRIX_INCLUDE + + +/* + Question: + - Shall we keep the position in the original matrix? +*/ diff --git a/install/MTL/include/boost/numeric/mtl/matrix/block_diagonal2D.hpp b/install/MTL/include/boost/numeric/mtl/matrix/block_diagonal2D.hpp new file mode 100644 index 00000000..821a4ebc --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/block_diagonal2D.hpp @@ -0,0 +1,255 @@ + +#ifndef MTL_DIST_BLOCK_DIAGONAL2D_INCLUDE +#define MTL_DIST_BLOCK_DIAGONAL2D_INCLUDE + + + +#include <vector> +#include <cassert> +#include <limits> +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/bool.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/mtl/matrix/mat_expr.hpp> + + +namespace mtl { + + namespace mat { + + +/// Block diagonal matrix structure +/** Blocks can be any existing matrix_type in mtl4. **/ +template <typename Matrix> +class block_diagonal2D + : public mat_expr< block_diagonal2D<Matrix> > +{ + public: + + typedef unsigned int size_type; + typedef Matrix block_type; + typedef std::vector<Matrix> block_matrix_type; + typedef std::vector<size_type> index_vector_type; + typedef block_diagonal2D<Matrix> self; + typedef typename Collection<Matrix>::value_type value_type; + + /// Constructor: number or rows and columns and optionally estimated number of blocks + explicit block_diagonal2D(size_type rows, size_type cols, size_type init_size= 0) + : nrows(rows), ncols(cols), nb_blocks(0), my_nnz(0), + min_ind(std::numeric_limits<size_type>::max()), max_ind(std::numeric_limits<size_type>::min()), + compact_heap(0) + { + start_block.reserve(init_size); + end_block.reserve(init_size); + blocks.reserve(init_size); + } + + ~block_diagonal2D() { delete[] compact_heap; } + + /// Returns the global number of rows + size_type num_rows() const { + return nrows ; + } + /// Returns the global number of coluums + size_type num_cols() const { + return ncols ; + } + /// Returns the global number of blocks + size_type num_blocks() const { + return nb_blocks; + } + + /// Minimal index + size_type min_index() const { return min_ind; } + + /// Maximal index + size_type max_index() const { return max_ind; } + + + block_type const& block(size_type i) const + { + MTL_DEBUG_THROW_IF(is_negative(i) || i >= nb_blocks, index_out_of_range()); + return blocks[i]; + } + + /// Insert a block from start x start to end x end + void insert(size_type start, size_type end, const block_type& A) + { + MTL_DEBUG_THROW_IF(start > end, logic_error()); + MTL_DEBUG_THROW_IF(is_negative(start) || end > nrows || end > ncols, index_out_of_range()); + assert(compact_heap == 0); // insertion after make_compact; might be relaxed later + + start_block.push_back(start); + end_block.push_back(end); + blocks.push_back(A); + my_nnz+= A.nnz(); + nb_blocks++; + + if (start < min_ind) + min_ind= start; + if (end > max_ind) + max_ind= end; +#if 0 + boost::mpi::communicator world; + if (world.rank() == 0) { + std::cout << "block_diag.insert " << nb_blocks-1 << "th block: start == " + << start_block << ", end == " << end_block << "block is:\n" + << blocks.back(); + } +#endif + } + + /// Element A[i][j] by summing over all blocks, use only for debugging because it is very slow + value_type operator()(size_type i, size_type j) const + { + value_type s= value_type(0); + for (std::size_t b= 0; b < blocks.size(); ++b) { + size_type st= start_block[b], e= end_block[b]; + if (st <= i && st <= j && i < e && j < e) + s+= blocks[b][i - st][j - st]; + } + return s; + } + + /// Memory of inserted + void make_compact(boost::mpl::true_) + { + assert(compact_heap == 0); // might be relaxed later + + size_type entries= 0; + for (size_type i= 0; i < nb_blocks; i++) + entries+= size(blocks[i]); + compact_heap= new value_type[entries]; + + size_type pos= 0; + for (size_type i= 0; i < nb_blocks; i++) { + size_type s= end_block[i] - start_block[i]; + block_type tmp(s, s, compact_heap + pos); + tmp= blocks[i]; + pos+= size(blocks[i]); + swap(blocks[i], tmp); + } + assert(pos == entries); + } + void make_compact(boost::mpl::false_) {} + + void make_compact() { make_compact(boost::is_same<typename mtl::traits::category<block_type>::type, tag::dense2D>()); } + + /// Number of non-zeros (accumulated over blocks) + size_type nnz() const { return my_nnz; } + + template <typename VectorIn, typename VectorOut> + void add_mult(const VectorIn& x, VectorOut& y) const + { + mtl::vampir_trace<3062> tracer; + MTL_DEBUG_THROW_IF(ncols != size(x) || nrows != size(y), incompatible_size()); + + // set_to_zero(y); + for(size_type i= 0; i < nb_blocks; i++) { + mtl::irange r(start_block[i], end_block[i]); + y[r]+= blocks[i] * x[r]; + } + } + + ///block_diagonal-matrix times cvec + template <typename VectorIn, typename VectorOut> + void mult(const VectorIn& x, VectorOut& y) const + { + mtl::vampir_trace<3062> tracer; + MTL_DEBUG_THROW_IF(ncols != size(x) || nrows != size(y), incompatible_size()); + + set_to_zero(y); + for(size_type i= 0; i < nb_blocks; i++) { + mtl::irange r(start_block[i], end_block[i]); + y[r]= blocks[i] * x[r]; + } + } + + template <typename VectorIn> + struct multiplier + : mtl::vec::assigner<multiplier<VectorIn> > + { + explicit multiplier(const self& P, const VectorIn& x) : P(P), x(x) {} + + template <typename VectorOut> + void assign_to(VectorOut& y) const + { P.mult(x, y); } + + const self& P; + const VectorIn& x; + }; + + + template <typename VectorIn> + multiplier<VectorIn> operator*(const VectorIn& x) // const + { return multiplier<VectorIn>(*this, x); } + + + private: + size_type nrows, ncols, nb_blocks, my_nnz, min_ind, max_ind; + index_vector_type start_block, end_block; + block_matrix_type blocks; + value_type* compact_heap; +}; + +// ================ +// Free functions +// ================ + + +/// Number of rows +template <typename Value> +typename block_diagonal2D<Value>::size_type +inline num_rows(const block_diagonal2D<Value>& matrix) +{ + return matrix.num_rows(); +} + +/// Number of columns +template <typename Value> +typename block_diagonal2D<Value>::size_type +inline num_cols(const block_diagonal2D<Value>& matrix) +{ + return matrix.num_cols(); +} + +/// Size of the matrix, i.e. the number of row times columns +template <typename Value> +typename block_diagonal2D<Value>::size_type +inline size(const block_diagonal2D<Value>& matrix) +{ + return matrix.num_cols() * matrix.num_rows(); +} + +// /// Distributed Vector of start block entrys in the matrix +// template <typename Value> +// typename block_diagonal2D<Value>::index_type +// inline start(const block_diagonal2D<Value>& matrix) +// { +// return matrix.start(); +// } + +// /// Distributed Vector of en block entrys in the matrix +// template <typename Value> +// typename block_diagonal2D<Value>::index_type +// inline end(const block_diagonal2D<Value>& matrix) +// { +// return matrix.end(); +// } + + + + +} // namespace matrix +} // namespace mtl + +#endif // MTL_DIST_BLOCK_DIAGONAL2D_INCLUDE + diff --git a/install/MTL/include/boost/numeric/mtl/matrix/compressed2D.hpp b/install/MTL/include/boost/numeric/mtl/matrix/compressed2D.hpp new file mode 100644 index 00000000..ab18bbfb --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/compressed2D.hpp @@ -0,0 +1,1340 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_COMPRESSED2D_INCLUDE +#define MTL_COMPRESSED2D_INCLUDE + +#include <algorithm> +#include <vector> +#include <map> +#include <cmath> +#include <boost/tuple/tuple.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/if.hpp> + +#include <boost/numeric/linear_algebra/identity.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/config.hpp> +#include <boost/numeric/mtl/utility/common_include.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/maybe.hpp> +#include <boost/numeric/mtl/utility/shrink_stl_vector.hpp> +#include <boost/numeric/mtl/utility/zipped_sort.hpp> +#include <boost/numeric/mtl/detail/base_cursor.hpp> +#include <boost/numeric/mtl/operation/is_negative.hpp> +#include <boost/numeric/mtl/operation/update.hpp> +#include <boost/numeric/mtl/operation/shift_block.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/matrix/base_matrix.hpp> +#include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp> +#include <boost/numeric/mtl/matrix/mat_expr.hpp> +#include <boost/numeric/mtl/matrix/element_matrix.hpp> +#include <boost/numeric/mtl/matrix/element_array.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/operation/compute_factors.hpp> +#include <boost/numeric/mtl/operation/num_rows.hpp> +#include <boost/numeric/mtl/operation/num_cols.hpp> +#include <boost/numeric/mtl/operation/size.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +#ifdef MTL_WITH_INITLIST +# include <initializer_list> +#endif + +#undef major // fight namespace pollution + +namespace mtl { namespace mat { + + +struct compressed_key +{ + typedef std::size_t size_t; + typedef compressed_key self; + + template <typename Elt, typename Parameters> + explicit compressed_key(compressed2D<Elt, Parameters> const& matrix, size_t offset) : offset(offset) + { + std::size_t my_major= matrix.indexer.find_major(matrix, offset); + major= my_major; + } + + template <typename Elt, typename Parameters> + explicit compressed_key(compressed2D<Elt, Parameters> const& matrix, size_t r, size_t c) + { + offset= matrix.indexer(matrix, r, c).value(); + major= matrix.indexer.major_minor_c(matrix, r, c).first; + } + + compressed_key(compressed_key const& other) { offset= other.offset; major= other.major; } + + self& operator= (self const& other) + { + offset= other.offset; major= other.major; + return *this; + } + + bool operator== (compressed_key const& other) const + { + //if (offset == other.offset && major != other.major) + // std::cout << offset << " " << other.offset << " " << major << " " << other.major << '\n'; + // The following tests doesn't hold everywhere (anymore) + // MTL_DEBUG_THROW_IF(offset == other.offset && major != other.major, logic_error("equal offsets imply equal major")); + return offset == other.offset; + } + + bool operator!= (compressed_key const& other) const { return !(*this == other); } + + size_t major; + size_t offset; +}; + + +// Cursor over every element +template <typename Elt, typename Parameters> +struct compressed_el_cursor + : public compressed_key +{ + typedef Elt value_type; + typedef compressed_key base; + typedef compressed_el_cursor self; + typedef std::size_t size_t; + + explicit compressed_el_cursor(compressed2D<Elt, Parameters> const& matrix, size_t r, size_t c) + : base(matrix, r, c), matrix(matrix) {} + + explicit compressed_el_cursor(compressed2D<Elt, Parameters> const& matrix, size_t offset) + : base(matrix, offset), matrix(matrix) {} + + compressed_el_cursor(const compressed_el_cursor<Elt, Parameters>& other) + : base(other), matrix(other.matrix) {} + + self& operator= (self const& other) { base::operator=(other); return *this; } + + self& operator++ () + { + ++offset; + MTL_DEBUG_THROW_IF(matrix.starts[major+1] < offset, runtime_error("Inconsistent incrementation!")); + while (major < matrix.starts.size()-1 && matrix.starts[major+1] == offset) + ++major; + return *this; + } + + base& operator* () { return *this; } + const base& operator* () const { return *this; } + + compressed2D<Elt, Parameters> const& matrix; +}; + + +// Cursor over every element +template <typename Elt, typename Parameters> +struct compressed_minor_cursor + : public compressed_key +{ + typedef Elt value_type; + typedef compressed_key base; + typedef compressed_minor_cursor self; + typedef std::size_t size_t; + + explicit compressed_minor_cursor(mtl::mat::compressed2D<Elt, Parameters> const& matrix, size_t r, size_t c) + : base(matrix, r, c), matrix(matrix) + {} + + explicit compressed_minor_cursor(mtl::mat::compressed2D<Elt, Parameters> const& matrix, size_t offset) + : base(matrix, offset), matrix(matrix) + {} + + compressed_minor_cursor(self const& other) : base(other), matrix(other.matrix) {} + + self& operator= (self const& other) + { base::operator=(other); return *this; } + + self& operator++() { ++offset; return *this; } + self& operator+=(size_t inc) { offset+= inc; return *this; } + self operator+(size_t inc) const { self tmp(*this); tmp+= inc; return tmp; } + + self& operator--() { --offset; return *this; } + base& operator* () { return *this; } + const base& operator* () const { return *this; } + + mtl::mat::compressed2D<Elt, Parameters> const& matrix; +}; + + + + +// Indexing for compressed matrices +template <typename SizeType> +struct compressed2D_indexer +{ + typedef SizeType size_type; + typedef std::pair<size_type, size_type> size_pair; + private: + // helpers for public functions + template <class Matrix> + utilities::maybe<size_type> offset(const Matrix& ma, size_type major, size_type minor) const + { + typedef utilities::maybe<size_type> result_type; + assert(ma.starts[major] <= ma.starts[major+1]); // Check sortedness + assert(ma.starts[major+1] <= ma.my_nnz); // Check bounds of indices + // Now we are save to use past-end addresses as iterators + + // Empty matrices are special cases + if (ma.indices.empty()) + return result_type(0, false); + + const size_type *first = &ma.indices[0] + ma.starts[major], + *last = &ma.indices[0] + ma.starts[major+1]; + // if empty row (or column) return start of next one + if (first == last) + return result_type(first - &ma.indices[0], false); + + const size_type *index= first; + if (last - index <= int(compressed_linear_search_limit)) + while (index != last && *index < minor) ++index; + else + index = std::lower_bound(first, last, minor); + return result_type(index - &ma.indices[0], index != last && *index == minor); + } + + public: + // Returns major and minor index in C style (starting with 0) + template <class Matrix> + size_pair major_minor_c(const Matrix& ma, size_type row, size_type col) const + { + using std::make_pair; + // convert into c indices + typename Matrix::index_type my_index; + size_type my_row= index::change_from(my_index, row), + my_col= index::change_from(my_index, col); + return make_pair(ma.major_(my_row, my_col), ma.minor_(my_row, my_col)); + } + + // Returns the offset if found + // If not found it returns the position where it would be inserted + template <class Matrix> + utilities::maybe<size_type> operator() (const Matrix& ma, size_type row, size_type col) const + { + size_type major, minor; + boost::tie(major, minor) = major_minor_c(ma, row, col); + return offset(ma, major, minor); + } + + // Same as above if internal representation is already known + template <class Matrix> + utilities::maybe<size_type> operator() (const Matrix& ma, size_pair major_minor) const + { + return offset(ma, major_minor.first, major_minor.second); + } + + // For a given offset the minor can be accessed directly, the major dim has to be searched + // Returned in internal (c) representation + template <class Matrix> + size_type find_major(const Matrix& ma, size_type offset) const + { + MTL_DEBUG_THROW_IF(ma.starts.empty(), logic_error("Major vector can't be empty")); + size_type my_major= std::upper_bound(ma.starts.begin(), ma.starts.end(), offset) - ma.starts.begin(); + return --my_major; + } + + template <class Matrix> + size_type minor_from_offset(const Matrix& ma, size_type offset) const + { + typedef typename Matrix::index_type my_index; + return index::change_to(my_index(), ma.indices[offset]); + } + +}; // compressed2D_indexer + + +/// Compressed 2D matrix type +// For now no external data +template <typename Elt, typename Parameters = mat::parameters<> > +class compressed2D + : public base_matrix<Elt, Parameters>, + public const_crtp_base_matrix< compressed2D<Elt, Parameters>, Elt, typename Parameters::size_type >, + public crtp_matrix_assign< compressed2D<Elt, Parameters>, Elt, typename Parameters::size_type >, + public mat_expr< compressed2D<Elt, Parameters> > +{ + typedef std::size_t size_t; + typedef base_matrix<Elt, Parameters> super; + typedef compressed2D self; + typedef mat_expr< compressed2D<Elt, Parameters> > expr_base; + + // Only allocation of new data, doesn't copy if already existent + void allocate(size_t new_nnz) + { + if (new_nnz) { + this->my_nnz = new_nnz; + data.resize(this->my_nnz); + indices.resize(this->my_nnz, 0); + } + } + + public: + typedef Parameters parameters; + typedef typename Parameters::orientation orientation; + typedef typename Parameters::index index_type; + typedef typename Parameters::dimensions dimensions; + typedef Elt value_type; + typedef compressed_key key_type; + // const value_type& isn't defined everywhere + typedef value_type const_reference; + + typedef typename Parameters::size_type size_type; + typedef crtp_matrix_assign<self, Elt, size_type> assign_base; + typedef compressed2D_indexer<size_type> indexer_type; + + void check() const { MTL_DEBUG_THROW_IF(inserting, access_during_insertion()); } + + /// Removes all values; e.g. for set_to_zero + void make_empty() + { + check(); + this->my_nnz = 0; + data.resize(0); + indices.resize(0); + std::fill(starts.begin(), starts.end(), 0); + } + + /// Change dimension of the matrix; data get lost. + void change_dim(size_type r, size_type c) + { + check(); + if (this->num_rows() != r || this->num_cols() != c) { + super::change_dim(r, c); + starts.resize(this->dim1()+1); + make_empty(); + } + } + + /// Sets nnz and resizes indices and data + void set_nnz(size_type n) + { + check(); + indices.resize(n); + data.resize(n); + this->my_nnz= n; + } + + // if compile time matrix size, we can set the start vector + /// Default constructor + explicit compressed2D () : inserting(false) + { + if (super::dim_type::is_static) starts.resize(super::dim1() + 1); + } + + + /// Setting dimension and allocate starting vector + explicit compressed2D (mtl::non_fixed::dimensions d, size_t nnz = 0) + : super(d), inserting(false) + { + starts.resize(super::dim1() + 1, 0); + allocate(nnz); + } + + /// Setting dimension and allocate starting vector + explicit compressed2D (size_type num_rows, size_type num_cols, size_t nnz = 0) + : super(non_fixed::dimensions(num_rows, num_cols)), inserting(false) + { + starts.resize(super::dim1() + 1, 0); + allocate(nnz); + } + + /// Initializing matrix from 3 arrays: \p Major, \p Minor,\p Entries. + /** For a row-major matrix Major shall contain the ranges of rows and Minor the column-indices. + This function is for advanced users only and should be used with care: + errors can lead to inconsistent matrices and segmentation faults. + **/ + compressed2D (size_type m, size_type n, size_type nnz, + size_type* Major, size_type* Minor, value_type* Entries) + : super(non_fixed::dimensions(m, n)), inserting(false) + { + allocate(nnz); + + data.assign(Entries, Entries + nnz); + starts.assign(Major, Major + super::dim1() + 1); + indices.assign(Minor, Minor + nnz); + } + + // Default is faster !!! Only used with move constructor and without defaults +#if !defined(MTL_WITH_DEFAULTIMPL) && defined(MTL_WITH_MOVE) + /// Copy constructor (just in case that is not generated by all compilers (generic matrix copy slower)) + compressed2D(const self& src) + : super(src), data(src.data), + starts(src.starts), indices(src.indices), inserting(false) + {} +#endif + + /// Copy from other types + template <typename MatrixSrc> + explicit compressed2D (const MatrixSrc& src) : inserting(false) + { + if (super::dim_type::is_static) starts.resize(super::dim1() + 1); + *this= src; + } + +#ifdef MTL_WITH_MOVE + compressed2D(self&& src) + { swap(*this, src); } +#endif + +#if defined(MTL_WITH_INITLIST) && defined(MTL_WITH_AUTO) && defined(MTL_WITH_RANGEDFOR) + /// Constructor for initializer list \p values + template <typename Value2> + compressed2D(std::initializer_list<std::initializer_list<Value2> > values) + : super(mtl::non_fixed::dimensions(values.size(), values.size()? values.begin()->size() : 0)), + inserting(false) + { + starts.resize(super::dim1() + 1, 0); + allocate(super::dim1() * super::dim2()); + *this= values; + } +#endif + +#ifdef MTL_WITH_DEFAULTIMPL + compressed2D(const compressed2D&) = default; +#endif + +#ifdef MTL_WITH_MOVE + self& operator=(self&& src) + { + // std::cout << "I am moving !!!\n"; + check(); + this->checked_change_dim(src.num_rows(), src.num_cols()); + swap(*this, src); + return *this; + } + + self& operator=(const self& src) + { + if (this == &src) + return *this; + check(); + this->checked_change_dim(src.num_rows(), src.num_cols()); + set_nnz(src.nnz()); + + starts= src.starts; + indices= src.indices; + data= src.data; + return *this; + } +#else + /// Consuming assignment operator (without move semantics) + self& operator=(self src) + { + assert(this != &src); // Self-copy would be an indication of an error + + check(); + // TODO Check the following line + this->checked_change_dim(src.num_rows(), src.num_cols()); + swap(*this, src); + return *this; + } +#endif + + using assign_base::operator=; + +#if 0 + void self_copy(const self& src) + { + if (this == &src) + return; + change_dim(num_rows(src), num_cols(src)); + set_nnz(src.nnz()); + + #ifdef MTL_WITH_OPENMP + # pragma omp parallel for schedule(static, 16) + #endif + for (int i= 0; i < int(src.dim1()); i++) { + const size_type cj0= src.starts[i], cj1= src.starts[i+1]; + starts[i]= cj0; + for (size_type j0= cj0; j0 != cj1; ++j0) { + indices[j0]= src.indices[j0]; + data[j0]= src.data[j0]; + } + } + starts[src.dim1()]= src.starts[src.dim1()]; + } +#endif + + /// Copy the pattern of matrix \p src + /** Advanced feature. Not generic, i.e. does not exist for all matrix types. + value_type of \p src and target can be different. + Changes dimension of target to that of \p src. + Existing entries are deleted. **/ + template <typename Src> + void copy_pattern(const Src& src) + { + using std::copy; + change_dim(num_rows(src), num_cols(src)); + copy(src.ref_major().begin(), src.ref_major().end(), starts.begin()); + + set_nnz(src.ref_minor().size()); + copy(src.ref_minor().begin(), src.ref_minor().end(), indices.begin()); + } + + void make_symmetric_pattern() + { + MTL_THROW_IF(this->num_cols() != this->num_rows(), matrix_not_square()); + self A(*this); + { + using math::zero; + inserter<self> ins(A, 2 * this->nnz() / this->dim1()); + + typename traits::row<self>::type row(*this); + typename traits::col<self>::type col(*this); + typename traits::const_value<self>::type value(*this); + typedef typename traits::range_generator<mtl::tag::major, self>::type cursor_type; + for (cursor_type cursor = mtl::begin<mtl::tag::major>(*this), cend = mtl::end<mtl::tag::major>(*this); + cursor != cend; ++cursor) { + typedef mtl::tag::nz inner_tag; + typedef typename traits::range_generator<inner_tag, cursor_type>::type icursor_type; + for (icursor_type icursor = mtl::begin<inner_tag>(cursor), icend = mtl::end<inner_tag>(cursor); icursor != icend; ++icursor) { + size_type r= row(*icursor), c= col(*icursor); + if (!indexer(*this, c, r)) + ins[c][r] << zero(value(*icursor)); + } + } + } + swap(*this, A); + } + + + // Copies range of values and their coordinates into compressed matrix + // For brute force initialization, should be used with uttermost care + // Won't be suitable for distributed matrices, take care of this to this later + template <typename ValueIterator, typename StartIterator, typename IndexIterator> + void raw_copy(ValueIterator first_value, ValueIterator last_value, + StartIterator first_start, IndexIterator first_index) + { + using std::copy; + + // check if starts has right size + allocate(last_value - first_value); // ???? + // check if nnz and indices has right size + + copy(first_value, last_value, data.begin()); + copy(first_start, first_start + this->dim1() + 1, starts.begin()); + copy(first_index, first_index + this->nnz(), indices.begin()); + } + + /// Value of matrix entry + const_reference operator() (size_type row, size_type col) const + { + using math::zero; + check(); MTL_DEBUG_THROW_IF(is_negative(row) || row >= this->num_rows() || is_negative(col) || col >= this->num_cols(), index_out_of_range()); + utilities::maybe<size_type> pos = indexer(*this, row, col); + return pos ? data[pos.value()] : zero(value_type()); + } + + /// L-value reference of stored matrix entry + /** To be used with care; in debug mode, exception is thrown if entry is not found **/ + value_type& lvalue(size_type row, size_type col) + { + utilities::maybe<size_type> pos = indexer(*this, row, col); + check(); MTL_DEBUG_THROW_IF(!pos, logic_error("This entry does not exist in the matrix")); + return data[pos.value()]; + } + + // For internal use + const value_type& value_from_offset(size_type offset) const + { + check(); MTL_DEBUG_THROW_IF(offset >= this->my_nnz, index_out_of_range("Offset larger than matrix")); + return data[offset]; + } + + value_type& value_from_offset(size_type offset) + { + check(); MTL_DEBUG_THROW_IF(offset >= this->my_nnz, index_out_of_range("Offset larger than matrix")); + return data[offset]; + } + + /// Swap matrices + friend void swap(self& matrix1, self& matrix2) + { + using std::swap; + swap(static_cast<super&>(matrix1), static_cast<super&>(matrix2)); + + swap(matrix1.data, matrix2.data); + swap(matrix1.starts, matrix2.starts); + swap(matrix1.indices, matrix2.indices); + swap(matrix1.inserting, matrix2.inserting); + } + + /// Remove zero entries + void crop() + { + check(); + if (data.empty()) return; + + using math::zero; + value_type z= zero(data[0]); + size_type nzi= 0; // Where to copy next non-zero + + std::vector<size_type> new_starts(this->dim1() + 1); + new_starts[0] = 0; + + for (size_type i = 0; i < this->dim1(); i++) { + for (size_type j= starts[i], end= starts[i+1]; j != end; ++j) + if (data[j] != z) + indices[nzi]= indices[j], data[nzi++]= data[j]; + new_starts[i+1]= nzi; + } + this->my_nnz= nzi; + data.resize(nzi); + indices.resize(nzi); + swap(starts, new_starts); + } + + + /// Address of first major index; to be used with care. [advanced] + size_type* address_major() { check(); return &starts[0]; } + /// Address of first major index; to be used with care. [advanced] + const size_type* address_major() const { check(); return &starts[0]; } + /// Address of first minor index; to be used with care. [advanced] + size_type* address_minor() { check(); return &indices[0]; } + /// Address of first minor index; to be used with care. [advanced] + const size_type* address_minor() const { check(); return &indices[0]; } + /// Address of first data entry; to be used with care. [advanced] + value_type* address_data() { check(); return &data[0]; } + /// Address of first data entry; to be used with care. [advanced] + const value_type* address_data() const { check(); return &data[0]; } + + const std::vector<size_type>& ref_major() const { return starts; } ///< Refer start vector [advanced] + std::vector<size_type>& ref_major() { return starts; } ///< Refer start vector [advanced] + const std::vector<size_type>& ref_minor() const { return indices; } ///< Refer index vector [advanced] + std::vector<size_type>& ref_minor() { return indices; } ///< Refer index vector [advanced] + + /// Release unused space in STL vectors + void shrink() + { + shrink_stl_vector(data); + shrink_stl_vector(starts); + shrink_stl_vector(indices); + } + + /// Number of non-zeros in row/column \p r_or_c when matrix is row-/column-major + size_type nnz_local(size_type r_or_c) const + { + MTL_DEBUG_THROW_IF(r_or_c >= this->dim1(), index_out_of_range()); + return starts[r_or_c+1] - starts[r_or_c]; + } + + template <typename> friend struct compressed2D_indexer; + template <typename, typename, typename> friend struct compressed2D_inserter; + template <typename, typename> friend struct compressed_el_cursor; + template <typename, typename> friend struct compressed_minor_cursor; + + indexer_type indexer; + std::vector<value_type> data; + protected: + std::vector<size_type> starts; + std::vector<size_type> indices; + bool inserting; +}; + + + +// ======== +// Inserter +// ======== + +/// Additional data structure to insert entries into a compressed2D matrix +template <typename Elt, typename Parameters, typename Updater = mtl::operations::update_store<Elt> > +struct compressed2D_inserter +{ + typedef compressed2D_inserter self; + typedef compressed2D<Elt, Parameters> matrix_type; + typedef typename matrix_type::size_type size_type; + typedef typename matrix_type::value_type value_type; + typedef std::pair<size_type, size_type> size_pair; + typedef std::map<size_pair, value_type> map_type; + typedef operations::update_proxy<self, size_type> proxy_type; + + private: + // stretch matrix rows or columns to slot size (or leave it if equal or greater) + void stretch(); + + struct bracket_proxy + { + bracket_proxy(self& ref, size_type row) : ref(ref), row(row) {} + + proxy_type operator[](size_type col) { return proxy_type(ref, row, col); } + + self& ref; + size_type row; + }; + + protected: + void finish() + { + // std::cout << "~compressed2D_inserter: " << matrix.my_nnz << " entries in matrix already (reserved for " << elements.size() + // << ") and " << spare.size() << " entries in map.\n"; + vampir_trace<3051> tracer; + if (num_rows(matrix) > 0 && num_cols(matrix) > 0) { + final_place(); + insert_spare(); + } + matrix.inserting = false; + } + + public: + /// Construction with matrix reference and optional slot size, see \ref matrix_insertion + explicit compressed2D_inserter(matrix_type& matrix, size_type slot_size = 5) + : matrix(matrix), elements(matrix.data), starts(matrix.starts), indices(matrix.indices), + slot_size(std::min(slot_size, matrix.dim2())), slot_ends(matrix.dim1()+1) + { + vampir_trace<3050> tracer; + MTL_THROW_IF(matrix.inserting, runtime_error("Two inserters on same matrix")); + matrix.inserting = true; + if (size(matrix) > 0) + stretch(); + } + + ~compressed2D_inserter() + { + // Check if finish wasn't called explicitly before + if (matrix.inserting) + finish(); + } + + /// Proxy to insert into A[row][col] + bracket_proxy operator[] (size_type row) + { + return bracket_proxy(*this, row); + } + + /// Proxy to insert into A[row][col] + proxy_type operator() (size_type row, size_type col) + { + return proxy_type(*this, row, col); + } + + /// Modify A[row][col] with \p val using \p Modifier + template <typename Modifier> + void modify(size_type row, size_type col, value_type val); + + /// Modify A[row][col] with \p val using the class' updater + void update(size_type row, size_type col, value_type val) + { + using math::zero; + modify<Updater>(row, col, val); + } + + /// For debugging only; print entries in all slots; ignores entries in spare map [advanced] + void print() const + { + for (size_type j= 0; j < matrix.dim1(); j++) + print(j); + } + + /// For debugging only; print entries in slot; ignores entries in spare map [advanced] + void print(size_type i) const + { + std::cout << "in slot " << i << ": "; + for (size_type j= starts[i]; j < slot_ends[i]; ++j) + std::cout << "[" << indices[j] << ": " << elements[j] << "]"; + std::cout << "\n"; + } + + /// Empties slot i (row or column according to orientation); for experts only [advanced] + /** Does not work if entries are in spare map !!!! **/ + void make_empty(size_type i) + { slot_ends[i]= starts[i]; } + + /// Value in A[r][c] + value_type value(size_type r, size_type c) const + { + size_pair mm= matrix.indexer.major_minor_c(matrix, r, c); + utilities::maybe<size_type> offset= matrix_offset(mm); + return offset ? matrix.data[offset.value()] : value_type(0); + } + + /// Insert \p elements into %matrix with pre-sorting + /** It should be faster for sufficiently large element matrices but our benchmarks showed the opposite. **/ + template <typename Matrix, typename Rows, typename Cols> + self& sorted_block_insertion(const element_matrix_t<Matrix, Rows, Cols>& elements); + + /// Insert \p elements into %matrix + template <typename Matrix, typename Rows, typename Cols> + self& operator<< (const element_matrix_t<Matrix, Rows, Cols>& elements) + { + using mtl::size; +#if 0 // shouldn't be slower now + if (size(elements.cols) > sorted_block_insertion_limit + && boost::is_same<typename Parameters::orientation, row_major>::value) + return sorted_block_insertion(elements); +#endif + + for (unsigned ri= 0; ri < size(elements.rows); ri++) + for (unsigned ci= 0; ci < size(elements.cols); ci++) + update (elements.rows[ri], elements.cols[ci], elements.matrix(ri, ci)); + return *this; + } + + /// Insert \p elements into %matrix + template <typename Matrix, typename Rows, typename Cols> + self& operator<< (const element_array_t<Matrix, Rows, Cols>& elements) + { + using mtl::size; + for (unsigned ri= 0; ri < size(elements.rows); ri++) + for (unsigned ci= 0; ci < size(elements.cols); ci++) + update (elements.rows[ri], elements.cols[ci], elements.array[ri][ci]); + return *this; + } + + // not so nice functions needed for direct access, e.g. in factorizations + std::vector<size_type> const& ref_major() const { return starts; } ///< Refer start vector [advanced] + std::vector<size_type> const& ref_minor() const { return indices; } ///< Refer index vector [advanced] + std::vector<size_type> const& ref_slot_ends() const { return slot_ends; } ///< Refer slot-end vector [advanced] + std::vector<value_type> const& ref_elements() const { return elements; } ///< Refer element vector [advanced] + + private: + utilities::maybe<typename self::size_type> matrix_offset(size_pair) const; + void final_place(); + void insert_spare(); + + // Show ith row/column + void display(size_type i) + { + std::cout << "slot " << i << " is ["; + for (size_type j= starts[i]; j < slot_ends[i]; ++j) + std::cout << '(' << indices[j] << ": " << elements[j] << ")" + << (j < slot_ends[i] - 1 ? ", " : ""); + std::cout << "]\n"; + } + + // eliminate double entries in a slot by using the updater + // indices are supposed to be sorted + void reduce_slot(size_type i) + { + size_type tgt= starts[i], src= tgt + 1, end= slot_ends[i]; + for (; src < end;) { + while (src < end && indices[tgt] == indices[src]) + Updater()(elements[tgt], elements[src++]); + ++tgt; + if (tgt == src) + ++src; + else if (src < end && indices[tgt] != indices[src]) { + indices[tgt]= indices[src]; + elements[tgt]= elements[src++]; + if (src >= end) ++tgt; // correction to not remain on the last entry + } + } + slot_ends[i]= tgt; + } + + protected: + compressed2D<Elt, Parameters>& matrix; + std::vector<value_type>& elements; + std::vector<size_type>& starts; + std::vector<size_type>& indices; + size_type slot_size; + std::vector<size_type> slot_ends; + map_type spare; +}; + +template <typename Elt, typename Parameters, typename Updater> +void compressed2D_inserter<Elt, Parameters, Updater>::stretch() +{ + using std::copy; + using std::copy_backward; + using std::swap; + + vampir_trace<3052> tracer; + // Stretching is much simpler for empty matrices + if (elements.empty()) { + for (size_type i= 0, s= 0; i <= matrix.dim1(); i++, s+= slot_size) + slot_ends[i]= starts[i]= s; + size_type new_total= (slot_ends[matrix.dim1()]= starts[matrix.dim1()]) + slot_size; + elements.reserve(new_total); indices.reserve(new_total); + elements.resize(new_total); indices.resize(new_total); + return; + } + + + + // If there are enough existing entries then skip the stretching (expensive) + if (elements.size() + matrix.dim1()/2 > std::size_t(slot_size * matrix.dim1())) { + // Use start of next row/col as slot_ends + copy(starts.begin() + 1, starts.end(), slot_ends.begin()); + slot_ends[matrix.dim1()]= starts[matrix.dim1()]; + return; + } + + std::vector<size_type> new_starts(matrix.dim1() + 1); + new_starts[0] = 0; + for (size_type i = 0; i < matrix.dim1(); i++) { + size_type entries = starts[i+1] - starts[i]; + slot_ends[i] = new_starts[i] + entries; + new_starts[i+1] = new_starts[i] + std::max(entries, slot_size); + } + // Add an additional slot for temporaries + size_type new_total= (slot_ends[matrix.dim1()]= new_starts[matrix.dim1()]) + slot_size; + elements.resize(new_total); + indices.resize(new_total); + // for (int i= 0; i < matrix.dim1()+1; i++) std::cout << "Slot " << i << " is [" << new_starts[i] << ", " << slot_ends[i] << ")\n"; + + // copy normally if not overlapping and backward if overlapping + // i goes down to 1 (not to 0) because i >= 0 never stops for unsigned ;-) + // &v[i] is replaced by &v[0]+i to enable past-end addresses for STL copy + for (size_type i = matrix.dim1(); i > 0; i--) + if (starts[i] <= new_starts[i-1]) { + // std::cout << "Kopiere vorwaerts von " << starts[i-1] << " bis " << starts[i] << " nach " << new_starts[i-1] << "\n"; + copy(&elements[0] + starts[i-1], &elements[0] + starts[i], &elements[0] + new_starts[i-1]); + copy(&indices[0] + starts[i-1], &indices[0] + starts[i], &indices[0] + new_starts[i-1]); + } else { + // std::cout << "Kopiere rueckwaerts von " << starts[i-1] << " bis " << starts[i] << " nach " << slot_ends[i-1] << "\n"; + copy_backward(&elements[0] + starts[i-1], &elements[0] + starts[i], &elements[0] + slot_ends[i-1]); + copy_backward(&indices[0] + starts[i-1], &indices[0] + starts[i], &indices[0] + slot_ends[i-1]); + } + swap(starts, new_starts); +} + +template <typename Elt, typename Parameters, typename Updater> +inline utilities::maybe<typename compressed2D_inserter<Elt, Parameters, Updater>::size_type> +compressed2D_inserter<Elt, Parameters, Updater>::matrix_offset(size_pair mm) const +{ + size_type major, minor; + boost::tie(major, minor) = mm; + + if (indices.empty()) + return utilities::maybe<size_type> (0, false); + + // &v[i] isn't liked by all libs -> &v[0]+i circumvents complaints + const size_type *first = &indices[0] + starts[major], + *last = &indices[0] + slot_ends[major]; + if (first == last) + return utilities::maybe<size_type> (first - &indices[0], false); + + const size_type *index= first; + if (last - index < 10) + while (index != last && *index < minor) ++index; + else + index = std::lower_bound(first, last, minor); + return utilities::maybe<size_type>(index - &indices[0], index != last && *index == minor); +} + + +template <typename Elt, typename Parameters, typename Updater> +template <typename Modifier> +inline void compressed2D_inserter<Elt, Parameters, Updater>::modify(size_type row, size_type col, value_type val) +{ + using std::copy_backward; + MTL_DEBUG_THROW_IF(is_negative(row) || row >= num_rows(matrix) || is_negative(col) || col >= num_cols(matrix), index_out_of_range()); + + Modifier modifier; + compressed2D_indexer<size_type> indexer; + size_pair mm = indexer.major_minor_c(matrix, row, col); + size_type major, minor; + boost::tie(major, minor) = mm; + + utilities::maybe<size_type> pos = matrix_offset(mm); + // Check if already in matrix and update it + if (pos) + modifier (elements[pos.value()], val); + else { + size_type& my_end = slot_ends[major]; + // Check if place in matrix to insert there + if (my_end != starts[major+1]) { + if (pos.value() != my_end) { + copy_backward(&elements[0] + pos.value(), &elements[0] + my_end, &elements[0] + (my_end+1)); + copy_backward(&indices[0] + pos.value(), &indices[0] + my_end, &indices[0] + (my_end+1)); + } + elements[pos.value()] = modifier.init(val); indices[pos.value()] = minor; + my_end++; + matrix.my_nnz++; // new entry + } else { + typename map_type::iterator it = spare.find(mm); + // If not in map insert it, otherwise update the value + if (it == spare.end()) { + spare.insert(std::make_pair(mm, modifier.init(val))); + matrix.my_nnz++; // new entry + } else + modifier(it->second, val); + } + } + // std::cout << "inserter update: " << matrix.my_nnz << " non-zero elements, new value is " << elements[pos] << "\n"; +} + +namespace detail { + + struct cmp_first + { + template <typename F, typename S> + bool operator()(const std::pair<F, S>& x, const std::pair<F, S>& y) const + { + return x.first < y.first; + } + }; +} + +template <typename Elt, typename Parameters, typename Updater> +template <typename Matrix, typename Rows, typename Cols> +compressed2D_inserter<Elt, Parameters, Updater>& +compressed2D_inserter<Elt, Parameters, Updater>::sorted_block_insertion(const element_matrix_t<Matrix, Rows, Cols>& iblock) +{ + using std::copy; using std::copy_backward; using std::min; + using mtl::size; using mtl::num_rows; using mtl::num_cols; + using namespace mtl::utility; + typedef zip_it<size_type, value_type> it_type; + + size_type m= size(iblock.rows), n= size(iblock.cols); + MTL_THROW_IF(m != num_rows(iblock.matrix) || n != num_cols(iblock.matrix), incompatible_size()); + MTL_THROW_IF(&iblock.matrix[0][1] - &iblock.matrix[0][0] != 1, logic_error("Rows must be consecutive")); + + size_type rmax= matrix.dim1(), &index_max0= indices[starts[rmax]]; + value_type& value_max0= elements[starts[rmax]]; + for (size_type i= 0; i < m; i++) { + size_type r= iblock.rows[i], &index_0= indices[starts[r]]; + value_type& value_0= elements[starts[r]]; + if (slot_ends[r] == starts[r]) { + size_type to_copy= min(starts[r+1] - starts[r], n); + copy(&iblock.cols[0], &iblock.cols[0]+to_copy, &index_0); + copy(&iblock.matrix[i][0], &iblock.matrix[i][0]+to_copy, &value_0); + slot_ends[r]= starts[r] + to_copy; + std::sort(it_type(&index_0, &value_0, 0), it_type(&index_0, &value_0, to_copy), less_0()); + reduce_slot(r); + // display(r); + matrix.my_nnz+= slot_ends[r] - starts[r]; + for (size_type j= to_copy; j < n; ++j) + update(r, iblock.cols[j], iblock.matrix[i][j]); + } else { + size_type to_copy= min(slot_size, n); + copy(&iblock.cols[0], &iblock.cols[0]+to_copy, &index_max0); + copy(&iblock.matrix[i][0], &iblock.matrix[i][0]+to_copy, &value_max0); + slot_ends[rmax]= starts[rmax] + to_copy; + std::sort(it_type(&index_max0, &value_max0, 0), it_type(&index_max0, &value_max0, to_copy), less_0()); + size_type tgt= starts[r], tend= slot_ends[r], later= starts[rmax], src= later, end= slot_ends[rmax]; + for (; src < end; ) { + // search for next equal entry in slot r + while (tgt < tend && indices[src] > indices[tgt]) ++tgt; + // reduce equal entries (they are consecutive) + if (tgt < tend) + while (src < end && indices[src] == indices[tgt]) + Updater()(elements[tgt], elements[src++]); + else { // all new entries are larger than the largest existing + for (; src < end && tgt < starts[r+1]; ++src) { // copy at the end of slot + indices[tgt]= indices[src]; + elements[tgt]= elements[src]; + slot_ends[r]= ++tgt; + ++matrix.my_nnz; + } + for (; src < end; ++src) // remainder goes into spare + update(r, indices[src], elements[src]); + later= starts[rmax]; // we're done, avoid postponed loop + } + // collect indices not found in r to deal with later + while (src < end && indices[src] < indices[tgt]) { + if (later != src) { + indices[later]= indices[src]; + elements[later]= elements[src]; + } + ++src; ++later; + } + } + for (size_type j= starts[rmax]; j < later; ++j) + update(r, indices[j], elements[j]); + } + } + return *this; +} + + +template <typename Elt, typename Parameters, typename Updater> +void compressed2D_inserter<Elt, Parameters, Updater>::final_place() +{ + using std::swap; + vampir_trace<3053> tracer; + + size_type dim1 = matrix.dim1(); + std::vector<size_type> new_starts(dim1 + 1); + new_starts[0] = 0; + + if (spare.empty()) { + // Check if everything is already in place + if (slot_ends[dim1-1] == matrix.my_nnz) { + starts[dim1]= slot_ends[dim1-1]; + if (std::size_t(matrix.my_nnz) < elements.size()) + elements.resize(matrix.my_nnz), + indices.resize(matrix.my_nnz); + return; + } + size_type pos= 0; + for (size_type i= 0; i < dim1; ++i) { + new_starts[i]= pos; + for (size_type j= starts[i], je= slot_ends[i]; j < je; ++j, ++pos) { + elements[pos]= elements[j]; + indices[pos]= indices[j]; + } + } + new_starts[dim1]= pos; + swap(new_starts, starts); + if (std::size_t(matrix.my_nnz) < elements.size()) + elements.resize(matrix.my_nnz), + indices.resize(matrix.my_nnz); + return; + } + + typename map_type::iterator it = spare.begin(); + for (size_type i = 0; i < dim1; i++) { + size_type entries = slot_ends[i] - starts[i]; + while (it != spare.end() && it->first.first == i) + entries++, it++; + new_starts[i+1] = new_starts[i] + entries; + } + + size_type new_total = new_starts[dim1], old_total = starts[dim1]; + if (new_total > old_total) { + elements.resize(new_total); + indices.resize(new_total); } + + operations::shift_blocks(dim1, starts, new_starts, slot_ends, elements); + operations::shift_blocks(dim1, starts, new_starts, slot_ends, indices); + + if (std::size_t(new_total) < elements.size()) { + elements.resize(new_total); + indices.resize(new_total); } + + for (size_type i = 0; i < dim1; i++) + slot_ends[i] = new_starts[i] + slot_ends[i] - starts[i]; + + swap(starts, new_starts); +} + +template <typename Elt, typename Parameters, typename Updater> +void compressed2D_inserter<Elt, Parameters, Updater>::insert_spare() +{ + vampir_trace<3054> tracer; + using std::copy_backward; + + for (typename map_type::iterator it = spare.begin(); it != spare.end(); ++it) { + size_pair mm = it->first; + size_type major = mm.first, minor = mm.second; + utilities::maybe<size_type> pos = matrix_offset(mm); + size_type& my_end = slot_ends[major]; + + // &v[i] see above + copy_backward(&elements[0] + pos.value(), &elements[0] + my_end, &elements[0] + (my_end+1)); + copy_backward(&indices[0] + pos.value(), &indices[0] + my_end, &indices[0] + (my_end+1)); + elements[pos.value()] = it->second; indices[pos.value()] = minor; + my_end++; + } +} + +// ================ +// Free functions +// ================ + +template <typename Value, typename Parameters> +typename compressed2D<Value, Parameters>::size_type +inline num_rows(const compressed2D<Value, Parameters>& matrix) +{ + return matrix.num_rows(); +} + +template <typename Value, typename Parameters> +typename compressed2D<Value, Parameters>::size_type +inline num_cols(const compressed2D<Value, Parameters>& matrix) +{ + return matrix.num_cols(); +} + +template <typename Value, typename Parameters> +// typename compressed2D<Value, Parameters>::size_type risks overflow +std::size_t +inline size(const compressed2D<Value, Parameters>& matrix) +{ + return std::size_t(matrix.num_cols()) * std::size_t(matrix.num_rows()); +} + + +}} // namespace mtl::matrix + +namespace mtl { + using mat::compressed2D; +} + +// ================ +// Range generators +// ================ + +namespace mtl { namespace traits { + + // VC 8.0 finds ambiguity with mtl::tag::morton_dense (I wonder why, especially here) + using mtl::mat::compressed2D; + using mtl::mat::compressed_el_cursor; + using mtl::mat::compressed_minor_cursor; + + // =========== + // For cursors + // =========== + + template <class Elt, class Parameters> + struct range_generator<glas::tag::nz, compressed2D<Elt, Parameters> > + : detail::all_offsets_range_generator<compressed2D<Elt, Parameters>, + compressed_el_cursor<Elt, Parameters>, + complexity_classes::linear_cached> + {}; + + // Cursor over all rows + // Supported if row major matrix + template <typename Elt, typename Parameters> + struct range_generator<glas::tag::row, compressed2D<Elt, Parameters> > + : boost::mpl::if_< + boost::is_same<typename Parameters::orientation, row_major> + , detail::all_rows_range_generator<compressed2D<Elt, Parameters>, complexity_classes::linear_cached> + , range_generator<tag::unsupported, compressed2D<Elt, Parameters> > + >::type {}; + + + template <class Elt, class Parameters> + struct range_generator<glas::tag::nz, + detail::sub_matrix_cursor<compressed2D<Elt, Parameters>, glas::tag::row, 2> > + { + typedef typename Collection<compressed2D<Elt, Parameters> >::size_type size_type; + typedef detail::sub_matrix_cursor<compressed2D<Elt, Parameters>, glas::tag::row, 2> cursor_type; + typedef complexity_classes::linear_cached complexity; + typedef compressed_minor_cursor<Elt, Parameters> type; + static int const level = 1; + + type begin(cursor_type const& cursor) const + { + return type(cursor.ref, cursor.key, cursor.ref.begin_col()); + } + type end(cursor_type const& cursor) const + { + return type(cursor.ref, cursor.key, cursor.ref.end_col()); + } + type lower_bound(cursor_type const& cursor, size_type position) const + { + return type(cursor.ref, cursor.key, std::min(position, cursor.ref.end_col())); + } + }; + + // Cursor over all columns + // Supported if column major matrix + template <typename Elt, typename Parameters> + struct range_generator<glas::tag::col, compressed2D<Elt, Parameters> > + : boost::mpl::if_< + boost::is_same<typename Parameters::orientation, col_major> + , detail::all_cols_range_generator<compressed2D<Elt, Parameters>, complexity_classes::linear_cached> + , range_generator<tag::unsupported, compressed2D<Elt, Parameters> > + >::type {}; + + + template <class Elt, class Parameters> + struct range_generator<glas::tag::nz, + detail::sub_matrix_cursor<compressed2D<Elt, Parameters>, glas::tag::col, 2> > + { + typedef typename Collection<compressed2D<Elt, Parameters> >::size_type size_type; + typedef detail::sub_matrix_cursor<compressed2D<Elt, Parameters>, glas::tag::col, 2> cursor_type; + typedef complexity_classes::linear_cached complexity; + typedef compressed_minor_cursor<Elt, Parameters> type; + static int const level = 1; + + type begin(cursor_type const& cursor) const + { + return type(cursor.ref, cursor.ref.begin_row(), cursor.key); + } + type end(cursor_type const& cursor) const + { + return type(cursor.ref, cursor.ref.end_row(), cursor.key); + } + type lower_bound(cursor_type const& cursor, size_type position) const + { + return type(cursor.ref, std::min(position, cursor.ref.end_row()), cursor.key); + } + }; + + // Cursor over all rows or columns, depending which one is major + template <typename Elt, typename Parameters> + struct range_generator<glas::tag::major, compressed2D<Elt, Parameters> > + : boost::mpl::if_< + boost::is_same<typename Parameters::orientation, row_major> + , range_generator<glas::tag::row, compressed2D<Elt, Parameters> > + , range_generator<glas::tag::col, compressed2D<Elt, Parameters> > + >::type {}; + + +// ============= +// For iterators +// ============= + + + template <class Elt, class Parameters> + struct range_generator<tag::const_iter::nz, + detail::sub_matrix_cursor<compressed2D<Elt, Parameters>, glas::tag::row, 2> > + { + typedef compressed2D<Elt, Parameters> matrix_type; + typedef typename matrix_type::size_type size_type; + typedef typename matrix_type::value_type value_type; + typedef detail::sub_matrix_cursor<matrix_type, glas::tag::row, 2> cursor; + + typedef complexity_classes::linear_cached complexity; + static int const level = 1; + typedef const value_type* type; + + type begin(cursor const& c) + { + const matrix_type& matrix= c.ref; + size_type offset= matrix.indexer(matrix, c.key, matrix.begin_col()); + return &matrix.data[0] + offset; + } + + // returned pointer can pass the end and must only be used for comparison + type end(cursor const& c) + { + const matrix_type& matrix= c.ref; + size_type offset= matrix.indexer(matrix, c.key, matrix.end_col()); + return &matrix.data[0] + offset; + } + }; + + + template <class Elt, class Parameters> + struct range_generator<tag::const_iter::nz, + detail::sub_matrix_cursor<compressed2D<Elt, Parameters>, glas::tag::col, 2> > + { + typedef compressed2D<Elt, Parameters> matrix_type; + typedef typename matrix_type::size_type size_type; + typedef typename matrix_type::value_type value_type; + typedef detail::sub_matrix_cursor<matrix_type, glas::tag::col, 2> cursor; + + typedef complexity_classes::linear_cached complexity; + static int const level = 1; + typedef const value_type* type; + + type begin(cursor const& c) + { + const matrix_type& matrix= c.ref; + size_type offset= matrix.indexer(matrix, matrix.begin_row(), c.key); + return &matrix.data[0] + offset; + } + + // returned pointer can pass the end and must only be used for comparison + type end(cursor const& c) + { + const matrix_type& matrix= c.ref; + size_type offset= matrix.indexer(matrix, matrix.end_row(), c.key); + return &matrix.data[0] + offset; + } + }; + + +}} // namespace mtl::traits + + + +#endif // MTL_COMPRESSED2D_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/coordinate2D.hpp b/install/MTL/include/boost/numeric/mtl/matrix/coordinate2D.hpp new file mode 100644 index 00000000..38a8038e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/coordinate2D.hpp @@ -0,0 +1,495 @@ + +#ifndef MTL_COORDINATE2D_INCLUDE +#define MTL_COORDINATE2D_INCLUDE + +#include <vector> +#include <cassert> +#include <boost/mpl/bool.hpp> + + +#include <boost/numeric/mtl/operation/is_negative.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/operation/sort.hpp> +#include <boost/numeric/mtl/operation/iota.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> + +namespace mtl { namespace mat { + + +/// Sparse matrix structure in coordinate format +template <typename Value, typename Parameters = mat::parameters<> > +class coordinate2D + : public base_matrix<Value, Parameters>, + public const_crtp_base_matrix< coordinate2D<Value, Parameters>, Value, typename Parameters::size_type >, + public crtp_matrix_assign< coordinate2D<Value, Parameters>, Value, typename Parameters::size_type >, + public mat_expr< coordinate2D<Value, Parameters> > +{ + public: + typedef Value value_type; + typedef Value& reference; + typedef Value const& const_reference; + typedef typename Parameters::size_type size_type; + typedef typename Parameters::dimensions dim_type; + typedef typename Parameters::orientation orientation; + + typedef coordinate2D self; + typedef base_matrix<Value, Parameters> super; + typedef crtp_matrix_assign<self, Value, size_type> assign_base; + + typedef std::vector< size_type > row_index_array_type ; + typedef std::vector< size_type > column_index_array_type ; + typedef std::vector< value_type > value_array_type ; + + /// Common constructor + explicit coordinate2D(size_type nrows, size_type ncols, size_type expected= 0) + : super(dim_type(nrows, ncols)) + { + if (expected > 0) { + rows.reserve(expected); + cols.reserve(expected); + values.reserve(expected); + } + my_is_sorted= true; + } + + using assign_base::operator=; + + size_type nnz() const { return rows.size(); } ///< Number of non-zeros + + value_array_type const& value_array() const { return values; } ///< Array of values (const) + value_array_type& value_array() { return values; } ///< Array of values (mutable) + + row_index_array_type const& row_index_array() const { return rows; } ///< Array of rows (const) + column_index_array_type const& column_index_array() const { return cols; } ///< Array of columns (const) + + row_index_array_type& row_index_array() { return rows; } ///< Array of rows (mutable) + column_index_array_type& column_index_array() { return cols; } ///< Array of columns (mutable) + + /// Drop all entries + void make_empty() + { + rows.resize(0); cols.resize(0); values.resize(0); + my_is_sorted= true; // haha + } + + /// Insert an entry at the end of the row-,col- and value-array + void push_back(size_type r, size_type c, const_reference v) + { + rows.push_back(r); cols.push_back(c); values.push_back(v); my_is_sorted= false; + } + + /// Insert an entry at the end of the row-,col- and value-array, like push_back + void insert(size_type r, size_type c, const_reference v) { push_back(r, c, v); } + + /// Whether the entries are sorted + bool is_sorted() const { return my_is_sorted; } + + /// sorting standard by rows + void sort() + { + if (nnz() > 0) + sort(mtl::traits::is_row_major<Parameters>()); + my_is_sorted= true; + } + + private: + // sorting by rows + void sort(boost::mpl::true_) + { + mtl::vec::sort_xy(rows, cols, values); + } + + // sorting by columns + void sort(boost::mpl::false_) + { + mtl::vec::sort_xy(cols, rows, values); + } + + template <typename OStream, typename Vector> + void print_stl_vector(OStream& os, const Vector& v) const + { + os << "["; + for (unsigned i= 0; i < v.size(); i++) + os << v[i] << (i+1 < v.size() ? "," : ""); + os << "]\n"; + } + + public: + template <typename OStream> + void print_internal(OStream& os) const + { + os << "rows = "; print_stl_vector(os, rows); + os << "cols = "; print_stl_vector(os, cols); + os << "values = "; print_stl_vector(os, values); + } + + void print_internal() const { print(std::cout); } + + ///operator * for vector= coordinaten-matrix * vector + template <typename Vector > + Vector operator*(const Vector& x) + { + + Vector res(this->num_rows()); + res= 0; + for (size_type i= 0; i < nnz(); i++) + res[rows[i]]+= values[i] * x[cols[i]]; + return res; + } + + value_type operator() (const size_type r, const size_type c) const + { + MTL_DEBUG_THROW_IF(is_negative(r) || r >= this->num_rows() + || is_negative(c) || c >= this->num_cols(), index_out_of_range()); + +#if 0 + if (my_is_sorted) + return find(r, c, mtl::traits::is_row_major<Parameters>()); +#endif + + for (size_type i= 0; i < nnz(); i++) + if (rows[i] == r && cols[i] == c) + return values[i]; + return value_type(0); + } + + template <typename Updater> + void compress(Updater up) + { + if (!my_is_sorted) + sort(); + + size_type i= 0, j= 1, end= rows.size(); + for (; j < end; ++j) + if (rows[i] == rows[j] && cols[i] == cols[j]) { + up(values[i], values[j]); + } else { + i++; + if (i != j) { + rows[i]= rows[j]; + cols[i]= cols[j]; + values[i]= values[j]; + } + } + if (end > 0) i++; + rows.resize(i); + cols.resize(i); + values.resize(i); + } + + template <typename Matrix, typename Updater> friend struct coordinate2D_inserter; + + private: + row_index_array_type rows; + column_index_array_type cols; + value_array_type values; + bool my_is_sorted; +}; + +// ================ +// Free functions +// ================ + + +/// Number of rows +template <typename Value, typename Parameters> +typename coordinate2D<Value, Parameters>::size_type +inline num_rows(const coordinate2D<Value, Parameters>& matrix) +{ + return matrix.num_rows(); +} + +/// Number of columns +template <typename Value, typename Parameters> +typename coordinate2D<Value, Parameters>::size_type +inline num_cols(const coordinate2D<Value, Parameters>& matrix) +{ + return matrix.num_cols(); +} + +/// Size of the matrix, i.e. the number of row times columns +template <typename Value, typename Parameters> +typename coordinate2D<Value, Parameters>::size_type +inline size(const coordinate2D<Value, Parameters>& matrix) +{ + return matrix.num_cols() * matrix.num_rows(); +} + +/// Number of NoZeros of the matrix +template <typename Value, typename Parameters> +typename coordinate2D<Value, Parameters>::size_type +inline nnz(const coordinate2D<Value, Parameters>& matrix) +{ + return matrix.nnz(); +} + + +template <typename Matrix, + typename Updater = mtl::operations::update_store<typename Matrix::value_type> > +struct coordinate2D_inserter +{ + typedef coordinate2D_inserter self; + typedef Matrix matrix_type; + typedef typename matrix_type::size_type size_type; + typedef typename matrix_type::value_type value_type; + typedef operations::update_proxy<self, size_type> proxy_type; + + // We only support storing so far !!! + // STATIC_ASSERT((boost::is_same<Updater, mtl::operations::update_store<value_type> >::value), "We only support storing so far"); + + coordinate2D_inserter(matrix_type& matrix, size_type slot_size= 1) + : matrix(matrix) + { + std::size_t ns= slot_size * matrix.dim1(); + if (ns > matrix.nnz()) { + matrix.rows.reserve(ns); + matrix.cols.reserve(ns); + matrix.values.reserve(ns); + } + } + + ~coordinate2D_inserter() { matrix.compress(Updater()); } + + private: + + struct update_proxy + { + // self is type of inserter not update_proxy !!! + update_proxy(self& ref, size_type row, size_type col) : ref(ref), row(row), col(col) {} + + template <typename Value> + update_proxy& operator<< (Value const& val) + { + ref.matrix.push_back(row, col, val); + return *this; + } + self& ref; + size_type row, col; + }; + + proxy_type operator() (size_type row, size_type col) + { + return proxy_type(*this, row, col); + } + + + struct bracket_proxy + { + bracket_proxy(self& ref, size_type row) : ref(ref), row(row) {} + + proxy_type operator[](size_type col) + { + return proxy_type(ref, row, col); + } + + self& ref; + size_type row; + }; + + public: + + bracket_proxy operator[] (size_type row) + { + return bracket_proxy(*this, row); + } + + template <typename Value> + void update(size_type row, size_type col, Value val) + { + matrix.push_back(row, col, val); + } + + template <typename Modifier, typename Value> + void modify(size_type row, size_type col, Value val) + { + matrix.push_back(row, col, val); + } + + template <typename EMatrix, typename Rows, typename Cols> + self& operator<< (const mat::element_matrix_t<EMatrix, Rows, Cols>& elements) + { + using mtl::size; + for (unsigned ri= 0; ri < size(elements.rows); ri++) + for (unsigned ci= 0; ci < size(elements.cols); ci++) + update (elements.rows[ri], elements.cols[ci], elements.matrix(ri, ci)); + return *this; + } + + template <typename EMatrix, typename Rows, typename Cols> + self& operator<< (const mat::element_array_t<EMatrix, Rows, Cols>& elements) + { + using mtl::size; + for (unsigned ri= 0; ri < size(elements.rows); ri++) + for (unsigned ci= 0; ci < size(elements.cols); ci++) + update (elements.rows[ri], elements.cols[ci], elements.array[ri][ci]); + return *this; + } + + protected: + matrix_type& matrix; +}; + +struct coordinate_key +{ + typedef std::size_t size_t; + + explicit coordinate_key(size_t offset) : offset(offset) {} + + bool operator== (coordinate_key const& other) const { return offset == other.offset; } + bool operator!= (coordinate_key const& other) const { return offset != other.offset; } + + size_t offset; +}; + + +// Cursor over every element +template <typename Value, typename Parameters> +struct coordinate_minor_cursor + : public coordinate_key +{ + typedef coordinate_minor_cursor<Value, Parameters> self; + typedef typename Parameters::size_type size_type; + typedef const coordinate2D<Value, Parameters>& matrix_ref_type; + static const int level= 2; + + coordinate_minor_cursor(matrix_ref_type ref, size_type offset) + : coordinate_key(offset), ref(ref) {} + + bool operator!=(const self& that) const + { + assert(&ref == &that.ref); + return this->offset != that.offset; + } + + self& operator++() { this->offset++; return *this; } + coordinate_key operator*() const { return *this; } + + matrix_ref_type ref; +}; + + +template <typename Value, typename Parameters> +struct coordinate_major_cursor +{ + typedef coordinate_major_cursor<Value, Parameters> self; + typedef typename Parameters::size_type size_type; + typedef const coordinate2D<Value, Parameters>& matrix_ref_type; + typedef coordinate_minor_cursor<Value, Parameters> inner_cursor; + static const int level= 2; + + void find_next_offset(boost::mpl::true_) + { + size_type i= offset; + for ( ; i < nnz(ref) && ref.row_index_array()[i] <= major; i++) ; + next_offset= i; + } + + void find_next_offset(boost::mpl::false_) + { + size_type i= offset; + for ( ; i < nnz(ref) && ref.col_index_array()[i] <= major; i++) ; + next_offset= i; + } + + void find_next_offset() { find_next_offset(mtl::traits::is_row_major<Parameters>()); } + + coordinate_major_cursor(matrix_ref_type ref, size_type major, size_type offset) + : ref(ref), major(major), offset(offset) + { + find_next_offset(); + } + + bool operator!=(const self& that) const + { + assert(&ref == &that.ref); + return this->offset != that.offset; + } + + self& operator++() + { + offset= next_offset; + major++; + find_next_offset(); + return *this; + } + + matrix_ref_type ref; + size_type major, offset, next_offset; +}; + +template <typename Value, typename Parameters> +struct coordinate_minor_range_generator +{ + typedef coordinate_major_cursor<Value, Parameters> outer_cursor_type; + typedef coordinate_minor_cursor<Value, Parameters> type; + static const int level= 2; + + type begin(outer_cursor_type c) const { return type(c.ref, c.offset); } + type end(outer_cursor_type c) const { return type(c.ref, c.next_offset); } +}; + +template <typename Value, typename Parameters> +struct coordinate_row_range_generator +{ + typedef const coordinate2D<Value, Parameters>& matrix_ref_type; + typedef coordinate_major_cursor<Value, Parameters> type; + typedef complexity_classes::linear_cached complexity; + static const int level= 1; + + type begin(matrix_ref_type A) const { return type(A, 0, 0); } + type end(matrix_ref_type A) const { return type(A, num_rows(A), nnz(A)); } +}; + +template <typename Value, typename Parameters> +struct coordinate_col_range_generator +{ + typedef const coordinate2D<Value, Parameters>& matrix_ref_type; + typedef coordinate_major_cursor<Value, Parameters> type; + typedef complexity_classes::linear_cached complexity; + static const int level= 1; + + type begin(matrix_ref_type A) const { return type(A, 0, 0); } + type end(matrix_ref_type A) const { return type(A, num_cols(A), nnz(A)); } +}; + + +}} // namespace mtl::matrix + + +namespace mtl { namespace traits { + + // Cursor over all rows + // Supported if row major matrix + template <typename Value, typename Parameters> + struct range_generator<glas::tag::row, mat::coordinate2D<Value, Parameters> > + : boost::mpl::if_< + boost::is_same<typename Parameters::orientation, row_major> + , mat::coordinate_row_range_generator<Value, Parameters> + , range_generator<tag::unsupported, mat::coordinate2D<Value, Parameters> > + >::type {}; + + template <typename Value, typename Parameters> + struct range_generator<glas::tag::col, mat::coordinate2D<Value, Parameters> > + : boost::mpl::if_< + boost::is_same<typename Parameters::orientation, col_major> + , mat::coordinate_col_range_generator<Value, Parameters> + , range_generator<tag::unsupported, mat::coordinate2D<Value, Parameters> > + >::type {}; + + template <class Value, class Parameters> + struct range_generator<glas::tag::nz, mat::coordinate_major_cursor<Value, Parameters> > + : mat::coordinate_minor_range_generator<Value, Parameters> + {}; + + +}} // namespace mtl::traits + +namespace mtl { + using mat::coordinate2D; +} + +#endif // MTL_COORDINATE2D_INCLUDE + diff --git a/install/MTL/include/boost/numeric/mtl/matrix/crtp_base_matrix.hpp b/install/MTL/include/boost/numeric/mtl/matrix/crtp_base_matrix.hpp new file mode 100644 index 00000000..d81960a5 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/crtp_base_matrix.hpp @@ -0,0 +1,737 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_CRTP_BASE_MATRIX_INCLUDE +#define MTL_CRTP_BASE_MATRIX_INCLUDE + +#include <iostream> +#include <algorithm> +#include <boost/mpl/bool.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/numeric/mtl/operation/print.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/matrix_bracket.hpp> +#include <boost/numeric/mtl/operation/copy.hpp> +#include <boost/numeric/mtl/operation/mult.hpp> +#include <boost/numeric/mtl/operation/right_scale_inplace.hpp> +#include <boost/numeric/mtl/operation/divide_by_inplace.hpp> +#include <boost/numeric/mtl/matrix/all_mat_expr.hpp> +#include <boost/numeric/mtl/matrix/diagonal_setup.hpp> +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/eval_dense.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/utility/iset.hpp> +#include <boost/numeric/mtl/operation/mult_assign_mode.hpp> +#include <boost/numeric/mtl/operation/compute_factors.hpp> +#include <boost/numeric/mtl/operation/column_in_matrix.hpp> +#include <boost/numeric/mtl/operation/row_in_matrix.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +#ifdef MTL_WITH_INITLIST +# include <initializer_list> +#endif + +namespace mtl { namespace mat { + +template <typename Source, typename Matrix> +struct crtp_assign +{ + Matrix& operator()(const Source& source, Matrix& matrix) + { + return assign(source, matrix, typename ashape::ashape<Source>::type()); + } +private: + /// Assign scalar to a matrix by setting the matrix to a multiple of unity matrix + /** Uses internally \sa diagonal_setup, for details see there. **/ + Matrix& assign(const Source& source, Matrix& matrix, ashape::scal) + { + vampir_trace<3055> tracer; + MTL_DEBUG_THROW_IF(num_rows(matrix) * num_cols(matrix) == 0, + range_error("Trying to initialize a 0 by 0 matrix with a value")); + diagonal_setup(matrix, source); + return matrix; + } + + /// Assign matrix expressions by copying except for some special expressions + Matrix& assign(const Source& source, Matrix& matrix, typename ashape::ashape<Matrix>::type) + { + vampir_trace<3056> tracer; + // Self-assignment between different types shouldn't happen. + matrix.checked_change_resource(source); + matrix_copy(source, matrix); + return matrix; + } +}; + + + +/// Assign sum by assigning first argument and adding second +/* Note that this is more special then assigning arbitrary expressions including matrices itself + because mat_mat_plus_expr <E1, E2> is a derived class from mat_expr < MatrixSrc >. **/ +template <typename E1, typename E2, typename Matrix> +struct crtp_assign<mat_mat_plus_expr<E1, E2>, Matrix> +{ + Matrix& operator()(const mat_mat_plus_expr<E1, E2>& src, Matrix& matrix) + { + vampir_trace<3056> tracer; + matrix.checked_change_resource(src.first); + matrix= src.first; + return matrix+= src.second; + } +}; + +/// Assign difference by assigning first argument and subtracting second +/* Note that this is more special then assigning arbitrary expressions including matrices itself + because mat_mat_minus_expr <E1, E2> is a derived class from mat_expr < MatrixSrc >. **/ +template <typename E1, typename E2, typename Matrix> +struct crtp_assign<mat_mat_minus_expr<E1, E2>, Matrix> +{ + Matrix& operator()(const mat_mat_minus_expr<E1, E2>& src, Matrix& matrix) + { + vampir_trace<3057> tracer; + matrix.checked_change_resource(src.first); + matrix= src.first; + return matrix-= src.second; + } +}; + +/// Assign product by calling mult +template <typename E1, typename E2, typename Matrix> +struct crtp_assign<mat_mat_times_expr<E1, E2>, Matrix> +{ + Matrix& operator()(const mat_mat_times_expr<E1, E2>& src, Matrix& matrix) + { + vampir_trace<4012> tracer; + operation::compute_factors<Matrix, mat_mat_times_expr<E1, E2> > factors(src); + matrix.checked_change_resource(factors.first, factors.second); + mult(factors.first, factors.second, matrix); + return matrix; + } +}; + + +/// Assign element-wise product +template <typename E1, typename E2, typename Matrix> +struct crtp_assign<mat_mat_ele_times_expr<E1, E2>, Matrix> +{ + Matrix& operator()(const mat_mat_ele_times_expr<E1, E2>& src, Matrix& matrix) + { + vampir_trace<3028> tracer; + operation::compute_factors<Matrix, mat_mat_ele_times_expr<E1, E2> > factors(src); + matrix.checked_change_resource(factors.first); + matrix= factors.first; + return matrix.ele_rscale(factors.second); + } +}; + + + +/// Assign c-style 2D-array, because it's easier to initialize. +template <typename Value, unsigned Rows, unsigned Cols, typename Matrix> +struct crtp_assign<Value[Rows][Cols], Matrix> +{ + Matrix& operator()(const Value src[Rows][Cols], Matrix& matrix) + { + vampir_trace<3059> tracer; + typedef typename Collection<Matrix>::size_type size_type; + + matrix.checked_change_dim(Rows, Cols); + inserter<Matrix> ins(matrix, matrix.dim2()); + + for (size_type r= 0; r < Rows; ++r) + for (size_type c= 0; c < Cols; ++c) + ins(r, c) << src[r][c]; + return matrix; + } +}; + +#if defined(MTL_WITH_INITLIST) && defined(MTL_WITH_AUTO) && defined(MTL_WITH_RANGEDFOR) + /// Constructor for initializer list \p values + template <typename Value2, typename Matrix> + struct crtp_assign<std::initializer_list<std::initializer_list<Value2> >, Matrix> + { + Matrix& operator()(std::initializer_list<std::initializer_list<Value2> > values, Matrix& matrix) + { + typedef typename Collection<Matrix>::size_type size_type; + size_type nr= values.size(), nc= nr > 0? values.begin()->size() : 0; + matrix.checked_change_dim(nr, nc); + inserter<Matrix> ins(matrix, matrix.dim2()); + + size_t r= 0; + for (auto l : values) { + size_t c= 0; + MTL_THROW_IF(l.size() != nc, logic_error("All sub-lists must have same size!")); + for (auto v : l) + ins(r, c++) << v; + r++; + } + return matrix; + } + }; +#endif + + +template <typename Vector, typename Matrix> +struct crtp_assign<multi_vector<Vector>, Matrix> +{ + Matrix& operator()(const multi_vector<Vector>& src, Matrix& matrix) + { + vampir_trace<3060> tracer; + typedef typename Collection<Matrix>::size_type size_type; + + matrix.checked_change_resource(src); + // del checked_change_dim(num_rows(src), num_cols(src)); + inserter<Matrix> ins(matrix); + + for (size_type r= 0; r < num_rows(src); ++r) + for (size_type c= 0; c < num_cols(src); ++c) + ins(r, c) << src[r][c]; + return matrix; + } +}; + + +/// Assign content of a file to the matrix +template <typename IFStream, typename OFStream, typename Matrix> +struct crtp_assign<io::matrix_file<IFStream, OFStream>, Matrix> +{ + Matrix& operator()(const io::matrix_file<IFStream, OFStream>& file, Matrix& matrix) + { + vampir_trace<3029> tracer; + IFStream stream(file.file_name().c_str()); + stream >> matrix; + return matrix; + } +}; + +/// Assign-add matrix expressions by incrementally copying except for some special expressions +template <typename Source, typename Matrix> +struct crtp_plus_assign +{ + Matrix& operator()(const Source& source, Matrix& matrix) + { + vampir_trace<3030> tracer; + return assign(source, matrix, typename ashape::ashape<Source>::type()); + } + private: + Matrix& assign(const Source& source, Matrix& matrix, typename ashape::ashape<Matrix>::type) + { + matrix_copy_plus(source, matrix); + return matrix; + } +}; + +/// Assign-add sum by adding both arguments +/** Note that this is more special then assigning arbitrary expressions including matrices itself + because mat_mat_plus_expr <E1, E2> is a derived class from + mat_expr < MatrixSrc >. **/ +template <typename E1, typename E2, typename Matrix> +struct crtp_plus_assign<mat_mat_plus_expr<E1, E2>, Matrix> +{ + Matrix& operator()(const mat_mat_plus_expr<E1, E2>& src, Matrix& matrix) + { + vampir_trace<3030> tracer; + matrix+= src.first; + return matrix+= src.second; + } +}; + +template <typename E1, typename E2, typename Matrix> +struct crtp_plus_assign<mat_mat_minus_expr<E1, E2>, Matrix> +{ + Matrix& operator()(const mat_mat_minus_expr<E1, E2>& src, Matrix& matrix) + { + vampir_trace<3030> tracer; + matrix+= src.first; + return matrix-= src.second; + } +}; + +template <typename E1, typename E2, typename Matrix> +struct crtp_plus_assign<mat_mat_ele_times_expr<E1, E2>, Matrix> +{ + Matrix& operator()(const mat_mat_ele_times_expr<E1, E2>& src, Matrix& matrix) + { + vampir_trace<3030> tracer; + Matrix Prod(ele_prod(src.first, src.second)); + return matrix+= Prod; + } +}; + +template <typename E1, typename E2, typename Matrix> +struct crtp_plus_assign<mat_mat_times_expr<E1, E2>, Matrix> +{ + Matrix& operator()(const mat_mat_times_expr<E1, E2>& src, Matrix& matrix) + { + vampir_trace<3030> tracer; + operation::compute_factors<Matrix, mat_mat_times_expr<E1, E2> > factors(src); + gen_mult(factors.first, factors.second, matrix, assign::plus_sum(), + tag::flat<tag::matrix>(), tag::flat<tag::matrix>(), tag::flat<tag::matrix>()); + return matrix; + } +}; + + +/// Assign-subtract matrix expressions by decrementally copying except for some special expressions +template <typename Source, typename Matrix> +struct crtp_minus_assign +{ + Matrix& operator()(const Source& source, Matrix& matrix) + { + vampir_trace<3031> tracer; + return assign(source, matrix, typename ashape::ashape<Source>::type()); + } +private: + Matrix& assign(const Source& source, Matrix& matrix, typename ashape::ashape<Matrix>::type) + { + matrix_copy_minus(source, matrix); + return matrix; + } +}; + +/// Assign-subtract sum by adding both arguments +/** Note that this is more special then assigning arbitrary expressions including matrices itself + because mat_mat_plus_expr <E1, E2> is a derived class from + mat_expr < MatrixSrc >. **/ +template <typename E1, typename E2, typename Matrix> +struct crtp_minus_assign<mat_mat_plus_expr<E1, E2>, Matrix> +{ + Matrix& operator()(const mat_mat_plus_expr<E1, E2>& src, Matrix& matrix) + { + vampir_trace<3031> tracer; + matrix-= src.first; + return matrix-= src.second; + } +}; + +/// Assign-subtracting difference by subtracting first argument and adding the second one +/** Note that this is more special then assigning arbitrary expressions including matrices itself + because mat_mat_minus_expr <E1, E2> is a derived class from + mat_expr < MatrixSrc >. **/ +template <typename E1, typename E2, typename Matrix> +struct crtp_minus_assign<mat_mat_minus_expr<E1, E2>, Matrix> +{ + Matrix& operator()(const mat_mat_minus_expr<E1, E2>& src, Matrix& matrix) + { + vampir_trace<3031> tracer; + matrix-= src.first; + return matrix+= src.second; + } +}; + +template <typename E1, typename E2, typename Matrix> +struct crtp_minus_assign<mat_mat_ele_times_expr<E1, E2>, Matrix> +{ + Matrix& operator()(const mat_mat_ele_times_expr<E1, E2>& src, Matrix& matrix) + { + vampir_trace<3031> tracer; + Matrix Prod(ele_prod(src.first, src.second)); + return matrix-= Prod; + } +}; + +/// Assign-subtract product by calling gen_mult +/** Note that this does not work for arbitrary expressions. **/ +template <typename E1, typename E2, typename Matrix> +struct crtp_minus_assign<mat_mat_times_expr<E1, E2>, Matrix> +{ + Matrix& operator()(const mat_mat_times_expr<E1, E2>& src, Matrix& matrix) + { + vampir_trace<3031> tracer; + operation::compute_factors<Matrix, mat_mat_times_expr<E1, E2> > factors(src); + gen_mult(factors.first, factors.second, matrix, assign::minus_sum(), tag::flat<tag::matrix>(), tag::flat<tag::matrix>(), tag::flat<tag::matrix>()); + return matrix; + } +}; + + + +/// Base class to provide matrix assignment operators generically +template <typename Matrix, typename ValueType, typename SizeType> +struct crtp_matrix_assign +{ +private: + + // For (compatible) dense matrices do a loop over all entries + template <typename Source> + Matrix& density_assign(const Source& src, boost::mpl::true_) + { + vampir_trace<3032> tracer; + // typedef typename Collection<Source>::size_type size_type; + typedef unsigned size_type; + + // std::cout << "Dense assignment\n"; + checked_change_resource(src); + + Matrix& matrix= static_cast<Matrix&>(*this); + for (size_type r= 0; r < num_rows(matrix); ++r) + for (size_type c= 0; c < num_cols(matrix); ++c) + matrix[r][c]= src[r][c]; + return matrix; + } + + // If sparse matrices are involved evaluate step-wise (or assignment from scalar) + template <typename Source> + Matrix& density_assign(const Source& src, boost::mpl::false_) + { + // std::cout << "Sparse assignment\n"; + return crtp_assign<Source, Matrix>()(src, static_cast<Matrix&>(*this)); + } + + + // For (compatible) dense matrices do a loop over all entries + template <typename Source> + Matrix& density_plus_assign(const Source& src, boost::mpl::true_) + { + vampir_trace<3033> tracer; + // typedef typename Collection<Source>::size_type size_type; + typedef unsigned size_type; + + // std::cout << "Dense assignment\n"; + checked_change_resource(src); + // del checked_change_dim(num_rows(src), num_cols(src)); + + Matrix& matrix= static_cast<Matrix&>(*this); + for (size_type r= 0; r < num_rows(matrix); ++r) + for (size_type c= 0; c < num_cols(matrix); ++c) + matrix[r][c]+= src[r][c]; + return matrix; + } + + // If sparse matrices are involved evaluate step-wise (or assignment from scalar) + template <typename Source> + Matrix& density_plus_assign(const Source& src, boost::mpl::false_) + { + // std::cout << "Sparse assignment\n"; + return crtp_plus_assign<Source, Matrix>()(src, static_cast<Matrix&>(*this)); + } + + // For (compatible) dense matrices do a loop over all entries + template <typename Source> + Matrix& density_minus_assign(const Source& src, boost::mpl::true_) + { + vampir_trace<3034> tracer; + // typedef typename Collection<Source>::size_type size_type; + typedef unsigned size_type; + + // std::cout << "Dense assignment\n"; + checked_change_resource(src); + + Matrix& matrix= static_cast<Matrix&>(*this); + for (size_type r= 0; r < num_rows(matrix); ++r) + for (size_type c= 0; c < num_cols(matrix); ++c) + matrix[r][c]-= src[r][c]; + return matrix; + } + + // If sparse matrices are involved evaluate step-wise (or assignment from scalar) + template <typename Source> + Matrix& density_minus_assign(const Source& src, boost::mpl::false_) + { + // std::cout << "Sparse assignment\n"; + return crtp_minus_assign<Source, Matrix>()(src, static_cast<Matrix&>(*this)); + } + + // For (compatible) dense matrices do a loop over all entries + template <typename Source> + Matrix& density_ele_rscale(const Source& src, boost::mpl::true_) + { + vampir_trace<3035> tracer; + // typedef typename Collection<Source>::size_type size_type; + typedef unsigned size_type; + + // std::cout << "Dense assignment\n"; + checked_change_resource(src); + // del checked_change_dim(num_rows(src), num_cols(src)); + + Matrix& matrix= static_cast<Matrix&>(*this); + for (size_type r= 0; r < num_rows(matrix); ++r) + for (size_type c= 0; c < num_cols(matrix); ++c) + matrix[r][c]*= src[r][c]; + return matrix; + } + + // If sparse matrices are involved evaluate step-wise (or assignment from scalar) + template <typename Factor> + Matrix& density_ele_rscale(const Factor& alpha, boost::mpl::false_) + { + // std::cout << "Sparse assignment\n"; + matrix_copy_ele_times(alpha, static_cast<Matrix&>(*this)); + return static_cast<Matrix&>(*this); + } + + public: + + /// Check wether source and target have compatible resources, generalization of check_dim + /** For expressions like A= B + C, A can be set to the size of B and C if still is 0 by 0. **/ + template <typename Src> + void check_resource(const Src& src) const + { check_resource(src, typename mtl::traits::category<Matrix>::type()); } + + // Default case just check_dim + template <typename Src> + void check_resource(const Src& src, tag::universe) const + { check_dim(num_rows(src), num_cols(src)); } + + /// Check wether source and target have compatible resources and wether target has already resources + /** For expressions like A+= B + C, A must be already larger then 0 by 0 and compatible to B and C. **/ + // Generalization with 2 arguments might be needed (check rows from first and columns from second) + template <typename Src> + void check_ready_resource(const Src& src) const + { + MTL_DEBUG_THROW_IF(num_rows(src) * num_cols(src) == 0, need_nonempty()); + check_resource(src); + } + + /// Check wether source and target have compatible resources and adapt empty target + /** For expressions like A= B + C, A can be set to the size of B and C if still is 0 by 0. **/ + template <typename Src> + void checked_change_resource(const Src& src) + { checked_change_resource(src, src); } + + /// Check whether source and target have compatible resources and adapt empty target + /** For expressions like A= B + C, A can be set to the size of B and C if still is 0 by 0. **/ + template <typename Src1, typename Src2> + void checked_change_resource(const Src1& src1, const Src2& src2) + { checked_change_resource_aux(src1, src2, typename mtl::traits::category<Matrix>::type()); } + + template <typename Src1, typename Src2> + void checked_change_resource_aux(const Src1& src1, const Src2& src2, tag::universe) + { checked_change_dim(num_rows(src1), num_cols(src2)); } + + + /// Check whether matrix sizes are compatible or if matrix is 0 by 0 change it to r by c. + /** Deprecated, superseded by checked_change_resource. **/ + void checked_change_dim(SizeType r, SizeType c) + { + Matrix& matrix= static_cast<Matrix&>(*this); + matrix.check_dim(r, c); + matrix.change_dim(r, c); + } + + /// Templated assignment implemented by functor to allow for partial specialization + // Despite there is only an untemplated assignment and despite the disable_if MSVC whines about ambiguity :-! + // Scalar assignment is also taking out because it has another return type + template <typename Source> + typename boost::disable_if_c<boost::is_same<Matrix, Source>::value + || boost::is_same<typename ashape::ashape<Source>::type, ashape::scal>::value, + Matrix&>::type + operator=(const Source& src) + { + return density_assign(src, boost::mpl::bool_< boost::is_same<typename ashape::ashape<Matrix>::type, + typename ashape::ashape<Source>::type>::value + && mtl::traits::eval_dense< mat_mat_asgn_expr<Matrix, Source> >::value >()); + } + + // Helper type for assigning scalars to handle both A= a; and A= a, b, c; + template <typename Source> + struct scalar_assign + { + scalar_assign(Source src, Matrix& matrix) + : src(src), with_comma(false), r(0), c(0), matrix(matrix), ins(matrix, 1) {} + + ~scalar_assign() + { + vampir_trace<3047> tracer; + if (with_comma) { + MTL_DEBUG_THROW_IF(r != num_rows(matrix), incompatible_size("Not all matrix entries initialized!")); + } else { + using std::min; + if (src == math::zero(src)) // it is already set to zero + return; + // Otherwise set diagonal (if square) + for (SizeType i= 0, n= min(num_rows(matrix), num_cols(matrix)); i < n; i++) + ins[i][i] << src; + } + } + + template <typename ValueSource> + scalar_assign& operator, (ValueSource val) + { + if (!with_comma) { + with_comma= true; + assert(r == 0 && c == 0); + ins[r][c++] << src; // We haven't set v[0] yet + if (c == num_cols(matrix)) + c= 0, r++; + } + ins[r][c++] << val; + if (c == num_cols(matrix)) + c= 0, r++; + return *this; + } + + Source src; + bool with_comma; + SizeType r, c; + Matrix& matrix; + inserter<Matrix> ins; + }; + + template <typename Source> + typename boost::enable_if<boost::is_same<typename ashape::ashape<Source>::type, ashape::scal>, + scalar_assign<Source> >::type + operator=(Source src) + { + Matrix& matrix= static_cast<Matrix&>(*this); + MTL_DEBUG_THROW_IF(num_rows(matrix) * num_cols(matrix) == 0, + range_error("Trying to initialize a 0 by 0 matrix with a value")); + set_to_zero(matrix); + return scalar_assign<Source>(src, static_cast<Matrix&>(*this)); + } + + template <typename Source> + Matrix& operator+=(const Source& src) + { + return density_plus_assign(src, mtl::traits::eval_dense< mat_mat_asgn_expr<Matrix, Source> >()); + } + + template <typename Source> + Matrix& operator-=(const Source& src) + { + return density_minus_assign(src, mtl::traits::eval_dense< mat_mat_asgn_expr<Matrix, Source> >()); + } + + /// Scale matrix (in place) with scalar value or other matrix + template <typename Factor> + Matrix& operator*=(const Factor& alpha) + { + right_scale_inplace(static_cast<Matrix&>(*this), alpha); + return static_cast<Matrix&>(*this); + } + + // Element-wise scaling from right (i.e. like *= as elementwise) + template <typename Factor> + Matrix& ele_rscale(const Factor& alpha) + { + return density_ele_rscale(alpha, mtl::traits::eval_dense< mat_mat_asgn_expr<Matrix, Factor> >()); + } + + /// Divide matrix (in place) by scalar value + // added by Hui Li + template <typename Factor> + Matrix& operator/=(const Factor& alpha) + { + divide_by_inplace(static_cast<Matrix&>(*this), alpha); + return static_cast<Matrix&>(*this); + } +}; + + + +template <typename Matrix, typename ValueType, typename SizeType> +struct const_crtp_matrix_bracket +{ + template <typename T> + typename boost::disable_if_c<boost::is_same<T, mtl::irange>::value || boost::is_same<T, mtl::iset>::value, + operations::bracket_proxy<Matrix, const Matrix&, ValueType> >::type + operator[] (const T& row) const + { + return operations::bracket_proxy<Matrix, const Matrix&, ValueType>(static_cast<const Matrix&>(*this), row); + } + + // Compiler error (later) if no sub_matrix function (or row vector resp.) available + template <typename T> + typename boost::enable_if<boost::is_same<T, mtl::irange>, operations::range_bracket_proxy<Matrix, const Matrix&, const Matrix> >::type + operator[] (const T& row_range) const + { + return operations::range_bracket_proxy<Matrix, const Matrix&, const Matrix>(static_cast<const Matrix&>(*this), row_range); + } + + operations::set_bracket_proxy<Matrix, const Matrix&, const Matrix> + operator[] (const iset& row_set) const + { + return operations::set_bracket_proxy<Matrix, const Matrix&, const Matrix>(static_cast<const Matrix&>(*this), row_set); + } +}; + +template <typename Matrix, typename ValueType, typename SizeType> +struct crtp_matrix_bracket +{ + operations::bracket_proxy<Matrix, const Matrix&, const ValueType&> + operator[] (SizeType row) const + { + return operations::bracket_proxy<Matrix, const Matrix&, const ValueType&>(static_cast<const Matrix&>(*this), row); + } + + template <typename T> + typename boost::disable_if_c<boost::is_same<T, mtl::irange>::value || boost::is_same<T, mtl::iset>::value, + operations::bracket_proxy<Matrix, Matrix&, ValueType&> >::type + // operations::bracket_proxy<Matrix, Matrix&, ValueType&> + operator[] (const T& row) + { + return operations::bracket_proxy<Matrix, Matrix&, ValueType&>(static_cast<Matrix&>(*this), row); + } + + // Compiler error (later) if no sub_matrix function available + operations::range_bracket_proxy<Matrix, const Matrix&, const Matrix> + operator[] (const irange& row_range) const + { + return operations::range_bracket_proxy<Matrix, const Matrix&, const Matrix>(static_cast<const Matrix&>(*this), row_range); + } + + // Compiler error (later) if no sub_matrix function available + template <typename T> + typename boost::enable_if<boost::is_same<T, mtl::irange>, operations::range_bracket_proxy<Matrix, Matrix&, Matrix> >::type + // operations::range_bracket_proxy<Matrix, Matrix&, Matrix> + operator[] (const T& row_range) + { + return operations::range_bracket_proxy<Matrix, Matrix&, Matrix>(static_cast<Matrix&>(*this), row_range); + } + + operations::set_bracket_proxy<Matrix, const Matrix&, const Matrix> + operator[] (const iset& row_set) const + { + return operations::set_bracket_proxy<Matrix, const Matrix&, const Matrix>(static_cast<const Matrix&>(*this), row_set); + } +}; + +template <typename Matrix, typename ValueType, typename SizeType> +struct crtp_matrix_lvalue +{ + // Function must be overwritten by Matrix if m(row, col) does not return a reference + ValueType& lvalue(SizeType row, SizeType col) + { + return static_cast<Matrix&>(*this)(row, col); + } +}; + +template <typename Matrix, typename ValueType, typename SizeType> +struct const_crtp_base_matrix + : public const_crtp_matrix_bracket<Matrix, ValueType, SizeType> +{}; + +template <typename Matrix, typename ValueType, typename SizeType> +struct mutable_crtp_base_matrix + : public crtp_matrix_bracket<Matrix, ValueType, SizeType>, + public crtp_matrix_assign<Matrix, ValueType, SizeType> +{}; + +template <typename Matrix, typename ValueType, typename SizeType> +struct crtp_base_matrix + : boost::mpl::if_<boost::is_const<Matrix>, + const_crtp_base_matrix<Matrix, ValueType, SizeType>, + mutable_crtp_base_matrix<Matrix, ValueType, SizeType> + >::type +{}; + + + +}} // namespace mtl::matrix + +#endif // MTL_CRTP_BASE_MATRIX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/dense2D.hpp b/install/MTL/include/boost/numeric/mtl/matrix/dense2D.hpp new file mode 100644 index 00000000..9e907da3 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/dense2D.hpp @@ -0,0 +1,910 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_DENSE2D_INCLUDE +#define MTL_DENSE2D_INCLUDE + + +#include <algorithm> +#include <boost/mpl/bool.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/if.hpp> +#include <boost/utility/enable_if.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp> +#include <boost/numeric/mtl/matrix/base_sub_matrix.hpp> +#include <boost/numeric/mtl/matrix/all_mat_expr.hpp> +#include <boost/numeric/mtl/matrix/operators.hpp> +#include <boost/numeric/mtl/detail/contiguous_memory_block.hpp> +#include <boost/numeric/mtl/operation/set_to_zero.hpp> +#include <boost/numeric/mtl/operation/compute_factors.hpp> +#include <boost/numeric/mtl/operation/clone.hpp> +#include <boost/numeric/mtl/operation/is_negative.hpp> +#include <boost/numeric/mtl/utility/common_include.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/is_static.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/utility/dense_el_cursor.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/utility/strided_dense_el_cursor.hpp> +#include <boost/numeric/mtl/utility/strided_dense_el_iterator.hpp> +#include <boost/numeric/mtl/utility/transposed_orientation.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> + +#ifdef MTL_WITH_INITLIST +# include <initializer_list> +#endif +#include <algorithm> + +// Forward declaration (for friend declaration) +namespace mtl { namespace traits { namespace detail { + template <typename, typename, bool> struct dense2D_iterator_range_generator; +}}} + +namespace mtl { namespace mat { + + +using std::size_t; + +// Forward declarations +template <typename Value, typename Parameters> class dense2D; +class dense2D_indexer; + +// Helper type +struct dense2D_sub_ctor {}; + +// Indexing for dense matrices +class dense2D_indexer +{ + // helpers for public functions + size_t offset(size_t ldim, size_t r, size_t c, row_major) const + { + return r * ldim + c; + } + size_t offset(size_t ldim, size_t r, size_t c, col_major) const + { + return c * ldim + r; + } + + size_t row(size_t offset, size_t ldim, row_major) const + { + return offset / ldim; + } + size_t row(size_t offset, size_t ldim, col_major) const + { + return offset % ldim; + } + + size_t col(size_t offset, size_t ldim, row_major) const + { + return offset % ldim; + } + size_t col(size_t offset, size_t ldim, col_major) const + { + return offset / ldim; + } + + public: + template <typename Value, class Parameters> + size_t operator() (const dense2D<Value, Parameters>& ma, size_t r, size_t c) const + { + typedef dense2D<Value, Parameters> matrix_type; + // convert into c indices + typename matrix_type::index_type my_index; + size_t my_r= index::change_from(my_index, r); + size_t my_c= index::change_from(my_index, c); + return offset(ma.ldim, my_r, my_c, typename matrix_type::orientation()); + } + + template <typename Value, class Parameters> + size_t row(const dense2D<Value, Parameters>& ma, + typename dense2D<Value, Parameters>::key_type key) const + { + typedef dense2D<Value, Parameters> matrix_type; + // row with c-index for my orientation + size_t r= row(ma.offset(key), ma.ldim, typename matrix_type::orientation()); + return index::change_to(typename matrix_type::index_type(), r); + } + + template <typename Value, class Parameters> + size_t col(const dense2D<Value, Parameters>& ma, + typename dense2D<Value, Parameters>::key_type key) const + { + typedef dense2D<Value, Parameters> matrix_type; + // column with c-index for my orientation + size_t c= col(ma.offset(key), ma.ldim, typename matrix_type::orientation()); + return index::change_to(typename matrix_type::index_type(), c); + } + template <typename, typename> friend class dense2D; +}; // dense2D_indexer + + +namespace detail +{ + + // Compute required memory + // Enabling mechanism to make sure that computation is valid + template <typename Parameters, bool Enable> + struct dense2D_array_size { + static std::size_t const value= 0; + }; + + template <typename Parameters> + struct dense2D_array_size<Parameters, true> + { + typedef typename Parameters::dimensions dimensions; + MTL_STATIC_ASSERT((dimensions::is_static), "Size must be known at compile time."); + static std::size_t const value= dimensions::Num_Rows * dimensions::Num_Cols; + }; + + // return const-ref if matrix on stack and type itself if on heap + template <typename Matrix, bool on_stack> + struct ref_on_stack + { + typedef Matrix type; + }; + + template <typename Matrix> + struct ref_on_stack<Matrix, true> + { + typedef const Matrix& type; + }; + +} // namespace detail + + +/// Dense matrix type +template <typename Value, typename Parameters = parameters<> > +class dense2D + : public base_sub_matrix<Value, Parameters>, + public mtl::detail::contiguous_memory_block< Value, Parameters::on_stack, + detail::dense2D_array_size<Parameters, Parameters::on_stack>::value >, + public crtp_base_matrix< dense2D<Value, Parameters>, Value, std::size_t >, + public mat_expr< dense2D<Value, Parameters> > +{ + typedef dense2D self; + typedef base_sub_matrix<Value, Parameters> super; + typedef mtl::detail::contiguous_memory_block<Value, Parameters::on_stack, + detail::dense2D_array_size<Parameters, Parameters::on_stack>::value> memory_base; + typedef mat_expr< dense2D<Value, Parameters> > expr_base; + typedef crtp_base_matrix< self, Value, std::size_t > crtp_base; + typedef crtp_matrix_assign< self, Value, std::size_t > assign_base; + public: + typedef Parameters parameters; + typedef typename Parameters::orientation orientation; + typedef typename Parameters::index index_type; + typedef typename Parameters::dimensions dim_type; + typedef Value value_type; + typedef const value_type& const_reference; + typedef value_type& reference; + + typedef const value_type* const_pointer_type; + typedef const_pointer_type key_type; + typedef std::size_t size_type; + typedef dense_el_cursor<Value> el_cursor_type; + typedef dense2D_indexer indexer_type; + + // Self-similar type unless dimension is fixed + // Not supported for the moment + typedef self sub_matrix_type; + + protected: + // Obviously, the next 3 functions must be called after setting dimensions + void set_nnz() { this->my_nnz = this->num_rows() * this->num_cols(); } + void set_ldim(row_major) { ldim= this->num_cols(); } + void set_ldim(col_major) { ldim= this->num_rows(); } + void set_ldim() { set_ldim(orientation()); } + + void init() + { + set_nnz(); set_ldim(); // set_to_zero(*this); + } + + public: + /// Default constructor, if compile time matrix size allocate memory + dense2D() : memory_base(dim_type().num_rows() * dim_type().num_cols()) + { init(); } + + /// Constructor that only sets dimensions, only for run-time dimensions + explicit dense2D(mtl::non_fixed::dimensions d) + : super(d), memory_base(d.num_rows() * d.num_cols()) + { init(); } + + /// Most common constructor from number of rows and columns + explicit dense2D(size_type num_rows, size_type num_cols) + : super(dim_type(num_rows, num_cols)), + memory_base(num_rows * num_cols) + { init(); } + + /// Constructor that sets dimensions and pointer to external data + explicit dense2D(mtl::non_fixed::dimensions d, value_type* a) + : super(d), memory_base(a, d.num_rows() * d.num_cols()) + { init(); } + + /// Constructor that sets dimensions and pointer to external data + explicit dense2D(size_type num_rows, size_type num_cols, value_type* a) + : super(mtl::non_fixed::dimensions(num_rows, num_cols)), memory_base(a, num_rows * num_cols) + { init(); } + + /// Constructor for compile time matrix size + /** sets dimensions and pointer to external data **/ + explicit dense2D(value_type* a) + : super(), memory_base(a, dim_type().num_rows() * dim_type().num_cols()) + { + MTL_STATIC_ASSERT((dim_type::is_static), "Size must be known at compile time."); + init(); + } + + /// Default copy constructor + dense2D(const self& m) + : super(dim_type(m.num_rows(), m.num_cols())), + memory_base(m) + { + // In case of sub-matrices we need m's ldim -> init doesn't work + this->my_nnz= m.my_nnz; ldim= m.ldim; + } + + /// Clone constructor, copies every source including sub-matrices and other matrices with references + explicit dense2D(const self& m, clone_ctor) + : super(mtl::non_fixed::dimensions(m.num_rows(), m.num_cols())), + memory_base(m, clone_ctor()) + { + init(); + *this= m; + } + + /// General copy constructor, uses functionality from CRTP base + template <typename MatrixSrc> + explicit dense2D(const MatrixSrc& src) + : super(), memory_base(dim_type().num_rows() * dim_type().num_cols()) + { + init(); + *this= src; + } + +#ifdef MTL_WITH_MOVE + /// Move constructor + dense2D(self&& src) : memory_base(dim_type().num_rows() * dim_type().num_cols()) + { init(); self_assign(src, boost::mpl::bool_<memory_base::on_stack>()); } +#endif + + /// Constructor for creating sub-matrices + template <typename MatrixSrc> + dense2D(MatrixSrc& matrix, dense2D_sub_ctor, + size_type begin_r, size_type end_r, size_type begin_c, size_type end_c) + : super(mtl::non_fixed::dimensions(matrix.num_rows(), matrix.num_cols())), + memory_base(matrix.data, (end_r - begin_r) * (end_c - begin_c), true) + { + sub_matrix_constructor(matrix, begin_r, end_r, begin_c, end_c, boost::mpl::bool_<memory_base::on_stack>()); + } + +#if defined(MTL_WITH_INITLIST) && defined(MTL_WITH_AUTO) && defined(MTL_WITH_RANGEDFOR) + /// Constructor for initializer list \p values + template <typename Value2> + dense2D(std::initializer_list<std::initializer_list<Value2> > values) + : super(mtl::non_fixed::dimensions(values.size(), values.size()? values.begin()->size() : 0)), + memory_base(this->num_rows() * this->num_cols()) + { + init(); + *this= values; + } +#endif + + private: + template <typename MatrixSrc> + void sub_matrix_constructor(MatrixSrc& matrix, size_type begin_r, size_type end_r, + size_type begin_c, size_type end_c, boost::mpl::false_) + { + matrix.check_ranges(begin_r, end_r, begin_c, end_c); + + if(end_r <= begin_r || end_c <= begin_c) + set_ranges(0, 0); + else { + // Leading dimension doesn't change + this->data += matrix.indexer(matrix, begin_r, begin_c); // Takes care of indexing + set_ranges(end_r - begin_r, end_c - begin_c); + } + this->my_nnz= matrix.nnz(); ldim= matrix.get_ldim(); + } + + template <typename MatrixSrc> + void sub_matrix_constructor(MatrixSrc&, size_type, size_type, + size_type, size_type, boost::mpl::true_) + { + MTL_THROW(logic_error("Matrices cannot be used as sub-matrices!")); + } + + public: + +#ifdef MTL_WITH_MOVE + /// Move assignment for data on heap + self& operator=(self&& src) + { return self_assign(src, boost::mpl::bool_<memory_base::on_stack>()); } + + /// (Copy) Assignment + self& operator=(const self& src) + { return self_assign(src, boost::mpl::true_()); } + +#else + /// (Copy) Assignment + self& operator=(typename detail::ref_on_stack<self, memory_base::on_stack>::type src) + { + return self_assign(src, boost::mpl::bool_<memory_base::on_stack>()); + } +#endif + + private: + // Already copied for lvalues -> data can be stolen (need non-const ref) + self& self_assign(self& src, boost::mpl::false_) + { + // Self-copy would be an indication of an error + assert(this != &src); + // std::cout << "In move assignment: this* = \n" << *this << "src = \n" << src; + + this->checked_change_dim(src.num_rows(), src.num_cols()); + if (this->category == memory_base::view || src.category == memory_base::view) + matrix_copy(src, *this); + else { + if (this->num_rows() != src.num_rows() || this->num_cols() != src.num_cols()) { + super::change_dim(src.num_rows(), src.num_cols()); + init(); + } + memory_base::move_assignment(src); + } + // std::cout << "End of move assignment: this* = \n" << *this; + return *this; + } + + // For matrices with data on stack (or lvalues in C++11) + self& self_assign(const self& src, boost::mpl::true_) + { + if (this != &src) { + this->checked_change_dim(src.num_rows(), src.num_cols()); + matrix_copy(src, *this); + } + return *this; + } + public: + + // import operators from CRTP base class +#if 0 // def __PGI + using crtp_base::operator=; +#else + using assign_base::operator=; +#endif + + /// Change dimension, can keep old data + void change_dim(size_type r, size_type c, bool keep_data = false) + { + change_dim(r, c, keep_data, mtl::traits::is_static<self>()); + } + + private: + void change_dim(size_type r, size_type c, bool keep_data, boost::mpl::false_) + { + if (r == this->num_rows() && c == this->num_cols()) + return; + + self temp; + if (keep_data) { + temp.super::change_dim(this->num_rows(), this->num_cols()); + temp.init(); + temp.memory_base::move_assignment(*this); + } + memory_base::realloc(r*c); + super::change_dim(r, c); + init(); + if (keep_data) { + if (r > temp.num_rows() || c > temp.num_cols()){ + set_to_zero(*this); +#if 0 + irange rr(0, std::min(r,temp.num_rows())), cr(0, std::min(c,temp.num_cols())); + *this[rr][cr]= temp[rr][cr]; +#endif + sub_matrix(*this,0,std::min(r,temp.num_rows()),0,std::min(c,temp.num_cols())) + = sub_matrix(temp,0,std::min(r,temp.num_rows()),0,std::min(c,temp.num_cols())); + } else + *this = temp[irange(0, r)][irange(0, c)]; + } + } + + void change_dim(size_type MTL_DEBUG_ARG(r), size_type MTL_DEBUG_ARG(c), bool, boost::mpl::true_) + { assert(r == this->num_rows() && c == this->num_cols()); } + + public: + /// Check whether indices r and c are in range + bool check_indices(size_t r, size_t c) const + { return r >= this->begin_row() && r < this->end_row() && c >= this->begin_col() && c < this->end_col(); } + + /// Constant access to element + const_reference operator() (size_t r, size_t c) const + { + MTL_DEBUG_THROW_IF(is_negative(r) || r >= this->num_rows() || is_negative(c) || c >= this->num_cols(), index_out_of_range()); + return this->data[indexer(*this, r, c)]; + } + + /// Mutable access to element + value_type& operator() (size_t r, size_t c) + { + MTL_DEBUG_THROW_IF(is_negative(r) || r >= this->num_rows() || is_negative(c) || c >= this->num_cols(), index_out_of_range()); + return this->data[indexer(*this, r, c)]; + } + + // offset regarding c-style indices + size_t c_offset(size_t r, size_t c) const + { return indexer.offset(ldim, r, c, orientation()); } + + /// Get lower dimension [advanced] + size_type get_ldim() const + { return ldim; } + + /// Swap two matrices + friend void swap(self& matrix1, self& matrix2) + { + swap(static_cast<memory_base&>(matrix1), static_cast<memory_base&>(matrix2)); + swap(static_cast<super&>(matrix1), static_cast<super&>(matrix2)); + std::swap(matrix1.ldim, matrix2.ldim); + } + + void crop() {} ///< Delete structural zeros; only dummy here + + /// Address of first data entry (mutable); to be used with care. [advanced] + value_type* address_data() { return this->data; } + /// Address of first data entry (constant); to be used with care. [advanced] + const value_type* address_data() const { return this->data; } + + /// Whether data is stored in strides + bool has_strided_data() const { return this->category != this->own; } + + protected: + + // Set ranges from begin_r to end_r and begin_c to end_c + void set_ranges(size_type begin_r, size_type end_r, size_type begin_c, size_type end_c) + { + super::set_ranges(begin_r, end_r, begin_c, end_c); + set_nnz(); + } + + // Set ranges to a num_row x num_col matrix, keeps indexing + void set_ranges(size_type num_rows, size_type num_cols) + { + set_ranges(this->begin_row(), this->begin_row() + num_rows, + this->begin_col(), this->begin_col() + num_cols); + } + + public: + + indexer_type indexer; + + friend class dense2D_indexer; + +#if !defined(_MSC_VER) || _MSC_VER != 1400 // Bug in MSVC 2005 + template <typename> friend struct sub_matrix_t; + template <typename, typename> friend struct mtl::traits::range_generator; + template <typename, typename, bool> friend struct mtl::traits::detail::dense2D_iterator_range_generator; + + protected: +#endif + + // Leading dimension is minor dimension in original matrix + // Opposed to other dims doesn't change in sub-matrices + size_type ldim; + +}; // dense2D + + +// ================ +// Free functions +// ================ + + +/// Number of rows +template <typename Value, typename Parameters> +typename dense2D<Value, Parameters>::size_type +inline num_rows(const dense2D<Value, Parameters>& matrix) +{ + return matrix.num_rows(); +} + +/// Number of columns +template <typename Value, typename Parameters> +typename dense2D<Value, Parameters>::size_type +inline num_cols(const dense2D<Value, Parameters>& matrix) +{ + return matrix.num_cols(); +} + +/// Size of the matrix, i.e. the number of row times columns +template <typename Value, typename Parameters> +typename dense2D<Value, Parameters>::size_type +inline size(const dense2D<Value, Parameters>& matrix) +{ + return matrix.num_cols() * matrix.num_rows(); +} + + +} + +using mat::dense2D; + +} // namespace mtl::matrix + + +namespace mtl { namespace traits { + + + // VC 8.0 finds ambiguity with mtl::tag::dense2D (I wonder why, especially here) + using mtl::mat::dense2D; + + // ================ + // Range generators + // For cursors + // ================ + + template <typename Value, typename Parameters> + struct range_generator<glas::tag::all, dense2D<Value, Parameters> > + : detail::dense_element_range_generator<dense2D<Value, Parameters>, + dense_el_cursor<Value>, complexity_classes::linear_cached> + {}; + + template <typename Value, typename Parameters> + struct range_generator<glas::tag::nz, dense2D<Value, Parameters> > + : detail::dense_element_range_generator<dense2D<Value, Parameters>, + dense_el_cursor<Value>, complexity_classes::linear_cached> + {}; + + namespace detail + { + // complexity of dense row cursor depends on storage scheme + // if orientation is row_major then complexity is cached_linear, otherwise linear + template <typename Orientation> struct dense2D_rc {}; + template<> struct dense2D_rc<row_major> + { + typedef complexity_classes::linear_cached type; + }; + template<> struct dense2D_rc<col_major> + { + typedef complexity_classes::linear type; + }; + + // Complexity of column cursor is of course opposite + template <typename Orientation> struct dense2D_cc + : dense2D_rc<typename mtl::traits::transposed_orientation<Orientation>::type> + {}; + } + + template <typename Value, typename Parameters> + struct range_generator<glas::tag::row, dense2D<Value, Parameters> > + : detail::all_rows_range_generator<dense2D<Value, Parameters>, + typename detail::dense2D_rc<typename Parameters::orientation>::type> + {}; + + // For a cursor pointing to some row give the range of elements in this row + template <typename Value, typename Parameters> + struct range_generator<glas::tag::nz, + detail::sub_matrix_cursor<dense2D<Value, Parameters>, glas::tag::row, 2> > + { + typedef dense2D<Value, Parameters> matrix; + typedef typename matrix::size_type size_type; + typedef detail::sub_matrix_cursor<matrix, glas::tag::row, 2> cursor; + + // linear for col_major and linear_cached for row_major + typedef typename detail::dense2D_rc<typename Parameters::orientation>::type complexity; + static int const level = 1; + + typedef typename boost::mpl::if_< + boost::is_same<typename Parameters::orientation, row_major> + , dense_el_cursor<Value> + , strided_dense_el_cursor<Value> + >::type type; + + private: + + type dispatch(cursor const& c, size_type col, row_major) const + { + return type(c.ref, c.key, col); + } + type dispatch(cursor const& c, size_type col, col_major) const + { + return type(c.ref, c.key, col, c.ref.ldim); + } + + public: + + type begin(cursor const& c) const + { + return dispatch(c, c.ref.begin_col(), typename matrix::orientation()); + } + type end(cursor const& c) const + { + return dispatch(c, c.ref.end_col(), typename matrix::orientation()); + } + type lower_bound(cursor const& c, size_type position) const + { + return dispatch(c, std::min(c.ref.end_col(), position), typename matrix::orientation()); + } + }; + + template <typename Value, typename Parameters> + struct range_generator<glas::tag::all, + detail::sub_matrix_cursor<dense2D<Value, Parameters>, glas::tag::row, 2> > + : range_generator<glas::tag::nz, + detail::sub_matrix_cursor<dense2D<Value, Parameters>, glas::tag::row, 2> > + {}; + + + template <typename Value, typename Parameters> + struct range_generator<glas::tag::col, dense2D<Value, Parameters> > + : detail::all_cols_range_generator<dense2D<Value, Parameters>, + typename detail::dense2D_cc<typename Parameters::orientation>::type> + {}; + + // For a cursor pointing to some row give the range of elements in this row + template <typename Value, typename Parameters> + struct range_generator<glas::tag::nz, + detail::sub_matrix_cursor<dense2D<Value, Parameters>, glas::tag::col, 2> > + { + typedef dense2D<Value, Parameters> matrix; + typedef typename matrix::size_type size_type; + typedef detail::sub_matrix_cursor<matrix, glas::tag::col, 2> cursor; + typedef typename detail::dense2D_cc<typename Parameters::orientation>::type complexity; + static int const level = 1; + + typedef typename boost::mpl::if_< + boost::is_same<typename Parameters::orientation, col_major> + , dense_el_cursor<Value> + , strided_dense_el_cursor<Value> + >::type type; + + private: + type dispatch(cursor const& c, size_type row, col_major) const + { + return type(c.ref, row, c.key); + } + type dispatch(cursor const& c, size_type row, row_major) const + { + return type(c.ref, row, c.key, c.ref.ldim); + } + + public: + type begin(cursor const& c) const + { + return dispatch(c, c.ref.begin_row(), typename matrix::orientation()); + } + type end(cursor const& c) const + { + return dispatch(c, c.ref.end_row(), typename matrix::orientation()); + } + type lower_bound(cursor const& c, size_type position) const + { + return dispatch(c, std::min(c.ref.end_row(), position), typename matrix::orientation()); + } + }; + + template <typename Value, typename Parameters> + struct range_generator<glas::tag::all, + detail::sub_matrix_cursor<dense2D<Value, Parameters>, glas::tag::col, 2> > + : public range_generator<glas::tag::nz, + detail::sub_matrix_cursor<dense2D<Value, Parameters>, glas::tag::col, 2> > + {}; + +// ============= +// For iterators +// ============= + + + namespace detail { + + // Traversal along major dimension first and then along minor + template <typename OuterTag, typename Orientation> + struct major_traversal + { + static const bool value= false; + }; + + template <> struct major_traversal<glas::tag::row, row_major> + { + static const bool value= true; + }; + + template <> struct major_traversal<glas::tag::col, col_major> + { + static const bool value= true; + }; + + + template <typename OuterTag, typename Matrix, bool is_const> + struct dense2D_iterator_range_generator + { + typedef Matrix matrix_type; + typedef typename matrix_type::size_type size_type; + typedef typename matrix_type::value_type value_type; + typedef typename matrix_type::parameters parameters; + typedef detail::sub_matrix_cursor<matrix_type, OuterTag, 2> cursor; + + // if traverse first along major dimension then memory access is contiguous (otherwise strided) + typedef typename boost::mpl::if_< + major_traversal<OuterTag, typename parameters::orientation> + , complexity_classes::linear_cached + , complexity_classes::linear + >::type complexity; + static int const level = 1; + + // if traverse first along major dimension use pointer otherwise strided iterator + typedef typename boost::mpl::if_< + major_traversal<OuterTag, typename parameters::orientation> + , typename boost::mpl::if_c< + is_const + , const value_type* + , value_type* + >::type + , typename boost::mpl::if_c< + is_const + , strided_dense_el_const_iterator<value_type> + , strided_dense_el_iterator<value_type> + >::type + >::type type; + + private: + // if traverse first along major dim. then return address as pointer + type dispatch(cursor const& c, size_type row, size_type col, complexity_classes::linear_cached) const + { + matrix_type& ma= const_cast<matrix_type&>(c.ref); + return ma.elements() + ma.indexer(ma, row, col); // &ref[row][col]; + } + + // otherwise strided + type dispatch(cursor const& c, size_type row, size_type col, complexity_classes::linear) const + { + // cast const away (is dirty and should be improved later (cursors must distinct constness)) + matrix_type& ref= const_cast<matrix_type&>(c.ref); + return type(ref, row, col, ref.ldim); + } + + type begin_dispatch(cursor const& c, glas::tag::row) const + { + return dispatch(c, c.key, c.ref.begin_col(), complexity()); + } + + type end_dispatch(cursor const& c, glas::tag::row) const + { + return dispatch(c, c.key, c.ref.end_col(), complexity()); + } + + + type begin_dispatch(cursor const& c, glas::tag::col) const + { + return dispatch(c, c.ref.begin_row(), c.key, complexity()); + } + + type end_dispatch(cursor const& c, glas::tag::col) const + { + return dispatch(c, c.ref.end_row(), c.key, complexity()); + } + + public: + + type begin(cursor const& c) const + { + return begin_dispatch(c, OuterTag()); + } + + type end(cursor const& c) const + { + return end_dispatch(c, OuterTag()); + } + }; + + } // namespace detail + + + template <typename Value, typename Parameters, typename OuterTag> + struct range_generator<tag::iter::nz, + detail::sub_matrix_cursor<dense2D<Value, Parameters>, OuterTag, 2> > + : public detail::dense2D_iterator_range_generator<OuterTag, dense2D<Value, Parameters>, false> + {}; + + template <typename Value, typename Parameters, typename OuterTag> + struct range_generator<tag::iter::all, + detail::sub_matrix_cursor<dense2D<Value, Parameters>, OuterTag, 2> > + : public detail::dense2D_iterator_range_generator<OuterTag, dense2D<Value, Parameters>, false> + {}; + + template <typename Value, typename Parameters, typename OuterTag> + struct range_generator<tag::const_iter::nz, + detail::sub_matrix_cursor<dense2D<Value, Parameters>, OuterTag, 2> > + : public detail::dense2D_iterator_range_generator<OuterTag, dense2D<Value, Parameters>, true> + {}; + + template <typename Value, typename Parameters, typename OuterTag> + struct range_generator<tag::const_iter::all, + detail::sub_matrix_cursor<dense2D<Value, Parameters>, OuterTag, 2> > + : public detail::dense2D_iterator_range_generator<OuterTag, dense2D<Value, Parameters>, true> + {}; + + +}} // namespace mtl::traits + +namespace mtl { namespace mat { + + // ========== + // Sub matrix + // ========== + + template <typename Value, typename Parameters> + struct sub_matrix_t<dense2D<Value, Parameters> > + { + typedef dense2D<Value, Parameters> matrix_type; + // copy orientation, ignore index, set dimension to non-fixed and on_stack to false + typedef parameters<typename Parameters::orientation> para_type; + + typedef dense2D<Value, para_type> sub_matrix_type; + typedef sub_matrix_type const const_sub_matrix_type; + typedef typename matrix_type::size_type size_type; + + sub_matrix_type operator()(matrix_type& matrix, size_type begin_r, size_type end_r, size_type begin_c, size_type end_c) + { + return sub_matrix_type(matrix, dense2D_sub_ctor(), begin_r, end_r, begin_c, end_c); + } + + const_sub_matrix_type + operator()(matrix_type const& matrix, size_type begin_r, size_type end_r, size_type begin_c, size_type end_c) + { + // To minimize code duplication, we use the non-const version + sub_matrix_type tmp((*this)(const_cast<matrix_type&>(matrix), begin_r, end_r, begin_c, end_c)); + return tmp; + } + }; + +}} // mtl::matrix + +namespace mtl { + + // Enable cloning of dense matrices + template <typename Value, typename Parameters> + struct is_clonable< mtl::mat::dense2D<Value, Parameters> > : boost::mpl::true_ {}; + +} // namespace mtl + + + +namespace math { + + // Multiplicative identities of matrices + template <typename Value, typename Parameters> + struct identity_t< mult<mtl::mat::dense2D<Value, Parameters> >, mtl::mat::dense2D<Value, Parameters> > + : public std::binary_function< mult<mtl::mat::dense2D<Value, Parameters> >, + mtl::mat::dense2D<Value, Parameters>, + mtl::mat::dense2D<Value, Parameters> > + { + typedef mtl::mat::dense2D<Value, Parameters> matrix_type; + + matrix_type operator() (const mult<matrix_type>&, const matrix_type& ref) const + { + matrix_type tmp(ref); + tmp= one(typename matrix_type::value_type()); + return tmp; + } + }; + +} // namespace math + + +#endif // MTL_DENSE2D_INCLUDE + + +/* +Limitations: +- with compile-time constant dimension, submatrices are not supported (would violate self-similarity) +- Element cursor doesn't work for sub-matrices (not contiguous) +*/ diff --git a/install/MTL/include/boost/numeric/mtl/matrix/diagonal_setup.hpp b/install/MTL/include/boost/numeric/mtl/matrix/diagonal_setup.hpp new file mode 100644 index 00000000..ff780490 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/diagonal_setup.hpp @@ -0,0 +1,48 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_DIAGONAL_SETUP_INCLUDE +#define MTL_DIAGONAL_SETUP_INCLUDE + +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/operation/set_to_zero.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> + +namespace mtl { namespace mat { + +/// Setup a matrix to a multiple of the unity matrix +/** Intended for sparse matrices but works also with dense matrices. + If the value is 0 the matrix is only zeroed out, whereby + a sparse matrix will be empty after this operation, + i.e. the zeros on the diagonal are not explicitly stored. + The diagonal in its generalized form is the set of entries with equal row and column + index (since r6843, older revision considered it erroneous to store + a non-zero scalar to a non-square matrix). + **/ +template <typename Matrix, typename Value> +inline void diagonal_setup(Matrix& matrix, const Value& value) +{ + using std::min; + if (num_rows(matrix) == 0 || num_cols(matrix) == 0) + return; + + set_to_zero(matrix); + inserter<Matrix> ins(matrix, 1); + for (typename Collection<Matrix>::size_type i= 0, n= min(num_rows(matrix), num_cols(matrix)); i < n; ++i) + ins[i][i] << value; +} + +}} // namespace mtl::matrix + +#endif // MTL_DIAGONAL_SETUP_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/dimension.hpp b/install/MTL/include/boost/numeric/mtl/matrix/dimension.hpp new file mode 100644 index 00000000..7acab089 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/dimension.hpp @@ -0,0 +1,117 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_DIMENSIONS_INCLUDE +#define MTL_DIMENSIONS_INCLUDE + +#include <iostream> +#include <cassert> +#include <boost/mpl/if.hpp> +#include <boost/utility/enable_if.hpp> + +namespace mtl { + +// dimension is a type for declaring matrix dimensions +// num_rows() and num_cols() return the number or rows and columns +// is_static says whether it is declared at compile time or not + +// Compile time version +namespace fixed +{ + + /// Compile-time dimensions + template <std::size_t Rows, std::size_t Cols> + struct dimensions + { + typedef std::size_t size_type; + + static size_type const Num_Rows= Rows; + static size_type const Num_Cols= Cols; + + // To have the same interface as fixed +#ifndef NDEBUG + /// Constructor does not need arguments but if given they are compared against the template arguments in debug mode + explicit dimensions(size_type r= Rows, size_type c= Cols) + { + assert(r == Rows); assert(c == Cols); + } +#else + explicit dimensions(size_type, size_type) {} + explicit dimensions(size_type) {} + explicit dimensions() {} +#endif + + size_type num_rows() const { return Rows; } ///< Number of rows + size_type num_cols() const { return Cols; } ///< Number of columns + + /// To check whether dimensions are static + static bool const is_static= true; + + /// Transposed dimension (type) + typedef dimensions<Cols, Rows> transposed_type; + transposed_type transpose() const + { + return transposed_type(); + } + }; + + /// Output of dimensions + template <std::size_t R, std::size_t C> + inline std::ostream& operator<< (std::ostream& stream, dimensions<R, C>) + { + return stream << R << 'x' << C; + } + +} // namespace fixed + +namespace non_fixed +{ + /// Run-time dimensions + struct dimensions + { + typedef std::size_t size_type; + + /// Constructor + dimensions(size_type r= 0, size_type c= 0) : r(r), c(c) {} + + /// Assignment + dimensions& operator=(const dimensions& x) + { + r= x.r; c= x.c; return *this; + } + size_type num_rows() const { return r; } ///< Number of rows + size_type num_cols() const { return c; } ///< Number of columns + + /// Transposed dimension + typedef dimensions transposed_type; + transposed_type transpose() + { + return transposed_type(c, r); + } + + /// To check whether dimensions are static + static bool const is_static= false; + protected: + size_type r, c; + }; + + /// Output of dimensions + inline std::ostream& operator<< (std::ostream& stream, dimensions d) + { + return stream << d.num_rows() << 'x' << d.num_cols(); + } + +} // namespace non_fixed + +} // namespace mtl + +#endif // MTL_DIMENSIONS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/element.hpp b/install/MTL/include/boost/numeric/mtl/matrix/element.hpp new file mode 100644 index 00000000..b84dbcd1 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/element.hpp @@ -0,0 +1,504 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. +// +// Algorithm inspired by Nick Vannieuwenhoven, written by Cornelius Steinhardt + + +#ifndef MTL_ELEMENT_INCLUDE +#define MTL_ELEMENT_INCLUDE + +#include <vector> +#include <set> +#include <algorithm> +#include <iostream> +#include <functional> + +#include <boost/unordered_set.hpp> + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/matrix/dense2D.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/utility/make_copy_or_reference.hpp> +#include <boost/numeric/itl/pc/comparators.hpp> + + +namespace mtl { namespace mat { + +/// A class representing an element with ValType equals the type of the numeric values +template <typename ValType> +class element +{ + +public: + /// The type of this element. + typedef element<ValType> element_type; + + /// The value type of the matrix and rhs elements. + typedef ValType value_type; + + /// The type of a set of neighbors. + typedef std::vector<element_type*, std::allocator<element_type*> > neighbor_collection_type; // trouble with Clang 4.2 w/o allocator + + /// An iterator over the neighbors of this element. + typedef typename neighbor_collection_type::iterator neighbor_iterator; + + /// The type of an unordered set of neighbors. + typedef typename boost::unordered_set< + element_type*, + compare::address_hasher<element_type>, + compare::address_compare_equal<element_type> + > neighbor_set_type; + + /// The type of the iterator over an unorderd set of neighbors. + typedef typename neighbor_set_type::iterator neighbor_set_iterator_type; + + /// The type of matrix. + typedef mtl::mat::dense2D<value_type> matrix_type; + + /// The type of the index vector. + typedef mtl::dense_vector<int> index_type; + + +/******************************************************************************* + * Constructors + ******************************************************************************/ + + + /** + * Constructs the element using the memory specified by the two references. + * + * p_indices: a reference to the memory where the indices may be stored. + * p_values: a reference to the memory where the values may be stored. + */ + public: + element(int p_sequence_number, const index_type& p_indices, const matrix_type& p_values) + : m_indices(p_indices), + m_values(p_values), + m_sequence_number(p_sequence_number) + {} + + element() + : m_sequence_number(-1) {} + + element(const element_type& other) + : m_sequence_number(-1) + { *this = other; } + + /// Deep copy the given element. + void operator=(const element_type& other) + { + m_sequence_number = other.m_sequence_number; + m_neighbors = other.m_neighbors; + + m_indices = other.m_indices; + m_values = other.m_values; + } + + /// Returns the unique identifier of this element. + inline int get_id() const { return m_sequence_number; } + inline int& get_id() {return m_sequence_number; } + + /// Returns the number of variables. + inline int nb_vars() const { return size(m_indices); } + + /// Returns the number of values. + inline int nb_values() const { return nb_vars()*nb_vars(); } + + /// Reference to the matrix of values. + inline matrix_type& get_values() { return m_values; } + + /// Constant reference to the matrix of values. + inline const matrix_type& get_values() const { return m_values; } + + /// Reference to the indices. + inline const index_type& get_indices() const { return m_indices; } + + /// Mutable reference to the indices. + inline index_type& get_indices() { return m_indices; } + + /// The actual number of non-zero values. + int nnz() const + { + const value_type zero= math::zero(value_type()); + int nbr_nz = 0; + for (int r = 0; r < nb_vars(); ++r) + for (int c = 0; c < nb_vars(); ++c) + nbr_nz += get_values()(r,c) != zero; + return nbr_nz; + } + + /// Reference to the set of neighbors. + neighbor_collection_type& get_neighbors() { return m_neighbors; } + + /// Reference to the set of neighbors. + const neighbor_collection_type& get_neighbors() const { return m_neighbors; } + + /// Number of neighbors this element is connected to. + int get_nb_neighbors() const { return int(m_neighbors.size()); } + + /// Add new neighbors, max 6 at the time + void add_neighbors(element* n1, element* n2= 0, element* n3= 0, + element* n4= 0, element* n5= 0, element* n6= 0) + { + m_neighbors.push_back(n1); + if (n2) { + m_neighbors.push_back(n2); + if (n3) m_neighbors.push_back(n3); + if (n4) m_neighbors.push_back(n4); + if (n5) m_neighbors.push_back(n5); + if (n6) m_neighbors.push_back(n6); + } + } + + +/******************************************************************************* + * Useful Inspector Methods + ******************************************************************************/ + + /// The set of nodes that is incident to the element. + boost::unordered_set<int> get_incident_nodes() const + { + boost::unordered_set<int> nodes(2 * get_nb_neighbors()); + for(typename neighbor_collection_type::const_iterator neigh_it = m_neighbors.begin(); + neigh_it != m_neighbors.end(); ++neigh_it) { + element_type& neigh = **neigh_it; + nodes.insert(neigh.get_indices().begin(), neigh.get_indices().end()); + } + // Remove the nodes of the element. + for( int i = 0; i < nb_vars(); ++i ) + nodes.erase( get_indices()(i) ); + return nodes; + } + + + /// Get the set of level-k neighbors, for a given k. + neighbor_set_type get_level_neighbors(const int level = 1) + { + neighbor_set_type result( get_nb_neighbors() * level ); + + if (level > 0) { + result.insert( m_neighbors.begin(), m_neighbors.end() ); + if (level > 1) { + for(int i = 0; i < get_nb_neighbors(); ++i) { + neighbor_set_type neighs(m_neighbors[i]->get_level_neighbors(level-1)); + result.insert( neighs.begin(), neighs.end() ); + } + result.erase( this ); + } + } + return result; + } + +/******************************************************************************* + * Manipulation + ******************************************************************************/ + public: + /// Permutes the rows and the columns of the element coefficient matrix along + /// with the indices such that the latter are sorted in ascending order. + void sort_indices() { + if(size(m_indices) == 0) { + assert(size(m_values) == 0); + return; + } + + bool sorted = true; + for(int i = 0; i < nb_vars()-1; ++i) { + sorted &= (get_indices()(i) < get_indices()(i+1)); + } + if(sorted) { + return; + } + + index_type orig_index( get_indices() ); + matrix_type orig_matrix( get_values() ); + + std::sort( + &(get_indices()(0)), + &(get_indices()(0))+nb_vars() + ); + + index_type orig_offset( nb_vars() ); + orig_offset = -1; + for(int i = 0; i < nb_vars(); ++i) { + int seek_idx = get_indices()(i); + int j = 0; + for(; (j < nb_vars()) && (orig_index(j) != seek_idx); ++j){}; + orig_offset(i) = j; + } + + matrix_type& values = get_values(); + for(int r = 0; r < nb_vars(); ++r) { + for(int c = 0; c < nb_vars(); ++c) { + values(r,c) = orig_matrix( orig_offset(r), orig_offset(c) ); + } + } + +#ifndef NDEBUG + sorted = true; + for(int i = 0; i < nb_vars()-1; ++i) { + sorted &= (get_indices()(i) < get_indices()(i+1)); + } + assert(sorted); +#endif + } + + + public: + /// Removes the given set of nodes from the element + template< class Vector > + void remove_nodes(const Vector& nodes, element_type& el) { + if(size(m_indices) == 0) { + assert(size(m_values) == 0); + return; + } + if(nb_vars() == 0) { + return; + } + +#ifndef NDEBUG + bool sorted = true; + for(unsigned int i = 1; i < mtl::size(nodes); ++i) { + sorted &= ( nodes[i-1] < nodes[i] ); + } + assert(sorted); +#endif + + const int nb_nodes = mtl::size(nodes); + + // Count number of remaining variables. + int new_nb_nodes = nb_vars(); + { + int i = 0, j = 0; + while( i < nb_vars() && j < nb_nodes ) { + const int diff = get_indices()(i) - nodes[j]; + if( diff < 0 ) { + ++i; + } else if( diff > 0 ) { + ++j; + } else { + --new_nb_nodes; + ++i; + ++j; + } + } + } + assert(new_nb_nodes >= 0); + + // Construct new index array. + index_type index; + index_type local_index(new_nb_nodes); + if(new_nb_nodes > 0) { + index.change_dim(new_nb_nodes); +// index = new index_type(new_nb_nodes); + int i = 0, j = 0, pos = 0; + while( i < nb_vars() && j < nb_nodes ) { + const int diff = get_indices()(i) - nodes[j]; + if( diff < 0 ) { + assert( pos < new_nb_nodes ); + // (*index)(pos) = get_indices()(i); + index[pos] = get_indices()(i); + local_index(pos) = i; + ++pos; + ++i; + } else if( diff > 0 ) { + ++j; + } else { + ++i; + ++j; + } + } + while( i < nb_vars() ) { + assert( pos < new_nb_nodes ); +// (*index)(pos) = get_indices()(i); + index[pos] = get_indices()(i); + local_index(pos) = i; + ++pos; + ++i; + } + } else { +// index = new index_type(0); + } + + matrix_type values; + if(new_nb_nodes > 0) { + values.change_dim( new_nb_nodes, new_nb_nodes ); + matrix_type tmp(get_values()), tmp2(new_nb_nodes, new_nb_nodes); + for(unsigned int i=0;i<size(local_index);i++){ + for(unsigned int j=0;j<size(local_index);j++){ + tmp2[i][j]=tmp[local_index(i)][local_index(j)]; + } + } + values = tmp2; + } else { +// std::cout<< "ELSE\n"; +// values = new matrix_type(0,0); + } + // Update the neighborhood. + std::set<int, std::less<int>, std::allocator<int> > remove_neighs; // trouble with Clang 4.2 w/o allocator + for( + neighbor_iterator neigh_it = m_neighbors.begin(); + neigh_it != m_neighbors.end(); + ++neigh_it + ) { + element_type& neigh = **neigh_it; + + // Search a matching index. + bool connected = false; + { + int i = 0, j = 0; + while( + (i < new_nb_nodes) && + (j < neigh.nb_vars()) && + !connected + ) { +// const int diff = (*index)(i) - neigh.get_indices()(j); + const int diff = index[i] - neigh.get_indices()(j); + if(diff < 0) { + ++i; + } else if(diff > 0) { + ++j; + } else { + connected = true; + } + } + } + + // If not found, then remove ourself from the neighbors and vice versa. + if(!connected) { + neighbor_iterator pos = std::find(neigh.get_neighbors().begin(), neigh.get_neighbors().end(), this ); + if( (pos != neigh.get_neighbors().end()) && (&neigh != &el) ) { + neigh.get_neighbors().erase(pos); + } + remove_neighs.insert( neigh.get_id() ); + } + } + + // Remove the neighbors we're no longer connected to. + for(std::set<int>::iterator it = remove_neighs.begin(); it != remove_neighs.end(); ++it) { + const int seek_seq_nbr = *it; + for (std::size_t j = 0; j < m_neighbors.size(); ++j) + if (m_neighbors[j] != 0 && m_neighbors[j]->get_id() == seek_seq_nbr) { + m_neighbors.erase( m_neighbors.begin()+j ); + break; + } + } + + if(new_nb_nodes == 0) { + m_neighbors.clear(); + } + + m_indices.change_dim(0); + m_values.change_dim(0, 0); + m_indices = index; + m_values = values; + } + + /// Absorbs the values of the given matrix with the given index. + template< class Matrix, class Vector > + void absorb(Matrix& other_values, Vector& other_indices) + { + const value_type zero= math::zero(value_type()); +#ifndef NDEBUG + bool sorted = true; + for(unsigned int i = 1; i < size(other_indices); ++i) { + sorted &= ( other_indices(i-1) < other_indices(i) ); + } + assert(sorted); +#endif + + const int other_idx_size = size( other_indices ); + + // Determine set of common indices. + const int max_common_idx = + (nb_vars() < other_idx_size) ? nb_vars() : other_idx_size; + mtl::dense_vector<int> my_idx( max_common_idx ); + mtl::dense_vector<int> ot_idx( max_common_idx ); + int offset = 0; + for(int i = 0, j = 0; i < nb_vars() && j < other_idx_size; ) { + int diff = (get_indices()(i) - other_indices(j)); + if(diff == 0) { + my_idx(offset) = i; + ot_idx(offset) = j; + ++offset; + ++i; + ++j; + } else if(diff < 0) { + ++i; + } else { + ++j; + } + } + + // Absorb the values. + for(int i = 0; i < offset; ++i) { + for(int j = i; j < offset; ++j) { + get_values()( my_idx(i), my_idx(j) ) += other_values( ot_idx(i), ot_idx(j) ); + other_values( ot_idx(i), ot_idx(j) ) = zero; + get_values()( my_idx(j), my_idx(i) ) += other_values( ot_idx(j), ot_idx(i) ); + other_values( ot_idx(j), ot_idx(i) ) = zero; + } + } + } + + /// Removes the numerical values from the element. + void clear() { + m_neighbors.clear(); + m_neighbors.resize(1); + matrix_type empty; + swap(m_values, empty); + m_indices.change_dim(0); + } + + template< class ValueType > friend class element_structure; + + private: + /// The set of neighbors of the element. + neighbor_collection_type m_neighbors; + + /// The set of indices of this element. + index_type m_indices; + + /// The [Size x Size] element matrix. + matrix_type m_values; + + /// A unique sequence number for the element, indicating it's order relative to other elements. + int m_sequence_number; + + int *dummy; +}; + + +/// Print an element to an output stream. +template<typename OStream, class ValueType> +OStream& operator<<(OStream& out, element<ValueType>& el) +{ + out << "ID: " << el.get_id() << "\n"; + if(el.nb_vars() > 0) { + out << "Indices: (" << el.get_indices()(0); + for(int i = 1; i < el.nb_vars(); ++i) { + out << ", " << el.get_indices()(i); + } + out << ")\n"; + } else { + out << "Indices: ()\n"; + } + out << "Neighbors: ("; + if (el.nb_vars() > 0) + for(int i = 0; i < el.get_nb_neighbors(); ++i) + out << el.get_neighbors()[i]->get_id() << (i+1 < el.get_nb_neighbors()? ", " : ")\n"); + out << "Values: \n" << el.get_values(); + return out; +} + + }} // mtl::matrix + +#endif // MTL_ELEMENT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/element_array.hpp b/install/MTL/include/boost/numeric/mtl/matrix/element_array.hpp new file mode 100644 index 00000000..b6127154 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/element_array.hpp @@ -0,0 +1,51 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ELEMENT_ARRAY_INCLUDE +#define MTL_ELEMENT_ARRAY_INCLUDE + +namespace mtl { namespace mat { + +template <typename Array, typename Rows, typename Cols> +struct element_array_t +{ + explicit element_array_t(const Array& array, const Rows& rows, const Cols& cols) + : array(array), rows(rows), cols(cols) + {} + + const Array& array; + const Rows& rows; + const Cols& cols; +}; + + +template <typename Array, typename Rows, typename Cols> +element_array_t<Array, Rows, Cols> +inline element_array(const Array& array, const Rows& rows, const Cols& cols) +{ + return element_array_t<Array, Rows, Cols>(array, rows, cols); +} + +template <typename Array, typename Rows> +element_array_t<Array, Rows, Rows> +inline element_array(const Array& array, const Rows& rows) +{ + return element_array_t<Array, Rows, Rows>(array, rows, rows); +} + +} // namespace matrix + +using mat::element_array; + +} // namespace mtl + +#endif // MTL_ELEMENT_ARRAY_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/element_matrix.hpp b/install/MTL/include/boost/numeric/mtl/matrix/element_matrix.hpp new file mode 100644 index 00000000..55610817 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/element_matrix.hpp @@ -0,0 +1,49 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ELEMENT_MATRIX_INCLUDE +#define MTL_ELEMENT_MATRIX_INCLUDE + +namespace mtl { namespace mat { + + +template <typename Matrix, typename Rows, typename Cols> +struct element_matrix_t +{ + explicit element_matrix_t(const Matrix& matrix, const Rows& rows, const Cols& cols) + : matrix(matrix), rows(rows), cols(cols) + {} + + const Matrix& matrix; + const Rows& rows; + const Cols& cols; +}; + + +template <typename Matrix, typename Rows, typename Cols> +element_matrix_t<Matrix, Rows, Cols> +inline element_matrix(const Matrix& matrix, const Rows& rows, const Cols& cols) +{ + return element_matrix_t<Matrix, Rows, Cols>(matrix, rows, cols); +} + +template <typename Matrix, typename Rows> +element_matrix_t<Matrix, Rows, Rows> +inline element_matrix(const Matrix& matrix, const Rows& rows) +{ + return element_matrix_t<Matrix, Rows, Rows>(matrix, rows, rows); +} + + +}} // namespace mtl::matrix + +#endif // MTL_ELEMENT_MATRIX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/element_structure.hpp b/install/MTL/include/boost/numeric/mtl/matrix/element_structure.hpp new file mode 100644 index 00000000..313ab7b6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/element_structure.hpp @@ -0,0 +1,300 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. +// +// Algorithm inspired by Nick Vannieuwenhoven, written by Cornelius Steinhardt + + + +#ifndef MTL_ELEMENT_STRUCTURE_INCLUDE +#define MTL_ELEMENT_STRUCTURE_INCLUDE + +#include <iostream> +#include <ostream> + +#include <boost/numeric/mtl/matrix/element.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> + +namespace mtl { namespace mat { + +#if 0 ///TODO need for write elmement_structur +namespace print { + + template< class Type > + struct print_type { + template<class Stream> + static void print(Stream&); + }; + + template< > + struct print_type<double> { + template<class Stream> + static void print(Stream& str) { + str << "double\n"; + } + }; + + template< > + struct print_type<float> { + template<class Stream> + static void print(Stream& str) { + str << "double\n"; + } + }; + + template< > + struct print_type<std::complex<double> > { + template<class Stream> + static void print(Stream& str) { + str << "complex\n"; + } + }; + + template< class Type > + struct print_value { + template<class Stream> + static void print(Stream&); + }; + + template< > + struct print_value<double> { + template<class Stream> + static void print(Stream& str, double& val) { + str << std::scientific << std::setprecision(15); + str << val; + } + }; + + template< > + struct print_value<float> { + template<class Stream> + static void print(Stream& str, float& val) { + str << std::scientific << std::setprecision(15); + str << double(val); + } + }; + + template< > + struct print_value<std::complex<double> > { + template<class Stream> + static void print(Stream& str, std::complex<double>& val) { + str << std::scientific << std::setprecision(15); + str << val.real() << "\t" << val.imag() << "\t"; + } + }; +} + #endif + +/** + * A generic abstract base class for meshes. It describes the concept of a mesh. + */ +template< class ValueType > +class element_structure +{ + +public: + /// Type of the numerical values of the element coefficient matrices. + typedef ValueType value_type; + + /// Type of the element. + typedef element<value_type> element_type; + + /// Type of index arrays. + typedef typename element_type::index_type index_type; + // Type of the indices themselves + typedef typename Collection<index_type>::value_type ii_type; + + /// Type of the iterator over the elements of the mesh. + typedef element_type* element_iterator; + + /// Type of this class. + typedef element_structure<ValueType> this_type; + typedef this_type self; + + /// Standard constructor. + element_structure(int total_elements= 0, int total_vars= 0, element_type* elements= 0) + : m_total_elements(total_elements), m_total_vars(total_vars), + m_elements(elements), index_heap(0), value_heap(0) + { } + + /// consume elements into element_structure + void consume(int total_elements, int total_vars, element_type* elements) + { + m_total_elements= total_elements; + m_total_vars= total_vars; + delete[] m_elements; + m_elements= elements; + delete[] index_heap; index_heap= 0; + delete[] value_heap; value_heap= 0; + } + + + /// Copy the given mesh. + element_structure(this_type const& other) + : m_total_elements(other.m_total_elements), + m_total_vars(other.m_total_vars), + m_elements(m_total_elements == 0 ? 0 : new element_type[m_total_elements]), + index_heap(0), value_heap(0) + { + typedef typename element_type::neighbor_collection_type neigh_coll_type; + + int j = 0; + bool ordered = true; + for(element_iterator it = other.element_begin(); it != other.element_end(); ++it) { + // Deep copy the elements. + m_elements[j] = *it; + ordered &= (it->get_id() == j); + ++j; + } + assert( ordered ); + // Reconstruct the network of neighbors. + for(element_iterator it = this->element_begin(); it != this->element_end(); ++it) { + neigh_coll_type new_neighs; + neigh_coll_type& old_neighs = it->get_neighbors(); + for(int i = 0; i < it->get_nb_neighbors(); ++i) { + element_type& neigh = *(old_neighs[i]); + int pos = neigh.get_id(); + new_neighs.push_back( this->m_elements+pos ); + } + old_neighs.assign(new_neighs.begin(), new_neighs.end()); + } + } + + /// Destructor + ~element_structure() { delete[] m_elements; delete[] index_heap; delete[] value_heap; } + + /// make compakt memory block from elements + void make_compact() + { + assert(index_heap == 0); assert(value_heap == 0); // might be relaxed later + + int total_indices= 0, total_values= 0; + for (int i= 0; i < m_total_elements; i++) { + total_indices+= m_elements[i].nb_vars(); + total_values+= m_elements[i].nb_values(); + } + index_heap= new ii_type[total_indices]; + value_heap= new value_type[total_values]; + + int index_pos= 0, value_pos= 0; + for (int i= 0; i < m_total_elements; i++) { + element_type& element= m_elements[i]; + int s= element.nb_vars(); + index_type index_tmp(s, index_heap + index_pos); + index_tmp= element.get_indices(); + swap(index_tmp, element.get_indices()); + index_pos+= s; + + typename element_type::matrix_type value_tmp(s, s, value_heap + value_pos); + value_tmp= element.get_values(); + swap(value_tmp, element.get_values()); + value_pos+= s * s; + } + assert(total_indices == index_pos); + assert(total_values == value_pos); + } + + /******************************************************************************* + * Inspector Members + ******************************************************************************/ + + /// Total number of elements in the grid. + int get_total_elements() const { return m_total_elements; } + + /// Total number of variables. + int get_total_vars() const { return m_total_vars; } + + /// Total number of non-zero values. + int get_total_nnz() const + { + int nnz = 0; + for(element_iterator it = element_begin(); it != element_end(); ++it) { + nnz += it->nnz(); + } + return nnz; + } + + /// Iterator to the first element. + element_iterator element_begin() const { return m_elements + 0; } + + /// An iterator to the element past the last element. + element_iterator element_end() const { return m_elements + this->get_total_elements(); } + +#if 1 + /// Writes the elements to the specified file. TODO at the moment very slow + void write_to_file(const std::string& filename) + { + //using namespace print; + + std::ofstream file(filename.c_str()); + + // Write header information. + file << get_total_elements() << "\n"; + file << this->get_total_vars() << "\n"; + //print_type<value_type>::print(file); + + // Write element matrices. + for(element_iterator it = element_begin(); it != element_end(); ++it) { + // Write indices. + for(int i = 0; i < it->nb_vars()-1; ++i) { + file << it->get_indices()(i) << " "; + } + file << it->get_indices()(it->nb_vars()-1) << "\n"; + + // Write values. + for(int r = 0; r < it->nb_vars(); ++r) { + for(int c = 0; c < it->nb_vars()-1; ++c) { + //print_value<value_type>::print(file, it->get_values()(r,c)); + file << it->get_values()(r,c); file << " "; + } + //print_value<value_type>::print(file, it->get_values()(r,it->nb_vars()-1)); + file << it->get_values()(r,it->nb_vars()-1); + file << "\n"; + } + file << "\n"; + } + } +#endif + + int m_total_elements; ///< The total number of elements. + int m_total_vars; ///< The total number of variables. + element_type* m_elements; ///< The elements of the grid, stored consecutively. + + ii_type* index_heap; + value_type* value_heap; +}; + +template <typename ValueType> +inline std::size_t num_rows(const element_structure<ValueType>& A) +{ return A.get_total_vars(); } + +template <typename ValueType> +inline std::size_t num_cols(const element_structure<ValueType>& A) +{ return A.get_total_vars(); } + +template <typename ValueType> +inline std::size_t size(const element_structure<ValueType>& A) +{ return A.get_total_vars() * A.get_total_vars(); } + + +template <typename ValueType> +inline void swap(element_structure<ValueType>& x, element_structure<ValueType>& y) +{ + swap(x.m_total_elements, y.m_total_elements); + swap(x.m_total_vars, y.m_total_vars); + swap(x.m_elements, y.m_elements); +} + + +}} // mtl::matrix + + +#endif // MTL_ELEMENT_STRUCTURE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/ell_matrix.hpp b/install/MTL/include/boost/numeric/mtl/matrix/ell_matrix.hpp new file mode 100644 index 00000000..792d9b69 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/ell_matrix.hpp @@ -0,0 +1,209 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_ELL_MATRIX_INCLUDE +#define MTL_MATRIX_ELL_MATRIX_INCLUDE + +#include <vector> +#include <cassert> + +#include <boost/static_assert.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/mtl/utility/wrapped_object.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/operation/std_output_operator.hpp> + + +namespace mtl { namespace mat { + +/// Matrix in Ell-Pack format; still in early stage, to be used with care (if at all) +template <typename Value, typename Parameters = mat::parameters<> > +class ell_matrix + : public base_matrix<Value, Parameters>, + public const_crtp_base_matrix< ell_matrix<Value, Parameters>, Value, typename Parameters::size_type >, + public crtp_matrix_assign< ell_matrix<Value, Parameters>, Value, typename Parameters::size_type >, + public mat_expr< ell_matrix<Value, Parameters> > +{ + BOOST_STATIC_ASSERT((mtl::traits::is_row_major<Parameters>::value)); + + typedef base_matrix<Value, Parameters> super; + typedef ell_matrix self; + typedef mat_expr< ell_matrix<Value, Parameters> > expr_base; + + void set_stride() + { my_stride= (this->dim1() + alignment - 1) / alignment * alignment; } + + public: + typedef Parameters parameters; + typedef typename Parameters::orientation orientation; + typedef typename Parameters::dimensions dimensions; + typedef Value value_type; + typedef value_type const_reference; + + typedef typename Parameters::size_type size_type; + typedef crtp_matrix_assign<self, Value, size_type> assign_base; + + static const unsigned alignment= 32; // TBD: make more flexible later + + /// Default constructor + explicit ell_matrix () + : super(non_fixed::dimensions(0, 0)), my_slots(0), inserting(false) + { set_stride(); } + + /// Construct matrix of size \p num_rows times \p num_cols + explicit ell_matrix (size_type num_rows, size_type num_cols) + : super(non_fixed::dimensions(num_rows, num_cols)), my_slots(0), inserting(false) + { set_stride(); } + + using assign_base::operator=; + + /// Print internal representation + template <typename OStream> + void print_internal(OStream& os) const + { +# ifdef MTL_HAS_STD_OUTPUT_OPERATOR + os << "indices = " << indices << '\n'; + os << "values = " << data << '\n'; +# endif + } + + /// Entry in row \p r and column \p c + value_type operator()(size_type r, size_type c) const + { + for (size_type k= r, i= 0; i < my_slots; ++i, k+= my_stride) + if (indices[k] == c) + return data[k]; + return value_type(0); + } + + const std::vector<size_type>& ref_minor() const { return indices; } ///< Refer index vector [advanced] + std::vector<size_type>& ref_minor() { return indices; } ///< Refer index vector [advanced] + const std::vector<value_type>& ref_data() const { return data; } ///< Refer data vector [advanced] + std::vector<value_type>& ref_data() { return data; } ///< Refer data vector [advanced] + + size_type stride() const { return my_stride; } /// Stride [advanced] + size_type slots() const { return my_slots; } /// Slots, i.e. maximum number of entries per row/column + + void make_empty() + { my_slots= 0; indices.resize(0); data.resize(0); } + + void change_dim(size_type r, size_type c) + { + if (this->num_rows() != r || this->num_cols() != c) { + super::change_dim(r, c); + set_stride(); + make_empty(); + } + } + + protected: + void allocate_slots(size_type s) + { + my_slots= s; + size_type size= my_stride * s; + indices.resize(size); data.resize(size); + } + + template <typename V, typename P, typename Updater> friend struct ell_matrix_inserter; + + std::vector<value_type> data; + std::vector<size_type> indices; + size_type my_stride, my_slots; + bool inserting; +}; + + +template <typename Value, typename Parameters, typename Updater = mtl::operations::update_store<Value> > +struct ell_matrix_inserter + : wrapped_object<compressed2D<Value, Parameters> >, + compressed2D_inserter<Value, Parameters, Updater> +{ + typedef typename Parameters::size_type size_type; + typedef Value value_type; + typedef ell_matrix<Value, Parameters> matrix_type; + typedef compressed2D<Value, Parameters> compressed_type; + typedef wrapped_object<compressed_type> wrapped_type; + typedef compressed2D_inserter<Value, Parameters, Updater> base_inserter; + + explicit ell_matrix_inserter(matrix_type& A, size_type slot_size = 5) + : wrapped_type(num_rows(A), num_cols(A)), + base_inserter(wrapped_type::wrapped_object_member, slot_size), + A(A) + { + A.inserting= true; + } + + ~ell_matrix_inserter() + { + this->finish(); + const compressed_type& B= this->wrapped_object_member; + // std::cout << "Finished insertion!\nA (compressed2D) is:\n" << B; + + size_type max_slots= 0; + for (size_type i= 0; i < B.dim1(); ++i) { + size_type s= this->starts[i+1] - this->starts[i]; + if (s > max_slots) + max_slots= s; + } + A.allocate_slots(max_slots); + + for (size_type i= 0; i < B.dim1(); ++i) { + size_type patch_entries= max_slots - (this->starts[i+1] - this->starts[i]), k= i, + patch_index= 0; + for (size_type j= this->starts[i]; j < this->starts[i+1]; ++j, k+= A.my_stride) { + patch_index= A.indices[k]= B.ref_minor()[j]; + A.data[k]= B.data[j]; + } + for (size_type j= 0; j < patch_entries; ++j, k+= A.my_stride) { + A.indices[k]= patch_index; + A.data[k]= value_type(0); + } + } + A.my_nnz= B.nnz(); + A.inserting= false; + } + + matrix_type& A; +}; + +// ================ +// Free functions +// ================ + +template <typename Value, typename Parameters> +typename ell_matrix<Value, Parameters>::size_type +inline num_rows(const ell_matrix<Value, Parameters>& matrix) +{ + return matrix.num_rows(); +} + +template <typename Value, typename Parameters> +typename ell_matrix<Value, Parameters>::size_type +inline num_cols(const ell_matrix<Value, Parameters>& matrix) +{ + return matrix.num_cols(); +} + +template <typename Value, typename Parameters> +// typename ell_matrix<Value, Parameters>::size_type risks overflow +std::size_t +inline size(const ell_matrix<Value, Parameters>& matrix) +{ + return std::size_t(matrix.num_cols()) * std::size_t(matrix.num_rows()); +} + + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_ELL_MATRIX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/hermitian_view.hpp b/install/MTL/include/boost/numeric/mtl/matrix/hermitian_view.hpp new file mode 100644 index 00000000..9875fb0d --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/hermitian_view.hpp @@ -0,0 +1,127 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_HERMITIAN_VIEW_INCLUDE +#define MTL_HERMITIAN_VIEW_INCLUDE + +#include <iostream> +#include <boost/shared_ptr.hpp> +#include <boost/numeric/mtl/matrix/map_view.hpp> +#include <boost/numeric/mtl/matrix/transposed_view.hpp> +#include <boost/numeric/mtl/operation/conj.hpp> +#include <boost/numeric/mtl/operation/matrix_bracket.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> + + +namespace mtl { namespace mat { + +template <class Matrix> +struct hermitian_view + : private transposed_view<Matrix>, + public map_view<mtl::sfunctor::conj<typename Matrix::value_type>, + transposed_view<Matrix> > +{ + typedef transposed_view<Matrix> trans_base; + typedef mtl::sfunctor::conj<typename Matrix::value_type> functor_type; + typedef map_view<functor_type, transposed_view<Matrix> > base; + typedef hermitian_view self; + typedef const Matrix& const_ref_type; + typedef typename Collection<Matrix>::size_type size_type; + typedef typename Collection<Matrix>::value_type value_type; + + typedef typename OrientedCollection<trans_base>::orientation orientation; // Should not be needed because defined in Collection (bug in g++???) + + hermitian_view(const Matrix& matrix) + : trans_base(const_cast<Matrix&>(matrix)), + base(functor_type(), static_cast<trans_base&>(*this)) + {} + +#if 0 + hermitian_view(boost::shared_ptr<Matrix> p) + : trans_base(p), base(functor_type(), static_cast<trans_base&>(*this)) + {} +#endif + + typename base::value_type operator()(size_type r, size_type c) const { return base::operator()(r, c); } + + operations::bracket_proxy<self, const self&, value_type> + operator[] (size_type r) const + { + return operations::bracket_proxy<self, const self&, value_type>(*this, r); + } + + friend size_type inline num_rows(const self& A) { return num_rows((const base&)(A)); } + friend size_type inline num_cols(const self& A) { return num_cols((const base&)(A)); } + + const_ref_type const_ref() const + { + // make two statements because nvcc cannot handle ref.ref + const transposed_view<Matrix>& r1= base::ref; + return r1.ref; + } + + size_type nnz() const { return base::nnz(); } + + friend inline std::ostream& operator<<(std::ostream& os, const self& A) { return os << (const base&)(A); } +}; + +// If not defined ambigous between map_view and transposed_view +template <class Matrix> +inline std::size_t size(const hermitian_view<Matrix>& A) +{ + return num_rows(A) * num_rows(A); +} + +// TBD submatrix of Hermitian (not trivial) + + +}} // namespace mtl::matrix + + + +// Traits for Hermitian views +namespace mtl { namespace traits { + +template <typename Matrix> +struct row< mtl::mat::hermitian_view<Matrix> > + : public row< mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, + mtl::mat::transposed_view<Matrix> > > +{}; + +template <typename Matrix> +struct col< mtl::mat::hermitian_view<Matrix> > + : public col< mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, + mtl::mat::transposed_view<Matrix> > > +{}; + +template <typename Matrix> +struct const_value< mtl::mat::hermitian_view<Matrix> > + : public const_value< mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, + mtl::mat::transposed_view<Matrix> > > +{}; + +template <typename Tag, typename Matrix> +struct range_generator< Tag, mtl::mat::hermitian_view<Matrix> > + : public range_generator< Tag, mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, + mtl::mat::transposed_view<Matrix> > > +{}; + +template <typename Matrix> +struct range_generator< tag::major, mtl::mat::hermitian_view<Matrix> > + : public range_generator< tag::major, mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, + mtl::mat::transposed_view<Matrix> > > +{}; + + +}} // mtl::traits + +#endif // MTL_HERMITIAN_VIEW_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/hessian_setup.hpp b/install/MTL/include/boost/numeric/mtl/matrix/hessian_setup.hpp new file mode 100644 index 00000000..07b507ac --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/hessian_setup.hpp @@ -0,0 +1,100 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_HESSIAN_MATRIX_UTILITIES_INCLUDE +#define MTL_HESSIAN_MATRIX_UTILITIES_INCLUDE + +#include <cmath> +#include <iostream> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/mtl/operation/entry_similar.hpp> + +namespace mtl { namespace mat { + +/// Fills a matrix A with A[i][j] = factor * (i + j) +/** Intended for dense matrices. + Works on sparse matrices with inserter but is very expensive. **/ +template <typename Matrix, typename Value> +void hessian_setup(Matrix& A, Value factor) +{ + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + + inserter<Matrix> ins(A, num_cols(A)); + + for (size_type r= 0; r < num_rows(A); r++) + for (size_type c= 0; c < num_cols(A); c++) + ins[r][c] << factor * (value_type(r) + value_type(c)); +} + +namespace impl { + + /* + - Check matrix product C = A * B with: + - A is MxN, B is NxL, C is MxL + - with matrices a_ij = i+j, b_ij = 2(i+j); + - c_ij = 1/3 N (1 - 3i - 3j + 6ij - 3N + 3iN + 3jN + 2N^2). + + */ + // Not really generic + template <typename Value> + double inline hessian_product_i_j (Value i, Value j, Value N) + { + return 1.0/3.0 * N * (1.0 - 3*i - 3*j + 6*i*j - 3*N + 3*i*N + 3*j*N + 2*N*N); + } + + template <typename Value> + inline bool similar_values(Value x, Value y) + { + using std::abs; using std::max; + return abs(x - y) / max(abs(x), abs(y)) < 0.000001; + } + + template <typename Matrix> + void inline check_entry(Matrix const& C, unsigned long r, unsigned long c, + unsigned long reduced_dim, double factor) + { + if (!entry_similar(C, r, c, factor * hessian_product_i_j(r, c, reduced_dim), 0.00001)) { + std::cerr << "Result in C[" << r << "][" << c << "] should be " + << factor * hessian_product_i_j(r, c, reduced_dim) + << " but is " << C[r][c] << "\n"; + MTL_THROW(unexpected_result()); + } + } + +} // impl + + +/// Check if matrix C is A * B with A and B set by hessian_setup +/** C has dimensions M x L and reduced_dim is N, see hessian_setup. **/ +template <typename Matrix> +void check_hessian_matrix_product(Matrix const& C, typename Matrix::size_type reduced_dim, double factor= 1.0) +{ + if (num_rows(C) * num_cols(C) == 0) return; // otherwise out of range + + impl::check_entry(C, 0, 0, reduced_dim, factor); + impl::check_entry(C, 0, num_cols(C)-1, reduced_dim, factor); + impl::check_entry(C, num_rows(C)-1, 0, reduced_dim, factor); + impl::check_entry(C, num_rows(C)-1, num_cols(C)-1, reduced_dim, factor); + impl::check_entry(C, num_rows(C)/2, num_cols(C)/2, reduced_dim, factor); +} + +} // namespace matrix; + +using mat::hessian_setup; +using mat::check_hessian_matrix_product; + +} // namespace mtl + +#endif // MTL_HESSIAN_MATRIX_UTILITIES_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/identity.hpp b/install/MTL/include/boost/numeric/mtl/matrix/identity.hpp new file mode 100644 index 00000000..fe9bef77 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/identity.hpp @@ -0,0 +1,38 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_IDENTITY_INCLUDE +#define MTL_MATRIX_IDENTITY_INCLUDE + +// #include <boost/numeric/linear_algebra/identity.hpp> +// #include <boost/numeric/mtl/mtl_fwd.hpp> +// #include <boost/numeric/mtl/matrix/parameter.hpp> +// #include <boost/numeric/mtl/matrix/diagonal_setup.hpp> + +#include <boost/numeric/mtl/matrix/identity2D.hpp> + +namespace mtl { namespace mat { + +inline identity2D identity(std::size_t nrows, std::size_t ncols) +{ + return identity2D(nrows, ncols); +} + + +inline identity2D identity(std::size_t nrows) +{ + return identity2D(nrows, nrows); +} + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_IDENTITY_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/identity2D.hpp b/install/MTL/include/boost/numeric/mtl/matrix/identity2D.hpp new file mode 100644 index 00000000..c0aac8fb --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/identity2D.hpp @@ -0,0 +1,83 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_IDENTITY2D_INCLUDE +#define MTL_MATRIX_IDENTITY2D_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/vector/mat_cvec_multiplier.hpp> + +namespace mtl { namespace mat { + +/// Matrix-free linear operator for identity +struct identity2D +{ + /// Constructor for \p m by \p m matrix + identity2D(std::size_t m) : m(m), n(m) {} + + /// Constructor for \p m by \p n matrix + identity2D(std::size_t m, std::size_t n) : m(m), n(n) {} + + /// Member function that realizes the multiplication + template <typename VectorIn, typename VectorOut, typename Assign> + void mult(const VectorIn& v, VectorOut& w, Assign) const + { + MTL_DEBUG_THROW_IF(std::size_t(size(v)) != n, incompatible_size()); + MTL_DEBUG_THROW_IF(size(w) != 0 && std::size_t(size(w)) != m, incompatible_size()); + + if (size(w) == 0) + w.change_dim(m); + + if (m == n) + Assign::first_update(w, v); + else if (m < n) + Assign::first_update(w, v[irange(m)]); + else { + VectorOut w1(w[irange(n)]), w2(w[irange(n, imax)]); + Assign::first_update(w1, v); + Assign::init(w2); + } + } + + /// Multiplication is procastinated until we know where the product goes + template <typename VectorIn> + vec::mat_cvec_multiplier<identity2D, VectorIn> operator*(const VectorIn& v) const + { return vec::mat_cvec_multiplier<identity2D, VectorIn>(*this, v); } + + std::size_t m, n; +}; + +inline std::size_t size(const identity2D& A) { return A.m * A.n; } ///< Matrix size +inline std::size_t num_rows(const identity2D& A) { return A.m; } ///< Number of rows +inline std::size_t num_cols(const identity2D& A) { return A.n; } ///< Number of columns + +}} // namespace mtl::matrix + +namespace mtl { + + template <> + struct Collection<mat::identity2D> + { + typedef double value_type; + typedef std::size_t size_type; + }; + + namespace ashape { + template <> struct ashape_aux<mtl::mat::identity2D> + { typedef nonscal type; }; + } +} + +#endif // MTL_MATRIX_IDENTITY2D_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/implicit_dense.hpp b/install/MTL/include/boost/numeric/mtl/matrix/implicit_dense.hpp new file mode 100644 index 00000000..7ca30eca --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/implicit_dense.hpp @@ -0,0 +1,279 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_IMPLICIT_DENSE_INCLUDE +#define MTL_MATRIX_IMPLICIT_DENSE_INCLUDE + +#include <vector> +#include <boost/numeric/linear_algebra/inverse.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp> +#include <boost/numeric/mtl/matrix/mat_expr.hpp> +#include <boost/numeric/mtl/concept/std_concept.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> + +#ifdef MTL_HAS_MPI +# include <boost/numeric/mtl/matrix/distributed.hpp> +# include <boost/numeric/mtl/matrix/inserter.hpp> +# include <boost/mpi/collectives.hpp> +#endif + +namespace mtl { namespace mat { + +template <typename Functor> +class implicit_dense + : public const_crtp_base_matrix< implicit_dense<Functor>, + typename Functor::result_type, typename Functor::size_type >, + public mat_expr< implicit_dense<Functor> > +{ + typedef implicit_dense self; + public: + typedef mtl::tag::row_major orientation; // for completeness + typedef typename Functor::result_type value_type; + typedef typename Functor::result_type const_reference; + typedef typename Functor::size_type size_type; + + // Should not be needed, to be removed after transposed_view is cleaned up + typedef index::c_index index_type; + typedef mtl::traits::detail::matrix_element_key<self> key_type; + typedef mtl::non_fixed::dimensions dim_type; + + explicit implicit_dense (const Functor& functor) : my_functor(functor) {} + + value_type operator() (size_type r, size_type c) const { return my_functor(r, c); } + + size_type nnz() const { return dim1() * dim2(); } + size_type dim1() const { return num_rows(my_functor); } + size_type dim2() const { return num_cols(my_functor); } + + friend size_type inline num_rows(const self& A) { return num_rows(A.my_functor); } + friend size_type inline num_cols(const self& A) { return num_cols(A.my_functor); } + + Functor& functor() { return my_functor; } + Functor const& functor() const { return my_functor; } + + private: + Functor my_functor; +}; + +template <typename Functor> +typename Functor::size_type inline size(const implicit_dense<Functor>& A) +{ + return num_rows(A) * num_cols(A); +} + +// ========== +// Sub matrix +// ========== + +// To do later + +}} // namespace mtl::matrix + + +namespace mtl { namespace traits { + + // ================ + // Range generators + // For cursors + // ================ + + template <typename Functor> + struct range_generator<glas::tag::row, mtl::mat::implicit_dense<Functor> > + : detail::all_rows_range_generator<mtl::mat::implicit_dense<Functor>, complexity_classes::linear> + {}; + + template <typename Functor> + struct range_generator<glas::tag::major, mtl::mat::implicit_dense<Functor> > + : range_generator<glas::tag::row, mtl::mat::implicit_dense<Functor> > + {}; + + template <typename Functor> + struct range_generator<glas::tag::nz, + detail::sub_matrix_cursor<mtl::mat::implicit_dense<Functor>, glas::tag::row, 2> > + : detail::all_cols_in_row_range_generator<detail::sub_matrix_cursor<mtl::mat::implicit_dense<Functor>, glas::tag::row, 2> > + {}; + + template <typename Functor> + struct range_generator<glas::tag::col, mtl::mat::implicit_dense<Functor> > + : detail::all_cols_range_generator<mtl::mat::implicit_dense<Functor>, complexity_classes::linear> + {}; + + template <typename Functor> + struct range_generator<glas::tag::nz, + detail::sub_matrix_cursor<mtl::mat::implicit_dense<Functor>, glas::tag::col, 2> > + : detail::all_rows_in_col_range_generator<detail::sub_matrix_cursor<mtl::mat::implicit_dense<Functor>, glas::tag::col, 2> > + {}; + + + template <typename Tag, typename Value> + struct range_generator<Tag, mtl::mat::ones_matrix<Value> > + : public range_generator<Tag, mtl::mat::implicit_dense<mtl::mat::ones_functor<Value> > > + {}; + + template <typename Value> + struct range_generator<glas::tag::major, mtl::mat::ones_matrix<Value> > + : public range_generator<glas::tag::major, mtl::mat::implicit_dense<mtl::mat::ones_functor<Value> > > + {}; + + template <typename Tag, typename Value> + struct range_generator<Tag, mtl::mat::hilbert_matrix<Value> > + : public range_generator<Tag, mtl::mat::implicit_dense<mtl::mat::hilbert_functor<Value> > > + {}; + + template <typename Value> + struct range_generator<glas::tag::major, mtl::mat::hilbert_matrix<Value> > + : public range_generator<glas::tag::major, mtl::mat::implicit_dense<mtl::mat::hilbert_functor<Value> > > + {}; + + template <typename Tag, typename Vector1, typename Vector2> + struct range_generator<Tag, mtl::mat::outer_product_matrix<Vector1, Vector2> > + : public range_generator<Tag, mtl::mat::implicit_dense<mtl::mat::outer_product_functor<Vector1, Vector2> > > + {}; + + template <typename Vector1, typename Vector2> + struct range_generator<glas::tag::major, mtl::mat::outer_product_matrix<Vector1, Vector2> > + : public range_generator<glas::tag::major, mtl::mat::implicit_dense<mtl::mat::outer_product_functor<Vector1, Vector2> > > + {}; + +}} // mtl::traits + +// ============= +// Some functors +// ============= + + +namespace mtl { namespace mat { + +template <typename Value= int> +class ones_functor +{ + typedef ones_functor self; + public: + typedef std::size_t size_type; + typedef Value result_type; + + ones_functor(size_type nr, size_type nc) : nr(nr), nc(nc) {} + + friend size_type inline num_rows(const self& A) { return A.nr; } + friend size_type inline num_cols(const self& A) { return A.nc; } + + result_type operator()(size_type, size_type) const { return Value(1); } + + private: + size_type nr, nc; +}; + + +template <typename Value= double> +class hilbert_functor +{ + typedef hilbert_functor self; + public: + typedef std::size_t size_type; + typedef Value result_type; + + hilbert_functor(size_type nr, size_type nc) : nr(nr), nc(nc) {} + + friend size_type inline num_rows(const self& A) { return A.nr; } + friend size_type inline num_cols(const self& A) { return A.nc; } + + result_type operator()(size_type r, size_type c) const + { + using math::reciprocal; + return reciprocal(Value(r + c + 1)); + } + private: + size_type nr, nc; +}; + + +template <typename Vector1, typename Vector2> +class outer_product_functor +{ + typedef outer_product_functor self; + public: + typedef std::size_t size_type; + typedef typename Multiplicable<typename Collection<Vector1>::value_type, + typename Collection<Vector2>::value_type>::result_type result_type; + + outer_product_functor(const Vector1& v1, const Vector2& v2) : my_v1(v1), my_v2(v2) {} + outer_product_functor(size_type r, size_type c) : my_v1(r), my_v2(c) {} + + friend size_type inline num_rows(const self& A) { return size(A.my_v1); } + friend size_type inline num_cols(const self& A) { return size(A.my_v2); } + + result_type operator()(size_type r, size_type c) const { return my_v1[r] * my_v2[c]; } + + Vector1& v1() { return my_v1; } + Vector1 const& v1() const { return my_v1; } + Vector2& v2() { return my_v2; } + Vector2 const& v2() const { return my_v2; } + + private: + Vector1 my_v1; // keeps copy + Vector2 my_v2; +}; + +// ====================== +// Some implicit matrices +// ====================== + + +template <typename Value= int> +class ones_matrix + : public implicit_dense<ones_functor<Value> > +{ + public: + typedef ones_functor<Value> functor_type; + typedef typename functor_type::size_type size_type; + typedef implicit_dense<functor_type> base; + + ones_matrix(size_type r, size_type c) : base(functor_type(r, c)) {} +}; + + +template <typename Value= double> +class hilbert_matrix + : public implicit_dense<hilbert_functor<Value> > +{ + public: + typedef hilbert_functor<Value> functor_type; + typedef typename functor_type::size_type size_type; + typedef implicit_dense<functor_type> base; + + hilbert_matrix(size_type r, size_type c) : base(functor_type(r, c)) {} +}; + + +template <typename Vector1, typename Vector2> +class outer_product_matrix + : public implicit_dense<outer_product_functor<Vector1, Vector2> > +{ + typedef outer_product_matrix self; + public: + typedef outer_product_functor<Vector1, Vector2> functor_type; + typedef typename functor_type::size_type size_type; + typedef implicit_dense<functor_type> base; + + outer_product_matrix(const Vector1& v1, const Vector2& v2) : base(functor_type(v1, v2)) {} + outer_product_matrix(size_type r, size_type c) : base(functor_type(r, c)) {} + + Vector1& v1() { return this->functor().v1(); } + Vector1 const& v1() const { return this->functor().v1(); } + Vector2& v2() { return this->functor().v2(); } + Vector2 const& v2() const { return this->functor().v2(); } +}; + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_IMPLICIT_DENSE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/indirect.hpp b/install/MTL/include/boost/numeric/mtl/matrix/indirect.hpp new file mode 100644 index 00000000..db3e626f --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/indirect.hpp @@ -0,0 +1,69 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_INDIRECT_INCLUDE +#define MTL_MATRIX_INDIRECT_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/detail/range_generator.hpp> +#include <boost/numeric/mtl/utility/complexity.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/iset.hpp> +#include <boost/numeric/mtl/operation/is_negative.hpp> +#include <boost/numeric/mtl/matrix/mat_expr.hpp> + +namespace mtl { namespace mat { + +/// Class for indirect access to matrix +/** So far only constant access, mutable access for appropriate matrices might be added later. **/ +template <typename Matrix> +struct indirect + : mat_expr<indirect<Matrix> >, + const_crtp_base_matrix<indirect<Matrix>, typename Collection<Matrix>::value_type, typename Collection<Matrix>::size_type> +{ + typedef indirect self; + typedef Matrix other; + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + // if implementation uses const_reference -> change collection accordingly + + + /// Construct from constant matrix reference and isets for rows and columns + indirect(const Matrix& ref, const iset& rows, const iset& cols) : ref(ref), rows(rows), cols(cols) {} + + friend size_type inline num_rows(const self& A) { return A.rows.size(); } ///< Number of rows + friend size_type inline num_cols(const self& A) { return A.cols.size(); } ///< Number of colums + size_type nnz() const { return num_rows(*this) * num_cols(*this); } ///< Number of non-zeros + + size_type dim1() const { return rows.size(); } ///< Dimension 1 is equal to number of rows + size_type dim2() const { return cols.size(); } ///< Dimension 2 is equal to number of columns + + value_type operator() (size_type r, size_type c) const + { return (ref(rows[r], cols[c])); } ///< Read A[r][c] + + private: + const Matrix& ref; + iset rows, cols; +}; + +template <typename Matrix> +inline std::size_t size(const indirect<Matrix>& A) +{ return num_rows(A) * num_rows(A); } + +}} // namespace mtl::matrix + + +// -- Range generators in utility/range_generator.hpp +// -- Property maps in utility/property_maps.hpp + + +#endif // MTL_MATRIX_INDIRECT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/inserter.hpp b/install/MTL/include/boost/numeric/mtl/matrix/inserter.hpp new file mode 100644 index 00000000..c7402772 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/inserter.hpp @@ -0,0 +1,90 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_INSERTER_INCLUDE +#define MTL_MATRIX_INSERTER_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/operation/update.hpp> +#include <boost/numeric/mtl/detail/trivial_inserter.hpp> + + + +namespace mtl { namespace mat { + +/// Matrix inserter +/** The matrix inserter has two template arguments: the type of the target matrix and + an update functor. + The update functor determines how an existing entry is updated: overwritten, added, + subtracted... + The default is to overwrite existing entries. +**/ +template <typename Matrix, + typename Updater = mtl::operations::update_store<typename Matrix::value_type> > +struct inserter + : public mtl::detail::trivial_inserter<Matrix, Updater> +{ + typedef mtl::detail::trivial_inserter<Matrix, Updater> base; + typedef typename Matrix::size_type size_type; + + explicit inserter(Matrix& matrix, size_type slot_size = 0) : base(matrix, slot_size) {} +}; + + +template <typename Value, typename Parameters, typename Updater> +struct inserter<compressed2D<Value, Parameters>, Updater> + : compressed2D_inserter<Value, Parameters, Updater> +{ + typedef compressed2D<Value, Parameters> matrix_type; + typedef typename matrix_type::size_type size_type; + typedef compressed2D_inserter<Value, Parameters, Updater > base; + + explicit inserter(matrix_type& matrix, size_type slot_size = 5) : base(matrix, slot_size) {} +}; + +template <typename Value, typename Parameters, typename Updater> +struct inserter<coordinate2D<Value, Parameters>, Updater> + : coordinate2D_inserter<coordinate2D<Value, Parameters>, Updater> +{ + typedef coordinate2D<Value, Parameters> matrix_type; + typedef typename Parameters::size_type size_type; + typedef coordinate2D_inserter<coordinate2D<Value, Parameters>, Updater> base; + + explicit inserter(matrix_type& matrix, size_type slot_size= 1) : base(matrix, slot_size) {} +}; + +template <typename Value, typename Parameters, typename Updater> +struct inserter<sparse_banded<Value, Parameters>, Updater> + : sparse_banded_inserter<Value, Parameters, Updater> +{ + typedef sparse_banded<Value, Parameters> matrix_type; + typedef typename Parameters::size_type size_type; + typedef sparse_banded_inserter<Value, Parameters, Updater> base; + + explicit inserter(matrix_type& matrix, size_type slot_size= 1) : base(matrix, slot_size) {} +}; + +template <typename Value, typename Parameters, typename Updater> +struct inserter<ell_matrix<Value, Parameters>, Updater> + : ell_matrix_inserter<Value, Parameters, Updater> +{ + typedef ell_matrix<Value, Parameters> matrix_type; + typedef typename matrix_type::size_type size_type; + typedef ell_matrix_inserter<Value, Parameters, Updater > base; + + explicit inserter(matrix_type& matrix, size_type slot_size = 5) : base(matrix, slot_size) {} +}; + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_INSERTER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/laplacian_setup.hpp b/install/MTL/include/boost/numeric/mtl/matrix/laplacian_setup.hpp new file mode 100644 index 00000000..a56e9793 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/laplacian_setup.hpp @@ -0,0 +1,47 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_LAPLACIAN_SETUP_INCLUDE +#define MTL_LAPLACIAN_SETUP_INCLUDE + +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/mtl/operation/set_to_zero.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace mat { + +/// Setup a matrix according to a Laplacian equation on a 2D-grid using a five-point-stencil +/** Intended for sparse matrices but works also with dense matrices. Changes the size of + the matrix \f$m\cdot n\times m\cdot n\f$. **/ +template <typename Matrix> +inline void laplacian_setup(Matrix& A, unsigned m, unsigned n) +{ + vampir_trace<3063> tracer; + A.change_dim(m*n, m*n); + set_to_zero(A); + inserter<Matrix> ins(A, 5); + + for (unsigned i= 0; i < m; i++) + for (unsigned j= 0; j < n; j++) { + typename Collection<Matrix>::value_type four(4.0), minus_one(-1.0); + unsigned row= i * n + j; + ins(row, row) << four; + if (j < n-1) ins(row, row+1) << minus_one; + if (i < m-1) ins(row, row+n) << minus_one; + if (j > 0) ins(row, row-1) << minus_one; + if (i > 0) ins(row, row-n) << minus_one; + } +} + +}} // namespace mtl::matrix + +#endif // MTL_LAPLACIAN_SETUP_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/lower.hpp b/install/MTL/include/boost/numeric/mtl/matrix/lower.hpp new file mode 100644 index 00000000..9461dc87 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/lower.hpp @@ -0,0 +1,38 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_LOWER_INCLUDE +#define MTL_MATRIX_LOWER_INCLUDE + +namespace mtl { namespace mat { + +namespace traits { + + template <typename Matrix> + struct lower + { + typedef typename traits::bands<Matrix>::type type; + }; +} + +/// Lower triangular matrix +template <typename Matrix> +typename traits::lower<Matrix>::type +inline lower(const Matrix& A) +{ + return bands(A, std::numeric_limits<long>::min(), 1); +} + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_LOWER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/make_fast_multi_vector_expr.hpp b/install/MTL/include/boost/numeric/mtl/matrix/make_fast_multi_vector_expr.hpp new file mode 100644 index 00000000..72e724ba --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/make_fast_multi_vector_expr.hpp @@ -0,0 +1,70 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_MAKE_FAST_MULTI_VECTOR_EXPR_INCLUDE +#define MTL_MATRIX_MAKE_FAST_MULTI_VECTOR_EXPR_INCLUDE + +#include <boost/numeric/mtl/utility/fast_multi_vector_expr.hpp> +#include <boost/numeric/mtl/matrix/mat_mat_plus_expr.hpp> +#include <boost/numeric/mtl/matrix/mat_mat_minus_expr.hpp> +#include <boost/numeric/mtl/matrix/map_view.hpp> +#include <boost/numeric/mtl/vector/vec_vec_plus_expr.hpp> +#include <boost/numeric/mtl/vector/vec_vec_minus_expr.hpp> +#include <boost/numeric/mtl/vector/map_view.hpp> + +namespace mtl { namespace mat { + + +template <typename E1, typename E2> +typename mtl::traits::fast_multi_vector_expr< mv_mv_plus_expr<E1, E2> >::type +inline make_fast_multi_vector_expr(const mv_mv_plus_expr<E1, E2>& expr) +{ + typedef typename mtl::traits::fast_multi_vector_expr< mv_mv_plus_expr<E1, E2> >::type type; + return type(make_fast_multi_vector_expr(expr.first), make_fast_multi_vector_expr(expr.second)); +} + +template <typename E1, typename E2> +typename mtl::traits::fast_multi_vector_expr< mv_mv_minus_expr<E1, E2> >::type +inline make_fast_multi_vector_expr(const mv_mv_minus_expr<E1, E2>& expr) +{ + typedef typename mtl::traits::fast_multi_vector_expr< mv_mv_minus_expr<E1, E2> >::type type; + return type(make_fast_multi_vector_expr(expr.first), make_fast_multi_vector_expr(expr.second)); +} + +template <typename Functor, typename Matrix> +typename mtl::traits::fast_multi_vector_expr< map_view<Functor, Matrix> >::type +inline make_fast_multi_vector_expr(const map_view<Functor, Matrix>& expr) +{ + typedef typename mtl::traits::fast_multi_vector_expr< map_view<Functor, Matrix> >::type type; + return type(expr.functor, make_fast_multi_vector_expr(expr.ref)); +} + +template <typename Value1, typename Matrix> +typename mtl::traits::fast_multi_vector_expr< scaled_view<Value1, Matrix> >::type +inline make_fast_multi_vector_expr(const scaled_view<Value1, Matrix>& expr) +{ + typedef typename mtl::traits::fast_multi_vector_expr< scaled_view<Value1, Matrix> >::type type; + return type(expr.functor.value(), make_fast_multi_vector_expr(expr.ref)); +} + +template <typename Value1, typename Matrix> +typename mtl::traits::fast_multi_vector_expr< rscaled_view<Value1, Matrix> >::type +inline make_fast_multi_vector_expr(const rscaled_view<Value1, Matrix>& expr) +{ + typedef typename mtl::traits::fast_multi_vector_expr< rscaled_view<Value1, Matrix> >::type type; + return type(make_fast_multi_vector_expr(expr.ref), expr.functor.value()); +} + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_MAKE_FAST_MULTI_VECTOR_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/map_view.hpp b/install/MTL/include/boost/numeric/mtl/matrix/map_view.hpp new file mode 100644 index 00000000..3c9e1a29 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/map_view.hpp @@ -0,0 +1,581 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAP_VIEW_INCLUDE +#define MTL_MAP_VIEW_INCLUDE + +#include <utility> +#include <boost/utility/enable_if.hpp> +#include <boost/mpl/if.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/is_multi_vector_expr.hpp> +#include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp> +#include <boost/numeric/mtl/operation/sub_matrix.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> +#include <boost/numeric/mtl/operation/tfunctor.hpp> +#include <boost/numeric/mtl/operation/conj.hpp> +#include <boost/numeric/mtl/operation/imag.hpp> +#include <boost/numeric/mtl/operation/real.hpp> +#include <boost/numeric/mtl/matrix/mat_expr.hpp> +#include <boost/numeric/mtl/vector/map_view.hpp> + + +namespace mtl { namespace mat { namespace detail { + // Forward declaration for friend declaration + template <typename, typename> struct map_value; + + template <typename Functor, typename Matrix> struct map_vector {}; // not defined in general + template <typename Functor, typename Vector> + struct map_vector<Functor, mtl::mat::multi_vector<Vector> > + { + typedef mtl::vec::map_view<Functor, Vector> type; + }; + +}}} + +namespace mtl { namespace mat { + +template <typename Functor, typename Matrix> +struct map_view + : public const_crtp_base_matrix< map_view<Functor, Matrix>, + typename Functor::result_type, typename Matrix::size_type >, + public mat_expr< map_view<Functor, Matrix> > +{ + typedef map_view self; + typedef mat_expr< self > expr_base; + typedef Matrix other; + typedef const Matrix& const_ref_type; + typedef typename Matrix::orientation orientation; + + typedef typename Functor::result_type value_type; + typedef typename Functor::result_type const_reference; + + typedef typename Matrix::key_type key_type; + typedef typename Matrix::size_type size_type; + typedef typename Matrix::index_type index_type; + typedef typename Matrix::dim_type dim_type; + + struct dummy { typedef void type; }; + typedef typename boost::mpl::eval_if<mtl::traits::is_multi_vector_expr<Matrix>, detail::map_vector<Functor, Matrix>, dummy>::type vector_type; + + map_view (const Functor& functor, const other& ref) : functor(functor), ref(ref) {} + + map_view (const Functor& functor, boost::shared_ptr<Matrix> p) + : functor(functor), my_copy(p), ref(*p) {} + +#ifdef MTL_WITH_CPP11_MOVE + map_view (self&& that) : functor(that.functor), my_copy(std::move(that.my_copy)), ref(that.ref) {} + map_view (const self& that) : functor(that.functor), ref(that.ref) { assert(that.my_copy.use_count() == 0); } +#endif + + + value_type operator() (size_type r, size_type c) const + { + return functor(ref(r, c)); + } + // for multi_vector, needs enable_if since only defined for multi_vector + template <typename S> + typename boost::lazy_enable_if<boost::is_integral<S>, detail::map_vector<Functor, Matrix> >::type + vector(S c) const + { + return typename detail::map_vector<Functor, Matrix>::type(functor, ref.vector(c)); + } + + size_type dim1() const { return ref.dim1(); } + size_type dim2() const { return ref.dim2(); } + dim_type dimensions() const { return ref.dimensions(); } + + size_type begin_row() const { return ref.begin_row(); } + size_type end_row() const { return ref.end_row(); } + size_type begin_col() const { return ref.begin_col(); } + size_type end_col() const { return ref.end_col(); } + + size_type nnz() const { return ref.nnz(); } + + friend size_type inline num_rows(const self& A) + { using mtl::mat::num_rows; return num_rows(A.ref); } + friend size_type inline num_cols(const self& A) + { using mtl::mat::num_cols; return num_cols(A.ref); } + template <typename, typename> friend struct detail::map_value; + + protected: + boost::shared_ptr<Matrix> my_copy; + public: + Functor functor; + const other& ref; +}; + +template <typename Functor, typename Matrix> +inline std::size_t size(const map_view<Functor, Matrix>& A) +{ return num_rows(A) * num_rows(A); } + +// ========== +// Sub matrix +// ========== + +template <typename Functor, typename Matrix> +struct sub_matrix_t< mtl::mat::map_view<Functor, Matrix> > +{ + typedef mtl::mat::map_view<Functor, Matrix> view_type; + + // Mapping of sub-matrix type + typedef typename sub_matrix_t<Matrix>::const_sub_matrix_type ref_sub_type; + typedef mtl::mat::map_view<Functor, ref_sub_type> const_sub_matrix_type; + typedef typename view_type::size_type size_type; + + const_sub_matrix_type operator()(view_type const& view, size_type begin_r, size_type end_r, + size_type begin_c, size_type end_c) + { + typedef boost::shared_ptr<ref_sub_type> pointer_type; + + // Submatrix of referred matrix (or view) + // Create a submatrix, whos address will be kept by map_view + // Functor is copied from view + pointer_type p(new ref_sub_type(sub_matrix(view.ref, begin_r, end_r, begin_c, end_c))); + return const_sub_matrix_type(view.functor, p); + } +}; + + +}} // namespace mtl::matrix + + +namespace mtl { namespace traits { + + namespace detail { + + + template <typename Functor, typename Matrix> + struct map_value + { + typedef typename Matrix::key_type key_type; + typedef typename mtl::mat::map_view<Functor, Matrix>::value_type value_type; + + map_value(mtl::mat::map_view<Functor, Matrix> const& map_matrix) + : map_matrix(map_matrix), its_value(map_matrix.ref) + {} + + value_type operator() (key_type const& key) const + { + return map_matrix.functor(its_value(key)); + } + + protected: + mtl::mat::map_view<Functor, Matrix> const& map_matrix; + typename mtl::traits::const_value<Matrix>::type its_value; + }; + + + + template <typename Functor, typename Matrix> + struct mapped_row + { + typedef typename Matrix::key_type key_type; + typedef typename Matrix::size_type size_type; + + explicit mapped_row(const mtl::mat::map_view<Functor, Matrix>& view) : its_row(view.ref) {} + explicit mapped_row(const mtl::mat::banded_view<Matrix>& view) : its_row(view.ref) {} + + size_type operator() (key_type const& key) const + { + return its_row(key); + } + + protected: + typename row<Matrix>::type its_row; + }; + + + template <typename Functor, typename Matrix> + struct mapped_col + { + typedef typename Matrix::key_type key_type; + typedef typename Matrix::size_type size_type; + + mapped_col(const mtl::mat::map_view<Functor, Matrix>& view) : its_col(view.ref) {} + mapped_col(const mtl::mat::banded_view<Matrix>& view) : its_col(view.ref) {} + + size_type operator() (key_type const& key) const + { + return its_col(key); + } + + protected: + typename col<Matrix>::type its_col; + }; + + } // namespace detail + + template <typename Functor, typename Matrix> + struct row<mtl::mat::map_view<Functor, Matrix> > + { + typedef detail::mapped_row<Functor, Matrix> type; + }; + + template <typename Functor, typename Matrix> + struct col<mtl::mat::map_view<Functor, Matrix> > + { + typedef detail::mapped_col<Functor, Matrix> type; + }; + + template <typename Functor, typename Matrix> + struct const_value<mtl::mat::map_view<Functor, Matrix> > + { + typedef detail::map_value<Functor, Matrix> type; + }; + + + // ================ + // Range generators + // ================ + + // Use range_generator of original matrix + template <typename Tag, typename Functor, typename Matrix> + struct range_generator<Tag, mtl::mat::map_view<Functor, Matrix> > + : public detail::referred_range_generator<mtl::mat::map_view<Functor, Matrix>, + range_generator<Tag, Matrix> > + {}; + + // To disambigue + template <typename Functor, typename Matrix> + struct range_generator<tag::major, mtl::mat::map_view<Functor, Matrix> > + : public detail::referred_range_generator<mtl::mat::map_view<Functor, Matrix>, + range_generator<tag::major, Matrix> > + {}; + + +}} // mtl::traits + + +namespace mtl { namespace mat { + +template <typename Scaling, typename Matrix> +struct scaled_view + : public map_view<tfunctor::scale<Scaling, typename Matrix::value_type>, Matrix> +{ + typedef tfunctor::scale<Scaling, typename Matrix::value_type> functor_type; + typedef map_view<functor_type, Matrix> base; + typedef scaled_view self; + + scaled_view(const Scaling& scaling, const Matrix& matrix) + : base(functor_type(scaling), matrix) + {} + + scaled_view(const Scaling& scaling, boost::shared_ptr<Matrix> p) + : base(functor_type(scaling), p) + {} + +#ifdef MTL_WITH_CPP11_MOVE + scaled_view (self&& that) : base(that) {} + scaled_view (const self& that) : base(that) {} +#endif +}; + +// rscaled_view -- added by Hui Li +template <typename Matrix, typename RScaling> +struct rscaled_view + : public map_view<tfunctor::rscale<typename Matrix::value_type,RScaling>, Matrix> +{ + typedef tfunctor::rscale<typename Matrix::value_type, RScaling> functor_type; + typedef map_view<functor_type, Matrix> base; + typedef rscaled_view self; + + rscaled_view(const Matrix& matrix, const RScaling& rscaling) + : base(functor_type(rscaling),matrix) + {} + + rscaled_view(boost::shared_ptr<Matrix> p, const RScaling& rscaling) + : base(functor_type(rscaling), p) + {} + +#ifdef MTL_WITH_CPP11_MOVE + rscaled_view (self&& that) : base(that) {} + rscaled_view (const self& that) : base(that) {} +#endif +}; + +// divide_by_view -- added by Hui Li +template <typename Matrix, typename Divisor> +struct divide_by_view + : public map_view<tfunctor::divide_by<typename Matrix::value_type,Divisor>, Matrix> +{ + typedef tfunctor::divide_by<typename Matrix::value_type, Divisor> functor_type; + typedef map_view<functor_type, Matrix> base; + typedef divide_by_view self; + + divide_by_view(const Matrix& matrix,const Divisor& div) + : base(functor_type(div), matrix) + {} + + divide_by_view(boost::shared_ptr<Matrix> p, const Divisor& div) + : base(functor_type(div), p) + {} + +#ifdef MTL_WITH_CPP11_MOVE + divide_by_view (self&& that) : base(that) {} + divide_by_view (const self& that) : base(that) {} +#endif +}; + +template <typename Matrix> +struct conj_view + : public map_view<mtl::sfunctor::conj<typename Matrix::value_type>, Matrix> +{ + typedef mtl::sfunctor::conj<typename Matrix::value_type> functor_type; + typedef map_view<functor_type, Matrix> base; + typedef conj_view self; + + conj_view(const Matrix& matrix) : base(functor_type(), matrix) {} + conj_view(boost::shared_ptr<Matrix> p) : base(functor_type(), p) {} + +#ifdef MTL_WITH_CPP11_MOVE + conj_view (self&& that) : base(that) {} + conj_view (const self& that) : base(that) {} +#endif +}; + +template <typename Matrix> +struct imag_view + : public map_view<mtl::sfunctor::imag<typename Matrix::value_type>, Matrix> +{ + typedef mtl::sfunctor::imag<typename Matrix::value_type> functor_type; + typedef map_view<functor_type, Matrix> base; + typedef imag_view self; + + imag_view(const Matrix& matrix) : base(functor_type(), matrix) {} + imag_view(boost::shared_ptr<Matrix> p) : base(functor_type(), p) {} + +#ifdef MTL_WITH_CPP11_MOVE + imag_view (self&& that) : base(that) {} + imag_view (const self& that) : base(that) {} +#endif +}; + +template <typename Matrix> +struct negate_view + : public map_view<mtl::sfunctor::negate<typename Matrix::value_type>, Matrix> +{ + typedef mtl::sfunctor::negate<typename Matrix::value_type> functor_type; + typedef map_view<functor_type, Matrix> base; + typedef negate_view self; + + negate_view(const Matrix& matrix) : base(functor_type(), matrix) {} + negate_view(boost::shared_ptr<Matrix> p) : base(functor_type(), p) {} + +#ifdef MTL_WITH_CPP11_MOVE + negate_view (self&& that) : base(that) {} + negate_view (const self& that) : base(that) {} +#endif +}; + +template <typename Matrix> +struct real_view + : public map_view<mtl::sfunctor::real<typename Matrix::value_type>, Matrix> +{ + typedef mtl::sfunctor::real<typename Matrix::value_type> functor_type; + typedef map_view<functor_type, Matrix> base; + typedef real_view self; + + real_view(const Matrix& matrix) : base(functor_type(), matrix) {} + real_view(boost::shared_ptr<Matrix> p) : base(functor_type(), p) {} + +#ifdef MTL_WITH_CPP11_MOVE + real_view (self&& that) : base(that) {} + real_view (const self& that) : base(that) {} +#endif +}; + +template <typename Scaling, typename Matrix> +struct sub_matrix_t< mtl::mat::scaled_view<Scaling, Matrix> > + : public sub_matrix_t< mtl::mat::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>, + Matrix> > +{}; + +template <typename Matrix> +struct sub_matrix_t< mtl::mat::conj_view<Matrix> > + : public sub_matrix_t< mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> > +{}; + +template <typename Matrix, typename RScaling> +struct sub_matrix_t< mtl::mat::rscaled_view<Matrix, RScaling> > + : public sub_matrix_t< mtl::mat::map_view<tfunctor::rscale<typename Matrix::value_type, RScaling>, + Matrix> > +{}; + +template <typename Matrix, typename Divisor> +struct sub_matrix_t< mtl::mat::divide_by_view<Matrix, Divisor> > + : public sub_matrix_t< mtl::mat::map_view<tfunctor::divide_by<typename Matrix::value_type, Divisor>, + Matrix> > +{}; + + +}} // namespace mtl::matrix + +namespace mtl { namespace sfunctor { + + template <typename Matrix> + struct conj_aux<Matrix, tag::matrix> + { + typedef mat::conj_view<Matrix> result_type; + + static inline result_type apply(const Matrix& matrix) + { + return result_type(matrix); + } + + result_type operator() (const Matrix& matrix) const + { + return apply(matrix); + } + }; + +}} // namespace mtl::sfunctor + +// Traits for specific views +namespace mtl { namespace traits { + +template <typename Scaling, typename Matrix> +struct row< mtl::mat::scaled_view<Scaling, Matrix> > + : public row< mtl::mat::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>, + Matrix> > +{}; + +template <typename Matrix> +struct row< mtl::mat::conj_view<Matrix> > + : public row< mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> > +{}; + +template <typename Matrix, typename RScaling> +struct row< mtl::mat::rscaled_view<Matrix, RScaling> > + : public row< mtl::mat::map_view<tfunctor::rscale<typename Matrix::value_type, RScaling>, + Matrix> > +{}; + +template <typename Matrix, typename Divisor> +struct row< mtl::mat::divide_by_view<Matrix, Divisor> > + : public row< mtl::mat::map_view<tfunctor::divide_by<typename Matrix::value_type, Divisor>, + Matrix> > +{}; + + +template <typename Scaling, typename Matrix> +struct col< mtl::mat::scaled_view<Scaling, Matrix> > + : public col< mtl::mat::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>, + Matrix> > +{}; + +template <typename Matrix> +struct col< mtl::mat::conj_view<Matrix> > + : public col< mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> > +{}; + +template <typename Matrix, typename RScaling> +struct col< mtl::mat::rscaled_view<Matrix, RScaling> > + : public col< mtl::mat::map_view<tfunctor::rscale<typename Matrix::value_type, RScaling>, + Matrix> > +{}; + +template <typename Matrix, typename Divisor> +struct col< mtl::mat::divide_by_view<Matrix, Divisor> > + : public col< mtl::mat::map_view<tfunctor::divide_by<typename Matrix::value_type, Divisor>, + Matrix> > +{}; + + + + + +template <typename Scaling, typename Matrix> +struct const_value< mtl::mat::scaled_view<Scaling, Matrix> > + : public const_value< mtl::mat::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>, + Matrix> > +{}; + +template <typename Matrix> +struct const_value< mtl::mat::conj_view<Matrix> > + : public const_value< mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> > +{}; + +template <typename Matrix, typename RScaling> +struct const_value< mtl::mat::rscaled_view<Matrix, RScaling> > + : public const_value< mtl::mat::map_view<tfunctor::rscale<typename Matrix::value_type, RScaling>, + Matrix> > +{}; + +template <typename Matrix, typename Divisor> +struct const_value< mtl::mat::divide_by_view<Matrix, Divisor> > + : public const_value< mtl::mat::map_view<tfunctor::divide_by<typename Matrix::value_type, Divisor>, + Matrix> > +{}; + + + + + +template <typename Tag, typename Scaling, typename Matrix> +struct range_generator< Tag, mtl::mat::scaled_view<Scaling, Matrix> > + : public range_generator< Tag, mtl::mat::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>, + Matrix> > +{}; + +template <typename Tag, typename Matrix> +struct range_generator< Tag, mtl::mat::conj_view<Matrix> > + : public range_generator< Tag, mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> > +{}; + +template <typename Tag, typename Matrix, typename RScaling> +struct range_generator< Tag, mtl::mat::rscaled_view<Matrix, RScaling> > + : public range_generator< Tag, mtl::mat::map_view<tfunctor::rscale<typename Matrix::value_type, RScaling>, + Matrix> > +{}; + +template <typename Tag, typename Matrix, typename Divisor> +struct range_generator< Tag, mtl::mat::divide_by_view<Matrix, Divisor> > + : public range_generator< Tag, mtl::mat::map_view<tfunctor::divide_by<typename Matrix::value_type, Divisor>, + Matrix> > +{}; + + + +template <typename Scaling, typename Matrix> +struct range_generator< tag::major, mtl::mat::scaled_view<Scaling, Matrix> > + : public range_generator< tag::major, mtl::mat::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>, + Matrix> > +{}; + +template <typename Matrix> +struct range_generator< tag::major, mtl::mat::conj_view<Matrix> > + : public range_generator< tag::major, mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> > +{}; + +template <typename Matrix, typename RScaling> +struct range_generator< tag::major, mtl::mat::rscaled_view<Matrix, RScaling> > + : public range_generator< tag::major, mtl::mat::map_view<tfunctor::rscale<typename Matrix::value_type, RScaling>, + Matrix> > +{}; + +template <typename Matrix, typename Divisor> +struct range_generator< tag::major, mtl::mat::divide_by_view<Matrix, Divisor> > + : public range_generator< tag::major, mtl::mat::map_view<tfunctor::divide_by<typename Matrix::value_type, Divisor>, + Matrix> > +{}; + + + +}} // mtl::traits + + +#endif // MTL_MAP_VIEW_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/mapped_inserter.hpp b/install/MTL/include/boost/numeric/mtl/matrix/mapped_inserter.hpp new file mode 100644 index 00000000..a12bb8ad --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/mapped_inserter.hpp @@ -0,0 +1,94 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_MAPPED_INSERTER_INCLUDE +#define MTL_MATRIX_MAPPED_INSERTER_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/update.hpp> + +namespace mtl { namespace mat { + +/// Inserter with shifted row and column indices +/** The main work is performed by the underlying base inserter whose type is given as template + argument. **/ +template <typename BaseInserter, typename Mapper > +class mapped_inserter +{ + public: + typedef mapped_inserter self; + typedef typename BaseInserter::matrix_type matrix_type; + typedef typename Collection<matrix_type>::size_type size_type; + typedef operations::update_proxy<BaseInserter, size_type> proxy_type; + + /// Constructor with matrix \p A, the mapping, and the slot size + mapped_inserter(matrix_type& A, Mapper& map, size_type slot_size= 0) + : ins(A, slot_size), map(map) {} + + private: + struct bracket_proxy + { + bracket_proxy(BaseInserter& ref, Mapper& map, size_type row) + : ref(ref),map(map), row(row) {} + + proxy_type operator[](size_type col) + { return proxy_type(ref, row, map.col(col)); } + + BaseInserter& ref; + Mapper& map; + size_type row; + }; + + public: + /// To be used in ins[r][c] << value; + bracket_proxy operator[] (size_type row) + { return bracket_proxy(ins, map, map.row(row)); } + + /// To be used in ins(r, c) << value; + proxy_type operator() (size_type row, size_type col) + { return proxy_type(ins, map.row(row),map.col(col)); } + + // update, modify and operator<< are used from BaseInserter + +private: + BaseInserter ins; + Mapper& map; +}; + +template< typename BaseInserter, typename Mapper, typename Elt, typename Parameters > +mapped_inserter< BaseInserter, Mapper >& operator<<(mapped_inserter< BaseInserter, Mapper >& minserter, + const compressed2D< Elt, Parameters >& rhs) +{ + + using mtl::tag::major; using mtl::tag::nz; using mtl::begin; using mtl::end; + namespace traits= mtl::traits; + typedef compressed2D< Elt, Parameters > Matrix; + + typename traits::row<Matrix>::type row(rhs); + typename traits::col<Matrix>::type col(rhs); + typename traits::const_value<Matrix>::type value(rhs); + + typedef typename traits::range_generator<major, Matrix>::type cursor_type; + typedef typename traits::range_generator<nz, cursor_type>::type icursor_type; + + for (cursor_type cursor = begin<major>(rhs), cend = end<major>(rhs); cursor != cend; ++cursor) + for (icursor_type icursor = begin<nz>(cursor), icend = end<nz>(cursor); icursor != icend; ++icursor) + minserter[row(*icursor)][col(*icursor)]<< value(*icursor); + + return minserter; +} + +} // namespace matrix + +} // namespace mtl + +#endif // MTL_MATRIX_MAPPED_INSERTER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/mat_expr.hpp b/install/MTL/include/boost/numeric/mtl/matrix/mat_expr.hpp new file mode 100644 index 00000000..6c46fdd7 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/mat_expr.hpp @@ -0,0 +1,46 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAT_EXPR_INCLUDE +#define MTL_MAT_EXPR_INCLUDE + +namespace mtl { namespace mat { + +/// Base class for CRTP with matrices +template <typename Matrix> +struct mat_expr +{ + typedef Matrix ref_type; +}; + + +/// Base class for CRTP with dense matrices +template <typename Matrix> +struct dmat_expr + : public mat_expr<Matrix> +{ + typedef mat_expr<Matrix> base; +}; + + +/// Base class for CRTP with sparse matrices +template <typename Matrix> +struct smat_expr + : public mat_expr<Matrix> +{ + typedef mat_expr<Matrix> base; +}; + + +}} // namespace mtl::matrix + +#endif // MTL_MAT_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_asgn_expr.hpp b/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_asgn_expr.hpp new file mode 100644 index 00000000..1610be5b --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_asgn_expr.hpp @@ -0,0 +1,27 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_MAT_MAT_ASGN_EXPR_INCLUDE +#define MTL_MATRIX_MAT_MAT_ASGN_EXPR_INCLUDE + +namespace mtl { namespace mat { + + +// Currently only dummy to be used in traits::eval_dense +template <typename E1, typename E2> +struct mat_mat_asgn_expr {}; + + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_MAT_MAT_ASGN_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_ele_times_expr.hpp b/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_ele_times_expr.hpp new file mode 100644 index 00000000..213ff483 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_ele_times_expr.hpp @@ -0,0 +1,62 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAT_MAT_ELE_TIMES_EXPR_INCLUDE +#define MTL_MAT_MAT_ELE_TIMES_EXPR_INCLUDE + +#include <boost/shared_ptr.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/matrix/mat_mat_op_expr.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> + + +namespace mtl { namespace mat { + +template <typename E1, typename E2> +struct mat_mat_ele_times_expr + : public mat_mat_op_expr< E1, E2, mtl::sfunctor::times<typename E1::value_type, typename E2::value_type> >, + public mat_expr< mat_mat_ele_times_expr<E1, E2> > +{ + typedef mat_mat_op_expr< E1, E2, mtl::sfunctor::times<typename E1::value_type, typename E2::value_type> > op_base; + typedef mat_expr< mat_mat_ele_times_expr<E1, E2> > crtp_base; + typedef mat_mat_ele_times_expr self; + typedef E1 first_argument_type ; + typedef E2 second_argument_type ; + typedef typename E1::orientation orientation; + typedef mtl::non_fixed::dimensions dim_type; + typedef typename E1::key_type key_type; + + + mat_mat_ele_times_expr( E1 const& v1, E2 const& v2 ) + : op_base( v1, v2 ), crtp_base(*this), first(v1), second(v2) + {} + + first_argument_type const& first ; + second_argument_type const& second ; +}; + +template <typename E1, typename E2> +std::size_t inline num_rows(const mat_mat_ele_times_expr<E1, E2>& expr) +{ return num_rows(expr.first); } + +template <typename E1, typename E2> +std::size_t inline num_cols(const mat_mat_ele_times_expr<E1, E2>& expr) +{ return num_cols(expr.second); } + +template <typename E1, typename E2> +std::size_t inline size(const mat_mat_ele_times_expr<E1, E2>& expr) +{ return num_rows(expr) * num_cols(expr); } + +}} // Namespace mtl::matrix + +#endif // MTL_MAT_MAT_ELE_TIMES_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_minus_expr.hpp b/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_minus_expr.hpp new file mode 100644 index 00000000..3c31628f --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_minus_expr.hpp @@ -0,0 +1,60 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAT_MAT_MINUS_EXPR_INCLUDE +#define MTL_MAT_MAT_MINUS_EXPR_INCLUDE + + +#include <boost/numeric/mtl/matrix/mat_mat_op_expr.hpp> +#include <boost/numeric/mtl/vector/vec_vec_pmop_expr.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl {namespace mat { + +template <typename E1, typename E2> +struct mat_mat_minus_expr + : public mat_mat_op_expr< E1, E2, mtl::sfunctor::minus<typename E1::value_type, typename E2::value_type> >, + public mat_expr< mat_mat_minus_expr<E1, E2> > +{ + typedef mat_mat_op_expr< E1, E2, mtl::sfunctor::minus<typename E1::value_type, typename E2::value_type> > op_base; + typedef mat_expr< mat_mat_minus_expr<E1, E2> > crtp_base; + typedef E1 first_argument_type ; + typedef E2 second_argument_type ; + + mat_mat_minus_expr( E1 const& v1, E2 const& v2 ) + : op_base( v1, v2 ), crtp_base(*this), first(v1), second(v2) + {} + + first_argument_type const& first ; + second_argument_type const& second ; +}; + +template <typename E1, typename E2> +struct mv_mv_minus_expr + : mat_mat_minus_expr<E1, E2> +{ + typedef mat_mat_minus_expr< E1, E2 > base; + typedef typename E1::vector_type V1; + typedef typename E2::vector_type V2; + typedef mtl::vec::vec_vec_pmop_expr< V1, V2, mtl::sfunctor::minus<typename V1::value_type, typename V2::value_type> > vector_type; + + mv_mv_minus_expr( E1 const& v1, E2 const& v2 ) + : base( v1, v2 ) + {} + + vector_type vector(std::size_t c) const { return vector_type(this->first.vector(c), this->second.vector(c)); } +}; + +}} // Namespace mtl::matrix + + +#endif // MTL_MAT_MAT_MINUS_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_op_expr.hpp b/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_op_expr.hpp new file mode 100644 index 00000000..bf131008 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_op_expr.hpp @@ -0,0 +1,100 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAT_MAT_OP_EXPR_INCLUDE +#define MTL_MAT_MAT_OP_EXPR_INCLUDE + +#include <boost/numeric/mtl/matrix/mat_expr.hpp> +#include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp> + +namespace mtl { namespace mat { + + +template <typename E1, typename E2, typename SFunctor> +struct mat_mat_op_expr + : public const_crtp_matrix_bracket< mat_mat_op_expr<E1, E2, SFunctor>, + typename SFunctor::result_type, + typename E1::size_type > + // : public mat_expr< mat_mat_op_expr<E1, E2, SFunctor> > +{ + // typedef mat_expr< mat_mat_op_expr<E1, E2, SFunctor> > expr_base; + typedef mat_mat_op_expr self; + + typedef typename SFunctor::result_type value_type; + + // temporary solution + typedef typename E1::size_type size_type; + + typedef value_type const_dereference_type ; + + typedef E1 first_argument_type ; + typedef E2 second_argument_type ; + + mat_mat_op_expr( first_argument_type const& v1, second_argument_type const& v2 ) + : // expr_base( *this ), + first( v1 ), second( v2 ) + { +#if 0 + first.delay_assign(); + second.delay_assign(); +#endif + } + + void delay_assign() const {} + + void check_shape() const {} // consistency of shapes depend on operation + + const_dereference_type operator() (size_type row, size_type col) const + { + return SFunctor::apply( first(row, col), second(row, col) ) ; + // return SFunctor::apply( first[row][col], second[row][col] ) ; + } + +#if 0 + template <typename> friend size_type size(const self&); + template <typename> friend size_type num_rows(const self&); + template <typename> friend size_type num_cols(const self&); +#endif + + first_argument_type const& first ; + second_argument_type const& second ; +}; + + +template <typename E1, typename E2, typename SFunctor> +typename mat_mat_op_expr<E1, E2, SFunctor>::size_type +inline size(mat_mat_op_expr<E1, E2, SFunctor> const& expr) +{ + expr.check_shape(); + return size(expr.first) ; +} + +template <typename E1, typename E2, typename SFunctor> +typename mat_mat_op_expr<E1, E2, SFunctor>::size_type +inline num_rows(mat_mat_op_expr<E1, E2, SFunctor> const& expr) +{ + expr.check_shape(); + return num_rows(expr.first) ; +} + +template <typename E1, typename E2, typename SFunctor> +typename mat_mat_op_expr<E1, E2, SFunctor>::size_type +inline num_cols(mat_mat_op_expr<E1, E2, SFunctor> const& expr) +{ + expr.check_shape(); + return num_cols(expr.first) ; +} + + +}} // namespace mtl + +#endif // MTL_MAT_MAT_OP_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_plus_expr.hpp b/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_plus_expr.hpp new file mode 100644 index 00000000..657b98f6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_plus_expr.hpp @@ -0,0 +1,73 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAT_MAT_PLUS_EXPR_INCLUDE +#define MTL_MAT_MAT_PLUS_EXPR_INCLUDE + +#include <boost/numeric/mtl/matrix/mat_mat_op_expr.hpp> +#include <boost/numeric/mtl/vector/vec_vec_pmop_expr.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace mat { + +template <typename E1, typename E2> +struct mat_mat_plus_expr + : public mat_mat_op_expr< E1, E2, mtl::sfunctor::plus<typename E1::value_type, typename E2::value_type> >, + public mat_expr< mat_mat_plus_expr<E1, E2> > +{ + typedef mat_mat_op_expr< E1, E2, mtl::sfunctor::plus<typename E1::value_type, typename E2::value_type> > op_base; + typedef mat_expr< mat_mat_plus_expr<E1, E2> > crtp_base; + typedef E1 first_argument_type ; + typedef E2 second_argument_type ; + + mat_mat_plus_expr( E1 const& v1, E2 const& v2 ) + : op_base( v1, v2 ), crtp_base(*this), first(v1), second(v2) + {} + + first_argument_type const& first ; + second_argument_type const& second ; +}; + +// Same as mat_mat_plus_expr for pair of dense matrix expressions +// Future versions will probably provide more efficient implementations for it +template <typename E1, typename E2> +struct dmat_dmat_plus_expr + : public mat_mat_op_expr< E1, E2, mtl::sfunctor::plus<typename E1::value_type, typename E2::value_type> > +{ + typedef mat_mat_op_expr< E1, E2, mtl::sfunctor::plus<typename E1::value_type, typename E2::value_type> > base; + dmat_dmat_plus_expr( E1 const& v1, E2 const& v2 ) + : base( v1, v2 ) + {} +}; + +template <typename E1, typename E2> +struct mv_mv_plus_expr + : mat_mat_plus_expr<E1, E2> +{ + typedef mat_mat_plus_expr< E1, E2 > base; + typedef typename E1::vector_type V1; + typedef typename E2::vector_type V2; + typedef mtl::vec::vec_vec_pmop_expr< V1, V2, mtl::sfunctor::plus<typename V1::value_type, typename V2::value_type> > vector_type; + + mv_mv_plus_expr( E1 const& v1, E2 const& v2 ) + : base( v1, v2 ) + {} + + vector_type vector(std::size_t c) const { return vector_type(this->first.vector(c), this->second.vector(c)); } +}; + + + + +}} // Namespace mtl::matrix + +#endif // MTL_MAT_MAT_PLUS_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_times_expr.hpp b/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_times_expr.hpp new file mode 100644 index 00000000..98f8d73f --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/mat_mat_times_expr.hpp @@ -0,0 +1,120 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAT_MAT_TIMES_EXPR_INCLUDE +#define MTL_MAT_MAT_TIMES_EXPR_INCLUDE + +#include <boost/mpl/if.hpp> +#include <boost/mpl/and.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/type_traits/is_base_of.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/matrix/mat_mat_op_expr.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> +#include <boost/numeric/mtl/operation/compute_factors.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/matrix/dense2D.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/mtl/concept/std_concept.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> + + +namespace mtl { namespace mat { + +template <typename E1, typename E2> +struct mat_mat_times_expr + : public mat_mat_op_expr< E1, E2, mtl::sfunctor::times<typename Collection<E1>::value_type, typename Collection<E2>::value_type> >, + public mat_expr< mat_mat_times_expr<E1, E2> > +{ + typedef mat_mat_op_expr< E1, E2, mtl::sfunctor::times<typename Collection<E1>::value_type, typename Collection<E2>::value_type> > op_base; + typedef mat_expr< mat_mat_times_expr<E1, E2> > crtp_base; + typedef mat_mat_times_expr self; + typedef E1 first_argument_type ; + typedef E2 second_argument_type ; + typedef typename E1::orientation orientation; + typedef mtl::non_fixed::dimensions dim_type; + typedef typename E1::key_type key_type; + + + typedef typename Collection<E1>::value_type first_value_type; + typedef typename Collection<E2>::value_type second_value_type; + typedef typename Multiplicable<first_value_type, second_value_type>::result_type result_value_type; + +#if 0 // Just an idea + typedef typename boost::mpl::if_< + boost::mpl::and_< + boost::is_base_of<tag::sparse, typename traits::category<E1>::type> + , boost::is_base_of<tag::sparse, typename traits::category<E2>::type> + > + , compressed2D<result_value_type> + , dense2D<result_value_type, parameters<> > + >::type evaluated_result_type; + + // Convert into matrix + + operator evaluated_result_type() const + { + return evaluated_result_type(first * second); + } +#endif + + mat_mat_times_expr( E1 const& v1, E2 const& v2 ) + : op_base( v1, v2 ), crtp_base(*this), first(v1), second(v2) + {} + + // To prevent that cout << A * B prints the element-wise product, suggestion by Hui Li + // It is rather inefficient, esp. for multiple products (complexity increases with the number of arguments :-!) + // or sparse matrices. + // Better compute your product first and print it then when compute time is an issue, + // this is ONLY for convenience. + result_value_type + operator()(std::size_t r, std::size_t c) const + { + using math::zero; + MTL_THROW_IF(num_cols(first) != num_rows(second), incompatible_size()); + + result_value_type ref, sum(zero(ref)); + for (std::size_t i= 0; i < num_cols(first); i++) + sum+= first(r, i) * second(i, c); + return sum; + } + + + result_value_type + operator()(std::size_t r, std::size_t c) + { + return (*const_cast<const self*>(this))(r, c); + } + + first_argument_type const& first ; + second_argument_type const& second ; +}; + +template <typename E1, typename E2> +std::size_t inline num_rows(const mat_mat_times_expr<E1, E2>& expr) +{ return num_rows(expr.first); } + +template <typename E1, typename E2> +std::size_t inline num_cols(const mat_mat_times_expr<E1, E2>& expr) +{ return num_cols(expr.second); } + +template <typename E1, typename E2> +std::size_t inline size(const mat_mat_times_expr<E1, E2>& expr) +{ return num_rows(expr) * num_cols(expr); } + +}} // Namespace mtl::matrix + +#endif // MTL_MAT_MAT_TIMES_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/mat_negate_expr.hpp b/install/MTL/include/boost/numeric/mtl/matrix/mat_negate_expr.hpp new file mode 100644 index 00000000..f8ad320f --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/mat_negate_expr.hpp @@ -0,0 +1,30 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAT_NEGATE_EXPR_INCLUDE +#define MTL_MAT_NEGATE_EXPR_INCLUDE + +#include <boost/numeric/mtl/matrix/map_view.hpp> + +namespace mtl { namespace mat { + +template <typename E1> +inline negate_view< E1 > +operator- (const mat_expr<E1>& e1) +{ + return negate_view< E1 >(static_cast<const E1&>(e1)); +} + +} } // Namespace mtl::matrix + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/matrix/morton_dense.hpp b/install/MTL/include/boost/numeric/mtl/matrix/morton_dense.hpp new file mode 100644 index 00000000..fea02cea --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/morton_dense.hpp @@ -0,0 +1,895 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MORTON_DENSE_INCLUDE +#define MTL_MORTON_DENSE_INCLUDE + +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/if.hpp> + +#include <boost/numeric/mtl/utility/common_include.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp> +#include <boost/numeric/mtl/matrix/base_sub_matrix.hpp> +#include <boost/numeric/mtl/detail/contiguous_memory_block.hpp> +#include <boost/numeric/mtl/detail/dilated_int.hpp> +#include <boost/numeric/mtl/utility/iterator_adaptor.hpp> +#include <boost/numeric/mtl/operation/set_to_zero.hpp> +#include <boost/numeric/mtl/matrix/mat_expr.hpp> +#include <boost/numeric/mtl/operation/print_matrix.hpp> +#include <boost/numeric/mtl/operation/compute_factors.hpp> +#include <boost/numeric/mtl/operation/clone.hpp> + +#ifdef MTL_WITH_INITLIST +# include <initializer_list> +#endif +#include <algorithm> + +namespace mtl { namespace mat { + +// Helper type +struct morton_dense_sub_ctor {}; + +template <std::size_t BitMask> +struct morton_dense_key +{ + typedef std::size_t size_type; + typedef dilated_int<std::size_t, BitMask, true> dilated_row_t; + typedef dilated_int<std::size_t, ~BitMask, true> dilated_col_t; + typedef morton_dense_key self; + + morton_dense_key(size_type my_row, size_type my_col) + : my_row(my_row), my_col(my_col), dilated_row(my_row), dilated_col(my_col) + {} + + bool operator== (self const& x) const + { + return my_row == x.my_row && my_col == x.my_col; + } + + bool operator!= (self const& x) + { + return !(*this == x); + } + + size_type row() const + { + return my_row; + } + + size_type col() const + { + return my_col; + } + + self& advance_row(int row_inc) + { + dilated_row.advance(row_inc); + // potential addition of signed and unsigned + my_row+= row_inc; + return *this; + } + + self& advance_col(int col_inc) + { + dilated_col.advance(col_inc); + // potential addition of signed and unsigned + my_col+= col_inc; + return *this; + } + + self& advance(int row_inc, int col_inc) + { + advance_row(row_inc); + advance_col(col_inc); + return *this; + } + +public: + size_type my_row, my_col; + dilated_row_t dilated_row; + dilated_col_t dilated_col; +}; + +template <std::size_t BitMask> +struct morton_dense_el_cursor + : public morton_dense_key<BitMask> +{ + typedef std::size_t size_type; + typedef dilated_int<std::size_t, ~BitMask, true> dilated_col_t; + typedef morton_dense_el_cursor self; + typedef morton_dense_key<BitMask> base; + typedef base key_type; + + morton_dense_el_cursor(size_type my_row, size_type my_col, size_type num_cols) + : base(my_row, my_col), num_cols(num_cols) + {} + + self& operator++ () + { + ++this->my_col; ++this->dilated_col; + if (this->my_col == num_cols) { + this->my_col= 0; this->dilated_col= dilated_col_t(0); + ++this->my_row; ++this->dilated_row; + } + return *this; + } + + base& operator* () + { + return *this; + } + + const base& operator* () const + { + return *this; + } + +protected: + size_t num_cols; +}; + +template <std::size_t BitMask> +struct morton_dense_row_cursor + : public morton_dense_key<BitMask> +{ + typedef std::size_t size_type; + typedef morton_dense_row_cursor self; + typedef morton_dense_key<BitMask> base; + typedef base key_type; + + morton_dense_row_cursor(size_type my_row, size_type my_col) + : base(my_row, my_col) + {} + + self& operator++ () + { + ++this->my_row; ++this->dilated_row; + return *this; + } + + self& operator+=(int inc) + { + this->advance_row(inc); + return *this; + } + + self& operator-- () + { + --this->my_row; --this->dilated_row; + return *this; + } + + self& operator-=(int dec) + { + this->advance_row(-dec); + return *this; + } + + self operator+ (int inc) const + { + self tmp(*this); + tmp.advance_row(inc); + return tmp; + } + + base& operator* () + { + return *this; + } + + const base& operator* () const + { + return *this; + } +}; + +template <std::size_t BitMask> +struct morton_dense_col_cursor + : public morton_dense_key<BitMask> +{ + typedef std::size_t size_type; + typedef morton_dense_col_cursor self; + typedef morton_dense_key<BitMask> base; + typedef base key_type; + + morton_dense_col_cursor(size_type my_row, size_type my_col) + : base(my_row, my_col) + {} + + self& operator++ () + { + ++this->my_col; ++this->dilated_col; + return *this; + } + + self& operator+=(int inc) + { + this->advance_col(inc); + return *this; + } + + self& operator-- () + { + --this->my_col; --this->dilated_col; + return *this; + } + + self& operator-=(int dec) + { + this->advance_col(-dec); + return *this; + } + + self operator+ (int inc) const + { + self tmp(*this); + tmp.advance_col(inc); + return tmp; + } + + base& operator* () + { + return *this; + } + + const base& operator* () const + { + return *this; + } +}; + + +template <typename Matrix> +struct morton_dense_row_const_iterator + : utilities::const_iterator_adaptor<typename mtl::traits::const_value<Matrix>::type, morton_dense_row_cursor<Matrix::mask>, + typename Matrix::value_type> +{ + static const std::size_t mask= Matrix::mask; + typedef morton_dense_row_cursor<mask> cursor_type; + typedef typename mtl::traits::const_value<Matrix>::type map_type; + typedef typename Matrix::value_type value_type; + typedef typename Matrix::size_type size_type; + typedef utilities::const_iterator_adaptor<map_type, cursor_type, value_type> base; + + morton_dense_row_const_iterator(const Matrix& matrix, size_type row, size_type col) + : base(map_type(matrix), cursor_type(row, col)) + {} +}; + + +template <typename Matrix> +struct morton_dense_row_iterator + : utilities::iterator_adaptor<typename mtl::traits::value<Matrix>::type, morton_dense_row_cursor<Matrix::mask>, + typename Matrix::value_type> +{ + static const std::size_t mask= Matrix::mask; + typedef morton_dense_row_cursor<mask> cursor_type; + typedef typename mtl::traits::value<Matrix>::type map_type; + typedef typename Matrix::value_type value_type; + typedef typename Matrix::size_type size_type; + typedef utilities::iterator_adaptor<map_type, cursor_type, value_type> base; + + morton_dense_row_iterator(Matrix& matrix, size_type row, size_type col) + : base(map_type(matrix), cursor_type(row, col)) + {} +}; + + +template <typename Matrix> +struct morton_dense_col_const_iterator + : utilities::const_iterator_adaptor<typename mtl::traits::const_value<Matrix>::type, morton_dense_col_cursor<Matrix::mask>, + typename Matrix::value_type> +{ + static const std::size_t mask= Matrix::mask; + typedef morton_dense_col_cursor<mask> cursor_type; + typedef typename mtl::traits::const_value<Matrix>::type map_type; + typedef typename Matrix::value_type value_type; + typedef typename Matrix::size_type size_type; + typedef utilities::const_iterator_adaptor<map_type, cursor_type, value_type> base; + + morton_dense_col_const_iterator(const Matrix& matrix, size_type row, size_type col) + : base(map_type(matrix), cursor_type(row, col)) + {} +}; + + +template <typename Matrix> +struct morton_dense_col_iterator + : utilities::iterator_adaptor<typename mtl::traits::value<Matrix>::type, morton_dense_col_cursor<Matrix::mask>, + typename Matrix::value_type> +{ + static const std::size_t mask= Matrix::mask; + typedef morton_dense_col_cursor<mask> cursor_type; + typedef typename mtl::traits::value<Matrix>::type map_type; + typedef typename Matrix::value_type value_type; + typedef typename Matrix::size_type size_type; + typedef utilities::iterator_adaptor<map_type, cursor_type, value_type> base; + + morton_dense_col_iterator(Matrix& matrix, size_type row, size_type col) + : base(map_type(matrix), cursor_type(row, col)) {} +}; + + + +/// Dense Morton-order matrix +template <typename Elt, std::size_t BitMask, typename Parameters = mtl::mat::parameters<> > +class morton_dense + : public base_sub_matrix<Elt, Parameters>, + public mtl::detail::contiguous_memory_block<Elt, false>, + public crtp_base_matrix< morton_dense<Elt, BitMask, Parameters>, Elt, std::size_t >, + public mat_expr< morton_dense<Elt, BitMask, Parameters> > +{ + typedef morton_dense self; + typedef base_sub_matrix<Elt, Parameters> super; + typedef mtl::detail::contiguous_memory_block<Elt, false> memory_base; + typedef crtp_matrix_assign< self, Elt, std::size_t > assign_base; + typedef mat_expr< morton_dense<Elt, BitMask, Parameters> > expr_base; + + public: + + typedef Parameters parameters; + typedef typename Parameters::orientation orientation; + typedef typename Parameters::index index_type; + typedef typename Parameters::dimensions dim_type; + typedef Elt value_type; + typedef const value_type& const_reference; + typedef value_type& reference; + typedef typename parameters::size_type size_type; + const static std::size_t mask= BitMask; + + // implement cursor for morton matrix, somewhere + // also, morton indexer? + + typedef morton_dense_key<BitMask> key_type; + typedef morton_dense_el_cursor<BitMask> el_cursor_type; + + typedef dilated_int<std::size_t, BitMask, true> dilated_row_t; + typedef dilated_int<std::size_t, ~BitMask, true> dilated_col_t; + + protected: + + // ranges of rows and columns + dilated_row_t my_begin_row, my_end_row; + dilated_col_t my_begin_col, my_end_col; + + // Set ranges from begin_r to end_r and begin_c to end_c + void set_ranges(size_type begin_r, size_type end_r, size_type begin_c, size_type end_c) + { + super::set_ranges(begin_r, end_r, begin_c, end_c); + my_begin_row= begin_r; my_end_row= end_r; + my_begin_col= begin_c; my_end_col= end_c; + set_nnz(); + } + + // Set ranges to a num_row x num_col matrix, keeps indexing + void set_ranges(size_type num_rows, size_type num_cols) + { + set_ranges(this->begin_row(), this->begin_row() + num_rows, + this->begin_col(), this->begin_col() + num_cols); + } + + void init(size_type num_rows, size_type num_cols) + { + set_ranges(num_rows, num_cols); + // set_to_zero(*this); + } + + public: + /// Default constructor + /** If compile time matrix size allocate memory. **/ + morton_dense() : memory_base(memory_need(dim_type().num_rows(), dim_type().num_cols())) + { + init(dim_type().num_rows(), dim_type().num_cols()); + } + + /// Construction from run-time dimension type + explicit morton_dense(mtl::non_fixed::dimensions d) + : memory_base(memory_need(d.num_rows(), d.num_cols())) + { + init(d.num_rows(), d.num_cols()); + } + + /// Construction of matrix of dimension \p num_rows by \p num_cols + morton_dense(size_type num_rows, size_type num_cols) + : memory_base(memory_need(num_rows, num_cols)) + { + init(num_rows, num_cols); + } + + /// Construction of matrix with dimension \p d using pointer \p a to external data + explicit morton_dense(mtl::non_fixed::dimensions d, value_type* a) + : memory_base(a, memory_need(d.num_rows(), d.num_cols())) + { + set_ranges(d.num_rows(), d.num_cols()); + } + + /// Construction of \p num_rows by \p num_cols matrix with pointer \p a to external data + explicit morton_dense(size_type num_rows, size_type num_cols, value_type* a) + : memory_base(a, memory_need(num_rows, num_cols)) + { + set_ranges(num_rows, num_cols); + } + + /// Construction of matrix with static dimension using pointer \p a to external data + explicit morton_dense(value_type* a) + : memory_base(a, memory_need(dim_type().num_rows(), dim_type().num_cols())) + { + BOOST_ASSERT((dim_type::is_static)); + set_ranges(dim_type().num_rows(), dim_type().num_cols()); + } + + /// Copy constructor + morton_dense(const self& m) + : super(m), memory_base(m) + { + set_ranges(m.num_rows(), m.num_cols()); + } + + /// Clone constructor + explicit morton_dense(const self& m, clone_ctor) + : memory_base(m, clone_ctor()) + { + init(m.num_rows(), m.num_cols()); + *this= m; + } + + /// Templated copy constructor + template <typename MatrixSrc> + explicit morton_dense(const MatrixSrc& src) + : memory_base(memory_need(dim_type().num_rows(), dim_type().num_cols())) + { + init(dim_type().num_rows(), dim_type().num_cols()); + *this= src; + } + +#if defined(MTL_WITH_INITLIST) && defined(MTL_WITH_AUTO) && defined(MTL_WITH_RANGEDFOR) + /// Constructor for initializer list \p values + template <typename Value2> + morton_dense(std::initializer_list<std::initializer_list<Value2> > values) + : super(mtl::non_fixed::dimensions(values.size(), values.size()? values.begin()->size() : 0)), + memory_base(this->num_rows() * this->num_cols()) + { + init(this->num_rows(), this->num_cols()); + *this= values; + } +#endif + +#ifdef MTL_WITH_MOVE + /// Move constructor + morton_dense(self&& src) : memory_base(memory_need(dim_type().num_rows(), dim_type().num_cols())) + { + init(dim_type().num_rows(), dim_type().num_cols()); + *this= std::move(src); + } +#endif + + /// Construct a sub-matrix as a view + explicit morton_dense(self& matrix, morton_dense_sub_ctor, + size_type begin_r, size_type end_r, size_type begin_c, size_type end_c) + : memory_base(matrix.data, memory_need(end_r - begin_r, end_c - begin_c), true) // View constructor + { + matrix.check_ranges(begin_r, end_r, begin_c, end_c); + + if (begin_r >= end_r || begin_c >= end_c) { + set_ranges(0, 0); + return; + } + + // Check whether sub-matrix is contigous memory block + // by comparing the address of the last and the first element in the entire and the sub-matrix + MTL_DEBUG_THROW_IF(&matrix[end_r-1][end_c-1] - &matrix[begin_r][begin_c] + != &matrix[end_r-begin_r-1][end_c-begin_c-1] - &matrix[0][0], + range_error("This sub-matrix cannot be used because it is split in memory")); + // Check with David if this is a sufficient condition (it is a necessary at least) + + dilated_row_t dilated_row(begin_r); + dilated_col_t dilated_col(begin_c); + + // Set new start address within masked matrix + this->data += dilated_row.dilated_value() + dilated_col.dilated_value(); + set_ranges(end_r - begin_r, end_c - begin_c); + } + + /// Change dimension to \p num_rows by \p num_cols + void change_dim(size_type num_rows, size_type num_cols) + { + set_ranges(num_rows, num_cols); + this->realloc(memory_need(num_rows, num_cols)); + } + + +#ifdef MTL_WITH_MOVE + /// Move Assignment + self& operator=(self&& src) + { + this->checked_change_dim(src.num_rows(), src.num_cols()); + if (this->category == memory_base::view || src.category == memory_base::view) + matrix_copy(src, *this); + else + memory_base::move_assignment(src); + // std::cout << "In dense2D::move_assignment\n"; + return *this; + } + + /// Copy Assignment + self& operator=(const self& src) + { + this->checked_change_dim(src.num_rows(), src.num_cols()); + // this->check_dim(src.num_rows(), src.num_cols()); + matrix_copy(src, *this); + return *this; + } +#else + /// Copy assignment (with move emulation) + self& operator=(self src) + { + // Self-copy would be an indication of an error + assert(this != &src); + + this->check_dim(src.num_rows(), src.num_cols()); + if (this->category == memory_base::view || src.category == memory_base::view) + matrix_copy(src, *this); + else + memory_base::move_assignment(src); + return *this; + } +#endif + + using assign_base::operator=; + + + value_type operator() (key_type const& key) const + { + return this->data[key.dilated_row.dilated_value() + key.dilated_col.dilated_value()]; + } + + void operator()(key_type const& key, value_type const& value) + { + this->data[key.dilated_row.dilated_value() + key.dilated_col.dilated_value()]= value; + } + + /// Constant reference to A[row][col] + const_reference operator() (size_type row, size_type col) const + { + MTL_DEBUG_THROW_IF(is_negative(row) || row >= this->num_rows() || is_negative(col) || col >= this->num_cols(), index_out_of_range()); + return this->data[dilated_row_t(row).dilated_value() + dilated_col_t(col).dilated_value()]; + } + + /// Mutable reference to A[row][col] + value_type& operator() (size_type row, size_type col) + { + MTL_DEBUG_THROW_IF(is_negative(row) || row >= this->num_rows() || is_negative(col) || col >= this->num_cols(), index_out_of_range()); + return this->data[dilated_row_t(row).dilated_value() + dilated_col_t(col).dilated_value()]; + } + + void crop() {} ///< Delete structural zeros, only dummy here + + protected: + void set_nnz() + { + this->my_nnz = this->num_rows() * this->num_cols(); + } + + size_type memory_need(size_type rows, size_type cols) + { + dilated_row_t n_rows(rows - 1); + dilated_col_t n_cols(cols - 1); + return (n_rows.dilated_value() + n_cols.dilated_value() + 1); + } + + /// Swap matrices + friend void swap(self& matrix1, self& matrix2) + { + swap(static_cast<memory_base&>(matrix1), static_cast<memory_base&>(matrix2)); + swap(static_cast<super&>(matrix1), static_cast<super&>(matrix2)); + } + + template <typename> friend struct sub_matrix_t; +}; + + +// ================ +// Free functions +// ================ + +/// Number of rows +template <typename Value, std::size_t Mask, typename Parameters> +typename morton_dense<Value, Mask, Parameters>::size_type +inline num_rows(const morton_dense<Value, Mask, Parameters>& matrix) +{ + return matrix.num_rows(); +} + +/// Number of columns +template <typename Value, std::size_t Mask, typename Parameters> +typename morton_dense<Value, Mask, Parameters>::size_type +inline num_cols(const morton_dense<Value, Mask, Parameters>& matrix) +{ + return matrix.num_cols(); +} + +/// Matrix size, i.e. number of rows times columns +template <typename Value, std::size_t Mask, typename Parameters> +typename morton_dense<Value, Mask, Parameters>::size_type +inline size(const morton_dense<Value, Mask, Parameters>& matrix) +{ + return matrix.num_cols() * matrix.num_rows(); +} + +}} // namespace mtl::matrix + + + + +// ================ +// Range generators +// ================ + +namespace mtl { namespace traits { + + // VC 8.0 finds ambiguity with mtl::tag::morton_dense (I wonder why) + using mtl::mat::morton_dense; + using mtl::mat::morton_dense_el_cursor; + using mtl::mat::morton_dense_col_cursor; + using mtl::mat::morton_dense_row_cursor; + using mtl::mat::morton_dense_col_const_iterator; + using mtl::mat::morton_dense_row_const_iterator; + using mtl::mat::morton_dense_col_iterator; + using mtl::mat::morton_dense_row_iterator; + + // =========== + // For cursors + // =========== + + template <class Elt, std::size_t BitMask, class Parameters> + struct range_generator<glas::tag::all, morton_dense<Elt, BitMask, Parameters> > + { + typedef morton_dense<Elt, BitMask, Parameters> Matrix; + typedef complexity_classes::linear_cached complexity; + static int const level = 1; + typedef morton_dense_el_cursor<BitMask> type; + type begin(Matrix const& matrix) + { + return type(matrix.begin_row(), matrix.begin_col(), matrix.num_cols()); + } + type end(Matrix const& matrix) + { + return type(matrix.end_row(), matrix.begin_col(), matrix.num_cols()); + } + }; + + template <class Elt, std::size_t BitMask, class Parameters> + struct range_generator<glas::tag::nz, morton_dense<Elt, BitMask, Parameters> > + : range_generator<glas::tag::all, morton_dense<Elt, BitMask, Parameters> > + {}; + + template <class Elt, std::size_t BitMask, class Parameters> + struct range_generator<glas::tag::row, morton_dense<Elt, BitMask, Parameters> > + : detail::all_rows_range_generator<morton_dense<Elt, BitMask, Parameters>, complexity_classes::linear_cached> + {}; + + // For a cursor pointing to some row give the range of elements in this row + template <class Elt, std::size_t BitMask, class Parameters> + struct range_generator<glas::tag::nz, + detail::sub_matrix_cursor<morton_dense<Elt, BitMask, Parameters>, glas::tag::row, 2> > + { + typedef morton_dense<Elt, BitMask, Parameters> matrix; + typedef typename Collection<matrix>::size_type size_type; + typedef detail::sub_matrix_cursor<matrix, glas::tag::row, 2> cursor; + typedef complexity_classes::linear_cached complexity; + static int const level = 1; + typedef morton_dense_col_cursor<BitMask> type; + + type begin(cursor const& c) const + { + return type(c.key, c.ref.begin_col()); + } + type end(cursor const& c) const + { + return type(c.key, c.ref.end_col()); + } + type lower_bound(cursor const& c, size_type position) const + { + return type(c.key, std::min(c.ref.end_col(), position)); + } + }; + + template <class Elt, std::size_t BitMask, class Parameters> + struct range_generator<glas::tag::all, + detail::sub_matrix_cursor<morton_dense<Elt, BitMask, Parameters>, glas::tag::row, 2> > + : range_generator<glas::tag::nz, + detail::sub_matrix_cursor<morton_dense<Elt, BitMask, Parameters>, glas::tag::row, 2> > + {}; + + template <class Elt, std::size_t BitMask, class Parameters> + struct range_generator<glas::tag::col, morton_dense<Elt, BitMask, Parameters> > + : detail::all_cols_range_generator<morton_dense<Elt, BitMask, Parameters>, complexity_classes::linear_cached> + {}; + + // For a cursor pointing to some row give the range of elements in this row + template <class Elt, std::size_t BitMask, class Parameters> + struct range_generator<glas::tag::nz, + detail::sub_matrix_cursor<morton_dense<Elt, BitMask, Parameters>, glas::tag::col, 2> > + { + typedef morton_dense<Elt, BitMask, Parameters> matrix; + typedef typename Collection<matrix>::size_type size_type; + typedef detail::sub_matrix_cursor<matrix, glas::tag::col, 2> cursor; + typedef complexity_classes::linear_cached complexity; + static int const level = 1; + typedef morton_dense_row_cursor<BitMask> type; + + type begin(cursor const& c) + { + return type(c.ref.begin_row(), c.key); + } + type end(cursor const& c) + { + return type(c.ref.end_row(), c.key); + } + type lower_bound(cursor const& c, size_type position) const + { + return type(std::min(c.ref.end_row(), position), c.key); + } + }; + + template <class Elt, std::size_t BitMask, class Parameters> + struct range_generator<glas::tag::all, + detail::sub_matrix_cursor<morton_dense<Elt, BitMask, Parameters>, glas::tag::col, 2> > + : range_generator<glas::tag::nz, + detail::sub_matrix_cursor<morton_dense<Elt, BitMask, Parameters>, glas::tag::col, 2> > + {}; + + +// ============= +// For iterators +// ============= + + namespace detail { + + template <typename OuterTag, typename Matrix, bool is_const> + struct morton_dense_iterator_range_generator + { + typedef Matrix matrix_type; + typedef typename matrix_type::size_type size_type; + typedef typename matrix_type::value_type value_type; + typedef typename matrix_type::parameters parameters; + typedef detail::sub_matrix_cursor<matrix_type, OuterTag, 2> cursor; + + typedef complexity_classes::linear_cached complexity; + static int const level = 1; + + typedef typename boost::mpl::if_< + boost::is_same<OuterTag, glas::tag::row> + , typename boost::mpl::if_c< + is_const + , morton_dense_col_const_iterator<Matrix> + , morton_dense_col_iterator<Matrix> + >::type + , typename boost::mpl::if_c< + is_const + , morton_dense_row_const_iterator<Matrix> + , morton_dense_row_iterator<Matrix> + >::type + >::type type; + + private: + + typedef typename boost::mpl::if_c<is_const, const Matrix&, Matrix&>::type mref_type; + + type begin_dispatch(cursor const& c, glas::tag::row) + { + return type(const_cast<mref_type>(c.ref), c.key, c.ref.begin_col()); + } + + type end_dispatch(cursor const& c, glas::tag::row) + { + return type(const_cast<mref_type>(c.ref), c.key, c.ref.end_col()); + } + + type begin_dispatch(cursor const& c, glas::tag::col) + { + return type(const_cast<mref_type>(c.ref), c.ref.begin_row(), c.key); + } + + type end_dispatch(cursor const& c, glas::tag::col) + { + return type(const_cast<mref_type>(c.ref), c.ref.end_row(), c.key); + } + + public: + + type begin(cursor const& c) + { + return begin_dispatch(c, OuterTag()); + } + + type end(cursor const& c) + { + return end_dispatch(c, OuterTag()); + } + }; + + } // namespace detail + + + template <typename Value, std::size_t BitMask, typename Parameters, typename OuterTag> + struct range_generator<tag::iter::nz, + detail::sub_matrix_cursor<morton_dense<Value, BitMask, Parameters>, OuterTag, 2> > + : public detail::morton_dense_iterator_range_generator<OuterTag, morton_dense<Value, BitMask, Parameters>, false> + {}; + + template <typename Value, std::size_t BitMask, typename Parameters, typename OuterTag> + struct range_generator<tag::iter::all, + detail::sub_matrix_cursor<morton_dense<Value, BitMask, Parameters>, OuterTag, 2> > + : public detail::morton_dense_iterator_range_generator<OuterTag, morton_dense<Value, BitMask, Parameters>, false> + {}; + + template <typename Value, std::size_t BitMask, typename Parameters, typename OuterTag> + struct range_generator<tag::const_iter::nz, + detail::sub_matrix_cursor<morton_dense<Value, BitMask, Parameters>, OuterTag, 2> > + : public detail::morton_dense_iterator_range_generator<OuterTag, morton_dense<Value, BitMask, Parameters>, true> + {}; + + template <typename Value, std::size_t BitMask, typename Parameters, typename OuterTag> + struct range_generator<tag::const_iter::all, + detail::sub_matrix_cursor<morton_dense<Value, BitMask, Parameters>, OuterTag, 2> > + : public detail::morton_dense_iterator_range_generator<OuterTag, morton_dense<Value, BitMask, Parameters>, true> + {}; + + +}} // namespace mtl::traits + + +namespace mtl { namespace mat { + + // ========== + // Sub matrix + // ========== + + template <typename Value, std::size_t BitMask, typename Parameters> + struct sub_matrix_t<morton_dense<Value, BitMask, Parameters> > + { + typedef morton_dense<Value, BitMask, Parameters> matrix_type; + typedef matrix_type sub_matrix_type; + typedef matrix_type const const_sub_matrix_type; + typedef typename matrix_type::size_type size_type; + + sub_matrix_type operator()(matrix_type& matrix, size_type begin_r, size_type end_r, size_type begin_c, size_type end_c) + { + return sub_matrix_type(matrix, morton_dense_sub_ctor(), begin_r, end_r, begin_c, end_c); + } + + const_sub_matrix_type + operator()(matrix_type const& matrix, size_type begin_r, size_type end_r, size_type begin_c, size_type end_c) + { + // To minimize code duplication, we use the non-const version + sub_matrix_type tmp((*this)(const_cast<matrix_type&>(matrix), begin_r, end_r, begin_c, end_c)); + return tmp; + } + }; + +}} // mtl::matrix + +namespace mtl { + + using mat::morton_dense; + + // Enable cloning of dense matrices + template <typename Value, std::size_t BitMask, typename Parameters> + struct is_clonable< mat::morton_dense<Value, BitMask, Parameters> > : boost::mpl::true_ {}; + +} // namespace mtl + +#endif // MTL_MORTON_DENSE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/multi_vector.hpp b/install/MTL/include/boost/numeric/mtl/matrix/multi_vector.hpp new file mode 100644 index 00000000..9605ab6e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/multi_vector.hpp @@ -0,0 +1,227 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_MULTI_VECTOR_INCLUDE +#define MTL_MATRIX_MULTI_VECTOR_INCLUDE + +#include <cassert> +#include <boost/utility/enable_if.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp> +#include <boost/numeric/mtl/matrix/mat_expr.hpp> +#include <boost/numeric/mtl/matrix/multi_vector_range.hpp> +#include <boost/numeric/mtl/matrix/make_fast_multi_vector_expr.hpp> +#include <boost/numeric/mtl/utility/is_what.hpp> +#include <boost/numeric/mtl/utility/is_composable_vector.hpp> +#include <boost/numeric/mtl/utility/is_multi_vector_expr.hpp> +#include <boost/numeric/mtl/utility/fast_multi_vector_expr.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> + + +namespace mtl { namespace mat { + + +// Might need to be defined later +struct multi_vector_key {}; + +/// Matrix constituting of set of column vectors (under development) +template <typename Vector> +class multi_vector + : public base_matrix<typename mtl::Collection<Vector>::value_type, parameters<> >, + public crtp_base_matrix< multi_vector<Vector>, typename Collection<Vector>::value_type, + typename Collection<Vector>::size_type>, + public mat_expr< multi_vector<Vector> > +{ + typedef base_matrix<typename Collection<Vector>::value_type, parameters<> > super; + + // Vector must by column vector + MTL_STATIC_ASSERT((boost::is_same<typename OrientedCollection<Vector>::orientation, + tag::col_major>::value), + "Vector must be a column vector."); + public: + typedef multi_vector self; + // typedef mtl::mat::parameters<> parameters; + typedef Vector vector_type; + typedef tag::col_major orientation; + typedef typename Collection<Vector>::value_type value_type; + typedef typename Collection<Vector>::size_type size_type; + typedef const value_type& const_reference; + typedef value_type& reference; + typedef multi_vector_key key_type; + typedef crtp_matrix_assign< self, value_type, size_type > assign_base; + + multi_vector() : super(non_fixed::dimensions(0, 0)), master(0) {} + + private: + void setup_data(size_type num_rows, size_type num_cols, boost::mpl::false_) + { + for (size_type i= 0; i < num_cols; ++i) + data[i]= Vector(num_rows); + master= 0; + } + + void setup_data(size_type num_rows, size_type num_cols, boost::mpl::true_) + { + master= new Vector(num_rows * num_cols); + for (size_type i= 0; i < num_cols; ++i) { + Vector tmp((*master)[irange(i * num_rows, (i+1) * num_rows)]); + swap(data[i], tmp); + } + } + + public: + /// Constructor by number of rows and columns + multi_vector(size_type num_rows, size_type num_cols) + : super(non_fixed::dimensions(num_rows, num_cols)), data(num_cols) + { + setup_data(num_rows, num_cols, mtl::traits::is_composable_vector<Vector>()); + this->my_nnz= num_rows * num_cols; + } + + /// Constructor column vector and number of columns (for easier initialization) + multi_vector(const Vector& v, size_type num_cols) + : super(non_fixed::dimensions(size(v), num_cols)), data(num_cols) + { + using mtl::num_rows; + setup_data(num_rows(v), num_cols, mtl::traits::is_composable_vector<Vector>()); + for (size_type i= 0; i < num_cols; ++i) + data[i]= v; + this->my_nnz= num_cols * size(v); + } + + ~multi_vector() { delete master; } + + private: + + void change_dim(size_type r, size_type c, boost::mpl::false_) + { + for (size_type i= 0; i < c; i++) + data[i].change_dim(r); + } + + void change_dim(size_type r, size_type c, boost::mpl::true_) + { + delete master; + setup_data(r, c, boost::mpl::true_()); + } + + public: + /// Change dimension, can keep old data + void change_dim(size_type r, size_type c) + { + if (r == super::num_rows() && c == super::num_cols()) return; + super::change_dim(r, c); + data.change_dim(c); + change_dim(r, c, mtl::traits::is_composable_vector<Vector>()); + } + + void self_assignment(const self& src, boost::mpl::false_) + { + for (size_type i= 0; i < super::num_cols(); i++) + data[i]= src.data[i]; + } + + void self_assignment(const self& src, boost::mpl::true_) + { *master= *src.master; } + + /// Copy constructor + /** Explicitly needed now. **/ + self& operator=(const self& src) + { + assign_base::checked_change_dim(src.num_rows(), src.num_cols()); + self_assignment(src, mtl::traits::is_composable_vector<Vector>()); + return *this; + } + + // Todo: multi_vector with other matrix expressions + /// Assign multi_vector and expressions thereof, general matrices currently not allowed + template <typename Src> + typename boost::enable_if_c<mtl::traits::is_multi_vector_expr<Src>::value + && !mtl::traits::is_fast_multi_vector_expr<Src>::value, self&>::type + operator=(const Src& src) + { + MTL_THROW_IF((mtl::mat::num_rows(src) != super::num_rows() + || mtl::mat::num_cols(src) != super::num_cols()), incompatible_size()); + for (std::size_t i= 0, n= super::num_cols(); i < n; ++i) + vector(i)= src.vector(i); + return *this; + } + + /// Assign multi_vector and expressions thereof that are stored internally by a single vector + template <typename Src> + typename boost::enable_if<mtl::traits::is_fast_multi_vector_expr<Src>, self&>::type + operator=(const Src& src) + { + assert(master); + *master= make_fast_multi_vector_expr(src); + return *this; + } + + template <typename Src> + typename boost::enable_if_c<mtl::traits::is_matrix<Src>::value + && !mtl::traits::is_multi_vector_expr<Src>::value, self&>::type + operator=(const Src& src) + { + assign_base::operator=(src); + return *this; + } + + /// Assign scalar + template <typename Src> + typename boost::enable_if<mtl::traits::is_scalar<Src>, self&>::type + operator=(const Src& src) + { + assign_base::operator=(src); + return *this; + } + + const_reference operator() (size_type i, size_type j) const { return data[j][i]; } + reference operator() (size_type i, size_type j) { return data[j][i]; } + + Vector& vector(size_type i) { return data[i]; } + const Vector& vector(size_type i) const { return data[i]; } + + Vector& at(size_type i) { return data[i]; } + const Vector& at(size_type i) const { return data[i]; } + + multi_vector_range<Vector> vector(irange const& r) const { return multi_vector_range<Vector>(*this, r); } + + inline friend const Vector& make_fast_multi_vector_expr(const self& mv) { assert(mv.master); return *mv.master; } + inline friend Vector& make_fast_multi_vector_expr(self& mv) { assert(mv.master); return *mv.master; } + + protected: + mtl::dense_vector<Vector, mtl::vec::parameters<> > data; + Vector* master; +}; + +/// Number of rows +template< typename Vector > +typename Collection< Vector >::size_type num_cols(const multi_vector< Vector >& A) { return A.num_cols(); } + +/// Number of columns +template< typename Vector > +typename Collection< Vector >::size_type num_rows(const multi_vector< Vector >& A) { return A.num_rows(); } + +/// Size as defined by number of rows times columns +template< typename Vector > +typename Collection< Vector >::size_type size(const multi_vector< Vector >& A) { return num_rows(A) * num_cols(A); } +}} // namespace mtl::matrix + +namespace mtl { + using mat::multi_vector; +} + +#endif // MTL_MATRIX_MULTI_VECTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/multi_vector_range.hpp b/install/MTL/include/boost/numeric/mtl/matrix/multi_vector_range.hpp new file mode 100644 index 00000000..74480519 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/multi_vector_range.hpp @@ -0,0 +1,53 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_MULTI_VECTOR_RANGE_INCLUDE +#define MTL_MATRIX_MULTI_VECTOR_RANGE_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/matrix/multi_vector.hpp> + +namespace mtl { namespace mat { + +// So far only const, might be refactored for mutability later +template <typename Vector> +class multi_vector_range +{ + public: + typedef multi_vector_range self; + typedef typename Collection<Vector>::size_type size_type; + typedef typename Collection<Vector>::value_type value_type; + typedef const value_type& const_reference; + + multi_vector_range(const multi_vector<Vector>& ref, const irange& r) : ref(ref), r(r) {} + + const_reference operator() (size_type i, size_type j) const { return ref[r.to_range(j)][i]; } + const Vector& vector(size_type i) const { return ref.vector(r.to_range(i)); } + + /// Number of rows + friend size_type num_rows(const self& A) { return num_rows(A.ref); } + + /// Number of columns + friend size_type num_cols(const self& A) { return A.r.size(); } + + /// Size as defined by number of rows times columns + friend size_type size(const self& A) { return num_rows(A) * num_cols(A); } + + protected: + const multi_vector<Vector>& ref; + const irange r; +}; + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_MULTI_VECTOR_RANGE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/operators.hpp b/install/MTL/include/boost/numeric/mtl/matrix/operators.hpp new file mode 100644 index 00000000..b2bbe56a --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/operators.hpp @@ -0,0 +1,100 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_OPERATORS_INCLUDE +#define MTL_MATRIX_OPERATORS_INCLUDE + +#include <boost/utility/enable_if.hpp> +#include <boost/mpl/and.hpp> + +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/is_multi_vector_expr.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/matrix/all_mat_expr.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> + + +namespace mtl { namespace mat { + +template <typename E1, typename E2> +inline mat_mat_plus_expr<E1, E2> +operator+ (const mat_expr<E1>& e1, const mat_expr<E2>& e2) +{ + // do not add matrices with inconsistent value types + MTL_STATIC_ASSERT((boost::is_same<typename ashape::ashape<E1>::type, + typename ashape::ashape<E2>::type>::value), "Matrices have not consistent algebraic shape (i.e. nested types)."); + return mat_mat_plus_expr<E1, E2>(static_cast<const E1&>(e1), static_cast<const E2&>(e2)); +} + +// if enabled it has priority over previous functions because that performs upcast +template <typename E1, typename E2> +typename boost::enable_if_c<mtl::traits::is_multi_vector_expr<E1>::value && mtl::traits::is_multi_vector_expr<E2>::value, mv_mv_plus_expr<E1, E2> >::type +inline operator+(const E1& e1, const E2& e2) +{ + return mv_mv_plus_expr<E1, E2>(e1, e2); +} + +// Specialization for multi_vector +// template <typename V1, typename V2> +// inline mv_mv_plus_expr<multi_vector<V1>, multi_vector<V2> > +// operator+(const multi_vector<V1>& m1, const multi_vector<V2>& m2) +// { +// return mv_mv_plus_expr<multi_vector<V1>, multi_vector<V2> >(m1, m2); +// } + +#if 0 +// Planned for future optimizations on sums of dense matrix expressions +template <typename E1, typename E2> +inline dmat_dmat_plus_expr<E1, E2> +operator+ (const dmat_expr<E1>& e1, const dmat_expr<E2>& e2) +{ + // do not add matrices with inconsistent value types + MTL_STATIC_ASSERT((boost::is_same<typename ashape::ashape<E1>::type, + typename ashape::ashape<E2>::type>::value), "Matrices have not consistent algebraic shape (i.e. nested types)."); + return dmat_dmat_plus_expr<E1, E2>(static_cast<const E1&>(e1), static_cast<const E2&>(e2)); +} +#endif + + +template <typename E1, typename E2> +inline mat_mat_minus_expr<E1, E2> +operator- (const mat_expr<E1>& e1, const mat_expr<E2>& e2) +{ + // do not add matrices with inconsistent value types + MTL_STATIC_ASSERT((boost::is_same<typename ashape::ashape<E1>::type, + typename ashape::ashape<E2>::type>::value), "Matrices have not consistent algebraic shape (i.e. nested types)."); + return mat_mat_minus_expr<E1, E2>(static_cast<const E1&>(e1), static_cast<const E2&>(e2)); +} + +// if enabled it has priority over previous functions because that performs upcast +template <typename E1, typename E2> +typename boost::enable_if_c<mtl::traits::is_multi_vector_expr<E1>::value && mtl::traits::is_multi_vector_expr<E2>::value, mv_mv_minus_expr<E1, E2> >::type +inline operator-(const E1& e1, const E2& e2) +{ + return mv_mv_minus_expr<E1, E2>(e1, e2); +} + +template <typename E1, typename E2> +inline mat_mat_ele_times_expr<E1, E2> +ele_prod(const mat_expr<E1>& e1, const mat_expr<E2>& e2) +{ + // do not multiply matrices element-wise with inconsistent value types + MTL_STATIC_ASSERT((boost::is_same<typename ashape::ashape<E1>::type, + typename ashape::ashape<E2>::type>::value), "Matrices do not have consistent algebraic shape (i.e. nested types)."); + return mat_mat_ele_times_expr<E1, E2>(static_cast<const E1&>(e1), static_cast<const E2&>(e2)); +} + + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_OPERATORS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/parameter.hpp b/install/MTL/include/boost/numeric/mtl/matrix/parameter.hpp new file mode 100644 index 00000000..19b77872 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/parameter.hpp @@ -0,0 +1,51 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_PARAMETERS_INCLUDE +#define MTL_MATRIX_PARAMETERS_INCLUDE + +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/detail/index.hpp> +#include <boost/numeric/mtl/matrix/dimension.hpp> +#include <boost/numeric/mtl/utility/is_static.hpp> + +namespace mtl { namespace mat { + +/// Type for bundling template parameters of common matrix types +/** OnStack = true can only be used with fixed::dimensions. + \sa \ref matrix_parameters + \sa \ref tuning_fsize + \sa \ref tuning_sizetype **/ +template <typename Orientation= row_major, + typename Index= index::c_index, + typename Dimensions= mtl::non_fixed::dimensions, + bool OnStack= mtl::traits::is_static<Dimensions>::value, + typename SizeType= std::size_t> +struct parameters +{ + typedef Orientation orientation; + typedef Index index; + typedef Dimensions dimensions; + static bool const on_stack= OnStack; + typedef SizeType size_type; + + // Matrix dimensions must be known at compile time to be on the stack + // MTL_STATIC_ASSERT(( !on_stack || dimensions::is_static ), "Types to be stored on stack must provide static size."); +}; + +/// Short-cut to define parameters with unsigned and defaults otherwise +typedef parameters<row_major, index::c_index, mtl::non_fixed::dimensions, false, unsigned> unsigned_parameters; + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_PARAMETERS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/permutation.hpp b/install/MTL/include/boost/numeric/mtl/matrix/permutation.hpp new file mode 100644 index 00000000..a486659d --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/permutation.hpp @@ -0,0 +1,59 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_PERMUTATION_INCLUDE +#define MTL_MATRIX_PERMUTATION_INCLUDE + +#include <boost/numeric/mtl/operation/size.hpp> +#include <boost/numeric/mtl/matrix/reorder.hpp> + +namespace mtl { namespace mat { + + +namespace traits { + + //\ Return type of mtl::mat::permutation + // Only for completeness + template <typename Value= short> + struct permutation + { + typedef typename reorder<Value>::type type; + }; +} + +template <typename Value, typename PermutationVector> +typename traits::permutation<Value>::type +inline permutation(const PermutationVector& v) +{ + using mtl::size; + return reorder(v, size(v)); +} + +/// Computes permutation matrix from corresponding vector +template <typename PermutationVector> +typename traits::permutation<>::type +inline permutation(const PermutationVector& v) +{ + return permutation<short>(v); +} + + +}} // namespace mtl::matrix + +namespace mtl { namespace vec { + + /// Import into vector namespace; see \ref mtl::mat::permutation + using mtl::mat::permutation; + +}} // namespace mtl::vector + +#endif // MTL_MATRIX_PERMUTATION_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/poisson2D_dirichlet.hpp b/install/MTL/include/boost/numeric/mtl/matrix/poisson2D_dirichlet.hpp new file mode 100644 index 00000000..2c10d9be --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/poisson2D_dirichlet.hpp @@ -0,0 +1,104 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_POISSON2D_DIRICHLET_INCLUDE +#define MTL_MATRIX_POISSON2D_DIRICHLET_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/vector/mat_cvec_multiplier.hpp> + +namespace mtl { namespace mat { + +/// Matrix-free linear operator for a Poisson equation on a rectangular domain of \p m by \p n with Dirichlet boundary conditions +struct poisson2D_dirichlet +{ + /// Constructor + poisson2D_dirichlet(int m, int n) : m(m), n(n), s(m * n) {} + + /// Member function that realizes the multiplication + template <typename VectorIn, typename VectorOut, typename Assign> + void mult(const VectorIn& v, VectorOut& w, Assign) const + { + MTL_DEBUG_THROW_IF(int(size(v)) != s, incompatible_size()); + MTL_DEBUG_THROW_IF(size(v) != size(w), incompatible_size()); + + const int nb = n < 3 ? 1 : (n - 2) / 4 * 4 + 1; + + // Inner domain + for (int i= 1; i < m-1; i++) { + int kmax= i * n + nb; + for (int k= i * n + 1; k < kmax; k+= 4) { + typename Collection<VectorIn>::value_type const v0= v[k], v1= v[k+1], v2= v[k+2], v3= v[k+3]; + Assign::apply(w[k], 4 * v0 - v[k-n] - v[k+n] - v[k-1] - v1); + Assign::apply(w[k+1], 4 * v1 - v[k-n+1] - v[k+n+1] - v0 - v2); + Assign::apply(w[k+2], 4 * v2 - v[k-n+2] - v[k+n+2] - v1 - v3); + Assign::apply(w[k+3], 4 * v3 - v[k-n+3] - v[k+n+3] - v2 - v[k+4]); + } + for (int j= nb, k= i * n + j; j < n-1; j++, k++) + Assign::apply(w[k], 4 * v[k] - v[k-n] - v[k+n] - v[k-1] - v[k+1]); + } + + // Upper border + for (int j= 1; j < n-1; j++) + Assign::apply(w[j], 4 * v[j] - v[j+n] - v[j-1] - v[j+1]); + + // Lower border + for (int j= 1, k= (m-1) * n + j; j < n-1; j++, k++) + Assign::apply(w[k], 4 * v[k] - v[k-n] - v[k-1] - v[k+1]); + + // Left border + for (int i= 1, k= n; i < m-1; i++, k+= n) + Assign::apply(w[k], 4 * v[k] - v[k-n] - v[k+n] - v[k+1]); + + // Right border + for (int i= 1, k= n+n-1; i < m-1; i++, k+= n) + Assign::apply(w[k], 4 * v[k] - v[k-n] - v[k+n] - v[k-1]); + + // Corners + Assign::apply(w[0], 4 * v[0] - v[1] - v[n]); + Assign::apply(w[n-1], 4 * v[n-1] - v[n-2] - v[2*n - 1]); + Assign::apply(w[(m-1)*n], 4 * v[(m-1)*n] - v[(m-2)*n] - v[(m-1)*n+1]); + Assign::apply(w[m*n-1], 4 * v[m*n-1] - v[m*n-2] - v[m*n-n-1]); + } + + /// Multiplication is procastinated until we know where the product goes + template <typename VectorIn> + vec::mat_cvec_multiplier<poisson2D_dirichlet, VectorIn> operator*(const VectorIn& v) const + { return vec::mat_cvec_multiplier<poisson2D_dirichlet, VectorIn>(*this, v); } + + int m, n, s; +}; + +inline std::size_t size(const poisson2D_dirichlet& A) { return A.s * A.s; } ///< Matrix size +inline std::size_t num_rows(const poisson2D_dirichlet& A) { return A.s; } ///< Number of rows +inline std::size_t num_cols(const poisson2D_dirichlet& A) { return A.s; } ///< Number of columns + +}} // namespace mtl::matrix + +namespace mtl { + + template <> + struct Collection<mat::poisson2D_dirichlet> + { + typedef double value_type; + typedef int size_type; + }; + + namespace ashape { + template <> struct ashape_aux<mtl::mat::poisson2D_dirichlet> + { typedef nonscal type; }; + } +} + +#endif // MTL_MATRIX_POISSON2D_DIRICHLET_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/reorder.hpp b/install/MTL/include/boost/numeric/mtl/matrix/reorder.hpp new file mode 100644 index 00000000..937fcceb --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/reorder.hpp @@ -0,0 +1,65 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_REORDER_INCLUDE +#define MTL_MATRIX_REORDER_INCLUDE + +#include <algorithm> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/mtl/matrix/reorder_ref.hpp> + +namespace mtl { namespace mat { + + +namespace traits { + + /// Return type of mtl::mat::reorder + template <typename Value= short> + struct reorder + { + typedef mtl::mat::compressed2D<Value, parameters<> > type; + }; +} + + +template <typename Value, typename ReorderVector> +typename traits::reorder<Value>::type +reorder(const ReorderVector& v, std::size_t cols= 0) +{ + typename traits::reorder<Value>::type A; + reorder_ref(v, A, cols); + return A; +} + + +/// Computes reordering matrix from corresponding vector +template <typename ReorderVector> +typename traits::reorder<>::type +inline reorder(const ReorderVector& v, std::size_t cols= 0) +{ + return reorder<short>(v, cols); +} + + +}} // namespace mtl::matrix + +namespace mtl { namespace vec { + + /// Import into vector namespace; see \ref mtl::mat::reorder + using mtl::mat::reorder; + +}} // namespace mtl::vector + +#endif // MTL_MATRIX_REORDER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/reorder_matrix_rows.hpp b/install/MTL/include/boost/numeric/mtl/matrix/reorder_matrix_rows.hpp new file mode 100644 index 00000000..54725072 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/reorder_matrix_rows.hpp @@ -0,0 +1,51 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_REORDER_MATRIX_ROWS_INCLUDE +#define MTL_MATRIX_REORDER_MATRIX_ROWS_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/mtl/operation/size.hpp> + +namespace mtl { namespace mat { + +/// Reorder the rows of a matrix without creating a reorder matrix +/** This is less elegant but avoids cyclic dependencies. Does not work with CCS matrices. **/ +template <typename ReorderVector, typename Matrix> +Matrix reorder_matrix_rows(const ReorderVector& v, const Matrix& A) +{ + using mtl::size; + + typename mtl::traits::col<Matrix>::type col(A); + typename mtl::traits::const_value<Matrix>::type value(A); + typedef typename mtl::traits::range_generator<tag::row, Matrix>::type cursor_type; + typedef typename mtl::traits::range_generator<tag::nz, cursor_type>::type icursor_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + + Matrix B(size(v), num_cols(A)); + + inserter<Matrix> ins(B, size_type(B.nnz() / num_cols(B) * 1.2)); + + for (std::size_t i= 0; i < size(v); i++) { + cursor_type cursor(v[i], A); // go to row given by reorder + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) + ins[i][col(*icursor)] << value(*icursor); + } + return B; +} + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_REORDER_MATRIX_ROWS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/reorder_ref.hpp b/install/MTL/include/boost/numeric/mtl/matrix/reorder_ref.hpp new file mode 100644 index 00000000..a693c1f6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/reorder_ref.hpp @@ -0,0 +1,53 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_REORDER_REF_INCLUDE +#define MTL_MATRIX_REORDER_REF_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/size.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> + +namespace mtl { namespace mat { + + +template <typename ReorderVector, typename Matrix> +void reorder_ref(const ReorderVector& v, Matrix& A, std::size_t cols= 0) +{ + using math::one; using mtl::size; + typedef typename Collection<Matrix>::value_type value_type; + + if (size(v) == 0) { + A.change_dim(0, cols); return; } + + // Find maximal entry (don't use mtl::max to allow for arrays and others) + std::size_t s= size(v), + my_max= std::size_t(*std::max_element(&v[0], &v[0] + s)) + 1; + + if (cols == 0) + cols= my_max; + else + MTL_THROW_IF(my_max > cols, range_error("Too large value in reorder vector")); + + A.change_dim(s, cols); + inserter<Matrix> ins(A, 1); + for (std::size_t i= 0; i < s; i++) + ins[i][v[i]] << one(value_type()); +} + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_REORDER_REF_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/shifted_inserter.hpp b/install/MTL/include/boost/numeric/mtl/matrix/shifted_inserter.hpp new file mode 100644 index 00000000..2c2bdaa8 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/shifted_inserter.hpp @@ -0,0 +1,74 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_SHIFTED_INSERTER_INCLUDE +#define MTL_MATRIX_SHIFTED_INSERTER_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/update.hpp> + +namespace mtl { namespace mat { + +/// Inserter with shifted row and column indices +/** The main work is performed by the underlying base inserter whose type is given as template + argument. **/ +template <typename BaseInserter> +class shifted_inserter +{ + public: + typedef shifted_inserter self; + typedef typename BaseInserter::matrix_type matrix_type; + typedef typename Collection<matrix_type>::size_type size_type; + typedef operations::update_proxy<BaseInserter, size_type> proxy_type; + + /// Constructor with matrix \p A, the slot size and the offsets + shifted_inserter(matrix_type& A, size_type slot_size= 0, + size_type row_offset= 0, size_type col_offset= 0) + : ins(A, slot_size), row_offset(row_offset), col_offset(col_offset) {} + + void set_row_offset(size_type ro) { row_offset= ro; } ///< Change row offset + void set_col_offset(size_type co) { col_offset= co; } ///< Change column offset + + size_type get_row_offset() const { return row_offset; } ///< Get row offset + size_type get_col_offset() const { return col_offset; } ///< Get column offset + + private: + struct bracket_proxy + { + bracket_proxy(BaseInserter& ref, size_type row, size_type col_offset) : ref(ref), row(row), col_offset(col_offset) {} + + proxy_type operator[](size_type col) + { return proxy_type(ref, row, col+col_offset); } + + BaseInserter& ref; + size_type row, col_offset; + }; + + public: + /// To be used in ins[r][c] << value; + bracket_proxy operator[] (size_type row) + { return bracket_proxy(ins, row+row_offset, col_offset); } + + /// To be used in ins(r, c) << value; + proxy_type operator() (size_type row, size_type col) + { return proxy_type(ins, row+row_offset, col+col_offset); } + + // update, modify and operator<< are used from BaseInserter + + private: + BaseInserter ins; + size_type row_offset, col_offset; +}; + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_SHIFTED_INSERTER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/sparse_banded.hpp b/install/MTL/include/boost/numeric/mtl/matrix/sparse_banded.hpp new file mode 100644 index 00000000..94ff3913 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/sparse_banded.hpp @@ -0,0 +1,360 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_SPARSE_BANDED_INCLUDE +#define MTL_MATRIX_SPARSE_BANDED_INCLUDE + +#include <algorithm> +#include <cassert> +#include <ostream> +#include <vector> +#include <boost/type_traits/make_signed.hpp> + +#include <boost/numeric/mtl/matrix/dimension.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/matrix/base_matrix.hpp> +#include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp> +#include <boost/numeric/mtl/matrix/mat_expr.hpp> +#include <boost/numeric/mtl/operation/is_negative.hpp> +#include <boost/numeric/mtl/operation/update.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/maybe.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> + +namespace mtl { namespace mat { + +/// Sparse banded matrix class +template <typename Value, typename Parameters = mat::parameters<> > +class sparse_banded + : public base_matrix<Value, Parameters>, + public const_crtp_base_matrix< sparse_banded<Value, Parameters>, Value, typename Parameters::size_type >, + public crtp_matrix_assign< sparse_banded<Value, Parameters>, Value, typename Parameters::size_type >, + public mat_expr< sparse_banded<Value, Parameters> > +{ + MTL_STATIC_ASSERT((mtl::traits::is_row_major<Parameters>::value), "Only row-major sparse banded matrices supported so far."); + + typedef std::size_t size_t; + typedef base_matrix<Value, Parameters> super; + typedef sparse_banded<Value, Parameters> self; + + public: + typedef Value value_type; + typedef typename Parameters::size_type size_type; + typedef typename boost::make_signed<size_type>::type band_size_type; + typedef crtp_matrix_assign<self, Value, size_type> assign_base; + + /// Construct matrix of dimension \p nr by \p nc + explicit sparse_banded(size_type nr= 0, size_type nc= 0) + : super(non_fixed::dimensions(nr, nc)), data(0), inserting(false) + {} + + /// Copy from other types + template <typename MatrixSrc> + explicit sparse_banded(const MatrixSrc& src) : data(0), inserting(false) + { *this= src; } + + + ~sparse_banded() { delete[] data; } + void check() const { MTL_DEBUG_THROW_IF(inserting, access_during_insertion()); } + void check(size_type MTL_DEBUG_ARG(r), size_type MTL_DEBUG_ARG(c)) const + { + check(); + MTL_DEBUG_THROW_IF(is_negative(r) || r >= this->num_rows() + || is_negative(c) || c >= this->num_cols(), index_out_of_range()); + } + + using assign_base::operator=; + + void make_empty() ///< Delete all entries + { + delete[] data; data= 0; + bands.resize(0); + } + + /// Change dimension to \p r by \p c; deletes all entries + void change_dim(size_type r, size_type c) + { + make_empty(); + super::change_dim(r, c); + } + + /// Offset of entry r,c if in matrix (otherwise offset of next entry) + utilities::maybe<size_type> offset(size_type r, size_type c) const + { + check(r, c); + band_size_type dia= band_size_type(c) - band_size_type(r); + size_type b= find_dia(dia); + return utilities::maybe<size_type>(r * bands.size() + b, size_t(b) < bands.size() && bands[b] == dia); + } + + /// Value of matrix entry + value_type operator()(size_type r, size_type c) const + { + using math::zero; + utilities::maybe<size_type> o= offset(r, c); + return o ? data[o.value()] : zero(value_type()); + } + + /// L-value reference of stored matrix entry + /** To be used with care; in debug mode, exception is thrown if entry is not found **/ + value_type& lvalue(size_type r, size_type c) + { + utilities::maybe<size_type> o= offset(r, c); + MTL_DEBUG_THROW_IF(!o, runtime_error("Entry doesn't exist.")); + return data[o.value()]; + } + + /// Print matrix on \p os + friend std::ostream& operator<<(std::ostream& os, const self& A) + { + const size_type bs= A.bands.size(), nc= num_cols(A), s= bs * num_rows(A); + print_size_max p; + for (size_type i= 0; i < s; i++) + p(A.data[i]); + + for (size_type r= 0; r < num_rows(A); r++) { + os << '['; + size_type b= 0; + while (b < bs && -A.bands[b] > long(r)) b++; + for (size_type c= 0; c < nc; c++) { + os.width(p.max); + if (b == bs || long(c) - long(r) < A.bands[b]) + os << Value(0); + else + os << A.data[r * bs + b++]; + os << (c + 1 == nc ? "]\n" : " "); + } + } + return os; + } + + /// Number of structural non-zeros (i.e. stored entries) which is the the number of bands times rows + size_type nnz() const { return bands.size() * this->num_rows(); } + size_type find_major(size_type offset) const { return offset % bands.size(); } + + friend size_t num_rows(const self& A) { return A.num_rows(); } + friend size_t num_cols(const self& A) { return A.num_cols(); } + + std::vector<band_size_type> const& ref_bands() const { return bands; } ///< Refer bands vector [advanced] + const value_type* ref_data() const { return data; } ///< Refer data pointer [advanced] + + private: + size_type find_dia(band_size_type dia) const + { + size_type i= 0; + while (i < size_type(bands.size()) && dia > bands[i]) i++; + return i; + } + + template <typename, typename, typename> friend struct sparse_banded_inserter; + + std::vector<band_size_type> bands; + value_type* data; + bool inserting; +}; + +/// Inserter for sparse banded matrix +template <typename Value, typename Parameters, typename Updater = mtl::operations::update_store<Value> > +struct sparse_banded_inserter +{ + typedef Value value_type; + typedef typename Parameters::size_type size_type; + typedef sparse_banded<Value, Parameters> matrix_type; + typedef sparse_banded_inserter self; + typedef typename matrix_type::band_size_type band_size_type; + typedef operations::update_proxy<self, size_type> proxy_type; + + private: + struct bracket_proxy + { + bracket_proxy(self& ref, size_type row) : ref(ref), row(row) {} + + proxy_type operator[](size_type col) { return proxy_type(ref, row, col); } + + self& ref; + size_type row; + }; + + void insert_dia(size_type dia_band, band_size_type dia) + { + using std::swap; + // empty vector and entry at the end + diagonals.push_back(std::vector<Value>(num_rows(A), Value(0))); + A.bands.push_back(dia); + + for (size_type i= diagonals.size() - 1; i > dia_band; i--) { + swap(diagonals[i-1], diagonals[i]); + swap(A.bands[i-1], A.bands[i]); + } + } + + public: + /// Construct inserter for matrix \p A; second argument for slot_size ignored + sparse_banded_inserter(matrix_type& A, size_type) : A(A) + { + MTL_THROW_IF(A.inserting, runtime_error("Two inserters on same matrix")); + MTL_THROW_IF(A.data, runtime_error("Inserter does not support modifications yet.")); + A.inserting= true; + } + + ~sparse_banded_inserter() + { + const size_type bs= A.bands.size(); + Value* p= A.data= new Value[A.bands.size() * num_rows(A)]; + for (size_type r= 0; r < num_rows(A); r++) + for (size_type b= 0; b < bs; b++) + *p++= diagonals[b][r]; + assert(p - A.data == long(A.bands.size() * num_rows(A))); + A.inserting= false; + } + + /// Proxy to insert into A[row][col] + bracket_proxy operator[] (size_type row) + { + return bracket_proxy(*this, row); + } + + /// Proxy to insert into A[row][col] + proxy_type operator() (size_type row, size_type col) + { + return proxy_type(*this, row, col); + } + + /// Modify A[row][col] with \p val using \p Modifier + template <typename Modifier> + void modify(size_type row, size_type col, Value val) + { + MTL_DEBUG_THROW_IF(is_negative(row) || row >= num_rows(A) || is_negative(col) || col >= num_cols(A), + index_out_of_range()); + const band_size_type dia= col - row; + const size_type dia_band= A.find_dia(dia); + + if (dia_band == size_type(A.bands.size()) || dia != A.bands[dia_band]) + insert_dia(dia_band, dia); + + Modifier()(diagonals[dia_band][row], val); + } + + /// Modify A[row][col] with \p val using the class' updater + void update(size_type row, size_type col, Value val) + { + using math::zero; + modify<Updater>(row, col, val); + } + + private: + matrix_type& A; + std::vector<std::vector<Value> > diagonals; +}; + + +template <typename Value, typename Parameters> +struct sparse_banded_key +{ + typedef std::size_t size_t; + typedef sparse_banded_key self; + typedef mtl::mat::sparse_banded<Value, Parameters> matrix_type; + + explicit sparse_banded_key(const matrix_type& A, size_t offset) + : A(A), offset(offset) {} + + bool operator== (sparse_banded_key const& other) const { return offset == other.offset; } + bool operator!= (sparse_banded_key const& other) const { return !(*this == other); } + + const matrix_type& A; + size_t offset; +}; + +// Cursor over every element +template <typename Value, typename Parameters> +struct sparse_banded_cursor + : public sparse_banded_key<Value, Parameters> +{ + typedef sparse_banded_key<Value, Parameters> base; + typedef mtl::mat::sparse_banded<Value, Parameters> matrix_type; + typedef sparse_banded_cursor self; + + explicit sparse_banded_cursor(const matrix_type& A, size_t offset) + : base(A, offset) {} + + self& operator++() { ++this->offset; return *this; } + const base& operator* () const { return *this; } +}; + +// ================ +// Free functions +// ================ + +template <typename Value, typename Parameters> +inline std::size_t size(const sparse_banded<Value, Parameters>& matrix) +{ + return std::size_t(matrix.num_cols()) * std::size_t(matrix.num_rows()); +} + +}} // namespace mtl::matrix + +namespace mtl { + using mat::sparse_banded; +} + + +// ================ +// Range generators +// ================ + +namespace mtl { namespace traits { + + // Cursor over all rows + // Supported if row major matrix + template <typename Value, typename Parameters> + struct range_generator<glas::tag::row, sparse_banded<Value, Parameters> > + : detail::all_rows_range_generator<sparse_banded<Value, Parameters>, complexity_classes::linear_cached> + {}; + + template <class Value, class Parameters> + struct range_generator<glas::tag::nz, + detail::sub_matrix_cursor<sparse_banded<Value, Parameters>, glas::tag::row, 2> > + { + typedef typename Parameters::size_type size_type; + typedef detail::sub_matrix_cursor<sparse_banded<Value, Parameters>, glas::tag::row, 2> cursor_type; + typedef complexity_classes::linear_cached complexity; + typedef mtl::mat::sparse_banded_cursor<Value, Parameters> type; + static int const level = 1; + MTL_STATIC_ASSERT((is_row_major<Parameters>::value), "Only row-major sparse banded matrices supported so far."); + + type begin(cursor_type const& cursor) const + { + size_type r= cursor.key, b= 0, bs= cursor.ref.ref_bands().size(); + while (b < bs && -cursor.ref.ref_bands()[b] > long(r)) b++; + return type(cursor.ref, r * bs + b); + } + type end(cursor_type const& cursor) const + { + size_type r= cursor.key, bs= cursor.ref.ref_bands().size(), b= bs, nc= cursor.ref.num_cols(); + while (b > 0 && cursor.ref.ref_bands()[b-1] + long(r) >= long(nc)) b--; + return type(cursor.ref, r * bs + b); + } + + // type lower_bound(cursor_type const& cursor, size_type position) const {} + }; + + + // Cursor over all rows or columns, depending which one is major + template <typename Value, typename Parameters> + struct range_generator<glas::tag::major, sparse_banded<Value, Parameters> > + : range_generator<glas::tag::row, sparse_banded<Value, Parameters> > + {}; + +}} // namespace mtl::traits + +#endif // MTL_MATRIX_SPARSE_BANDED_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/strict_lower.hpp b/install/MTL/include/boost/numeric/mtl/matrix/strict_lower.hpp new file mode 100644 index 00000000..1d00bf94 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/strict_lower.hpp @@ -0,0 +1,46 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_STRICT_LOWER_INCLUDE +#define MTL_MATRIX_STRICT_LOWER_INCLUDE + +namespace mtl { namespace mat { + +namespace traits { + + template <typename Matrix> + struct strict_lower + { + typedef typename traits::bands<Matrix>::type type; + }; +} + +/// Strict lower triangular matrix +template <typename Matrix> +typename traits::strict_lower<Matrix>::type +inline strict_lower(const Matrix& A) +{ + return bands(A, std::numeric_limits<long>::min(), 0); +} + +/// Triangle-lower starting at off-diagonoal \p d (for compatibility with matlib) +template <typename Matrix> +typename traits::strict_lower<Matrix>::type +inline tril(const Matrix& A, long d= 0) +{ + return bands(A, std::numeric_limits<long>::min(), d+1); +} + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_STRICT_LOWER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/strict_upper.hpp b/install/MTL/include/boost/numeric/mtl/matrix/strict_upper.hpp new file mode 100644 index 00000000..b3ae92bc --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/strict_upper.hpp @@ -0,0 +1,48 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_STRICT_UPPER_INCLUDE +#define MTL_MATRIX_STRICT_UPPER_INCLUDE + +#include <boost/numeric/mtl/matrix/bands.hpp> + +namespace mtl { namespace mat { + +namespace traits { + + template <typename Matrix> + struct strict_upper + { + typedef typename bands<Matrix>::type type; + }; +} + +/// Strict upper triangle matrix +template <typename Matrix> +typename traits::strict_upper<Matrix>::type +inline strict_upper(const Matrix& A) +{ + return bands(A, 1, std::numeric_limits<long>::max()); +} + +/// Triangle-upper starting at off-diagonoal \p d (for compatibility with matlib) +template <typename Matrix> +typename traits::strict_upper<Matrix>::type +inline triu(const Matrix& A, long d= 0) +{ + return bands(A, d, std::numeric_limits<long>::max()); +} + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_STRICT_UPPER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/transposed_view.hpp b/install/MTL/include/boost/numeric/mtl/matrix/transposed_view.hpp new file mode 100644 index 00000000..942b6087 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/transposed_view.hpp @@ -0,0 +1,298 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRANSPOSED_VIEW_INCLUDE +#define MTL_TRANSPOSED_VIEW_INCLUDE + +#include <utility> +#include <boost/shared_ptr.hpp> +#include <boost/mpl/if.hpp> +#include <boost/type_traits/is_const.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/type_traits/remove_const.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/transposed_orientation.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/property_map_impl.hpp> +#include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp> +#include <boost/numeric/mtl/operation/sub_matrix.hpp> +#include <boost/numeric/mtl/matrix/mat_expr.hpp> + +namespace mtl { namespace mat { + + +template <class Matrix> +struct transposed_view + : public boost::mpl::if_< + boost::is_const<Matrix> + , const_crtp_base_matrix< const transposed_view<const Matrix>, + typename Matrix::value_type, typename Matrix::size_type > + , crtp_base_matrix< transposed_view<Matrix>, + typename Matrix::value_type, typename Matrix::size_type > + >::type, + public mat::mat_expr< transposed_view<Matrix> > +{ + typedef transposed_view self; + typedef mat_expr< self > expr_base; + typedef Matrix other; + + typedef typename mtl::traits::transposed_orientation<typename Matrix::orientation>::type orientation; + typedef typename Matrix::index_type index_type; + typedef typename Matrix::value_type value_type; + typedef typename Matrix::const_reference const_reference; + typedef typename Matrix::key_type key_type; + typedef typename Matrix::size_type size_type; + typedef typename Matrix::dim_type::transposed_type dim_type; + typedef mat::parameters<orientation, index_type, dim_type> parameters; + + typedef typename boost::mpl::if_<boost::is_const<Matrix>, + const_reference, + value_type& + >::type access_type; + + typedef typename boost::mpl::if_<boost::is_const<Matrix>, + const Matrix&, + Matrix& + >::type ref_type; + typedef const Matrix& const_ref_type; + + + transposed_view (ref_type ref) : ref(ref) {} + + transposed_view (const boost::shared_ptr<Matrix>& p) : my_copy(p), ref(*p) {} + +#ifdef MTL_WITH_CPP11_MOVE + transposed_view (self&& that) : my_copy(std::move(that.my_copy)), ref(that.ref) {} + transposed_view (const self& that) : ref(that.ref) { assert(that.my_copy.use_count() == 0); } +#endif + + const_reference operator() (size_type r, size_type c) const + { return ref(c, r); } + + access_type operator() (size_type r, size_type c) + { return ref(c, r); } + + size_type dim1() const { return ref.dim2(); } + size_type dim2() const { return ref.dim1(); } + + dim_type dimensions() const + { return ref.dimensions().transpose(); } + + size_type begin_row() const { return ref.begin_col(); } + size_type end_row() const { return ref.end_col(); } + size_type begin_col() const { return ref.begin_row(); } + size_type end_col() const { return ref.end_row(); } + size_type nnz() const { return ref.nnz(); } + + friend size_type inline num_rows(const self& A) + { using mtl::mat::num_cols; return num_cols(A.ref); } + friend size_type inline num_cols(const self& A) + { using mtl::mat::num_rows; return num_rows(A.ref); } + protected: + boost::shared_ptr<Matrix> my_copy; + public: + ref_type ref; +}; + +template <class Matrix> +inline std::size_t size(const transposed_view<Matrix>& A) +{ + return num_rows(A.ref) * num_rows(A.ref); +} + +// ========== +// Sub matrix +// ========== + +template <typename Matrix> +struct sub_matrix_t< transposed_view<Matrix> > +{ + typedef transposed_view<Matrix> matrix_type; + typedef typename boost::remove_const<Matrix>::type tmp_type; + + // Transposed of submatrix type + typedef transposed_view<typename sub_matrix_t<tmp_type>::sub_matrix_type> sub_matrix_type; + typedef transposed_view<typename sub_matrix_t<tmp_type>::const_sub_matrix_type> const_sub_matrix_type; + typedef typename matrix_type::size_type size_type; + + sub_matrix_type operator()(matrix_type& A, size_type begin_r, size_type end_r, size_type begin_c, size_type end_c) + { + typedef typename sub_matrix_t<Matrix>::sub_matrix_type ref_sub_type; + typedef boost::shared_ptr<ref_sub_type> pointer_type; + + // Submatrix of referred matrix, colums and rows interchanged + // Create a submatrix, whos address will be kept by transposed_view + pointer_type p(new ref_sub_type(sub_matrix(A.ref, begin_c, end_c, begin_r, end_r))); + return sub_matrix_type(p); + } + + const_sub_matrix_type operator()(matrix_type const& A, size_type begin_r, size_type end_r, + size_type begin_c, size_type end_c) + { + typedef typename sub_matrix_t<Matrix>::const_sub_matrix_type ref_sub_type; + typedef boost::shared_ptr<ref_sub_type> pointer_type; + + // Submatrix of referred matrix, colums and rows interchanged + // Create a submatrix, whos address will be kept by transposed_view + pointer_type p(new ref_sub_type(sub_matrix(A.ref, begin_c, end_c, begin_r, end_r))); + return const_sub_matrix_type(p); + } + +}; + +}} // mtl::matrix + +namespace mtl { namespace traits { + + + namespace detail { + + template <class Matrix, class Ref> + struct transposed_row + { + typedef typename Matrix::key_type key_type; + typedef typename Matrix::size_type size_type; + + transposed_row(mtl::mat::transposed_view<Ref> const& transposed_matrix) + : its_col(transposed_matrix.ref) {} + + size_type operator() (key_type const& key) const + { + return its_col(key); + } + + protected: + typename col<typename boost::remove_const<Matrix>::type>::type its_col; + }; + + + template <class Matrix, class Ref> + struct transposed_col + { + typedef typename Matrix::key_type key_type; + typedef typename Matrix::size_type size_type; + + transposed_col(mtl::mat::transposed_view<Ref> const& transposed_matrix) + : its_row(transposed_matrix.ref) {} + + size_type operator() (key_type const& key) const + { + return its_row(key); + } + + protected: + typename row<typename boost::remove_const<Matrix>::type>::type its_row; + }; + + } // namespace detail + + template <class Matrix> + struct row<mat::transposed_view<Matrix> > + { + typedef detail::transposed_row<Matrix, Matrix> type; + }; + + template <class Matrix> + struct col<mat::transposed_view<Matrix> > + { + typedef detail::transposed_col<Matrix, Matrix> type; + }; + + template <class Matrix> + struct const_value<mtl::mat::transposed_view<Matrix> > + { + typedef mtl::detail::const_value_from_other<mtl::mat::transposed_view<Matrix> > type; + }; + + + template <class Matrix> + struct value<mtl::mat::transposed_view<Matrix> > + { + typedef mtl::detail::value_from_other<mtl::mat::transposed_view<Matrix> > type; + }; + + +// ================ +// Range generators +// ================ + + namespace detail + { + template <class UseTag, class Matrix> + struct range_transposer_impl + { + typedef range_generator<UseTag, typename boost::remove_const<Matrix>::type> generator; + // typedef range_generator<UseTag, Matrix> generator; + typedef typename generator::complexity complexity; + typedef typename generator::type type; + static int const level = generator::level; + type begin(mtl::mat::transposed_view<Matrix> const& m) + { + return generator().begin(m.ref); + } + type end(mtl::mat::transposed_view<Matrix> const& m) + { + return generator().end(m.ref); + } + }; + + // If considered range_generator for Matrix isn't supported, i.e. has infinite complexity + // then define as unsupported for transposed view + // (range_transposer_impl wouldn't compile in this case) + template <class UseTag, class Matrix> + struct range_transposer + : boost::mpl::if_< + boost::is_same<typename range_generator<UseTag, typename boost::remove_const<Matrix>::type>::complexity, + complexity_classes::infinite> + , range_generator<tag::unsupported, Matrix> + , range_transposer_impl<UseTag, Matrix> + >::type {}; + } + + // Row and column cursors are interchanged + template <class Matrix> + struct range_generator<glas::tag::col, mat::transposed_view<Matrix> > + : detail::range_transposer<glas::tag::row, Matrix> + {}; + + template <class Matrix> + struct range_generator<glas::tag::row, mat::transposed_view<Matrix> > + : detail::range_transposer<glas::tag::col, Matrix> + {}; + + + // To traverse the major dimension refer to the Matrix + template <class Matrix> + struct range_generator<tag::major, mat::transposed_view<Matrix> > + : detail::range_transposer<tag::major, Matrix> + {}; + + + // Other cursors still use the same tag, e.g. elements + template <class Tag, class Matrix> + struct range_generator<Tag, mat::transposed_view<Matrix> > + : detail::range_transposer<Tag, Matrix> + {}; + + + +}} // namespace mtl::traits + +namespace mtl { + using mat::transposed_view; +} + +#endif // MTL_TRANSPOSED_VIEW_INCLUDE + + + diff --git a/install/MTL/include/boost/numeric/mtl/matrix/upper.hpp b/install/MTL/include/boost/numeric/mtl/matrix/upper.hpp new file mode 100644 index 00000000..d21b27df --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/upper.hpp @@ -0,0 +1,41 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_UPPER_INCLUDE +#define MTL_MATRIX_UPPER_INCLUDE + +#include <boost/numeric/mtl/matrix/bands.hpp> +#include <limits> + +namespace mtl { namespace mat { + +namespace traits { + + template <typename Matrix> + struct upper + { + typedef typename traits::bands<Matrix>::type type; + }; +} + +/// Upper triangular matrix +template <typename Matrix> +typename traits::upper<Matrix>::type +inline upper(const Matrix& A) +{ + return bands(A, 0, std::numeric_limits<long>::max()); +} + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_UPPER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/matrix/view_ref.hpp b/install/MTL/include/boost/numeric/mtl/matrix/view_ref.hpp new file mode 100644 index 00000000..a448adb4 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/matrix/view_ref.hpp @@ -0,0 +1,55 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_VIEW_REF_INCLUDE +#define MTL_MATRIX_VIEW_REF_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/matrix/map_view.hpp> +#include <boost/numeric/mtl/matrix/transposed_view.hpp> +#include <boost/numeric/mtl/matrix/hermitian_view.hpp> + + +namespace mtl { namespace mat { + +template <typename Matrix> +inline Matrix& view_ref(Matrix& A) +{ return A; } + +template <typename Matrix> +inline const Matrix& view_ref(const Matrix& A) +{ return A; } + +template <typename Matrix> +inline Matrix& view_ref(transposed_view<Matrix>& A) +{ return A.ref; } + +template <typename Matrix> +inline const Matrix& view_ref(transposed_view<const Matrix>& A) +{ return A.ref; } + +template <typename Matrix> +inline const Matrix& view_ref(const transposed_view<Matrix>& A) +{ return A.ref; } + +template <typename Matrix> +inline const Matrix& view_ref(const conj_view<Matrix>& A) +{ return A.ref; } + +template <typename Matrix> +inline const Matrix& view_ref(const hermitian_view<Matrix>& A) +{ return A.const_ref(); } + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_VIEW_REF_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/mtl.hpp b/install/MTL/include/boost/numeric/mtl/mtl.hpp new file mode 100644 index 00000000..35271678 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/mtl.hpp @@ -0,0 +1,20 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MTL_INCLUDE +#define MTL_MTL_INCLUDE + +#include <boost/numeric/mtl/types.hpp> +#include <boost/numeric/mtl/operations.hpp> +#include <boost/numeric/mtl/interfaces.hpp> + +#endif // MTL_MTL_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/mtl_conditional_fwd.hpp b/install/MTL/include/boost/numeric/mtl/mtl_conditional_fwd.hpp new file mode 100644 index 00000000..bbedd2ca --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/mtl_conditional_fwd.hpp @@ -0,0 +1,41 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_MTL_CONDITIONAL_FWD_INCLUDE +#define MTL_MTL_CONDITIONAL_FWD_INCLUDE + +// Forward declarations that need meta-programming (enable_if and alike) + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/is_composable_vector.hpp> +#include <boost/numeric/mtl/utility/is_distributed.hpp> +#include <boost/numeric/mtl/utility/iset.hpp> +#include <boost/numeric/mtl/utility/is_lazy.hpp> +#include <boost/numeric/mtl/utility/is_multi_vector_expr.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/is_static.hpp> +#include <boost/numeric/mtl/utility/is_vector_reduction.hpp> +#include <boost/numeric/mtl/utility/is_what.hpp> + + +namespace mtl { + + namespace vec { + + template <typename Vector> + typename mtl::traits::enable_if_vector<Vector, conj_view<Vector> >::type + inline conj(const Vector& v); + } + +} // namespace mtl + +#endif // MTL_MTL_CONDITIONAL_FWD_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/mtl_fwd.hpp b/install/MTL/include/boost/numeric/mtl/mtl_fwd.hpp new file mode 100644 index 00000000..171b4ef8 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/mtl_fwd.hpp @@ -0,0 +1,450 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MTL_FWD_INCLUDE +#define MTL_MTL_FWD_INCLUDE + +/// Main name space for %Matrix Template Library +namespace mtl { + + template <typename T, typename U, typename Assign> struct lazy_assign; + template <typename VectorOut, typename Matrix, typename VectorIn, typename Assign> struct row_mat_cvec_index_evaluator; + + /// Namespace for tags used for concept-free dispatching + namespace tag { + struct row_major; + struct col_major; + + struct scalar; + struct vector; + struct matrix; + + /// Namespace for constant iterator tags + namespace const_iter {} + + /// Namespace for iterator tags + namespace iter {} + } + using tag::row_major; + using tag::col_major; + + namespace index { + struct c_index; + struct f_index; + } + + /// Namespace for compile-time parameters, e.g. %matrix dimensions + namespace fixed { + template <std::size_t Rows, std::size_t Cols> struct dimensions; + } + + /// Namespace for run-time parameters, e.g. %matrix dimensions + namespace non_fixed { + struct dimensions; + } + + /// Namespace for matrices and views and operations exclusively on matrices + namespace mat { + + template <typename Orientation, typename Index, typename Dimensions, bool OnStack, typename SizeType> struct parameters; + + template <typename Value, typename Parameters> class dense2D; + + template <typename Value, typename Parameters> + typename dense2D<Value, Parameters>::size_type num_cols(const dense2D<Value, Parameters>& matrix); + template <typename Value, typename Parameters> + typename dense2D<Value, Parameters>::size_type num_rows(const dense2D<Value, Parameters>& matrix); + template <typename Value, typename Parameters> + typename dense2D<Value, Parameters>::size_type size(const dense2D<Value, Parameters>& matrix); + + template <typename Value, std::size_t Mask, typename Parameters> class morton_dense; + +#if !defined(_MSC_VER) || _MSC_VER != 1400 // Trouble in MSVC 2005 + template <typename Value, std::size_t Mask, typename Parameters> + typename morton_dense<Value, Mask, Parameters>::size_type num_cols(const morton_dense<Value, Mask, Parameters>& matrix); + template <typename Value, std::size_t Mask, typename Parameters> + typename morton_dense<Value, Mask, Parameters>::size_type num_rows(const morton_dense<Value, Mask, Parameters>& matrix); + template <typename Value, std::size_t Mask, typename Parameters> + typename morton_dense<Value, Mask, Parameters>::size_type size(const morton_dense<Value, Mask, Parameters>& matrix); +#endif + + template <typename Value, typename Parameters> class compressed2D; + + template <typename Value, typename Parameters> + typename compressed2D<Value, Parameters>::size_type num_cols(const compressed2D<Value, Parameters>& matrix); + template <typename Value, typename Parameters> + typename compressed2D<Value, Parameters>::size_type num_rows(const compressed2D<Value, Parameters>& matrix); + template <typename Value, typename Parameters> + // typename compressed2D<Value, Parameters>::size_type + std::size_t + size(const compressed2D<Value, Parameters>& matrix); + + template <typename Value, typename Parameters, typename Updater> struct compressed2D_inserter; + + template <typename T, typename Parameters> class coordinate2D; + template <typename Matrix, typename Updater> struct coordinate2D_inserter; + + template <typename T, typename Parameters> class sparse_banded; + template <typename T, typename Parameters, typename Updater> struct sparse_banded_inserter; + + template <typename Value, typename Parameters> class ell_matrix; + template <typename Value, typename Parameters, typename Updater> struct ell_matrix_inserter; + + template <typename Matrix, typename Updater> struct inserter; + template <typename BaseInserter> class shifted_inserter; + + template <typename Vector> class multi_vector; + template <typename Vector> class multi_vector_range; + template <typename Value> class element; + template <typename Value> class element_structure; + template <typename Functor> class implicit_dense; + template <typename Value> class ones_functor; + template <typename Value> class ones_matrix; + template <typename Value> class hilbert_functor; + template <typename Value> class hilbert_matrix; + template <typename Vector1, typename Vector2> class outer_product_functor; + template <typename Vector1, typename Vector2> class outer_product_matrix; + + template <typename Matrix> struct transposed_view; + + template <typename Matrix> struct mat_expr; + template <typename Matrix> struct dmat_expr; + template <typename Matrix> struct smat_expr; + template <typename M1, typename M2, typename SFunctor> struct mat_mat_op_expr; + template <typename M1, typename M2> struct mat_mat_plus_expr; + template <typename M1, typename M2> struct mv_mv_plus_expr; + template <typename M1, typename M2> struct mat_mat_minus_expr; + template <typename M1, typename M2> struct mv_mv_minus_expr; + template <typename M1, typename M2> struct mat_mat_ele_times_expr; + template <typename M1, typename M2> struct mat_mat_times_expr; + template <typename M1, typename M2> struct mat_mat_asgn_expr; + + template <typename Matrix> struct mat_expr; + template <typename Functor, typename Matrix> struct map_view; + template <typename Scaling, typename Matrix> struct scaled_view; + template <typename Matrix, typename RScaling> struct rscaled_view; // added by Hui Li + template <typename Matrix, typename Divisor> struct divide_by_view; // added by Hui Li + template <typename Matrix> struct conj_view; + template <typename Matrix> struct negate_view; + template <typename Matrix> struct imag_view; + template <typename Matrix> struct real_view; + template <typename Matrix> struct hermitian_view; + template <typename Matrix> struct banded_view; + template <typename Matrix> struct indirect; + + template <typename Matrix> class lu_solver; + + template <typename Matrix> std::size_t size(const banded_view<Matrix>&); + template <class Matrix> std::size_t size(const transposed_view<Matrix>&); + template <typename Functor, typename Matrix> std::size_t size(const map_view<Functor, Matrix>&); + template <class Matrix> std::size_t size(const hermitian_view<Matrix>& ); + } + + //using mat::dense2D; + //using mat::morton_dense; + //using mat::compressed2D; + //using mat::coordinate2D; + //using mat::multi_vector; + //using mat::transposed_view; + + template <typename E1, typename E2> struct mat_cvec_times_expr; + + /// Namespace for vectors and views and %operations exclusively on vectors + namespace vec { + template <typename Vector> struct vec_expr; + template <typename Value, typename Parameters> class dense_vector; + template <typename Value, typename Parameters> class strided_vector_ref; + template <typename Value, typename Parameters> class sparse_vector; + template <typename Functor, typename Vector> struct map_view; + template <typename Vector> struct conj_view; + template <typename Vector> struct real_view; + template <typename Vector> struct imag_view; + template <typename Vector> struct negate_view; + template <typename Scaling, typename Vector> struct scaled_view; + template <typename Vector, typename RScaling> struct rscaled_view; // added by Hui Li + template <typename Vector, typename Divisor> struct divide_by_view; // added by Hui Li + template <class E1, class E2, typename SFunctor> struct vec_vec_op_expr; + template <class E1, class E2, typename SFunctor> struct vec_vec_pmop_expr; + template <class E1, class E2, typename SFunctor> struct vec_vec_aop_expr; + template <class E1, class E2, typename SFunctor> struct vec_vec_ele_prod_expr; + template <class E1, class E2, typename SFunctor> struct vec_scal_aop_expr; + template <class E1, class E2> struct vec_vec_asgn_expr; + template <class E1, class E2> struct vec_vec_plus_asgn_expr; + template <class E1, class E2> struct vec_vec_minus_asgn_expr; + template <class E1, class E2> struct vec_vec_times_asgn_expr; // is this really used??? +// template <class E1, class E2> struct vec_vec_div_asgn_expr; // is this really used??? + template <class E1, class E2> struct vec_scal_times_asgn_expr; + template <class E1, class E2> struct vec_scal_div_asgn_expr; // added by Hui Li + template <class E1, class E2> struct vec_scal_asgn_expr; + template <typename E1, typename E2> struct rvec_mat_times_expr; + + template <typename Vector> struct vec_const_ref_expr; + template <unsigned BSize, typename Vector> class unrolled1; + + template <typename Scalar, typename Vector, typename Functor, typename Assign> struct reduction_index_evaluator; + template <typename Scalar, typename Vector1, typename Vector2, typename ConjOpt, typename Assign> struct dot_index_evaluator; + template <unsigned long Unroll, typename Vector1, typename Vector2, typename ConjOpt> struct dot_class; + + template <typename Vector, typename Functor> struct lazy_reduction; + + template <typename Matrix, typename VectorIn> struct mat_cvec_multiplier; + + template <typename Value, typename Parameters, typename Value2> + inline void fill(dense_vector<Value, Parameters>& vector, const Value2& value); + + template <typename Value, typename Parameters> + typename dense_vector<Value, Parameters>::size_type + inline size(const dense_vector<Value, Parameters>& vector); + + template <typename Value, typename Parameters> + typename dense_vector<Value, Parameters>::size_type + inline num_rows(const dense_vector<Value, Parameters>& vector); + + template <typename Value, typename Parameters> + typename dense_vector<Value, Parameters>::size_type + inline num_cols(const dense_vector<Value, Parameters>& vector); + + template <typename Value, typename Parameters> + std::size_t size(const strided_vector_ref<Value, Parameters>& v); + + template <typename Functor, typename Vector> + std::size_t size(const map_view<Functor, Vector>& v); + + template <typename E1, typename E2, typename SFunctor> + std::size_t size(const vec_vec_op_expr<E1, E2, SFunctor>& v); + + template <typename E1, typename E2, typename SFunctor> + std::size_t size(const vec_vec_aop_expr<E1, E2, SFunctor>& v); + + template <typename E1, typename E2, typename SFunctor> + std::size_t size(const vec_vec_pmop_expr<E1, E2, SFunctor>& v); + + template <typename E1, typename E2, typename SFunctor> + inline std::size_t size(const vec_scal_aop_expr<E1, E2, SFunctor>& v); + + template <unsigned BSize, typename Vector> + inline std::size_t size(const unrolled1<BSize, Vector>& v); + + template <typename E1, typename E2> + std::size_t inline size(const rvec_mat_times_expr<E1, E2>& x); + + template <typename E1, typename E2> + std::size_t inline size(const mat_cvec_times_expr<E1, E2>& x); + + template <typename Matrix, typename VectorIn> + std::size_t size(const mat_cvec_multiplier<Matrix, VectorIn>& m); + + /// Namespace for fixed vector dimension types + namespace fixed { + template <std::size_t Size> struct dimension; + } + /// Namespace for non-fixed vector dimension types, i.e. size dynamically determined at run-time + namespace non_fixed { + struct dimension; + } + + } + + //using dense_vector; + + // Export free vector functions into mtl namespace + // It is also needed to handle STL vectors in MTL + using vec::fill; + using vec::size; + using vec::num_rows; + using vec::num_cols; + + /// Namespace for %operations (if not defined in mtl) + namespace operations { + template <typename T> struct update_store; + } + + + namespace vec { + + template <typename Vector, typename Updater = mtl::operations::update_store<typename Vector::value_type> > struct inserter; + template <typename Vector, typename Size> struct update_proxy; + } + + + + + + /// Namespace for type %traits + namespace traits { + template <typename Value> struct category; + template <typename Value> struct algebraic_category; + + template <typename Collection> struct value; + template <typename Collection> struct const_value; + template <typename Collection> struct row; + template <typename Collection> struct col; + template <class Matrix> struct offset; + + template <class Vector> struct index; + template <typename Tag, typename Collection> struct range_generator; + + template <typename T> struct eval_dense; + + template <typename Matrix> struct transposed_orientation; + + template <typename Collection> struct root; + + // for internal implementations + namespace detail { + // needed collection.hpp (at least) + template <typename Collection, typename Cursor, typename Complexity> struct dense_element_range_generator; + template <typename Matrix, typename Cursor, typename Complexity> struct all_offsets_range_generator; + template <typename Matrix, typename Tag, int Level = 2> struct sub_matrix_cursor; + template <typename Matrix> struct matrix_element_key; + template <typename Matrix, int pos> struct matrix_element_cursor; + template <typename Matrix, typename Complexity, int Level = 2> struct all_rows_range_generator; + template <typename Cursor> struct all_cols_in_row_range_generator; + template <typename Matrix, typename Complexity, int Level = 2> struct all_cols_range_generator; + template <typename Cursor> struct all_rows_in_col_range_generator; + template <typename Collection, typename RangeGenerator> struct referred_range_generator; + } + } + + template <typename Matrix> struct ColumnInMatrix; + template <typename Matrix> struct RowInMatrix; + + template <class Tag, class Collection> typename traits::range_generator<Tag, Collection>::type + begin(Collection const& c); + + template <class Tag, class Collection> typename traits::range_generator<Tag, Collection>::type + end(Collection const& c); + + + /// Namespace for functors with application operator and fully typed parameters + namespace tfunctor { + /// Functor for scaling matrices, vectors and ordinary scalars + template <typename V1, typename V2, typename AlgebraicCategory = tag::scalar> struct scale; + + /// Functor for scaling matrices, vectors and ordinary scalars + template <typename V1, typename V2, typename AlgebraicCategory = tag::scalar> struct rscale; + + /// Functor for scaling matrices, vectors and ordinary scalars + template <typename V1, typename V2, typename AlgebraicCategory = tag::scalar> struct divide_by; + } + + /// Namespace for functors with static function apply and fully typed parameters + namespace sfunctor { + template <typename Value, typename AlgebraicCategory = tag::scalar> struct conj_aux; + template <typename Value> struct conj; + template <typename Value> struct imag; + template <typename Value> struct real; + template <typename Value> struct negate; + template <typename Value1, typename Value2> struct plus; + template <typename Value1, typename Value2> struct minus; + template <typename Value1, typename Value2> struct times; + template <typename Value1, typename Value2> struct divide; + template <typename Value1, typename Value2> struct assign; + template <typename Value1, typename Value2> struct plus_assign; + template <typename Value1, typename Value2> struct minus_assign; + template <typename Value1, typename Value2> struct times_assign; + template <typename Value1, typename Value2> struct divide_assign; + template <typename Value> struct identity; + template <typename Value> struct abs; + template <typename Value> struct sqrt; + template <typename Value> struct square; + template <typename F, typename G> struct compose; + template <typename F, typename G> struct compose_first; + template <typename F, typename G> struct compose_second; + template <typename F, typename G, typename H> struct compose_both; + template <typename F, typename G> struct compose_binary; + } + + // Namespace documentations + + /// Namespace for static assignment functors + namespace assign {} + + /// Namespace for complexity classes + namespace complexity_classes {} + + /// Namespace for %operations (if not defined in mtl) + namespace operations {} + + /// Namespace for recursive operations and types with recursive memory layout + namespace recursion {} + + /// Namespace for %utilities + namespace utility {} + + /// Namespace for implementations using recursators + namespace wrec {} + + namespace mat { + template <typename Matrix, typename ValueType, typename SizeType> struct crtp_matrix_assign; + template <typename Matrix, typename ValueType, typename SizeType> struct const_crtp_matrix_bracket; + template <typename Matrix, typename ValueType, typename SizeType> struct crtp_matrix_bracket; + template <typename Matrix, typename ValueType, typename SizeType> struct const_crtp_base_matrix; + template <typename Matrix, typename ValueType, typename SizeType> struct crtp_base_matrix; + template <typename Matrix> struct const_crtp_matrix_range_bracket; + } + + namespace detail { + template <typename Value, bool OnStack, unsigned Size= 0> struct contiguous_memory_block; + template <typename Matrix, typename Updater> struct trivial_inserter; + template <typename Collection> struct with_format_t; + } + + /// Free function defined for all matrix and vector types + template <typename Collection> void swap(Collection& c1, Collection& c2); + + /// User registration that class has a clone constructor, otherwise use regular copy constructor. + template<typename T> struct is_clonable; + + /// Helper type to define constructors that always copy + struct clone_ctor {}; + + /// Helper type to define constructors that refer to another object instead of copying it (e.g. transposed vectors) + struct refer_ctor {}; + + class irange; + class iset; + class srange; + + template <typename T, typename U> struct fused_expr; + namespace vec { + template <typename T, typename U> struct fused_index_evaluator; + // template <typename T, typename U> size_t size(const fused_index_evaluator<T, U>&); // not needed currently + } + + /// Namespace for I/O operations + namespace io { + class matrix_market_istream; + class matrix_market_ostream; + + template <typename MatrixIStream, typename MatrixOStream> class matrix_file; + typedef matrix_file<matrix_market_istream, matrix_market_ostream> matrix_market; + } + + // Multiplication functors + template <typename Assign, typename Backup> struct gen_cursor_dmat_dmat_mult_t; + template <typename Assign, typename Backup> struct gen_dmat_dmat_mult_t; + template <unsigned long Tiling1, unsigned long Tiling2, typename Assign, typename Backup> struct gen_tiling_dmat_dmat_mult_t; + template <typename Assign, typename Backup> struct gen_tiling_44_dmat_dmat_mult_t; + template <typename Assign, typename Backup> struct gen_tiling_22_dmat_dmat_mult_t; + template <typename BaseMult, typename BaseTest, typename Assign, typename Backup> struct gen_recursive_dmat_dmat_mult_t; + template <typename Assign, typename Backup> struct gen_platform_dmat_dmat_mult_t; + template <typename Assign, typename Backup> struct gen_blas_dmat_dmat_mult_t; + template <std::size_t SizeLimit, typename FunctorSmall, typename FunctorLarge> struct size_switch_dmat_dmat_mult_t; + template <bool IsStatic, typename FunctorStatic, typename FunctorDynamic> struct static_switch_dmat_dmat_mult_t; + template <typename Assign, typename Backup> struct fully_unroll_fixed_size_dmat_dmat_mult_t; + +} // namespace mtl + +#endif // MTL_MTL_FWD_INCLUDE + + diff --git a/install/MTL/include/boost/numeric/mtl/operation/adjoint.hpp b/install/MTL/include/boost/numeric/mtl/operation/adjoint.hpp new file mode 100644 index 00000000..f7ccf7c0 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/adjoint.hpp @@ -0,0 +1,43 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ADJOINT_INCLUDE +#define MTL_ADJOINT_INCLUDE + +#include <boost/numeric/mtl/operation/hermitian.hpp> + +namespace mtl { namespace mat { + +namespace traits { + + template <typename LinOp> + struct adjoint + { + typedef typename mtl::mat::detail::hermitian<LinOp>::result_type type; + type operator()(const LinOp& A) + { + return hermitian(A); + } + }; +} + +/// Adjoint linear operator, typically Hermitian transposed +template <typename LinOp> +typename traits::adjoint<LinOp>::type +inline adjoint(const LinOp& A) +{ + return traits::adjoint<LinOp>()(A); +} + +}} // namespace mtl::matrix + +#endif // MTL_ADJOINT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/adjust_cursor.hpp b/install/MTL/include/boost/numeric/mtl/operation/adjust_cursor.hpp new file mode 100644 index 00000000..127f531b --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/adjust_cursor.hpp @@ -0,0 +1,27 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_DETAIL_ADJUST_CURSOR_INCLUDE +#define MTL_DETAIL_ADJUST_CURSOR_INCLUDE + +namespace mtl { namespace detail { + + template <typename Size, typename Cursor> + void inline adjust_cursor(Size diff, Cursor& c, tag::dense) { c+= diff; } + + template <typename Size, typename Cursor> + void inline adjust_cursor(Size diff, Cursor& c, tag::sparse) {} + + +}} // namespace mtl::detail + +#endif // MTL_DETAIL_ADJUST_CURSOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/assign_each_nonzero.hpp b/install/MTL/include/boost/numeric/mtl/operation/assign_each_nonzero.hpp new file mode 100644 index 00000000..e798625e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/assign_each_nonzero.hpp @@ -0,0 +1,59 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ASSIGN_EACH_NONZERO_INCLUDE +#define MTL_ASSIGN_EACH_NONZERO_INCLUDE + +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + + namespace vec { + + /// Assign the result of \p f(i) to each non-zero i in non-constant vector \p v + template <typename Vector, typename Functor> + inline void assign_each_nonzero(Vector& v, const Functor& f) + { + vampir_trace<3008> tracer; + typedef typename traits::range_generator<tag::iter::nz, Vector>::type iterator; + for (iterator i= begin<tag::iter::nz>(v), iend= end<tag::iter::nz>(v); i != iend; ++i) + *i= f(*i); + } + + } // namespace vector + + namespace mat { + + /// Assign the result of \p f(i) to each non-zero i in non-constant matrix \p A + template <typename Matrix, typename Functor> + inline void assign_each_nonzero(Matrix& m, const Functor& f) + { + vampir_trace<3008> tracer; + typename mtl::traits::value<Matrix>::type value(m); + + typedef typename mtl::traits::range_generator<tag::major, Matrix>::type cursor_type; + typedef typename mtl::traits::range_generator<tag::nz, cursor_type>::type icursor_type; + + for (cursor_type cursor = begin<tag::major>(m), cend = end<tag::major>(m); cursor != cend; ++cursor) + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); + icursor != icend; ++icursor) + value(*icursor, f(value(*icursor))); + } + + } // namespace matrix + +} // namespace mtl + +#endif // MTL_ASSIGN_EACH_NONZERO_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/assign_mode.hpp b/install/MTL/include/boost/numeric/mtl/operation/assign_mode.hpp new file mode 100644 index 00000000..1887f4ef --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/assign_mode.hpp @@ -0,0 +1,210 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ASSIGN_MODE_INCLUDE +#define MTL_ASSIGN_MODE_INCLUDE + +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> + +namespace mtl { namespace assign { + +/// Functor for assigning the result of a calculation (e.g. a sum) to a typically scalar value +struct assign_sum +{ + static const bool init_to_zero= true; + + template <typename T> + static void init(T& v) + { + using math::zero; + v= zero(v); + } + + // Sets x with y when empty or not initialized + template <typename T, typename U> + static void set_empty(T& x, const U& y) + { + x= y; + } + + // The first update sets the value and avoids the zeroing + template <typename T, typename U> + static void first_update(T& x, const U& y) + { + x= y; + } + + template <typename T, typename U> + static void update(T& x, const U& y) + { + x+= y; + } + + // To be used like sfunctor + template <typename T, typename U> + static T& apply(T& x, const U& y) + { + return x= y; + } + +}; + +/// Functor for incrementing a typically scalar value with the result of a calculation (e.g. a sum) +struct plus_sum +{ + static const bool init_to_zero= false; + + template <typename T> + static void init(T&) {} + + // Sets x with y when empty or not initialized + template <typename T, typename U> + static void set_empty(T& x, const U& y) + { + x= y; + } + + template <typename T, typename U> + static void first_update(T& x, const U& y) + { + x+= y; + } + + template <typename T, typename U> + static void update(T& x, const U& y) + { + x+= y; + } + + // To be used like sfunctor + template <typename T, typename U> + static T& apply(T& x, const U& y) + { + return x+= y; + } +}; + + +/// Functor for incrementing a typically scalar value with the result of a calculation (e.g. a sum) +struct minus_sum +{ + static const bool init_to_zero= false; + + template <typename T> + static void init(T&) {} + + // Sets x with y when empty or not initialized + template <typename T, typename U> + static void set_empty(T& x, const U& y) + { + x= -y; + } + + template <typename T, typename U> + static void first_update(T& x, const U& y) + { + x-= y; + } + + template <typename T, typename U> + static void update(T& x, const U& y) + { + x-= y; + } + + // To be used like sfunctor + template <typename T, typename U> + static T& apply(T& x, const U& y) + { + return x-= y; + } +}; + + + +/// Functor for multiplying a typically scalar value with the result of a calculation (e.g. a sum) +struct times_sum +{ + static const bool init_to_zero= false; + + template <typename T> + static void init(T&) {} + + // Sets x with y when empty or not initialized + template <typename T, typename U> + static void set_empty(T& x, const U&) + { + x= T(0); + } + + template <typename T, typename U> + static void first_update(T& x, const U& y) + { + x*= y; + } + + template <typename T, typename U> + static void update(T& x, const U& y) + { + x*= y; + } + + // To be used like sfunctor + template <typename T, typename U> + static T& apply(T& x, const U& y) + { + return x*= y; + } +}; + +/// Functor for dividing a typically scalar value with the result of a calculation (e.g. a sum) +struct divide_sum +{ + static const bool init_to_zero= false; + + template <typename T> + static void init(T&) {} + + // Sets x with y when empty or not initialized + template <typename T, typename U> + static void set_empty(T& x, const U& y) + { + MTL_DEBUG_THROW_IF(y == U(0), division_by_zero()); + x= T(0); + } + + template <typename T, typename U> + static void first_update(T& x, const U& y) + { + MTL_DEBUG_THROW_IF(y == U(0), division_by_zero()); + x/= y; + } + + template <typename T, typename U> + static void update(T& x, const U& y) + { + MTL_DEBUG_THROW_IF(y == U(0), division_by_zero()); + x/= y; + } + + // To be used like sfunctor + template <typename T, typename U> + static T& apply(T& x, const U& y) + { + return x/= y; + } +}; + +}} // namespace mtl::assign + +#endif // MTL_ASSIGN_MODE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/bin_op_expr.hpp b/install/MTL/include/boost/numeric/mtl/operation/bin_op_expr.hpp new file mode 100644 index 00000000..2fac2b37 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/bin_op_expr.hpp @@ -0,0 +1,37 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_BIN_OP_EXPR_INCLUDE +#define MTL_BIN_OP_EXPR_INCLUDE + +namespace mtl { + +/// Minimalistic expression template for binary operation: keeps only references. +template <typename E1, typename E2> +struct bin_op_expr +{ + typedef bin_op_expr self; + + typedef E1 first_argument_type ; + typedef E2 second_argument_type ; + + bin_op_expr( first_argument_type const& v1, second_argument_type const& v2 ) + : first( v1 ), second( v2 ) + {} + + first_argument_type const& first ; + second_argument_type const& second ; +}; + +} // namespace mtl + +#endif // MTL_BIN_OP_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/cholesky.hpp b/install/MTL/include/boost/numeric/mtl/operation/cholesky.hpp new file mode 100644 index 00000000..f632e87a --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/cholesky.hpp @@ -0,0 +1,615 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_CHOLESKY_INCLUDE +#define MTL_CHOLESKY_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/recursion/matrix_recursator.hpp> +#include <boost/numeric/mtl/utility/glas_tag.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/operation/dmat_dmat_mult.hpp> +#include <boost/numeric/mtl/operation/assign_mode.hpp> +#include <boost/numeric/mtl/matrix/transposed_view.hpp> +#include <boost/numeric/mtl/recursion/base_case_cast.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace mat { + +namespace with_bracket { + + // ============================================================================ + // Generic Cholesky factorization and operands for Cholesky on with submatrices + // ============================================================================ + + template < typename Matrix > + void cholesky_base (Matrix & matrix) + { + vampir_trace<5001> tracer; + typedef typename Collection<Matrix>::size_type size_type; + for (size_type k = 0; k < matrix.num_cols(); k++) { + matrix[k][k] = sqrt (matrix[k][k]); + + for (size_type i = k + 1; i < matrix.num_rows(); i++) { + matrix[i][k] /= matrix[k][k]; + typename Collection<Matrix>::value_type d = matrix[i][k]; + + for (size_type j = k + 1; j <= i; j++) + matrix[i][j] -= d * matrix[j][k]; + } + } + } + + + template < typename MatrixSW, typename MatrixNW > + void tri_solve_base(MatrixSW & SW, const MatrixNW & NW) + { + vampir_trace<5002> tracer; + typedef typename Collection<MatrixSW>::size_type size_type; + for (size_type k = 0; k < NW.num_rows (); k++) { + + for (size_type i = 0; i < SW.num_rows (); i++) { + SW[i][k] /= NW[k][k]; + typename MatrixSW::value_type d = SW[i][k]; + + for (size_type j = k + 1; j < SW.num_cols (); j++) + SW[i][j] -= d * NW[j][k]; + } + } + } + + + // Lower(SE) -= SW * SW^T + template < typename MatrixSE, typename MatrixSW > + void tri_schur_base(MatrixSE & SE, const MatrixSW & SW) + { + vampir_trace<5003> tracer; + typedef typename Collection<MatrixSE>::size_type size_type; + for (size_type k = 0; k < SW.num_cols (); k++) + + for (size_type i = 0; i < SE.num_rows (); i++) { + typename MatrixSW::value_type d = SW[i][k]; + for (size_type j = 0; j <= i; j++) + SE[i][j] -= d * SW[j][k]; + } + } + + + template < typename MatrixNE, typename MatrixNW, typename MatrixSW > + void schur_update_base(MatrixNE & NE, const MatrixNW & NW, const MatrixSW & SW) + { + vampir_trace<5004> tracer; + typedef typename Collection<MatrixNE>::size_type size_type; + for (size_type k = 0; k < NW.num_cols (); k++) + for (size_type i = 0; i < NE.num_rows (); i++) { + typename MatrixNW::value_type d = NW[i][k]; + for (size_type j = 0; j < NE.num_cols (); j++) + NE[i][j] -= d * SW[j][k]; + } + } + + + // ====================== + // Corresponding functors + // ====================== + + struct cholesky_base_t + { + template < typename Matrix > + void operator() (Matrix & matrix) + { + cholesky_base(matrix); + } + }; + + struct tri_solve_base_t + { + template < typename MatrixSW, typename MatrixNW > + void operator() (MatrixSW & SW, const MatrixNW & NW) + { + tri_solve_base(SW, NW); + } + }; + + struct tri_schur_base_t + { + template < typename MatrixSE, typename MatrixSW > + void operator() (MatrixSE & SE, const MatrixSW & SW) + { + tri_schur_base(SE, SW); + } + }; + + struct schur_update_base_t + { + template < typename MatrixNE, typename MatrixNW, typename MatrixSW > + void operator() (MatrixNE & NE, const MatrixNW & NW, const MatrixSW & SW) + { + schur_update_base(NE, NW, SW); + } + }; + +} // namespace with_bracket + +#if 0 +namespace with_iterator { + + // ============================================================================ + // Generic Cholesky factorization and operands for Cholesky on with submatrices + // ============================================================================ + // CURRENTLY NOT SUPPORTED -- CAUSES SEGFAULT, e.g. with icc 11.0 in r8536 !!!! + // ============================================================================ + + template < typename Matrix > + void cholesky_base (Matrix& matrix) + { + vampir_trace<5001> tracer; + typedef typename Collection<Matrix>::size_type size_type; + + using namespace glas::tag; using mtl::traits::range_generator; + typedef tag::iter::all all_it; + + typedef typename Collection<Matrix>::value_type value_type; + typedef typename range_generator<col, Matrix>::type cur_type; + typedef typename range_generator<all_it, cur_type>::type iter_type; + + typedef typename range_generator<row, Matrix>::type rcur_type; + typedef typename range_generator<all_it, rcur_type>::type riter_type; + + size_type k= 0; + for (cur_type kb= begin<col>(matrix), kend= end<col>(matrix); kb != kend; ++kb, ++k) { + + iter_type ib= begin<all_it>(kb), iend= end<all_it>(kb); + ib+= k; // points now to matrix[k][k] + + value_type root= sqrt (*ib); + *ib= root; + + ++ib; // points now to matrix[k+1][k] + rcur_type rb= begin<row>(matrix); rb+= k+1; // to row k+1 + for (size_type i= k + 1; ib != iend; ++ib, ++rb, ++i) { + *ib = *ib / root; + typename Collection<Matrix>::value_type d = *ib; + riter_type it1= begin<all_it>(rb); it1+= k+1; // matrix[i][k+1] + riter_type it1end= begin<all_it>(rb); it1end+= i+1; // matrix[i][i+1] + iter_type it2= begin<all_it>(kb); it2+= k+1; // matrix[k+1][k] + for (; it1 != it1end; ++it1, ++it2) + *it1 = *it1 - d * *it2; + } + } + } + + + template < typename MatrixSW, typename MatrixNW > + void tri_solve_base(MatrixSW & SW, const MatrixNW & NW) + { + vampir_trace<5002> tracer; + typedef typename Collection<MatrixSW>::size_type size_type; + + using namespace glas::tag; using mtl::traits::range_generator; + typedef tag::iter::all all_it; + typedef tag::const_iter::all all_cit; + + typedef typename range_generator<col, MatrixNW>::type ccur_type; + typedef typename range_generator<all_cit, ccur_type>::type citer_type; + + typedef typename range_generator<row, MatrixSW>::type rcur_type; + typedef typename range_generator<all_it, rcur_type>::type riter_type; + + for (size_type k = 0; k < NW.num_rows (); k++) + for (size_type i = 0; i < SW.num_rows (); i++) { + + typename MatrixSW::value_type d = SW[i][k] /= NW[k][k]; + + rcur_type sw_i= begin<row>(SW); sw_i+= i; // row i + riter_type it1= begin<all_it>(sw_i); it1+= k+1; // SW[i][k+1] + riter_type it1end= end<all_it>(sw_i); + + ccur_type nw_k= begin<col>(NW); nw_k+= k; // column k + citer_type it2= begin<all_cit>(nw_k); it2+= k+1; // NW[k+1][k] + + for(; it1 != it1end; ++it1, ++it2) + *it1 = *it1 - d * *it2; + } + } + + + // Lower(SE) -= SW * SW^T + template < typename MatrixSE, typename MatrixSW > + void tri_schur_base(MatrixSE & SE, const MatrixSW & SW) + { + vampir_trace<5003> tracer; + typedef typename Collection<MatrixSE>::size_type size_type; + + using namespace glas::tag; using mtl::traits::range_generator; + typedef tag::iter::all all_it; + typedef tag::const_iter::all all_cit; + + typedef typename range_generator<col, MatrixSW>::type ccur_type; + typedef typename range_generator<all_cit, ccur_type>::type citer_type; + + typedef typename range_generator<row, MatrixSE>::type rcur_type; + typedef typename range_generator<all_it, rcur_type>::type riter_type; + + for (size_type k = 0; k < SW.num_cols (); k++) + for (size_type i = 0; i < SE.num_rows (); i++) { + typename MatrixSW::value_type d = SW[i][k]; + + rcur_type se_i= begin<row>(SE); se_i+= i; // row i + riter_type it1= begin<all_it>(se_i); // SE[i][0] + riter_type it1end= begin<all_it>(se_i); it1end+= i+1; // SE[i][i+i] + + ccur_type sw_k= begin<col>(SW); sw_k+= k; // column k + citer_type it2= begin<all_cit>(sw_k); // SW[0][k] + + for(; it1 != it1end; ++it1, ++it2) + *it1 = *it1 - d * *it2; + } + } + + + template < typename MatrixNE, typename MatrixNW, typename MatrixSW > + void schur_update_base(MatrixNE & NE, const MatrixNW & NW, const MatrixSW & SW) + { + vampir_trace<5004> tracer; + typedef typename Collection<MatrixNE>::size_type size_type; + + using namespace glas::tag; using mtl::traits::range_generator; + typedef tag::iter::all all_it; + typedef tag::const_iter::all all_cit; + + typedef typename range_generator<col, MatrixSW>::type ccur_type; + typedef typename range_generator<all_cit, ccur_type>::type citer_type; + + typedef typename range_generator<row, MatrixNE>::type rcur_type; + typedef typename range_generator<all_it, rcur_type>::type riter_type; + + for (size_type k = 0; k < NW.num_cols (); k++) + for (size_type i = 0; i < NE.num_rows (); i++) { + typename MatrixNW::value_type d = NW[i][k]; +#if 0 + rcur_type ne_i= begin<row>(NE); ne_i+= i; // row i + riter_type it1= begin<all_it>(ne_i); // NE[i][0] + riter_type it1end= end<all_it>(ne_i); // NE[i][num_col] + + ccur_type sw_k= begin<col>(SW); sw_k+= k; // column k + citer_type it2= begin<all_cit>(sw_k); // SW[0][k] +#endif + for (size_type j = 0; j < NE.num_cols (); j++) + NE[i][j] -= d * SW[j][k]; + } + } + + + // ====================== + // Corresponding functors + // ====================== + + struct cholesky_base_t + { + template < typename Matrix > + void operator() (Matrix & matrix) + { + cholesky_base(matrix); + } + }; + + struct tri_solve_base_t + { + template < typename MatrixSW, typename MatrixNW > + void operator() (MatrixSW & SW, const MatrixNW & NW) + { + tri_solve_base(SW, NW); + } + }; + + struct tri_schur_base_t + { + template < typename MatrixSE, typename MatrixSW > + void operator() (MatrixSE & SE, const MatrixSW & SW) + { + tri_schur_base(SE, SW); + } + }; + + struct schur_update_base_t + { + template < typename MatrixNE, typename MatrixNW, typename MatrixSW > + void operator() (MatrixNE & NE, const MatrixNW & NW, const MatrixSW & SW) + { + schur_update_base(NE, NW, SW); + } + }; + +} // namespace with_iterator +#endif + + +// ================================== +// Functor types for Cholesky visitor +// ================================== + + +template <typename BaseTest, typename CholeskyBase, typename TriSolveBase, typename TriSchur, typename SchurUpdate> +struct recursive_cholesky_visitor_t +{ + typedef BaseTest base_test; + + template < typename Recursator > + bool is_base(const Recursator& recursator) const + { + return base_test()(recursator); + } + + template < typename Matrix > + void cholesky_base(Matrix & matrix) const + { + CholeskyBase()(matrix); + } + + template < typename MatrixSW, typename MatrixNW > + void tri_solve_base(MatrixSW & SW, const MatrixNW & NW) const + { + TriSolveBase()(SW, NW); + } + + template < typename MatrixSE, typename MatrixSW > + void tri_schur_base(MatrixSE & SE, const MatrixSW & SW) const + { + TriSchur()(SE, SW); + } + + template < typename MatrixNE, typename MatrixNW, typename MatrixSW > + void schur_update_base(MatrixNE & NE, const MatrixNW & NW, const MatrixSW & SW) const + { + SchurUpdate()(NE, NW, SW); + } +}; + + +namespace detail { + + // Compute schur update with external multiplication; must have Assign == minus_mult_assign_t !!! + template <typename MatrixMult> + struct mult_schur_update_t + { + template < typename MatrixNE, typename MatrixNW, typename MatrixSW > + void operator()(MatrixNE & NE, const MatrixNW & NW, const MatrixSW & SW) + { + transposed_view<MatrixSW> trans_sw(const_cast<MatrixSW&>(SW)); + MatrixMult()(NW, trans_sw, NE); + } + }; + +} // detail + + +namespace with_bracket { + typedef recursive_cholesky_visitor_t<recursion::bound_test_static<64>, cholesky_base_t, tri_solve_base_t, + tri_schur_base_t, schur_update_base_t > + recursive_cholesky_base_visitor_t; +} + +#if 0 +namespace with_iterator { + typedef recursive_cholesky_visitor_t<recursion::bound_test_static<64>, + cholesky_base_t, tri_solve_base_t, tri_schur_base_t, schur_update_base_t> + recursive_cholesky_base_visitor_t; +} +#endif + +typedef with_bracket::recursive_cholesky_base_visitor_t recursive_cholesky_default_visitor_t; + + + + + + +namespace with_recursator { + + template <typename Recursator, typename Visitor> + void schur_update(Recursator E, Recursator W, Recursator N, Visitor vis) + { + vampir_trace<5005> tracer; + using namespace recursion; + + if (E.is_empty() || W.is_empty() || N.is_empty()) + return; + + if (vis.is_base(E)) { + typedef typename Visitor::base_test base_test; + typedef typename base_case_matrix<typename Recursator::matrix_type, base_test>::type matrix_type; + + matrix_type base_E(base_case_cast<base_test>(E.get_value())), + base_W(base_case_cast<base_test>(W.get_value())), + base_N(base_case_cast<base_test>(N.get_value())); + vis.schur_update_base(base_E, base_W, base_N); + } else{ + schur_update( E.north_east(),W.north_west() ,N.south_west() , vis); + schur_update( E.north_east(), W.north_east(), N.south_east(), vis); + + schur_update(E.north_west() , W.north_east(), N.north_east(), vis); + schur_update(E.north_west() ,W.north_west() ,N.north_west() , vis); + + schur_update(E.south_west() ,W.south_west() ,N.north_west() , vis); + schur_update(E.south_west() , W.south_east(), N.north_east(), vis); + + schur_update( E.south_east(), W.south_east(), N.south_east(), vis); + schur_update( E.south_east(),W.south_west() ,N.south_west() , vis); + } + } + + + template <typename Recursator, typename Visitor> + void tri_solve(Recursator S, Recursator N, Visitor vis) + { + using namespace recursion; + vampir_trace<5006> tracer; + + if (S.is_empty()) + return; + + if (vis.is_base(S)) { + typedef typename Visitor::base_test base_test; + typedef typename base_case_matrix<typename Recursator::matrix_type, base_test>::type matrix_type; + + matrix_type base_S(base_case_cast<base_test>(S.get_value())), + base_N(base_case_cast<base_test>(N.get_value())); + + vis.tri_solve_base(base_S, base_N); + } else{ + + tri_solve(S.north_west() ,N.north_west(), vis); + schur_update( S.north_east(),S.north_west() ,N.south_west(), vis); + tri_solve( S.north_east(), N.south_east(), vis); + tri_solve(S.south_west() ,N.north_west() , vis); + schur_update( S.south_east(),S.south_west() ,N.south_west(), vis); + tri_solve( S.south_east(), N.south_east(), vis); + } + } + + + template <typename Recursator, typename Visitor> + void tri_schur(Recursator E, Recursator W, Visitor vis) + { + using namespace recursion; + vampir_trace<5007> tracer; + + if (E.is_empty() || W.is_empty()) + return; + + if (vis.is_base(W)) { + typedef typename Visitor::base_test base_test; + typedef typename base_case_matrix<typename Recursator::matrix_type, base_test>::type matrix_type; + + matrix_type base_E(base_case_cast<base_test>(E.get_value())), + base_W(base_case_cast<base_test>(W.get_value())); + vis.tri_schur_base(base_E, base_W); + } else{ + + schur_update(E.south_west(), W.south_west(), W.north_west(), vis); + schur_update(E.south_west(), W.south_east(), W.north_east(), vis); + tri_schur( E.south_east() , W.south_east(), vis); + tri_schur( E.south_east() ,W.south_west() , vis); + tri_schur( E.north_west(), W.north_east(), vis); + tri_schur( E.north_west(),W.north_west() , vis); + } + } + + + template <typename Recursator, typename Visitor> + void cholesky(Recursator recursator, Visitor vis) + { + using namespace recursion; + vampir_trace<5008> tracer; + + if (recursator.is_empty()) + return; + + if (vis.is_base (recursator)){ + typedef typename Visitor::base_test base_test; + typedef typename base_case_matrix<typename Recursator::matrix_type, base_test>::type matrix_type; + + matrix_type base_matrix(base_case_cast<base_test>(recursator.get_value())); + vis.cholesky_base (base_matrix); + } else { + cholesky(recursator.north_west(), vis); + tri_solve( recursator.south_west(), recursator.north_west(), vis); + tri_schur( recursator.south_east(), recursator.south_west(), vis); + cholesky( recursator.south_east(), vis); + } + } + +} // namespace with_recursator + + + +template <typename Backup= with_bracket::cholesky_base_t> +struct recursive_cholesky_t +{ + template <typename Matrix> + void operator()(Matrix& matrix) + { + (*this)(matrix, recursive_cholesky_default_visitor_t()); + } + + template <typename Matrix, typename Visitor> + void operator()(Matrix& matrix, Visitor vis) + { + apply(matrix, vis, typename mtl::traits::category<Matrix>::type()); + } + +private: + // If the matrix is not sub-divisible then take backup function + template <typename Matrix, typename Visitor> + void apply(Matrix& matrix, Visitor, tag::universe) + { + Backup()(matrix); + } + + // Only if matrix is sub-divisible, otherwise backup + template <typename Matrix, typename Visitor> + void apply(Matrix& matrix, Visitor vis, tag::qsub_divisible) + { + mat::recursator<Matrix> recursator(matrix); + with_recursator::cholesky(recursator, vis); + } +}; + + +template <typename Matrix, typename Visitor> +inline void recursive_cholesky(Matrix& matrix, Visitor vis) +{ + recursive_cholesky_t<>()(matrix, vis); +} + +template <typename Matrix> +inline void recursive_cholesky(Matrix& matrix) +{ + recursive_cholesky(matrix, recursive_cholesky_default_visitor_t()); +} + + + + + +template <typename Matrix> +void fill_matrix_for_cholesky(Matrix& matrix) +{ + vampir_trace<5008> tracer; + typedef typename Collection<Matrix>::size_type size_type; + typedef typename Collection<Matrix>::value_type value_type; + + value_type x= 1.0; + for (size_type i= 0; i < num_rows(matrix); i++) + for (size_type j= 0; j <= i; j++) + if (i != j) { + matrix[i][j]= x; matrix[j][i]= x; + x+= 1.0; + } + + for (size_type i= 0; i < num_rows(matrix); i++) { + value_type rowsum= 0.0; + for (size_type j=0; j<matrix.num_cols(); j++) + if (i != j) + rowsum += matrix[i][j]; + matrix[i][i]= rowsum * 2; + } +} + + +}} // namespace mtl::matrix + + + + +#endif // MTL_CHOLESKY_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/clone.hpp b/install/MTL/include/boost/numeric/mtl/operation/clone.hpp new file mode 100644 index 00000000..aaa6a1ad --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/clone.hpp @@ -0,0 +1,68 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_CLONE_INCLUDE +#define MTL_CLONE_INCLUDE + +#include <boost/utility/enable_if.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { + +template<typename T> +struct is_clonable : boost::mpl::false_ +{ }; + +/// Move-semantics-related anti-dot: always copy in constructor. +/** Some collections have referring semantics in copy constructors, e.g. sub-matrices. + That means + \code + Matrix B= sub_matrix(A, ...); + \endcode + creates a sub-matrix of A in B. As a consequence, changes in B modify A and vice versa + (unless it's outside the sub-matrix). + In contrast, clone forces the copy semantics + \code + Matrix B= clone(sub_matrix(A, ...)); + \endcode + B now contains the values of A's sub-matrix but is an independent matrix. + Modifications to either A or B have no effect to each other. + Requires that type T is declared clonable in terms of + \code + is_clonable<T> : boost::mpl::true_ {}; + \endcode +**/ +template <typename T> +typename boost::enable_if<is_clonable<T>, T>::type +clone(const T& x) +{ + vampir_trace<3004> tracer; + // std::cout << "Cloning clone function.\n"; + return T(x, clone_ctor()); +} + + +template <typename T> +typename boost::disable_if<is_clonable<T>, T>::type +clone(const T& x) +{ + // std::cout << "Not cloning clone function.\n"; + return x; +} + + +} // namespace mtl + +#endif // MTL_CLONE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/column_in_matrix.hpp b/install/MTL/include/boost/numeric/mtl/operation/column_in_matrix.hpp new file mode 100644 index 00000000..5fec58ed --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/column_in_matrix.hpp @@ -0,0 +1,97 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_COLUMN_IN_MATRIX_INCLUDE +#define MTL_COLUMN_IN_MATRIX_INCLUDE + +#include <boost/mpl/if.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> + +namespace mtl { + + +/// Type of column in matrix as vector if accessible +template <typename Matrix> +struct ColumnInMatrix +{ + static const bool exists= false; +}; + +template <typename Value, typename Parameters> +struct ColumnInMatrix<mtl::mat::dense2D<Value, Parameters> > +{ + typedef mtl::mat::dense2D<Value, Parameters> ref_type; + typedef typename ref_type::size_type size_type; + typedef typename ref_type::value_type value_type; + + static const bool aligned= !boost::is_same<typename Parameters::orientation, row_major>::value; + static const bool exists= true; + + typedef typename boost::mpl::if_c< + aligned + , vec::dense_vector<Value, vec::parameters<> > + , vec::strided_vector_ref<Value, vec::parameters<> > + >::type type; + + static inline type apply(ref_type& A, const irange& row_range, size_type col) + { + return dispatch<type, ref_type>(A, row_range, col, boost::mpl::bool_<aligned>()); + } + + template <typename Ref> + static inline size_type vector_size(const Ref& A, const irange& row_range) + { + using std::min; + size_type finish= min(row_range.finish(), num_rows(A)); + return row_range.start() < finish ? finish - row_range.start() : 0; + } + + template <typename Return, typename Ref> + static inline Return dispatch(Ref& A, const irange& row_range, size_type col, boost::mpl::true_) + { + return Return(vector_size(A, row_range), const_cast<value_type*>(&A[row_range.start()][col])); // TODO make work without const cast + } + + template <typename Return, typename Ref> + static inline Return dispatch(Ref& A, const irange& row_range, size_type col, boost::mpl::false_) + { + return Return(vector_size(A, row_range), &A[row_range.start()][col], num_cols(A)); + } +}; + +template <typename Value, typename Parameters> +struct ColumnInMatrix<const mtl::mat::dense2D<Value, Parameters> > +{ + typedef mtl::mat::dense2D<Value, Parameters> const ref_type; + typedef mtl::mat::dense2D<Value, Parameters> ref2_type; + typedef typename ref2_type::size_type size_type; + + static const bool aligned= !boost::is_same<typename Parameters::orientation, row_major>::value; + static const bool exists= true; + + typedef typename boost::mpl::if_c< + aligned + , vec::dense_vector<Value, vec::parameters<> > // TODO needs constification !!! + , vec::strided_vector_ref<const Value, vec::parameters<> > + >::type type; + + static inline type apply(ref_type& A, const irange& row_range, size_type col) + { + return ColumnInMatrix<ref2_type>::template dispatch<type, ref_type>(A, row_range, col, boost::mpl::bool_<aligned>()); + } +}; + +} // namespace mtl + +#endif // MTL_COLUMN_IN_MATRIX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/compute_factors.hpp b/install/MTL/include/boost/numeric/mtl/operation/compute_factors.hpp new file mode 100644 index 00000000..fa46b1d1 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/compute_factors.hpp @@ -0,0 +1,92 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_COMPUTE_FACTORS_INCLUDE +#define MTL_COMPUTE_FACTORS_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace operation { + +// Default is to just refer to the expression +template <typename Result, typename Expr> +struct compute_one_factor +{ + typedef const Expr& type; + typedef const Expr& const_reference; + + compute_one_factor(type src) : value(src) {} + + type value; +}; + +template <typename Result, typename E1, typename E2> +struct compute_one_factor<Result, mat::mat_mat_times_expr<E1, E2> > +{ + typedef Result type; + typedef const Result& const_reference; + + compute_one_factor(const mat::mat_mat_times_expr<E1, E2>& src) + : value(src.first * src.second) {} + + type value; +}; + +template <typename Result, typename E1, typename E2> +struct compute_one_factor<Result, mat::mat_mat_ele_times_expr<E1, E2> > +{ + typedef Result type; + typedef const Result& const_reference; + + compute_one_factor(const mat::mat_mat_ele_times_expr<E1, E2>& src) + : value(ele_prod(src.first, src.second)) {} + + type value; +}; + + +// Only defined for mat::mat_mat_times_expr and mat::mat_mat_ele_times_expr +template <typename Result, typename Expr> +struct compute_factors {}; + +template <typename Result, typename E1, typename E2> +struct compute_factors<Result, mat::mat_mat_times_expr<E1, E2> > +{ + compute_factors(const mat::mat_mat_times_expr<E1, E2>& src) + : first_factor(src.first), second_factor(src.second), + first(first_factor.value), second(second_factor.value) + {} + + compute_one_factor<Result, E1> first_factor; + compute_one_factor<Result, E2> second_factor; + + typename compute_one_factor<Result, E1>::const_reference first; + typename compute_one_factor<Result, E2>::const_reference second; +}; + +// First factor is handled implicitly in the evaluation +template <typename Result, typename E1, typename E2> +struct compute_factors<Result, mat::mat_mat_ele_times_expr<E1, E2> > +{ + compute_factors(const mat::mat_mat_ele_times_expr<E1, E2>& src) + : first(src.first), second_factor(src.second), + second(second_factor.value) + {} + + const E1& first; + compute_one_factor<Result, E2> second_factor; + typename compute_one_factor<Result, E2>::const_reference second; +}; + +}} // namespace mtl::operation + +#endif // MTL_COMPUTE_FACTORS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/compute_summand.hpp b/install/MTL/include/boost/numeric/mtl/operation/compute_summand.hpp new file mode 100644 index 00000000..f0b8d06f --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/compute_summand.hpp @@ -0,0 +1,82 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL__OPERATION_COMPUTE_SUMMAND_INCLUDE +#define MTL__OPERATION_COMPUTE_SUMMAND_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/copy_expression_const_ref_container.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace operation { + +/// Compute a summand in an expression +/** For instance matrix vector products are transformed into mult function calls + when assigned to a column vector. Adding such a vector to other vector expressions + requires to compute (evaluate) the summand first and then add the resulting + vector. The current implementation assumes that the result of the operation + can be represented by the multiplied column vector. This is for instance wrong + when the matrix is complex and the vector real. To handle this is signifantly + more complicated and is planned for the future. +**/ +template <typename Expr> +struct compute_summand +{ + typedef Expr type; + compute_summand(const Expr& expr) : value(expr) {} + // value is a const& if Expr is a true vector and a copy if it is an expression + typename mtl::traits::copy_expression_const_ref_container<Expr>::type value; +}; + + +/// Specialization for matrix vector products +template <typename Matrix, typename CVector> +struct compute_summand< mat_cvec_times_expr<Matrix, CVector> > +{ + typedef CVector type; + + compute_summand(const mat_cvec_times_expr<Matrix, CVector>& expr) + : value(num_rows(expr.first)) +#ifndef NDEBUG // might be helpful, e.g. for generating AST + , first(expr.first), second(expr.second) +#endif + { + vampir_trace<3005> tracer; + value= expr.first * expr.second; + } + + CVector value; +#ifndef NDEBUG + const Matrix& first; + const CVector& second; +#endif +}; + +/// Specialization for matrix vector products +template <typename Matrix, typename CVector> +struct compute_summand< vec::mat_cvec_multiplier<Matrix, CVector> > +{ + typedef CVector type; + + compute_summand(const vec::mat_cvec_multiplier<Matrix, CVector>& expr) + : value(num_rows(expr.A)) + { + vampir_trace<3005> tracer; + expr.assign_to(value); + } + + CVector value; +}; + +}} // namespace mtl::operation + +#endif // MTL__OPERATION_COMPUTE_SUMMAND_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/conj.hpp b/install/MTL/include/boost/numeric/mtl/operation/conj.hpp new file mode 100644 index 00000000..0e2437ce --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/conj.hpp @@ -0,0 +1,146 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_CONJ_INCLUDE +#define MTL_CONJ_INCLUDE + +#include <complex> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/algebraic_category.hpp> +#include <boost/numeric/mtl/utility/is_what.hpp> +#include <boost/numeric/mtl/utility/view_code.hpp> +#include <boost/numeric/mtl/utility/viewed_collection.hpp> +#include <boost/numeric/mtl/utility/compose_view.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/matrix/view_ref.hpp> + +namespace mtl { + +namespace sfunctor { + + template <typename Value, typename AlgebraicCategory> + struct conj_aux + { + typedef Value result_type; + + static inline result_type apply(const Value& v) + { + return v; + } + + result_type operator() (const Value& v) const + { + return v; + } + }; + + + template <typename Value, typename AlgebraicCategory> + struct conj_aux<std::complex<Value>, AlgebraicCategory> + { + typedef std::complex<Value> result_type; + + static inline result_type apply(const std::complex<Value>& v) + { + return std::conj(v); + } + + result_type operator() (const std::complex<Value>& v) const + { + return std::conj(v); + } + }; + + // Only declarations here, definitions in mat::map_view (map_view) + template <typename Matrix> + struct conj_aux<Matrix, tag::matrix>; + + template <typename Vector> + struct conj_aux<Vector, tag::vector>; + + // Short cut for result type + template <typename Value> + struct conj + : public conj_aux<Value, typename mtl::traits::algebraic_category<Value>::type> + {}; + +} // namespace sfunctor + + namespace vec { + + /// Conjugate of an vector + template <typename Vector> + typename mtl::traits::enable_if_vector<Vector, conj_view<Vector> >::type + inline conj(const Vector& v) + { + return conj_view<Vector>(v); + } + } + + namespace mat { + + namespace detail { + + template <typename Matrix> + struct conj_trait + { + static const unsigned code= mtl::traits::view_toggle_conj<mtl::traits::view_code<Matrix> >::value; + typedef typename mtl::traits::compose_view<code, typename mtl::traits::viewed_collection<Matrix>::type>::type type; + + static inline type apply(const Matrix& A) + { + return type(view_ref(A)); + } + }; + + } + + /// Conjugate of a matrix + template <typename Matrix> + typename mtl::traits::lazy_enable_if_matrix<Matrix, detail::conj_trait<Matrix> >::type + inline conj(const Matrix& A) + { + return detail::conj_trait<Matrix>::apply(A); + } + } + + namespace scalar { + + // Only scalar values remain here + template <typename Value> + typename mtl::traits::enable_if_scalar< + Value + , typename sfunctor::conj<Value>::result_type + >::type + inline conj(const Value& v) + { + return mtl::sfunctor::conj<Value>::apply(v); + } + + float inline conj(float v) { return v; } + double inline conj(double v) { return v; } + long double inline conj(long double v) { return v; } + } + + /// Conjugate of vector, matrix, or scalar + using vec::conj; + using mat::conj; + using scalar::conj; + // using std::conj; + +} // namespace mtl + +#endif // MTL_CONJ_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/copy.hpp b/install/MTL/include/boost/numeric/mtl/operation/copy.hpp new file mode 100644 index 00000000..a4dc7c8c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/copy.hpp @@ -0,0 +1,299 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_COPY_INCLUDE +#define MTL_COPY_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/detail/index.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/flatcat.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/utility/updater_to_assigner.hpp> +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/mtl/operation/set_to_zero.hpp> +#include <boost/numeric/mtl/operation/update.hpp> +#include <boost/numeric/mtl/operation/print.hpp> +#include <boost/numeric/mtl/operation/crop.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +#include <boost/type_traits/is_same.hpp> +#include <boost/utility/enable_if.hpp> +#include <iostream> +#include <limits> + +namespace mtl { + + namespace detail { + + // Set Destination matrix to zero when source is sparse + // (otherwise everything is overwritten anyway) + template <typename MatrixDest> + inline void zero_with_sparse_src(MatrixDest& dest, tag::flat<tag::sparse>) + { + set_to_zero(dest); + } + + template <typename MatrixDest> + inline void zero_with_sparse_src(MatrixDest&, tag::universe) {} + + // Adapt inserter size to operation + template <typename Updater> struct copy_inserter_size {}; + + // Specialization for store + template <typename Value> + struct copy_inserter_size< operations::update_store<Value> > + { + template <typename MatrixSrc, typename MatrixDest> + static inline int apply(const MatrixSrc& src, const MatrixDest& dest) + { + // std::cout << "nnz = " << src.nnz() << ", dim1 = " << dest.dim1() << "\n"; + return int(src.nnz() * 1.2 / dest.dim1()); + } + }; + + struct sum_of_sizes + { + template <typename MatrixSrc, typename MatrixDest> + static inline int apply(const MatrixSrc& src, const MatrixDest& dest) + { return int((src.nnz() + dest.nnz()) * 1.2 / dest.dim1()); } + }; + + // Specialization for plus and minus + template <typename Value> struct copy_inserter_size< operations::update_plus<Value> > : sum_of_sizes {}; + template <typename Value> struct copy_inserter_size< operations::update_minus<Value> > : sum_of_sizes {}; + + } // namespace detail + + + template <typename Updater, typename MatrixSrc, typename MatrixDest> + inline void gen_matrix_copy(const MatrixSrc& src, MatrixDest& dest, bool with_reset) + { + vampir_trace<3002> tracer; + MTL_THROW_IF(num_rows(src) != num_rows(dest) || num_cols(src) != num_cols(dest), incompatible_size()); + + if (with_reset) + detail::zero_with_sparse_src(dest, traits::sparsity_flatcat<MatrixSrc>()); + + typename traits::row<MatrixSrc>::type row(src); + typename traits::col<MatrixSrc>::type col(src); + typename traits::const_value<MatrixSrc>::type value(src); + typedef typename traits::range_generator<tag::major, MatrixSrc>::type cursor_type; + + // std::cout << "Slot size is " << detail::copy_inserter_size<Updater>::apply(src, dest) << "\n"; + mat::inserter<MatrixDest, Updater> ins(dest, detail::copy_inserter_size<Updater>::apply(src, dest)); + for (cursor_type cursor = mtl::begin<tag::major>(src), cend = mtl::end<tag::major>(src); + cursor != cend; ++cursor) { + // std::cout << dest << '\n'; + + typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type; + for (icursor_type icursor = mtl::begin<tag::nz>(cursor), icend = mtl::end<tag::nz>(cursor); + icursor != icend; ++icursor) { + //std::cout << "in " << row(*icursor) << ", " << col(*icursor) << " insert " << value(*icursor) << '\n'; + ins(row(*icursor), col(*icursor)) << value(*icursor); } + } + } + + // Specialization for multi_vector + template <typename Updater, typename MatrixSrc, typename Vector> + inline void gen_matrix_copy(const MatrixSrc& src, mtl::mat::multi_vector<Vector>& dest, bool) + { + MTL_THROW_IF(num_rows(src) != num_rows(dest) || num_cols(src) != num_cols(dest), incompatible_size()); + typedef typename mtl::traits::updater_to_assigner<Updater>::type Assigner; + + for (std::size_t i= 0, n= num_cols(src); i < n; ++i) + Assigner::first_update(dest.vector(i), src.vector(i)); + } + + namespace { +# ifdef __clang__ +# pragma clang diagnostic ignored "-Wunneeded-internal-declaration" +# pragma clang diagnostic ignored "-Wunused-function" +# endif + inline long inc_wo_over(long i) { return i == std::numeric_limits<long>::max() ? i : i+1; } + inline long negate_wo_over(long i) { return i == std::numeric_limits<long>::min() ? std::numeric_limits<long>::max() : -i; } + } + + template <typename Updater, typename ValueSrc, typename Para, typename ValueDest> + typename boost::enable_if<boost::is_same<Updater, operations::update_store<ValueDest> > >::type + inline gen_matrix_copy(const mat::banded_view<mtl::mat::compressed2D<ValueSrc, Para> >& src, mtl::mat::compressed2D<ValueDest, Para>& dest, bool) + { + vampir_trace<3061> tracer; + typedef typename Para::size_type size_type; + dest.change_dim(num_rows(src), num_cols(src)); // contains make_empty + set_to_zero(dest); + const mtl::mat::compressed2D<ValueSrc, Para> &sref= src.ref; + const std::vector<size_type> &sstarts= sref.ref_major(), &sindices= sref.ref_minor(); + long first, last; + if (traits::is_row_major<Para>::value) { + first= src.get_begin(); + last= src.get_end(); + } else { + first= inc_wo_over(negate_wo_over(src.get_end())); + last= inc_wo_over(negate_wo_over(src.get_begin())); + } + + long jd= 0, j_end= sstarts[0]; + for (long i= 0, i_end= src.dim1(), f= first, l= last; i < i_end; ++i) { + dest.ref_major()[i]= jd; + long j= j_end; + j_end= sstarts[i+1]; + while (j < j_end && long(sindices[j]) < f) j++; + while (j < j_end && long(sindices[j]) < l) jd++, j++; + f= inc_wo_over(f); + l= inc_wo_over(l); + } + dest.ref_major()[src.dim1()]= jd; + dest.set_nnz(jd); // resizes indices and data + + for (long i= 0, i_end= src.dim1(), jd= 0, j_end= sstarts[0]; i < i_end; ++i) { + dest.ref_major()[i]= jd; + long j= j_end; + j_end= sstarts[i+1]; + while (j < j_end && long(sindices[j]) < first) j++; + while (j < j_end && long(sindices[j]) < last) { + dest.ref_minor()[jd]= sindices[j]; + dest.data[jd++]= sref.data[j++]; + } + first= inc_wo_over(first); + last= inc_wo_over(last); + } + } + + + /// Copy matrix \p src into matrix \p dest + template <typename MatrixSrc, typename MatrixDest> + inline void matrix_copy(const MatrixSrc& src, MatrixDest& dest) + { + gen_matrix_copy< operations::update_store<typename MatrixDest::value_type> >(src, dest, true); + } + + + /// Add matrix \p src to matrix \p dest in copy-like style + template <typename MatrixSrc, typename MatrixDest> + inline void matrix_copy_plus(const MatrixSrc& src, MatrixDest& dest) + { + gen_matrix_copy< operations::update_plus<typename MatrixDest::value_type> >(src, dest, false); + } + + /// Subtract matrix \p src from matrix \p dest in copy-like style + template <typename MatrixSrc, typename MatrixDest> + inline void matrix_copy_minus(const MatrixSrc& src, MatrixDest& dest) + { + gen_matrix_copy< operations::update_minus<typename MatrixDest::value_type> >(src, dest, false); + } + + /// Multiply matrix \p src element-wise with matrix \p dest in copy-like style + template <typename MatrixSrc, typename MatrixDest> + inline void matrix_copy_ele_times(const MatrixSrc& src, MatrixDest& dest) + { + vampir_trace<3001> tracer; + MTL_THROW_IF(num_rows(src) != num_rows(dest) || num_cols(src) != num_cols(dest), incompatible_size()); + + typename traits::row<MatrixDest>::type row(dest); + typename traits::col<MatrixDest>::type col(dest); + typename traits::value<MatrixDest>::type value(dest); + typedef typename traits::range_generator<tag::major, MatrixDest>::type cursor_type; + typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type; + + for (cursor_type cursor = begin<tag::major>(dest), cend = end<tag::major>(dest); cursor != cend; ++cursor) + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) + value(*icursor, value(*icursor) * src[row(*icursor)][col(*icursor)]); +#if 0 // copy would result in a*0 = a and 0*b = b!!!! + gen_matrix_copy< operations::update_times<typename MatrixDest::value_type> >(src, dest, false); +#endif + crop(dest); + } + + + template <typename MatrixSrc, typename MatrixDest> + inline void copy(const MatrixSrc& src, tag::flat<tag::matrix>, MatrixDest& dest, tag::flat<tag::matrix>) + // inline void copy(const MatrixSrc& src, tag::matrix_expr, MatrixDest& dest, tag::matrix) + { + return matrix_copy(src, dest); + } + + + + template <typename Updater, typename VectorSrc, typename VectorDest> + inline void gen_vector_copy(const VectorSrc& src, VectorDest& dest, bool with_reset) + { + // Works only with dense vectors as dest !!!!! (source could be sparse) + // Needs vector inserter + vampir_trace<2001> tracer; + + MTL_STATIC_ASSERT((boost::is_same<typename ashape::ashape<VectorSrc>::type, + typename ashape::ashape<VectorDest>::type>::value), "Source and target must have the same algebraic shape."); + + MTL_THROW_IF(size(src) != size(dest), incompatible_size()); + + if (with_reset) + detail::zero_with_sparse_src(dest, typename traits::category<VectorSrc>::type()); + + typename traits::index<VectorSrc>::type index(src); + typename traits::const_value<VectorSrc>::type value(src); + + typedef typename traits::range_generator<tag::nz, VectorSrc>::type cursor_type; + for (cursor_type cursor = begin<tag::nz>(src), cend = end<tag::nz>(src); + cursor != cend; ++cursor) + Updater()(dest[index(*cursor)], value(*cursor)); + } + + /// Copy vector \p src into vector \p dest + template <typename VectorSrc, typename VectorDest> + inline void vector_copy(const VectorSrc& src, VectorDest& dest) + { + gen_vector_copy< operations::update_store<typename VectorDest::value_type> >(src, dest, true); + } + + + /// Add vector \p src to vector \p dest in copy-like style + template <typename VectorSrc, typename VectorDest> + inline void vector_copy_plus(const VectorSrc& src, VectorDest& dest) + { + gen_vector_copy< operations::update_plus<typename VectorDest::value_type> >(src, dest, false); + } + + /// Subtract vector \p src from vector \p dest in copy-like style + template <typename VectorSrc, typename VectorDest> + inline void vector_copy_minus(const VectorSrc& src, VectorDest& dest) + { + gen_vector_copy< operations::update_minus<typename VectorDest::value_type> >(src, dest, false); + } + + + + template <typename VectorSrc, typename VectorDest> + inline void copy(const VectorSrc& src, tag::flat<tag::vector>, VectorDest& dest, tag::flat<tag::vector>) + { + return vector_copy(src, dest); + } + + + template <typename CollSrc, typename CollDest> + inline void copy(const CollSrc& src, CollDest& dest) + { + vampir_trace<3003> tracer; + return copy(src, traits::flatcat2<CollSrc, tag::matrix, tag::vector>(), + dest, traits::flatcat2<CollDest, tag::matrix, tag::vector>()); + } + + +} // namespace mtl + +#endif // MTL_COPY_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/copysign.hpp b/install/MTL/include/boost/numeric/mtl/operation/copysign.hpp new file mode 100644 index 00000000..6281f894 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/copysign.hpp @@ -0,0 +1,86 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_COPYSIGN_INCLUDE +#define MTL_COPYSIGN_INCLUDE + +#include <complex> +#include <cmath> +#include <boost/numeric/mtl/operation/real.hpp> +#include <boost/numeric/mtl/operation/imag.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { + +namespace sfunctor { + + template <typename Value1, typename Value2> + struct copysign + { + static inline Value1 apply(const Value1& v, const Value2& s) + { + using math::zero; using std::abs; + + Value1 a(abs(v)); + return s < zero(s) ? -a : a; + } + }; + + // This specialization is questionable and thus subject to elimination + template <typename Value1, typename Value2> + struct copysign<std::complex<Value1>, Value2> + { + static inline Value1 apply(const std::complex<Value1>& v, const Value2& s) + { + using mtl::real; using mtl::imag; + return std::complex<Value1>(copysign<Value1, Value2>::apply(real(v), s), + copysign<Value1, Value2>::apply(imag(v), s)); + } + }; +#if 0 // ndef _MSC_VER doesn't work on BigRed with gcc 4.2.2 (????) and isn't used anyway + template <> + struct copysign<float, float> + { + static inline float apply(float v, float s) + { return ::copysignf(v, s); } + }; + + template <> + struct copysign<double, double> + { + static inline double apply(double v, double s) + { return ::copysign(v, s); } + }; + + template <> + struct copysign<long double, long double> + { + static inline long double apply(long double v, long double s) + { return copysignl(v, s); } + }; +#endif // _MSC_VER +} + +/// sign of scalars; for complex numbers sign of real part +template <typename Value1, typename Value2> +inline Value1 copysign(const Value1& v, const Value2& s) +{ + vampir_trace<1001> tracer; + return sfunctor::copysign<Value1, Value2>::apply(v, s); +} + + + + +} // namespace mtl + +#endif // MTL_COPYSIGN_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/crop.hpp b/install/MTL/include/boost/numeric/mtl/operation/crop.hpp new file mode 100644 index 00000000..88039f1e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/crop.hpp @@ -0,0 +1,50 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_CROP_INCLUDE +#define MTL_CROP_INCLUDE + +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { + + namespace vec { + + /// Remove all zero entries from a collection + /** Does nothing for dense collections **/ + template <typename T> + typename mtl::traits::enable_if_vector<T, T&>::type inline crop(T& x) + { + vampir_trace<3006> tracer; + x.crop(); return x; + } + } + + namespace mat { + + /// Remove all zero entries from a collection + /** Does nothing for dense collections **/ + template <typename T> + typename mtl::traits::enable_if_matrix<T, T&>::type inline crop(T& x) + { + vampir_trace<3006> tracer; + x.crop(); return x; + } + } + + using vec::crop; + using mat::crop; + +} // namespace mtl + +#endif // MTL_CROP_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/cross.hpp b/install/MTL/include/boost/numeric/mtl/operation/cross.hpp new file mode 100644 index 00000000..b2f9ddcc --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/cross.hpp @@ -0,0 +1,69 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_CROSS_INCLUDE +#define MTL_VECTOR_CROSS_INCLUDE + +#include <boost/numeric/mtl/concept/std_concept.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace vec { + + namespace detail { + + // Result type of cross product + template <typename Vector1, typename Vector2> + struct cross_result + { + typedef typename Multiplicable<typename Collection<Vector1>::value_type, + typename Collection<Vector2>::value_type>::result_type value; + typedef dense_vector<value> type; + }; + } + +/// Cross product +/** Only exists for 3 and 7 dimensions. + Consider specialization for fixed-size types + **/ +template <typename Vector1, typename Vector2> +typename detail::cross_result<Vector1, Vector2>::type +inline cross(const Vector1& v1, const Vector2& v2) +{ + vampir_trace<2002> tracer; + MTL_THROW_IF((size(v1) != 3 && size(v1) != 7 ) || size(v1) != size(v2), incompatible_size()); + + typename detail::cross_result<Vector1, Vector2>::type result(size(v1)); + + if (size(v1) == 3) + for (unsigned i= 0; i < 3; i++) { + unsigned k= (i+1) % 3, l= (i+2) % 3; + result[i]= v1[k] * v2[l] - v1[l] * v2[k]; + } + else // must be 7 thus + for (unsigned i= 0; i < 7; i++) { + unsigned k= (i+1) % 7, l= (i+3) % 7; + result[i]= v1[k] * v2[l] - v1[l] * v2[k]; + + k= (i+2) % 7, l= (i+6) % 7; + result[i]+= v1[k] * v2[l] - v1[l] * v2[k]; + + k= (i+4) % 7, l= (i+5) % 7; + result[i]+= v1[k] * v2[l] - v1[l] * v2[k]; + } + return result; +} + + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_CROSS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/cuppen.hpp b/install/MTL/include/boost/numeric/mtl/operation/cuppen.hpp new file mode 100644 index 00000000..11e7f9d7 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/cuppen.hpp @@ -0,0 +1,133 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// With contributions from Cornelius Steinhardt + +#ifndef MTL_MATRIX_CUPPEN_INCLUDE +#define MTL_MATRIX_CUPPEN_INCLUDE + +#include <cmath> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/iota.hpp> +#include <boost/numeric/mtl/operation/secular.hpp> +#include <boost/numeric/mtl/operation/sort.hpp> +#include <boost/numeric/mtl/operation/trans.hpp> +#include <boost/numeric/mtl/utility/domain.hpp> +#include <boost/numeric/mtl/matrix/permutation.hpp> + +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/itl/iteration/basic_iteration.hpp> +#include <boost/numeric/itl/krylov/fsm.hpp> + +namespace mtl { namespace mat { + +/// Eigenvalues of triangle matrix A with Cuppen's divide and conquer algorithm +/** Eigenvalues are returned in vector lambda. A is overwritten. **/ +template <typename Matrix, typename Vector> +void inline cuppen_inplace(Matrix& A, Matrix& Q, Vector& lambda) +{ + using std::abs; using mtl::irange; using mtl::imax; using mtl::iall; using vec::iota; + + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + typedef vec::dense_vector<size_type, vec::parameters<> > size_vector; // todo: with type trait + + size_type nrows= num_rows(A); + MTL_THROW_IF(nrows != num_cols(A), matrix_not_square()); + const value_type zero= 0, one= 1; + + if (nrows == 1){ + lambda[0]= A[0][0]; + Q= one; + } else { + size_type m= size_type(nrows/2); + irange till_m(m), from_m(m, imax); + + size_vector perm(nrows); + Matrix T1(A[till_m][till_m]), T2(A[from_m][from_m]), // sub-matrices of A + Q0(nrows, nrows), Q1(Q0[till_m][till_m]), Q2(Q0[from_m][from_m]); // Q0 and sub-matrices + Vector v(nrows, zero), diag(nrows), lambda1(diag[till_m]), lambda2(diag[from_m]); // sub-vectors of diag + + //DIVIDE + value_type b= A[m-1][m]; + T1[m-1][m-1]-= abs(b); + T2[0][0]-= abs(b); + + v[m-1]= b > zero ? one : -one; + v[m]= one; + + cuppen_inplace(T1, Q1, lambda1); + cuppen_inplace(T2, Q2, lambda2); + + Q0[till_m][from_m]= zero; Q0[from_m][till_m]= zero; // zero out non-diagonal blocks + + T1[m-1][m-1]+= abs(b); + T2[0][0]+= abs(b); + + iota(perm); + sort(diag, perm); + + // CONQUER, start with eq. (3.0.2) using rows (not columns) + v[till_m]= b < zero ? Vector(-trans(Q1[m-1][iall])) : trans(Q1[m-1][iall]); + v[from_m]= trans(Q2[0][iall]); + + // permutation on v + mtl::mat::traits::permutation<>::type P= mtl::mat::permutation(perm); + Vector v1(P * v); + + lambda= secular(v1, diag, abs(b)); // solve secular equation + + // std::cout << "lambda is " << lambda << "\ndiag is " << diag << '\n'; + //Lemma 3.0.2 ... calculate eigenvectors + Matrix Q_tilde(nrows, nrows); + for (size_type i = 0; i < nrows; i++) { + for (size_type j= 0; j < size(diag); ++j) + MTL_DEBUG_THROW_IF (diag[j] == lambda[i], logic_error("Can't compute eigenvector, probably due to double eigenvalue.")); + Vector li(nrows, lambda[i]), lambda_i(ele_quot(v1, diag - li)); + Q_tilde[iall][i]= lambda_i / two_norm(lambda_i); // normalized eigenvector in Matrix Q + } + + Q= Q0 * P * Q_tilde; + +#if 0 + for (size_type i = 0; i < nrows; i++) { + // Vector qi(Q[iall][i]); // Todo: find out valgrind complains about the memory of qi for reasons inexplicable + Vector qi(nrows); + for (size_type j= 0; j < nrows; j++) + qi[j]= Q[j][i]; + + std::cout << "q[" << i << "] = " << qi << ", lambda[i] = " << lambda[i] + << ", diff = " << two_norm(Vector(A*qi - lambda[i]*qi)) << ", A*qi = " << Vector(A*qi) << ", li*qi = " << Vector(lambda[i]*qi) << '\n'; + itl::basic_iteration<double> iter(1.0, 20, 1e-5, 1e-5); + fsm(A, qi, lambda[i], 0.1, iter); + std::cout << "q[" << i << "] = " << qi << ", diff = " << two_norm(Vector(A*qi - lambda[i]*qi)) << '\n'; + Q[iall][i]= qi; + } +#endif + } +} + +/// Eigenvalues of triangle matrix A with Cuppen's divide and conquer algorithm +/** Eigenvalues are returned in vector lambda. A is copied. **/ +// A not as reference to force copy +template <typename Matrix, typename Vector> +void inline cuppen(Matrix A, Matrix& Q, Vector& lambda) +{ + Q= 0.0; + cuppen_inplace(A, Q, lambda); +} + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_CUPPEN_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/cursor_pseudo_dot.hpp b/install/MTL/include/boost/numeric/mtl/operation/cursor_pseudo_dot.hpp new file mode 100644 index 00000000..2d9fd080 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/cursor_pseudo_dot.hpp @@ -0,0 +1,90 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_CURSOR_PSEUDO_DOT_INCLUDE +#define MTL_CURSOR_PSEUDO_DOT_INCLUDE + +namespace mtl { + + + +namespace functor { + + template <unsigned MaxDepth, typename Value, typename Cursor1, typename Prop1, typename Cursor2, typename Prop2, unsigned Depth> + struct cursor_pseudo_dot_block + { + static unsigned const offset= MaxDepth - Depth; + + void operator() (Cursor1 i1, Prop1& prop1, Cursor2 i2, Prop2& prop2, + Value& s0, Value& s1, Value& s2, Value& s3, + Value& s4, Value& s5, Value& s6, Value& s7) + { + Cursor1 tmp1(i1); tmp1+= offset; + Cursor2 tmp2(i2); tmp2+= offset; + s0+= prop1(*tmp1) * prop2(*tmp2); + // s0+= prop1(i1 + offset) * prop2(i2 + offset); + typedef cursor_pseudo_dot_block<MaxDepth, Value, Cursor1, Prop1, Cursor2, Prop2, Depth-1> block_rest; + block_rest() (i1, prop1, i2, prop2, s1, s2, s3, s4, s5, s6, s7, s0); + } + }; + + //template <> + template <unsigned MaxDepth, typename Value, typename Cursor1, typename Prop1, typename Cursor2, typename Prop2> + struct cursor_pseudo_dot_block<MaxDepth, Value, Cursor1, Prop1, Cursor2, Prop2, 1> + { + static unsigned const offset= MaxDepth - 1; + + void operator() (Cursor1 i1, Prop1& prop1, Cursor2 i2, Prop2& prop2, + Value& s0, Value&, Value&, Value&, + Value&, Value&, Value&, Value&) + { + s0+= prop1(*(i1 + offset)) * prop2(*(i2 + offset)); + } + }; + + template <unsigned MaxDepth, typename Value, typename Cursor1, typename Prop1, typename Cursor2, typename Prop2> + struct cursor_pseudo_dot_t + { + Value operator() (Cursor1 i1, Cursor1 end1, Prop1& prop1, Cursor2 i2, Prop2& prop2) + { + using math::zero; + Value ref, my_zero(zero(ref)), + s0= my_zero, s1= my_zero, s2= my_zero, s3= my_zero, + s4= my_zero, s5= my_zero, s6= my_zero, s7= my_zero; + std::size_t size= end1 - i1, blocks= size / MaxDepth, blocked_size= blocks * MaxDepth; + + typedef cursor_pseudo_dot_block<MaxDepth, Value, Cursor1, Prop1, Cursor2, Prop2, MaxDepth> dot_block_type; + for (unsigned i= 0; i < blocked_size; i+= MaxDepth, i1+= MaxDepth, i2+= MaxDepth) { + dot_block_type()(i1, prop1, i2, prop2, s0, s1, s2, s3, s4, s5, s6, s7); + } + + typedef cursor_pseudo_dot_block<MaxDepth, Value, Cursor1, Prop1, Cursor2, Prop2, MaxDepth> dot_single_type; + s0+= s1 + s2 + s3 + s4 + s5 + s6 + s7; + for (unsigned i= blocked_size; i < size; ++i, ++i1, ++i2) + dot_single_type()(i1, prop1, i2, prop2, s0, s1, s2, s3, s4, s5, s6, s7); + return s0; + } + }; + +} // namespace functor + +template <unsigned MaxDepth, typename Value, typename Cursor1, typename Prop1, typename Cursor2, typename Prop2> +Value cursor_pseudo_dot(Cursor1 i1, Cursor1 end1, Prop1 prop1, Cursor2 i2, Prop2 prop2, Value) +{ + return functor::cursor_pseudo_dot_t<MaxDepth, Value, Cursor1, Prop1, Cursor2, Prop2>()(i1, end1, prop1, i2, prop2); +} + + + +} // namespace mtl + +#endif // MTL_CURSOR_PSEUDO_DOT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/diagonal.hpp b/install/MTL/include/boost/numeric/mtl/operation/diagonal.hpp new file mode 100644 index 00000000..dc6198a0 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/diagonal.hpp @@ -0,0 +1,69 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_DIAGONAL_INCLUDE +#define MTL_DIAGONAL_INCLUDE + + +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { + + namespace vec { + + /// Transform a vector into a diagonal matrix + template <typename Vector> + mtl::mat::compressed2D<typename Collection<Vector>::value_type, mat::parameters<> > + // typename mtl::traits::enable_if_vector<Vector, mtl::mat::compressed2D<typename Collection<Vector>::value_type> >::type + inline diagonal(const Vector& v) + { + vampir_trace<2016> tracer; + typedef mtl::mat::compressed2D<typename Collection<Vector>::value_type, mat::parameters<> > matrix_type; + matrix_type D(size(v), size(v)); + D= 0; + mtl::mat::inserter<matrix_type> ins(D, 1); + for (typename Collection<Vector>::size_type i= 0; i < size(v); ++i) + ins[i][i] << v[i]; + + return D; + } + } + + namespace mat { + + /// Return the vector with the diagonal of the matrix + template <typename Matrix> + // typename mtl::traits::enable_if_matrix<Matrix, conj_view<Matrix> >::type + mtl::vec::dense_vector<typename Collection<Matrix>::value_type, vec::parameters<> > + inline diagonal(const Matrix& A) + { + vampir_trace<3007> tracer; + using std::min; + typedef typename Collection<Matrix>::size_type size_type; + size_type n= min(num_rows(A), num_cols(A)); + mtl::vec::dense_vector<typename Collection<Matrix>::value_type, vec::parameters<> > v(n); + + for (size_type i= 0; i < n; ++i) + v[i]= A[i][i]; + return v; + } + } + +} // namespace mtl + +#endif // MTL_DIAGONAL_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/div_result.hpp b/install/MTL/include/boost/numeric/mtl/operation/div_result.hpp new file mode 100644 index 00000000..b6055905 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/div_result.hpp @@ -0,0 +1,52 @@ +/* + * div_result.h + * MTL + * + * Created by Hui Li (huil@Princeton.EDU) + * + */ + +#ifndef MTL_DIV_RESULT_INCLUDE +#define MTL_DIV_RESULT_INCLUDE + +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/matrix/map_view.hpp> +#include <boost/numeric/mtl/vector/map_view.hpp> + +namespace mtl { namespace traits { + +template < typename Op1, typename Op2, typename DivOp > struct div_result_aux {}; + +/// Result type for dividing Op1 by Op2 +/** Can be used in enable-if-style as type is only defined when appropriate **/ +template < typename Op1, typename Op2 > +struct div_result + : public div_result_aux < Op1, Op2, typename ashape::div_op<typename ashape::ashape<Op1>::type, + typename ashape::ashape<Op2>::type >::type > +{}; + +/// Divide column vector by scalar +template < typename Op1, typename Op2 > +struct div_result_aux < Op1, Op2, ::mtl::ashape::cvec_scal_div > +{ + typedef typename vec::divide_by_view<Op1,Op2> type; +}; + +/// Divide row vector by scalar +template < typename Op1, typename Op2 > +struct div_result_aux < Op1, Op2, ::mtl::ashape::rvec_scal_div > +{ + typedef typename vec::divide_by_view<Op1,Op2> type; +}; + +/// Divide matrix by scalar +template < typename Op1, typename Op2 > +struct div_result_aux < Op1, Op2, ::mtl::ashape::mat_scal_div > +{ + typedef typename mat::divide_by_view<Op1,Op2> type; +}; + +}} // namespace mtl::traits + + +#endif diff --git a/install/MTL/include/boost/numeric/mtl/operation/divide_by.hpp b/install/MTL/include/boost/numeric/mtl/operation/divide_by.hpp new file mode 100644 index 00000000..b87a1dca --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/divide_by.hpp @@ -0,0 +1,94 @@ +/* + * divide_by.h + * MTL4 + * + * Created by Hui Li (huil@Princeton.EDU) + * + */ + +#ifndef MTL_DIVIDE_BY_INCLUDE +#define MTL_DIVIDE_BY_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/std_concept.hpp> +#include <boost/numeric/mtl/matrix/map_view.hpp> +#include <boost/numeric/mtl/vector/map_view.hpp> +#include <boost/numeric/mtl/utility/algebraic_category.hpp> + +namespace mtl { namespace tfunctor { + + // AlgebraicCategory is by default tag::scalar + template <typename Value1, typename Value2, typename AlgebraicCategory> + struct divide_by + { + typedef typename Multiplicable<Value1, Value2>::result_type result_type; + + explicit divide_by(const Value2& v2) : v2(v2) {} + + result_type operator() (const Value1& v1) const + { + return v1 / v2; + } + private: + Value2 v2; + }; + + + template <typename Matrix, typename Value2> + struct divide_by<Matrix, Value2, tag::matrix> + { + typedef mat::divide_by_view<Matrix,Value2> result_type; + + explicit divide_by(const Value2& v2) : v2(v2) {} + + result_type operator() (const Matrix& matrix) const + { + return result_type(matrix, v2); + } + private: + Value2 v2; + }; + + + template <typename Vector, typename Value2> + struct divide_by<Vector, Value2, tag::vector> + { + typedef vec::divide_by_view<Vector, Value2> result_type; + + explicit divide_by(const Value2& v2) : v2(v2) {} + + result_type operator() (const Vector& vector) const + { + return result_type(vector, v2); + } + private: + Value2 v2; + }; + + +} // namespace tfunctor + + +namespace mat { + + template <typename Value1, typename Value2> + typename tfunctor::divide_by<Value1, Value2, typename traits::algebraic_category<Value1>::type>::result_type + inline divide_by(const Value1& value1, const Value2& value2) + { + return tfunctor::divide_by<Value1, Value2, typename traits::algebraic_category<Value1>::type>(value2)(value1); + } +} + +namespace vec { + + template <typename Value1, typename Value2> + typename tfunctor::divide_by<Value1, Value2, typename traits::algebraic_category<Value1>::type>::result_type + inline divide_by(const Value1& value1, const Value2& value2) + { + return tfunctor::divide_by<Value1, Value2, typename traits::algebraic_category<Value1>::type>(value2)(value1); + } +} + +} // namespace mtl + +#endif // MTL_DIVIDE_BY_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/divide_by_inplace.hpp b/install/MTL/include/boost/numeric/mtl/operation/divide_by_inplace.hpp new file mode 100644 index 00000000..f2a3e4f3 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/divide_by_inplace.hpp @@ -0,0 +1,40 @@ +/* + * divide_by_inplace.hpp + * MTL4 + * + * Created by Hui Li (huil@Princeton.EDU) + * + */ + +#ifndef MTL_DIVIDE_BY_INPLACE_INCLUDE +#define MTL_DIVIDE_BY_INPLACE_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/operation/assign_each_nonzero.hpp> +#include <boost/numeric/mtl/operation/divide_by.hpp> + + +namespace mtl { + + + /// Divide collection \p c (from right) by scalar factor \p alpha; \p c is altered + template <typename Factor, typename Coll> + void divide_by_inplace(Coll& c, const Factor& alpha, tag::scalar) + { + // assign_each_nonzero(c, boost::lambda::_1 / alpha); + assign_each_nonzero(c, tfunctor::divide_by<typename Collection<Coll>::value_type, Factor>(alpha)); + } + + /// Divide collection \p c (from right) by factor \p alpha; \p c is altered + template <typename Factor, typename Collection> + void divide_by_inplace(Collection& c, const Factor& alpha) + { + divide_by_inplace(c, alpha, typename traits::category<Factor>::type()); + } + + +} // namespace mtl + +#endif // MTL_DIVIDE_BY_INPLACE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/dmat_dmat_mult.hpp b/install/MTL/include/boost/numeric/mtl/operation/dmat_dmat_mult.hpp new file mode 100644 index 00000000..56087c7d --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/dmat_dmat_mult.hpp @@ -0,0 +1,1067 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_DMAT_DMAT_MULT_INCLUDE +#define MTL_DMAT_DMAT_MULT_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/utility/enable_if.hpp> + +#include <boost/numeric/mtl/operation/set_to_zero.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/operation/cursor_pseudo_dot.hpp> +#include <boost/numeric/mtl/operation/multi_action_block.hpp> +#include <boost/numeric/mtl/operation/assign_mode.hpp> +#include <boost/numeric/mtl/operation/static_size.hpp> +#include <boost/numeric/mtl/operation/static_num_rows.hpp> +#include <boost/numeric/mtl/operation/static_num_cols.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/flatcat.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/glas_tag.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/is_static.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/meta_math/loop.hpp> +#include <boost/numeric/mtl/recursion/base_case_test.hpp> +#include <boost/numeric/mtl/recursion/base_case_matrix.hpp> +#include <boost/numeric/mtl/recursion/matrix_recursator.hpp> +#include <boost/numeric/mtl/recursion/base_case_cast.hpp> +#include <boost/numeric/mtl/interface/blas.hpp> + +#include <boost/numeric/mtl/matrix/dense2D.hpp> +#include <boost/numeric/mtl/operation/print_matrix.hpp> +#include <boost/numeric/mtl/operation/no_op.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +#include <iostream> +#include <complex> + +namespace mtl { + +// ===================================================== +// Generic matrix product with cursors and property maps +// ===================================================== + + +// To allow 5th parameter, is ignored +// This is the bottom line of dmat_dmat_mult implementations. +// All MTL4 matrix types and views (so far) have cursors and property maps +// so that we disabled the backup functor by default. +// If some type has no cursor, one can still use a backup functor (whatever this may be). +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign= assign::assign_sum, + typename Backup= no_op> +struct gen_cursor_dmat_dmat_mult_ft +{ + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + apply(A, B, C, traits::flatcat1<MatrixA, tag::has_cursor>(), traits::flatcat1<MatrixB, tag::has_cursor>()); + } + +private: + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, tag::universe, tag::universe) + { + Backup()(A, B, C); + } + + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, tag::flat<tag::has_cursor>, tag::flat<tag::has_cursor>) + { + // asm("#cursor"); + vampir_trace<4001> tracer; + // std::cout << "Canonical cursor\n"; + typedef glas::tag::row row; + typedef glas::tag::col col; + typedef glas::tag::all all; + + typedef typename traits::const_value<MatrixA>::type a_value_type; + typedef typename traits::const_value<MatrixB>::type b_value_type; + typedef typename traits::value<MatrixC>::type c_value_type; + + typedef typename traits::range_generator<row, MatrixA>::type a_cur_type; + typedef typename traits::range_generator<row, MatrixC>::type c_cur_type; + + typedef typename traits::range_generator<col, MatrixB>::type b_cur_type; + typedef typename traits::range_generator<all, c_cur_type>::type c_icur_type; + + typedef typename traits::range_generator<all, a_cur_type>::type a_icur_type; + typedef typename traits::range_generator<all, b_cur_type>::type b_icur_type; + +#ifndef NDEBUG + typename traits::row<MatrixA>::type row_a(A); + typename traits::col<MatrixA>::type col_a(A); + typename traits::row<MatrixB>::type row_b(B); + typename traits::col<MatrixB>::type col_b(B); + typename traits::row<MatrixC>::type row_c(C); + typename traits::col<MatrixC>::type col_c(C); +#else +# undef MTL_DEBUG_DMAT_DMAT_MULT // doesn't work with NDEBUG +#endif + + if (Assign::init_to_zero) set_to_zero(C); + + a_value_type a_value(A); + b_value_type b_value(B); + c_value_type c_value(C); + + a_cur_type ac= begin<row>(A), aend= end<row>(A); + for (c_cur_type cc= begin<row>(C); ac != aend; ++ac, ++cc) { + + b_cur_type bc= begin<col>(B), bend= end<col>(B); + for (c_icur_type cic= begin<all>(cc); bc != bend; ++bc, ++cic) { + + typename MatrixC::value_type c_tmp(c_value(*cic)); +#ifdef MTL_DEBUG_DMAT_DMAT_MULT + std::cout << "Calculating C[" << row_c(*cic) << "][" << col_c(*cic) << "], initial value is " + << c_tmp << "\n"; +#endif + a_icur_type aic= begin<all>(ac), aiend= end<all>(ac); + for (b_icur_type bic= begin<all>(bc); aic != aiend; ++aic, ++bic) { +#ifdef MTL_DEBUG_DMAT_DMAT_MULT + std::cout << "Updating with A[" << row_a(*aic) << "][" << col_a(*aic) << "] /* value is " + << a_value(*aic) << " */ * "; + std::cout << "B[" << row_b(*bic) << "][" << col_b(*bic) << "] /* value is " + << b_value(*bic) << " */ * "; +#endif + assert(row_a(*aic) == row_c(*cic)); // Must do here because ac has no props + assert(col_b(*bic) == col_c(*cic)); + assert(col_a(*aic) == row_b(*bic)); + Assign::update(c_tmp, a_value(*aic) * b_value(*bic)); +#ifdef MTL_DEBUG_DMAT_DMAT_MULT + std::cout << "C's current value is " << c_tmp << "\n"; +#endif + } + c_value(*cic, c_tmp); + } + } + } +}; + + +template <typename Assign= assign::assign_sum, + typename Backup= no_op> // To allow 2nd parameter, is ignored +struct gen_cursor_dmat_dmat_mult_t +{ + template <typename MatrixA, typename MatrixB, typename MatrixC> + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + gen_cursor_dmat_dmat_mult_ft<MatrixA, MatrixB, MatrixC, Assign, Backup>()(A, B, C); + } +}; + + +// ===================================== +// Generic matrix product with iterators +// ===================================== + +template <typename MatrixA, typename MatrixB, typename MatrixC, + typename Assign= assign::assign_sum, + typename Backup= gen_cursor_dmat_dmat_mult_t<Assign> > +struct gen_dmat_dmat_mult_ft +{ + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + apply(A, B, C, traits::flatcat1<MatrixA, tag::has_iterator>(), traits::flatcat1<MatrixB, tag::has_iterator>()); + } + +private: + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, tag::universe, tag::universe) + { + Backup()(A, B, C); + } + + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, tag::flat<tag::has_iterator>, tag::flat<tag::has_iterator>) + { + // asm("#iterator"); + vampir_trace<4002> tracer; + // std::cout << "Canonical iterator\n"; + using namespace tag; + using traits::range_generator; + typedef typename range_generator<row, MatrixA>::type a_cur_type; + typedef typename range_generator<row, MatrixC>::type c_cur_type; + typedef typename range_generator<col, MatrixB>::type b_cur_type; + typedef typename range_generator<iter::all, c_cur_type>::type c_icur_type; + typedef typename range_generator<const_iter::all, a_cur_type>::type a_icur_type; + typedef typename range_generator<const_iter::all, b_cur_type>::type b_icur_type; + + if (Assign::init_to_zero) set_to_zero(C); + + a_cur_type ac= mtl::begin<row>(A), aend= mtl::end<row>(A); + for (c_cur_type cc= mtl::begin<row>(C); ac != aend; ++ac, ++cc) { + + b_cur_type bc= mtl::begin<col>(B), bend= mtl::end<col>(B); + for (c_icur_type cic= mtl::begin<iter::all>(cc); bc != bend; ++bc, ++cic) { + + typename MatrixC::value_type c_tmp(*cic); + a_icur_type aic= mtl::begin<const_iter::all>(ac), aiend= mtl::end<const_iter::all>(ac); + for (b_icur_type bic= mtl::begin<const_iter::all>(bc); aic != aiend; ++aic, ++bic) { + Assign::update(c_tmp, *aic * *bic); + } + *cic= c_tmp; + } + } + } +}; + + +template <typename Assign= assign::assign_sum, + typename Backup= gen_cursor_dmat_dmat_mult_t<Assign> > +struct gen_dmat_dmat_mult_t +{ + template <typename MatrixA, typename MatrixB, typename MatrixC> + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + gen_dmat_dmat_mult_ft<MatrixA, MatrixB, MatrixC, Assign, Backup>()(A, B, C); + } +}; + + +/* + +Unrolling matrix product with dimensions that are not multiples of blocks + +1. Do with optimization: + C_nw += A_nw * B_nw + - wherby the matrix dimensions of sub-matrices are the largest multiples of block sizes + smaller or equal to the matrix dimensions of the original matrix + + +2. Do without optimization + C_nw += A_ne * B_sw + C_ne += A_n * B_e + C_s += A_s * B + +The inner loop can be unrolled arbitrarily. So, we can simplify + +1. Do with optimization: + C_nw += A_n * B_w + - wherby the matrix dimensions of sub-matrices are the largest multiples of block sizes + smaller or equal to the matrix dimensions of the original matrix + + +2. Do with optimization only in inner loop + C_ne += A_n * B_e + C_s += A_s * B + + +*/ + +// ======================= +// Unrolled with iterators +// required has_2D_layout +// ======================= + +// Define defaults if not yet given as Compiler flag +#ifndef MTL_DMAT_DMAT_MULT_TILING1 +# define MTL_DMAT_DMAT_MULT_TILING1 2 +#endif + +#ifndef MTL_DMAT_DMAT_MULT_TILING2 +# define MTL_DMAT_DMAT_MULT_TILING2 4 +#endif + +#ifndef MTL_DMAT_DMAT_MULT_INNER_UNROLL +# define MTL_DMAT_DMAT_MULT_INNER_UNROLL 8 +#endif + + +template <unsigned long Index0, unsigned long Max0, unsigned long Index1, unsigned long Max1, typename Assign> +struct gen_tiling_dmat_dmat_mult_block + : public meta_math::loop2<Index0, Max0, Index1, Max1> +{ + typedef meta_math::loop2<Index0, Max0, Index1, Max1> base; + typedef gen_tiling_dmat_dmat_mult_block<base::next_index0, Max0, base::next_index1, Max1, Assign> next_t; + + template <typename Value, typename ValueA, typename SizeA, typename ValueB, typename SizeB> + static inline void apply(Value& tmp00, Value& tmp01, Value& tmp02, Value& tmp03, Value& tmp04, + Value& tmp05, Value& tmp06, Value& tmp07, Value& tmp08, Value& tmp09, + Value& tmp10, Value& tmp11, Value& tmp12, Value& tmp13, Value& tmp14, Value& tmp15, + ValueA *begin_a, SizeA& ari, ValueB *begin_b, SizeB& bci) + { + tmp00+= begin_a[ base::index0 * ari ] * begin_b[ base::index1 * bci ]; + next_t::apply(tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, tmp08, tmp09, + tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp00, + begin_a, ari, begin_b, bci); + } + + template <typename Value, typename MatrixC, typename SizeC> + static inline void update(Value& tmp00, Value& tmp01, Value& tmp02, Value& tmp03, Value& tmp04, + Value& tmp05, Value& tmp06, Value& tmp07, Value& tmp08, Value& tmp09, + Value& tmp10, Value& tmp11, Value& tmp12, Value& tmp13, Value& tmp14, Value& tmp15, + MatrixC& C, SizeC i, SizeC k) + { + Assign::update(C(i + base::index0, k + base::index1), tmp00); + next_t::update(tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, tmp08, tmp09, + tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp00, + C, i, k); + } +}; + +template <unsigned long Max0, unsigned long Max1, typename Assign> +struct gen_tiling_dmat_dmat_mult_block<Max0, Max0, Max1, Max1, Assign> + : public meta_math::loop2<Max0, Max0, Max1, Max1> +{ + typedef meta_math::loop2<Max0, Max0, Max1, Max1> base; + + template <typename Value, typename ValueA, typename SizeA, typename ValueB, typename SizeB> + static inline void apply(Value& tmp00, Value&, Value&, Value&, Value&, + Value&, Value&, Value&, Value&, Value&, + Value&, Value&, Value&, Value&, Value&, Value&, + ValueA *begin_a, SizeA& ari, ValueB *begin_b, SizeB& bci) + { + tmp00+= begin_a[ base::index0 * ari ] * begin_b[ base::index1 * bci ]; + } + + template <typename Value, typename MatrixC, typename SizeC> + static inline void update(Value& tmp00, Value&, Value&, Value&, Value&, + Value&, Value&, Value&, Value&, Value&, + Value&, Value&, Value&, Value&, Value&, Value&, + MatrixC& C, SizeC i, SizeC k) + { + Assign::update(C(i + base::index0, k + base::index1), tmp00); + } +}; + + +template <typename MatrixA, typename MatrixB, typename MatrixC, + unsigned long Tiling1= MTL_DMAT_DMAT_MULT_TILING1, + unsigned long Tiling2= MTL_DMAT_DMAT_MULT_TILING2, + typename Assign= assign::assign_sum, + typename Backup= gen_dmat_dmat_mult_t<Assign> > +struct gen_tiling_dmat_dmat_mult_ft +{ + MTL_STATIC_ASSERT((Tiling1 * Tiling2 <= 16), "Tile (Tiling1 * Tiling2) cannot be larger than 16."); + + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + apply(A, B, C, traits::layout_flatcat<MatrixA>(), traits::layout_flatcat<MatrixB>()); + } + +private: + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, tag::universe, tag::universe) + { + Backup()(A, B, C); + } + + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, tag::flat<tag::has_2D_layout>, tag::flat<tag::has_2D_layout>) + { + // asm("#tiling"); + vampir_trace<4003> tracer; + // Indices run out of range for smaller matrices + if (num_rows(A) < 2 || num_cols(A) < 2 || num_cols(B) < 2) { + Backup()(A, B, C); + return; + } + + // std::cout << "meta-unrolling\n"; + if (Assign::init_to_zero) set_to_zero(C); + + typedef gen_tiling_dmat_dmat_mult_block<1, Tiling1, 1, Tiling2, Assign> block; + typedef typename MatrixC::size_type size_type; + typedef typename MatrixC::value_type value_type; + const value_type z= math::zero(C[0][0]); // if this are matrices we need their size + + size_type i_max= num_rows(C), i_block= Tiling1 * (i_max / Tiling1), + k_max= num_cols(C), k_block= Tiling2 * (k_max / Tiling2); + size_t ari= &A(1, 0) - &A(0, 0), // how much is the offset of A's entry increased by incrementing row + aci= &A(0, 1) - &A(0, 0), bri= &B(1, 0) - &B(0, 0), bci= &B(0, 1) - &B(0, 0); + + // C_nw += A_nw * B_nw + for (size_type i= 0; i < i_block; i+= Tiling1) + for (size_type k= 0; k < k_block; k+= Tiling2) { + + value_type tmp00= z, tmp01= z, tmp02= z, tmp03= z, tmp04= z, + tmp05= z, tmp06= z, tmp07= z, tmp08= z, tmp09= z, + tmp10= z, tmp11= z, tmp12= z, tmp13= z, tmp14= z, tmp15= z; + const typename MatrixA::value_type *begin_a= &A(i, 0), *end_a= begin_a + num_cols(A) * aci; + const typename MatrixB::value_type *begin_b= &B(0, k); + + for (; begin_a != end_a; begin_a+= aci, begin_b+= bri) + block::apply(tmp00, tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, tmp08, tmp09, + tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, + begin_a, ari, begin_b, bci); + block::update(tmp00, tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, tmp08, tmp09, + tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, + C, i, k); + } + + // C_ne += A_n * B_e + for (size_type i= 0; i < i_block; i++) + for (size_type k = k_block; k < k_max; k++) { + value_type tmp00= z; + const typename MatrixA::value_type *begin_a= &A(i, 0), *end_a= begin_a + num_cols(A) * aci; + const typename MatrixB::value_type *begin_b= &B(0, k); + + for (; begin_a != end_a; begin_a+= aci, begin_b+= bri) + tmp00 += *begin_a * *begin_b; + Assign::update(C(i, k), tmp00); + } + + // C_s += A_s * B + for (size_type i= i_block; i < i_max; i++) + for (size_type k = 0; k < k_max; k++) { + value_type tmp00= z; + const typename MatrixA::value_type *begin_a= &A(i, 0), *end_a= begin_a + num_cols(A) * aci; + const typename MatrixB::value_type *begin_b= &B(0, k); + + for (; begin_a != end_a; begin_a+= aci, begin_b+= bri) + tmp00 += *begin_a * *begin_b; + Assign::update(C(i, k), tmp00); + } + } +}; + +template <unsigned long Tiling1= MTL_DMAT_DMAT_MULT_TILING1, + unsigned long Tiling2= MTL_DMAT_DMAT_MULT_TILING2, + typename Assign= assign::assign_sum, + typename Backup= gen_dmat_dmat_mult_t<Assign> > +struct gen_tiling_dmat_dmat_mult_t +{ + template <typename MatrixA, typename MatrixB, typename MatrixC> + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + gen_tiling_dmat_dmat_mult_ft< + MatrixA, MatrixB, MatrixC, Tiling1, Tiling2, Assign, Backup + >()(A, B, C); + } +}; + + + +// ================================= +// Unrolled with iterators fixed 4x4 +// required has_2D_layout +// ================================= + + +template <typename MatrixA, typename MatrixB, typename MatrixC, + typename Assign= assign::assign_sum, + typename Backup= gen_dmat_dmat_mult_t<Assign> > +struct gen_tiling_44_dmat_dmat_mult_ft +{ + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + apply(A, B, C, traits::layout_flatcat<MatrixA>(), traits::layout_flatcat<MatrixB>()); + } + +private: + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, tag::universe, tag::universe) + { + Backup()(A, B, C); + } + + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, tag::flat<tag::has_2D_layout>, tag::flat<tag::has_2D_layout>) + { + // asm("#tiling44"); + vampir_trace<4004> tracer; + // Indices run out of range for smaller matrices + if (num_rows(A) < 2 || num_cols(A) < 2 || num_cols(B) < 2) { + Backup()(A, B, C); + return; + } + + // std::cout << "4x4 unrolling\n"; + if (Assign::init_to_zero) set_to_zero(C); + + typedef typename MatrixC::size_type size_type; + typedef typename MatrixC::value_type value_type; + + const size_type Tiling1= 4, Tiling2= 4; + const value_type z= math::zero(C[0][0]); // if this are matrices we need their size + + size_type i_max= num_rows(C), i_block= Tiling1 * (i_max / Tiling1), + k_max= num_cols(C), k_block= Tiling2 * (k_max / Tiling2); + size_t ari= &A(1, 0) - &A(0, 0), // how much is the offset of A's entry increased by incrementing row + aci= &A(0, 1) - &A(0, 0), bri= &B(1, 0) - &B(0, 0), bci= &B(0, 1) - &B(0, 0); + + // C_nw += A_nw * B_nw + for (size_type i= 0; i < i_block; i+= Tiling1) + for (size_type k= 0; k < k_block; k+= Tiling2) { + + value_type tmp00= z, tmp01= z, tmp02= z, tmp03= z, tmp04= z, + tmp05= z, tmp06= z, tmp07= z, tmp08= z, tmp09= z, + tmp10= z, tmp11= z, tmp12= z, tmp13= z, tmp14= z, tmp15= z; + const typename MatrixA::value_type *begin_a= &A(i, 0), *end_a= begin_a + num_cols(A) * aci; + const typename MatrixB::value_type *begin_b= &B(0, k); + + for (; begin_a != end_a; begin_a+= aci, begin_b+= bri) { + tmp00+= begin_a[ 0 * ari ] * begin_b[ 0 * bci ]; + tmp01+= begin_a[ 0 * ari ] * begin_b[ 1 * bci ]; + tmp02+= begin_a[ 0 * ari ] * begin_b[ 2 * bci ]; + tmp03+= begin_a[ 0 * ari ] * begin_b[ 3 * bci ]; + tmp04+= begin_a[ 1 * ari ] * begin_b[ 0 * bci ]; + tmp05+= begin_a[ 1 * ari ] * begin_b[ 1 * bci ]; + tmp06+= begin_a[ 1 * ari ] * begin_b[ 2 * bci ]; + tmp07+= begin_a[ 1 * ari ] * begin_b[ 3 * bci ]; + tmp08+= begin_a[ 2 * ari ] * begin_b[ 0 * bci ]; + tmp09+= begin_a[ 2 * ari ] * begin_b[ 1 * bci ]; + tmp10+= begin_a[ 2 * ari ] * begin_b[ 2 * bci ]; + tmp11+= begin_a[ 2 * ari ] * begin_b[ 3 * bci ]; + tmp12+= begin_a[ 3 * ari ] * begin_b[ 0 * bci ]; + tmp13+= begin_a[ 3 * ari ] * begin_b[ 1 * bci ]; + tmp14+= begin_a[ 3 * ari ] * begin_b[ 2 * bci ]; + tmp15+= begin_a[ 3 * ari ] * begin_b[ 3 * bci ]; + } + Assign::update(C(i + 0, k + 0), tmp00); + Assign::update(C(i + 0, k + 1), tmp01); + Assign::update(C(i + 0, k + 2), tmp02); + Assign::update(C(i + 0, k + 3), tmp03); + Assign::update(C(i + 1, k + 0), tmp04); + Assign::update(C(i + 1, k + 1), tmp05); + Assign::update(C(i + 1, k + 2), tmp06); + Assign::update(C(i + 1, k + 3), tmp07); + Assign::update(C(i + 2, k + 0), tmp08); + Assign::update(C(i + 2, k + 1), tmp09); + Assign::update(C(i + 2, k + 2), tmp10); + Assign::update(C(i + 2, k + 3), tmp11); + Assign::update(C(i + 3, k + 0), tmp12); + Assign::update(C(i + 3, k + 1), tmp13); + Assign::update(C(i + 3, k + 2), tmp14); + Assign::update(C(i + 3, k + 3), tmp15); + } + + // C_ne += A_n * B_e + for (size_type i= 0; i < i_block; i++) + for (size_type k = k_block; k < k_max; k++) { + value_type tmp00= z; + const typename MatrixA::value_type *begin_a= &A(i, 0), *end_a= begin_a + num_cols(A) * aci; + const typename MatrixB::value_type *begin_b= &B(0, k); + + for (; begin_a != end_a; begin_a+= aci, begin_b+= bri) + tmp00 += *begin_a * *begin_b; + Assign::update(C(i, k), tmp00); + } + + // C_s += A_s * B + for (size_type i= i_block; i < i_max; i++) + for (size_type k = 0; k < k_max; k++) { + value_type tmp00= z; + const typename MatrixA::value_type *begin_a= &A(i, 0), *end_a= begin_a + num_cols(A) * aci; + const typename MatrixB::value_type *begin_b= &B(0, k); + + for (; begin_a != end_a; begin_a+= aci, begin_b+= bri) + tmp00 += *begin_a * *begin_b; + Assign::update(C(i, k), tmp00); + } + } +}; + +template <typename Assign= assign::assign_sum, + typename Backup= gen_dmat_dmat_mult_t<Assign> > +struct gen_tiling_44_dmat_dmat_mult_t +{ + template <typename MatrixA, typename MatrixB, typename MatrixC> + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + gen_tiling_44_dmat_dmat_mult_ft< + MatrixA, MatrixB, MatrixC, Assign, Backup + >()(A, B, C); + } +}; + + + + +// ================================= +// Unrolled with iterators fixed 2x2 +// required has_2D_layout +// ================================= + + +template <typename MatrixA, typename MatrixB, typename MatrixC, + typename Assign= assign::assign_sum, + typename Backup= gen_dmat_dmat_mult_t<Assign> > +struct gen_tiling_22_dmat_dmat_mult_ft +{ + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + apply(A, B, C, traits::layout_flatcat<MatrixA>(), traits::layout_flatcat<MatrixB>()); + } + +private: + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, tag::universe, tag::universe) + { + Backup()(A, B, C); + } + + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, tag::flat<tag::has_2D_layout>, tag::flat<tag::has_2D_layout>) + { + // asm("#tiling22"); + vampir_trace<4005> tracer; + // Indices run out of range for smaller matrices + if (num_rows(A) < 2 || num_cols(A) < 2 || num_cols(B) < 2) { + Backup()(A, B, C); + return; + } + + // std::cout << "2x2 unrolling\n"; + if (Assign::init_to_zero) set_to_zero(C); + + typedef typename MatrixC::size_type size_type; + typedef typename MatrixC::value_type value_type; + + const size_type Tiling1= 2, Tiling2= 2; + const value_type z= math::zero(C[0][0]); // if this are matrices we need their size + + size_type i_max= num_rows(C), i_block= Tiling1 * (i_max / Tiling1), + k_max= num_cols(C), k_block= Tiling2 * (k_max / Tiling2); + size_t ari= &A(1, 0) - &A(0, 0), // how much is the offset of A's entry increased by incrementing row + aci= &A(0, 1) - &A(0, 0), bri= &B(1, 0) - &B(0, 0), bci= &B(0, 1) - &B(0, 0); + + // C_nw += A_nw * B_nw + for (size_type i= 0; i < i_block; i+= Tiling1) + for (size_type k= 0; k < k_block; k+= Tiling2) { + + value_type tmp00= z, tmp01= z, tmp02= z, tmp03= z; + const typename MatrixA::value_type *begin_a= &A(i, 0), *end_a= begin_a + num_cols(A) * aci; + const typename MatrixB::value_type *begin_b= &B(0, k); + + for (; begin_a != end_a; begin_a+= aci, begin_b+= bri) { + tmp00+= begin_a[ 0 ] * begin_b[ 0 ]; + tmp01+= begin_a[ 0 ] * begin_b[bci]; + tmp02+= begin_a[ari] * begin_b[ 0 ]; + tmp03+= begin_a[ari] * begin_b[bci]; + } + Assign::update(C(i + 0, k + 0), tmp00); + Assign::update(C(i + 0, k + 1), tmp01); + Assign::update(C(i + 1, k + 0), tmp02); + Assign::update(C(i + 1, k + 1), tmp03); + } + + // C_ne += A_n * B_e + for (size_type i= 0; i < i_block; i++) + for (size_type k = k_block; k < k_max; k++) { + value_type tmp00= z; + const typename MatrixA::value_type *begin_a= &A(i, 0), *end_a= begin_a + num_cols(A) * aci; + const typename MatrixB::value_type *begin_b= &B(0, k); + + for (; begin_a != end_a; begin_a+= aci, begin_b+= bri) + tmp00 += *begin_a * *begin_b; + Assign::update(C(i, k), tmp00); + } + + // C_s += A_s * B + for (size_type i= i_block; i < i_max; i++) + for (size_type k = 0; k < k_max; k++) { + value_type tmp00= z; + const typename MatrixA::value_type *begin_a= &A(i, 0), *end_a= begin_a + num_cols(A) * aci; + const typename MatrixB::value_type *begin_b= &B(0, k); + + for (; begin_a != end_a; begin_a+= aci, begin_b+= bri) + tmp00 += *begin_a * *begin_b; + Assign::update(C(i, k), tmp00); + } + } +}; + +template <typename Assign= assign::assign_sum, + typename Backup= gen_dmat_dmat_mult_t<Assign> > +struct gen_tiling_22_dmat_dmat_mult_t +{ + template <typename MatrixA, typename MatrixB, typename MatrixC> + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + gen_tiling_22_dmat_dmat_mult_ft< + MatrixA, MatrixB, MatrixC, Assign, Backup + >()(A, B, C); + } +}; + + + + +// ======================== +// Recursive Multiplication +// ======================== + +namespace wrec { + + template <typename BaseMult, typename BaseTest= recursion::bound_test_static<64> > + struct gen_dmat_dmat_mult_t + { + template <typename RecA, typename RecB, typename RecC> + void operator()(RecA const& rec_a, RecB const& rec_b, RecC& rec_c) + { + vampir_trace<4006> tracer; + // std::cout << "wrec::mult \n"; + using namespace recursion; + // using mtl::mat::is_empty; // ambiguity with std::tr1::is_empty in VS2010 + // Ambiguity with boost::is_empty in Open64 + if (mtl::mat::is_empty(rec_a) || mtl::mat::is_empty(rec_b) || mtl::mat::is_empty(rec_c)) + return; + + if (BaseTest()(rec_a)) { + typename base_case_matrix<typename RecC::matrix_type, BaseTest>::type + C= base_case_cast<BaseTest>(*rec_c); + BaseMult()(base_case_cast<BaseTest>(*rec_a), + base_case_cast<BaseTest>(*rec_b), C); + } else { + RecC c_north_west= north_west(rec_c), c_north_east= north_east(rec_c), + c_south_west= south_west(rec_c), c_south_east= south_east(rec_c); + + (*this)(north_west(rec_a), north_west(rec_b), c_north_west); + (*this)(north_west(rec_a), north_east(rec_b), c_north_east); + (*this)(south_west(rec_a), north_east(rec_b), c_south_east); + (*this)(south_west(rec_a), north_west(rec_b), c_south_west); + (*this)(south_east(rec_a), south_west(rec_b), c_south_west); + (*this)(south_east(rec_a), south_east(rec_b), c_south_east); + (*this)(north_east(rec_a), south_east(rec_b), c_north_east); + (*this)(north_east(rec_a), south_west(rec_b), c_north_west); + } + } + }; + +} // namespace wrec + + +template <typename BaseMult, + typename BaseTest= recursion::bound_test_static<64>, + typename Assign= assign::assign_sum, + typename Backup= gen_dmat_dmat_mult_t<Assign> > +struct gen_recursive_dmat_dmat_mult_t +{ + template <typename MatrixA, typename MatrixB, typename MatrixC> + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + apply(A, B, C, traits::flatcat1<MatrixA, tag::qsub_divisible>(), + traits::flatcat1<MatrixB, tag::qsub_divisible>(), traits::flatcat1<MatrixC, tag::qsub_divisible>()); + } + +private: + // If one matrix is not sub-divisible then take backup function + template <typename MatrixA, typename MatrixB, typename MatrixC> + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, tag::universe, tag::universe, tag::universe) + { + Backup()(A, B, C); + } + + // Only if matrix is sub-divisible, otherwise backup + template <typename MatrixA, typename MatrixB, typename MatrixC> + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, + tag::flat<tag::qsub_divisible>, tag::flat<tag::qsub_divisible>, tag::flat<tag::qsub_divisible>) + { + vampir_trace<4007> tracer; + // std::cout << "do recursion\n"; + if (Assign::init_to_zero) set_to_zero(C); + + // Make sure that mult functor of basecase has appropriate assign mode (in all nestings) + // i.e. replace assign::assign_sum by assign::plus_sum including backup functor + + using mat::recursator; + recursator<MatrixA> rec_a(A); + recursator<MatrixB> rec_b(B); + recursator<MatrixC> rec_c(C); + equalize_depth(rec_a, rec_b, rec_c); + + wrec::gen_dmat_dmat_mult_t<BaseMult, BaseTest>() (rec_a, rec_b, rec_c); + } +}; + + + +// ================================== +// Plattform specific implementations +// ================================== + +// Here only general definition that calls backup function +// Special implementations needed in other files, which are included at the end + +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign= assign::assign_sum, + typename Backup= gen_dmat_dmat_mult_t<Assign> > +struct gen_platform_dmat_dmat_mult_ft + : public Backup +{}; + + +template <typename Assign= assign::assign_sum, + typename Backup= gen_dmat_dmat_mult_t<Assign> > +struct gen_platform_dmat_dmat_mult_t +{ + template <typename MatrixA, typename MatrixB, typename MatrixC> + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + gen_platform_dmat_dmat_mult_ft<MatrixA, MatrixB, MatrixC, Assign, Backup>()(A, B, C); + } +}; + + +// ================================== +// BLAS functions as far as supported +// ================================== + + +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign= assign::assign_sum, + typename Backup= gen_dmat_dmat_mult_t<Assign> > +struct gen_blas_dmat_dmat_mult_ft + : public Backup +{}; + + +#ifdef MTL_HAS_BLAS + +namespace detail { + + // Transform from assign representation to BLAS + double inline dgemm_alpha(assign::assign_sum) { return 1.0; } + double inline dgemm_alpha(assign::plus_sum) { return 1.0; } + double inline dgemm_alpha(assign::minus_sum) { return -1.0; } + + // Transform from assign representation to BLAS + double inline dgemm_beta(assign::assign_sum) { return 0.0; } + double inline dgemm_beta(assign::plus_sum) { return 1.0; } + double inline dgemm_beta(assign::minus_sum) { return 1.0; } + + template <typename Value, typename ParaA, typename ParaB, typename ParaC, typename Function, typename Assign> + void inline xgemm(const dense2D<Value, ParaA>& A, const dense2D<Value, ParaB>& B, + dense2D<Value, ParaC>& C, Function f, Assign) + { + vampir_trace<4008> tracer; + // std::cout << "use generic BLAS\n"; + int m= num_rows(A), n= num_cols(B), k= num_cols(A), lda= A.get_ldim(), ldb= B.get_ldim(), ldc= C.get_ldim(); + Value alpha= dgemm_alpha(Assign()), beta= dgemm_beta(Assign()); + char a_trans= traits::is_row_major<ParaA>::value ? 'T' : 'N', + b_trans= traits::is_row_major<ParaB>::value ? 'T' : 'N'; + + if (traits::is_row_major<ParaC>::value) { + // C^T= B^T * A^T + a_trans= 'T' + 'N' - a_trans; b_trans= 'T' + 'N' - b_trans; + f(&b_trans, &a_trans, &n /* col(B) */, &m /* row(A) */, &k /* col(A)=row(B) */, + &alpha, &B[0][0], &ldb, &A[0][0], &lda, &beta, &C[0][0], &ldc); + } else + f(&a_trans, &b_trans, &m, &n, &k, &alpha, &A[0][0], &lda, &B[0][0], &ldb, &beta, &C[0][0], &ldc); + } + +} // detail + +template<typename ParaA, typename ParaB, typename ParaC, typename Assign, typename Backup> +struct gen_blas_dmat_dmat_mult_ft<dense2D<float, ParaA>, dense2D<float, ParaB>, + dense2D<float, ParaC>, Assign, Backup> +{ + void operator()(const dense2D<float, ParaA>& A, const dense2D<float, ParaB>& B, + dense2D<float, ParaC>& C) + { + detail::xgemm(A, B, C, MTL_BLAS_NAME(sgemm), Assign()); + } +}; + +template<typename ParaA, typename ParaB, typename ParaC, typename Assign, typename Backup> +struct gen_blas_dmat_dmat_mult_ft<dense2D<double, ParaA>, dense2D<double, ParaB>, + dense2D<double, ParaC>, Assign, Backup> +{ + void operator()(const dense2D<double, ParaA>& A, const dense2D<double, ParaB>& B, + dense2D<double, ParaC>& C) + { + detail::xgemm(A, B, C, MTL_BLAS_NAME(dgemm), Assign()); + } +}; + + +template<typename ParaA, typename ParaB, typename ParaC, typename Assign, typename Backup> +struct gen_blas_dmat_dmat_mult_ft<dense2D<std::complex<float>, ParaA>, dense2D<std::complex<float>, ParaB>, + dense2D<std::complex<float>, ParaC>, Assign, Backup> +{ + void operator()(const dense2D<std::complex<float>, ParaA>& A, const dense2D<std::complex<float>, ParaB>& B, + dense2D<std::complex<float>, ParaC>& C) + { + detail::xgemm(A, B, C, MTL_BLAS_NAME(cgemm), Assign()); + } +}; + + +template<typename ParaA, typename ParaB, typename ParaC, typename Assign, typename Backup> +struct gen_blas_dmat_dmat_mult_ft<dense2D<std::complex<double>, ParaA>, dense2D<std::complex<double>, ParaB>, + dense2D<std::complex<double>, ParaC>, Assign, Backup> +{ + void operator()(const dense2D<std::complex<double>, ParaA>& A, const dense2D<std::complex<double>, ParaB>& B, + dense2D<std::complex<double>, ParaC>& C) + { + detail::xgemm(A, B, C, MTL_BLAS_NAME(zgemm), Assign()); + } +}; + + + +#endif // MTL_HAS_BLAS + +template <typename Assign= assign::assign_sum, + typename Backup= gen_dmat_dmat_mult_t<Assign> > +struct gen_blas_dmat_dmat_mult_t + : public Backup +{ + template <typename MatrixA, typename MatrixB, typename MatrixC> + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + gen_blas_dmat_dmat_mult_ft<MatrixA, MatrixB, MatrixC, Assign, Backup>()(A, B, C); + } +}; + + +// ============================================================ +// Switch between two functors depending on minimal matrix size +// ============================================================ + +template <std::size_t SizeLimit, typename FunctorSmall, typename FunctorLarge> +struct size_switch_dmat_dmat_mult_t +{ + template <typename MatrixA, typename MatrixB, typename MatrixC> + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + const bool all_static= traits::is_static<MatrixA>::value && traits::is_static<MatrixB>::value + && traits::is_static<MatrixC>::value; + apply(A, B, C, boost::mpl::bool_<all_static>()); + } + + private: + // Decided at run time + template <typename MatrixA, typename MatrixB, typename MatrixC> + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, boost::mpl::false_) + { + if (mtl::mat::size(A) <= SizeLimit || mtl::mat::size(B) <= SizeLimit || mtl::mat::size(C) <= SizeLimit) + FunctorSmall()(A, B, C); + else + FunctorLarge()(A, B, C); + } + + // Decided at compile time + template <typename MatrixA, typename MatrixB, typename MatrixC> + void apply(MatrixA const& A, MatrixB const& B, MatrixC& C, boost::mpl::true_) + { + const bool is_small= mtl::static_size<MatrixA>::value <= SizeLimit || mtl::static_size<MatrixB>::value <= SizeLimit + || mtl::static_size<MatrixC>::value <= SizeLimit; + typename boost::mpl::if_c<is_small, FunctorSmall, FunctorLarge>::type()(A, B, C); + } +}; + + +// ==================================================================================== +// Switch between two functors depending on whether matrix size is know at compile time +// ==================================================================================== + +template <bool IsStatic, typename FunctorStatic, typename FunctorDynamic> +struct static_switch_dmat_dmat_mult_t +{ + template <typename MatrixA, typename MatrixB, typename MatrixC> + void operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + typename boost::mpl::if_c<IsStatic, FunctorStatic, FunctorDynamic>::type()(A, B, C); + } +}; + +// ============================================================== +// Completely unroll fixed size computations, will be tuned later +// ============================================================== + +template <std::size_t Index0, std::size_t Max0, std::size_t Index1, std::size_t Max1, typename Assign> +struct fully_unroll_dmat_dmat_mult_init_block + : public meta_math::loop2<Index0, Max0, Index1, Max1> +{ + typedef meta_math::loop2<Index0, Max0, Index1, Max1> base; + typedef fully_unroll_dmat_dmat_mult_init_block<base::next_index0, Max0, base::next_index1, Max1, Assign> next_t; + + template <typename MatrixA, typename MatrixB, typename MatrixC> + static inline void apply(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + // Assign::first_update(C[base::index0][base::index1], A[base::index0][0] * B[0][base::index1]); + Assign::first_update(C(base::index0, base::index1), A(base::index0, 0) * B(0, base::index1)); + next_t::apply(A, B, C); + } +}; + +template <std::size_t Max0, std::size_t Max1, typename Assign> +struct fully_unroll_dmat_dmat_mult_init_block<Max0, Max0, Max1, Max1, Assign> + : public meta_math::loop2<Max0, Max0, Max1, Max1> +{ + typedef meta_math::loop2<Max0, Max0, Max1, Max1> base; + + template <typename MatrixA, typename MatrixB, typename MatrixC> + static inline void apply(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + Assign::first_update(C(base::index0, base::index1), A(base::index0, 0) * B(0, base::index1)); + } +}; + + +template <std::size_t Index0, std::size_t Max0, std::size_t Index1, std::size_t Max1, + std::size_t Index2, std::size_t Max2, typename Assign> +struct fully_unroll_dmat_dmat_mult_block + : public meta_math::loop3<Index0, Max0, Index1, Max1, Index2, Max2> +{ + typedef meta_math::loop3<Index0, Max0, Index1, Max1, Index2, Max2> base; + typedef fully_unroll_dmat_dmat_mult_block<base::next_index0, Max0, base::next_index1, Max1, base::next_index2, Max2, Assign> next_t; + + template <typename MatrixA, typename MatrixB, typename MatrixC> + static inline void apply(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + Assign::update(C(base::index1, base::index2), A(base::index1, base::index0) * B(base::index0, base::index2)); + next_t::apply(A, B, C); + } +}; + +template <std::size_t Max0, std::size_t Max1, std::size_t Max2, typename Assign> +struct fully_unroll_dmat_dmat_mult_block<Max0, Max0, Max1, Max1, Max2, Max2, Assign> + : public meta_math::loop3<Max0, Max0, Max1, Max1, Max2, Max2> +{ + typedef meta_math::loop3<Max0, Max0, Max1, Max1, Max2, Max2> base; + + template <typename MatrixA, typename MatrixB, typename MatrixC> + static inline void apply(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + Assign::update(C(base::index1, base::index2), A(base::index1, base::index0) * B(base::index0, base::index2)); + } +}; + +template <typename Assign= assign::assign_sum, + typename Backup= gen_dmat_dmat_mult_t<Assign> > +struct fully_unroll_fixed_size_dmat_dmat_mult_t +{ + // if C is empty just do nothing + template <typename MatrixA, typename MatrixB, typename MatrixC> + typename boost::enable_if_c<static_size<MatrixC>::value == 0>::type + operator()(MatrixA const&, MatrixB const&, MatrixC&) {} + + // just initialize + template <typename MatrixA, typename MatrixB, typename MatrixC> + typename boost::enable_if_c<static_num_cols<MatrixA>::value == 0 && static_size<MatrixC>::value != 0>::type + operator()(MatrixA const&, MatrixB const&, MatrixC& C) { if (Assign::init_to_zero) set_to_zero(C); } + + struct noop + { + template <typename MatrixA, typename MatrixB, typename MatrixC> + static inline void apply(MatrixA const&, MatrixB const&, MatrixC&) {} + }; + + // really compute + template <typename MatrixA, typename MatrixB, typename MatrixC> + typename boost::enable_if_c<static_size<MatrixA>::value != 0 && static_size<MatrixC>::value != 0>::type + operator()(MatrixA const& A, MatrixB const& B, MatrixC& C) + { + vampir_trace<1002> tracer; + typedef typename static_num_rows<MatrixC>::type size_type; + static const size_type rows_c= static_num_rows<MatrixC>::value, cols_c= static_num_cols<MatrixC>::value, + cols_a= static_num_cols<MatrixA>::value; + // corresponds to C= A[all][0] * B[0][all]; + fully_unroll_dmat_dmat_mult_init_block<1, rows_c, 1, cols_c, Assign>::apply(A, B, C); + + // corresponds to C+= A[all][1:] * B[1:][all]; if necessary + typedef fully_unroll_dmat_dmat_mult_block<2, cols_a, 1, rows_c, 1, cols_c, Assign> f2; + typedef typename boost::mpl::if_c<(cols_a > 1), f2, noop>::type f3; + f3::apply(A, B, C); + } +}; + + +} // namespace mtl + +#endif // MTL_DMAT_DMAT_MULT_INCLUDE + +// Include plattform specific implementations +#include <boost/numeric/mtl/operation/opteron/matrix_mult.hpp> + diff --git a/install/MTL/include/boost/numeric/mtl/operation/dot.hpp b/install/MTL/include/boost/numeric/mtl/operation/dot.hpp new file mode 100644 index 00000000..5adac719 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/dot.hpp @@ -0,0 +1,268 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_DOT_INCLUDE +#define MTL_DOT_INCLUDE + + +#include <boost/numeric/mtl/concept/std_concept.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/conj.hpp> +#include <boost/numeric/meta_math/loop1.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/mtl/utility/omp_size_type.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> + +namespace mtl { + + namespace vec { + + namespace detail { + + // Result type of dot product + template <typename Vector1, typename Vector2> + struct dot_result + { + typedef typename Multiplicable<typename Collection<Vector1>::value_type, + typename Collection<Vector2>::value_type>::result_type type; + }; + + // Whether or not conjugating first argument + struct without_conj + { + template <typename Value> + Value operator()(const Value& v) { return v; } + }; + + struct with_conj + { + template <typename Value> + typename mtl::sfunctor::conj<Value>::result_type + operator() (const Value& v) + { + using mtl::conj; + return conj(v); + } + }; + } + + namespace sfunctor { + + template <unsigned long Index0, unsigned long Max0> + struct dot_aux + : public meta_math::loop1<Index0, Max0> + { + typedef meta_math::loop1<Index0, Max0> base; + typedef dot_aux<base::next_index0, Max0> next_t; + + template <typename Value, typename Vector1, typename Vector2, typename Size, typename ConjOpt> + static inline void + apply(Value& tmp00, Value& tmp01, Value& tmp02, Value& tmp03, Value& tmp04, + Value& tmp05, Value& tmp06, Value& tmp07, + const Vector1& v1, const Vector2& v2, Size i, ConjOpt conj_opt) + { + // vampir_trace<9901> tracer; + tmp00+= conj_opt(v1[ i + base::index0 ]) * v2[ i + base::index0 ]; + next_t::apply(tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, tmp00, + v1, v2, i, conj_opt); + } + }; + + + template <unsigned long Max0> + struct dot_aux<Max0, Max0> + { + typedef meta_math::loop1<Max0, Max0> base; + + template <typename Value, typename Vector1, typename Vector2, typename Size, typename ConjOpt> + static inline void + apply(Value& tmp00, Value&, Value&, Value&, Value&, Value&, Value&, Value&, + const Vector1& v1, const Vector2& v2, Size i, ConjOpt conj_opt) + { + tmp00+= conj_opt(v1[ i + base::index0 ]) * v2[ i + base::index0 ]; + } + }; + + + template <unsigned long Unroll> + struct dot + { + template <typename Vector1, typename Vector2, typename ConjOpt> + typename detail::dot_result<Vector1, Vector2>::type + static inline apply(const Vector1& v1, const Vector2& v2, ConjOpt conj_opt) + { + MTL_STATIC_ASSERT((Unroll >= 1), "Unroll size must be at least 1."); + // MTL_STATIC_ASSERT((Unroll <= 8), "Maximal unrolling is 8."); // Might be relaxed in future versions + + vampir_trace<2003> tracer; + MTL_THROW_IF(mtl::size(v1) != mtl::size(v2), incompatible_size()); + typedef typename detail::dot_result<Vector1, Vector2>::type value_type; + +# ifdef MTL_WITH_OPENMP + value_type dummy, z= math::zero(dummy), result= z; + typedef typename mtl::traits::omp_size_type<typename Collection<Vector1>::size_type>::type size_type; + size_type i_max= mtl::size(v1), i_block= Unroll * (i_max / Unroll); + + + #pragma omp parallel + { + + vampir_trace<8001> tracer; + value_type tmp00= z, tmp01= z, tmp02= z, tmp03= z, tmp04= z, tmp05= z, tmp06= z, tmp07= z; + + #pragma omp for + for (size_type i= 0; i < i_block; i+= Unroll) + dot_aux<1, Unroll>::apply(tmp00, tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, v1, v2, i, conj_opt); + + #pragma omp critical + result+= ((tmp00 + tmp01) + (tmp02 + tmp03)) + ((tmp04 + tmp05) + (tmp06 + tmp07)); + } + for (size_type i= i_block; i < i_max; i++) + result+= conj_opt(v1[i]) * v2[i]; + + return result; +# else + typedef typename Collection<Vector1>::size_type size_type; + + value_type dummy, z= math::zero(dummy), tmp00= z, tmp01= z, tmp02= z, tmp03= z, tmp04= z, + tmp05= z, tmp06= z, tmp07= z; + size_type i_max= mtl::size(v1), i_block= Unroll * (i_max / Unroll); + + for (size_type i= 0; i < i_block; i+= Unroll) + dot_aux<1, Unroll>::apply(tmp00, tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, v1, v2, i, conj_opt); + + for (size_type i= i_block; i < i_max; i++) + tmp00+= conj_opt(v1[i]) * v2[i]; + return ((tmp00 + tmp01) + (tmp02 + tmp03)) + ((tmp04 + tmp05) + (tmp06 + tmp07)); +# endif + } + + + }; + } + + template <typename Vector1, typename Vector2, typename ConjOpt> + typename detail::dot_result<Vector1, Vector2>::type + inline dot_simple(const Vector1& v1, const Vector2& v2, ConjOpt conj_opt) + { + vampir_trace<2040> tracer; + typedef typename Collection<Vector1>::size_type size_type; + typedef typename detail::dot_result<Vector1, Vector2>::type value_type; + + value_type dummy, s= math::zero(dummy); + for (size_type i= 0, i_max= mtl::size(v1); i < i_max; ++i) + s+= conj_opt(v1[i]) * v2[i]; + return s; + } + + template <unsigned long Unroll, typename Vector1, typename Vector2, typename ConjOpt> + struct dot_class + { + typedef typename detail::dot_result<Vector1, Vector2>::type result_type; + dot_class(const Vector1& v1, const Vector2& v2) : v1(v1), v2(v2) {} + + operator result_type() const { return sfunctor::dot<Unroll>::apply(v1, v2, ConjOpt()); } + + const Vector1& v1; + const Vector2& v2; + }; + + template <typename Vector1, typename Vector2, typename ConjOpt> + struct dot_class<1, Vector1, Vector2, ConjOpt> + { + typedef typename detail::dot_result<Vector1, Vector2>::type result_type; + dot_class(const Vector1& v1, const Vector2& v2) : v1(v1), v2(v2) {} + + operator result_type() const { return dot_simple(v1, v2, ConjOpt()); } + + const Vector1& v1; + const Vector2& v2; + }; + + /// Lazy dot product + /** It is automatically evaluated when (implicitly) converted to result_type which doesn't work in template expressions. + Can be used for source-to-source transformations. **/ + template <typename Vector1, typename Vector2> + dot_class<4, Vector1, Vector2, detail::with_conj> + inline lazy_dot(const Vector1& v1, const Vector2& v2) + { + return dot_class<4, Vector1, Vector2, detail::with_conj>(v1, v2); + } + + template <unsigned long Unroll, typename Vector1, typename Vector2> + dot_class<Unroll, Vector1, Vector2, detail::with_conj> + inline lazy_dot(const Vector1& v1, const Vector2& v2) + { + return dot_class<Unroll, Vector1, Vector2, detail::with_conj>(v1, v2); + } + + template <typename Vector1, typename Vector2> + dot_class<4, Vector1, Vector2, detail::without_conj> + inline lazy_dot_real(const Vector1& v1, const Vector2& v2) + { + return dot_class<4, Vector1, Vector2, detail::without_conj>(v1, v2); + } + + template <unsigned long Unroll, typename Vector1, typename Vector2> + dot_class<Unroll, Vector1, Vector2, detail::without_conj> + inline lazy_dot_real(const Vector1& v1, const Vector2& v2) + { + return dot_class<Unroll, Vector1, Vector2, detail::without_conj>(v1, v2); + } + + /// Dot product defined as hermitian(v) * w + /** Unrolled four times by default **/ + template <typename Vector1, typename Vector2> + typename detail::dot_result<Vector1, Vector2>::type + inline dot(const Vector1& v1, const Vector2& v2) + { + // return dot_simple(v1, v2, detail::with_conj()); + return sfunctor::dot<4>::apply(v1, v2, detail::with_conj()); + } + + /// Dot product with user-specified unrolling defined as hermitian(v) * w + template <unsigned long Unroll, typename Vector1, typename Vector2> + typename detail::dot_result<Vector1, Vector2>::type + inline dot(const Vector1& v1, const Vector2& v2) + { + return sfunctor::dot<Unroll>::apply(v1, v2, detail::with_conj()); + } + /// Dot product without conjugate defined as trans(v) * w + /** Unrolled four times by default **/ + template <typename Vector1, typename Vector2> + typename detail::dot_result<Vector1, Vector2>::type + inline dot_real(const Vector1& v1, const Vector2& v2) + { + return sfunctor::dot<4>::apply(v1, v2, detail::without_conj()); + } + + /// Dot product without conjugate with user-specified unrolling defined as trans(v) * w + template <unsigned long Unroll, typename Vector1, typename Vector2> + typename detail::dot_result<Vector1, Vector2>::type + inline dot_real(const Vector1& v1, const Vector2& v2) + { + return sfunctor::dot<Unroll>::apply(v1, v2, detail::without_conj()); + } + + + } // namespace vector + + using vec::dot; + using vec::dot_real; + using vec::lazy_dot; + using vec::lazy_dot_real; + +} // namespace mtl + +#endif // MTL_DOT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/eigenvalue.hpp b/install/MTL/include/boost/numeric/mtl/operation/eigenvalue.hpp new file mode 100644 index 00000000..870c4a8e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/eigenvalue.hpp @@ -0,0 +1,256 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. +// +// Author Marc Hartung + +#ifndef MTL_MATRIX_EIGENVALUE_INCLUDE +#define MTL_MATRIX_EIGENVALUE_INCLUDE + +#include <cmath> +#include <complex> +#include <utility> + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/qr_givens.hpp> +#include <boost/numeric/mtl/operation/misc.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> + +namespace mtl { namespace mat { + + +/// Solver class for general eigenvalues +/** Not yet tested for complex matrices. **/ +template <typename Matrix> +class eigenvalue_solver { + + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + +public: + + /** \brief Constructor needs a sqare-matrix as input + * \param MTL-Matrix type + * + */ + eigenvalue_solver(const Matrix& IN) : ncols(num_cols(IN)), nrows(num_rows(IN)) { + zero= math::zero(IN[0][0]); + one= math::one(IN[0][0]); + R = hessenberg(IN); + I = Matrix(ncols,nrows); + I = one; + + //Standartwert Initialisierung: + + maxIteration = 20*ncols*ncols; + eps = 1.0e-8; + } + + + /** \brief Changes the zero-tolerance + * \param value_type of allowed distance to zero + */ + void setTolerance(value_type in) { + eps = in; + } + + /** \brief Changes the number of allowed iterations + * \param size_type variable of maximum allowed iterations + */ + void setMaxIteration(size_type in) { + maxIteration = in; + } + + /** \brief Starts the calculation of eigenvalues. + */ + void calc() { + value_type singleCont; + std::complex<value_type> compCont; + size_type size, allIt = 0; + for(size_type i=ncols-1;i>0 && i<ncols && allIt<=maxIteration;i--) { + size = i+1; // verkleinert die Matrix-Dimensionen + irange r(0,size); + singleCont = std::abs(R[i][i-1])+1; + compCont = getComplex2x2EW(i) + 1; + while( allIt < maxIteration && std::abs(R[i][i-1])>eps) { + if(isRealEW(i)) { + if(std::abs(R[i][i-1])<singleCont) { //SingleShift + singleCont = std::abs(R[i][i-1]); + singleShift(r); + } + else { //DoubleShift + singleCont = std::abs(R[i][i-1]); + doubleShift(r); + } + allIt++; + } + else { + if(std::abs(compCont-getComplex2x2EW(i))>eps) { + compCont = getComplex2x2EW(i); + doubleShift(r); + allIt++; + } + else { + i--; + break; + } + } + } + } + } + + + /** \brief Returner for the calculated eigenvalues + * + * Before using get_eigenvalues() you have to use calc()! + * \param dense_vector<complex<value_type>> of eigenvalues + */ + dense_vector<std::complex<value_type> > get_eigenvalues() + { + using mtl::conj; + dense_vector<std::complex<double> > res(ncols, 0.0); + size_type i; + for(i=ncols-1;i>0 && i<ncols;i--) { + if(std::abs(R[i][i-1])<eps || isRealEW(i)) { // wenn ein reeller EW + res[i] = R[i][i]; + } + else { // wenn zwei konjungiert komplexe EW + + std::complex<value_type> ews = getComplex2x2EW(i); + res[i-1] = ews; + res[i] = conj(ews); + i--; + } + } + if(i==0) { // zur Vermeidung von Zugriffsfehler + res[0] = R[0][0]; + } + return res; + } + + + +private: + Matrix R, I; + size_type ncols, nrows, maxIteration; + value_type zero, one, eps; + + + bool isRealEW(size_type k) { + if(std::abs(sqrt(square(R[k-1][k-1]+R[k][k])/4.0+R[k-1][k]*R[k][k-1]-R[k-1][k-1]*R[k][k])) >= 0.0) { + return true; + } + return false; + } + + /** \brief Calculates real eigenvalues of a 2x2-matrix defined by col/row k arround the diagonal of the input-matrix + * + * First entry of the pair is the eigenvalue closer to the (kxk)-entry (Wilkinson-shift for single shifting) + */ + std::pair<value_type, value_type> get2x2EW(const size_type k) { + std::pair<value_type, value_type> res; + value_type front, back, comparator; + + front = (R[k-1][k-1]+R[k][k])/2.0; + back = sqrt(square(R[k-1][k-1]+R[k][k])/4.0+R[k-1][k]*R[k][k-1]-R[k-1][k-1]*R[k][k]); + comparator = R[k][k]-front; + + if( std::abs(comparator-back) < std::abs(comparator+back) ) { + res.first = front+back; + res.second = front-back; + } + else { + res.first = front-back; + res.second = front+back; + } + return res; + } + + + /** \brief Calculates a complex eigenvalue of a 2x2-matrix defined by col/row k arround the diagonal of the input-matrix + * + */ + std::complex<value_type> getComplex2x2EW(const size_type k) { + std::complex<value_type> res; + res = square(R[k-1][k-1]+R[k][k])/4.0+R[k-1][k]*R[k][k-1]-R[k-1][k-1]*R[k][k]; + res = sqrt(res); + res += (R[k-1][k-1]+R[k][k])/2.0; + return res; + } + + /** \brief Performes a double shift for submatrix defined by range r + */ + + void doubleShift(irange r) + { + using mtl::conj; + value_type s,t; + + if(isRealEW(r.finish()-1)) { + std::pair<value_type, value_type> ews = get2x2EW(r.finish()-1); + s = ews.first+ews.second; + t = ews.first*ews.second; + } + else { + std::complex<value_type> ew = getComplex2x2EW(r.finish()-1); + s = 2.0*ew.real(); + t = std::abs(ew*conj(ew)); + } + + Matrix RIter(R[r][r]*R[r][r] - s*R[r][r] + t*I[r][r]); + + qr_givens_solver<Matrix> QR(RIter); + QR.setTolerance(eps); + QR.calc(); + + RIter = R[r][r]; + R[r][r] = (QR.getQ()) * RIter * trans(QR.getQ()); + + } + + + + /** \brief Performes a single shift for submatrix defined by range r + */ + void singleShift(irange r) { + value_type sh = get2x2EW(r.finish()-1).first; + if(!(std::abs(sh) >= 0.0)) { + sh = R[r.finish()-1][r.finish()-1]; + } + Matrix RIter(R[r][r] - sh*I[r][r]); //Shift wird abgezogen + + qr_givens_solver<Matrix> QR(RIter); //QR-Zerlegung + QR.setTolerance(eps); + QR.calc(); + + R[r][r] = ((QR.getR())*trans(QR.getQ())) + sh*I[r][r]; //QR-Iteration mit dem Rückshift + + } + +}; + +/// Calculation of eigenvalues of general matrix A +/** Not yet tested for complex matrices. **/ +template <typename Matrix> +dense_vector<std::complex<typename Collection<Matrix>::value_type> > +inline eigenvalues(const Matrix& A) +{ + eigenvalue_solver<Matrix> s(A); + s.calc(); + return s.get_eigenvalues(); +} + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_EIGENVALUE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/eigenvalue_symmetric.hpp b/install/MTL/include/boost/numeric/mtl/operation/eigenvalue_symmetric.hpp new file mode 100644 index 00000000..49a332d9 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/eigenvalue_symmetric.hpp @@ -0,0 +1,177 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// With contributions from Cornelius Steinhardt + +#ifndef MTL_MATRIX_EIGENVALUE_SYMMETRIC_INCLUDE +#define MTL_MATRIX_EIGENVALUE_SYMMETRIC_INCLUDE + +#include <cmath> +#include <boost/utility.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/make_copy_or_reference.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/concept/magnitude.hpp> +#include <boost/numeric/mtl/operation/conj.hpp> +#include <boost/numeric/mtl/operation/diagonal.hpp> +#include <boost/numeric/mtl/operation/givens.hpp> +#include <boost/numeric/mtl/operation/hessenberg.hpp> +#include <boost/numeric/mtl/operation/householder.hpp> +#include <boost/numeric/mtl/operation/qr.hpp> +#include <boost/numeric/mtl/operation/rank_one_update.hpp> +#include <boost/numeric/mtl/operation/signum.hpp> +#include <boost/numeric/mtl/operation/trans.hpp> + +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> +#include <boost/numeric/mtl/matrix/dense2D.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace mat { + + +/// Eigenvalues of symmetric matrix A with implicit QR algorithm +// Return Diagonalmatrix with eigenvalues as diag(A) +template <typename Matrix> +mtl::vec::dense_vector<typename Collection<Matrix>::value_type, mtl::vec::parameters<> > +inline qr_sym_imp(const Matrix& A) +{ + vampir_trace<5010> tracer; + using std::abs; using mtl::signum; using mtl::real; + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Magnitude<value_type>::type magnitude_type; // to multiply with 2 not 2+0i + typedef typename Collection<Matrix>::size_type size_type; + size_type ncols = num_cols(A), nrows = num_rows(A), N; + value_type zero= math::zero(A[0][0]), h00, h10, h11, beta, mu, a, b, tol; + const magnitude_type two(2); + Matrix Q(nrows,ncols), H(nrows,ncols), G(2,2); + + tol= 1.0e-8; // ????evtl ein Iterator wie bei den Gleichungssystemen, Problem: Keine Rechte Seite bzw b + + MTL_THROW_IF(ncols != nrows , matrix_not_square()); + + // Hessenberg_form of Matrix A + H= hessenberg(A); + N= nrows; + + // QR_algo with implizit sym QR-step from Wilkinson + while (1) { + h00= H[N-2][N-2]; + h10= H[N-1][N-2]; + h11= H[N-1][N-1]; + + //reduction, residuum and watch for breakdown + if(abs(h10) < tol * abs(h11 + h00)) + N--; + if (N < 2) + break; + + // Wilkinson_shift + beta= (h00 - h11) / two; + mu = h11 + (beta != zero ? beta - signum(beta) * sqrt(beta * beta + h10 * h10) : -h10); + a= H[0][0] - mu, b= H[1][0]; + + //implizit QR-step + for (size_type k = 0; k < N - 1; k++) { + givens<Matrix>(H, a, b).trafo(k); + if (k < N - 2) + a= H[k+1][k], b= H[k+2][k]; + } + } + return diagonal(H); +} + + +/// Evaluation of eigenvalues with QR-Algorithm of matrix A +// Return Diagonalmatrix with eigenvalues as diag(A) +template <typename Matrix> +mtl::vec::dense_vector<typename Collection<Matrix>::value_type, mtl::vec::parameters<> > +inline qr_algo(const Matrix& A, typename Collection<Matrix>::size_type itMax) +{ + vampir_trace<5011> tracer; + typedef typename Collection<Matrix>::size_type size_type; + size_type ncols = num_cols(A), nrows = num_rows(A); + Matrix Q(nrows, ncols), H(nrows, ncols), R(nrows, ncols); + + MTL_THROW_IF(ncols != nrows , matrix_not_square()); + + H= hessenberg(A); + for (size_type i = 0; i < itMax; i++) { + boost::tie(Q, R)= qr_factors(H); + H= R * Q; + } + return diagonal(H); +} + + +# ifdef MTL_SYMMETRIC_EIGENVALUE_WITH_QR + +/// Calculation of eigenvalues of symmetric matrix A +template <typename Matrix> +mtl::vec::dense_vector<typename Collection<Matrix>::value_type, mtl::vec::parameters<> > +inline eigenvalue_symmetric(const Matrix& A, typename Collection<Matrix>::size_type itMax) +{ + return qr_algo(A, itMax == 0 ? num_rows(A) : itMax); +} + +#else + +/// Calculation of eigenvalues of symmetric matrix A +template <typename Matrix> +mtl::vec::dense_vector<typename Collection<Matrix>::value_type, mtl::vec::parameters<> > +inline eigenvalue_symmetric(const Matrix& A, typename Collection<Matrix>::size_type) +{ + typedef dense2D<typename Collection<Matrix>::value_type, parameters<> > arg_type; + make_in_copy_or_reference<arg_type, Matrix> copy_or_ref(A); + return qr_sym_imp(copy_or_ref.value); +} + +#endif + +#if 0 // Too nasty to get it through all warnings :-! + +/// Calculation of eigenvalues of symmetric matrix A +template <typename Matrix> +mtl::vec::dense_vector<typename Collection<Matrix>::value_type, mtl::vec::parameters<> > +inline eigenvalue_symmetric(const Matrix& A, + typename Collection<Matrix>::size_type itMax= 0) +{ + vampir_trace<5012> tracer; +# ifdef MTL_SYMMETRIC_EIGENVALUE_WITH_QR + return qr_algo(A, itMax == 0 ? num_rows(A) : itMax); +# else + itMax= 0; // for not yelling at unused variable + // qr_sym_imp works only with dense matrices of dynamic size, for other types copy + typedef dense2D<typename Collection<Matrix>::value_type> arg_type; + make_in_copy_or_reference<arg_type, Matrix> copy_or_ref(A); + return qr_sym_imp(copy_or_ref.value); +# endif +} + +#endif + +template <typename Matrix> +mtl::vec::dense_vector<typename Collection<Matrix>::value_type, mtl::vec::parameters<> > +inline eigenvalue_symmetric(const Matrix& A) +{ + return eigenvalue_symmetric(A, 0); +} + + +}} // namespace mtl::matrix + + +#endif // MTL_MATRIX_EIGENVALUE_SYMMETRIC_INCLUDE + diff --git a/install/MTL/include/boost/numeric/mtl/operation/element_structure_algorithms.hpp b/install/MTL/include/boost/numeric/mtl/operation/element_structure_algorithms.hpp new file mode 100644 index 00000000..9a72cfc2 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/element_structure_algorithms.hpp @@ -0,0 +1,256 @@ + +#ifndef ELEMENT_STRUCTURE_ALGORITHMS +#define ELEMENT_STRUCTURE_ALGORITHMS + + +#include <boost/numeric/mtl/mtl.hpp> +#include <boost/numeric/mtl/matrix/element.hpp> + +namespace imf { + +// Extracts an artificial element structure from the given sparse matrix. This +// algorithm +template< class Element_struct, class Matrix > +void greedy_extract_element_structure(Element_struct& es, Matrix& M , std::string& output) { + +/******************************************************************************* + * PHASE 1: Generate Artificial 1x1 and kxk Elements + ******************************************************************************/ + + typedef unsigned int usint; + + // Elements + typedef typename Matrix::value_type value_type; + typedef typename Matrix::size_type size_type; + typedef mtl::mat::element<value_type> element_type; + typedef typename element_type::index_type index_type; + typedef typename element_type::matrix_type matrix_type; + // typedef typename element_type::neighbor_iterator neigh_iterator; + +#if 0 + // Sparse matrices + typedef glas::compressed_sparse_structure<glas::row_orientation> sparse_structure; + typedef typename sparse_structure::compressed_index_array_type compressed_index_array_type; + typedef glas::sparse_matrix<value_type, sparse_structure> sparse_type; + + compressed_index_array_type& row_start = glas::compressed_index_array( M ); + typename sparse_structure::index_array_type& col_idx = glas::index_array( M ); + typename sparse_type::value_array_type& values = glas::value_array(M); +#endif + std::vector<size_type> row_start(M.ref_major()); + std::vector<size_type> col_idx(M.ref_minor()); + std::vector<value_type> values(M.data); + + const value_type ZERO = value_type(0); + const usint nb_rows = num_rows( M ); + + // Determine a "suitable" guess for the maximum size of the elements. + double avg_nnz_row = M.nnz(); + double std_dev = 0; + for(usint r = 0; r < nb_rows; ++r) { + std_dev += pow(double(row_start[r+1]-row_start[r]), 2) / double(nb_rows); + } + int max_idx = int(avg_nnz_row + 2*std_dev) + 1; + if( max_idx < 7 ) { + max_idx = 7; + } + + std::cout << "max_idx="<<max_idx<< std::endl; + + std::cout << "nnz="<< M.nnz() << std::endl; + + std::vector<element_type*> elements; + elements.reserve(M.nnz() / max_idx); + + std::vector<int> idx; + idx.reserve(max_idx); + + // Generate the element matrices from the given sparse matrix. + int seq_nbr = 0; + for(usint row = 0; row < nb_rows; ++row) { + for( + usint col_off = row_start[row]; + col_off < row_start[row+1]; + ) { + std::cout<< "row="<< row << "-"<< nb_rows << "\n"; + // We have at most k different indices. + idx.clear(); + idx.push_back(row); + for( + int my_size = 1; + (my_size < max_idx) && (col_off < row_start[row+1]); + ++col_off + ) { + if( col_idx[col_off] != row ) { + idx.push_back( col_idx[col_off] ); + ++my_size; + } + } + std::sort( idx.begin(), idx.end() ); + + // Construct index. + index_type el_index( idx.size() ); + for(usint i = 0; i < idx.size(); ++i) { + el_index(i) = idx[i]; + } + + // Copy values. + const usint n = size(el_index); + matrix_type el_vals(n,n); + el_vals = ZERO; + bool non_zero = false; + for(usint i = 0; i < n; ++i) { + const int lrow = el_index(i); + + // Seek matching indices. + usint k = row_start[lrow]; + usint j = 0; + while( (k < row_start[lrow+1]) && (j < n) ) { + const int diff = el_index(j) - col_idx[k]; + if(diff > 0) { + ++k; + } else if(diff < 0) { + ++j; + } else { + // We found a match. Copy the value. + el_vals( i,j ) = values[k]; + values[k] = ZERO; + non_zero |= (el_vals(i,j) != ZERO); + ++j; + ++k; + } + } + } + + // if the element matrix is non-zero, add it. + if(non_zero) { + element_type* el = new element_type(seq_nbr, el_index, el_vals); + elements.push_back(el); + ++seq_nbr; + } + } + // If the diagonal entry is not included in the sparsity of the matrix, + // it is wise *not* to add an element with a single node. In this + // manner, we will avoid the situation wherein that element is selected, + // and the matrix is zero at this position, but where the elimination of + // a different element (which includes the node of this row as off- + // diagonal element) would make the matrix at this position non-zero + // (and hence invertible). + } + + // Remove unnecessary nodes. + for(usint i = 0; i < elements.size(); ++i) { + element_type& el = *(elements[i]); + index_type& idx = el.get_indices(); + matrix_type& vals = el.get_values(); + + std::vector<int> remove_nodes; + for(int c = 0; c < el.nb_vars(); ++c) { + bool all_zero = true; + for(int k = 0; k < el.nb_vars(); ++k) { + all_zero &= ( (vals(k,c) == ZERO) && (vals(c,k) == ZERO) ); + } + if(all_zero) { + remove_nodes.push_back( idx(c) ); + } + } + el.remove_nodes(remove_nodes, el); + } + + // Generate neighbourhood information. + std::vector<int>* node_element_map = new std::vector<int>[nb_rows]; + for( usint i = 0; i < elements.size(); ++i ) { + element_type& el = *(elements[i]); + index_type& idx = el.get_indices(); + for(int j = 0; j < el.nb_vars(); ++j) { + node_element_map[ idx(j) ].push_back(el.get_id()); + } + } + // Construct neighbourhood set for every element. + for( usint i = 0; i < elements.size(); ++i ) { + element_type& el = *(elements[i]); + index_type& idx = el.get_indices(); + std::set<int> neighs; + for(int j = 0; j < el.nb_vars(); ++j) { + neighs.insert( + node_element_map[ idx(j) ].begin(), + node_element_map[ idx(j) ].end() + ); + } + // An element shouldn't neighbour itself. + neighs.erase( el.get_id() ); + for( + std::set<int>::iterator it = neighs.begin(); + it != neighs.end(); + ++it + ) { + el.get_neighbors().push_back( elements[*it] ); + } + } + delete[] node_element_map; + +/******************************************************************************* + * PHASE 3: Construct Grid + ******************************************************************************/ + const int orig_els = elements.size(); + element_type* elems = new element_type[ elements.size() ]; + + // Map the location of the new elements. + std::vector<int> seq_nbr_map( orig_els, -1 ); + for(usint i = 0; i < elements.size(); ++i) { + seq_nbr_map[ elements[i]->get_id() ] = i; + } + + // Construct the element set. + for(usint i = 0; i < elements.size(); ++i) { + // Copy the element to the grid. + elems[i] = *(elements[i]); + element_type& el = elems[i]; + el.get_id() = i; + + typename element_type::neighbor_collection_type& neighs = + el.get_neighbors(); + for( usint j = 0; j < neighs.size(); ++j ) { + // Remap the neighbour pointer to the new location. + int offset = seq_nbr_map[neighs[j]->get_id()]; + neighs[j] = elems + offset; + + assert( offset >= 0 ); + } + + // Clear the data of the copy. + elements[i]->clear(); + } +#if 0 +#ifndef NDEBUG +#if VERBOSE_MODE > 10 + std::cout << "The elements in the algebraic grid: " << std::endl; + for(usint i = 0; i < elements.size(); ++i) { + std::cout << elems[i] << std::endl; + } +#endif +#endif +#endif + + es.consume(orig_els, nb_rows, elems); +#if 0 + element_structure<value_type>* es = new element_structure<value_type>( + orig_els, nb_rows, elems + ); +#endif + // Delete the copied elements. + for(usint i = 0; i < elements.size(); ++i) { + assert( elements[i] ); + delete elements[i]; + } + elements.clear(); + + std::cout << "Generated " << orig_els << " artificial elements." << + std::endl; + es.write_to_file(output); +// return es; +} + +} // end namespace imf + +#endif /* ELEMENT_STRUCTURE_ALGORITHMS */ diff --git a/install/MTL/include/boost/numeric/mtl/operation/entry1D.hpp b/install/MTL/include/boost/numeric/mtl/operation/entry1D.hpp new file mode 100644 index 00000000..9b4e9d39 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/entry1D.hpp @@ -0,0 +1,55 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ENTRY1D_INCLUDE +#define MTL_ENTRY1D_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/matrix/multi_vector.hpp> + +namespace mtl { + + namespace vec { + + template <typename Vector> + inline typename Collection<Vector>::value_type const& + entry1D(const Vector& v, typename Collection<Vector>::size_type i) + { + return v[i]; + } + + template <typename Vector> + inline typename Collection<Vector>::value_type& + entry1D(Vector& v, typename Collection<Vector>::size_type i) + { + return v[i]; + } + } + + namespace mat { + + template <typename Vector> + inline Vector& entry1D(multi_vector<Vector>& A, typename Collection<Vector>::size_type i) + { + return A.vector(i); + } + + template <typename Vector> + inline Vector const& entry1D(const multi_vector<Vector>& A, typename Collection<Vector>::size_type i) + { + return A.vector(i); + } + } + +} // namespace mtl + +#endif // MTL_ENTRY1D_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/entry_similar.hpp b/install/MTL/include/boost/numeric/mtl/operation/entry_similar.hpp new file mode 100644 index 00000000..723fdb33 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/entry_similar.hpp @@ -0,0 +1,70 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ENTRY_SIMILAR_INCLUDE +#define MTL_ENTRY_SIMILAR_INCLUDE + + + +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> + + +namespace mtl { + + namespace mat { + + template <typename Matrix, typename Value> + bool inline entry_similar(const Matrix& A, typename Collection<Matrix>::size_type i, + typename Collection<Matrix>::size_type j, const Value& v, const Value& eps, tag::universe) + { + using std::abs; + return abs(A[i][j] - v) <= eps; + } + + /// Compares A[i][j] with \p v returns false if larger than eps + /** Function works on distributed matrices where only one process tests and the other return true. + The functions enables writing tests that work in parallel (and all other platforms). **/ + template <typename Matrix, typename Value> + bool inline entry_similar(const Matrix& A, typename Collection<Matrix>::size_type i, + typename Collection<Matrix>::size_type j, const Value& v, const Value& eps) + { + return entry_similar(A, i, j, v, eps, typename mtl::traits::category<Matrix>::type()); + } + + } // namespacs matrix + + namespace vec { + + template <typename Vector, typename Value> + bool inline entry_similar(const Vector& x, typename Collection<Vector>::size_type i, + const Value& v, const Value& eps, tag::universe) + { + using std::abs; + return abs(x[i] - v) <= eps; + } + + /// Compares x[i] with \p v returns false if larger than eps + /** Function works on distributed matrices where only one process tests and the other return true. + The functions enables writing tests that work in parallel (and all other platforms). **/ + template <typename Vector, typename Value> + bool inline entry_similar(const Vector& x, typename Collection<Vector>::size_type i, + const Value& v, const Value& eps) + { + return entry_similar(x, i, v, eps, typename mtl::traits::category<Vector>::type()); + } + + } + +} // namespace mtl + +#endif // MTL_ENTRY_SIMILAR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/evaluate_lazy.hpp b/install/MTL/include/boost/numeric/mtl/operation/evaluate_lazy.hpp new file mode 100644 index 00000000..c0de078d --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/evaluate_lazy.hpp @@ -0,0 +1,37 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_EVALUATE_LAZY_INCLUDE +#define MTL_EVALUATE_LAZY_INCLUDE + +#include <boost/numeric/mtl/operation/lazy_assign.hpp> +#include <boost/numeric/mtl/vector/lazy_reduction.hpp> + + +namespace mtl { + +/// Overloaded function to evaluate lazy expressions +template <typename T, typename U, typename Assign> +void inline evaluate_lazy(lazy_assign<T, U, Assign>& lazy) +{ + Assign::first_update(lazy.first, lazy.second); +} + +template <typename T, typename Vector, typename Functor, typename Assign> +void inline evaluate_lazy(lazy_assign<T, vec::lazy_reduction<Vector, Functor>, Assign>& lazy) +{ + lazy.first= Functor::post_reduction(vec::reduction<4, Functor, T>::apply(lazy.second.v)); +} + +} // namespace mtl + +#endif // MTL_EVALUATE_LAZY_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/extended_complex.hpp b/install/MTL/include/boost/numeric/mtl/operation/extended_complex.hpp new file mode 100644 index 00000000..2b79001c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/extended_complex.hpp @@ -0,0 +1,206 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_OPERATION_EXTENDED_COMPLEX_INCLUDE +#define MTL_OPERATION_EXTENDED_COMPLEX_INCLUDE + +#include <complex> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_unsigned.hpp> +#include <boost/numeric/mtl/utility/different_non_complex.hpp> +#include <boost/numeric/mtl/utility/extended_complex.hpp> + + +// Now we dare writing in the standard namespace +namespace std { + +// ======== +// Addition +// ======== + +template <typename T, typename U> +typename mtl::traits::extended_complex<T, U>::type // implicit enable_if +inline operator+(const T& x, const complex<U>& y) +{ + typedef typename mtl::traits::extended_complex<T, U>::type type; + return type(x + real(y), imag(y)); +} + +template <typename T, typename U> +typename mtl::traits::extended_complex<T, U>::type // implicit enable_if +inline operator+(const complex<T>& x, const U& y) +{ + typedef typename mtl::traits::extended_complex<T, U>::type type; + return type(real(x) + y, imag(x)); +} + +template <typename T, typename U> +typename mtl::traits::extended_complex<T, U>::type // implicit enable_if +inline operator+(const complex<T>& x, const complex<U>& y) +{ + typedef typename mtl::traits::extended_complex<T, U>::type type; + return type(real(x) + real(y), imag(x) + imag(y)); +} + +// =========== +// Subtraction +// =========== + +namespace detail { + + // To avoid stupid warnings on unary - for unsigned int specialize it + template <typename T> + typename boost::disable_if<boost::is_unsigned<T>, T>::type + inline negate_helper(const T& x) + { return -x; } + + template <typename T> + typename boost::enable_if<boost::is_unsigned<T>, T>::type + inline negate_helper(const T& x) + { return T(0) - x; } +} + +template <typename T, typename U> +typename mtl::traits::extended_complex<T, U>::type // implicit enable_if +inline operator-(const T& x, const complex<U>& y) +{ + typedef typename mtl::traits::extended_complex<T, U>::type type; + return type(x - real(y), detail::negate_helper(imag(y))); // see above for helper +} + +template <typename T, typename U> +typename mtl::traits::extended_complex<T, U>::type // implicit enable_if +inline operator-(const complex<T>& x, const U& y) +{ + typedef typename mtl::traits::extended_complex<T, U>::type type; + return type(real(x) - y, imag(x)); +} + +template <typename T, typename U> +typename mtl::traits::extended_complex<T, U>::type // implicit enable_if +inline operator-(const complex<T>& x, const complex<U>& y) +{ + typedef typename mtl::traits::extended_complex<T, U>::type type; + return type(real(x) - real(y), imag(x) - imag(y)); +} + +// ============== +// Multiplication +// ============== + +template <typename T, typename U> +typename mtl::traits::extended_complex<T, U>::type // implicit enable_if +inline operator*(const T& x, const complex<U>& y) +{ + typedef typename mtl::traits::extended_complex<T, U>::type type; + return type(x * real(y), x * imag(y)); +} + +template <typename T, typename U> +typename mtl::traits::extended_complex<T, U>::type // implicit enable_if +inline operator*(const complex<T>& x, const U& y) +{ + typedef typename mtl::traits::extended_complex<T, U>::type type; + return type(real(x) * y, imag(x) * y); +} + +template <typename T, typename U> +typename mtl::traits::extended_complex<T, U>::type // implicit enable_if +inline operator*(const complex<T>& x, const complex<U>& y) +{ + typedef typename mtl::traits::extended_complex<T, U>::type type; + return type(real(x) * real(y) - imag(x) * imag(y), + real(x) * imag(y) + imag(x) * real(y)); +} + +// ======== +// Division +// ======== +// Not necessarily the most efficient implementations +// Dealing primarily with types + +template <typename T, typename U> +typename mtl::traits::extended_complex<T, U>::type // implicit enable_if +inline operator/(const T& x, const complex<U>& y) +{ + typedef typename mtl::traits::extended_complex<T, U>::type type; + type r(x); + return r/= type(real(y), imag(y)); +} + +template <typename T, typename U> +typename mtl::traits::extended_complex<T, U>::type // implicit enable_if +inline operator/(const complex<T>& x, const U& y) +{ + typedef typename mtl::traits::extended_complex<T, U>::type type; + return type(real(x) / y, imag(x) / y); +} + +template <typename T, typename U> +typename mtl::traits::extended_complex<T, U>::type // implicit enable_if +inline operator/(const complex<T>& x, const complex<U>& y) +{ + typedef typename mtl::traits::extended_complex<T, U>::type type; + type r(real(x), imag(x)); + return r/= type(real(y), imag(y)); +} + + +// ========== +// Comparison +// ========== + +template <typename T, typename U> +typename boost::enable_if<mtl::traits::different_non_complex<T, U>, bool>::type +inline operator==(const complex<T>& x, const U& y) +{ + return real(x) == y && imag(x) == T(0); +} + +template <typename T, typename U> +typename boost::enable_if<mtl::traits::different_non_complex<T, U>, bool>::type +inline operator==(const T& x, const complex<U>& y) +{ + return x == real(y) && imag(y) == T(0); +} + +template <typename T, typename U> +typename boost::enable_if<mtl::traits::different_non_complex<T, U>, bool>::type +inline operator==(const complex<T>& x, const complex<U>& y) +{ + return real(x) == real(y) && imag(x) == imag(y); +} + +template <typename T, typename U> +typename boost::enable_if<mtl::traits::different_non_complex<T, U>, bool>::type +inline operator!=(const complex<T>& x, const U& y) +{ + return real(x) != y || imag(x) != T(0); +} + +template <typename T, typename U> +typename boost::enable_if<mtl::traits::different_non_complex<T, U>, bool>::type +inline operator!=(const T& x, const complex<U>& y) +{ + return x != real(y) || imag(y) != T(0); +} + +template <typename T, typename U> +typename boost::enable_if<mtl::traits::different_non_complex<T, U>, bool>::type +inline operator!=(const complex<T>& x, const complex<U>& y) +{ + return real(x) != real(y) || imag(x) != imag(y); +} + +} // namespace std + +#endif // MTL_OPERATION_EXTENDED_COMPLEX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/fill.hpp b/install/MTL/include/boost/numeric/mtl/operation/fill.hpp new file mode 100644 index 00000000..28a5434c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/fill.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_FILL_INCLUDE +#define MTL_FILL_INCLUDE + +#include <algorithm> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { + +// Sets all values of a matrix +template <class Matrix> +void fill(Matrix& ma, typename Matrix::value_type value) +{ + vampir_trace<3009> tracer; + std::fill(ma.elements(), ma.elements()+ma.num_elements(), value); +} + +// Temporary solution +// will be replaced by sequences and cursors generated by begin<all>(ma) and end<all>(ma) +// Using segmented cursors, matrices with non-contigous element storing can be handled + +} // namespace mtl + +#endif // MTL_FILL_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/frobenius_norm.hpp b/install/MTL/include/boost/numeric/mtl/operation/frobenius_norm.hpp new file mode 100644 index 00000000..c03523f6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/frobenius_norm.hpp @@ -0,0 +1,54 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_FROBENIUS_NORM_INCLUDE +#define MTL_FROBENIUS_NORM_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/operation/max_of_sums.hpp> +#include <boost/numeric/mtl/operation/squared_abs.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace mat { + +/// Frobenius norm, i.e. square root of sum of squares of all entries sqrt(sum_i sum_j(|a[i][j]|^2)) +template <typename Matrix> +typename RealMagnitude<typename Collection<Matrix>::value_type>::type +inline frobenius_norm(const Matrix& matrix) +{ + vampir_trace<3010> tracer; + using std::sqrt; using std::abs; using math::zero; + namespace traits = mtl::traits; + typename traits::const_value<Matrix>::type value(matrix); + + typedef typename Collection<Matrix>::value_type value_type; + typedef typename RealMagnitude<value_type>::type real_type; + real_type ref, sum= zero(ref); + + typedef typename traits::range_generator<tag::major, Matrix>::type cursor_type; + typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type; + + for (cursor_type cursor = begin<tag::major>(matrix), cend = end<tag::major>(matrix); cursor != cend; ++cursor) + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) + sum+= squared_abs(value(*icursor)); + return sqrt(sum); +} + +}} // namespace mtl::matrix + +#endif // MTL_FROBENIUS_NORM_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/fuse.hpp b/install/MTL/include/boost/numeric/mtl/operation/fuse.hpp new file mode 100644 index 00000000..ecc3e93a --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/fuse.hpp @@ -0,0 +1,44 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_FUSE_INCLUDE +#define MTL_FUSE_INCLUDE + +#include <boost/utility/enable_if.hpp> +#include <boost/mpl/and.hpp> + +#include <boost/numeric/mtl/utility/is_lazy.hpp> +#include <boost/numeric/mtl/operation/fused_expr.hpp> + +namespace mtl { + +/// Fuse two lazy expressions (operator notation of fuse) +template <typename T, typename U> +typename boost::enable_if<boost::mpl::and_<traits::is_lazy<T>, traits::is_lazy<U> >, fused_expr<T, U> >::type +operator||(const T& x, const U& y) +{ + return fused_expr<T, U>(const_cast<T&>(x), const_cast<U&>(y)); +} + +/// Fuse two lazy expressions +template <typename T, typename U> +typename boost::enable_if<boost::mpl::and_<traits::is_lazy<T>, traits::is_lazy<U> >, fused_expr<T, U> >::type +fuse(const T& x, const U& y) +{ + return fused_expr<T, U>(const_cast<T&>(x), const_cast<U&>(y)); +} + + + +} // namespace mtl + +#endif // MTL_FUSE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/fused_expr.hpp b/install/MTL/include/boost/numeric/mtl/operation/fused_expr.hpp new file mode 100644 index 00000000..bfe497bb --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/fused_expr.hpp @@ -0,0 +1,153 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_FUSED_EXPR_INCLUDE +#define MTL_FUSED_EXPR_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/mpl/and.hpp> +#include <boost/numeric/mtl/operation/index_evaluator.hpp> +#include <boost/numeric/mtl/utility/index_evaluatable.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { + +/// Expression template for fusing other expression +template <typename T, typename U> +struct fused_expr +{ + typedef boost::mpl::and_<traits::forward_index_evaluatable<T>, traits::forward_index_evaluatable<U> > forward; + typedef boost::mpl::and_<traits::backward_index_evaluatable<T>, traits::backward_index_evaluatable<U> > backward; + + fused_expr(T& first, U& second) + : first(first), second(second), delayed_assign(false) + { + first.delay_assign(); second.delay_assign(); + } + + ~fused_expr() { if (!delayed_assign) eval(forward(), backward()); } + + void delay_assign() const { delayed_assign= true; } + + template <typename TT, typename UU> + void forward_eval_loop(const TT& const_first_eval, const UU& const_second_eval, boost::mpl::false_) + { + vampir_trace<6001> tracer; + // hope there is a more elegant way; copying the arguments causes errors due to double destructor evaluation + TT& first_eval= const_cast<TT&>(const_first_eval); + UU& second_eval= const_cast<UU&>(const_second_eval); + MTL_DEBUG_THROW_IF(mtl::size(first_eval) != mtl::size(second_eval), incompatible_size()); + + for (std::size_t i= 0, s= size(first_eval); i < s; i++) { + first_eval(i); second_eval(i); + } + } + + template <typename TT, typename UU> + void forward_eval_loop(const TT& const_first_eval, const UU& const_second_eval, boost::mpl::true_) + { + vampir_trace<6002> tracer; + // hope there is a more elegant way; copying the arguments causes errors due to double destructor evaluation + TT& first_eval= const_cast<TT&>(const_first_eval); + UU& second_eval= const_cast<UU&>(const_second_eval); + MTL_DEBUG_THROW_IF(mtl::vec::size(first_eval) != mtl::vec::size(second_eval), incompatible_size()); + + const std::size_t s= size(first_eval), sb= s >> 2 << 2; + + for (std::size_t i= 0; i < sb; i+= 4) { + first_eval.template at<0>(i); second_eval.template at<0>(i); + first_eval.template at<1>(i); second_eval.template at<1>(i); + first_eval.template at<2>(i); second_eval.template at<2>(i); + first_eval.template at<3>(i); second_eval.template at<3>(i); + } + + for (std::size_t i= sb; i < s; i++) { + first_eval(i); second_eval(i); + } + } + + // Forward evaluation dominates backward + template <bool B2> + void eval(boost::mpl::true_, boost::mpl::bool_<B2>) + { +#ifdef MTL_LAZY_LOOP_WO_UNROLL + typedef boost::mpl::false_ to_unroll; +#else + typedef boost::mpl::and_<traits::unrolled_index_evaluatable<T>, traits::unrolled_index_evaluatable<U> > to_unroll; +#endif + // Currently lazy evaluation is only available on vector expressions, might change in the future + // std::cout << "Forward evaluation\n"; + forward_eval_loop(index_evaluator(first), index_evaluator(second), to_unroll()); + } + + template <typename TT, typename UU> + void backward_eval_loop(const TT& const_first_eval, const UU& const_second_eval, boost::mpl::false_) + { + vampir_trace<6003> tracer; + // hope there is a more elegant way; copying the arguments causes errors due to double destructor evaluation + TT& first_eval= const_cast<TT&>(const_first_eval); + UU& second_eval= const_cast<UU&>(const_second_eval); + MTL_DEBUG_THROW_IF(mtl::size(first_eval) != mtl::size(second_eval), incompatible_size()); + + for (std::size_t i= size(first_eval); i-- > 0; ) { + // std::cout << "i is " << i << "\n"; + first_eval(i); second_eval(i); + } + } + + template <typename TT, typename UU> + void backward_eval_loop(const TT& const_first_eval, const UU& const_second_eval, boost::mpl::true_) + { + vampir_trace<6004> tracer; + // hope there is a more elegant way; copying the arguments causes errors due to double destructor evaluation + TT& first_eval= const_cast<TT&>(const_first_eval); + UU& second_eval= const_cast<UU&>(const_second_eval); + MTL_DEBUG_THROW_IF(mtl::size(first_eval) != mtl::size(second_eval), incompatible_size()); + + std::size_t s= size(first_eval), i= s-1, m= s % 4; + for (; m; m--) { + // std::cout << "i is " << i << "\n"; + first_eval(i); second_eval(i--); + } + for(long j= i - 3; j >= 0; j-= 4) { + // std::cout << "i is " << j+3 << ".." << j << "\n"; + first_eval.template at<3>(j); second_eval.template at<3>(j); + first_eval.template at<2>(j); second_eval.template at<2>(j); + first_eval.template at<1>(j); second_eval.template at<1>(j); + first_eval.template at<0>(j); second_eval.template at<0>(j); + } + } + + // Backward evaluation if forward isn't possible + void eval(boost::mpl::false_, boost::mpl::true_) + { + // std::cout << "Backward evaluation\n"; + backward_eval_loop(index_evaluator(first), index_evaluator(second), boost::mpl::true_()); + } + + // Sequential evaluation + void eval(boost::mpl::false_, boost::mpl::false_) + { + // std::cout << "Non-fused evaluation\n"; + evaluate_lazy(first); evaluate_lazy(second); + } + + T& first; + U& second; + mutable bool delayed_assign; +}; + + +} // namespace mtl + +#endif // MTL_FUSED_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/fused_index_evaluator.hpp b/install/MTL/include/boost/numeric/mtl/operation/fused_index_evaluator.hpp new file mode 100644 index 00000000..d681d6d5 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/fused_index_evaluator.hpp @@ -0,0 +1,45 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_FUSED_INDEX_EVALUATOR_INCLUDE +#define MTL_FUSED_INDEX_EVALUATOR_INCLUDE + +#include <boost/numeric/mtl/utility/index_evaluator.hpp> + +namespace mtl { namespace vec { + +template <typename T, typename U> +struct fused_index_evaluator +{ + fused_index_evaluator(T& first, U& second) + : first(index_evaluator(first)), second(index_evaluator(second)) {} + + template <unsigned Offset> + void at(std::size_t i) + { + first.template at<Offset>(i); + second.template at<Offset>(i); + } + + void operator() (std::size_t i) { at<0>(i); } + void operator[] (std::size_t i) { at<0>(i); } + + typename traits::index_evaluator<T>::type first; + typename traits::index_evaluator<U>::type second; +}; + +template <typename T, typename U> +inline size_t size(const fused_index_evaluator<T, U>& expr) { return size(expr.first); } + +}} // namespace mtl::vector + +#endif // MTL_FUSED_INDEX_EVALUATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/givens.hpp b/install/MTL/include/boost/numeric/mtl/operation/givens.hpp new file mode 100644 index 00000000..b233cbf5 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/givens.hpp @@ -0,0 +1,129 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// With contributions from Cornelius Steinhardt + +#ifndef MTL_MATRIX_GIVENS_INCLUDE +#define MTL_MATRIX_GIVENS_INCLUDE + +#include <cmath> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/householder.hpp> +#include <boost/numeric/mtl/operation/rank_one_update.hpp> +#include <boost/numeric/mtl/operation/trans.hpp> + +namespace mtl { namespace mat { + +/// Given's transformator +/** Requires Hessenberg form, i.e. for transformations near the diagonal. + For general form use qr_givens. + \sa qr_givens. **/ +template <typename Matrix> +class givens +{ + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + + public: + /// Re-set the rotation parameters \p a and \p b + void set_rotation(value_type a, value_type b) + { + using std::abs; + value_type zero= math::zero(a), one= math::one(b), t; + + if ( b == zero ) { + c= one; s= zero; + } else if ( abs(b) > abs(a) ) { + t= -a / b; + s= one / sqrt(one + t*t); + c= s * t; + } else { + t= -b / a; + c= one / sqrt(one + t*t); + s= c * t; + } + G= c, s, + -s, c; + } + + + /// Constructor takes %matrix \p H to be transformed and the rotation parameters \p a and \p b + givens(Matrix& H, value_type a, value_type b) : H(H), G(2, 2) + { set_rotation(a, b); } + + /// Given's transformation of \p H with \p G regarding column \p k + Matrix& trafo(const Matrix& G, size_type k) + { + irange r(k,k+2); + // trans(H[r][ind])*= G; H[ind][r]*= G; // most compact form but does not work yet + + Matrix col_block(H[r][iall]), col_perm(trans(G) * col_block); + H[r][iall]= col_perm; + Matrix row_perm(H[iall][r] * G); + H[iall][r]= row_perm; + + return H; + } + + /// Given's transformation of \p H regarding column \p k + Matrix& trafo(size_type k) + { + return trafo(G, k); + } + + private: + Matrix& H, G; + value_type c, s; +}; + +}// namespace matrix + + +namespace vec { + +/// Given's transformator on %vector (swap a*line(k) with b*line(k+1) ) +template <typename Vector> +class givens +{ + typedef typename Collection<Vector>::value_type value_type; + typedef typename Collection<Vector>::size_type size_type; + + public: + /// Constructor takes %vector \p v to be transformed and the rotation parameters \p a and \p b + givens(Vector& v, value_type a, value_type b) : v(v), a(a), b(b) + { } + + /// Given's transformation of \p v with \p a and \p b regarding column \p k + Vector& trafo(size_type k) + { + value_type w1(0), w2(0); + w1= a*v[k] - b*v[k+1]; //given's rotation on solution + w2= b*v[k] + a*v[k+1]; //rotation on vector + v[k]= w1; + v[k+1]= w2; + + return v; + } + + private: + Vector& v; + value_type a, b; +}; + +}// namespace vector + + +} // namespace mtl + +#endif // MTL_MATRIX_GIVENS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/hermitian.hpp b/install/MTL/include/boost/numeric/mtl/operation/hermitian.hpp new file mode 100644 index 00000000..758532a4 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/hermitian.hpp @@ -0,0 +1,58 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_HERMITIAN_INCLUDE +#define MTL_HERMITIAN_INCLUDE + +#include <boost/numeric/mtl/matrix/hermitian_view.hpp> +#include <boost/numeric/mtl/matrix/view_ref.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/utility/view_code.hpp> +#include <boost/numeric/mtl/utility/viewed_collection.hpp> +#include <boost/numeric/mtl/utility/compose_view.hpp> + +namespace mtl { + + // vector version to be done + + namespace mat { + + namespace detail { + + template <typename Matrix> + struct hermitian + { + static const unsigned code= mtl::traits::view_toggle_hermitian<mtl::traits::view_code<Matrix> >::value; + typedef typename mtl::traits::compose_view<code, typename mtl::traits::viewed_collection<Matrix>::type>::type result_type; + + static inline result_type apply(const Matrix& A) + { + return result_type(view_ref(A)); + } + }; + + } // namespace detail + + /// Return hermitian of matrix A + template <typename Matrix> + typename mtl::traits::enable_if_matrix<Matrix, typename detail::hermitian<Matrix>::result_type >::type + inline hermitian(const Matrix& A) + { + return detail::hermitian<Matrix>::apply(A); + } + } + + using mat::hermitian; + +} // namespace mtl + +#endif // MTL_HERMITIAN_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/hessenberg.hpp b/install/MTL/include/boost/numeric/mtl/operation/hessenberg.hpp new file mode 100644 index 00000000..977929e8 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/hessenberg.hpp @@ -0,0 +1,194 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// With contributions from Cornelius Steinhardt + +#ifndef MTL_MATRIX_HESSENBERG_INCLUDE +#define MTL_MATRIX_HESSENBERG_INCLUDE + +#include <cmath> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/concept/magnitude.hpp> +#include <boost/numeric/mtl/operation/householder.hpp> +#include <boost/numeric/mtl/operation/rank_one_update.hpp> +#include <boost/numeric/mtl/operation/trans.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace mat { + +/// Hessenberg-Factorization of matrix A with householder-vectors +/** Return Hessenberg matrix and tril(B,-2) are Householder-vectors **/ +template <typename Matrix> +Matrix inline hessenberg_factors(const Matrix& A) +{ + vampir_trace<5014> tracer; + if (num_rows(A) < 3) + return A; + + using mtl::imax; + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + size_type ncols = num_cols(A), nrows = num_rows(A); + value_type zero= math::zero(A[0][0]), beta; + Matrix B(clone(A)); + + for(size_type i= 0; i < ncols-2; i++){ + // mtl::dense_vector<value_type> v(B[irange(i+1, imax)][i]); + mtl::dense_vector<value_type, vec::parameters<> > v(nrows-i-1), w(nrows); + for (size_type j = 0; j < size(v); j++) + v[j]= B[j+i+1][i]; + beta= householder(v).second; + v= householder(v).first; +; + if( beta != zero){ + w= beta * B[irange(0,imax)][irange(i+1,imax)] * v; + //rank_one_update(B[irange(0,imax)][irange(i+1,imax)],-w,v); + for(size_type row = 0; row < nrows; row++){ + for(size_type col = i+1; col < ncols; col++){ + B[row][col] -= w[row] * v[col-i-1]; + } + } + //vector*Matrix + for(size_type k=0; k < size(w); k++){ + w[k]= zero; + for(size_type j = 0; j < size(v); j++){ + w[k] += beta * v[j] * B[j+i+1][k]; + } + } + //rank_one_update(A[irange(i+1,imax)][irange(0,imax)],-v,w); + for(size_type row = i+1; row < nrows; row++){ + for(size_type col = 0; col < ncols; col++){ + B[row][col] -= v[row-i-1] * w[col]; + } + } + // B[irange(i+2, imax)][i]= v[irange(1, nrows-i-1)]; + for(size_type row = i+2; row < nrows; row++){ + B[row][i] = v[row-i-1]; + } + } + } + return B; +} + + +/// Extract Householder vectors from Hessenberg factorization H of some A +template <typename Matrix> +Matrix inline extract_householder_hessenberg(const Matrix& H) +{ + vampir_trace<5015> tracer; + return Matrix(tril(H, -2)); +} + +/// Compute Householder vectors from Hessenberg factorization of A +template <typename Matrix> +Matrix inline householder_hessenberg(const Matrix& A) +{ + vampir_trace<5016> tracer; + return Matrix(tril(hessenberg_factors(A), -2)); +} + + +/// Extract Hessenberg form from factorization H of some A +template <typename Matrix> +Matrix inline extract_hessenberg(const Matrix& H) +{ + vampir_trace<5017> tracer; + return Matrix(triu(H, -1)); +} + +/// Hessenberg form of A +template <typename Matrix> +Matrix inline hessenberg(const Matrix& A) +{ + vampir_trace<5018> tracer; + // return triu(hessenberg_factors(A), -1); + MTL_THROW_IF(num_rows(A) < 3, matrix_too_small()); + + typedef typename Collection<Matrix>::value_type value_type; + // typedef typename Magnitude<value_type>::type magnitude_type; // to multiply with 2 not 2+0i + typedef typename Collection<Matrix>::size_type size_type; + size_type ncols = num_cols(A), nrows = num_rows(A); + value_type zero= math::zero(A[0][0]); + Matrix H(nrows,ncols); + + H= hessenberg_factors(A); + + // H= bands(hessenberg_factors(A), -nrows, -1); + // set (doubly) strict lower triangle to zero + for(size_type row = 2; row < nrows; row++){ + for(size_type col = 0; col < row-1; col++){ + H[row][col]= zero; + } + } + + return H; +} + + +/// Return Q where Q'*A*Q == hessenberg(A) +template <typename Matrix> +Matrix inline hessenberg_q(const Matrix& A) +{ + vampir_trace<5013> tracer; + using std::abs; + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Magnitude<value_type>::type magnitude_type; // to multiply with 2 not 2+0i + typedef typename Collection<Matrix>::size_type size_type; + size_type ncols = num_cols(A), nrows = num_rows(A), mini; + value_type zero= math::zero(A[0][0]), one= math::one(A[0][0]); + const magnitude_type two(2); + Matrix Q(nrows,ncols); + + MTL_THROW_IF(num_rows(A) < 3, matrix_too_small()); + + Q= one; + + //Extract Q + for(size_type i = 0; i < nrows-2; i++){ + mtl::dense_vector<value_type, parameters<> > v(nrows-1), w(nrows); + v[0]= one; +// std::cout<< "v=" << v << "\n"; +// std::cout<< "w=" << w << "\n"; + for(size_type k = 1; k < size(v); k++) + v[k]= A[nrows-k][i]; + + magnitude_type beta= two / abs(dot(v, v)); // abs: x+0i -> x + if (beta != two) { + //trans(Vector)*Matrix + for(size_type k = 0; k < size(w); k++) { + w[k]= zero; + for(size_type j = 0; j < size(v); j++){ +// std::cout<< "k=" << k << " j=" << j << "\n"; + w[k]+= beta * v[j] * Q[j+i+1][k]; + } + } + //rank_one_update(Q[irange(i+1,imax)][irange(0,imax)],-v,w); + for(size_type row = i+1; row < nrows; row++) + for(size_type col = 0; col < ncols; col++){ +// std::cout<< "row=" << row << " col=" << col << "\n"; + Q[row][col] -= v[row-1] * w[col]; + } + } + } + return Q; +} + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_HESSENBERG_INCLUDE + diff --git a/install/MTL/include/boost/numeric/mtl/operation/householder.hpp b/install/MTL/include/boost/numeric/mtl/operation/householder.hpp new file mode 100644 index 00000000..215118b6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/householder.hpp @@ -0,0 +1,90 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// With contributions from Cornelius Steinhardt + +#ifndef MTL_MATRIX_HOUSEHOLDER_INCLUDE +#define MTL_MATRIX_HOUSEHOLDER_INCLUDE + +#include <cmath> +#include <cassert> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace vec { + + +/// Computes Householder vector v and scalar b for vector \p y +/** such that identity_matrix(size(y))-b*v*v' projects the vector y + to a positive multiple of the first unit vector. **/ +template <typename Vector> +std::pair<typename mtl::vec::dense_vector<typename Collection<Vector>::value_type, parameters<> >, typename Collection<Vector>::value_type> +inline householder(Vector& y) +{ + vampir_trace<2004> tracer; + assert(size(y) > 0); + typedef typename Collection<Vector>::value_type value_type; + // typedef typename Collection<Vector>::size_type size_type; + const value_type zero= math::zero(y[0]), one= math::one(y[0]); + + Vector v(y); + v[0]= one; + irange tail(1, imax); + value_type s( dot(v[tail], v[tail]) ), b, v0; + + //evaluation of v and b + if (s == zero) + b= zero; + else { + value_type mu= sqrt(y[0] * y[0] + s); + v0= v[0]= y[0] <= zero ? y[0] - mu : -s / (y[0] + mu); // complex < zero???? + b= 2 * v0 * v0 / (s + v0 * v0); // 2* complex??????? + v/= v0; // normalization of the first entry + } + + return std::make_pair(v,b); +} + +/// Computes Householder vector for vector \p y +/** More stable Householder transformation, also for non-square matrices. **/ +template <typename Vector> +typename mtl::vec::dense_vector<typename Collection<Vector>::value_type, parameters<> > +inline householder_s(Vector& y) +{ + vampir_trace<2005> tracer; + typedef typename Collection<Vector>::value_type value_type; + const value_type zero= math::zero(y[0]); + + Vector u(y); + value_type nu(sqrt( dot(u, u) )), s; + + if (nu != zero){ + if(u[0] < 0){ + s= -1; + } else { + s= 1; + } + u[0]= u[0] + s * nu; + u/= sqrt( dot(u, u) ); + } + + return u; +} + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_HOUSEHOLDER_INCLUDE + diff --git a/install/MTL/include/boost/numeric/mtl/operation/imag.hpp b/install/MTL/include/boost/numeric/mtl/operation/imag.hpp new file mode 100644 index 00000000..33c56052 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/imag.hpp @@ -0,0 +1,90 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_IMAG_INCLUDE +#define MTL_IMAG_INCLUDE + +#include <complex> +#include <boost/numeric/linear_algebra/identity.hpp> + +namespace mtl { + +namespace sfunctor { + + template <typename Value> + struct imag + { + typedef Value result_type; + + static inline result_type apply(const Value& v) + { + using math::zero; + return zero(v); + } + result_type operator()(const Value& v) const + { + using math::zero; + return zero(v); + } + }; + + template <typename Value> + struct imag<std::complex<Value> > + { + typedef Value result_type; + + static inline result_type apply(const std::complex<Value>& v) + { + return std::imag(v); + } + result_type operator()(const std::complex<Value>& v) const + { + return std::imag(v); + } + }; + +} + +/// Imaginary part of scalars (including non-complex) +template <typename Value> +typename mtl::traits::enable_if_scalar<Value, typename sfunctor::imag<Value>::result_type>::type +inline imag(const Value& v) +{ + return sfunctor::imag<Value>::apply(v); +} + +namespace vec { + + /// Imaginary part of an vector + template <typename Vector> + typename mtl::traits::enable_if_vector<Vector, imag_view<Vector> >::type + inline imag(const Vector& v) + { + return imag_view<Vector>(v); + } +} + +namespace mat { + + /// Imaginary part of an vector + template <typename Matrix> + typename mtl::traits::enable_if_matrix<Matrix, imag_view<Matrix> >::type + inline imag(const Matrix& v) + { + return imag_view<Matrix>(v); + } +} + + +} // namespace mtl + +#endif // MTL_IMAG_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/index_evaluator.hpp b/install/MTL/include/boost/numeric/mtl/operation/index_evaluator.hpp new file mode 100644 index 00000000..da9cdc95 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/index_evaluator.hpp @@ -0,0 +1,94 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_INDEX_EVALUATOR_INCLUDE +#define MTL_INDEX_EVALUATOR_INCLUDE + +#include <boost/utility/enable_if.hpp> +#include <boost/mpl/and.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/operation/lazy_assign.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/vector/vec_vec_aop_expr.hpp> +#include <boost/numeric/mtl/vector/vec_scal_aop_expr.hpp> +#include <boost/numeric/mtl/vector/reduction_index_evaluator.hpp> +#include <boost/numeric/mtl/vector/dot_index_evaluator.hpp> +#include <boost/numeric/mtl/vector/row_mat_cvec_index_evaluator.hpp> +#include <boost/numeric/mtl/operation/fused_index_evaluator.hpp> +#include <boost/numeric/mtl/operation/fused_expr.hpp> +#include <boost/numeric/itl/pc/ic_0.hpp> +#include <boost/numeric/itl/pc/ilu_0.hpp> + +namespace mtl { + +/// Overloaded function that maps from lazy expressions to the according index-wise evaluation classes +template <typename T, typename U, typename Assign> +typename boost::enable_if<boost::mpl::and_<mtl::traits::is_vector<T>, mtl::traits::is_vector<U> >, + mtl::vec::vec_vec_aop_expr<T, U, Assign> >::type +inline index_evaluator(lazy_assign<T, U, Assign>& lazy) +{ + return mtl::vec::vec_vec_aop_expr<T, U, Assign>(lazy.first, lazy.second, true); +} + +template <typename T, typename U, typename Assign> +typename boost::enable_if<boost::mpl::and_<mtl::traits::is_vector<T>, mtl::traits::is_scalar<U> >, + mtl::vec::vec_scal_aop_expr<T, U, Assign> >::type +inline index_evaluator(lazy_assign<T, U, Assign>& lazy) +{ + return mtl::vec::vec_scal_aop_expr<T, U, Assign>(lazy.first, lazy.second, true); +} + +template <typename Scalar, typename Vector, typename Functor, typename Assign> +mtl::vec::reduction_index_evaluator<Scalar, Vector, Functor, Assign> +inline index_evaluator(lazy_assign<Scalar, mtl::vec::lazy_reduction<Vector, Functor>, Assign>& lazy) +{ + return mtl::vec::reduction_index_evaluator<Scalar, Vector, Functor, Assign>(lazy.first, lazy.second.v); +} + +template <typename Scalar, unsigned long Unroll, typename Vector1, + typename Vector2, typename ConjOpt, typename Assign> +mtl::vec::dot_index_evaluator<Scalar, Vector1, Vector2, ConjOpt, Assign> +inline index_evaluator(lazy_assign<Scalar, mtl::vec::dot_class<Unroll, Vector1, Vector2, ConjOpt>, Assign>& lazy) +{ + return mtl::vec::dot_index_evaluator<Scalar, Vector1, Vector2, ConjOpt, Assign>(lazy.first, lazy.second.v1, lazy.second.v2); +} + +template <typename VectorOut, typename Matrix, typename VectorIn, typename Assign> +mtl::vec::row_mat_cvec_index_evaluator<VectorOut, Matrix, VectorIn, Assign> +inline index_evaluator(lazy_assign<VectorOut, mtl::mat_cvec_times_expr<Matrix, VectorIn>, Assign>& lazy) +{ + return mtl::vec::row_mat_cvec_index_evaluator<VectorOut, Matrix, VectorIn, Assign>(lazy.first, lazy.second.first, lazy.second.second); +} + +template <typename V1, typename Matrix, typename Value, typename V2> +itl::pc::ic_0_evaluator<V1, itl::pc::solver<itl::pc::ic_0<Matrix, Value>, V2, true> > +inline index_evaluator(lazy_assign<V1, itl::pc::solver<itl::pc::ic_0<Matrix, Value>, V2, true>, assign::assign_sum>& lazy) +{ + return itl::pc::ic_0_evaluator<V1, itl::pc::solver<itl::pc::ic_0<Matrix, Value>, V2, true> >(lazy.first, lazy.second); +} + +// reuse ic_0_evaluator with ilu_0 preconditioner since IC(0) and ILU(0) do the same at the upper triangle ;-) +template <typename V1, typename Factorizer, typename Matrix, typename Value, typename V2> +itl::pc::ic_0_evaluator<V1, itl::pc::solver<itl::pc::ilu<Matrix, Factorizer, Value>, V2, true> > +inline index_evaluator(lazy_assign<V1, itl::pc::solver<itl::pc::ilu<Matrix, Factorizer, Value>, V2, true>, assign::assign_sum>& lazy) +{ + return itl::pc::ic_0_evaluator<V1, itl::pc::solver<itl::pc::ilu<Matrix, Factorizer, Value>, V2, true> >(lazy.first, lazy.second); +} + +template <typename T, typename U> +inline mtl::vec::fused_index_evaluator<T, U> index_evaluator(fused_expr<T, U>& expr) +{ return mtl::vec::fused_index_evaluator<T, U>(expr.first, expr.second); } + +} // namespace mtl + +#endif // MTL_INDEX_EVALUATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/infinity_norm.hpp b/install/MTL/include/boost/numeric/mtl/operation/infinity_norm.hpp new file mode 100644 index 00000000..e79dae0f --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/infinity_norm.hpp @@ -0,0 +1,98 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_INFINITY_NORM_INCLUDE +#define MTL_INFINITY_NORM_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/concept/magnitude.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/operation/max_of_sums.hpp> +#include <boost/numeric/mtl/vector/lazy_reduction.hpp> +#include <boost/numeric/mtl/vector/reduction.hpp> +#include <boost/numeric/mtl/vector/reduction_functors.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + + namespace vec { + + template <unsigned long Unroll, typename Vector> + typename traits::enable_if_vector<Vector, typename RealMagnitude<typename Collection<Vector>::value_type>::type>::type + inline infinity_norm(const Vector& vector) + { + vampir_trace<2006> tracer; + typedef typename RealMagnitude<typename Collection<Vector>::value_type>::type result_type; + return reduction<Unroll, infinity_norm_functor, result_type>::apply(vector); + } + + /*! Infinity-norm for vectors: infinity_norm(x) \f$\rightarrow |x|_\infty\f$. + \retval The magnitude type of the respective value type, see Magnitude. + + The norms are defined as \f$|v|_\infty=\max_i |v_i|\f$. + + Vector norms are unrolled 8-fold by default. + An n-fold unrolling can be generated with infinity_norm<n>(x). + The maximum for n is 8 (it might be increased later). + **/ + template <typename Vector> + typename mtl::traits::enable_if_vector<Vector, typename RealMagnitude<typename Collection<Vector>::value_type>::type>::type + inline infinity_norm(const Vector& vector) + { + return infinity_norm<8>(vector); + } + + template <typename Vector> + lazy_reduction<Vector, infinity_norm_functor> inline lazy_infinity_norm(const Vector& v) + { return lazy_reduction<Vector, infinity_norm_functor>(v); } + } + + namespace mat { + + // Ignore unrolling for matrices + template <unsigned long Unroll, typename Matrix> + typename mtl::traits::enable_if_matrix<Matrix, typename RealMagnitude<typename Collection<Matrix>::value_type>::type>::type + inline infinity_norm(const Matrix& matrix) + { + vampir_trace<3011> tracer; + using mtl::impl::max_of_sums; + typename mtl::traits::row<Matrix>::type row(matrix); + return max_of_sums(matrix, mtl::traits::is_row_major<typename OrientedCollection<Matrix>::orientation>(), + row, num_rows(matrix)); + } + + /*! Infinity-norm for matrices: infinity_norm(x) \f$\rightarrow |x|_\infty\f$. + \retval The magnitude type of the respective value type, see Magnitude. + + The norms are defined as \f$|A|_\infty=\max_i\{\sum_j(|A_{ij}|)\}\f$. + Matrix norms are not (yet) optimized by unrolling. + **/ + template <typename Matrix> + typename mtl::traits::enable_if_matrix<Matrix, typename RealMagnitude<typename Collection<Matrix>::value_type>::type>::type + inline infinity_norm(const Matrix& matrix) + { + return infinity_norm<8>(matrix); + } + } + + using vec::infinity_norm; + using vec::lazy_infinity_norm; + using mat::infinity_norm; + +} // namespace mtl + +#endif // MTL_INFINITY_NORM_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/inv.hpp b/install/MTL/include/boost/numeric/mtl/operation/inv.hpp new file mode 100644 index 00000000..edb62a0e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/inv.hpp @@ -0,0 +1,171 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_INV_INCLUDE +#define MTL_MATRIX_INV_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/matrix/identity.hpp> +#include <boost/numeric/mtl/operation/upper_trisolve.hpp> +#include <boost/numeric/mtl/operation/lu.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/vector/unit_vector.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace mat { + +namespace traits { + + /// Return type of inv(Matrix) + /** Might be specialized later for the sake of efficiency **/ + template <typename Matrix> + struct inv + { + typedef typename Collection<Matrix>::value_type value_type; + typedef ::mtl::mat::dense2D<value_type> type; + }; + +} // traits + +/// Invert upper triangular matrix +template <typename Matrix, typename MatrixOut> +void inv_upper(Matrix const& A, MatrixOut& Inv) +{ + vampir_trace<5019> tracer; + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + + const size_type N= num_rows(A); + MTL_DEBUG_THROW_IF(num_cols(A) != N, matrix_not_square()); + MTL_DEBUG_THROW_IF(N != num_rows(Inv) || num_cols(A) != num_cols(Inv), incompatible_size()); + + Inv= math::zero(value_type()); + + for (size_type k= 0; k < N; ++k) { + irange r(k+1); + typename mtl::ColumnInMatrix<MatrixOut>::type col_k(Inv[r][k]); + upper_trisolve(A[r][r], vec::unit_vector<value_type>(k, k+1), col_k, mtl::tag::regular_diagonal()); + } +} + + +/// Invert upper triangular matrix +template <typename Matrix> +inline typename traits::inv<Matrix>::type +inv_upper(Matrix const& A) +{ + typedef typename Collection<Matrix>::size_type size_type; + const size_type N= num_rows(A); + typename traits::inv<Matrix>::type Inv(N, N); + inv_upper(A, Inv); + return Inv; +} + +#if 0 +/// Invert lower triangular matrix +template <typename Matrix, typename MatrixOut> +inline void inv_lower(Matrix const& A, MatrixOut& Inv) +{ + vampir_trace<5020> tracer; + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + + const size_type N= num_rows(A); + MTL_DEBUG_THROW_IF(num_cols(A) != N, matrix_not_square()); + MTL_DEBUG_THROW_IF(N != num_rows(Inv) || num_cols(A) != num_cols(Inv), incompatible_size()); + + Inv= math::zero(value_type()); + + for (size_type k= 0; k < N; ++k) { + irange r(k, N); + typename mtl::ColumnInMatrix<MatrixOut>::type col_k(Inv[r][k]); + lower_trisolve(A[r][r], unit_vector<value_type>(0, N-k), col_k, mtl::tag::regular_diagonal()); + } +} + +template <typename Matrix> +typename traits::inv<Matrix>::type +inline inv_lower(Matrix const& A) +{ + typedef typename Collection<Matrix>::size_type size_type; + const size_type N= num_rows(A); + typename traits::inv<Matrix>::type Inv(N, N); + inv_lower(A, Inv); + return Inv; +} +#endif + +#if 1 +/// Invert lower triangular matrix +template <typename Matrix> +typename traits::inv<Matrix>::type +inline inv_lower(Matrix const& A) +{ + vampir_trace<5020> tracer; + Matrix T(trans(A)); // Shouldn't be needed + return typename traits::inv<Matrix>::type(trans(inv_upper(T))); +} +#endif + + + + +/// Invert matrix +/** Uses pivoting LU factorization and triangular inversion + \sa \ref lu, \ref inv_upper, \ref inv_lower **/ +template <typename Matrix, typename MatrixOut> +inline void inv(Matrix const& A, MatrixOut& Inv) +{ + vampir_trace<5021> tracer; + typedef typename Collection<Matrix>::size_type size_type; + typedef typename Collection<Matrix>::value_type value_type; + typedef typename traits::inv<Matrix>::type result_type; + + const size_type N= num_rows(A); + MTL_THROW_IF(num_cols(A) != num_cols(A), matrix_not_square()); + MTL_DEBUG_THROW_IF(N != num_rows(Inv) || num_cols(A) != num_cols(Inv), incompatible_size()); + + if (N == 1) { + Inv[0][0]= value_type(1) / A[0][0]; + return; + } + + result_type PLU(A); + mtl::dense_vector<size_type, vec::parameters<> > Pv(num_rows(A)); + + lu(PLU, Pv); + result_type PU(upper(PLU)), PL(strict_lower(PLU)); + for (size_type i= 0; i < num_rows(A); i++) + PL[i][i]= value_type(1); + + Inv= inv_upper(PU) * inv_lower(PL) * permutation(Pv); +} + +template <typename Matrix> +typename traits::inv<Matrix>::type +inline inv(Matrix const& A) +{ + typedef typename Collection<Matrix>::size_type size_type; + const size_type N= num_rows(A); + typename traits::inv<Matrix>::type Inv(N, N); + inv(A, Inv); + return Inv; +} + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_INV_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/invert_diagonal.hpp b/install/MTL/include/boost/numeric/mtl/operation/invert_diagonal.hpp new file mode 100644 index 00000000..47b50c88 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/invert_diagonal.hpp @@ -0,0 +1,59 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_INVERT_DIAGONAL_INCLUDE +#define MTL_INVERT_DIAGONAL_INCLUDE + +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/linear_algebra/inverse.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace mat { + +///Returns \p A with invert diagonal +template <typename Matrix> +inline void invert_diagonal(Matrix& A) +{ + vampir_trace<3012> tracer; + using math::reciprocal; + namespace traits = mtl::traits; + + typename traits::row<Matrix>::type row(A); + typename traits::col<Matrix>::type col(A); + typename traits::value<Matrix>::type value(A); + + typedef typename traits::range_generator<tag::major, Matrix>::type cursor_type; + typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type; + + for (cursor_type cursor = begin<tag::major>(A), cend = end<tag::major>(A); cursor != cend; ++cursor) + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) + if (row(*icursor) == col(*icursor)) + value(*icursor, reciprocal(value(*icursor))); +} + +// Specialization for compressed2D +template <typename Value, typename Parameters> +inline void invert_diagonal(compressed2D<Value, Parameters>& A) +{ + vampir_trace<3026> tracer; + using math::reciprocal; + for (typename Parameters::size_type i= 0, end= std::min(num_rows(A), num_cols(A)); i < end; i++) + A.lvalue(i, i)= reciprocal(A.lvalue(i, i)); +} + + +}} // namespace mtl::matrix + +#endif // MTL_INVERT_DIAGONAL_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/iota.hpp b/install/MTL/include/boost/numeric/mtl/operation/iota.hpp new file mode 100644 index 00000000..4ec754a4 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/iota.hpp @@ -0,0 +1,32 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_IOTA_INCLUDE +#define MTL_VECTOR_IOTA_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace vec { + +/// Assigns sequentially increasing values to %vector v +template <typename Vector> +void iota(Vector& v, const typename Collection<Vector>::value_type offset= 0) +{ + vampir_trace<3013> tracer; + for (typename Collection<Vector>::size_type i= 0; i < size(v); i++) + v[i]= i + offset; +} + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_IOTA_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/is_negative.hpp b/install/MTL/include/boost/numeric/mtl/operation/is_negative.hpp new file mode 100644 index 00000000..88653b90 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/is_negative.hpp @@ -0,0 +1,31 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_IS_NEGATIVE_INCLUDE +#define MTL_IS_NEGATIVE_INCLUDE + +#include <boost/type_traits/is_unsigned.hpp> +#include <boost/utility/enable_if.hpp> + +namespace mtl { + +template <typename T> +typename boost::enable_if<boost::is_unsigned<T>, bool>::type +inline is_negative(T) { return false; } + +template <typename T> +typename boost::disable_if<boost::is_unsigned<T>, bool>::type +inline is_negative(T x) { return x < 0; } + +} // namespace mtl + +#endif // MTL_IS_NEGATIVE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/lazy.hpp b/install/MTL/include/boost/numeric/mtl/operation/lazy.hpp new file mode 100644 index 00000000..34ece755 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/lazy.hpp @@ -0,0 +1,55 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_LAZY_INCLUDE +#define MTL_LAZY_INCLUDE + +#include <boost/numeric/mtl/operation/assign_mode.hpp> + +namespace mtl { + +/// Helper class for lazy evaluation +template <typename T> +struct lazy_t +{ + lazy_t(T& data) : data(data) {} + + template <typename U> + lazy_assign<T, U, assign::assign_sum> operator=(const U& other) + { return lazy_assign<T, U, assign::assign_sum>(data, other); } + + template <typename U> + lazy_assign<T, U, assign::plus_sum> operator+=(const U& other) + { return lazy_assign<T, U, assign::plus_sum>(data, other); } + + template <typename U> + lazy_assign<T, U, assign::minus_sum> operator-=(const U& other) + { return lazy_assign<T, U, assign::minus_sum>(data, other); } + + T& data; +}; + +/// Do not compute or assign x immediately but delay it until explicitly performed +template <typename T> +inline lazy_t<T> lazy(T& x) +{ return lazy_t<T>(x); } + +/// Do not compute or assign x immediately but delay it until explicitly performed +template <typename T> +inline lazy_t<const T> lazy(const T& x) +{ return lazy_t<const T>(x); } + + + +} // namespace mtl + +#endif // MTL_LAZY_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/lazy_assign.hpp b/install/MTL/include/boost/numeric/mtl/operation/lazy_assign.hpp new file mode 100644 index 00000000..f0173e72 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/lazy_assign.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_LAZY_ASSIGN_INCLUDE +#define MTL_LAZY_ASSIGN_INCLUDE + +namespace mtl { + + +/// Helper class for lazy assignment semantics +template <typename T, typename U, typename Assign> +struct lazy_assign +{ + typedef Assign assign_type; + + lazy_assign(T& first, const U& second) : first(first), second(second) {} + void delay_assign() const {} + + T& first; + const U& second; + +}; + +} // namespace mtl + +#endif // MTL_LAZY_ASSIGN_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/left_scale_inplace.hpp b/install/MTL/include/boost/numeric/mtl/operation/left_scale_inplace.hpp new file mode 100644 index 00000000..e11be9db --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/left_scale_inplace.hpp @@ -0,0 +1,76 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_LEFT_SCALE_INPLACE_INCLUDE +#define MTL_LEFT_SCALE_INPLACE_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/operation/assign_each_nonzero.hpp> +#include <boost/numeric/mtl/operation/mult.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + + namespace impl { + + template <typename Factor, typename Coll> + inline Coll& left_scale_inplace(const Factor& alpha, tag::scalar, Coll& c) + { + vampir_trace<3014> tracer; + assign_each_nonzero(c, tfunctor::scale<Factor, typename Collection<Coll>::value_type>(alpha)); + + return c; + } + + template <typename Factor, typename Collection> + inline Collection& left_scale_inplace(const Factor& alpha, tag::matrix, Collection& c) + { + vampir_trace<3014> tracer; + Collection tmp(alpha * c); + swap(tmp, c); + return c; + } + } + + namespace mat { + + /// Scale matrix \p c from left with scalar or matrix factor \p alpha; \p c is altered + template <typename Factor, typename Matrix> + typename mtl::traits::enable_if_matrix<Matrix, Matrix&>::type + inline left_scale_inplace(const Factor& alpha, Matrix& A) + { + return mtl::impl::left_scale_inplace(alpha, typename mtl::traits::category<Factor>::type(), A); + } + } + + namespace vec { + + /// Scale vector \p c from left with scalar or matrix factor \p alpha; \p c is altered + template <typename Factor, typename Vector> + typename mtl::traits::enable_if_vector<Vector, Vector&>::type + inline left_scale_inplace(const Factor& alpha, Vector& v) + { + return mtl::impl::left_scale_inplace(alpha, typename mtl::traits::category<Factor>::type(), v); + } + } + + using vec::left_scale_inplace; + using mat::left_scale_inplace; + +} // namespace mtl + +#endif // MTL_LEFT_SCALE_INPLACE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/look_at_each_nonzero.hpp b/install/MTL/include/boost/numeric/mtl/operation/look_at_each_nonzero.hpp new file mode 100644 index 00000000..cf251805 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/look_at_each_nonzero.hpp @@ -0,0 +1,96 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_FOR_EACH_NONZERO_INCLUDE +#define MTL_FOR_EACH_NONZERO_INCLUDE + +#include <utility> + +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + + namespace vec { + + /// Perform \p f(v[i]) on each non-zero i in constant vector \p v; thus the must keep the result in its state + template <typename Vector, typename Functor> + inline void look_at_each_nonzero(const Vector& v, Functor& f) + { + vampir_trace<2007> tracer; + typedef typename mtl::traits::range_generator<tag::const_iter::nz, Vector>::type iterator; + for (iterator i= begin<tag::iter::nz>(v), iend= end<tag::iter::nz>(v); i != iend; ++i) + f(*i); + } + + /// Perform \p f(v[i], i) on each non-zero i in constant vector \p v; thus the must keep the result in its state + template <typename Vector, typename Functor> + typename mtl::traits::enable_if_vector<Vector>::type // to be called for vectors only + inline look_at_each_nonzero_pos(const Vector& v, Functor& f) + { + vampir_trace<2008> tracer; + typename mtl::traits::index<Vector>::type index(v); + typename mtl::traits::const_value<Vector>::type value(v); + + typedef typename traits::range_generator<tag::nz, Vector>::type iterator; + for (iterator i= begin<tag::nz>(v), iend= end<tag::nz>(v); i != iend; ++i) + f(value(*i), index(*i)); + } + + } // namespace vector + + namespace mat { + + /// Perform a potentially mutating \p f(A[i][j]) on each non-zero entry in matrix \p A + template <typename Matrix, typename Functor> + inline void look_at_each_nonzero(const Matrix& A, Functor& f) + { + vampir_trace<3016> tracer; + typename mtl::traits::const_value<Matrix>::type value(A); + + typedef typename mtl::traits::range_generator<tag::major, Matrix>::type cursor_type; + typedef typename mtl::traits::range_generator<tag::nz, cursor_type>::type icursor_type; + + for (cursor_type cursor = begin<tag::major>(A), cend = end<tag::major>(A); cursor != cend; ++cursor) + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); + icursor != icend; ++icursor) + f(value(*icursor)); + } + + /// Perform a potentially mutating \p f(A[i][j], make_pair(i, j)) on each non-zero entry in matrix \p A + template <typename Matrix, typename Functor> + typename mtl::traits::enable_if_matrix<Matrix>::type // to be called for matrices only + inline look_at_each_nonzero_pos(const Matrix& A, Functor& f) + { + vampir_trace<3017> tracer; + typename mtl::traits::row<Matrix>::type row(A); + typename mtl::traits::col<Matrix>::type col(A); + typename mtl::traits::const_value<Matrix>::type value(A); + + typedef typename mtl::traits::range_generator<tag::major, Matrix>::type cursor_type; + typedef typename mtl::traits::range_generator<tag::nz, cursor_type>::type icursor_type; + + for (cursor_type cursor = begin<tag::major>(A), cend = end<tag::major>(A); cursor != cend; ++cursor) + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); + icursor != icend; ++icursor) + f(value(*icursor), std::make_pair(row(*icursor), col(*icursor))); + } + + } // namespace matrix + +} // namespace mtl + +#endif // MTL_FOR_EACH_NONZERO_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/lower_trisolve.hpp b/install/MTL/include/boost/numeric/mtl/operation/lower_trisolve.hpp new file mode 100644 index 00000000..a738784b --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/lower_trisolve.hpp @@ -0,0 +1,292 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_LOWER_TRISOLVE_INCLUDE +#define MTL_LOWER_TRISOLVE_INCLUDE + +#include <boost/mpl/int.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> + +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/linear_algebra/inverse.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace mat { + + +namespace detail { + + /// Class that implements lower trisolver + /** DiaTag can be tag::regular_diagonal, tag::unit_diagonal, or tag::inverse_diagonal. + CompactStorage means that matrix contains only lower entries (strict lower when DiaTag == unit_diagonal). \sa \ref trisolve_object **/ + template <typename Matrix, typename DiaTag, bool CompactStorage= false> + struct lower_trisolve_t + { + MTL_STATIC_ASSERT((boost::is_same<DiaTag, tag::regular_diagonal>::value + || boost::is_same<DiaTag, tag::unit_diagonal>::value + || boost::is_same<DiaTag, tag::inverse_diagonal>::value), + "DiaTag must be either tag::regular_diagonal, tag::unit_diagonal, or tag::inverse_diagonal."); + + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + typedef typename OrientedCollection<Matrix>::orientation my_orientation; + typedef typename mtl::traits::category<Matrix>::type my_category; + typedef typename mtl::traits::range_generator<tag::major, Matrix>::type a_cur_type; // row or col depending on Matrix + typedef typename mtl::traits::range_generator<tag::nz, a_cur_type>::type a_icur_type; + + /// Construction from matrix \p A + lower_trisolve_t(const Matrix& A) : A(A), value_a(A), col_a(A), row_a(A) + { MTL_THROW_IF(num_rows(A) != num_cols(A), matrix_not_square()); } + + template <typename M, typename D, bool C> + struct generic_version + : boost::mpl::int_<(mtl::traits::is_row_major<M>::value ? 0 : 2) + + (boost::is_same<D, tag::unit_diagonal>::value ? 1 : 2) + > {}; + + template <typename M, typename D, bool C> + struct version + : generic_version<M, D, C> {}; + + + template <typename Value, typename Para, typename D> + struct version<compressed2D<Value, Para>, D, true> + : boost::mpl::if_<mtl::traits::is_row_major<Para>, + typename boost::mpl::if_<boost::is_same<D, tag::unit_diagonal>, + boost::mpl::int_<5>, + boost::mpl::int_<6> >::type, + generic_version<compressed2D<Value, Para>, D, true> + >::type {}; + + /// Solve \p w = A * \p v + template <typename VectorIn, typename VectorOut> + void operator()(const VectorIn& v, VectorOut& w) const + { vampir_trace<5022> tracer; apply(v, w, version<Matrix, DiaTag, CompactStorage>()); } + + + private: + template <typename Value> + Value inline lower_trisolve_diavalue(const Value& v, tag::regular_diagonal) const + { using math::reciprocal; return reciprocal(v); } + + template <typename Value> + Value lower_trisolve_diavalue(const Value& v, tag::inverse_diagonal) const + { return v; } + + template <typename Tag> int dia_inc(Tag) { return 0; } + int dia_inc(tag::unit_diagonal) { return 1; } + + // Generic row-major unit_diagonal + template <typename VectorIn, typename VectorOut> + void apply(const VectorIn& v, VectorOut& w, boost::mpl::int_<1>) const + { + using namespace tag; + a_cur_type ac= begin<row>(A), aend= end<row>(A); + for (size_type r= 0; ac != aend; ++r, ++ac) { + a_icur_type aic= begin<nz>(ac), aiend= CompactStorage ? end<nz>(ac) : lower_bound<nz>(ac, r); + typename Collection<VectorOut>::value_type rr= v[r]; + for (; aic != aiend; ++aic) { + MTL_DEBUG_THROW_IF(col_a(*aic) >= r, logic_error("Matrix entries must be sorted for this.")); + rr-= value_a(*aic) * w[col_a(*aic)]; + } + w[r]= rr; + } + } + + // Generic row-major not unit_diagonal + template <typename VectorIn, typename VectorOut> + void apply(const VectorIn& v, VectorOut& w, boost::mpl::int_<2>) const + { + using namespace tag; + a_cur_type ac= begin<row>(A), aend= end<row>(A); + for (size_type r= 0; ac != aend; ++r, ++ac) { + a_icur_type aic= begin<nz>(ac), aiend= CompactStorage ? end<nz>(ac) : lower_bound<nz>(ac, r+1); + MTL_THROW_IF(aic == aiend, missing_diagonal()); + --aiend; + MTL_THROW_IF(col_a(*aiend) != r, missing_diagonal()); + + value_type dia= value_a(*aiend); + typename Collection<VectorOut>::value_type rr= v[r]; + + for (; aic != aiend; ++aic) { + MTL_DEBUG_THROW_IF(col_a(*aic) >= r, logic_error("Matrix entries must be sorted for this.")); + rr-= value_a(*aic) * w[col_a(*aic)]; + } + w[r]= rr * lower_trisolve_diavalue(dia, DiaTag()); + } + } + + // Generic column-major unit_diagonal + template <typename VectorIn, typename VectorOut> + void apply(const VectorIn& v, VectorOut& w, boost::mpl::int_<3>) const + { + using namespace tag; + w= v; + a_cur_type ac= begin<col>(A), aend= end<col>(A); + for (size_type r= 0; ac != aend; ++r, ++ac) { + a_icur_type aic= CompactStorage ? begin<nz>(ac) : lower_bound<nz>(ac, r+1), aiend= end<nz>(ac); + typename Collection<VectorOut>::value_type rr= w[r]; + + for (; aic != aiend; ++aic) { + MTL_DEBUG_THROW_IF(row_a(*aic) <= r, logic_error("Matrix entries must be sorted for this.")); + w[row_a(*aic)]-= value_a(*aic) * rr; + } + } + } + + // Generic column-major not unit_diagonal + template <typename VectorIn, typename VectorOut> + void apply(const VectorIn& v, VectorOut& w, boost::mpl::int_<4>) const + { + using namespace tag; + w= v; + a_cur_type ac= begin<col>(A), aend= end<col>(A); + for (size_type r= 0; ac != aend; ++r, ++ac) { + a_icur_type aic= CompactStorage ? begin<nz>(ac) : lower_bound<nz>(ac, r), aiend= end<nz>(ac); + MTL_DEBUG_THROW_IF(aic == aiend || row_a(*aic) != r, missing_diagonal()); + typename Collection<VectorOut>::value_type rr= w[r]*= lower_trisolve_diavalue(value_a(*aic), DiaTag()); + + for (++aic; aic != aiend; ++aic) { + MTL_DEBUG_THROW_IF(row_a(*aic) <= r, logic_error("Matrix entries must be sorted for this.")); + w[row_a(*aic)]-= value_a(*aic) * rr; + } + } + } + + // Tuning for IC_0 and similar using compressed2D row-major compact with implicit unit diagonal + template <typename VectorIn, typename VectorOut> + void apply(const VectorIn& v, VectorOut& w, boost::mpl::int_<5>) const + { + vampir_trace<5048> tracer; + if (num_rows(A) == 0) return; + size_type j1= A.ref_major()[1]; + for (size_type r= 0, rend= num_rows(A); r != rend; ++r) { + size_type j0= j1; + j1= A.ref_major()[r+1]; + typename Collection<VectorOut>::value_type rr= v[r]; + for (; j0 != j1; ++j0) { + MTL_DEBUG_THROW_IF(A.ref_minor()[j0] > r, logic_error("Matrix entries from U in lower triangular.")); + rr-= A.data[j0] * w[A.ref_minor()[j0]]; + } + w[r]= rr; + } + } + + // Tuning for IC_0 and similar using compressed2D row-major compact with explicitly stored diagonal (possibly already inverted) + template <typename VectorIn, typename VectorOut> + void apply(const VectorIn& v, VectorOut& w, boost::mpl::int_<6>) const + { + vampir_trace<5047> tracer; + for (size_type r= 0, rend= num_rows(A); r != rend; ++r) { + size_type j0= A.ref_major()[r], j1= A.ref_major()[r+1]; + MTL_THROW_IF(j0 == j1, missing_diagonal()); + --j1; + MTL_THROW_IF(A.ref_minor()[j1] != r, missing_diagonal()); + value_type dia= A.data[j1]; + typename Collection<VectorOut>::value_type rr= v[r]; + for (; j0 != j1; ++j0) { + MTL_DEBUG_THROW_IF(A.ref_minor()[j0] > r, logic_error("Matrix entries from U in lower triangular.")); + rr-= A.data[j0] * w[A.ref_minor()[j0]]; + } + w[r]= rr * lower_trisolve_diavalue(dia, DiaTag()); + } + } + + const Matrix& A; + typename mtl::traits::const_value<Matrix>::type value_a; + typename mtl::traits::col<Matrix>::type col_a; + typename mtl::traits::row<Matrix>::type row_a; + }; + +} // detail + + +/// Solves the lower triangular matrix A with the rhs v and returns the solution vector +template <typename Matrix, typename Vector> +Vector inline lower_trisolve(const Matrix& A, const Vector& v) +{ + Vector w(resource(v)); + detail::lower_trisolve_t<Matrix, tag::regular_diagonal> solver(A); + solver(v, w); + return w; +} + +/// Solves the lower triangular matrix A with the rhs v +template <typename Matrix, typename VectorIn, typename VectorOut> +inline void lower_trisolve(const Matrix& A, const VectorIn& v, VectorOut& w) +{ + detail::lower_trisolve_t<Matrix, tag::regular_diagonal> solver(A); + solver(v, w); +} + +/// Solves the lower triangular matrix A (only one's in the diagonal) with the rhs v and returns the solution vector +template <typename Matrix, typename Vector> +Vector inline unit_lower_trisolve(const Matrix& A, const Vector& v) +{ + Vector w(resource(v)); + detail::lower_trisolve_t<Matrix, tag::unit_diagonal> solver(A); + solver(v, w); + return w; +} + +/// Solves the lower triangular matrix A (only one's in the diagonal) with the rhs v and returns the solution vector +template <typename Matrix, typename VectorIn, typename VectorOut> +inline void unit_lower_trisolve(const Matrix& A, const VectorIn& v, VectorOut& w) +{ + detail::lower_trisolve_t<Matrix, tag::unit_diagonal> solver(A); + solver(v, w); +} + +/// Solves the lower triangular matrix A (inverse the diagonal) with the rhs v and returns the solution vector +template <typename Matrix, typename Vector> +Vector inline inverse_lower_trisolve(const Matrix& A, const Vector& v) +{ + Vector w(resource(v)); + detail::lower_trisolve_t<Matrix, tag::inverse_diagonal> solver(A); + solver(v, w); + return w; +} + +/// Solves the lower triangular matrix A (inverse the diagonal) with the rhs v and returns the solution vector +template <typename Matrix, typename VectorIn, typename VectorOut> +inline void inverse_lower_trisolve(const Matrix& A, const VectorIn& v, VectorOut& w) +{ + detail::lower_trisolve_t<Matrix, tag::inverse_diagonal> solver(A); + solver(v, w); +} + +template <typename Matrix, typename Vector, typename DiaTag> +Vector inline lower_trisolve(const Matrix& A, const Vector& v, DiaTag) +{ + Vector w(resource(v)); + detail::lower_trisolve_t<Matrix, DiaTag> solver(A); + solver(v, w); + return w; +} + +template <typename Matrix, typename VectorIn, typename VectorOut, typename DiaTag> +inline void lower_trisolve(const Matrix& A, const VectorIn& v, VectorOut& w, DiaTag) +{ + detail::lower_trisolve_t<Matrix, DiaTag> solver(A); + solver(v, w); +} + +}} // namespace mtl::matrix + +#endif // MTL_LOWER_TRISOLVE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/lu.hpp b/install/MTL/include/boost/numeric/mtl/operation/lu.hpp new file mode 100644 index 00000000..ce773687 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/lu.hpp @@ -0,0 +1,241 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// With contributions from Cornelius Steinhardt + +#ifndef MTL_MATRIX_LU_INCLUDE +#define MTL_MATRIX_LU_INCLUDE + +#include <cmath> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/utility/lu_matrix_type.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/matrix/upper.hpp> +#include <boost/numeric/mtl/matrix/lower.hpp> +#include <boost/numeric/mtl/matrix/permutation.hpp> +#include <boost/numeric/mtl/operation/adjoint.hpp> +#include <boost/numeric/mtl/operation/lower_trisolve.hpp> +#include <boost/numeric/mtl/operation/upper_trisolve.hpp> +#include <boost/numeric/mtl/operation/max_pos.hpp> +#include <boost/numeric/mtl/operation/swap_row.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace mat { + +/// LU factorization in place (without pivoting and optimization so far) +/** eps is tolerance for pivot element. If less or equal the matrix is considered singular. + eps is given as double right now, might be refactored to the magnitude type of the value type in the future. **/ +template <typename Matrix> +void inline lu(Matrix& LU, double eps= 0) +{ + vampir_trace<5023> tracer; + using std::abs; + MTL_THROW_IF(num_rows(LU) != num_cols(LU), matrix_not_square()); + + for (std::size_t k= 0; k < num_rows(LU)-1; k++) { + if (abs(LU[k][k]) <= eps) throw matrix_singular(); + irange r(k+1, imax); // Interval [k+1, n-1] + LU[r][k]/= LU[k][k]; + LU[r][r]-= LU[r][k] * LU[k][r]; + } +} + +/// LU factorization in place (with pivoting and without optimization so far) +/** eps is tolerance for pivot element. If less or equal the matrix is considered singular. + eps is given as double right now, might be refactored to the magnitude type of the value type in the future. **/ +template <typename Matrix, typename PermuationVector> +void inline lu(Matrix& A, PermuationVector& P, double eps= 0) +{ + vampir_trace<5024> tracer; + using math::zero; using std::abs; + typedef typename Collection<Matrix>::size_type size_type; + size_type ncols = num_cols(A), nrows = num_rows(A); + + MTL_THROW_IF(ncols != nrows , matrix_not_square()); + P.change_dim(nrows); + + for (size_type i= 0; i < nrows; i++) + P[i]= i; + + for (size_type i= 0; i < nrows-1; i++) { + irange r(i+1, imax), ir(i, i+1); // Intervals [i+1, n-1], [i, i] + size_type rmax= max_abs_pos(A[irange(i, imax)][ir]).first + i; + swap_row(A, i, rmax); + swap_row(P, i, rmax); + + if(abs(A[i][i]) <= eps) throw matrix_singular(); // other gmres test doesn't work + + A[r][i]/= A[i][i]; // Scale column i + A[r][r]-= A[r][i] * A[i][r]; // Decrease bottom right block of matrix + } +} + + +/// LU factorization without factorization that returns the matrix +/** eps is tolerance for pivot element. If less or equal the matrix is considered singular. + eps is given as double right now, might be refactored to the magnitude type of the value type in the future. **/ +template <typename Matrix> +Matrix inline lu_f(const Matrix& A, double eps= 0) +{ + vampir_trace<5025> tracer; + Matrix LU(A); + lu(LU, eps); + return LU; +} + +/// Solve Ax = b by LU factorization without pivoting; vector x is returned +template <typename Matrix, typename Vector> +Vector inline lu_solve_straight(const Matrix& A, const Vector& b, double eps= 0) +{ + vampir_trace<5026> tracer; + Matrix LU(A); + lu(LU, eps); + return upper_trisolve(upper(LU), unit_lower_trisolve(strict_lower(LU), b)); +} + +/// Solve LUx = b by with forward and backward-LU subsitution, lu(LU) was allready done +template <typename Matrix, typename Vector> +Vector inline lu_solve_apply(const Matrix& LU, const Vector& b) +{ + vampir_trace<5026> tracer; + return upper_trisolve(upper(LU), unit_lower_trisolve(strict_lower(LU), b)); +} + +/// Apply the factorization L*U with permutation P on vector b to solve Ax = b +template <typename Matrix, typename PermVector, typename Vector> +Vector inline lu_apply(const Matrix& LU, const PermVector& P, const Vector& b) +{ + vampir_trace<5027> tracer; + return upper_trisolve(upper(LU), unit_lower_trisolve(strict_lower(LU), Vector(mat::permutation(P) * b))); +} + + +/// Solve Ax = b by LU factorization with column pivoting; vector x is returned +template <typename Matrix, typename Vector> +Vector inline lu_solve(const Matrix& A, const Vector& b, double eps= 0) +{ + vampir_trace<5028> tracer; + mtl::dense_vector<std::size_t, vec::parameters<> > P(num_rows(A)); + Matrix LU(A); + + lu(LU, P, eps); + return lu_apply(LU, P, b); +} + + +/// Apply the factorization L*U with permutation P on vector b to solve adjoint(A)x = b +/** That is \f$P^{-1}(LU)^H x = b\f$ --> \f$x= P^{-1}L^{-H} U^{-H} b\f$ where \f$P^{{-1}^{{-1}^H}} = P^{-1}\f$ **/ +template <typename Matrix, typename PermVector, typename Vector> +Vector inline lu_adjoint_apply(const Matrix& LU, const PermVector& P, const Vector& b) +{ + vampir_trace<5029> tracer; + return Vector(trans(mat::permutation(P)) * unit_upper_trisolve(adjoint(LU), lower_trisolve(adjoint(LU), b))); +} + + +/// Solve \f$adjoint(A)x = b\f$ by LU factorization with column pivoting; vector x is returned +template <typename Matrix, typename Vector> +Vector inline lu_adjoint_solve(const Matrix& A, const Vector& b, double eps= 0) +{ + vampir_trace<5030> tracer; + mtl::dense_vector<std::size_t, vec::parameters<> > P(num_rows(A)); + Matrix LU(A); + + lu(LU, P, eps); + return lu_adjoint_apply(LU, P, b); +} + +/// Class that keeps LU factorization (and permutation); using column pivoting +template <typename Matrix> +class lu_solver +{ + typedef typename mtl::traits::lu_matrix_type<Matrix>::type matrix_type; + typedef mtl::vec::dense_vector<std::size_t, mtl::vec::parameters<> > permutation_type; + public: + /// Construct from matrix \p A and use optionally threshold \p eps in factorization + explicit lu_solver(const Matrix& A, double eps= 0) + : LU(A), P(num_rows(A)) + { + lu(LU, P, eps); + } + + /// Solve A*x = b with factorization from constructor + template <typename VectorIn, typename VectorOut> + void solve(const VectorIn& b, VectorOut& x) const + { + x= upper_trisolve(upper(LU), unit_lower_trisolve(strict_lower(LU), VectorIn(mat::permutation(P) * b))); + } + /// Solve \f$adjoint(A)x = b\f$ using LU factorization + template <typename VectorIn, typename VectorOut> + void adjoint_solve(const VectorIn& b, VectorOut& x) const + { + x= trans(mat::permutation(P)) * unit_upper_trisolve(adjoint(LU), lower_trisolve(adjoint(LU), b)); + } + + private: + matrix_type LU; + permutation_type P; +}; + + +}} // namespace mtl::matrix + + + + + + + + + + + + + + + + + +// ### For illustration purposes +#if 0 + +namespace mtl { namespace matrix { + +template <typename Matrix> +void inline lu(Matrix& LU) +{ + MTL_THROW_IF(num_rows(LU) != num_cols(LU), matrix_not_square()); + + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + + size_type n= num_rows(LU); + for (size_type k= 0; k < num_rows(LU); k++) { + value_type pivot= LU[k][k]; + for (size_type j= k+1; j < n; j++) { + value_type alpha= LU[j][k]/= pivot; + for (size_type i= k+1; i < n; i++) + LU[j][i]-= alpha * LU[k][i]; + } + } +} + + + +}} // namespace mtl::matrix + +#endif + +#endif // MTL_MATRIX_LU_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/make_sparse.hpp b/install/MTL/include/boost/numeric/mtl/operation/make_sparse.hpp new file mode 100644 index 00000000..41dfe263 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/make_sparse.hpp @@ -0,0 +1,118 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_MAKE_SPARSE_INCLUDE +#define MTL_VECTOR_MAKE_SPARSE_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/size.hpp> +#include <boost/numeric/mtl/operation/update.hpp> +#include <boost/numeric/mtl/matrix/compressed2D.hpp> +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> + +namespace mtl { namespace vec { + +// Commands in Matlab +// S = sparse(i,j,s,m,n,nzmax) +// S = sparse(i,j,s,m,n) +// S = sparse(i,j,s) +// S = sparse(m,n) + +template <typename SizeVector, typename ValueVector> +struct make_sparse_trait +{ + typedef typename Collection<SizeVector>::value_type size_type; + typedef typename Collection<ValueVector>::value_type value_type; + typedef mat::parameters<row_major, index::c_index, mtl::non_fixed::dimensions, false, size_type> paras; + typedef mat::compressed2D<value_type, paras> type; +}; + +/// Generates an \p m by \p n matrix from the vectors \p rows, \p cols, and \p values. +/** A sparse matrix is created (compressed2D). The value type is the same as the element type + of the value vector and the size type the same as the entries of the vectors with the row indices. + Zero entries in \p values are ignored. Entries with same coordinates are added. + Same as <a href="http://www.mathworks.de/de/help/matlab/ref/sparse.html">Matlab's sparse</a> function besides that it is zero-indexed. + **/ +template <typename SizeVector1, typename SizeVector2, typename ValueVector> +inline typename make_sparse_trait<SizeVector1, ValueVector>::type +make_sparse(const SizeVector1& rows, const SizeVector2& cols, const ValueVector& values, + std::size_t m, std::size_t n) +{ + MTL_THROW_IF(size(rows) != size(cols), incompatible_size()); + MTL_THROW_IF(size(rows) != size(values), incompatible_size()); + + typedef make_sparse_trait<SizeVector1, ValueVector> traits; + typedef typename traits::type matrix_type; + typedef typename traits::value_type value_type; + typedef typename traits::size_type size_type; + + size_type ms(m), ns(n); // shouldn't be needed :-! + matrix_type A(ms, ns); + mat::inserter<matrix_type, update_plus<value_type> > ins(A, size_type(size(rows) / m + 1)); + + for (std::size_t i= 0; i < size(rows); i++) + if (values[i] != value_type(0)) + ins[rows[i]][cols[i]] << values[i]; + return A; +} + +/// Generates an \p m by \p n matrix from the vectors \p rows, \p cols, and \p values. +/** A sparse matrix is created (compressed2D). The value type is the same as the element type + of the value vector and the size type the same as the entries of the vectors with the row indices. + Zero entries in \p values are ignored. Entries with same coordinates are added. Last parameter + is ignored and can be omitted. + Same as <a href="http://www.mathworks.de/de/help/matlab/ref/sparse.html">Matlab's sparse</a> function besides that it is zero-indexed. + **/ +template <typename SizeVector1, typename SizeVector2, typename ValueVector> +inline typename make_sparse_trait<SizeVector1, ValueVector>::type +make_sparse(const SizeVector1& rows, const SizeVector2& cols, const ValueVector& values, + std::size_t m, std::size_t n, std::size_t) +{ + return make_sparse(rows, cols, values, m, n); +} + +/// Generates a matrix from the vectors \p rows, \p cols, and \p values. +/** A sparse matrix is created (compressed2D). + The number of rows/columns is one plus the maximum of the entries of \p rows and \p cols. + The value type is the same as the element type + of the value vector and the size type the same as the entries of the vectors with the row indices. + Zero entries in \p values are ignored. Entries with same coordinates are added. + Same as <a href="http://www.mathworks.de/de/help/matlab/ref/sparse.html">Matlab's sparse</a> function besides that it is zero-indexed. + **/ +template <typename SizeVector1, typename SizeVector2, typename ValueVector> +inline typename make_sparse_trait<SizeVector1, ValueVector>::type +make_sparse(const SizeVector1& rows, const SizeVector2& cols, const ValueVector& values) +{ + return make_sparse(rows, cols, values, max(rows)+1, max(cols)+1); +} + +/// Generates an empty \p m by \p n matrix. +/** A sparse matrix is created (compressed2D<double>). + Same as <a href="http://www.mathworks.de/de/help/matlab/ref/sparse.html">Matlab's sparse</a> function besides that it is zero-indexed. + **/ +inline mat::compressed2D<double> make_sparse(std::size_t m, std::size_t n) +{ + return mat::compressed2D<double>(m, n); +} + + + + + +} // namespace :vector + + using vec::make_sparse; + +} // namespace mtl + +#endif // MTL_VECTOR_MAKE_SPARSE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/make_tag_vector.hpp b/install/MTL/include/boost/numeric/mtl/operation/make_tag_vector.hpp new file mode 100644 index 00000000..7e1552e0 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/make_tag_vector.hpp @@ -0,0 +1,34 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_MAKE_TAG_VECTOR_INCLUDE +#define MTL_MAKE_TAG_VECTOR_INCLUDE + +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/utility/srange.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> + +namespace mtl { + + template <typename Range> + inline dense_vector<bool> + make_tag_vector(std::size_t n, const Range& r) + { + dense_vector<bool> v(n); + for (std::size_t i= 0; i < n; i++) + v[i]= r.in_range(i); + return v; + } + +} // namespace mtl + +#endif // MTL_MAKE_TAG_VECTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/mat_cvec_times_expr.hpp b/install/MTL/include/boost/numeric/mtl/operation/mat_cvec_times_expr.hpp new file mode 100644 index 00000000..732139b2 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/mat_cvec_times_expr.hpp @@ -0,0 +1,46 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAT_CVEC_TIMES_EXPR_INCLUDE +#define MTL_MAT_CVEC_TIMES_EXPR_INCLUDE + +#include <boost/numeric/mtl/operation/bin_op_expr.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/concept/std_concept.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { + +template <typename E1, typename E2> +struct mat_cvec_times_expr + : public bin_op_expr< E1, E2 >, + public mtl::vec::vec_expr< mat_cvec_times_expr<E1, E2> > +{ + typedef bin_op_expr< E1, E2 > base; + typedef mat_cvec_times_expr<E1, E2> self; + + typedef typename Multiplicable<typename Collection<E1>::value_type, + typename Collection<E2>::value_type>::result_type value_type; + typedef typename Collection<E2>::size_type size_type; + + mat_cvec_times_expr( E1 const& matrix, E2 const& vector ) : base(matrix, vector) {} +}; + + namespace vec { + template <typename E1, typename E2> + std::size_t inline size(const mat_cvec_times_expr<E1, E2>& x) + { return num_rows(x.first); } + } + +} // namespace mtl + +#endif // MTL_MAT_CVEC_TIMES_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/mat_vec_mult.hpp b/install/MTL/include/boost/numeric/mtl/operation/mat_vec_mult.hpp new file mode 100644 index 00000000..e7bf3251 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/mat_vec_mult.hpp @@ -0,0 +1,843 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAT_VEC_MULT_INCLUDE +#define MTL_MAT_VEC_MULT_INCLUDE + +#include <cassert> +// #include <iostream> +#include <boost/mpl/bool.hpp> + +#include <boost/numeric/mtl/config.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/is_static.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/utility/multi_tmp.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/utility/omp_size_type.hpp> +#include <boost/numeric/mtl/operation/set_to_zero.hpp> +#include <boost/numeric/mtl/operation/update.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/meta_math/loop.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace mat { + +namespace impl { + + template <std::size_t Index0, std::size_t Max0, std::size_t Index1, std::size_t Max1, typename Assign> + struct fully_unroll_mat_cvec_mult + : public meta_math::loop2<Index0, Max0, Index1, Max1> + { + typedef meta_math::loop2<Index0, Max0, Index1, Max1> base; + typedef fully_unroll_mat_cvec_mult<base::next_index0, Max0, base::next_index1, Max1, Assign> next_t; + + template <typename Matrix, typename VectorIn, typename VectorOut> + static inline void apply(const Matrix& A, const VectorIn& v, VectorOut& w) + { + Assign::update(w[base::index0], A[base::index0][base::index1] * v[base::index1]); + next_t::apply(A, v, w); + } + }; + + // need specialization here for not going back to column 0 but column 1 + template <std::size_t Index0, std::size_t Max0, std::size_t Max1, typename Assign> + struct fully_unroll_mat_cvec_mult<Index0, Max0, Max1, Max1, Assign> + : public meta_math::loop2<Index0, Max0, Max1, Max1> + { + typedef meta_math::loop2<Index0, Max0, Max1, Max1> base; + typedef fully_unroll_mat_cvec_mult<base::next_index0, Max0, 2, Max1, Assign> next_t; + + template <typename Matrix, typename VectorIn, typename VectorOut> + static inline void apply(const Matrix& A, const VectorIn& v, VectorOut& w) + { + Assign::update(w[base::index0], A[base::index0][base::index1] * v[base::index1]); + next_t::apply(A, v, w); + } + }; + + template <std::size_t Max0, std::size_t Max1, typename Assign> + struct fully_unroll_mat_cvec_mult<Max0, Max0, Max1, Max1, Assign> + : public meta_math::loop2<Max0, Max0, Max1, Max1> + { + typedef meta_math::loop2<Max0, Max0, Max1, Max1> base; + + template <typename Matrix, typename VectorIn, typename VectorOut> + static inline void apply(const Matrix& A, const VectorIn& v, VectorOut& w) + { + Assign::update(w[base::index0], A[base::index0][base::index1] * v[base::index1]); + } + }; + + struct noop + { + template <typename Matrix, typename VectorIn, typename VectorOut> + static inline void apply(const Matrix&, const VectorIn&, VectorOut&) {} + }; +} // impl + +// Dense matrix vector multiplication with run-time matrix size +template <typename Matrix, typename VectorIn, typename VectorOut, typename Assign> +inline void dense_mat_cvec_mult(const Matrix& A, const VectorIn& v, VectorOut& w, Assign, boost::mpl::true_) +{ + vampir_trace<3017> tracer; + typedef typename static_num_rows<Matrix>::type size_type; + static const size_type rows_a= static_num_rows<Matrix>::value, cols_a= static_num_cols<Matrix>::value; + + assert(rows_a > 0 && cols_a > 0); + // w= A[all][0] * v[0]; N.B.: 1D is unrolled by the compiler faster (at least on gcc) + for (size_type i= 0; i < rows_a; i++) + Assign::first_update(w[i], A[i][0] * v[0]); + + // corresponds to w+= A[all][1:] * v[1:]; if necessary + typedef impl::fully_unroll_mat_cvec_mult<1, rows_a, 2, cols_a, Assign> f2; + typedef typename boost::mpl::if_c<(cols_a > 1), f2, impl::noop>::type f3; + f3::apply(A, v, w); +} + +template <unsigned Index, unsigned Size> +struct init_ptrs +{ + template <typename Matrix, typename Ptrs> + inline static void apply(const Matrix& A, Ptrs& ptrs) + { + ptrs.value= &A[Index][0]; + init_ptrs<Index+1, Size>::apply(A, ptrs.sub); + } +}; + +template <unsigned Size> +struct init_ptrs<Size, Size> +{ + template <typename Matrix, typename Ptrs> + inline static void apply(const Matrix&, Ptrs&) {} +}; + +template <unsigned Index, unsigned Size> +struct square_cvec_mult_rows +{ + template <typename Tmps, typename Ptrs, typename ValueIn> + inline static void compute(Tmps& tmps, Ptrs& ptrs, ValueIn vi) + { + tmps.value+= *ptrs.value++ * vi; + square_cvec_mult_rows<Index+1, Size>::compute(tmps.sub, ptrs.sub, vi); + } + + template <typename As, typename VectorOut, typename Tmps> + inline static void update(As, VectorOut& w, const Tmps& tmps) + { + As::first_update(w[Index], tmps.value); + square_cvec_mult_rows<Index+1, Size>::update(As(), w, tmps.sub); + } +}; + +template <unsigned Size> +struct square_cvec_mult_rows<Size, Size> +{ + template <typename Tmps, typename Ptrs, typename ValueIn> + inline static void compute(Tmps&, Ptrs&, ValueIn) {} + + template <typename As, typename VectorOut, typename Tmps> + inline static void update(As, VectorOut&, const Tmps&) {} +}; + +template <unsigned Index, unsigned Size> +struct square_cvec_mult_cols +{ + template <typename Tmps, typename Ptrs, typename VPtr> + inline static void compute(Tmps& tmps, Ptrs& ptrs, VPtr vp) + { + square_cvec_mult_rows<0, Size>::compute(tmps, ptrs, *vp); + square_cvec_mult_cols<Index+1, Size>::compute(tmps, ptrs, ++vp); + } +}; + +template <unsigned Size> +struct square_cvec_mult_cols<Size, Size> +{ + template <typename Tmps, typename Ptrs, typename VPtr> + inline static void compute(Tmps&, Ptrs&, VPtr) {} +}; + + +// Dense matrix vector multiplication with run-time matrix size +template <unsigned Size, typename MValue, typename MPara, typename ValueIn, typename ParaIn, + typename VectorOut, typename Assign> +inline void square_cvec_mult(const dense2D<MValue, MPara>& A, const mtl::vec::dense_vector<ValueIn, ParaIn>& v, VectorOut& w, Assign) +{ + // vampir_trace<3067> tracer; + MTL_STATIC_ASSERT((mtl::traits::is_row_major<MPara>::value), "Only row-major matrices supported in this function."); + + typedef typename Collection<VectorOut>::value_type value_type; + multi_tmp<Size, value_type> tmps(math::zero(w[0])); + + multi_tmp<Size, const MValue*> ptrs; + init_ptrs<0, Size>::apply(A, ptrs); + + const ValueIn* vp= &v[0]; + + square_cvec_mult_cols<0, Size>::compute(tmps, ptrs, vp); // outer loop over columns + square_cvec_mult_rows<0, Size>::update(Assign(), w, tmps); // update rows +} + + +// Dense matrix vector multiplication with run-time matrix size +template <typename MValue, typename MPara, typename ValueIn, typename ParaIn, typename VectorOut, typename Assign> +typename boost::enable_if<mtl::traits::is_row_major<MPara> >::type +inline dense_mat_cvec_mult(const dense2D<MValue, MPara>& A, const mtl::vec::dense_vector<ValueIn, ParaIn>& v, VectorOut& w, Assign, boost::mpl::false_) +{ + // vampir_trace<3066> tracer; + + using math::zero; + if (mtl::size(w) == 0) return; + + typedef typename Collection<VectorOut>::value_type value_type; + // typedef ValueIn value_in_type; + typedef typename MPara::size_type size_type; + + const size_type nr= num_rows(A), nc= num_cols(A); + if (nr == nc && nr <= 8) + switch (nr) { + case 1: Assign::first_update(w[0], A[0][0] * v[0]); return; + case 2: square_cvec_mult<2>(A, v, w, Assign()); return; + case 3: square_cvec_mult<3>(A, v, w, Assign()); return; + case 4: square_cvec_mult<4>(A, v, w, Assign()); return; + case 5: square_cvec_mult<5>(A, v, w, Assign()); return; + case 6: square_cvec_mult<6>(A, v, w, Assign()); return; + case 7: square_cvec_mult<7>(A, v, w, Assign()); return; + case 8: square_cvec_mult<8>(A, v, w, Assign()); return; + } + + + const size_type nrb= nr / 4 * 4; + const value_type z(math::zero(w[0])); + + for (size_type i= 0; i < nrb; i+= 4) { + value_type tmp0(z), tmp1(z), tmp2(z), tmp3(z); + const MValue *p0= &A[i][0], *pe= p0 + nc, *p1= &A[i+1][0], *p2= &A[i+2][0], *p3= &A[i+3][0]; + const ValueIn* vp= &v[0]; + for (; p0 != pe; ) { + const ValueIn vj= *vp++; + tmp0+= *p0++ * vj; + tmp1+= *p1++ * vj; + tmp2+= *p2++ * vj; + tmp3+= *p3++ * vj; + } + Assign::first_update(w[i], tmp0); + Assign::first_update(w[i+1], tmp1); + Assign::first_update(w[i+2], tmp2); + Assign::first_update(w[i+3], tmp3); + } + + for (size_type i= nrb; i < nr; i++) { + value_type tmp= z; + const ValueIn* vp= &v[0]; + for (const MValue *p0= &A[i][0], *pe= p0 + nc; p0 != pe; ) + tmp+= *p0++ * *vp++; + Assign::first_update(w[i], tmp); + } +} + + +// Dense matrix vector multiplication with run-time matrix size +template <typename Matrix, typename VectorIn, typename VectorOut, typename Assign> +inline void dense_mat_cvec_mult(const Matrix& A, const VectorIn& v, VectorOut& w, Assign, boost::mpl::false_) +{ + vampir_trace<3018> tracer; + // Naive implementation, will be moved to a functor and complemented with more efficient ones + + using math::zero; + if (mtl::size(w) == 0) return; + // std::cout << "Bin in richtiger Funktion\n"; + + // if (Assign::init_to_zero) set_to_zero(w); // replace update with first_update insteda + + typedef typename Collection<VectorOut>::value_type value_type; + typedef typename Collection<VectorIn>::value_type value_in_type; + typedef typename Collection<Matrix>::size_type size_type; + + const value_type z(math::zero(w[0])); + const size_type nr= num_rows(A), nrb= nr / 4 * 4, nc= num_cols(A); + + for (size_type i= 0; i < nrb; i+= 4) { + value_type tmp0(z), tmp1(z), tmp2(z), tmp3(z); + for (size_type j= 0; j < nc; j++) { + const value_in_type vj= v[j]; + tmp0+= A[i][j] * vj; + tmp1+= A[i+1][j] * vj; + tmp2+= A[i+2][j] * vj; + tmp3+= A[i+3][j] * vj; + } + Assign::first_update(w[i], tmp0); + Assign::first_update(w[i+1], tmp1); + Assign::first_update(w[i+2], tmp2); + Assign::first_update(w[i+3], tmp3); + } + + for (size_type i= nrb; i < nr; i++) { + value_type tmp= z; + for (size_type j= 0; j < nc; j++) + tmp+= A[i][j] * v[j]; + Assign::first_update(w[i], tmp); + } +} + +// Dense matrix vector multiplication +template <typename Matrix, typename VectorIn, typename VectorOut, typename Assign> +inline void mat_cvec_mult(const Matrix& A, const VectorIn& v, VectorOut& w, Assign, tag::flat<tag::dense>) +{ +# ifdef MTL_NOT_UNROLL_FSIZE_MAT_VEC_MULT + boost::mpl::false_ selector; +# else + mtl::traits::is_static<Matrix> selector; +# endif + dense_mat_cvec_mult(A, v, w, Assign(), selector); +} + +// Element structure vector multiplication +template <typename Matrix, typename VectorIn, typename VectorOut, typename Assign> +inline void mat_cvec_mult(const Matrix& A, const VectorIn& v, VectorOut& w, Assign, tag::flat<tag::element_structure>) +{ + vampir_trace<3048> tracer; + if (mtl::size(w) == 0) return; + + typedef typename Collection<VectorOut>::value_type value_type; + typedef typename Collection<VectorIn>::value_type value_in_type; + + value_in_type varray[1024]; + value_type warray[1024]; + + if (Assign::init_to_zero) set_to_zero(w); + for(int elmi= 0; elmi < A.m_total_elements; elmi++){ + const typename Matrix::element_type& elementi= A.m_elements[elmi]; + const typename Matrix::element_type::index_type& indices= elementi.get_indices(); + unsigned int n(size(indices)); + + if (n <= 1024) { + VectorIn vtmp(n, varray); + for (unsigned int i= 0; i < n; i++) + vtmp[i]= v[indices[i]]; + VectorOut wtmp(n, warray); + wtmp= elementi.get_values() * vtmp; + for (unsigned int i= 0; i < n; i++) + Assign::update(w[indices[i]], wtmp[i]); + } else { + VectorIn vtmp(n); + for (unsigned int i= 0; i < n; i++) + vtmp[i]= v[indices[i]]; + VectorOut wtmp(elementi.get_values() * vtmp); + for (unsigned int i= 0; i < n; i++) + Assign::update(w[indices[i]], wtmp[i]); + } + } +} + +// Multi-vector vector multiplication (tag::multi_vector is derived from dense) +template <typename Matrix, typename VectorIn, typename VectorOut, typename Assign> +inline void mat_cvec_mult(const Matrix& A, const VectorIn& v, VectorOut& w, Assign, tag::flat<tag::multi_vector>) +{ + vampir_trace<3019> tracer; + if (Assign::init_to_zero) set_to_zero(w); + for (unsigned i= 0; i < num_cols(A); i++) + Assign::update(w, A.vector(i) * v[i]); +} + +// Transposed multi-vector vector multiplication (tag::transposed_multi_vector is derived from dense) +template <typename TransposedMatrix, typename VectorIn, typename VectorOut, typename Assign> +inline void mat_cvec_mult(const TransposedMatrix& A, const VectorIn& v, VectorOut& w, Assign, tag::flat<tag::transposed_multi_vector>) +{ + vampir_trace<3020> tracer; + typename TransposedMatrix::const_ref_type B= A.ref; // Referred matrix + + if (Assign::init_to_zero) set_to_zero(w); + for (unsigned i= 0; i < num_cols(B); i++) + Assign::update(w[i], dot_real(B.vector(i), v)); +} + +// Hermitian multi-vector vector multiplication (tag::hermitian_multi_vector is derived from dense) +template <typename HermitianMatrix, typename VectorIn, typename VectorOut, typename Assign> +inline void mat_cvec_mult(const HermitianMatrix& A, const VectorIn& v, VectorOut& w, Assign, tag::flat<tag::hermitian_multi_vector>) +{ + vampir_trace<3021> tracer; + typename HermitianMatrix::const_ref_type B= A.const_ref(); // Referred matrix + + if (Assign::init_to_zero) set_to_zero(w); + for (unsigned i= 0; i < num_cols(B); i++) + Assign::update(w[i], dot(B.vector(i), v)); +} + + + +// Sparse row-major matrix vector multiplication +template <typename Matrix, typename VectorIn, typename VectorOut, typename Assign> +inline void smat_cvec_mult(const Matrix& A, const VectorIn& v, VectorOut& w, Assign, tag::row_major) +{ + vampir_trace<3022> tracer; + using namespace tag; + using mtl::traits::range_generator; + using math::zero; + using mtl::vec::set_to_zero; + + typedef typename range_generator<row, Matrix>::type a_cur_type; + typedef typename range_generator<nz, a_cur_type>::type a_icur_type; + typename mtl::traits::col<Matrix>::type col_a(A); + typename mtl::traits::const_value<Matrix>::type value_a(A); + + if (Assign::init_to_zero) set_to_zero(w); + + typedef typename Collection<VectorOut>::value_type value_type; + a_cur_type ac= begin<row>(A), aend= end<row>(A); + for (unsigned i= 0; ac != aend; ++ac, ++i) { + value_type tmp= zero(w[i]); + for (a_icur_type aic= begin<nz>(ac), aiend= end<nz>(ac); aic != aiend; ++aic) + tmp+= value_a(*aic) * v[col_a(*aic)]; + Assign::update(w[i], tmp); + } +} + +// Row-major compressed2D with very few entries (i.e. Very Sparse MATrix) times vector +template <typename MValue, typename MPara, typename VectorIn, typename VectorOut, typename Assign> +inline void vsmat_cvec_mult(const compressed2D<MValue, MPara>& A, const VectorIn& v, VectorOut& w, Assign, tag::row_major) +{ + vampir_trace<3064> tracer; + using math::zero; + + typedef compressed2D<MValue, MPara> Matrix; + typedef typename Collection<Matrix>::size_type size_type; + typedef typename Collection<VectorOut>::value_type value_type; + + if (size(w) == 0) return; + const value_type z(math::zero(w[0])); + + // std::cout << "very sparse: nnz = " << A.nnz() << ", num_rows = " << num_rows(A) << '\n'; + + size_type nr= num_rows(A); + for (size_type i1= 0, i2= std::min<size_type>(1024, nr); i1 < i2; i1= i2, i2= std::min<size_type>(i2 + 1024, nr)) { + // std::cout << "range = " << i1 << " .. " << i2 << "\n"; + if (A.ref_major()[i1] < A.ref_major()[i2]) + for (size_type i= i1; i < i2; ++i) { + const size_type cj0= A.ref_major()[i], cj1= A.ref_major()[i+1]; + value_type tmp0(z); + for (size_type j0= cj0; j0 != cj1; ++j0) + tmp0+= A.data[j0] * v[A.ref_minor()[j0]]; + Assign::first_update(w[i], tmp0); + } + } +} + +#ifdef MTL_CRS_CVEC_MULT_TUNING +template <unsigned Index, unsigned BSize, typename SizeType> +struct crs_cvec_mult_block +{ + template <typename Matrix, typename VectorIn, typename CBlock, typename TBlock> + void operator()(const Matrix& A, const VectorIn& v, const CBlock& cj, TBlock& tmp) const + { + for (SizeType j= cj.value; j != cj.sub.value; ++j) // cj is one index larger + tmp.value+= A.data[j] * v[A.ref_minor()[j]]; + sub(A, v, cj.sub, tmp.sub); + } + + template <typename VectorOut, typename TBlock, typename Assign> + void first_update(VectorOut& w, SizeType i, const TBlock& tmp, Assign as) const + { + Assign::first_update(w[i + Index], tmp.value); + sub.first_update(w, i, tmp.sub, as); + } + + crs_cvec_mult_block<Index+1, BSize, SizeType> sub; +}; + + +template <unsigned BSize, typename SizeType> +struct crs_cvec_mult_block<BSize, BSize, SizeType> +{ + template <typename Matrix, typename VectorIn, typename CBlock, typename TBlock> + void operator()(const Matrix& A, const VectorIn& v, const CBlock& cj, TBlock& tmp) const + { + for (SizeType j= cj.value; j != cj.sub.value; ++j)// cj is one index larger + tmp.value+= A.data[j] * v[A.ref_minor()[j]]; + } + + template <typename VectorOut, typename TBlock, typename Assign> + void first_update(VectorOut& w, SizeType i, const TBlock& tmp, Assign) const + { + Assign::first_update(w[i + BSize], tmp.value); + } +}; + + +// Row-major compressed2D vector multiplication +template <unsigned BSize, typename MValue, typename MPara, typename VectorIn, typename VectorOut, typename Assign> +inline void smat_cvec_mult(const compressed2D<MValue, MPara>& A, const VectorIn& v, VectorOut& w, Assign as, tag::row_major) +{ + vampir_trace<3049> tracer; + using math::zero; + + if (A.nnz() < num_rows(A)) { + vsmat_cvec_mult(A, v, w, as, tag::row_major()); + return; + } + + typedef compressed2D<MValue, MPara> Matrix; + typedef typename Collection<VectorOut>::value_type value_type; + typedef typename mtl::traits::omp_size_type<typename Collection<Matrix>::size_type>::type size_type; + + if (size(w) == 0) return; + const value_type z(math::zero(w[0])); + + size_type nr= num_rows(A), nrb= nr / BSize * BSize; + + #ifdef MTL_WITH_OPENMP + # pragma omp parallel + #endif + { + #ifdef MTL_WITH_OPENMP + vampir_trace<8004> tracer; + # pragma omp for + #endif + for (size_type i= 0; i < nrb; i+= BSize) { + multi_constant_from_array<0, BSize+1, size_type> cj(A.ref_major(), i); + multi_tmp<BSize, value_type> tmp(z); + crs_cvec_mult_block<0, BSize-1, size_type> block; + + block(A, v, cj, tmp); + block.first_update(w, i, tmp, as); + } + } + + for (size_type i= nrb; i < nr; ++i) { + const size_type cj0= A.ref_major()[i], cj1= A.ref_major()[i+1]; + value_type tmp0(z); + for (size_type j0= cj0; j0 != cj1; ++j0) + tmp0+= A.data[j0] * v[A.ref_minor()[j0]]; + Assign::first_update(w[i], tmp0); + } +} + +template <typename MValue, typename MPara, typename VectorIn, typename VectorOut, typename Assign> +typename mtl::traits::enable_if_scalar<typename Collection<VectorOut>::value_type>::type +inline smat_cvec_mult(const compressed2D<MValue, MPara>& A, const VectorIn& v, VectorOut& w, Assign, tag::row_major) +{ + smat_cvec_mult<crs_cvec_mult_block_size>(A, v, w, Assign(), tag::row_major()); +} +#endif + + +#if !defined(MTL_CRS_CVEC_MULT_NO_ACCEL) && !defined(MTL_CRS_CVEC_MULT_TUNING) + +template <typename MValue, typename MPara, typename VectorIn, typename VectorOut, typename Assign> +typename mtl::traits::enable_if_scalar<typename Collection<VectorOut>::value_type>::type +inline adapt_crs_cvec_mult(const compressed2D<MValue, MPara>& A, const VectorIn& v, VectorOut& w, Assign) +{ + vampir_trace<3065> tracer; + using math::zero; + assert(!Assign::init_to_zero); + + typedef compressed2D<MValue, MPara> Matrix; + typedef typename Collection<Matrix>::size_type size_type; + typedef typename Collection<VectorOut>::value_type value_type; + + const value_type z(math::zero(w[0])); + size_type nr= num_rows(A), nrb= nr / 4 * 4, nrb2= nr / 64 * 64; + + for (size_type i1= 0; i1 < nrb2; i1+= 64) + if (A.ref_major()[i1] != A.ref_major()[i1 + 64]) + for (size_type i2= i1, i2e= i1+64; i2 < i2e; i2+= 16) + if (A.ref_major()[i2] != A.ref_major()[i2 + 16]) + for (size_type i= i2, i3e= i2+16; i < i3e; i+= 4) + if (A.ref_major()[i] != A.ref_major()[i + 4]) { + const size_type cj0= A.ref_major()[i], cj1= A.ref_major()[i+1], cj2= A.ref_major()[i+2], + cj3= A.ref_major()[i+3], cj4= A.ref_major()[i+4]; + value_type tmp0(z), tmp1(z), tmp2(z), tmp3(z); + for (size_type j0= cj0; j0 != cj1; ++j0) + tmp0+= A.data[j0] * v[A.ref_minor()[j0]]; + for (size_type j1= cj1; j1 != cj2; ++j1) + tmp1+= A.data[j1] * v[A.ref_minor()[j1]]; + for (size_type j2= cj2; j2 != cj3; ++j2) + tmp2+= A.data[j2] * v[A.ref_minor()[j2]]; + for (size_type j3= cj3; j3 != cj4; ++j3) + tmp3+= A.data[j3] * v[A.ref_minor()[j3]]; + + Assign::first_update(w[i], tmp0); + Assign::first_update(w[i+1], tmp1); + Assign::first_update(w[i+2], tmp2); + Assign::first_update(w[i+3], tmp3); + } + + for (size_type i= nrb2; i < nrb; i+= 4) + if (A.ref_major()[i] != A.ref_major()[i + 4]) { + const size_type cj0= A.ref_major()[i], cj1= A.ref_major()[i+1], cj2= A.ref_major()[i+2], + cj3= A.ref_major()[i+3], cj4= A.ref_major()[i+4]; + value_type tmp0(z), tmp1(z), tmp2(z), tmp3(z); + for (size_type j0= cj0; j0 != cj1; ++j0) + tmp0+= A.data[j0] * v[A.ref_minor()[j0]]; + for (size_type j1= cj1; j1 != cj2; ++j1) + tmp1+= A.data[j1] * v[A.ref_minor()[j1]]; + for (size_type j2= cj2; j2 != cj3; ++j2) + tmp2+= A.data[j2] * v[A.ref_minor()[j2]]; + for (size_type j3= cj3; j3 != cj4; ++j3) + tmp3+= A.data[j3] * v[A.ref_minor()[j3]]; + + Assign::first_update(w[i], tmp0); + Assign::first_update(w[i+1], tmp1); + Assign::first_update(w[i+2], tmp2); + Assign::first_update(w[i+3], tmp3); + } + + for (size_type i= nrb; i < nr; ++i) { + const size_type cj0= A.ref_major()[i], cj1= A.ref_major()[i+1]; + value_type tmp0(z); + for (size_type j0= cj0; j0 != cj1; ++j0) + tmp0+= A.data[j0] * v[A.ref_minor()[j0]]; + Assign::first_update(w[i], tmp0); + } +} + +// Row-major compressed2D vector multiplication +template <typename MValue, typename MPara, typename VectorIn, typename VectorOut, typename Assign> +typename mtl::traits::enable_if_scalar<typename Collection<VectorOut>::value_type>::type +inline smat_cvec_mult(const compressed2D<MValue, MPara>& A, const VectorIn& v, VectorOut& w, Assign as, tag::row_major) +{ + vampir_trace<3049> tracer; + // vampir_trace<5056> tttracer; + using math::zero; + + if (A.nnz() < num_rows(A) && !as.init_to_zero) { + vsmat_cvec_mult(A, v, w, as, tag::row_major()); + return; + } + + typedef compressed2D<MValue, MPara> Matrix; + typedef typename Collection<VectorOut>::value_type value_type; + typedef typename mtl::traits::omp_size_type<typename Collection<Matrix>::size_type>::type size_type; + + if (size(w) == 0) return; + const value_type z(math::zero(w[0])); + + size_type nr= num_rows(A), nrb= nr / 4 * 4; + if (nr > 10) { + size_type nh= nr / 2, nq= nr / 4, nt= nr - nq; + if (!as.init_to_zero && + (A.ref_major()[1] == A.ref_major()[0] + || A.ref_major()[nq] == A.ref_major()[nq+1] + || A.ref_major()[nh] == A.ref_major()[nh+1] + || A.ref_major()[nt] == A.ref_major()[nt+1] + || A.ref_major()[nr-1] == A.ref_major()[nr])) { + adapt_crs_cvec_mult(A, v, w, as); + return; + } + } + + #ifdef MTL_WITH_OPENMP + # pragma omp parallel + #endif + { + #ifdef MTL_WITH_OPENMP + vampir_trace<8004> tracer; + # pragma omp for + #endif + for (size_type i= 0; i < nrb; i+= 4) { + const size_type cj0= A.ref_major()[i], cj1= A.ref_major()[i+1], cj2= A.ref_major()[i+2], + cj3= A.ref_major()[i+3], cj4= A.ref_major()[i+4]; + value_type tmp0(z), tmp1(z), tmp2(z), tmp3(z); + for (size_type j0= cj0; j0 != cj1; ++j0) + tmp0+= A.data[j0] * v[A.ref_minor()[j0]]; + for (size_type j1= cj1; j1 != cj2; ++j1) + tmp1+= A.data[j1] * v[A.ref_minor()[j1]]; + for (size_type j2= cj2; j2 != cj3; ++j2) + tmp2+= A.data[j2] * v[A.ref_minor()[j2]]; + for (size_type j3= cj3; j3 != cj4; ++j3) + tmp3+= A.data[j3] * v[A.ref_minor()[j3]]; + + Assign::first_update(w[i], tmp0); + Assign::first_update(w[i+1], tmp1); + Assign::first_update(w[i+2], tmp2); + Assign::first_update(w[i+3], tmp3); + } + } + + for (size_type i= nrb; i < nr; ++i) { + const size_type cj0= A.ref_major()[i], cj1= A.ref_major()[i+1]; + value_type tmp0(z); + for (size_type j0= cj0; j0 != cj1; ++j0) + tmp0+= A.data[j0] * v[A.ref_minor()[j0]]; + Assign::first_update(w[i], tmp0); + } +} +#endif + +// Row-major ell_matrix vector multiplication +template <typename MValue, typename MPara, typename VectorIn, typename VectorOut, typename Assign> +typename mtl::traits::enable_if_scalar<typename Collection<VectorOut>::value_type>::type +inline smat_cvec_mult(const ell_matrix<MValue, MPara>& A, const VectorIn& v, VectorOut& w, Assign, tag::row_major) +{ + typedef typename MPara::size_type size_type; + + const size_type stride= A.stride(), slots= A.slots(); + for (size_type r= 0; r < A.dim1(); ++r) { + MValue s(0); + for (size_type k= r, i= 0; i < slots; ++i, k+= stride) + s+= A.ref_data()[k] * v[A.ref_minor()[k]]; + Assign::first_update(w[r], s); + } + } + + +// Row-major sparse_banded vector multiplication +template <typename MValue, typename MPara, typename VectorIn, typename VectorOut, typename Assign> +typename mtl::traits::enable_if_scalar<typename Collection<VectorOut>::value_type>::type +inline smat_cvec_mult(const sparse_banded<MValue, MPara>& A, const VectorIn& v, VectorOut& w, Assign, tag::row_major) +{ + vampir_trace<3069> tracer; + typedef sparse_banded<MValue, MPara> Matrix; + typedef typename Collection<VectorOut>::value_type value_type; + typedef typename Matrix::band_size_type band_size_type; + typedef typename MPara::size_type size_type; + typedef mtl::vec::dense_vector<band_size_type, parameters<> > vector_type; + + if (size(w) == 0) return; + const value_type z(math::zero(w[0])); + + size_type nr= num_rows(A), nc= num_cols(A), nb= A.ref_bands().size(); + if (nb == size_type(0) && Assign::init_to_zero) { + set_to_zero(w); + return; + } + + vector_type bands(A.ref_bands()), begin_rows(max(0, -bands)), end_rows(min(nr, nc - bands)); + assert(end_rows[nb-1] > 0); + + // std::cout << "bands = " << bands << ", begin_rows = " << begin_rows << ", end_rows = " << end_rows << "\n"; + size_type begin_pos= 0, end_pos= nb - 1; + + // find lowest diagonal in row 0 + while (begin_pos < nb && begin_rows[begin_pos] > 0) begin_pos++; + // if at the end, the first rows are empty + if (begin_pos == nb && Assign::init_to_zero) { + w[irange(begin_rows[--begin_pos])]= z; + // std::cout << "w[0.." << begin_rows[begin_pos] << "] <- 0\n"; + } + + band_size_type from= begin_rows[begin_pos]; + // find first entry with same value + while (begin_pos > 0 && begin_rows[begin_pos - 1] == from) { + assert(from == 0); // should only happen when multiple bands start in row 0 + begin_pos--; + } + for (bool active= true; active; ) { + // search backwards for the next-largest entry + band_size_type to= begin_pos > 0 && begin_rows[begin_pos - 1] <= end_rows[end_pos] ? begin_rows[begin_pos - 1] : end_rows[end_pos]; + + // std::cout << "rows " << from << ".." << to << ": with bands "; + // for (size_type i= begin_pos; i <= end_pos; i++) + // std::cout << bands[i] << (i < end_pos ? ", " : "\n"); + + const MValue* Aps= A.ref_data() + (from * nb + begin_pos); + + const band_size_type blocked_to= ((to - from) & -4) + from; + assert((blocked_to - from) % 4 == 0 && blocked_to >= band_size_type(from) && blocked_to <= band_size_type(to)); + for (band_size_type r= from; r < blocked_to; r+= 4) { + value_type tmp0(z), tmp1(z), tmp2(z), tmp3(z); + const MValue *Ap0= Aps, *Ap1= Aps + nb, *Ap2= Ap1 + nb, *Ap3= Ap2 + nb; + for (size_type b= begin_pos; b <= end_pos; ++b, ++Ap0, ++Ap1, ++Ap2, ++Ap3) { + tmp0+= *Ap0 * v[r + bands[b]]; + tmp1+= *Ap1 * v[r + bands[b] + 1]; + tmp2+= *Ap2 * v[r + bands[b] + 2]; + tmp3+= *Ap3 * v[r + bands[b] + 3]; + } + Assign::first_update(w[r], tmp0); + Assign::first_update(w[r+1], tmp1); + Assign::first_update(w[r+2], tmp2); + Assign::first_update(w[r+3], tmp3); + Aps+= 4 * nb; + } + + for (band_size_type r= blocked_to; r < band_size_type(to); r++) { + value_type tmp(z); + const MValue* Ap= Aps; + for (size_type b= begin_pos; b <= end_pos; ++b, ++Ap) + tmp+= *Ap * v[r + bands[b]]; + Assign::first_update(w[r], tmp); + Aps+= nb; + } + + if (begin_pos > 0) { + if (begin_rows[begin_pos-1] == to) + begin_pos--; + if (end_rows[end_pos] == to) + end_pos--; + } else { // begin == 0 -> decrement end_pos or finish + if (end_rows[0] == to) { + active= false; + assert(end_rows[0] = end_rows[end_pos]); + } else { + assert(end_pos > 0); + end_pos--; + } + } + assert(begin_pos <= end_pos); + from= to; + } + + if (size_type(end_rows[0]) < nr && Assign::init_to_zero) { + w[irange(end_rows[0], nr)]= z; + // std::cout << "w[" << end_rows[0] << ".." << nr << "] <- 0\n"; + } +} + +// Sparse column-major matrix vector multiplication +template <typename Matrix, typename VectorIn, typename VectorOut, typename Assign> +inline void smat_cvec_mult(const Matrix& A, const VectorIn& v, VectorOut& w, Assign, tag::col_major) +{ + vampir_trace<3023> tracer; + using namespace tag; namespace traits = mtl::traits; + using traits::range_generator; + using mtl::vec::set_to_zero; + typedef typename range_generator<col, Matrix>::type a_cur_type; + typedef typename range_generator<nz, a_cur_type>::type a_icur_type; + + typename traits::row<Matrix>::type row_a(A); + typename traits::const_value<Matrix>::type value_a(A); + + if (Assign::init_to_zero) set_to_zero(w); + + unsigned rv= 0; // traverse all rows of v + for (a_cur_type ac= begin<col>(A), aend= end<col>(A); ac != aend; ++ac, ++rv) { + typename Collection<VectorIn>::value_type vv= v[rv]; + for (a_icur_type aic= begin<nz>(ac), aiend= end<nz>(ac); aic != aiend; ++aic) + Assign::update(w[row_a(*aic)], value_a(*aic) * vv); + } +} + +// Sparse matrix vector multiplication +template <typename Matrix, typename VectorIn, typename VectorOut, typename Assign> +inline void mat_cvec_mult(const Matrix& A, const VectorIn& v, VectorOut& w, Assign, tag::flat<tag::sparse>) +{ + smat_cvec_mult(A, v, w, Assign(), typename OrientedCollection<Matrix>::orientation()); +} + + + +}} // namespace mtl::matrix + + + + +#endif // MTL_MAT_VEC_MULT_INCLUDE + diff --git a/install/MTL/include/boost/numeric/mtl/operation/matrix_bracket.hpp b/install/MTL/include/boost/numeric/mtl/operation/matrix_bracket.hpp new file mode 100644 index 00000000..8b98d4e0 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/matrix_bracket.hpp @@ -0,0 +1,101 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_BRACKETS_INCLUDE +#define MTL_MATRIX_BRACKETS_INCLUDE + +#include <algorithm> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/utility/iset.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/column_in_matrix.hpp> +#include <boost/numeric/mtl/operation/row_in_matrix.hpp> + +namespace mtl { namespace operations { + + template <typename Matrix, typename Ref, typename ValueRef> + struct bracket_proxy + { + typedef typename Matrix::value_type value_type; + typedef typename Matrix::size_type size_type; + typedef RowInMatrix<typename boost::remove_reference<Ref>::type> row_traits; + + explicit bracket_proxy(Ref matrix, size_type row) : matrix(matrix), row(row) {} + + ValueRef operator[] (size_type col) { return matrix(row, col); } + + template <typename T> struct my_traits { static const bool value= boost::is_same<T, mtl::irange>::value && row_traits::exists; }; + + template <typename T> + typename boost::lazy_enable_if_c<my_traits<T>::value, row_traits>::type + operator[] (const T& col_range) + { + return row_traits::apply(matrix, row, col_range); + } + protected: + Ref matrix; + size_type row; + }; + + + + template <typename Matrix, typename Ref, typename ValueRef> + struct range_bracket_proxy + { + typedef typename Matrix::size_type size_type; + typedef ColumnInMatrix<typename boost::remove_reference<Ref>::type> col_traits; + + explicit range_bracket_proxy(Ref matrix, const irange& row_range) : matrix(matrix), row_range(row_range) {} + + ValueRef operator[] (const irange& col_range) + { + return sub_matrix(matrix, row_range.start(), row_range.finish(), + col_range.start(), col_range.finish()); + } + + template <typename T> struct my_traits { static const bool value = boost::is_integral<T>::value && col_traits::exists; }; + + template <typename T> + typename boost::lazy_enable_if_c<my_traits<T>::value, col_traits>::type + operator[] (T col) { return col_traits::apply(matrix, row_range, col); } + + protected: + Ref matrix; + irange row_range; + }; + + template <typename Matrix, typename Ref, typename ValueRef> + struct set_bracket_proxy + { + set_bracket_proxy(Ref matrix, const iset& row_set) : matrix(matrix), row_set(row_set) {} + + mtl::mat::indirect<Matrix> operator[] (const iset& col_set) + { + return mtl::mat::indirect<Matrix>(matrix, row_set, col_set); + } + + protected: + Ref matrix; + iset row_set; + }; + +} // namespace operations + +} // NAMESPACE mtl + +#endif // MTL_MATRIX_BRACKETS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/max.hpp b/install/MTL/include/boost/numeric/mtl/operation/max.hpp new file mode 100644 index 00000000..926346f7 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/max.hpp @@ -0,0 +1,66 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAX_INCLUDE +#define MTL_MAX_INCLUDE + +#include <iostream> +#include <cmath> + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/vector/reduction.hpp> +#include <boost/numeric/mtl/vector/reduction_functors.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace vec { + + namespace impl { + + // Do we really need this for matrices? + // Then we need a different dispatching + + template <unsigned long Unroll, typename Vector> + typename Collection<Vector>::value_type + inline max(const Vector& vector, tag::vector) + { + typedef typename Collection<Vector>::value_type result_type; + return vec::reduction<Unroll, vec::max_functor, result_type>::apply(vector); + } + + } // namespace impl + +///Returns maximal entry of %vector v +template <unsigned long Unroll, typename Value> +typename Collection<Value>::value_type +inline max(const Value& value) +{ + vampir_trace<2010> tracer; + return impl::max<Unroll>(value, typename traits::category<Value>::type()); +} + +template <typename Value> +typename Collection<Value>::value_type +inline max(const Value& value) +{ + return max<8>(value); +} + +} // namespace vector + +using vec::max; + +} // namespace mtl::vector + +#endif // MTL_MAX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/max_abs_pos.hpp b/install/MTL/include/boost/numeric/mtl/operation/max_abs_pos.hpp new file mode 100644 index 00000000..58828abb --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/max_abs_pos.hpp @@ -0,0 +1,90 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_MAX_ABS_POS_INCLUDE +#define MTL_MATRIX_MAX_ABS_POS_INCLUDE + +#include <utility> +#include <cmath> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/concept/magnitude.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { + +namespace mat { +///Returns pair (row, col) from absolut maximal entry of %matrix A + template <typename Matrix> + typename mtl::traits::enable_if_matrix<Matrix, std::pair<typename Collection<Matrix>::size_type, typename Collection<Matrix>::size_type> >::type + inline max_abs_pos(const Matrix& A) + { + vampir_trace<3024> tracer; + namespace traits = mtl::traits; + using std::abs; + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + + typename RealMagnitude<value_type>::type max(abs(A[0][0])); + size_type r= 0, c= 0; + + typename traits::row<Matrix>::type row(A); + typename traits::col<Matrix>::type col(A); + typename traits::const_value<Matrix>::type value(A); + typedef typename traits::range_generator<tag::major, Matrix>::type cursor_type; + + for (cursor_type cursor = begin<tag::major>(A), cend = end<tag::major>(A); cursor != cend; ++cursor) { + typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type; + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) + if (abs(value(*icursor)) > max) { + max= abs(value(*icursor)); + r= row(*icursor); + c= col(*icursor); + } + } + + return std::make_pair(r, c); + } + +} // namespace matrix + +namespace vec { +///Returns position from absolut maximal entry of %vector v + template <typename Vector> + typename mtl::traits::enable_if_vector<Vector, typename Collection<Vector>::size_type>::type + inline max_abs_pos(const Vector& v) + { + vampir_trace<2011> tracer; + using std::abs; + typedef typename Collection<Vector>::size_type size_type; + typedef typename Collection<Vector>::value_type value_type; + + size_type i= 0; + size_type max_col= size(v); + value_type max(abs(v[0])); + + for(size_type j= 1; j < max_col; j++) + if(abs(v[j]) > max) { + max = abs(v[j]); + i= j; + } + return i; + } + +} // namespace vector + +} // namespace mtl + +#endif // MTL_MATRIX_MAX_ABS_POS_INCLUDE + diff --git a/install/MTL/include/boost/numeric/mtl/operation/max_of_sums.hpp b/install/MTL/include/boost/numeric/mtl/operation/max_of_sums.hpp new file mode 100644 index 00000000..488d9428 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/max_of_sums.hpp @@ -0,0 +1,74 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAX_OF_SUMS_INCLUDE +#define MTL_MAX_OF_SUMS_INCLUDE + +#include <boost/numeric/mtl/concept/magnitude.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/linear_algebra/operators.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +#include <numeric> +#include <cmath> + + +namespace mtl { namespace impl { + +// We need property map of the minor index +template <typename Matrix, typename MinorIndex> +typename RealMagnitude<typename Collection<Matrix>::value_type>::type +inline max_of_sums(const Matrix& matrix, bool aligned, MinorIndex minor_index, unsigned dim2) +{ + vampir_trace<2012> tracer; + using std::max; using std::abs; using math::zero; + + typedef typename Collection<Matrix>::value_type value_type; + typedef typename RealMagnitude<value_type>::type real_type; + real_type ref, my_zero= zero(ref); + + // If matrix is empty then the result is the identity from the default-constructed value + if (num_rows(matrix) == 0 || num_cols(matrix) == 0) + return my_zero; + + typedef typename traits::range_generator<tag::major, Matrix>::type cursor_type; + typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type; + typename traits::const_value<Matrix>::type value(matrix); + + if (aligned) { + real_type maxv= my_zero; + for (cursor_type cursor = begin<tag::major>(matrix), cend = end<tag::major>(matrix); cursor != cend; ++cursor) { + real_type sum= my_zero; + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) + sum+= abs(value(*icursor)); + maxv= max(maxv, sum); + } + return maxv; + } + + // If matrix has other orientation, we compute all sums in a vector + dense_vector<real_type> sums(dim2, my_zero); + for (cursor_type cursor = begin<tag::major>(matrix), cend = end<tag::major>(matrix); cursor != cend; ++cursor) + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) + sums[minor_index(*icursor)]+= abs(value(*icursor)); + // replace by mtl::accumulate<8> + return std::accumulate(sums.begin(), sums.end(), my_zero, math::max<real_type>()); +} + + +}} // namespace mtl::impl + +#endif // MTL_MAX_OF_SUMS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/max_pos.hpp b/install/MTL/include/boost/numeric/mtl/operation/max_pos.hpp new file mode 100644 index 00000000..c28a4924 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/max_pos.hpp @@ -0,0 +1,146 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_MAX_POS +#define MTL_MATRIX_MAX_POS + +#include <cmath> +#include <utility> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/pos_type.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/operation/look_at_each_nonzero.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +#if 0 +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#endif + + + +namespace mtl { + + namespace vec { + + template <typename Vector> + struct max_pos_functor + { + typedef typename Collection<Vector>::value_type value_type; + typedef typename mtl::traits::pos_type<Vector>::type pos_type; + typedef std::pair<value_type, pos_type> result_type; + + // initialize with max value and max position + max_pos_functor() + { + value.first= math::identity(math::max<value_type>(), value_type()); // minimal value for comparison + value.second= math::identity(math::min<pos_type>(), pos_type()); // maximal position to check if changed + } + + void operator()(const value_type& x, const pos_type& p) + { + if (x > value.first) + value= std::make_pair(x, p); + } + + bool unchanged() const { return value.second == math::identity(math::min<pos_type>(), pos_type()); } + + result_type value; + }; + ///Returns position of maximal entry of %vector v + template <typename Vector> + typename max_pos_functor<Vector>::pos_type + inline max_pos(const Vector& v) + { + vampir_trace<2013> tracer; + max_pos_functor<Vector> f; + look_at_each_nonzero_pos(v, f); + + MTL_DEBUG_THROW_IF(f.unchanged(), runtime_error("max_pos cannot be applied on empty container")); + return f.value.second; + } + + } // namespace vector + + namespace mat { + ///Returns pair (row, col) from maximal entry of %matrix A + using mtl::vec::max_pos; + } + + +#if 0 +namespace matrix { +///Returns pair (row, col) from maximal entry of %matrix A + template <typename Matrix> + std::pair<typename Collection<Matrix>::size_type, typename Collection<Matrix>::size_type> + inline max_pos(const Matrix& A) + { + namespace traits = mtl::traits; + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + + value_type max(A[0][0]); + size_type r= 0, c= 0; + + typename traits::row<Matrix>::type row(A); + typename traits::col<Matrix>::type col(A); + typename traits::const_value<Matrix>::type value(A); + typedef typename traits::range_generator<tag::major, Matrix>::type cursor_type; + + for (cursor_type cursor = begin<tag::major>(A), cend = end<tag::major>(A); cursor != cend; ++cursor) { + typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type; + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) + if (value(*icursor) > max) { + max= value(*icursor); + r= row(*icursor); + c= col(*icursor); + } + } + + return std::make_pair(r, c); +} + +} // namespace matrix + +namespace vector { +///Returns position from maximal entry of %vector v + template <typename Vector> + typename Collection<Vector>::size_type + inline max_pos(const Vector& v) + { + typedef typename Collection<Vector>::size_type size_type; + typedef typename Collection<Vector>::value_type value_type; + + size_type i= 0; + + size_type max_col= size(v); + value_type max(v[0]); + + for(size_type j= 1;i < max_col; j++) + if(v[j] > max) { + max = v[j]; + i= j; + } + return i; + } + +} // namespace vector + +#endif + + +} // namespace mtl + +#endif // MTL_MATRIX_MAX_POS + diff --git a/install/MTL/include/boost/numeric/mtl/operation/merge_complex_matrix.hpp b/install/MTL/include/boost/numeric/mtl/operation/merge_complex_matrix.hpp new file mode 100644 index 00000000..5e90ca50 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/merge_complex_matrix.hpp @@ -0,0 +1,23 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_MERGE_COMPLEX_MATRIX_INCLUDE +#define MTL_MATRIX_MERGE_COMPLEX_MATRIX_INCLUDE + +namespace mtl { namespace mat { + + + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_MERGE_COMPLEX_MATRIX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/merge_complex_vector.hpp b/install/MTL/include/boost/numeric/mtl/operation/merge_complex_vector.hpp new file mode 100644 index 00000000..4dbce83a --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/merge_complex_vector.hpp @@ -0,0 +1,44 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_MERGE_COMPLEX_VECTOR_INCLUDE +#define MTL_VECTOR_MERGE_COMPLEX_VECTOR_INCLUDE + +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace vec { + +/// Merge two real-valued vectors into one complex-valued vector. +/** Elements of the complex vector must be constructible from two real elements. + Complex vector is resized if its size is 0 otherwise the vectors must have + the same length. **/ +template <typename VectorReal, typename VectorImaginary, typename VectorComplex> +inline void merge_complex_vector(const VectorReal& r, const VectorImaginary& i, VectorComplex& c) +{ + vampir_trace<2014> tracer; + typedef typename Collection<VectorComplex>::value_type value_type; + + MTL_THROW_IF(size(r) != size(i), incompatible_size()); + c.checked_change_dim(size(r)); + + for (std::size_t j= 0; j < size(r); ++j) + c[j]= value_type(r[j], i[j]); +} + + + + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_MERGE_COMPLEX_VECTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/min.hpp b/install/MTL/include/boost/numeric/mtl/operation/min.hpp new file mode 100644 index 00000000..0ce97e5b --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/min.hpp @@ -0,0 +1,64 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MIN_INCLUDE +#define MTL_MIN_INCLUDE + +#include <iostream> +#include <cmath> + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/vector/reduction.hpp> +#include <boost/numeric/mtl/vector/reduction_functors.hpp> + + +namespace mtl { namespace vec { + + namespace impl { + + // Do we really need this for matrices? + // Then we need a different dispatching + + template <unsigned long Unroll, typename Vector> + typename Collection<Vector>::value_type + inline min(const Vector& vector, tag::vector) + { + typedef typename Collection<Vector>::value_type result_type; + return vec::reduction<Unroll, vec::min_functor, result_type>::apply(vector); + } + + } // namespace impl + +///Returns minimal value of %vector v +template <unsigned long Unroll, typename Value> +typename Collection<Value>::value_type +inline min(const Value& value) +{ + return impl::min<Unroll>(value, typename traits::category<Value>::type()); +} + +template <typename Value> +typename Collection<Value>::value_type +inline min(const Value& value) +{ + return min<8>(value); +} + +} // namespace vector + +using vec::min; + +} // namespace mtl + +#endif // MTL_MIN_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/min_pos.hpp b/install/MTL/include/boost/numeric/mtl/operation/min_pos.hpp new file mode 100644 index 00000000..33c2ed15 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/min_pos.hpp @@ -0,0 +1,71 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MIN_POS_INCLUDE +#define MTL_MIN_POS_INCLUDE + +#include <utility> + +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/pos_type.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/operation/look_at_each_nonzero.hpp> + + +namespace mtl { + + namespace vec { + + template <typename Vector> + struct min_pos_functor + { + typedef typename Collection<Vector>::value_type value_type; + typedef typename mtl::traits::pos_type<Vector>::type pos_type; + typedef std::pair<value_type, pos_type> result_type; + + // initialize with max value and max position + min_pos_functor() : value(math::identity(math::min<result_type>(), result_type())) {} + + void operator()(const value_type& x, const pos_type& p) + { + if (x < value.first) + value= std::make_pair(x, p); + } + + bool unchanged() const { return value.second == math::identity(math::min<pos_type>(), pos_type()); } + + result_type value; + }; + ///Returns position of minimal entry of %vector v + template <typename Vector> + typename min_pos_functor<Vector>::pos_type + inline min_pos(const Vector& v) + { + min_pos_functor<Vector> f; + look_at_each_nonzero_pos(v, f); + + MTL_DEBUG_THROW_IF(f.unchanged(), runtime_error("min_pos cannot be applied on empty container")); + return f.value.second; + } + + } // namespace vector + + namespace mat { + + using mtl::vec::min_pos; + } + + +} // namespace mtl + +#endif // MTL_MIN_POS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/minimal_increase.hpp b/install/MTL/include/boost/numeric/mtl/operation/minimal_increase.hpp new file mode 100644 index 00000000..1e6a13e0 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/minimal_increase.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MINIMAL_INCREASE_INCLUDE +#define MTL_MINIMAL_INCREASE_INCLUDE + +#include <limits> + +namespace mtl { + +/// Increase x minimally: if x == 0 take minimal value, if x > 0 multiply by (1+2eps) otherwise divide by +template <typename T> +T inline minimal_increase(const T& x) +{ + const T factor= T(1) + T(2) * std::numeric_limits<T>::epsilon(); + if (x == T(0)) + return std::numeric_limits<T>::denorm_min(); + else + return x > T(0) ? x * factor : x / factor; +} + + + +} // namespace mtl + +#endif // MTL_MINIMAL_INCREASE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/misc.hpp b/install/MTL/include/boost/numeric/mtl/operation/misc.hpp new file mode 100644 index 00000000..51b262db --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/misc.hpp @@ -0,0 +1,28 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// With contributions from Cornelius Steinhardt + +#ifndef MTL_MISC_INCLUDE +#define MTL_MISC_INCLUDE + +namespace mtl { + + template <typename T> + T square(const T& x) + { return x * x; } + +}// namespace mtl + + +#endif // MTL_MISC_INCLUDE + diff --git a/install/MTL/include/boost/numeric/mtl/operation/mult.hpp b/install/MTL/include/boost/numeric/mtl/operation/mult.hpp new file mode 100644 index 00000000..f7abdaf1 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/mult.hpp @@ -0,0 +1,335 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MULT_INCLUDE +#define MTL_MULT_INCLUDE + +#include <boost/numeric/mtl/config.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/flatcat.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/operation/dmat_dmat_mult.hpp> +#include <boost/numeric/mtl/operation/smat_smat_mult.hpp> +#include <boost/numeric/mtl/operation/smat_dmat_mult.hpp> +#include <boost/numeric/mtl/operation/mat_vec_mult.hpp> +#include <boost/numeric/mtl/operation/rvec_mat_mult.hpp> // Row vector times matrix +#include <boost/numeric/mtl/operation/mult_specialize.hpp> +#include <boost/numeric/mtl/operation/assign_mode.hpp> +#include <boost/numeric/mtl/operation/mult_assign_mode.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> + +#include <boost/mpl/if.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace mat { + + +/// Multiplication: mult(a, b, c) computes c= a * b; +/** The 3 types must be compatible, e.g. all three matrices or b and c are column vectors and a is a matrix. + The dimensions are checked at compile time. **/ +template <typename A, typename B, typename C> +typename mtl::traits::enable_if_matrix<A>::type +inline mult(const A& a, const B& b, C& c) +{ + vampir_trace<4010> tracer; + MTL_DEBUG_THROW_IF(static_cast<const void*>(&a) == static_cast<const void*>(&c) + || static_cast<const void*>(&b) == static_cast<const void*>(&c), + argument_result_conflict()); + + // dispatch between matrices, vectors, and scalars + using mtl::traits::shape_flatcat; + gen_mult(a, b, c, assign::assign_sum(), shape_flatcat<A>(), shape_flatcat<B>(), shape_flatcat<C>()); + // typename category<A>::type(), typename category<B>::type(), typename category<C>::type()); +} + + +/// Multiplication: mult_add(a, b, c) computes c+= a * b; +/** The 3 types must be compatible, e.g. all three matrices or b and c are column vectors and a is a matrix. + The dimensions are checked at compile time. **/ +template <typename A, typename B, typename C> +typename mtl::traits::enable_if_matrix<A>::type +inline mult_add(const A& a, const B& b, C& c) +{ + vampir_trace<4010> tracer; + // dispatch between matrices, vectors, and scalars + using mtl::traits::shape_flatcat; + gen_mult(a, b, c, assign::plus_sum(), shape_flatcat<A>(), shape_flatcat<B>(), shape_flatcat<C>()); + // typename category<A>::type(), typename category<B>::type(), typename category<C>::type()); +} + + +/// Four term multiplication: mult(a, x, y, z) computes z= a * x + y; +/** The 4 types must be compatible, i.e. a*x must be assignable to z and z must be incrementable by y. + Right now, it is not more efficient than z= a * x; z+= y. For compatibility with MTL2. **/ +template <typename A, typename X, typename Y, typename Z> +inline void mult(const A& a, const X& x, const Y& y, Z& z) +{ + vampir_trace<4010> tracer; + mult(a, x, z); + z+= y; +} + + +// Matrix multiplication +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign> +inline void gen_mult(const MatrixA& a, const MatrixB& b, MatrixC& c, Assign, tag::flat<tag::matrix>, tag::flat<tag::matrix>, tag::flat<tag::matrix>) +{ + vampir_trace<4011> tracer; +#if 1 + MTL_DEBUG_THROW_IF((const void*)&a == (const void*)&c || (const void*)&b == (const void*)&c, argument_result_conflict()); +#else + if ((const void*)&a == (const void*)&c || (const void*)&b == (const void*)&c) { + C tmp(num_rows(c), num_cols(c)); + mult(a, b, tmp); + swap(C, tmp); + return; + } +#endif + + MTL_DEBUG_THROW_IF(num_rows(a) != num_rows(c) || num_cols(a) != num_rows(b) || num_cols(b) != num_cols(c), incompatible_size()); + // dispatch between dense and sparse + using mtl::traits::sparsity_flatcat; + mat_mat_mult(a, b, c, Assign(), sparsity_flatcat<MatrixA>(), sparsity_flatcat<MatrixB>(), sparsity_flatcat<MatrixC>()); + // typename category<MatrixA>::type(), typename category<MatrixB>::type(), typename category<MatrixC>::type()); +} + + +/// Dense matrix multiplication +/** The function for dense matrix multiplication defines a default multiplication functor. + Alternatively the user can define his own functors for specific triplets of matrix types, + see detail::dmat_dmat_mult_specialize. + The default functor for dense matrix multiplication is: + -# Use BLAS if available, otherwise + -# Recursive multiplication with: + -# Platform optimized mult on blocks if available, otherwise + -# Tiled multiplication on blocks if available, otherwise + -# Naive multiplication on blocks + -# Naive multiplication on entire matrices if recursion is not available +**/ +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign> +inline void mat_mat_mult(const MatrixA& A, const MatrixB& b, MatrixC& c, Assign, tag::flat<tag::dense>, tag::flat<tag::dense>, tag::flat<tag::dense>) +{ + vampir_trace<4012> tracer; + using assign::plus_sum; using assign::assign_sum; + + static const unsigned long tiling1= detail::dmat_dmat_mult_tiling1<MatrixA, MatrixB, MatrixC>::value; + static const unsigned long tiling2= detail::dmat_dmat_mult_tiling2<MatrixA, MatrixB, MatrixC>::value; + typedef gen_tiling_dmat_dmat_mult_t<tiling1, tiling2, plus_sum> tiling_mult_t; + + typedef gen_platform_dmat_dmat_mult_t<plus_sum, tiling_mult_t> platform_mult_t; + typedef gen_recursive_dmat_dmat_mult_t<platform_mult_t> recursive_mult_t; + typedef gen_blas_dmat_dmat_mult_t<assign_sum, recursive_mult_t> blas_mult_t; + typedef size_switch_dmat_dmat_mult_t<straight_dmat_dmat_mult_limit, tiling_mult_t, blas_mult_t> variable_size_t; + + typedef fully_unroll_fixed_size_dmat_dmat_mult_t<Assign> fully_unroll_t; + typedef size_switch_dmat_dmat_mult_t<fully_unroll_dmat_dmat_mult_limit, fully_unroll_t, tiling_mult_t> fixed_size_t; + + static const bool all_static= mtl::traits::is_static<MatrixA>::value && mtl::traits::is_static<MatrixB>::value + && mtl::traits::is_static<MatrixC>::value; + typedef static_switch_dmat_dmat_mult_t<all_static, fixed_size_t, variable_size_t> default_functor_t; + + /// Use user-defined functor if provided (assign mode can be arbitrary) + typedef typename boost::mpl::if_< + detail::dmat_dmat_mult_specialize<MatrixA, MatrixB, MatrixC> + , typename detail::dmat_dmat_mult_specialize<MatrixA, MatrixB, MatrixC>::type + , default_functor_t + >::type raw_functor_type; + + /// Finally substitute assign mode (consistently) + typename assign::mult_assign_mode<raw_functor_type, Assign>::type functor; + + functor(A, b, c); +} + +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign> +inline void mat_mat_mult(const MatrixA& A, const MatrixB& b, MatrixC& c, Assign, tag::flat<tag::dense>, tag::flat<tag::dense>, tag::flat<tag::sparse>) +{ + vampir_trace<4012> tracer; + // This is a useless and extremely inefficient operation!!!! + // We compute this with a dense matrix and copy the result back + dense2D<typename Collection<MatrixC>::value_type, mat::parameters<> > c_copy(num_rows(c), num_cols(c)); + c_copy= c; + mat_mat_mult(A, b, c_copy, Assign(), tag::flat<tag::dense>(), tag::flat<tag::dense>(), tag::flat<tag::dense>()); + c= c_copy; +} + +/// Sparse matrix multiplication +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign> +inline void mat_mat_mult(const MatrixA& A, const MatrixB& b, MatrixC& c, Assign, tag::flat<tag::sparse>, tag::flat<tag::sparse>, tag::flat<tag::sparse>) +{ + vampir_trace<4012> tracer; + smat_smat_mult(A, b, c, Assign(), typename OrientedCollection<MatrixA>::orientation(), + typename OrientedCollection<MatrixB>::orientation()); +} + +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign> +inline void mat_mat_mult(const MatrixA& A, const MatrixB& b, MatrixC& c, Assign, tag::flat<tag::sparse>, tag::flat<tag::sparse>, tag::flat<tag::dense>) +{ + vampir_trace<4012> tracer; + // This is a useless and extremely inefficient operation!!!! + // We compute this with a sparse matrix and copy the result back + compressed2D<typename Collection<MatrixC>::value_type, mat::parameters<> > c_copy(num_rows(c), num_cols(c)); + c_copy= c; + smat_smat_mult(A, b, c_copy, Assign(), typename OrientedCollection<MatrixA>::orientation(), + typename OrientedCollection<MatrixB>::orientation()); + c= c_copy; +} + +/// Product of sparse times dense matrix +/** This function (specialization of mult) is intended to multiply sparse matrices with multiple matrices + gathered into a dense matrix. Likewise, the resulting dense matrix corresponds to multiple vectors. + The default functor for this operation is: + -# Use tiled multiplication if available, otherwise + -# Naive multiplication +**/ +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign> +inline void mat_mat_mult(const MatrixA& A, const MatrixB& b, MatrixC& c, Assign, tag::flat<tag::sparse>, tag::flat<tag::dense>, tag::flat<tag::dense>) +{ + vampir_trace<4012> tracer; + using assign::plus_sum; using assign::assign_sum; + using namespace functor; + + // static const unsigned long tiling1= detail::dmat_dmat_mult_tiling1<MatrixA, MatrixB, MatrixC>::value; + + //typedef gen_smat_dmat_mult<Assign> default_functor_t; + typedef gen_tiling_smat_dmat_mult<8, Assign> default_functor_t; + + // Finally substitute assign mode (consistently) + // typename assign::mult_assign_mode<raw_functor_type, Assign>::type functor; + + default_functor_t functor; + functor(A, b, c); +} + +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign> +inline void mat_mat_mult(const MatrixA& A, const MatrixB& b, MatrixC& c, Assign, tag::flat<tag::sparse>, tag::flat<tag::dense>, tag::flat<tag::sparse>) +{ + vampir_trace<4012> tracer; + // This is a useless and extremely inefficient operation!!!! + // We compute this with a sparse matrix and copy the result back + dense2D<typename Collection<MatrixC>::value_type, mat::parameters<> > c_copy(num_rows(c), num_cols(c)); + c_copy= c; + mat_mat_mult(A, b, c_copy, Assign(), tag::flat<tag::sparse>(), tag::flat<tag::dense>(), tag::flat<tag::dense>()); + c= c_copy; +} + + +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign> +inline void mat_mat_mult(const MatrixA& A, const MatrixB& b, MatrixC& c, Assign, tag::flat<tag::dense>, tag::flat<tag::sparse>, tag::flat<tag::dense>) +{ + vampir_trace<4012> tracer; + // This is could be a usefull operation, i.e. multiplying multiple row vectors with a sparse matrix + // Might be supported in future + // Now we compute this with a sparse matrix as first argument + compressed2D<typename Collection<MatrixA>::value_type, mat::parameters<> > A_copy(num_rows(A), num_cols(A)); + A_copy= A; + compressed2D<typename Collection<MatrixC>::value_type, mat::parameters<> > c_copy(num_rows(c), num_cols(c)); + c_copy= c; + mat_mat_mult(A_copy, b, c_copy, Assign(), tag::flat<tag::sparse>(), tag::flat<tag::sparse>(), tag::flat<tag::sparse>()); + c= c_copy; +} + + + +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign> +inline void mat_mat_mult(const MatrixA& A, const MatrixB& b, MatrixC& c, Assign, tag::flat<tag::dense>, tag::flat<tag::sparse>, tag::flat<tag::sparse>) +{ + vampir_trace<4012> tracer; + // This is not a usefull operation, because the result is dense + // Now we compute this with a sparse matrix as first argument + compressed2D<typename Collection<MatrixA>::value_type, mat::parameters<> > A_copy(num_rows(A), num_cols(A)); + A_copy= A; + mat_mat_mult(A_copy, b, c, Assign(), tag::flat<tag::sparse>(), tag::flat<tag::sparse>(), tag::flat<tag::sparse>()); +} + + + +// Matrix vector multiplication +template <typename Matrix, typename VectorIn, typename VectorOut, typename Assign> +inline void gen_mult(const Matrix& A, const VectorIn& v, VectorOut& w, Assign, tag::flat<tag::matrix>, tag::flat<tag::col_vector>, tag::flat<tag::col_vector>) +{ + vampir_trace<4011> tracer; + // Vector must be column vector + // If vector is row vector then matrix must have one column and the operation is a outer product + // -> result should be a matrix too + + // Check if element types are compatible (in contrast to tag dispatching, nesting is considered here) + MTL_STATIC_ASSERT((boost::is_same< typename ashape::mult_op<typename ashape::ashape<Matrix>::type, + typename ashape::ashape<VectorIn>::type >::type, + ::mtl::ashape::mat_cvec_mult + >::value), + "The type nesting of the arguments does not allow for a consistent matrix vector product."); + + +#if 1 + MTL_DEBUG_THROW_IF((void*)&v == (void*)&w, argument_result_conflict()); +#else + if ((void*)&v == (void*)&w) { + VectorOut tmp(size(w)); + mult(A, b, tmp); + swap(w, tmp); + return; + } +#endif + // w.checked_change_dim(num_rows(A)); // destroys distribution in parallel -> dimension changed in assignment + MTL_DEBUG_THROW_IF(num_rows(A) != mtl::size(w), incompatible_size()); + MTL_DEBUG_THROW_IF(num_cols(A) != mtl::size(v), incompatible_size()); + + mat_cvec_mult(A, v, w, Assign(), mtl::traits::mat_cvec_flatcat<Matrix>()); +} + + +// Vector matrix multiplication +template <typename VectorIn, typename Matrix, typename VectorOut, typename Assign> +inline void gen_mult(const VectorIn& v, const Matrix& A, VectorOut& w, Assign, tag::flat<tag::row_vector>, tag::flat<tag::matrix>, tag::flat<tag::row_vector>) +{ + vampir_trace<4011> tracer; + // Vector must be column vector + // If vector is row vector then matrix must have one column and the operation is a outer product + // -> result should be a matrix too + + // Check if element types are compatible (in contrast to tag dispatching, nesting is considered here) + MTL_STATIC_ASSERT((boost::is_same< typename ashape::mult_op<typename ashape::ashape<VectorIn>::type, + typename ashape::ashape<Matrix>::type >::type, + ::mtl::ashape::rvec_mat_mult + >::value), + "The type nesting of the arguments does not allow for a consistent matrix vector product."); + +#if 1 + MTL_DEBUG_THROW_IF((void*)&v == (void*)&w, argument_result_conflict()); +#else + if ((void*)&v == (void*)&w) { + VectorOut tmp(size(w)); + mult(A, b, tmp); + swap(w, tmp); + return; + } +#endif + // w.checked_change_dim(num_cols(A)); + w.checked_change_resource(v); + MTL_DEBUG_THROW_IF(num_cols(v) != num_rows(A), incompatible_size()); + + // same dispatching criterion as mat_cvec_mult (until now) + rvec_mat_mult(v, A, w, Assign(), typename mtl::traits::mat_cvec_flatcat<Matrix>::type()); +} + + + + + +}} // namespace mtl::matrix + +#endif // MTL_MULT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/mult_assign_mode.hpp b/install/MTL/include/boost/numeric/mtl/operation/mult_assign_mode.hpp new file mode 100644 index 00000000..9e656bc1 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/mult_assign_mode.hpp @@ -0,0 +1,148 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MULT_ASSIGN_MODE_INCLUDE +#define MTL_MULT_ASSIGN_MODE_INCLUDE + +#include <boost/numeric/mtl/operation/assign_mode.hpp> +#include <boost/numeric/mtl/operation/dmat_dmat_mult.hpp> +#include <boost/numeric/mtl/operation/no_op.hpp> + +namespace mtl { namespace assign { + +namespace detail { + + template <typename Assign> + struct subm_assign + { + typedef Assign type; + }; + + template<> + struct subm_assign<assign_sum> + { + typedef plus_sum type; + }; + +} + +// Set assign_mode of functor 'Mult' to 'Assign' +// including assign_mode of backup functors and functors for sub-matrices +template <typename Mult, typename Assign> +struct mult_assign_mode +{}; + + +#if 0 +// Omit the fully typed functors; they shouldn't be used directly +template <typename MatrixA, typename MatrixB, typename MatrixC, typename OldAssign, typename Backup, + typename Assign> +struct mult_assign_mode<gen_dmat_dmat_mult_ft<MatrixA, MatrixB, MatrixC, OldAssign, Backup>, + Assign> +{ + typedef gen_dmat_dmat_mult_ft<MatrixA, MatrixB, MatrixC, Assign, Backup> type; +}; +#endif + + +template <typename Assign> +struct mult_assign_mode<no_op, Assign> +{ + typedef no_op type; +}; + +template <typename OldAssign, typename Backup, typename Assign> +struct mult_assign_mode<gen_dmat_dmat_mult_t<OldAssign, Backup>, Assign> +{ + typedef typename mult_assign_mode<Backup, Assign>::type backup_type; + typedef gen_dmat_dmat_mult_t<Assign, backup_type> type; +}; + +template <typename OldAssign, typename Backup, typename Assign> +struct mult_assign_mode<gen_cursor_dmat_dmat_mult_t<OldAssign, Backup>, Assign> +{ + typedef typename mult_assign_mode<Backup, Assign>::type backup_type; + typedef gen_cursor_dmat_dmat_mult_t<Assign, backup_type> type; +}; + +template <unsigned long Tiling1, unsigned long Tiling2, typename OldAssign, typename Backup, typename Assign> +struct mult_assign_mode<gen_tiling_dmat_dmat_mult_t<Tiling1, Tiling2, OldAssign, Backup>, Assign> +{ + typedef typename mult_assign_mode<Backup, Assign>::type backup_type; + typedef gen_tiling_dmat_dmat_mult_t<Tiling1, Tiling2, Assign, backup_type> type; +}; + +template <typename OldAssign, typename Backup, typename Assign> +struct mult_assign_mode<gen_tiling_44_dmat_dmat_mult_t<OldAssign, Backup>, Assign> +{ + typedef typename mult_assign_mode<Backup, Assign>::type backup_type; + typedef gen_tiling_44_dmat_dmat_mult_t<Assign, backup_type> type; +}; + +template <typename OldAssign, typename Backup, typename Assign> +struct mult_assign_mode<gen_tiling_22_dmat_dmat_mult_t<OldAssign, Backup>, Assign> +{ + typedef typename mult_assign_mode<Backup, Assign>::type backup_type; + typedef gen_tiling_22_dmat_dmat_mult_t<Assign, backup_type> type; +}; + +template <typename BaseMult, typename BaseTest, typename OldAssign, typename Backup, typename Assign> +struct mult_assign_mode<gen_recursive_dmat_dmat_mult_t<BaseMult, BaseTest, OldAssign, Backup>, Assign> +{ + typedef typename mult_assign_mode<Backup, Assign>::type backup_type; + + // Corresponding assignment type for sub-matrices + typedef typename detail::subm_assign<Assign>::type base_assign_type; + typedef typename mult_assign_mode<BaseMult, base_assign_type>::type base_mult_type; + + typedef gen_recursive_dmat_dmat_mult_t<base_mult_type, BaseTest, Assign, backup_type> type; +}; + +template <typename OldAssign, typename Backup, typename Assign> +struct mult_assign_mode<gen_platform_dmat_dmat_mult_t<OldAssign, Backup>, Assign> +{ + typedef typename mult_assign_mode<Backup, Assign>::type backup_type; + typedef gen_platform_dmat_dmat_mult_t<Assign, backup_type> type; +}; + +template <typename OldAssign, typename Backup, typename Assign> +struct mult_assign_mode<gen_blas_dmat_dmat_mult_t<OldAssign, Backup>, Assign> +{ + typedef typename mult_assign_mode<Backup, Assign>::type backup_type; + typedef gen_blas_dmat_dmat_mult_t<Assign, backup_type> type; +}; + +template <std::size_t SizeLimit, typename FunctorSmall, typename FunctorLarge, typename Assign> +struct mult_assign_mode<size_switch_dmat_dmat_mult_t<SizeLimit, FunctorSmall, FunctorLarge>, Assign> +{ + typedef typename mult_assign_mode<FunctorSmall, Assign>::type small_type; + typedef typename mult_assign_mode<FunctorLarge, Assign>::type large_type; + typedef size_switch_dmat_dmat_mult_t<SizeLimit, small_type, large_type> type; +}; + +template <bool IsStatic, typename FunctorStatic, typename FunctorDynamic, typename Assign> +struct mult_assign_mode<static_switch_dmat_dmat_mult_t<IsStatic, FunctorStatic, FunctorDynamic>, Assign> +{ + typedef typename mult_assign_mode<FunctorStatic, Assign>::type static_type; + typedef typename mult_assign_mode<FunctorDynamic, Assign>::type dynamic_type; + typedef static_switch_dmat_dmat_mult_t<IsStatic, static_type, dynamic_type> type; +}; + +template <typename OldAssign, typename Backup, typename Assign> +struct mult_assign_mode<fully_unroll_fixed_size_dmat_dmat_mult_t<OldAssign, Backup>, Assign> +{ + typedef fully_unroll_fixed_size_dmat_dmat_mult_t<Assign, Backup> type; +}; + +}} // namespace mtl::assign + +#endif // MTL_MULT_ASSIGN_MODE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/mult_result.hpp b/install/MTL/include/boost/numeric/mtl/operation/mult_result.hpp new file mode 100644 index 00000000..a2b9b2d2 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/mult_result.hpp @@ -0,0 +1,156 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MULT_RESULT_INCLUDE +#define MTL_MULT_RESULT_INCLUDE + +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> + +#if 0 +#include <boost/numeric/mtl/matrix/map_view.hpp> +#include <boost/numeric/mtl/matrix/mat_mat_times_expr.hpp> +#include <boost/numeric/mtl/matrix/implicit_dense.hpp> +#include <boost/numeric/mtl/vector/map_view.hpp> +#include <boost/numeric/mtl/operation/mat_cvec_times_expr.hpp> +#include <boost/numeric/mtl/vector/rvec_mat_times_expr.hpp> +#endif + +namespace mtl { namespace traits { + +template <typename Op1, typename Op2, typename MultOp> struct mult_result_aux; +template <typename Op1, typename Op2, typename MultOp> struct vec_mult_result_aux; + //template <typename Op1, typename Op2, typename MultOp1, typename MultOp2> struct mult_result_if_equal_aux; + +/// Result type for multiplying arguments of types Op1 and Op2 +/** Can be used in enable-if-style as type is only defined when appropriate. + This one is used if at least one argument is a matrix. +**/ +template <typename Op1, typename Op2> +struct mult_result + : public mult_result_aux<Op1, Op2, typename ashape::mult_op<typename ashape::ashape<Op1>::type, + typename ashape::ashape<Op2>::type >::type> +{}; + + +/// Result type for multiplying arguments of types Op1 and Op2 +/** Can be used in enable-if-style as type is only defined when appropriate. + This one is used if at least one argument is a vector and none is a matrix. +**/ +template <typename Op1, typename Op2> +struct vec_mult_result + : public vec_mult_result_aux<Op1, Op2, typename ashape::mult_op<typename ashape::ashape<Op1>::type, + typename ashape::ashape<Op2>::type >::type> +{}; + + +/// Result type for multiplying arguments of types Op1 and Op2 +/** MultOp according to the algebraic shapes **/ +template <typename Op1, typename Op2, typename MultOp> +struct mult_result_aux {}; + +/// Scale matrix from left +template <typename Op1, typename Op2> +struct mult_result_aux<Op1, Op2, ::mtl::ashape::scal_mat_mult> +{ + typedef mat::scaled_view<Op1, Op2> type; +}; + + +/// Scale matrix from right needs functor for scaling from right +template <typename Op1, typename Op2> +struct mult_result_aux<Op1, Op2, ::mtl::ashape::mat_scal_mult> +{ + typedef mat::rscaled_view<Op1, Op2> type; +}; + +/// Multiply matrices +template <typename Op1, typename Op2> +struct mult_result_aux<Op1, Op2, ::mtl::ashape::mat_mat_mult> +{ + typedef mat::mat_mat_times_expr<Op1, Op2> type; +}; + +/// Multiply matrix with column vector +template <typename Op1, typename Op2> +struct mult_result_aux<Op1, Op2, ::mtl::ashape::mat_cvec_mult> +{ + typedef mat_cvec_times_expr<Op1, Op2> type; +}; + +/// Multiply column with row vector and return implicit matrix +template <typename Op1, typename Op2> +struct vec_mult_result_aux<Op1, Op2, ::mtl::ashape::cvec_rvec_mult> +{ + typedef mtl::mat::outer_product_matrix<Op1, Op2> type; +}; + +/// Result type for multiplying arguments of types Op1 and Op2 +/** MultOp according to the algebraic shapes **/ +template <typename Op1, typename Op2, typename MultOp> +struct vec_mult_result_aux {}; + +/// Scale row vector from left +template <typename Op1, typename Op2> +struct vec_mult_result_aux<Op1, Op2, ::mtl::ashape::scal_rvec_mult> +{ + typedef vec::scaled_view<Op1, Op2> type; +}; + + + + +/// Scale column vector from left +template <typename Op1, typename Op2> +struct vec_mult_result_aux<Op1, Op2, ::mtl::ashape::scal_cvec_mult> +{ + typedef vec::scaled_view<Op1, Op2> type; +}; + +/// Multiply row vector with matrix +// added by Cornelius and Peter +template <typename Op1, typename Op2> +struct vec_mult_result_aux<Op1, Op2, ::mtl::ashape::rvec_mat_mult> +{ + typedef vec::rvec_mat_times_expr<Op1, Op2> type; +}; + +/// Scale row vector from right +// added by Hui Li +template <typename Op1, typename Op2> +struct vec_mult_result_aux<Op1, Op2, ::mtl::ashape::rvec_scal_mult> +{ + typedef vec::rscaled_view<Op1, Op2> type; +}; + +/// Scale column vector from right +// added by Hui Li +template <typename Op1, typename Op2> +struct vec_mult_result_aux<Op1, Op2, ::mtl::ashape::cvec_scal_mult> +{ + typedef vec::rscaled_view<Op1, Op2> type; +}; + + +/// Enabler if operation is rvec_cvec_mult +template <typename Op1, typename Op2, typename Result> +struct lazy_enable_if_rvec_cvec_mult + : boost::lazy_enable_if<boost::is_same<typename ashape::mult_op<typename ashape::ashape<Op1>::type, + typename ashape::ashape<Op2>::type >::type, + ashape::rvec_cvec_mult>, + Result> +{}; + + +}} // namespace mtl::traits + +#endif // MTL_MULT_RESULT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/mult_specialize.hpp b/install/MTL/include/boost/numeric/mtl/operation/mult_specialize.hpp new file mode 100644 index 00000000..15122ee2 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/mult_specialize.hpp @@ -0,0 +1,54 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MULT_SPECIALIZE_INCLUDE +#define MTL_MULT_SPECIALIZE_INCLUDE + +#include <boost/numeric/mtl/operation/dmat_dmat_mult.hpp> +#include <boost/mpl/bool.hpp> + +namespace mtl { namespace mat {namespace detail { + +template <typename MatrixA, typename MatrixB, typename MatrixC> +struct dmat_dmat_mult_tiling1 +{ + static const unsigned long value= 2; +}; + +template <typename MatrixA, typename MatrixB, typename MatrixC> +struct dmat_dmat_mult_tiling2 +{ + static const unsigned long value= 4; +}; + +template <typename MatrixA, typename MatrixB, typename MatrixC> +struct dmat_dmat_mult_specialize + : public boost::mpl::false_ +{}; + +/* + In order to specialize the functor, write for instance: + +template <typename MatrixA, typename MatrixB, typename MatrixC> +struct dmat_dmat_mult_specialize + : public boost::mpl::true_ +{ + typedef gen_dmat_dmat_mult_t<> type; +}; +*/ + + + + +}}} // namespace mtl::mat::detail + +#endif // MTL_MULT_SPECIALIZE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/multi_action_block.hpp b/install/MTL/include/boost/numeric/mtl/operation/multi_action_block.hpp new file mode 100644 index 00000000..b6929b19 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/multi_action_block.hpp @@ -0,0 +1,80 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MULTI_ACTION_BLOCK_INCLUDE +#define MTL_MULTI_ACTION_BLOCK_INCLUDE + +namespace mtl { + +/* + Functor for unrolling arbitrary loops with independent operations + ... + + */ +template <typename MultiAction, unsigned Steps> struct multi_action_block; + + +template <typename MultiAction, unsigned MaxSteps, unsigned RemainingSteps> +struct multi_action_helper +{ + static unsigned const step= MaxSteps - RemainingSteps; + + void operator() (MultiAction const& action) const + { + action(step); + multi_action_helper<MultiAction, MaxSteps, RemainingSteps-1>()(action); + } + + void operator() (MultiAction& action) const + { + action(step); + multi_action_helper<MultiAction, MaxSteps, RemainingSteps-1>()(action); + } +}; + + +template <typename MultiAction, unsigned MaxSteps> +struct multi_action_helper<MultiAction, MaxSteps, 1> +{ + static unsigned const step= MaxSteps - 1; + + void operator() (MultiAction const& action) const + { + action(step); + } + + void operator() (MultiAction& action) const + { + action(step); + } +}; + + +template <typename MultiAction, unsigned Steps> +struct multi_action_block +{ + void operator() (MultiAction const& action) const + { + multi_action_helper<MultiAction, Steps, Steps>()(action); + } + + void operator() (MultiAction& action) const + { + multi_action_helper<MultiAction, Steps, Steps>()(action); + } +}; + + + +} // namespace mtl + +#endif // MTL_MULTI_ACTION_BLOCK_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/no_op.hpp b/install/MTL/include/boost/numeric/mtl/operation/no_op.hpp new file mode 100644 index 00000000..b517402c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/no_op.hpp @@ -0,0 +1,22 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_NO_OP_INCLUDE +#define MTL_NO_OP_INCLUDE + +namespace mtl { + +struct no_op {}; + +} // namespace mtl + +#endif // MTL_NO_OP_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/norms.hpp b/install/MTL/include/boost/numeric/mtl/operation/norms.hpp new file mode 100644 index 00000000..83e11934 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/norms.hpp @@ -0,0 +1,21 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_NORMS_INCLUDE +#define MTL_NORMS_INCLUDE + +#include <boost/numeric/mtl/operation/one_norm.hpp> +#include <boost/numeric/mtl/operation/two_norm.hpp> +#include <boost/numeric/mtl/operation/infinity_norm.hpp> +#include <boost/numeric/mtl/operation/frobenius_norm.hpp> + +#endif // MTL_NORMS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/num_cols.hpp b/install/MTL/include/boost/numeric/mtl/operation/num_cols.hpp new file mode 100644 index 00000000..2f8858fa --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/num_cols.hpp @@ -0,0 +1,63 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_NUM_COLS_INCLUDE +#define MTL_NUM_COLS_INCLUDE + +#include <vector> + +namespace mtl { + +namespace traits { + + /// General declaration, used to disable unsupported types + template <typename Collection> + struct num_cols {}; + + /// num_cols implementation for STL vectors + template <typename Value> + struct num_cols< std::vector<Value> > + { + typedef std::size_t type; + type operator()(const std::vector<Value>& ) { return 1; } + }; + + /// num_cols implementation for (1D) arrays interpreted as vectors + template <typename Value, unsigned Size> + struct num_cols<Value[Size]> + { + typedef std::size_t type; + type operator()(const Value[Size]) { return 1; } + }; + + /// num_cols implementation for (2D and higher) arrays interpreted as matrices + template <typename Value, unsigned Rows, unsigned Cols> + struct num_cols<Value[Rows][Cols]> + { + typedef std::size_t type; + type operator()(const Value[Rows][Cols]) { return Cols; } + }; +} + + +/// num_cols function for non-MTL types (uses implicit enable_if), 1D interpreted as Column vector +template <typename Collection> +typename traits::num_cols<Collection>::type +inline num_cols(const Collection& c) +{ + return traits::num_cols<Collection>()(c); +} + + +} // namespace mtl + +#endif // MTL_NUM_COLS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/num_rows.hpp b/install/MTL/include/boost/numeric/mtl/operation/num_rows.hpp new file mode 100644 index 00000000..7b337553 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/num_rows.hpp @@ -0,0 +1,63 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_NUM_ROWS_INCLUDE +#define MTL_NUM_ROWS_INCLUDE + +#include <vector> + +namespace mtl { + +namespace traits { + + /// General declaration, used to disable unsupported types + template <typename Collection> + struct num_rows {}; + + /// num_rows implementation for STL vectors + template <typename Value> + struct num_rows< std::vector<Value> > + { + typedef std::size_t type; + type operator()(const std::vector<Value>& v) { return v.size(); } + }; + + /// num_rows implementation for (1D) arrays interpreted as vectors + template <typename Value, unsigned Size> + struct num_rows<Value[Size]> + { + typedef std::size_t type; + type operator()(const Value[Size]) { return Size; } + }; + + /// num_rows implementation for (2D and higher) arrays interpreted as matrices + template <typename Value, unsigned Rows, unsigned Cols> + struct num_rows<Value[Rows][Cols]> + { + typedef std::size_t type; + type operator()(const Value[Rows][Cols]) { return Rows; } + }; +} + + +/// num_rows function for non-MTL types (uses implicit enable_if), 1D interpreted as Column vector +template <typename Collection> +typename traits::num_rows<Collection>::type +inline num_rows(const Collection& c) +{ + return traits::num_rows<Collection>()(c); +} + + +} // namespace mtl + +#endif // MTL_NUM_ROWS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/one_norm.hpp b/install/MTL/include/boost/numeric/mtl/operation/one_norm.hpp new file mode 100644 index 00000000..77e31a1f --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/one_norm.hpp @@ -0,0 +1,96 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ONE_NORM_INCLUDE +#define MTL_ONE_NORM_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/operation/max_of_sums.hpp> +#include <boost/numeric/mtl/vector/lazy_reduction.hpp> +#include <boost/numeric/mtl/vector/reduction.hpp> +#include <boost/numeric/mtl/vector/reduction_functors.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + + namespace vec { + + template <unsigned long Unroll, typename Vector> + typename traits::enable_if_vector<Vector, typename RealMagnitude<typename Collection<Vector>::value_type>::type>::type + inline one_norm(const Vector& vector) + { + vampir_trace<2014> tracer; + typedef typename RealMagnitude<typename Collection<Vector>::value_type>::type result_type; + return reduction<Unroll, one_norm_functor, result_type>::apply(vector); + } + + /*! One-norm for vectors: one_norm(x) \f$\rightarrow |x|_1\f$. + \retval The magnitude type of the respective value type, see Magnitude. + + The norms are defined as \f$|v|_1=\sum_i |v_i|\f$. + Vector norms are unrolled 8-fold by default. + An n-fold unrolling can be generated with one_norm<n>(x). + The maximum for n is 8 (it might be increased later). + **/ + template <typename Vector> + typename traits::enable_if_vector<Vector, typename RealMagnitude<typename Collection<Vector>::value_type>::type>::type + inline one_norm(const Vector& vector) + { + return one_norm<8>(vector); + } + + template <typename Vector> + lazy_reduction<Vector, one_norm_functor> inline lazy_one_norm(const Vector& v) + { return lazy_reduction<Vector, one_norm_functor>(v); } + } + + namespace mat { + + // Ignore unrolling for matrices + template <unsigned long Unroll, typename Matrix> + typename mtl::traits::enable_if_matrix<Matrix, typename RealMagnitude<typename Collection<Matrix>::value_type>::type>::type + inline one_norm(const Matrix& matrix) + { + vampir_trace<3025> tracer; + using mtl::impl::max_of_sums; + typename mtl::traits::col<Matrix>::type col(matrix); + return max_of_sums(matrix, !mtl::traits::is_row_major<typename OrientedCollection<Matrix>::orientation>(), + col, num_cols(matrix)); + } + + /*! One-norm for matrices: one_norm(x) \f$\rightarrow |x|_1\f$. + \retval The magnitude type of the respective value type, see Magnitude. + + The norms are defined as \f$|A|_1=\max_j\{\sum_i(|A_{ij}|)\}\f$. + Matrix norms are not optimized by unrolling (yet). + **/ + template <typename Matrix> + typename mtl::traits::enable_if_matrix<Matrix, typename RealMagnitude<typename Collection<Matrix>::value_type>::type>::type + inline one_norm(const Matrix& matrix) + { + return one_norm<8>(matrix); + } + } + + using vec::one_norm; + using vec::lazy_one_norm; + using mat::one_norm; + +} // namespace mtl + +#endif // MTL_ONE_NORM_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/ones.hpp b/install/MTL/include/boost/numeric/mtl/operation/ones.hpp new file mode 100644 index 00000000..7caaef79 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/ones.hpp @@ -0,0 +1,42 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ONES_INCLUDE +#define MTL_ONES_INCLUDE + +#include <boost/numeric/mtl/matrix/implicit_dense.hpp> + +namespace mtl { + + namespace mat { + + /// Return r by c matrix with ones of type Value in all entries + template <typename Value> + ones_matrix<Value> inline ones(std::size_t r, std::size_t c) + { + return ones_matrix<Value>(r, c); + } + + /// Return r by c matrix with ones of type Value in all entries + ones_matrix<> inline ones(std::size_t r, std::size_t c) + { + return ones_matrix<>(r, c); + } + + } + + using mat::ones; + + +} // namespace mtl + +#endif // MTL_ONES_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/operators.hpp b/install/MTL/include/boost/numeric/mtl/operation/operators.hpp new file mode 100644 index 00000000..a851fe67 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/operators.hpp @@ -0,0 +1,125 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_OPERATORS_INCLUDE +#define MTL_OPERATORS_INCLUDE + +#include <boost/utility/enable_if.hpp> +#include <boost/mpl/and.hpp> + +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/matrix/operators.hpp> +//#include <boost/numeric/mtl/vector/operators.hpp> +#include <boost/numeric/mtl/operation/mult_result.hpp> +#include <boost/numeric/mtl/operation/div_result.hpp> +#include <boost/numeric/mtl/operation/dot.hpp> +#include <boost/numeric/mtl/operation/mat_cvec_times_expr.hpp> +#include <boost/numeric/mtl/matrix/all_mat_expr.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/true_copy.hpp> +#include <boost/numeric/mtl/vector/rvec_mat_times_expr.hpp> + + +namespace mtl { + +namespace mat { + + /// Multiplication for all supported types of operations + /** Enable-if-like technique make sure that only called when properly defined **/ + template <typename Op1, typename Op2> + typename mtl::traits::mult_result<typename mtl::traits::true_copy<Op1>::type, Op2>::type + inline operator*(const Op1& op1, const Op2& op2) + { + + return typename mtl::traits::mult_result<typename mtl::traits::true_copy<Op1>::type, Op2>::type(op1, op2); + } + + + + /// Division of matrices and vectors by salars + /** Enable-if-like technique make sure that only called when properly defined **/ + // added by Hui Li + // enable_if_matrix shouldn't be needed but was nessecary in cuppen.hpp + template < typename Op1, typename Op2 > + typename mtl::traits::enable_if_matrix<Op1, typename mtl::traits::div_result<Op1,Op2>::type>::type + inline operator/(const Op1& op1, const Op2& op2) + { + return typename mtl::traits::div_result<Op1,Op2>::type(op1,op2); + } + +} // namespace matrix + + +namespace vec { + + /// Multiplication for all supported types of operations + /** Enable-if-like technique make sure that only called when properly defined **/ + template <typename Op1, typename Op2> + typename mtl::traits::vec_mult_result<typename mtl::traits::true_copy<Op1>::type, Op2>::type + inline operator*(const Op1& op1, const Op2& op2) + { + return typename mtl::traits::vec_mult_result<typename mtl::traits::true_copy<Op1>::type, Op2>::type(op1, op2); + } + + /// Multiply row vector with column vector; result is scalar + template <typename Op1, typename Op2> + typename traits::lazy_enable_if_rvec_cvec_mult<Op1, Op2, detail::dot_result<Op1, Op2> >::type + inline operator*(const Op1& op1, const Op2& op2) + { + return dot_real(op1, op2); + } + + /// Division of matrices and vectors by salars + /** Enable-if-like technique make sure that only called when properly defined **/ + // added by Hui Li + template < typename Op1, typename Op2 > + typename traits::div_result<Op1,Op2>::type + inline operator/(const Op1& op1, const Op2& op2) + { + return typename traits::div_result<Op1,Op2>::type(op1,op2); + } + + /// Compare two vectors for equality + /** Enable-if makes sure that only called when properly defined **/ + template < typename Op1, typename Op2 > + typename boost::enable_if<boost::mpl::and_<mtl::traits::is_vector<Op1>, + mtl::traits::is_vector<Op2> >, + bool>::type + inline operator==(const Op1& op1, const Op2& op2) + { + unsigned s1= num_rows(op1) * num_cols(op1), s2= num_rows(op2) * num_cols(op2); // ugly hack to fight with ADL + if (s1 != s2) + return false; + for (unsigned i= 0; i < s1; i++) + if (op1[i] != op2[i]) + return false; + return true; + } + + /// Compare two vectors for unequality + /** Enable-if makes sure that only called when properly defined **/ + template < typename Op1, typename Op2 > + typename boost::enable_if<boost::mpl::and_<mtl::traits::is_vector<Op1>, + mtl::traits::is_vector<Op2> >, + bool>::type + inline operator!=(const Op1& op1, const Op2& op2) + { + return !(op1 == op2); + } + +} // namespace vector + + +} // namespace mtl + +#endif // MTL_OPERATORS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/opteron/matrix_mult.hpp b/install/MTL/include/boost/numeric/mtl/operation/opteron/matrix_mult.hpp new file mode 100644 index 00000000..ae734a5b --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/opteron/matrix_mult.hpp @@ -0,0 +1,1562 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Written mostly by Michael Adams +// Modified by Peter Gottschling + +#ifndef MTL_OPTERON_MATRIX_MULT_INCLUDE +#define MTL_OPTERON_MATRIX_MULT_INCLUDE + +#if defined MTL_USE_OPTERON_OPTIMIZATION && defined __GNUC__ && !defined __INTEL_COMPILER + +#include <boost/numeric/mtl/operation/assign_mode.hpp> +#include <boost/numeric/mtl/operation/set_to_zero.hpp> +#include <boost/numeric/mtl/recursion/bit_masking.hpp> + + +namespace mtl { + +namespace detail { + template <unsigned long MaskA, unsigned long MaskB, unsigned long MaskC> + struct opteron_shark_teeth + { + static const unsigned long base_case_bits= 5, tooth_length = 1; + static const bool value= is_k_power_base_case_row_major_t_shark<base_case_bits, tooth_length, MaskA>::value + && is_k_power_base_case_col_major_t_shark<base_case_bits, tooth_length, MaskB>::value + && is_k_power_base_case_row_major_t_shark<base_case_bits, tooth_length, MaskC>::value; + }; + + template <typename Assign, unsigned long MaskA, typename PA, + unsigned long MaskB, typename PB, + unsigned long MaskC, typename PC> + inline void + opteron_shark_teeth_mult(const morton_dense<double, MaskA, PA>& a, const morton_dense<double, MaskB, PB>& b, + morton_dense<double, MaskC, PC>& c) + { + // Never sets the matrix to zero; this is supposed to be done before if necessary + + typedef typename morton_dense<double, MaskA, PA>::size_type size_type; + size_type i_max= c.num_rows(), i_block= 2 * (i_max / 2), + j_max= c.num_cols(), j_block= 2 * (j_max / 2), + k_max= a.num_cols(); + const int stride= 32; + + double *ap= &const_cast<morton_dense<double, MaskA, PA>&>(a)[0][0], + *bp= &const_cast<morton_dense<double, MaskB, PB>&>(b)[0][0], *cp= &c[0][0]; + + // C_nw += A_n * B_n + for (size_type i= 0; i < i_block; i+=2) + for (int j = 0; j < j_block; j+=2) { + double tmp00= 0.0, tmp01= 0.0, tmp10= 0.0, tmp11= 0.0; + for (int k = 0; k < k_max; k++) { + tmp00 += ap[0+(i)*stride+2*k] * bp[0+(j)*stride+2*k]; + tmp01 += ap[0+(i)*stride+2*k] * bp[1+(j)*stride+2*k]; + tmp10 += ap[1+(i)*stride+2*k] * bp[0+(j)*stride+2*k]; + tmp11 += ap[1+(i)*stride+2*k] * bp[1+(j)*stride+2*k]; + } + Assign::update(cp[0+(i)*stride+2*(j+0)], tmp00); + Assign::update(cp[0+(i)*stride+2*(j+1)], tmp01); + Assign::update(cp[1+(i)*stride+2*(j+0)], tmp10); + Assign::update(cp[1+(i)*stride+2*(j+1)], tmp11); + } + + // C_ne += A_n * B_e + for (size_type i= 0; i < i_block; i+=2) + for (int j = j_block; j < j_max; j++) { + double tmp00= 0.0, tmp10= 0.0; + for (int k = 0; k < k_max; k++) { + tmp00 += ap[0+(i)*stride+2*k] * bp[0+(j)*stride+2*k]; + tmp10 += ap[1+(i)*stride+2*k] * bp[0+(j)*stride+2*k]; + } + Assign::update(cp[0+(i)*stride+2*(j+0)], tmp00); + Assign::update(cp[1+(i)*stride+2*(j+0)], tmp10); + } + + // C_s += A_s * B + for (size_type i= i_block; i < i_max; i++) + for (int j = 0; j < j_max; j++) { + double tmp00= 0.0; + for (int k = 0; k < k_max; k++) + tmp00 += ap[0+(i)*stride+2*k] * bp[0+(j)*stride+2*k]; + Assign::update(cp[0+(i)*stride+2*(j+0)], tmp00); + } + } + +} // namespace detail + + +// for C= AB and C+= AB +template <unsigned long MaskA, typename PA, + unsigned long MaskB, typename PB, + unsigned long MaskC, typename PC, + typename Assign, typename Backup> +struct gen_platform_dmat_dmat_mult_ft<morton_dense<double, MaskA, PA>, morton_dense<double, MaskB, PB>, + morton_dense<double, MaskC, PC>, Assign, Backup> +{ + void mult_ass(double * D, double * C, double * BT) const; + + void operator()(const morton_dense<double, MaskA, PA>& a, const morton_dense<double, MaskB, PB>& b, + morton_dense<double, MaskC, PC>& c) const + { + // std::cout << "use Assembly\n"; + + if (detail::opteron_shark_teeth<MaskA, MaskB, MaskC>::value) { + if (Assign::init_to_zero) + set_to_zero(c); + if (a.num_rows() == 32 && a.num_cols() == 32 && b.num_cols() == 32) { + double *ap= const_cast<morton_dense<double, MaskA, PA>&>(a).elements(), + *bp= const_cast<morton_dense<double, MaskB, PB>&>(b).elements(), cp= &c.elements(); + mult_ass(cp, ap, bp); + } else + detail::opteron_shark_teeth_mult<Assign>(a, b, c); + return; + } + Backup()(a, b, c); + } +}; + + +// for C-= AB +template <unsigned long MaskA, typename PA, + unsigned long MaskB, typename PB, + unsigned long MaskC, typename PC, + typename Backup> +struct gen_platform_dmat_dmat_mult_ft<morton_dense<double, MaskA, PA>, morton_dense<double, MaskB, PB>, + morton_dense<double, MaskC, PC>, assign::minus_sum, Backup> +{ + void mult_ass(double * D, double * C, double * BT) const; + + void operator()(const morton_dense<double, MaskA, PA>& a, const morton_dense<double, MaskB, PB>& b, + morton_dense<double, MaskC, PC>& c) const + { + // std::cout << "use Assembly\n"; + + if (detail::opteron_shark_teeth<MaskA, MaskB, MaskC>::value) { + if (a.num_rows() == 32 && a.num_cols() == 32 && b.num_cols() == 32) { + double ap= &const_cast<morton_dense<double, MaskA, PA>&>(a).elements(), + bp= &const_cast<morton_dense<double, MaskB, PB>&>(b).elements(), cp= &c.elements(); + mult_ass(cp, ap, bp); + } else + detail::opteron_shark_teeth_mult<assign::minus_sum>(a, b, c); + return; + } + Backup()(a, b, c); + } +}; + + + + + +template <unsigned long MaskA, typename PA, + unsigned long MaskB, typename PB, + unsigned long MaskC, typename PC, + typename Assign, typename Backup> +void gen_platform_dmat_dmat_mult_ft<morton_dense<double, MaskA, PA>, morton_dense<double, MaskB, PB>, + morton_dense<double, MaskC, PC>, Assign, Backup>:: +mult_ass(double * D, double * C, double * BT) const +{ + // std::cout << "in Assembly\n"; + const int baseOrder= 32, + stride = baseOrder; + /* + double * restrict D = aa + ((d*baseSize)&(rowMask|colMask)); + double * restrict C = aa + ((c*baseSize)&(rowMask|colMask)); + double * restrict BT = aa + ((d*baseSize)&colMask)/2 + + ((c*baseSize)&colMask); + */ + + #if 0 + for (int i = 0; i < baseOrder; i+=2) + for (int j = 0; j < baseOrder; j+=2) + for (int k = 0; k < baseOrder; k++) + { + D[0+(i)*stride+2*(j+0)] += C[0+(i)*stride+2*k] * BT[0+(j)*stride+2*k]; + D[0+(i)*stride+2*(j+1)] += C[0+(i)*stride+2*k] * BT[1+(j)*stride+2*k]; + D[1+(i)*stride+2*(j+0)] += C[1+(i)*stride+2*k] * BT[0+(j)*stride+2*k]; + D[1+(i)*stride+2*(j+1)] += C[1+(i)*stride+2*k] * BT[1+(j)*stride+2*k]; + } + #endif + + #if 0 + // Reorder loops (Ordering based on where the target code is going). + for (int j = 0; j < baseOrder; j+=2) + for (int i = 0; i < baseOrder; i+=16) + { + for (int k = 0; k < baseOrder; k++) + { + for (int i2 = i; i2 < i+16; i2+=2) + { + D[0+(i2)*stride+2*(j+0)] += C[0+(i2)*stride+2*k] * BT[0+(j)*stride+2*k]; + D[1+(i2)*stride+2*(j+0)] += C[1+(i2)*stride+2*k] * BT[0+(j)*stride+2*k]; + } + } + for (int k = 0; k < baseOrder; k++) + { + for (int i2 = i; i2 < i+16; i2+=2) + { + D[0+(i2)*stride+2*(j+1)] += C[0+(i2)*stride+2*k] * BT[1+(j)*stride+2*k]; + D[1+(i2)*stride+2*(j+1)] += C[1+(i2)*stride+2*k] * BT[1+(j)*stride+2*k]; + } + } + } + #endif + + #if 0 + // Unroll i2 + + for (int j = 0; j < baseOrder; j+=2) + for (int i = 0; i < baseOrder; i+=16) + { + for (int k = 0; k < baseOrder; k++) + { + D[0+(i+ 0)*stride+2*(j+0)]+=C[0+(i+ 0)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+ 0)*stride+2*(j+0)]+=C[1+(i+ 0)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+ 2)*stride+2*(j+0)]+=C[0+(i+ 2)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+ 2)*stride+2*(j+0)]+=C[1+(i+ 2)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+ 4)*stride+2*(j+0)]+=C[0+(i+ 4)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+ 4)*stride+2*(j+0)]+=C[1+(i+ 4)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+ 6)*stride+2*(j+0)]+=C[0+(i+ 6)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+ 6)*stride+2*(j+0)]+=C[1+(i+ 6)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+ 8)*stride+2*(j+0)]+=C[0+(i+ 8)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+ 8)*stride+2*(j+0)]+=C[1+(i+ 8)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+10)*stride+2*(j+0)]+=C[0+(i+10)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+10)*stride+2*(j+0)]+=C[1+(i+10)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+12)*stride+2*(j+0)]+=C[0+(i+12)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+12)*stride+2*(j+0)]+=C[1+(i+12)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+14)*stride+2*(j+0)]+=C[0+(i+14)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+14)*stride+2*(j+0)]+=C[1+(i+14)*stride+2*k]*BT[0+j*stride+2*k]; + } + for (int k = 0; k < baseOrder; k++) + { + D[0+(i+ 0)*stride+2*(j+1)]+=C[0+(i+ 0)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+ 0)*stride+2*(j+1)]+=C[1+(i+ 0)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+ 2)*stride+2*(j+1)]+=C[0+(i+ 2)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+ 2)*stride+2*(j+1)]+=C[1+(i+ 2)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+ 4)*stride+2*(j+1)]+=C[0+(i+ 4)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+ 4)*stride+2*(j+1)]+=C[1+(i+ 4)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+ 6)*stride+2*(j+1)]+=C[0+(i+ 6)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+ 6)*stride+2*(j+1)]+=C[1+(i+ 6)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+ 8)*stride+2*(j+1)]+=C[0+(i+ 8)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+ 8)*stride+2*(j+1)]+=C[1+(i+ 8)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+10)*stride+2*(j+1)]+=C[0+(i+10)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+10)*stride+2*(j+1)]+=C[1+(i+10)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+12)*stride+2*(j+1)]+=C[0+(i+12)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+12)*stride+2*(j+1)]+=C[1+(i+12)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+14)*stride+2*(j+1)]+=C[0+(i+14)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+14)*stride+2*(j+1)]+=C[1+(i+14)*stride+2*k]*BT[1+j*stride+2*k]; + } + } + #endif + + #if 0 + // Prep k + for (int j = 0; j < baseOrder; j+=2) + for (int i = 0; i < baseOrder; i+=16) + { + { + double d00 = D[0+(i+ 0)*stride+2*(j+0)]; + double d01 = D[1+(i+ 0)*stride+2*(j+0)]; + double d02 = D[0+(i+ 2)*stride+2*(j+0)]; + double d03 = D[1+(i+ 2)*stride+2*(j+0)]; + double d04 = D[0+(i+ 4)*stride+2*(j+0)]; + double d05 = D[1+(i+ 4)*stride+2*(j+0)]; + double d06 = D[0+(i+ 6)*stride+2*(j+0)]; + double d07 = D[1+(i+ 6)*stride+2*(j+0)]; + double d08 = D[0+(i+ 8)*stride+2*(j+0)]; + double d09 = D[1+(i+ 8)*stride+2*(j+0)]; + double d10 = D[0+(i+10)*stride+2*(j+0)]; + double d11 = D[1+(i+10)*stride+2*(j+0)]; + double d12 = D[0+(i+12)*stride+2*(j+0)]; + double d13 = D[1+(i+12)*stride+2*(j+0)]; + double d14 = D[0+(i+14)*stride+2*(j+0)]; + double d15 = D[1+(i+14)*stride+2*(j+0)]; + for (int k = 0; k < baseOrder; k++) + { + d00+=C[0+(i+ 0)*stride+2*k]*BT[0+j*stride+2*k]; + d01+=C[1+(i+ 0)*stride+2*k]*BT[0+j*stride+2*k]; + d02+=C[0+(i+ 2)*stride+2*k]*BT[0+j*stride+2*k]; + d03+=C[1+(i+ 2)*stride+2*k]*BT[0+j*stride+2*k]; + d04+=C[0+(i+ 4)*stride+2*k]*BT[0+j*stride+2*k]; + d05+=C[1+(i+ 4)*stride+2*k]*BT[0+j*stride+2*k]; + d06+=C[0+(i+ 6)*stride+2*k]*BT[0+j*stride+2*k]; + d07+=C[1+(i+ 6)*stride+2*k]*BT[0+j*stride+2*k]; + d08+=C[0+(i+ 8)*stride+2*k]*BT[0+j*stride+2*k]; + d09+=C[1+(i+ 8)*stride+2*k]*BT[0+j*stride+2*k]; + d10+=C[0+(i+10)*stride+2*k]*BT[0+j*stride+2*k]; + d11+=C[1+(i+10)*stride+2*k]*BT[0+j*stride+2*k]; + d12+=C[0+(i+12)*stride+2*k]*BT[0+j*stride+2*k]; + d13+=C[1+(i+12)*stride+2*k]*BT[0+j*stride+2*k]; + d14+=C[0+(i+14)*stride+2*k]*BT[0+j*stride+2*k]; + d15+=C[1+(i+14)*stride+2*k]*BT[0+j*stride+2*k]; + } + D[0+(i+ 0)*stride+2*(j+0)] = d00; + D[1+(i+ 0)*stride+2*(j+0)] = d01; + D[0+(i+ 2)*stride+2*(j+0)] = d02; + D[1+(i+ 2)*stride+2*(j+0)] = d03; + D[0+(i+ 4)*stride+2*(j+0)] = d04; + D[1+(i+ 4)*stride+2*(j+0)] = d05; + D[0+(i+ 6)*stride+2*(j+0)] = d06; + D[1+(i+ 6)*stride+2*(j+0)] = d07; + D[0+(i+ 8)*stride+2*(j+0)] = d08; + D[1+(i+ 8)*stride+2*(j+0)] = d09; + D[0+(i+10)*stride+2*(j+0)] = d10; + D[1+(i+10)*stride+2*(j+0)] = d11; + D[0+(i+12)*stride+2*(j+0)] = d12; + D[1+(i+12)*stride+2*(j+0)] = d13; + D[0+(i+14)*stride+2*(j+0)] = d14; + D[1+(i+14)*stride+2*(j+0)] = d15; + } + + { + double d00 = D[0+(i+ 0)*stride+2*(j+1)]; + double d01 = D[1+(i+ 0)*stride+2*(j+1)]; + double d02 = D[0+(i+ 2)*stride+2*(j+1)]; + double d03 = D[1+(i+ 2)*stride+2*(j+1)]; + double d04 = D[0+(i+ 4)*stride+2*(j+1)]; + double d05 = D[1+(i+ 4)*stride+2*(j+1)]; + double d06 = D[0+(i+ 6)*stride+2*(j+1)]; + double d07 = D[1+(i+ 6)*stride+2*(j+1)]; + double d08 = D[0+(i+ 8)*stride+2*(j+1)]; + double d09 = D[1+(i+ 8)*stride+2*(j+1)]; + double d10 = D[0+(i+10)*stride+2*(j+1)]; + double d11 = D[1+(i+10)*stride+2*(j+1)]; + double d12 = D[0+(i+12)*stride+2*(j+1)]; + double d13 = D[1+(i+12)*stride+2*(j+1)]; + double d14 = D[0+(i+14)*stride+2*(j+1)]; + double d15 = D[1+(i+14)*stride+2*(j+1)]; + for (int k = 0; k < baseOrder; k++) + { + d00+=C[0+(i+ 0)*stride+2*k]*BT[1+j*stride+2*k]; + d01+=C[1+(i+ 0)*stride+2*k]*BT[1+j*stride+2*k]; + d02+=C[0+(i+ 2)*stride+2*k]*BT[1+j*stride+2*k]; + d03+=C[1+(i+ 2)*stride+2*k]*BT[1+j*stride+2*k]; + d04+=C[0+(i+ 4)*stride+2*k]*BT[1+j*stride+2*k]; + d05+=C[1+(i+ 4)*stride+2*k]*BT[1+j*stride+2*k]; + d06+=C[0+(i+ 6)*stride+2*k]*BT[1+j*stride+2*k]; + d07+=C[1+(i+ 6)*stride+2*k]*BT[1+j*stride+2*k]; + d08+=C[0+(i+ 8)*stride+2*k]*BT[1+j*stride+2*k]; + d09+=C[1+(i+ 8)*stride+2*k]*BT[1+j*stride+2*k]; + d10+=C[0+(i+10)*stride+2*k]*BT[1+j*stride+2*k]; + d11+=C[1+(i+10)*stride+2*k]*BT[1+j*stride+2*k]; + d12+=C[0+(i+12)*stride+2*k]*BT[1+j*stride+2*k]; + d13+=C[1+(i+12)*stride+2*k]*BT[1+j*stride+2*k]; + d14+=C[0+(i+14)*stride+2*k]*BT[1+j*stride+2*k]; + d15+=C[1+(i+14)*stride+2*k]*BT[1+j*stride+2*k]; + } + D[0+(i+ 0)*stride+2*(j+1)] = d00; + D[1+(i+ 0)*stride+2*(j+1)] = d01; + D[0+(i+ 2)*stride+2*(j+1)] = d02; + D[1+(i+ 2)*stride+2*(j+1)] = d03; + D[0+(i+ 4)*stride+2*(j+1)] = d04; + D[1+(i+ 4)*stride+2*(j+1)] = d05; + D[0+(i+ 6)*stride+2*(j+1)] = d06; + D[1+(i+ 6)*stride+2*(j+1)] = d07; + D[0+(i+ 8)*stride+2*(j+1)] = d08; + D[1+(i+ 8)*stride+2*(j+1)] = d09; + D[0+(i+10)*stride+2*(j+1)] = d10; + D[1+(i+10)*stride+2*(j+1)] = d11; + D[0+(i+12)*stride+2*(j+1)] = d12; + D[1+(i+12)*stride+2*(j+1)] = d13; + D[0+(i+14)*stride+2*(j+1)] = d14; + D[1+(i+14)*stride+2*(j+1)] = d15; + } + } + #endif + + #if 0 + // Begin SSE + for (int j = 0; j < baseOrder; j+=2) + for (int i = 0; i < baseOrder; i+=16) + { + { + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+0)]); + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+0)]); + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+0)]); + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+0)]); + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+0)]); + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+0)]); + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+0)]); + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+0)]); + for (int k = 0; k < baseOrder; k++) + { + __m128d bt0 = _mm_load1_pd(&BT[0+j*stride+2*k]); + d00+=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt0; + d02+=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt0; + d04+=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt0; + d06+=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt0; + d08+=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt0; + d10+=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt0; + d12+=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt0; + d14+=_mm_load_pd(&C[0+(i+14)*stride+2*k])*bt0; + } + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+0)], d00); + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+0)], d02); + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+0)], d04); + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+0)], d06); + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+0)], d08); + _mm_store_pd(&D[0+(i+10)*stride+2*(j+0)], d10); + _mm_store_pd(&D[0+(i+12)*stride+2*(j+0)], d12); + _mm_store_pd(&D[0+(i+14)*stride+2*(j+0)], d14); + } + + { + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+1)]); + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+1)]); + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+1)]); + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+1)]); + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+1)]); + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+1)]); + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+1)]); + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+1)]); + for (int k = 0; k < baseOrder; k++) + { + __m128d bt0 = _mm_load1_pd(&BT[1+j*stride+2*k]); + d00+=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt0; + d02+=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt0; + d04+=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt0; + d06+=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt0; + d08+=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt0; + d10+=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt0; + d12+=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt0; + d14+=_mm_load_pd(&C[0+(i+14)*stride+2*k])*bt0; + } + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+1)], d00); + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+1)], d02); + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+1)], d04); + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+1)], d06); + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+1)], d08); + _mm_store_pd(&D[0+(i+10)*stride+2*(j+1)], d10); + _mm_store_pd(&D[0+(i+12)*stride+2*(j+1)], d12); + _mm_store_pd(&D[0+(i+14)*stride+2*(j+1)], d14); + } + } + #endif + + #if 0 + // Tweak SSE + #define MM_LOAD1_PD(a,b) \ + { \ + __asm__("movlpd %1, %0" : "=x" (a) : "m"(*b)); \ + __asm__("movhpd %1, %0" : "=x" (a) : "m"(*b), "0" (a)); \ + } + #define MM_LOAD1U_PD(a,b) \ + { \ + __asm__("movlpd %1, %0" : "=x" (a) : "m"(*b)); \ + __asm__("movhpd %1, %0" : "=x" (a) : "m"(*b), "0" (a)); \ + } + #define MM_MUL_PD(out,addr) \ + { out = _mm_mul_pd(out, *(__m128d*)addr); } + for (int j = 0; j < baseOrder; j+=2) + for (int i = 0; i < baseOrder; i+=16) + { + { + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+0)]); + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+0)]); + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+0)]); + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+0)]); + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+0)]); + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+0)]); + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+0)]); + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+0)]); + for (int k = 0; k < baseOrder; k++) + { + __m128d bt0; + MM_LOAD1_PD(bt0, &BT[0+j*stride+2*k]); + d00+=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt0; + d02+=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt0; + d04+=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt0; + d06+=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt0; + d08+=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt0; + d10+=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt0; + d12+=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt0; + MM_MUL_PD(bt0, &C[0+(i+14)*stride+2*k]); + d14+=bt0; + } + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+0)], d00); + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+0)], d02); + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+0)], d04); + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+0)], d06); + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+0)], d08); + _mm_store_pd(&D[0+(i+10)*stride+2*(j+0)], d10); + _mm_store_pd(&D[0+(i+12)*stride+2*(j+0)], d12); + _mm_store_pd(&D[0+(i+14)*stride+2*(j+0)], d14); + } + + { + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+1)]); + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+1)]); + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+1)]); + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+1)]); + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+1)]); + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+1)]); + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+1)]); + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+1)]); + for (int k = 0; k < baseOrder; k++) + { + __m128d bt1; + MM_LOAD1U_PD(bt1, &BT[1+j*stride+2*k]); + d00+=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt1; + d02+=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt1; + d04+=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt1; + d06+=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt1; + d08+=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt1; + d10+=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt1; + d12+=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt1; + MM_MUL_PD(bt1, &C[0+(i+14)*stride+2*k]); + d14+=bt1; + } + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+1)], d00); + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+1)], d02); + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+1)], d04); + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+1)], d06); + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+1)], d08); + _mm_store_pd(&D[0+(i+10)*stride+2*(j+1)], d10); + _mm_store_pd(&D[0+(i+12)*stride+2*(j+1)], d12); + _mm_store_pd(&D[0+(i+14)*stride+2*(j+1)], d14); + } + } + #endif + + #if 0 + // Factor and unroll k + #define MM_LOAD1_PD(a,b) \ + { \ + __asm__("movlpd %1, %0" : "=x" (a) : "m"(*b)); \ + + __asm__("movhpd %1, %0" : "=x" (a) : "m"(*b), "0" (a)); \ + } + #define MM_LOAD1U_PD(a,b) \ + { \ + __asm__("movlpd %1, %0" : "=x" (a) : "m"(*b)); \ + __asm__("movhpd %1, %0" : "=x" (a) : "m"(*b), "0" (a)); \ + } + #define MM_MUL_PD(out,addr) \ + { out = _mm_mul_pd(out, *(__m128d*)addr); } + #define BLOCK0_0(i,j,k) \ + { \ + __m128d bt0; \ + MM_LOAD1_PD(bt0, &BT[0+j*stride+2*k]); \ + d00+=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt0; \ + d02+=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt0; \ + d04+=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt0; \ + d06+=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt0; \ + d08+=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt0; \ + d10+=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt0; \ + d12+=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt0; \ + MM_MUL_PD(bt0, &C[0+(i+14)*stride+2*k]); \ + d14+=bt0; \ + } + #define BLOCK0_1(i,j,k) \ + { \ + __m128d bt1; \ + MM_LOAD1U_PD(bt1, &BT[1+j*stride+2*k]); \ + d00+=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt1; \ + d02+=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt1; \ + d04+=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt1; \ + d06+=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt1; \ + d08+=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt1; \ + d10+=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt1; \ + d12+=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt1; \ + MM_MUL_PD(bt1, &C[0+(i+14)*stride+2*k]); \ + d14+=bt1; \ + } + for (int j = 0; j < baseOrder; j+=2) + for (int i = 0; i < baseOrder; i+=16) + { + { + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+0)]); + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+0)]); + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+0)]); + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+0)]); + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+0)]); + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+0)]); + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+0)]); + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+0)]); + for (int k = 0; k < baseOrder; k+=32) + { + BLOCK0_0(i,j,(k+ 0)); + BLOCK0_0(i,j,(k+ 1)); + BLOCK0_0(i,j,(k+ 2)); + BLOCK0_0(i,j,(k+ 3)); + BLOCK0_0(i,j,(k+ 4)); + BLOCK0_0(i,j,(k+ 5)); + BLOCK0_0(i,j,(k+ 6)); + BLOCK0_0(i,j,(k+ 7)); + BLOCK0_0(i,j,(k+ 8)); + BLOCK0_0(i,j,(k+ 9)); + BLOCK0_0(i,j,(k+10)); + BLOCK0_0(i,j,(k+11)); + BLOCK0_0(i,j,(k+12)); + BLOCK0_0(i,j,(k+13)); + BLOCK0_0(i,j,(k+14)); + BLOCK0_0(i,j,(k+15)); + BLOCK0_0(i,j,(k+16)); + BLOCK0_0(i,j,(k+17)); + BLOCK0_0(i,j,(k+18)); + BLOCK0_0(i,j,(k+19)); + BLOCK0_0(i,j,(k+20)); + BLOCK0_0(i,j,(k+21)); + BLOCK0_0(i,j,(k+22)); + BLOCK0_0(i,j,(k+23)); + BLOCK0_0(i,j,(k+24)); + BLOCK0_0(i,j,(k+25)); + BLOCK0_0(i,j,(k+26)); + BLOCK0_0(i,j,(k+27)); + BLOCK0_0(i,j,(k+28)); + BLOCK0_0(i,j,(k+29)); + BLOCK0_0(i,j,(k+30)); + BLOCK0_0(i,j,(k+31)); + } + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+0)], d00); + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+0)], d02); + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+0)], d04); + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+0)], d06); + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+0)], d08); + _mm_store_pd(&D[0+(i+10)*stride+2*(j+0)], d10); + _mm_store_pd(&D[0+(i+12)*stride+2*(j+0)], d12); + _mm_store_pd(&D[0+(i+14)*stride+2*(j+0)], d14); + } + + { + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+1)]); + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+1)]); + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+1)]); + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+1)]); + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+1)]); + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+1)]); + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+1)]); + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+1)]); + for (int k = 0; k < baseOrder; k+=32) + { + BLOCK0_1(i,j,(k+ 0)); + BLOCK0_1(i,j,(k+ 1)); + BLOCK0_1(i,j,(k+ 2)); + BLOCK0_1(i,j,(k+ 3)); + BLOCK0_1(i,j,(k+ 4)); + BLOCK0_1(i,j,(k+ 5)); + BLOCK0_1(i,j,(k+ 6)); + BLOCK0_1(i,j,(k+ 7)); + BLOCK0_1(i,j,(k+ 8)); + BLOCK0_1(i,j,(k+ 9)); + BLOCK0_1(i,j,(k+10)); + BLOCK0_1(i,j,(k+11)); + BLOCK0_1(i,j,(k+12)); + BLOCK0_1(i,j,(k+13)); + BLOCK0_1(i,j,(k+14)); + BLOCK0_1(i,j,(k+15)); + BLOCK0_1(i,j,(k+16)); + BLOCK0_1(i,j,(k+17)); + BLOCK0_1(i,j,(k+18)); + BLOCK0_1(i,j,(k+19)); + BLOCK0_1(i,j,(k+20)); + BLOCK0_1(i,j,(k+21)); + BLOCK0_1(i,j,(k+22)); + BLOCK0_1(i,j,(k+23)); + BLOCK0_1(i,j,(k+24)); + BLOCK0_1(i,j,(k+25)); + BLOCK0_1(i,j,(k+26)); + BLOCK0_1(i,j,(k+27)); + BLOCK0_1(i,j,(k+28)); + BLOCK0_1(i,j,(k+29)); + BLOCK0_1(i,j,(k+30)); + BLOCK0_1(i,j,(k+31)); + } + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+1)], d00); + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+1)], d02); + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+1)], d04); + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+1)], d06); + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+1)], d08); + _mm_store_pd(&D[0+(i+10)*stride+2*(j+1)], d10); + _mm_store_pd(&D[0+(i+12)*stride+2*(j+1)], d12); + _mm_store_pd(&D[0+(i+14)*stride+2*(j+1)], d14); + } + } + #endif + + #if 1 + // Factor and unroll i + #define MM_LOAD1_PD(a,b) \ + { \ + __asm__("movlpd %1, %0" : "=x" (a) : "m"(*b)); \ + __asm__("movhpd %1, %0" : "=x" (a) : "m"(*b), "0" (a)); \ + } + #define MM_LOAD1U_PD(a,b) \ + { \ + __asm__("movlpd %1, %0" : "=x" (a) : "m"(*b)); \ + __asm__("movhpd %1, %0" : "=x" (a) : "m"(*b), "0" (a)); \ + } + #define MM_MUL_PD(out,addr) \ + { out = _mm_mul_pd(out, *(__m128d*)addr); } + #define BLOCK0_0(i,j,k) \ + { \ + __m128d bt0; \ + MM_LOAD1_PD(bt0, &BT[0+j*stride+2*k]); \ + d00+=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt0; \ + d02+=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt0; \ + d04+=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt0; \ + d06+=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt0; \ + d08+=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt0; \ + d10+=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt0; \ + d12+=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt0; \ + MM_MUL_PD(bt0, &C[0+(i+14)*stride+2*k]); \ + d14+=bt0; \ + } + #define BLOCK0_1(i,j,k) \ + { \ + __m128d bt1; \ + MM_LOAD1U_PD(bt1, &BT[1+j*stride+2*k]); \ + d00+=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt1; \ + d02+=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt1; \ + d04+=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt1; \ + d06+=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt1; \ + d08+=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt1; \ + d10+=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt1; \ + d12+=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt1; \ + MM_MUL_PD(bt1, &C[0+(i+14)*stride+2*k]); \ + d14+=bt1; \ + } + #define BLOCK1_0(i,j) \ + { \ + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+0)]); \ + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+0)]); \ + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+0)]); \ + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+0)]); \ + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+0)]); \ + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+0)]); \ + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+0)]); \ + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+0)]); \ + for (int k = 0; k < baseOrder; k+=32) \ + { \ + BLOCK0_0(i,j,(k+ 0)); \ + BLOCK0_0(i,j,(k+ 1)); \ + BLOCK0_0(i,j,(k+ 2)); \ + BLOCK0_0(i,j,(k+ 3)); \ + BLOCK0_0(i,j,(k+ 4)); \ + BLOCK0_0(i,j,(k+ 5)); \ + BLOCK0_0(i,j,(k+ 6)); \ + BLOCK0_0(i,j,(k+ 7)); \ + BLOCK0_0(i,j,(k+ 8)); \ + BLOCK0_0(i,j,(k+ 9)); \ + BLOCK0_0(i,j,(k+10)); \ + BLOCK0_0(i,j,(k+11)); \ + BLOCK0_0(i,j,(k+12)); \ + BLOCK0_0(i,j,(k+13)); \ + BLOCK0_0(i,j,(k+14)); \ + BLOCK0_0(i,j,(k+15)); \ + BLOCK0_0(i,j,(k+16)); \ + BLOCK0_0(i,j,(k+17)); \ + BLOCK0_0(i,j,(k+18)); \ + BLOCK0_0(i,j,(k+19)); \ + BLOCK0_0(i,j,(k+20)); \ + BLOCK0_0(i,j,(k+21)); \ + BLOCK0_0(i,j,(k+22)); \ + BLOCK0_0(i,j,(k+23)); \ + BLOCK0_0(i,j,(k+24)); \ + BLOCK0_0(i,j,(k+25)); \ + BLOCK0_0(i,j,(k+26)); \ + BLOCK0_0(i,j,(k+27)); \ + BLOCK0_0(i,j,(k+28)); \ + BLOCK0_0(i,j,(k+29)); \ + BLOCK0_0(i,j,(k+30)); \ + BLOCK0_0(i,j,(k+31)); \ + } \ + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+0)], d00); \ + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+0)], d02); \ + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+0)], d04); \ + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+0)], d06); \ + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+0)], d08); \ + _mm_store_pd(&D[0+(i+10)*stride+2*(j+0)], d10); \ + _mm_store_pd(&D[0+(i+12)*stride+2*(j+0)], d12); \ + _mm_store_pd(&D[0+(i+14)*stride+2*(j+0)], d14); \ + } + #define BLOCK1_1(i,j) \ + { \ + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+1)]); \ + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+1)]); \ + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+1)]); \ + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+1)]); \ + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+1)]); \ + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+1)]); \ + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+1)]); \ + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+1)]); \ + for (int k = 0; k < baseOrder; k+=32) \ + { \ + BLOCK0_1(i,j,(k+ 0)); \ + BLOCK0_1(i,j,(k+ 1)); \ + BLOCK0_1(i,j,(k+ 2)); \ + BLOCK0_1(i,j,(k+ 3)); \ + BLOCK0_1(i,j,(k+ 4)); \ + BLOCK0_1(i,j,(k+ 5)); \ + BLOCK0_1(i,j,(k+ 6)); \ + BLOCK0_1(i,j,(k+ 7)); \ + BLOCK0_1(i,j,(k+ 8)); \ + BLOCK0_1(i,j,(k+ 9)); \ + BLOCK0_1(i,j,(k+10)); \ + BLOCK0_1(i,j,(k+11)); \ + BLOCK0_1(i,j,(k+12)); \ + BLOCK0_1(i,j,(k+13)); \ + BLOCK0_1(i,j,(k+14)); \ + BLOCK0_1(i,j,(k+15)); \ + BLOCK0_1(i,j,(k+16)); \ + BLOCK0_1(i,j,(k+17)); \ + BLOCK0_1(i,j,(k+18)); \ + BLOCK0_1(i,j,(k+19)); \ + BLOCK0_1(i,j,(k+20)); \ + BLOCK0_1(i,j,(k+21)); \ + BLOCK0_1(i,j,(k+22)); \ + BLOCK0_1(i,j,(k+23)); \ + BLOCK0_1(i,j,(k+24)); \ + BLOCK0_1(i,j,(k+25)); \ + BLOCK0_1(i,j,(k+26)); \ + BLOCK0_1(i,j,(k+27)); \ + BLOCK0_1(i,j,(k+28)); \ + BLOCK0_1(i,j,(k+29)); \ + BLOCK0_1(i,j,(k+30)); \ + BLOCK0_1(i,j,(k+31)); \ + } \ + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+1)], d00); \ + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+1)], d02); \ + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+1)], d04); \ + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+1)], d06); \ + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+1)], d08); \ + _mm_store_pd(&D[0+(i+10)*stride+2*(j+1)], d10); \ + _mm_store_pd(&D[0+(i+12)*stride+2*(j+1)], d12); \ + _mm_store_pd(&D[0+(i+14)*stride+2*(j+1)], d14); \ + } + + for (int j = 0; j < baseOrder; j+=2) + { + BLOCK1_0( 0,j); + BLOCK1_1( 0,j); + BLOCK1_0(16,j); + BLOCK1_1(16,j); + } + #endif + +} + +// Avoid conflicts with further defitions + +#undef MM_LOAD1_PD +#undef MM_LOAD1U_PD +#undef MM_MUL_PD +#undef BLOCK0_0 +#undef BLOCK0_1 +#undef BLOCK1_0 +#undef BLOCK1_1 + + +template <unsigned long MaskA, typename PA, + unsigned long MaskB, typename PB, + unsigned long MaskC, typename PC, + typename Backup> +void gen_platform_dmat_dmat_mult_ft<morton_dense<double, MaskA, PA>, morton_dense<double, MaskB, PB>, + morton_dense<double, MaskC, PC>, assign::minus_sum, Backup>:: +mult_ass(double * D, double * C, double * BT) const +{ + // std::cout << "in Assembly\n"; + const int baseOrder= 32, + stride = baseOrder; + + /* + double * restrict D = aa + ((d*baseSize)&(rowMask|colMask)); + double * restrict C = aa + ((c*baseSize)&(rowMask|colMask)); + double * restrict BT = aa + ((d*baseSize)&colMask)/2 + + ((c*baseSize)&colMask); + */ + +#if 0 + for (int i = 0; i < baseOrder; i+=2) + for (int j = 0; j < baseOrder; j+=2) + for (int k = 0; k < baseOrder; k++) + { + D[0+(i)*stride+2*(j+0)] -= C[0+(i)*stride+2*k] * BT[0+(j)*stride+2*k]; + D[0+(i)*stride+2*(j+1)] -= C[0+(i)*stride+2*k] * BT[1+(j)*stride+2*k]; + D[1+(i)*stride+2*(j+0)] -= C[1+(i)*stride+2*k] * BT[0+(j)*stride+2*k]; + D[1+(i)*stride+2*(j+1)] -= C[1+(i)*stride+2*k] * BT[1+(j)*stride+2*k]; + } +#endif + +#if 0 + // Reorder loops (Ordering based on where the target code is going). + for (int j = 0; j < baseOrder; j+=2) + for (int i = 0; i < baseOrder; i+=16) + { + for (int k = 0; k < baseOrder; k++) + { + for (int i2 = i; i2 < i+16; i2+=2) + { + D[0+(i2)*stride+2*(j+0)] -= C[0+(i2)*stride+2*k] * BT[0+(j)*stride+2*k]; + D[1+(i2)*stride+2*(j+0)] -= C[1+(i2)*stride+2*k] * BT[0+(j)*stride+2*k]; + } + } + for (int k = 0; k < baseOrder; k++) + { + for (int i2 = i; i2 < i+16; i2+=2) + { + D[0+(i2)*stride+2*(j+1)] -= C[0+(i2)*stride+2*k] * BT[1+(j)*stride+2*k]; + D[1+(i2)*stride+2*(j+1)] -= C[1+(i2)*stride+2*k] * BT[1+(j)*stride+2*k]; + } + } + } +#endif + +#if 0 + // Unroll i2 + + for (int j = 0; j < baseOrder; j+=2) + for (int i = 0; i < baseOrder; i+=16) + { + for (int k = 0; k < baseOrder; k++) + { + D[0+(i+ 0)*stride+2*(j+0)]-=C[0+(i+ 0)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+ 0)*stride+2*(j+0)]-=C[1+(i+ 0)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+ 2)*stride+2*(j+0)]-=C[0+(i+ 2)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+ 2)*stride+2*(j+0)]-=C[1+(i+ 2)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+ 4)*stride+2*(j+0)]-=C[0+(i+ 4)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+ 4)*stride+2*(j+0)]-=C[1+(i+ 4)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+ 6)*stride+2*(j+0)]-=C[0+(i+ 6)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+ 6)*stride+2*(j+0)]-=C[1+(i+ 6)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+ 8)*stride+2*(j+0)]-=C[0+(i+ 8)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+ 8)*stride+2*(j+0)]-=C[1+(i+ 8)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+10)*stride+2*(j+0)]-=C[0+(i+10)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+10)*stride+2*(j+0)]-=C[1+(i+10)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+12)*stride+2*(j+0)]-=C[0+(i+12)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+12)*stride+2*(j+0)]-=C[1+(i+12)*stride+2*k]*BT[0+j*stride+2*k]; + D[0+(i+14)*stride+2*(j+0)]-=C[0+(i+14)*stride+2*k]*BT[0+j*stride+2*k]; + D[1+(i+14)*stride+2*(j+0)]-=C[1+(i+14)*stride+2*k]*BT[0+j*stride+2*k]; + } + for (int k = 0; k < baseOrder; k++) + { + D[0+(i+ 0)*stride+2*(j+1)]-=C[0+(i+ 0)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+ 0)*stride+2*(j+1)]-=C[1+(i+ 0)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+ 2)*stride+2*(j+1)]-=C[0+(i+ 2)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+ 2)*stride+2*(j+1)]-=C[1+(i+ 2)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+ 4)*stride+2*(j+1)]-=C[0+(i+ 4)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+ 4)*stride+2*(j+1)]-=C[1+(i+ 4)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+ 6)*stride+2*(j+1)]-=C[0+(i+ 6)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+ 6)*stride+2*(j+1)]-=C[1+(i+ 6)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+ 8)*stride+2*(j+1)]-=C[0+(i+ 8)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+ 8)*stride+2*(j+1)]-=C[1+(i+ 8)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+10)*stride+2*(j+1)]-=C[0+(i+10)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+10)*stride+2*(j+1)]-=C[1+(i+10)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+12)*stride+2*(j+1)]-=C[0+(i+12)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+12)*stride+2*(j+1)]-=C[1+(i+12)*stride+2*k]*BT[1+j*stride+2*k]; + D[0+(i+14)*stride+2*(j+1)]-=C[0+(i+14)*stride+2*k]*BT[1+j*stride+2*k]; + D[1+(i+14)*stride+2*(j+1)]-=C[1+(i+14)*stride+2*k]*BT[1+j*stride+2*k]; + } + } +#endif + +#if 0 + // Prep k + for (int j = 0; j < baseOrder; j+=2) + for (int i = 0; i < baseOrder; i+=16) + { + { + double d00 = D[0+(i+ 0)*stride+2*(j+0)]; + double d01 = D[1+(i+ 0)*stride+2*(j+0)]; + double d02 = D[0+(i+ 2)*stride+2*(j+0)]; + double d03 = D[1+(i+ 2)*stride+2*(j+0)]; + double d04 = D[0+(i+ 4)*stride+2*(j+0)]; + double d05 = D[1+(i+ 4)*stride+2*(j+0)]; + double d06 = D[0+(i+ 6)*stride+2*(j+0)]; + double d07 = D[1+(i+ 6)*stride+2*(j+0)]; + double d08 = D[0+(i+ 8)*stride+2*(j+0)]; + double d09 = D[1+(i+ 8)*stride+2*(j+0)]; + double d10 = D[0+(i+10)*stride+2*(j+0)]; + double d11 = D[1+(i+10)*stride+2*(j+0)]; + double d12 = D[0+(i+12)*stride+2*(j+0)]; + double d13 = D[1+(i+12)*stride+2*(j+0)]; + double d14 = D[0+(i+14)*stride+2*(j+0)]; + double d15 = D[1+(i+14)*stride+2*(j+0)]; + for (int k = 0; k < baseOrder; k++) + { + d00-=C[0+(i+ 0)*stride+2*k]*BT[0+j*stride+2*k]; + d01-=C[1+(i+ 0)*stride+2*k]*BT[0+j*stride+2*k]; + d02-=C[0+(i+ 2)*stride+2*k]*BT[0+j*stride+2*k]; + d03-=C[1+(i+ 2)*stride+2*k]*BT[0+j*stride+2*k]; + d04-=C[0+(i+ 4)*stride+2*k]*BT[0+j*stride+2*k]; + d05-=C[1+(i+ 4)*stride+2*k]*BT[0+j*stride+2*k]; + d06-=C[0+(i+ 6)*stride+2*k]*BT[0+j*stride+2*k]; + d07-=C[1+(i+ 6)*stride+2*k]*BT[0+j*stride+2*k]; + d08-=C[0+(i+ 8)*stride+2*k]*BT[0+j*stride+2*k]; + d09-=C[1+(i+ 8)*stride+2*k]*BT[0+j*stride+2*k]; + d10-=C[0+(i+10)*stride+2*k]*BT[0+j*stride+2*k]; + d11-=C[1+(i+10)*stride+2*k]*BT[0+j*stride+2*k]; + d12-=C[0+(i+12)*stride+2*k]*BT[0+j*stride+2*k]; + d13-=C[1+(i+12)*stride+2*k]*BT[0+j*stride+2*k]; + d14-=C[0+(i+14)*stride+2*k]*BT[0+j*stride+2*k]; + d15-=C[1+(i+14)*stride+2*k]*BT[0+j*stride+2*k]; + } + D[0+(i+ 0)*stride+2*(j+0)] = d00; + D[1+(i+ 0)*stride+2*(j+0)] = d01; + D[0+(i+ 2)*stride+2*(j+0)] = d02; + D[1+(i+ 2)*stride+2*(j+0)] = d03; + D[0+(i+ 4)*stride+2*(j+0)] = d04; + D[1+(i+ 4)*stride+2*(j+0)] = d05; + D[0+(i+ 6)*stride+2*(j+0)] = d06; + D[1+(i+ 6)*stride+2*(j+0)] = d07; + D[0+(i+ 8)*stride+2*(j+0)] = d08; + D[1+(i+ 8)*stride+2*(j+0)] = d09; + D[0+(i+10)*stride+2*(j+0)] = d10; + D[1+(i+10)*stride+2*(j+0)] = d11; + D[0+(i+12)*stride+2*(j+0)] = d12; + D[1+(i+12)*stride+2*(j+0)] = d13; + D[0+(i+14)*stride+2*(j+0)] = d14; + D[1+(i+14)*stride+2*(j+0)] = d15; + } + + { + double d00 = D[0+(i+ 0)*stride+2*(j+1)]; + double d01 = D[1+(i+ 0)*stride+2*(j+1)]; + double d02 = D[0+(i+ 2)*stride+2*(j+1)]; + double d03 = D[1+(i+ 2)*stride+2*(j+1)]; + double d04 = D[0+(i+ 4)*stride+2*(j+1)]; + double d05 = D[1+(i+ 4)*stride+2*(j+1)]; + double d06 = D[0+(i+ 6)*stride+2*(j+1)]; + double d07 = D[1+(i+ 6)*stride+2*(j+1)]; + double d08 = D[0+(i+ 8)*stride+2*(j+1)]; + double d09 = D[1+(i+ 8)*stride+2*(j+1)]; + double d10 = D[0+(i+10)*stride+2*(j+1)]; + double d11 = D[1+(i+10)*stride+2*(j+1)]; + double d12 = D[0+(i+12)*stride+2*(j+1)]; + double d13 = D[1+(i+12)*stride+2*(j+1)]; + double d14 = D[0+(i+14)*stride+2*(j+1)]; + double d15 = D[1+(i+14)*stride+2*(j+1)]; + for (int k = 0; k < baseOrder; k++) + { + d00-=C[0+(i+ 0)*stride+2*k]*BT[1+j*stride+2*k]; + d01-=C[1+(i+ 0)*stride+2*k]*BT[1+j*stride+2*k]; + d02-=C[0+(i+ 2)*stride+2*k]*BT[1+j*stride+2*k]; + d03-=C[1+(i+ 2)*stride+2*k]*BT[1+j*stride+2*k]; + d04-=C[0+(i+ 4)*stride+2*k]*BT[1+j*stride+2*k]; + d05-=C[1+(i+ 4)*stride+2*k]*BT[1+j*stride+2*k]; + d06-=C[0+(i+ 6)*stride+2*k]*BT[1+j*stride+2*k]; + d07-=C[1+(i+ 6)*stride+2*k]*BT[1+j*stride+2*k]; + d08-=C[0+(i+ 8)*stride+2*k]*BT[1+j*stride+2*k]; + d09-=C[1+(i+ 8)*stride+2*k]*BT[1+j*stride+2*k]; + d10-=C[0+(i+10)*stride+2*k]*BT[1+j*stride+2*k]; + d11-=C[1+(i+10)*stride+2*k]*BT[1+j*stride+2*k]; + d12-=C[0+(i+12)*stride+2*k]*BT[1+j*stride+2*k]; + d13-=C[1+(i+12)*stride+2*k]*BT[1+j*stride+2*k]; + d14-=C[0+(i+14)*stride+2*k]*BT[1+j*stride+2*k]; + d15-=C[1+(i+14)*stride+2*k]*BT[1+j*stride+2*k]; + } + D[0+(i+ 0)*stride+2*(j+1)] = d00; + D[1+(i+ 0)*stride+2*(j+1)] = d01; + D[0+(i+ 2)*stride+2*(j+1)] = d02; + D[1+(i+ 2)*stride+2*(j+1)] = d03; + D[0+(i+ 4)*stride+2*(j+1)] = d04; + D[1+(i+ 4)*stride+2*(j+1)] = d05; + D[0+(i+ 6)*stride+2*(j+1)] = d06; + D[1+(i+ 6)*stride+2*(j+1)] = d07; + D[0+(i+ 8)*stride+2*(j+1)] = d08; + D[1+(i+ 8)*stride+2*(j+1)] = d09; + D[0+(i+10)*stride+2*(j+1)] = d10; + D[1+(i+10)*stride+2*(j+1)] = d11; + D[0+(i+12)*stride+2*(j+1)] = d12; + D[1+(i+12)*stride+2*(j+1)] = d13; + D[0+(i+14)*stride+2*(j+1)] = d14; + D[1+(i+14)*stride+2*(j+1)] = d15; + } + } +#endif + +#if 0 + // Begin SSE + for (int j = 0; j < baseOrder; j+=2) + for (int i = 0; i < baseOrder; i+=16) + { + { + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+0)]); + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+0)]); + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+0)]); + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+0)]); + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+0)]); + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+0)]); + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+0)]); + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+0)]); + for (int k = 0; k < baseOrder; k++) + { + __m128d bt0 = _mm_load1_pd(&BT[0+j*stride+2*k]); + d00-=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt0; + d02-=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt0; + d04-=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt0; + d06-=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt0; + d08-=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt0; + d10-=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt0; + d12-=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt0; + d14-=_mm_load_pd(&C[0+(i+14)*stride+2*k])*bt0; + } + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+0)], d00); + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+0)], d02); + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+0)], d04); + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+0)], d06); + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+0)], d08); + _mm_store_pd(&D[0+(i+10)*stride+2*(j+0)], d10); + _mm_store_pd(&D[0+(i+12)*stride+2*(j+0)], d12); + _mm_store_pd(&D[0+(i+14)*stride+2*(j+0)], d14); + } + + { + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+1)]); + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+1)]); + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+1)]); + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+1)]); + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+1)]); + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+1)]); + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+1)]); + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+1)]); + for (int k = 0; k < baseOrder; k++) + { + __m128d bt0 = _mm_load1_pd(&BT[1+j*stride+2*k]); + d00-=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt0; + d02-=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt0; + d04-=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt0; + d06-=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt0; + d08-=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt0; + d10-=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt0; + d12-=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt0; + d14-=_mm_load_pd(&C[0+(i+14)*stride+2*k])*bt0; + } + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+1)], d00); + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+1)], d02); + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+1)], d04); + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+1)], d06); + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+1)], d08); + _mm_store_pd(&D[0+(i+10)*stride+2*(j+1)], d10); + _mm_store_pd(&D[0+(i+12)*stride+2*(j+1)], d12); + _mm_store_pd(&D[0+(i+14)*stride+2*(j+1)], d14); + } + } +#endif + +#if 0 + // Tweak SSE +#define MM_LOAD1_PD(a,b) \ +{ \ + __asm__("movlpd %1, %0" : "=x" (a) : "m"(*b)); \ + __asm__("movhpd %1, %0" : "=x" (a) : "m"(*b), "0" (a)); \ +} +#define MM_LOAD1U_PD(a,b) \ +{ \ + __asm__("movlpd %1, %0" : "=x" (a) : "m"(*b)); \ + __asm__("movhpd %1, %0" : "=x" (a) : "m"(*b), "0" (a)); \ +} +#define MM_MUL_PD(out,addr) \ +{ out = _mm_mul_pd(out, *(__m128d*)addr); } + for (int j = 0; j < baseOrder; j+=2) + for (int i = 0; i < baseOrder; i+=16) + { + { + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+0)]); + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+0)]); + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+0)]); + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+0)]); + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+0)]); + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+0)]); + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+0)]); + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+0)]); + for (int k = 0; k < baseOrder; k++) + { + __m128d bt0; + MM_LOAD1_PD(bt0, &BT[0+j*stride+2*k]); + d00-=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt0; + d02-=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt0; + d04-=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt0; + d06-=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt0; + d08-=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt0; + d10-=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt0; + d12-=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt0; + MM_MUL_PD(bt0, &C[0+(i+14)*stride+2*k]); + d14-=bt0; + } + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+0)], d00); + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+0)], d02); + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+0)], d04); + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+0)], d06); + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+0)], d08); + _mm_store_pd(&D[0+(i+10)*stride+2*(j+0)], d10); + _mm_store_pd(&D[0+(i+12)*stride+2*(j+0)], d12); + _mm_store_pd(&D[0+(i+14)*stride+2*(j+0)], d14); + } + + { + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+1)]); + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+1)]); + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+1)]); + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+1)]); + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+1)]); + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+1)]); + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+1)]); + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+1)]); + for (int k = 0; k < baseOrder; k++) + { + __m128d bt1; + MM_LOAD1U_PD(bt1, &BT[1+j*stride+2*k]); + d00-=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt1; + d02-=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt1; + d04-=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt1; + d06-=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt1; + d08-=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt1; + d10-=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt1; + d12-=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt1; + MM_MUL_PD(bt1, &C[0+(i+14)*stride+2*k]); + d14-=bt1; + } + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+1)], d00); + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+1)], d02); + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+1)], d04); + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+1)], d06); + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+1)], d08); + _mm_store_pd(&D[0+(i+10)*stride+2*(j+1)], d10); + _mm_store_pd(&D[0+(i+12)*stride+2*(j+1)], d12); + _mm_store_pd(&D[0+(i+14)*stride+2*(j+1)], d14); + } + } +#endif + +#if 0 + // Factor and unroll k +#define MM_LOAD1_PD(a,b) \ +{ \ + __asm__("movlpd %1, %0" : "=x" (a) : "m"(*b)); \ + __asm__("movhpd %1, %0" : "=x" (a) : "m"(*b), "0" (a)); \ +} +#define MM_LOAD1U_PD(a,b) \ +{ \ + __asm__("movlpd %1, %0" : "=x" (a) : "m"(*b)); \ + __asm__("movhpd %1, %0" : "=x" (a) : "m"(*b), "0" (a)); \ +} +#define MM_MUL_PD(out,addr) \ +{ out = _mm_mul_pd(out, *(__m128d*)addr); } +#define BLOCK0_0(i,j,k) \ + { \ + __m128d bt0; \ + MM_LOAD1_PD(bt0, &BT[0+j*stride+2*k]); \ + d00-=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt0; \ + d02-=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt0; \ + d04-=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt0; \ + d06-=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt0; \ + d08-=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt0; \ + d10-=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt0; \ + d12-=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt0; \ + MM_MUL_PD(bt0, &C[0+(i+14)*stride+2*k]); \ + d14-=bt0; \ + } +#define BLOCK0_1(i,j,k) \ + { \ + __m128d bt1; \ + MM_LOAD1U_PD(bt1, &BT[1+j*stride+2*k]); \ + d00-=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt1; \ + d02-=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt1; \ + d04-=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt1; \ + d06-=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt1; \ + d08-=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt1; \ + d10-=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt1; \ + d12-=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt1; \ + MM_MUL_PD(bt1, &C[0+(i+14)*stride+2*k]); \ + d14-=bt1; \ + } + for (int j = 0; j < baseOrder; j+=2) + for (int i = 0; i < baseOrder; i+=16) + { + { + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+0)]); + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+0)]); + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+0)]); + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+0)]); + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+0)]); + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+0)]); + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+0)]); + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+0)]); + for (int k = 0; k < baseOrder; k+=32) + { + BLOCK0_0(i,j,(k+ 0)); + BLOCK0_0(i,j,(k+ 1)); + BLOCK0_0(i,j,(k+ 2)); + BLOCK0_0(i,j,(k+ 3)); + BLOCK0_0(i,j,(k+ 4)); + BLOCK0_0(i,j,(k+ 5)); + BLOCK0_0(i,j,(k+ 6)); + BLOCK0_0(i,j,(k+ 7)); + BLOCK0_0(i,j,(k+ 8)); + BLOCK0_0(i,j,(k+ 9)); + BLOCK0_0(i,j,(k+10)); + BLOCK0_0(i,j,(k+11)); + BLOCK0_0(i,j,(k+12)); + BLOCK0_0(i,j,(k+13)); + BLOCK0_0(i,j,(k+14)); + BLOCK0_0(i,j,(k+15)); + BLOCK0_0(i,j,(k+16)); + BLOCK0_0(i,j,(k+17)); + BLOCK0_0(i,j,(k+18)); + BLOCK0_0(i,j,(k+19)); + BLOCK0_0(i,j,(k+20)); + BLOCK0_0(i,j,(k+21)); + BLOCK0_0(i,j,(k+22)); + BLOCK0_0(i,j,(k+23)); + BLOCK0_0(i,j,(k+24)); + BLOCK0_0(i,j,(k+25)); + BLOCK0_0(i,j,(k+26)); + BLOCK0_0(i,j,(k+27)); + BLOCK0_0(i,j,(k+28)); + BLOCK0_0(i,j,(k+29)); + BLOCK0_0(i,j,(k+30)); + BLOCK0_0(i,j,(k+31)); + } + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+0)], d00); + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+0)], d02); + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+0)], d04); + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+0)], d06); + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+0)], d08); + _mm_store_pd(&D[0+(i+10)*stride+2*(j+0)], d10); + _mm_store_pd(&D[0+(i+12)*stride+2*(j+0)], d12); + _mm_store_pd(&D[0+(i+14)*stride+2*(j+0)], d14); + } + + { + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+1)]); + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+1)]); + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+1)]); + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+1)]); + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+1)]); + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+1)]); + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+1)]); + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+1)]); + for (int k = 0; k < baseOrder; k+=32) + { + BLOCK0_1(i,j,(k+ 0)); + BLOCK0_1(i,j,(k+ 1)); + BLOCK0_1(i,j,(k+ 2)); + BLOCK0_1(i,j,(k+ 3)); + BLOCK0_1(i,j,(k+ 4)); + BLOCK0_1(i,j,(k+ 5)); + BLOCK0_1(i,j,(k+ 6)); + BLOCK0_1(i,j,(k+ 7)); + BLOCK0_1(i,j,(k+ 8)); + BLOCK0_1(i,j,(k+ 9)); + BLOCK0_1(i,j,(k+10)); + BLOCK0_1(i,j,(k+11)); + BLOCK0_1(i,j,(k+12)); + BLOCK0_1(i,j,(k+13)); + BLOCK0_1(i,j,(k+14)); + BLOCK0_1(i,j,(k+15)); + BLOCK0_1(i,j,(k+16)); + BLOCK0_1(i,j,(k+17)); + BLOCK0_1(i,j,(k+18)); + BLOCK0_1(i,j,(k+19)); + BLOCK0_1(i,j,(k+20)); + BLOCK0_1(i,j,(k+21)); + BLOCK0_1(i,j,(k+22)); + BLOCK0_1(i,j,(k+23)); + BLOCK0_1(i,j,(k+24)); + BLOCK0_1(i,j,(k+25)); + BLOCK0_1(i,j,(k+26)); + BLOCK0_1(i,j,(k+27)); + BLOCK0_1(i,j,(k+28)); + BLOCK0_1(i,j,(k+29)); + BLOCK0_1(i,j,(k+30)); + BLOCK0_1(i,j,(k+31)); + } + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+1)], d00); + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+1)], d02); + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+1)], d04); + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+1)], d06); + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+1)], d08); + _mm_store_pd(&D[0+(i+10)*stride+2*(j+1)], d10); + _mm_store_pd(&D[0+(i+12)*stride+2*(j+1)], d12); + _mm_store_pd(&D[0+(i+14)*stride+2*(j+1)], d14); + } + } +#endif + +#if 1 + // Factor and unroll i +#define MM_LOAD1_PD(a,b) \ +{ \ + __asm__("movlpd %1, %0" : "=x" (a) : "m"(*b)); \ + __asm__("movhpd %1, %0" : "=x" (a) : "m"(*b), "0" (a)); \ +} +#define MM_LOAD1U_PD(a,b) \ +{ \ + __asm__("movlpd %1, %0" : "=x" (a) : "m"(*b)); \ + __asm__("movhpd %1, %0" : "=x" (a) : "m"(*b), "0" (a)); \ +} +#define MM_MUL_PD(out,addr) \ +{ out = _mm_mul_pd(out, *(__m128d*)addr); } +#define BLOCK0_0(i,j,k) \ + { \ + __m128d bt0; \ + MM_LOAD1_PD(bt0, &BT[0+j*stride+2*k]); \ + d00-=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt0; \ + d02-=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt0; \ + d04-=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt0; \ + d06-=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt0; \ + d08-=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt0; \ + d10-=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt0; \ + d12-=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt0; \ + MM_MUL_PD(bt0, &C[0+(i+14)*stride+2*k]); \ + d14-=bt0; \ + } +#define BLOCK0_1(i,j,k) \ + { \ + __m128d bt1; \ + MM_LOAD1U_PD(bt1, &BT[1+j*stride+2*k]); \ + d00-=_mm_load_pd(&C[0+(i+ 0)*stride+2*k])*bt1; \ + d02-=_mm_load_pd(&C[0+(i+ 2)*stride+2*k])*bt1; \ + d04-=_mm_load_pd(&C[0+(i+ 4)*stride+2*k])*bt1; \ + d06-=_mm_load_pd(&C[0+(i+ 6)*stride+2*k])*bt1; \ + d08-=_mm_load_pd(&C[0+(i+ 8)*stride+2*k])*bt1; \ + d10-=_mm_load_pd(&C[0+(i+10)*stride+2*k])*bt1; \ + d12-=_mm_load_pd(&C[0+(i+12)*stride+2*k])*bt1; \ + MM_MUL_PD(bt1, &C[0+(i+14)*stride+2*k]); \ + d14-=bt1; \ + } +#define BLOCK1_0(i,j) \ + { \ + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+0)]); \ + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+0)]); \ + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+0)]); \ + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+0)]); \ + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+0)]); \ + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+0)]); \ + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+0)]); \ + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+0)]); \ + for (int k = 0; k < baseOrder; k+=32) \ + { \ + BLOCK0_0(i,j,(k+ 0)); \ + BLOCK0_0(i,j,(k+ 1)); \ + BLOCK0_0(i,j,(k+ 2)); \ + BLOCK0_0(i,j,(k+ 3)); \ + BLOCK0_0(i,j,(k+ 4)); \ + BLOCK0_0(i,j,(k+ 5)); \ + BLOCK0_0(i,j,(k+ 6)); \ + BLOCK0_0(i,j,(k+ 7)); \ + BLOCK0_0(i,j,(k+ 8)); \ + BLOCK0_0(i,j,(k+ 9)); \ + BLOCK0_0(i,j,(k+10)); \ + BLOCK0_0(i,j,(k+11)); \ + BLOCK0_0(i,j,(k+12)); \ + BLOCK0_0(i,j,(k+13)); \ + BLOCK0_0(i,j,(k+14)); \ + BLOCK0_0(i,j,(k+15)); \ + BLOCK0_0(i,j,(k+16)); \ + BLOCK0_0(i,j,(k+17)); \ + BLOCK0_0(i,j,(k+18)); \ + BLOCK0_0(i,j,(k+19)); \ + BLOCK0_0(i,j,(k+20)); \ + BLOCK0_0(i,j,(k+21)); \ + BLOCK0_0(i,j,(k+22)); \ + BLOCK0_0(i,j,(k+23)); \ + BLOCK0_0(i,j,(k+24)); \ + BLOCK0_0(i,j,(k+25)); \ + BLOCK0_0(i,j,(k+26)); \ + BLOCK0_0(i,j,(k+27)); \ + BLOCK0_0(i,j,(k+28)); \ + BLOCK0_0(i,j,(k+29)); \ + BLOCK0_0(i,j,(k+30)); \ + BLOCK0_0(i,j,(k+31)); \ + } \ + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+0)], d00); \ + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+0)], d02); \ + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+0)], d04); \ + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+0)], d06); \ + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+0)], d08); \ + _mm_store_pd(&D[0+(i+10)*stride+2*(j+0)], d10); \ + _mm_store_pd(&D[0+(i+12)*stride+2*(j+0)], d12); \ + _mm_store_pd(&D[0+(i+14)*stride+2*(j+0)], d14); \ + } +#define BLOCK1_1(i,j) \ + { \ + __m128d d00 = _mm_load_pd(&D[0+(i+ 0)*stride+2*(j+1)]); \ + __m128d d02 = _mm_load_pd(&D[0+(i+ 2)*stride+2*(j+1)]); \ + __m128d d04 = _mm_load_pd(&D[0+(i+ 4)*stride+2*(j+1)]); \ + __m128d d06 = _mm_load_pd(&D[0+(i+ 6)*stride+2*(j+1)]); \ + __m128d d08 = _mm_load_pd(&D[0+(i+ 8)*stride+2*(j+1)]); \ + __m128d d10 = _mm_load_pd(&D[0+(i+10)*stride+2*(j+1)]); \ + __m128d d12 = _mm_load_pd(&D[0+(i+12)*stride+2*(j+1)]); \ + __m128d d14 = _mm_load_pd(&D[0+(i+14)*stride+2*(j+1)]); \ + for (int k = 0; k < baseOrder; k+=32) \ + { \ + BLOCK0_1(i,j,(k+ 0)); \ + BLOCK0_1(i,j,(k+ 1)); \ + BLOCK0_1(i,j,(k+ 2)); \ + BLOCK0_1(i,j,(k+ 3)); \ + BLOCK0_1(i,j,(k+ 4)); \ + BLOCK0_1(i,j,(k+ 5)); \ + BLOCK0_1(i,j,(k+ 6)); \ + BLOCK0_1(i,j,(k+ 7)); \ + BLOCK0_1(i,j,(k+ 8)); \ + BLOCK0_1(i,j,(k+ 9)); \ + BLOCK0_1(i,j,(k+10)); \ + BLOCK0_1(i,j,(k+11)); \ + BLOCK0_1(i,j,(k+12)); \ + BLOCK0_1(i,j,(k+13)); \ + BLOCK0_1(i,j,(k+14)); \ + BLOCK0_1(i,j,(k+15)); \ + BLOCK0_1(i,j,(k+16)); \ + BLOCK0_1(i,j,(k+17)); \ + BLOCK0_1(i,j,(k+18)); \ + BLOCK0_1(i,j,(k+19)); \ + BLOCK0_1(i,j,(k+20)); \ + BLOCK0_1(i,j,(k+21)); \ + BLOCK0_1(i,j,(k+22)); \ + BLOCK0_1(i,j,(k+23)); \ + BLOCK0_1(i,j,(k+24)); \ + BLOCK0_1(i,j,(k+25)); \ + BLOCK0_1(i,j,(k+26)); \ + BLOCK0_1(i,j,(k+27)); \ + BLOCK0_1(i,j,(k+28)); \ + BLOCK0_1(i,j,(k+29)); \ + BLOCK0_1(i,j,(k+30)); \ + BLOCK0_1(i,j,(k+31)); \ + } \ + _mm_store_pd(&D[0+(i+ 0)*stride+2*(j+1)], d00); \ + _mm_store_pd(&D[0+(i+ 2)*stride+2*(j+1)], d02); \ + _mm_store_pd(&D[0+(i+ 4)*stride+2*(j+1)], d04); \ + _mm_store_pd(&D[0+(i+ 6)*stride+2*(j+1)], d06); \ + _mm_store_pd(&D[0+(i+ 8)*stride+2*(j+1)], d08); \ + _mm_store_pd(&D[0+(i+10)*stride+2*(j+1)], d10); \ + _mm_store_pd(&D[0+(i+12)*stride+2*(j+1)], d12); \ + _mm_store_pd(&D[0+(i+14)*stride+2*(j+1)], d14); \ + } + + for (int j = 0; j < baseOrder; j+=2) + { + BLOCK1_0( 0,j); + BLOCK1_1( 0,j); + BLOCK1_0(16,j); + BLOCK1_1(16,j); + } +#endif + +} + +// Avoid name space pollution + +#undef MM_LOAD1_PD +#undef MM_LOAD1U_PD +#undef MM_MUL_PD +#undef BLOCK0_0 +#undef BLOCK0_1 +#undef BLOCK1_0 +#undef BLOCK1_1 + + +} // namespace mtl + +#endif // MTL_USE_OPTERON_OPTIMIZATION + +#endif // MTL_OPTERON_MATRIX_MULT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/orth.hpp b/install/MTL/include/boost/numeric/mtl/operation/orth.hpp new file mode 100644 index 00000000..48a83e58 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/orth.hpp @@ -0,0 +1,172 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ORTH_INCLUDE +#define MTL_ORTH_INCLUDE + +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/operation/size.hpp> +#include <boost/numeric/mtl/operation/size1D.hpp> +#include <boost/numeric/mtl/operation/entry1D.hpp> +#include <boost/numeric/mtl/operation/dot.hpp> +#include <boost/numeric/mtl/operation/two_norm.hpp> +#include <boost/numeric/mtl/operation/is_negative.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace vec { + + namespace impl { + + template <typename VVector> + inline void orth(VVector& v, typename mtl::Collection<VVector>::size_type j, tag::vector) + { + vampir_trace<2018> tracer; + using mtl::two_norm; using mtl::size1D; + MTL_DEBUG_THROW_IF(is_negative(j) || j >= size1D(v), index_out_of_range()); + + typedef typename mtl::Collection<VVector>::size_type Size; + for (Size i= 0; i < j; ++i) + entry1D(v, j)-= dot(entry1D(v, i), entry1D(v, j)) * entry1D(v, i); + entry1D(v, j)/= two_norm(entry1D(v, j)); + } + + template <typename VVector> + inline void orth(VVector& v, tag::vector) + { + typedef typename mtl::Collection<VVector>::size_type Size; + using mtl::size1D; + for (Size j= 0; j < size1D(v); ++j) + orth(v, j, tag::vector()); + } + + + template <typename VVector> + mtl::mat::dense2D<typename mtl::Collection + <typename mtl::Collection<VVector>::value_type + >::value_type, mat::parameters<> > + inline orthogonalize_factors(VVector& v, tag::vector) + { + vampir_trace<2019> tracer; + using ::mtl::two_norm; using math::zero; using mtl::size1D; + typedef typename mtl::Collection<VVector>::size_type Size; + typedef typename mtl::Collection<VVector>::value_type Vector; + typedef typename mtl::Collection<Vector>::value_type Scalar; + + mtl::mat::dense2D<Scalar, mat::parameters<> > tau(size1D(v), size1D(v)); + tau= zero(Scalar()); + + if (size1D(v) == 0) + return tau; + + tau[0][0]= dot(entry1D(v, 0), entry1D(v, 0)); + + for (Size j= 1; j < size1D(v); ++j) { +#ifdef MTL_WITH_FUSED_ORTHOGONALIZATION + Scalar t= dot(entry1D(v, 0), entry1D(v, j)) / tau[0][0], t2; + tau[0][j]= t; + for (Size i= 1; i < j; ++i) { + (lazy(entry1D(v, j))-= t * entry1D(v, i-1)) || (lazy(t2)= lazy_dot(entry1D(v, i), entry1D(v, j))); + t= tau[i][j]= t2 / tau[i][i]; + } + entry1D(v, j)-= t * entry1D(v, j-1); +#else + for (Size i= 0; i < j; ++i) { + Scalar t= dot(entry1D(v, i), entry1D(v, j)) / tau[i][i]; + tau[i][j]= t; + entry1D(v, j)-= t * entry1D(v, i); + } +#endif + tau[j][j]= dot(entry1D(v, j), entry1D(v, j)); + } + return tau; + } + + } // impl + + + +/*! Orthonormalize a vector of vectors. + + The outer type must be a random access collection and + the vector type must provide a dot function. + For instance dense_vector<dense_vector<double> > or + std::vector<dense_vector<std::complex<double> > > are eligible. + It is planned to implement the function for matrices as well + where the columns will be ortho-normalized. +**/ +template <typename Value> +inline void orth(Value& value) +{ + impl::orth(value, typename traits::category<Value>::type()); +} + +/*! Orthonormalize the i-th entry of a vector of vectors. + + The i-th vector is orthogonalized w.r.t. to the preceeding ones and + consecutively normalized. + The outer type must be a random access collection and + the vector type must provide a dot function. + For instance dense_vector<dense_vector<double> > or + std::vector<dense_vector<std::complex<double> > > are eligible. + It is planned to implement the function for matrices as well + where the columns will be ortho-normalized. +**/ +template <typename Value> +inline void orth(Value& value, typename mtl::Collection<Value>::size_type i) +{ + impl::orth(value, i, typename traits::category<Value>::type()); +} + + +/*! Orthogonalize a vector of vectors. + + Opposed to orth the vectors are not normalized. + An upper matrix with the factors used in the orthogonalization is returned. + The diagonal contains dot(v[i], v[i]). + The returned factors are for instance used in bicgstab_ell. + The outer type must be a random access collection and + the vector type must provide a dot function. + For instance dense_vector<dense_vector<double> > or + std::vector<dense_vector<std::complex<double> > > are eligible. +**/ +template <typename Value> +mtl::mat::dense2D<typename mtl::Collection + <typename mtl::Collection<Value>::value_type + >::value_type, mat::parameters<> > +inline orthogonalize_factors(Value& v) +{ + return impl::orthogonalize_factors(v, typename traits::category<Value>::type()); +} + +} // namespace vector + +namespace mat { + + // If other matrix types will be supported within a template function, it needs reimplementation!!! + template <typename Vector> + inline void orth(multi_vector<Vector>& A) + { + mtl::vec::impl::orth(A, mtl::tag::vector()); + } +} + +using vec::orth; +using vec::orthogonalize_factors; + +} // namespace mtl + +#endif // MTL_ORTH_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/print.hpp b/install/MTL/include/boost/numeric/mtl/operation/print.hpp new file mode 100644 index 00000000..2b7cc7e5 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/print.hpp @@ -0,0 +1,100 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_PRINT_INCLUDE +#define MTL_PRINT_INCLUDE + +#include <iostream> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/operation/print_size.hpp> +#include <boost/numeric/mtl/operation/print_matrix.hpp> +#include <boost/numeric/mtl/operation/print_vector.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> + + +namespace mtl { + +namespace detail { + + template <typename Collection> + struct with_format_t + { + explicit with_format_t(const Collection& collection, int width, int precision) + : collection(collection), width(width), precision(precision) + {} + + const Collection& collection; + int width, precision; + }; + + template <typename Collection> + inline std::ostream& operator<< (std::ostream& out, with_format_t<Collection> const& value) + { + return print(value.collection, out, value.width, value.precision); + } + + +} // namespace detail + +namespace mat { + + template <typename Matrix> + inline std::ostream& operator<< (std::ostream& out, const mat_expr<Matrix>& expr) + { + const Matrix& A= static_cast<const Matrix&>(expr); + return print_matrix(A, out, print_size(A), 0); + } + + template <typename Value> + inline std::ostream& + print(Value const& value, std::ostream& out= std::cout, int width= 3, int precision= 2) + { + return print_matrix(value, out, width, precision); + } + + template <typename Collection> + inline mtl::detail::with_format_t<Collection> with_format(const Collection& collection, int width= 3, int precision= 2) + { + return mtl::detail::with_format_t<Collection>(collection, width, precision); + } +} // namespace matrix + +namespace vec { + + + template <typename Vector> + inline std::ostream& operator<< (std::ostream& out, const vec::vec_expr<Vector>& expr) + { + return print_vector(static_cast<const Vector&>(expr), out, 0, 0); + } + + + template <typename Value> + inline std::ostream& + print(Value const& value, std::ostream& out= std::cout, int width= 3, int precision= 2) + { + return print_vector(value, out, width, precision); + } + + template <typename Collection> + inline mtl::detail::with_format_t<Collection> with_format(const Collection& collection, int width= 3, int precision= 2) + { + return mtl::detail::with_format_t<Collection>(collection, width, precision); + } + +} // namespace vector + + +} // mtl + + +#endif // MTL_PRINT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/print_matrix.hpp b/install/MTL/include/boost/numeric/mtl/operation/print_matrix.hpp new file mode 100644 index 00000000..a8f636e0 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/print_matrix.hpp @@ -0,0 +1,52 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_PRINT_MATRIX_INCLUDE +#define MTL_PRINT_MATRIX_INCLUDE + +#include <cstddef> +#include <iostream> +#include <sstream> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> + +namespace mtl { namespace mat { + +template <typename Matrix> +std::ostream& print_matrix(Matrix const& matrix, std::ostream& out= std::cout, int width= 3, int precision= 2) +{ + // typedef typename Collection<Matrix>::size_type size_type; + // all indices will start from 0; otherwise wrong + for (std::size_t r= 0, nr= num_rows(matrix); r < nr; ++r) { + out << '['; + for (std::size_t c= 0, nc= num_cols(matrix); c < nc; ++c) { + if (precision) + out.precision(precision); + out.fill (' '); out.width (width); +#ifdef MTL_PRINT_STRING_TMP // probably very slow but looks better for certain types + std::ostringstream st; + st << matrix(r, c) << (c + 1 < nc ? " " : "]\n"); + out << std::right << st.str(); +#else + out << matrix(r, c) << (c + 1 < nc ? " " : "]\n"); +#endif + } + } + return out; +} + +}} // namespace mtl::matrix + +#endif // MTL_PRINT_MATRIX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/print_size.hpp b/install/MTL/include/boost/numeric/mtl/operation/print_size.hpp new file mode 100644 index 00000000..9f4eac0e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/print_size.hpp @@ -0,0 +1,55 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_PRINT_SIZE_INCLUDE +#define MTL_PRINT_SIZE_INCLUDE + +#include <sstream> + +#include <boost/numeric/mtl/operation/look_at_each_nonzero.hpp> + +namespace mtl { + + struct print_size_max + { + print_size_max() : max(0) {} + + template <typename T> + void operator()(const T& x) + { + std::ostringstream st; + st << x; + int s= st.str().size(); + // std::cout << "Size is " << s << ": " << st.str() << '\n'; + if (s > max) max= s; + } + + int max; + }; + + namespace mat { + + template <typename Matrix> + int inline print_size(const Matrix& A) + { + print_size_max p; + // look_at_each_nonzero(A, p); // Doesn't work on all expressions yet + for (size_t r = 0, nr = num_rows(A); r < nr; ++r) + for (size_t c = 0, nc= num_cols(A); c < nc; ++c) + p(A(r, c)); + return p.max; + } + } + +} // namespace mtl + +#endif // MTL_PRINT_SIZE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/print_vector.hpp b/install/MTL/include/boost/numeric/mtl/operation/print_vector.hpp new file mode 100644 index 00000000..502f2143 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/print_vector.hpp @@ -0,0 +1,42 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_PRINT_VECTOR_INCLUDE +#define MTL_PRINT_VECTOR_INCLUDE + +#include <iostream> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> + +namespace mtl { namespace vec { + +template <typename Vector> +std::ostream& print_vector(Vector const& vector, std::ostream& out= std::cout, int width= 0, int precision= 0) +{ + using mtl::vec::size; + out << '{' << mtl::vec::size(vector) + << (traits::is_row_major< typename OrientedCollection<Vector>::orientation >::value ? "R" : "C") + << "}[" ; + for (size_t r = 0; r < mtl::vec::size(vector); ++r) { + out.fill (' '); + if (width) out.width (width); + // out.flags (std::ios_base::right); + if (precision) out.precision(precision); + out << vector[r] << (r+1 < mtl::vec::size(vector) ? "," : ""); + } + return out << ']'; +} + +}} // namespace mtl::vector + +#endif // MTL_PRINT_VECTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/product.hpp b/install/MTL/include/boost/numeric/mtl/operation/product.hpp new file mode 100644 index 00000000..e96378ea --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/product.hpp @@ -0,0 +1,71 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_PRODUCT_INCLUDE +#define MTL_PRODUCT_INCLUDE + +#include <iostream> +#include <cmath> + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/vector/lazy_reduction.hpp> +#include <boost/numeric/mtl/vector/reduction.hpp> +#include <boost/numeric/mtl/vector/reduction_functors.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { + + namespace vec { + + namespace impl { + + // Do we really need this for matrices? + + template <unsigned long Unroll, typename Vector> + typename Collection<Vector>::value_type + inline product(const Vector& vector, tag::vector) + { + typedef typename Collection<Vector>::value_type result_type; + return vec::reduction<Unroll, vec::product_functor, result_type>::apply(vector); + } + + } // namespace impl + + ///Returns product of all collection-entries (%vector-entries) + template <unsigned long Unroll, typename Value> + typename Collection<Value>::value_type + inline product(const Value& value) + { vampir_trace<2020> tracer; + return impl::product<Unroll>(value, typename traits::category<Value>::type()); + } + + template <typename Value> + typename Collection<Value>::value_type + inline product(const Value& value) + { + return product<8>(value); + } + + template <typename Vector> + lazy_reduction<Vector, product_functor> inline lazy_product(const Vector& v) + { return lazy_reduction<Vector, product_functor>(v); } + + } // namespace vector + + using vec::lazy_product; + using vec::product; + +} // namespace mtl + +#endif // MTL_PRODUCT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/qr.hpp b/install/MTL/include/boost/numeric/mtl/operation/qr.hpp new file mode 100644 index 00000000..71a7a92e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/qr.hpp @@ -0,0 +1,110 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// With contributions from Cornelius Steinhardt +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + + +#ifndef MTL_MATRIX_QR_INCLUDE +#define MTL_MATRIX_QR_INCLUDE + +#include <cmath> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/linear_algebra/inverse.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/concept/magnitude.hpp> +#include <boost/numeric/mtl/operation/householder.hpp> +#include <boost/numeric/mtl/operation/rank_one_update.hpp> +#include <boost/numeric/mtl/operation/trans.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace mat { + + +/// QR-Factorization of matrix A(m x n) +/** Return pair R upper triangel matrix and Q= orthogonal matrix. R and Q are always dense2D **/ +template <typename Matrix, typename MatrixQ, typename MatrixR> +void qr(const Matrix& A, MatrixQ& Q, MatrixR& R) +{ + vampir_trace<4013> tracer; + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + typedef typename Magnitude<value_type>::type magnitude_type; + typedef mtl::dense_vector<value_type, vec::parameters<> > vector_type; + + size_type ncols = num_cols(A), nrows = num_rows(A), + mini= ncols == nrows ? ncols - 1 : (nrows >= ncols ? ncols : nrows); + magnitude_type factor= magnitude_type(2); + + Q= 1; + for (size_type i = 0; i < mini; i++) { + irange r(i, imax); // Intervals [i, n-1] + vector_type w(R[r][i]), v(householder_s(w)); + + // R-= 2*v*(v'*R) + MatrixR Rsub(R[r][r]); + vector_type tmp(-factor * trans(Rsub) * v); + rank_one_update(Rsub, v, tmp); + + //update Q: Q-= 2*(v*Q)*v' + MatrixQ Qsub(Q[iall][r]); + vector_type qtmp(-factor * Qsub * v); + rank_one_update(Qsub, qtmp, v); + } //end for +} + +/// QR-Factorization of matrix A(m x n) +template <typename Matrix> +std::pair<mtl::mat::dense2D<typename Collection<Matrix>::value_type, mat::parameters<> >, + mtl::mat::dense2D<typename Collection<Matrix>::value_type, mat::parameters<> > > +inline qr(const Matrix& A) +{ + mtl::mat::dense2D<typename Collection<Matrix>::value_type, mat::parameters<> > R(A), Q(num_rows(A),num_rows(A)); + qr(A, Q, R); + return std::make_pair(Q,R); +} + + + +// QR-Factorization of matrix A +// Return Q and R with A = Q*R R upper triangle and Q othogonal +template <typename Matrix> +std::pair<typename mtl::mat::dense2D<typename Collection<Matrix>::value_type, mat::parameters<> >, + typename mtl::mat::dense2D<typename Collection<Matrix>::value_type, mat::parameters<> > > +inline qr_factors(const Matrix& A) +{ + vampir_trace<4014> tracer; + using std::abs; + typedef typename Collection<Matrix>::value_type value_type; + // typedef typename Magnitude<value_type>::type magnitude_type; // to multiply with 2 not 2+0i + typedef typename Collection<Matrix>::size_type size_type; + size_type ncols = num_cols(A), nrows = num_rows(A); + value_type zero= math::zero(A[0][0]), one= math::one(A[0][0]); + + //evaluation of Q + Matrix Q(nrows, nrows), Qk(nrows, nrows), HEL(nrows, ncols), R(nrows, ncols), R_tmp(nrows, ncols); + Q= one; R= zero; HEL= zero; + + boost::tie(Q, R_tmp)= qr(A); + R= upper(R_tmp); + + return std::make_pair(Q,R); +} + +}} // namespace mtl::matrix + + +#endif // MTL_MATRIX_QR_INCLUDE + diff --git a/install/MTL/include/boost/numeric/mtl/operation/qr_givens.hpp b/install/MTL/include/boost/numeric/mtl/operation/qr_givens.hpp new file mode 100644 index 00000000..2149f7f7 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/qr_givens.hpp @@ -0,0 +1,159 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +// Author: Marc Hartung + +#ifndef MTL_MATRIX_QR_GIVENS_INCLUDE +#define MTL_MATRIX_QR_GIVENS_INCLUDE + +#include <cmath> +#include <utility> + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/operation/conj.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> + + +namespace mtl { namespace mat { + + +/// General Given's transformator +/** + * Input-matrix A will be splitted in A = Q*R. Q and R are accessible from getQ() and getR(). + * \sa givens + */ +template <typename Matrix> +class qr_givens_solver { + + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + +public: + + /** \brief Constructor needs a sqare-matrix as input + * \param MTL-Matrix type + * + */ + + qr_givens_solver(const Matrix& IN) : R(IN), G(2,2), Q(num_cols(IN), num_rows(IN)) { + value_type one = math::one(c); + Q = one; + eps = 1.0e-8; + } + + /** \brief Returns Q as the input-matrix-type + * + * \return Matrix Q + */ + + Matrix& getQ() { + return Q; + } + + /** \brief Returns R as the input-matrix-type + * + * \return Matrix R + */ + Matrix& getR() { + return R; + } + + /** \brief Sets the distance to zero + * + * \param value_type tolerance to zero + */ + void setTolerance(value_type tol) { + eps = tol; + } + + /** \brief Starts QR decompostion + */ + void calc() + { + value_type zero= math::zero(c); + Matrix RIter(2, num_rows(R)), Iter(2, num_rows(R)); + for(size_type i= 0; i < R.num_cols() - 1; i++) { + irange r(i, num_cols(R)); + for(size_type j= num_rows(R)-1;j>i;j--) { + if (std::abs(R[j][i]) > eps) { + set_rotation(R[i][i], R[j][i]); + Iter[0][r] = R[i][r]; + Iter[1][r] = R[j][r]; + RIter[iall][r] = G*Iter[iall][r]; + R[i][r] = RIter[0][r]; + R[j][r] = RIter[1][r]; + Iter[0][iall] = Q[i][iall]; + Iter[1][iall] = Q[j][iall]; + RIter = G*Iter; + Q[i][iall] = RIter[0][iall]; + Q[j][iall] = RIter[1][iall]; + } + R[j][i] = zero; + } + + } + + for(size_type i= 0; i < num_cols(R) - 1; i++) + R[i+1][i] = zero; + + } + + private: + + Matrix R, G, Q; + value_type c, s, eps; + + template <typename T> + inline T square(T x) const { return x * x; } + + /// Coefficients for Given's rotation + void set_rotation(value_type a, value_type b) + { + using std::abs; + using mtl::conj; + + value_type zero= math::zero(a), one= math::one(b), t; + + if ( b == zero ) { + c= one; s= zero; + } else if ( abs(b) > abs(a) ) { + t = a / abs(b); + s = one/ sqrt(one + square(abs(t))); + c = s * t; + s *= (b/abs(b)); + } else { + t = b / abs(a); + c = one / sqrt(one + square(abs(t))); + s = c * t; + c = (a/abs(a))*c; + } + + G= conj(c), conj(s), + -s, c; + } + +}; + +/// QR-Factorization of matrix A(m x n) based on Givens' rotation +template <typename Matrix> +std::pair<Matrix, Matrix> +inline qr_givens(const Matrix& A) +{ + qr_givens_solver<Matrix> solver(A); + solver.calc(); + return std::make_pair(solver.getQ(), solver.getR()); +} + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_QR_GIVENS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/random.hpp b/install/MTL/include/boost/numeric/mtl/operation/random.hpp new file mode 100644 index 00000000..9b2e53a6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/random.hpp @@ -0,0 +1,117 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_RANDOM_INCLUDE +#define MTL_RANDOM_INCLUDE + +// Provisional implementation, do not use in production code!!! +// Will be reimplemented with boost::random + +#include <cstdlib> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + +template <typename T> +struct seed +{ + seed() { srand(17 * ++counter); } + T operator()() const { return rand(); } + + static int counter; +}; + +template <typename T> +int seed<T>::counter= 0; + +namespace impl { + + // all non-distributed matrices except multi-vectors + template <typename Coll, typename Generator> + void inline random(Coll& A, Generator& generator, tag::universe, tag::matrix) + { + typedef typename Collection<Coll>::size_type size_type; + mat::inserter<Coll> ins(A, A.dim2()); + for (size_type r= 0; r < num_rows(A); r++) + for (size_type c= 0; c < num_cols(A); c++) + ins[r][c] << generator(); + } + + template <typename Coll, typename Generator> + void inline random(Coll& A, Generator&, tag::universe, tag::multi_vector) + { + for (typename Collection<Coll>::size_type i= 0; i < num_cols(A); ++i) + random(A.vector(i)); + } + +} // namespace impl + + +namespace vec { + + /// Fill vector with random values; generator must be a nullary function. + template <typename Vector, typename Generator> + typename mtl::traits::enable_if_vector<Vector>::type + inline random(Vector& v, Generator& generator) + { + vampir_trace<2021> tracer; + typedef typename Collection<Vector>::size_type size_type; + for (size_type i= 0; i < size(v); i++) + v[i]= generator(); + } + + /// Fill vector with random values. + /** Currently done with rand(). Will be improved one day. You can provide + your own generator as second argument. **/ + template <typename Vector> + typename mtl::traits::enable_if_vector<Vector>::type + inline random(Vector& v) + { + seed<typename Collection<Vector>::value_type> s; + random(v, s); + } + + +} // namespace vector + +namespace mat { + + /// Fill matrix with random values; generator must be a nullary function. + template <typename Matrix, typename Generator> + typename mtl::traits::enable_if_matrix<Matrix>::type + inline random(Matrix& A, Generator& generator) + { + vampir_trace<4015> tracer; + typename mtl::traits::category<Matrix>::type cat; + mtl::impl::random(A, generator, cat, cat); + } + + /// Fill matrix with random values. + /** Currently done with rand(). Will be improved one day. You can provide + your own generator as second argument. **/ + template <typename Matrix> + typename mtl::traits::enable_if_matrix<Matrix>::type + inline random(Matrix& A) + { + seed<typename Collection<Matrix>::value_type> s; + random(A, s); + } + +} // namespace matrix + +} // namespace mtl + +#endif // MTL_RANDOM_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/rank_one_update.hpp b/install/MTL/include/boost/numeric/mtl/operation/rank_one_update.hpp new file mode 100644 index 00000000..0b433b38 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/rank_one_update.hpp @@ -0,0 +1,56 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_RANK_ONE_UPDATE_INCLUDE +#define MTL_RANK_ONE_UPDATE_INCLUDE + +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/mtl/operation/update.hpp> +#include <boost/numeric/mtl/operation/conj.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace mat { + + +/// Rank-one update: rank_one_update(A, x, y) computes A+= x * conj(y)^T +/** The current implementation works for column and row vectors (although + the notation above refers to column vectors). **/ +template <typename Matrix, typename VectorX, typename VectorY> +inline void rank_one_update(Matrix& matrix, const VectorX& x, const VectorY& y) +{ + using mtl::conj; + vampir_trace<2022> tracer; + MTL_THROW_IF(num_rows(matrix) != size(x) || num_cols(matrix) != size(y), incompatible_size()); + namespace traits = mtl::traits; + typedef typename traits::range_generator<tag::nz, VectorX>::type x_cursor; + typename traits::index<VectorX>::type index_x(x); + typename traits::const_value<VectorX>::type value_x(x); + + typedef typename traits::range_generator<tag::nz, VectorY>::type y_cursor; + typename traits::index<VectorY>::type index_y(y); + typename traits::const_value<VectorY>::type value_y(y); + + mat::inserter<Matrix, operations::update_plus<typename Collection<Matrix>::value_type> > ins(matrix); + + for (x_cursor xc= begin<tag::nz>(x), xend= end<tag::nz>(x); xc != xend; ++xc) + for (y_cursor yc= begin<tag::nz>(y), yend= end<tag::nz>(y); yc != yend; ++yc) + ins(index_x(*xc), index_y(*yc)) << value_x(*xc) * conj(value_y(*yc)); +} + + +}} // namespace mtl::matrix + +#endif // MTL_RANK_ONE_UPDATE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/rank_two_update.hpp b/install/MTL/include/boost/numeric/mtl/operation/rank_two_update.hpp new file mode 100644 index 00000000..3208829b --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/rank_two_update.hpp @@ -0,0 +1,32 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_RANK_TWO_UPDATE_INCLUDE +#define MTL_RANK_TWO_UPDATE_INCLUDE + +#include <boost/numeric/mtl/operation/rank_one_update.hpp> + +namespace mtl { namespace mat { + +/// Rank-two update: rank_two_update(A, x, y) computes A+= x * conj(y)^T + y * conj(x)^T +/** The current implementation works for column and row vectors (although + the notation above refers to column vectors). **/ +template <typename Matrix, typename VectorX, typename VectorY> +inline void rank_two_update(Matrix& matrix, const VectorX& x, const VectorY& y) +{ + rank_one_update(matrix, x, y); + rank_one_update(matrix, y, x); +} + +}} // namespace mtl::matrix + +#endif // MTL_RANK_TWO_UPDATE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/raw_copy.hpp b/install/MTL/include/boost/numeric/mtl/operation/raw_copy.hpp new file mode 100644 index 00000000..84fc8070 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/raw_copy.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_RAW_COPY_INCLUDE +#define MTL_RAW_COPY_INCLUDE +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { + +// Copies range of values into elements +// As name says it is a raw operation and to used with uttermost care +template <typename Matrix, typename InputIterator> +void raw_copy(InputIterator first, InputIterator last, Matrix& matrix) +{ + using std::copy; + vampir_trace<2> tracer; + copy(first, last, matrix.elements()); +} + +// Temporary solution +// will be replaced by sequences and cursors generated by begin<all>(ma) and end<all>(ma) +// Using segmented cursors, matrices with non-contigous element storing can be handled + +} // namespace mtl + +#endif // MTL_RAW_COPY_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/real.hpp b/install/MTL/include/boost/numeric/mtl/operation/real.hpp new file mode 100644 index 00000000..b2159918 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/real.hpp @@ -0,0 +1,93 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_REAL_INCLUDE +#define MTL_REAL_INCLUDE + +#include <complex> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/mtl/vector/map_view.hpp> + +namespace mtl { + +namespace sfunctor { + + template <typename Value> + struct real + { + typedef Value result_type; + + static inline Value apply(const Value& v) + { + return v; + } + + Value operator()(const Value& v) const + { + return v; + } + }; + + template <typename Value> + struct real<std::complex<Value> > + { + typedef Value result_type; + + static inline result_type apply(const std::complex<Value>& v) + { + return std::real(v); + } + result_type operator()(const std::complex<Value>& v) const + { + return std::real(v); + } + }; +} + +/// real part of scalars (including non-complex) +template <typename Value> +typename mtl::traits::enable_if_scalar<Value, typename sfunctor::real<Value>::result_type>::type +inline real(const Value& v) +{ + vampir_trace<3> tracer; + return sfunctor::real<Value>::apply(v); +} + +namespace vec { + + /// Real part of a vector + template <typename Vector> + typename mtl::traits::enable_if_vector<Vector, real_view<Vector> >::type + inline real(const Vector& v) + { + return real_view<Vector>(v); + } +} + +namespace mat { + + /// Real part of a matrix + template <typename Matrix> + typename mtl::traits::enable_if_matrix<Matrix, real_view<Matrix> >::type + inline real(const Matrix& v) + { + return real_view<Matrix>(v); + } +} + +} // namespace mtl + +#endif // MTL_REAL_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/resource.hpp b/install/MTL/include/boost/numeric/mtl/operation/resource.hpp new file mode 100644 index 00000000..bfa36fa3 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/resource.hpp @@ -0,0 +1,54 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_RESOURCE_INCLUDE +#define MTL_RESOURCE_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + + namespace traits { + + template <typename Vector> + struct vector_resource + { + typedef typename Collection<Vector>::size_type type; + type inline static apply(const Vector& v) { using mtl::vec::size; return size(v); } + }; + } + + namespace vec { + + /// Describes the resources need for a certain vector. + /** All necessary information to construct appropriate/consistent temporary vectors. + Normally, this is just the size of the vector. + For distributed vector we also need its distribution. **/ + template <typename Vector> + typename mtl::traits::vector_resource<Vector>::type + inline resource(const Vector& v) + { + vampir_trace<4> tracer; + return mtl::traits::vector_resource<Vector>::apply(v); + } + + } // namespace vector + + namespace mat { + // maybe a pair of size_type? like position + } + +} // namespace mtl + +#endif // MTL_RESOURCE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/right_scale_inplace.hpp b/install/MTL/include/boost/numeric/mtl/operation/right_scale_inplace.hpp new file mode 100644 index 00000000..8ac652ab --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/right_scale_inplace.hpp @@ -0,0 +1,80 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_RIGHT_SCALE_INPLACE_INCLUDE +#define MTL_RIGHT_SCALE_INPLACE_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/operation/assign_each_nonzero.hpp> +#include <boost/numeric/mtl/operation/mult.hpp> +#include <boost/numeric/mtl/operation/rscale.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + + +/// Scale collection \p c from right with scalar factor \p alpha; \p c is altered +template <typename Factor, typename Coll> +void right_scale_inplace(Coll& c, const Factor& alpha, tag::scalar) +{ + vampir_trace<5> tracer; + assign_each_nonzero(c, tfunctor::rscale<typename Collection<Coll>::value_type, Factor>(alpha)); +} + +template <typename Factor, typename Matrix> +void right_scale_inplace(Matrix& m, tag::matrix, const Factor& alpha, tag::matrix) +{ + using mtl::swap; + + vampir_trace<4016> tracer; + Matrix tmp(num_rows(m), num_cols(m)); + mult(m, alpha, tmp); + swap(m, tmp); +} + +#if 0 // Row vector times Matrix is not yet implemented +template <typename Factor, typename Vector> +void right_scale_inplace(Vector& v, tag::vector, const Factor& alpha, tag::matrix) +{ + using mtl::swap; + + Vector tmp(size(v)); + gen_mult(v, alpha, tmp, assign::assign_sum(), tag::row_vector(), tag::matrix(), tag::row_vector()); + swap(v, tmp); +} +#endif + +/// Scale collection \p c from right with matrix factor \p alpha; \p c is altered +template <typename Factor, typename Collection> +void right_scale_inplace(Collection& c, const Factor& alpha, tag::matrix) +{ + // Need to dispatch further to use different constructors for temporary + right_scale_inplace(c, typename traits::category<Collection>::type(), alpha, tag::matrix()); +} + +/// Scale collection \p c from right with factor \p alpha; \p c is altered +template <typename Factor, typename Collection> +void right_scale_inplace(Collection& c, const Factor& alpha) +{ + // Dispatch between scalar and matrix factors + right_scale_inplace(c, alpha, typename traits::category<Factor>::type()); +} + + + + +} // namespace mtl + +#endif // MTL_RIGHT_SCALE_INPLACE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/row_in_matrix.hpp b/install/MTL/include/boost/numeric/mtl/operation/row_in_matrix.hpp new file mode 100644 index 00000000..3e1d7cd8 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/row_in_matrix.hpp @@ -0,0 +1,105 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ROW_IN_MATRIX_INCLUDE +#define MTL_ROW_IN_MATRIX_INCLUDE + +#include <boost/mpl/if.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + +/// Type of row in matrix as vector if accessible +template <typename Matrix> +struct RowInMatrix +{ + static const bool exists= false; +}; + +template <typename Value, typename Parameters> +struct RowInMatrix<mtl::mat::dense2D<Value, Parameters> > +{ + typedef mtl::mat::dense2D<Value, Parameters> ref_type; + typedef typename ref_type::size_type size_type; + typedef typename ref_type::value_type value_type; + typedef mtl::vec::parameters<row_major> vec_para; + + static const bool aligned= boost::is_same<typename Parameters::orientation, row_major>::value; + static const bool exists= true; + + typedef typename boost::mpl::if_c< + aligned + , vec::dense_vector<Value, vec_para> + , vec::strided_vector_ref<Value, vec_para> + >::type type; + + static inline type apply(ref_type& A, size_type row, const irange& col_range) + { + return dispatch<type, ref_type>(A, row, col_range, boost::mpl::bool_<aligned>()); + } + + template <typename Ref> + static inline size_type vector_size(const Ref& A, const irange& col_range) + { + using std::min; + + vampir_trace<1003> tracer; + size_type finish= min(col_range.finish(), num_cols(A)); + return col_range.start() < finish ? finish - col_range.start() : 0; + } + + template <typename Return, typename Ref> + static inline Return dispatch(Ref& A, size_type row, const irange& col_range, boost::mpl::true_) + { + vampir_trace<2023> tracer; + return Return(vector_size(A, col_range), const_cast<value_type*>(&A[row][col_range.start()])); // TODO make work without const cast + } + + template <typename Return, typename Ref> + static inline Return dispatch(Ref& A, size_type row, const irange& col_range, boost::mpl::false_) + { + vampir_trace<1004> tracer; + return Return(vector_size(A, col_range), &A[row][col_range.start()], num_rows(A)); + } +}; + +template <typename Value, typename Parameters> +struct RowInMatrix<const mtl::mat::dense2D<Value, Parameters> > +{ + typedef mtl::mat::dense2D<Value, Parameters> const ref_type; + typedef mtl::mat::dense2D<Value, Parameters> ref2_type; + typedef typename ref2_type::size_type size_type; + typedef vec::parameters<row_major> vec_para; + + static const bool aligned= boost::is_same<typename Parameters::orientation, row_major>::value; + static const bool exists= true; + + typedef typename boost::mpl::if_c< + aligned + , vec::dense_vector<Value, vec_para> // TODO needs constification !!! + , vec::strided_vector_ref<const Value, vec_para> + >::type type; + + static inline type apply(ref_type& A, size_type row, const irange& col_range) + { + return RowInMatrix<ref2_type>::template dispatch<type, ref_type>(A, row, col_range, boost::mpl::bool_<aligned>()); + } +}; + + +} // namespace mtl + +#endif // MTL_ROW_IN_MATRIX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/rscale.hpp b/install/MTL/include/boost/numeric/mtl/operation/rscale.hpp new file mode 100644 index 00000000..e825fd83 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/rscale.hpp @@ -0,0 +1,112 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. +/* + * rscale.hpp + * MTL4 + * + * Created by Hui Li (huil@Princeton.EDU) + * + */ + +#ifndef MTL_RSCALE_INCLUDE +#define MTL_RSCALE_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/std_concept.hpp> +#include <boost/numeric/mtl/matrix/map_view.hpp> +#include <boost/numeric/mtl/vector/map_view.hpp> +#include <boost/numeric/mtl/utility/algebraic_category.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace tfunctor { + + // AlgebraicCategory is by default tag::scalar + template <typename Value1, typename Value2, typename AlgebraicCategory> + struct rscale + { + typedef typename Multiplicable<Value1, Value2>::result_type result_type; + + explicit rscale(const Value2& v2) : v2(v2) {} + + result_type operator() (const Value1& v1) const + { + return v1 * v2; + } + + Value2 value() const { return v2; } + private: + Value2 v2; + }; + + + template <typename Matrix, typename Value2> + struct rscale<Matrix, Value2, tag::matrix> + { + typedef mat::rscaled_view<Matrix,Value2> result_type; + + explicit rscale(const Value2& v2) : v2(v2) {} + + result_type operator() (const Matrix& matrix) const + { + return result_type(matrix, v2); + } + private: + Value2 v2; + }; + + + template <typename Vector, typename Value2> + struct rscale<Vector, Value2, tag::vector> + { + typedef vec::rscaled_view<Vector, Value2> result_type; + + explicit rscale(const Value2& v2) : v2(v2) {} + + result_type operator() (const Vector& vector) const + { + return result_type(vector, v2); + } + private: + Value2 v2; + }; + + +} // namespace tfunctor + + +namespace mat { + + template <typename Value1, typename Value2> + typename tfunctor::rscale<Value1, Value2, typename traits::algebraic_category<Value1>::type>::result_type + inline rscale(const Value1& value1, const Value2& value2) + { + vampir_trace<4017> tracer; + return tfunctor::rscale<Value1, Value2, typename traits::algebraic_category<Value1>::type>(value2)(value1); + } +} + +namespace vec { + + template <typename Value1, typename Value2> + typename tfunctor::rscale<Value1, Value2, typename traits::algebraic_category<Value1>::type>::result_type + inline rscale(const Value1& value1, const Value2& value2) + { + vampir_trace<2024> tracer; + return tfunctor::rscale<Value1, Value2, typename traits::algebraic_category<Value1>::type>(value2)(value1); + } +} + + +} // namespace mtl + +#endif // MTL_RSCALE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/rvec_mat_mult.hpp b/install/MTL/include/boost/numeric/mtl/operation/rvec_mat_mult.hpp new file mode 100644 index 00000000..f063997c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/rvec_mat_mult.hpp @@ -0,0 +1,219 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_RVEC_MAT_MULT_INCLUDE +#define MTL_VECTOR_RVEC_MAT_MULT_INCLUDE + +#include <cassert> +#include <boost/mpl/bool.hpp> + +#include <boost/numeric/mtl/mtl_conditional_fwd.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/is_static.hpp> +#include <boost/numeric/mtl/operation/set_to_zero.hpp> +#include <boost/numeric/mtl/operation/update.hpp> +#include <boost/numeric/mtl/operation/conj.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/meta_math/loop.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace vec { + +namespace impl { + + template <std::size_t Index0, std::size_t Max0, std::size_t Index1, std::size_t Max1, typename Assign> + struct fully_unroll_rvec_mat_mult + : public meta_math::loop2<Index0, Max0, Index1, Max1> + { + typedef meta_math::loop2<Index0, Max0, Index1, Max1> base; + typedef fully_unroll_rvec_mat_mult<base::next_index0, Max0, base::next_index1, Max1, Assign> next_t; + + template <typename VectorIn, typename Matrix, typename VectorOut> + static inline void apply(const VectorIn& v, const Matrix& A, VectorOut& w) + { + Assign::update(w[base::index0], v[base::index1] * A[base::index1][base::index0]); + next_t::apply(v, A, w); + } + }; + + template <std::size_t Max0, std::size_t Max1, typename Assign> + struct fully_unroll_rvec_mat_mult<Max0, Max0, Max1, Max1, Assign> + : public meta_math::loop2<Max0, Max0, Max1, Max1> + { + typedef meta_math::loop2<Max0, Max0, Max1, Max1> base; + + template <typename VectorIn, typename Matrix, typename VectorOut> + static inline void apply(const VectorIn& v, const Matrix& A, VectorOut& w) + { + Assign::update(w[base::index0], v[base::index1] * A[base::index1][base::index0]); + } + }; + + struct rvec_mat_noop + { + template <typename VectorIn, typename Matrix, typename VectorOut> + static inline void apply(const VectorIn&, const Matrix&, VectorOut&) {} + }; +} // impl + +// Dense matrix vector multiplication with run-time matrix size +template <typename VectorIn, typename Matrix, typename VectorOut, typename Assign> +inline void dense_rvec_mat_mult(const VectorIn& v, const Matrix& A, VectorOut& w, Assign, boost::mpl::true_) +{ + vampir_trace<1008> tracer; + typedef typename static_num_rows<Matrix>::type size_type; + static const size_type rows_a= static_num_rows<Matrix>::value, cols_a= static_num_cols<Matrix>::value; + + assert(rows_a > 0 && cols_a > 0); + // w= A[all][0] * v[0]; N.B.: 1D is unrolled by the compiler faster (at least on gcc) + for (size_type i= 0; i < cols_a; i++) + Assign::first_update(w[i], v[0] * A[0][i]); + + // corresponds to w+= v[1:] * A[1:][all]; if necessary + typedef impl::fully_unroll_rvec_mat_mult<1, cols_a, 2, rows_a, Assign> f2; + typedef typename boost::mpl::if_c<(rows_a > 1), f2, impl::rvec_mat_noop>::type f3; + f3::apply(v, A, w); +} + +// Dense matrix vector multiplication with run-time matrix size +template <typename VectorIn, typename Matrix, typename VectorOut, typename Assign> +inline void dense_rvec_mat_mult(const VectorIn& v, const Matrix& A, VectorOut& w, Assign, boost::mpl::false_) +{ + // Naive implementation, will be moved to a functor and complemented with more efficient ones + vampir_trace<3027> tracer; + using math::zero; using mtl::vec::set_to_zero; + if (size(w) == 0) return; + + if (Assign::init_to_zero) set_to_zero(w); + + typedef typename Collection<VectorOut>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + + for (size_type i= 0; i < num_cols(A); i++) { + value_type tmp= zero(w[i]); + for (size_type j= 0; j < num_rows(A); j++) + tmp+= v[j] * A[j][i]; + Assign::update(w[i], tmp); + } +} + +// Dense vector matrix multiplication +template <typename VectorIn, typename Matrix, typename VectorOut, typename Assign> +inline void rvec_mat_mult(const VectorIn& v, const Matrix& A, VectorOut& w, Assign, tag::flat<tag::dense>) +{ +# ifdef MTL_NOT_UNROLL_FSIZE_MAT_VEC_MULT + boost::mpl::false_ selector; +# else + mtl::traits::is_static<Matrix> selector; +# endif + dense_rvec_mat_mult(v, A, w, Assign(), selector); +} + +// Multi-vector vector multiplication (tag::multi_vector is derived from dense) +template <typename VectorIn, typename Matrix, typename VectorOut, typename Assign> +inline void rvec_mat_mult(const VectorIn& v, const Matrix& A, VectorOut& w, Assign, tag::flat<tag::multi_vector>) +{ + vampir_trace<2025> tracer; + if (Assign::init_to_zero) set_to_zero(w); + for (unsigned i= 0; i < num_cols(A); i++) + Assign::update(w[i], dot_real(v, A.vector(i))); +} + +// Transposed multi-vector vector multiplication (tag::transposed_multi_vector is derived from dense) +template <typename VectorIn, typename TransposedMatrix, typename VectorOut, typename Assign> +inline void rvec_mat_mult(const VectorIn& v, const TransposedMatrix& A, VectorOut& w, Assign, tag::flat<tag::transposed_multi_vector>) +{ + vampir_trace<2026> tracer; + typename TransposedMatrix::const_ref_type B= A.ref; // Referred matrix + + if (Assign::init_to_zero) set_to_zero(w); + for (unsigned i= 0; i < num_cols(B); i++) + Assign::update(w, v[i] * trans(B.vector(i))); +} + +// Hermitian multi-vector vector multiplication (tag::hermitian_multi_vector is derived from dense) +template <typename VectorIn, typename HermitianMatrix, typename VectorOut, typename Assign> +inline void rvec_mat_mult(const VectorIn& v, const HermitianMatrix& A, VectorOut& w, Assign, tag::flat<tag::hermitian_multi_vector>) +{ + vampir_trace<2027> tracer; + typename HermitianMatrix::const_ref_type B= A.const_ref(); // Referred matrix + + if (Assign::init_to_zero) set_to_zero(w); + for (unsigned i= 0; i < num_cols(B); i++) + Assign::update(w, v[i] * mtl::vec::conj(trans(B.vector(i)))); +} + + +// Vector sparse matrix multiplication +template <typename VectorIn, typename Matrix, typename VectorOut, typename Assign> +inline void rvec_mat_mult(const VectorIn& v, const Matrix& A, VectorOut& w, Assign, tag::flat<tag::sparse>) +{ + vampir_trace<3028> tracer; + rvec_smat_mult(v, A, w, Assign(), typename OrientedCollection<Matrix>::orientation()); +} + + + +template <typename VectorIn, typename Matrix, typename VectorOut, typename Assign> +inline void rvec_smat_mult(const VectorIn& v, const Matrix& A, VectorOut& w, Assign, tag::row_major) +{ + using namespace tag; namespace traits = mtl::traits; + using traits::range_generator; + using mtl::vec::set_to_zero; + typedef typename range_generator<row, Matrix>::type a_cur_type; + typedef typename range_generator<nz, a_cur_type>::type a_icur_type; + + typename traits::col<Matrix>::type col_a(A); + typename traits::const_value<Matrix>::type value_a(A); + + if (Assign::init_to_zero) set_to_zero(w); + + unsigned cv= 0; // traverse all columns of v + for (a_cur_type ac= begin<row>(A), aend= end<row>(A); ac != aend; ++ac, ++cv) { + typename Collection<VectorIn>::value_type vv= v[cv]; + for (a_icur_type aic= begin<nz>(ac), aiend= end<nz>(ac); aic != aiend; ++aic) + Assign::update(w[col_a(*aic)], vv * value_a(*aic)); + } +} + +template <typename VectorIn, typename Matrix, typename VectorOut, typename Assign> +inline void rvec_smat_mult(const VectorIn& v, const Matrix& A, VectorOut& w, Assign, tag::col_major) +{ + using namespace tag; + using mtl::traits::range_generator; + using math::zero; + using mtl::vec::set_to_zero; + + typedef typename range_generator<col, Matrix>::type a_cur_type; + typedef typename range_generator<nz, a_cur_type>::type a_icur_type; + typename mtl::traits::row<Matrix>::type row_a(A); + typename mtl::traits::const_value<Matrix>::type value_a(A); + + if (Assign::init_to_zero) set_to_zero(w); + + typedef typename Collection<VectorOut>::value_type value_type; + + a_cur_type ac= begin<col>(A), aend= end<col>(A); + for (unsigned i= 0; ac != aend; ++ac, ++i) { + value_type tmp= zero(w[i]); + for (a_icur_type aic= begin<nz>(ac), aiend= end<nz>(ac); aic != aiend; ++aic) + tmp+= v[row_a(*aic)] * value_a(*aic); + Assign::update(w[i], tmp); + } +} + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_RVEC_MAT_MULT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/scale.hpp b/install/MTL/include/boost/numeric/mtl/operation/scale.hpp new file mode 100644 index 00000000..6c91c53f --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/scale.hpp @@ -0,0 +1,108 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SCALE_INCLUDE +#define MTL_SCALE_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/std_concept.hpp> +#include <boost/numeric/mtl/matrix/map_view.hpp> +#include <boost/numeric/mtl/vector/map_view.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/utility/true_copy.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + + namespace vec { + + template <typename Value1, typename Vector> + typename traits::enable_if_vector<Vector, scaled_view<typename mtl::traits::true_copy<Value1>::type, Vector> >::type + inline scale(const Value1& value1, const Vector& vector) + { + vampir_trace<2028> tracer; + return scaled_view<typename mtl::traits::true_copy<Value1>::type, Vector>(value1, vector); + } + } + + namespace mat { + + template <typename Value1, typename Matrix> + typename traits::enable_if_matrix<Matrix, scaled_view<Value1, Matrix> >::type + inline scale(const Value1& value1, const Matrix& matrix) + { + vampir_trace<3029> tracer; + return scaled_view<Value1, Matrix> (value1, matrix); + } + } + + using vec::scale; + using mat::scale; + + + namespace tfunctor { + + // AlgebraicCategory is by default tag::scalar + template <typename Value1, typename Value2, typename AlgebraicCategory> + struct scale + { + typedef typename Multiplicable<Value1, Value2>::result_type result_type; + explicit scale(const Value1& v1) : v1(v1) {} + + result_type operator() (const Value2& v2) const + { + return v1 * v2; + } + + Value1 value() const { return v1; } + private: + Value1 v1; + }; + + + template <typename Value1, typename Matrix> + struct scale<Value1, Matrix, tag::matrix> + { + typedef mat::scaled_view<Value1, Matrix> result_type; + explicit scale(const Value1& v1) : v1(v1) {} + + result_type operator() (const Matrix& matrix) const + { + return result_type(v1, matrix); + } + private: + typename mtl::traits::true_copy<Value1>::type v1; + }; + + + template <typename Value1, typename Vector> + struct scale<Value1, Vector, tag::vector> + { + typedef typename mtl::traits::true_copy<Value1>::type type1; + + typedef vec::scaled_view<type1, Vector> result_type; + explicit scale(const Value1& v1) : v1(type1(v1)) {} + + result_type operator() (const Vector& vector) const + { + return result_type(v1, vector); + } + private: + type1 v1; + }; + + } // namespace tfunctor + +} // namespace mtl + +#endif // MTL_SCALE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/secular.hpp b/install/MTL/include/boost/numeric/mtl/operation/secular.hpp new file mode 100644 index 00000000..8314be41 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/secular.hpp @@ -0,0 +1,117 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// With contributions from Cornelius Steinhardt + +#ifndef MTL_VECTOR_SECULAR_INCLUDE +#define MTL_VECTOR_SECULAR_INCLUDE + +#include <cmath> +#include <boost/utility.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/mtl/operation/minimal_increase.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace vec { + +/// Class for the secular equation( to solve eigenvalue problems) +template <typename Vector> +class secular_f +{ + typedef typename Collection<Vector>::value_type value_type; + typedef typename Collection<Vector>::size_type size_type; + + public: + /// Constructor needs 2 Vectors z(nummerator), d(dominator) and sigma as factor before the sum + secular_f(const Vector& z, const Vector& d, value_type sigma) + : z(z), d(d), sigma(sigma) {} + + /// secular_f equation as function, evaluates the function value + /** \f$f(x)=1+\sigma * sum_{i=1}^{n}\frac{z_i}{d_i-x} \f$**/ + value_type f(const value_type& lamb) + { + value_type fw= 1; + for(size_type i=0; i<size(z); i++) + fw+= sigma*z[i]*z[i]/(d[i]-lamb); + return fw; + } + + value_type square(value_type x) const { return x*x; } + + /// gradient of secular_f equation as function, evaluates the gradientfunction value + /** \f$gradf(x)=\sigma * sum_{i=1}^{n}\frac{z_i}{(d_i-x)^2} \f$**/ + value_type grad_f(const value_type& lamb) + { + value_type gfw= 0.0; + for(size_type i=0; i<size(z); i++) + gfw+= square(z[i] / (d[i] - lamb)); // , std::cout << "gfw = " << gfw << '\n'; //TODO + return sigma*gfw; + } + + /// Evaluates the roots of secular_f equation =0 with newton algo. + /** Computes mixed Newton and interval nesting. d must be sorted. **/ + Vector roots() + { + assert(size(z) > 1); + const double tol= 1.0e-6; + Vector start(resource(z)), lambda(resource(z)); + + for (size_type i= 0; i < size(z); i++) { + // Equal poles -> eigenvalue + if (i < size(z) - 1 && d[i] == d[i+1]) { + lambda[i]= d[i]; continue; } + + // Check if root is too close to pole (i.e. d[i]+eps > 0) then take this because we can't reach the root + value_type next= minimal_increase(d[i]), lamb, old; + if (f(next) >= value_type(0)){ + lambda[i]= next; continue; } + + if (i < size(z) - 1) + old= lamb= start[i]= (d[i] + d[i+1]) / 2; //start points between pols + else + old= lamb= start[i]= 1.5 * d[i] - 0.5 * d[i-1]; // last start point plus half the distance to second-last + + while (std::abs(f(lamb)) > tol) { + if (lamb <= d[i]) + start[i]= lamb= (d[i] + start[i]) / 2; + else + lamb-= f(lamb) / grad_f(lamb); + if (old == lamb) break; + old= lamb; + } + lambda[i]= lamb; + } + return lambda; + } + + private: + Vector z, d; + value_type sigma; +}; + +template <typename Vector, typename Value> +inline Vector secular(const Vector& z, const Vector& d, Value sigma) +{ + vampir_trace<3030> tracer; + secular_f<Vector> functor(z, d, sigma); + return functor.roots(); +} + +}}// namespace vector + + +#endif // MTL_VECTOR_SECULAR_INCLUDE + diff --git a/install/MTL/include/boost/numeric/mtl/operation/set_to_zero.hpp b/install/MTL/include/boost/numeric/mtl/operation/set_to_zero.hpp new file mode 100644 index 00000000..2ebe6790 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/set_to_zero.hpp @@ -0,0 +1,178 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SET_TO_0_INCLUDE +#define MTL_SET_TO_0_INCLUDE + +#include <algorithm> +#include <cassert> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { + + // Forward declarations + namespace mat { + template <typename Coll> + typename mtl::traits::enable_if_matrix<Coll>::type + set_to_zero(Coll& collection); + } + namespace vec { + template <typename Coll> + typename mtl::traits::enable_if_vector<Coll>::type + set_to_zero(Coll& collection); + } + + namespace impl { + + template <typename Coll> + void set_to_zero(Coll& collection, tag::vector_ref, ashape::scal) + { + using math::zero; + typename Collection<Coll>::value_type ref, my_zero(zero(ref)); + for (typename Collection<Coll>::size_type i= 0; i < size(collection); ++i) + collection[i]= my_zero; + } + + template <typename Coll> + void set_to_zero(Coll& collection, tag::contiguous_dense, ashape::scal) + { + using math::zero; + typename Collection<Coll>::value_type ref, my_zero(zero(ref)); + + std::fill(collection.elements(), collection.elements()+collection.used_memory(), my_zero); + } + + template <typename Coll> + void set_to_zero(Coll& collection, tag::std_vector, ashape::scal) + { + using math::zero; + typename Collection<Coll>::value_type ref, my_zero(zero(ref)); + + std::fill(collection.begin(), collection.end(), my_zero); + } + + template <typename Matrix> + void set_to_zero(Matrix& matrix, tag::morton_dense, ashape::scal) + { + using math::zero; + typename Collection<Matrix>::value_type ref, my_zero(zero(ref)); + // maybe faster to do it straight + // if performance problems we'll take care of the holes + // std::cout << "set_to_zero: used_memory = " << matrix.used_memory() << "\n"; + std::fill(matrix.elements(), matrix.elements() + matrix.used_memory(), my_zero); + +#if 0 + for (int i= 0; i < matrix.num_rows(); i++) + for (int j= 0; j < matrix.num_cols(); j++) + matrix[i][j]= my_zero; +#endif + } + + // For nested collection, we must consider the dimensions of the elements + // (Morton-order is included in contiguous_dense) + template <typename Coll> + void set_to_zero(Coll& collection, tag::contiguous_dense, ashape::nonscal) + { + for (typename Collection<Coll>::size_type i= 0; i < collection.used_memory(); ++i) + set_to_zero(collection.value_n(i)); + } + + + // Is approbriate for all sparse matrices and vectors (including collections as value_type) + template <typename Coll> + void set_to_zero(Coll& collection, tag::sparse, ashape::universe) + { + collection.make_empty(); + } + + // Special treatment for multi_vector + template <typename Coll> + void set_to_zero(Coll& collection, tag::multi_vector, ashape::universe) + { + using mtl::vec::set_to_zero; + for (typename Collection<Coll>::size_type i= 0; i < num_cols(collection); ++i) + set_to_zero(collection.vector(i)); + } + + template <typename Coll> + bool has_strided_data(const Coll&) + { return false; } + + template <typename Value, typename Parameter> + bool has_strided_data(const mat::dense2D<Value, Parameter>& A) + { return A.has_strided_data(); } + + + template <typename Matrix> + void naive_set_to_zero(Matrix& A, tag::matrix, tag::dense) + { + using math::zero; + typename Collection<Matrix>::value_type ref, my_zero(zero(ref)); + + for (unsigned i= 0; i < num_rows(A); i++) + for (unsigned j= 0; j < num_cols(A); j++) + A[i][j]= my_zero; + } + + template <typename Matrix> + void naive_set_to_zero(Matrix&, tag::matrix, tag::sparse) + { + assert(true); // must not be called + } + + } + + +namespace mat { + + /// Sets all values of a collection to 0 + /// More spefically the defined multiplicative identity element + template <typename Coll> + typename mtl::traits::enable_if_matrix<Coll>::type + set_to_zero(Coll& collection) + { + using mtl::traits::category; + vampir_trace<3031> tracer; + typedef typename Collection<Coll>::value_type value_type; + if (mtl::impl::has_strided_data(collection)) + mtl::impl::naive_set_to_zero(collection, typename category<Coll>::type(), typename category<Coll>::type()); + else + mtl::impl::set_to_zero(collection, typename category<Coll>::type(),typename ashape::ashape<value_type>::type()); // 2. ashape ??? + } +} + +namespace vec { + + /// Sets all values of a collection to 0 + /// More spefically the defined multiplicative identity element + template <typename Coll> + typename mtl::traits::enable_if_vector<Coll>::type + set_to_zero(Coll& collection) + { + using mtl::traits::category; + vampir_trace<2029> tracer; + typedef typename Collection<Coll>::value_type value_type; + mtl::impl::set_to_zero(collection, typename category<Coll>::type(),typename ashape::ashape<value_type>::type()); + } + +} + +} // namespace mtl + +#endif // MTL_SET_TO_0_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/sfunctor.hpp b/install/MTL/include/boost/numeric/mtl/operation/sfunctor.hpp new file mode 100644 index 00000000..9d01d352 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/sfunctor.hpp @@ -0,0 +1,431 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SFUNCTOR_INCLUDE +#define MTL_SFUNCTOR_INCLUDE + +#include <cmath> +#include <boost/numeric/mtl/concept/std_concept.hpp> +#include <boost/numeric/mtl/concept/magnitude.hpp> +#include <boost/numeric/mtl/concept/static_functor.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace sfunctor { + +template <typename Value1, typename Value2> +struct plus +{ + typedef const Value1& first_argument_type; + typedef const Value2& second_argument_type; + typedef typename Addable<Value1, Value2>::result_type result_type; + + static inline result_type apply(const Value1& v1, const Value2& v2) + { + return v1 + v2; + } + + result_type operator() (const Value1& v1, const Value2& v2) const + { + vampir_trace<23> tracer; + return v1 + v2; + } +}; + +template <typename Value1, typename Value2> +struct minus +{ + typedef const Value1& first_argument_type; + typedef const Value2& second_argument_type; + typedef typename Subtractable<Value1, Value2>::result_type result_type; + + static inline result_type apply(const Value1& v1, const Value2& v2) + { + return v1 - v2; + } + + result_type operator() (const Value1& v1, const Value2& v2) const + { + vampir_trace<24> tracer; + return v1 - v2; + } +}; + +template <typename Value1, typename Value2> +struct times +{ + typedef const Value1& first_argument_type; + typedef const Value2& second_argument_type; + typedef typename Multiplicable<Value1, Value2>::result_type result_type; + + static inline result_type apply(const Value1& v1, const Value2& v2) + { + return v1 * v2; + } + + result_type operator() (const Value1& v1, const Value2& v2) const + { + vampir_trace<25> tracer; + return v1 * v2; + } +}; + +template <typename Value1, typename Value2> +struct divide +{ + typedef const Value1& first_argument_type; + typedef const Value2& second_argument_type; + typedef typename Divisible<Value1, Value2>::result_type result_type; + + static inline result_type apply(const Value1& v1, const Value2& v2) + { + return v1 / v2; + } + + result_type operator() (const Value1& v1, const Value2& v2) const + { + vampir_trace<26> tracer; + return v1 / v2; + } +}; + +template <typename Value1, typename Value2> +struct assign +{ + typedef Value1& first_argument_type; + typedef const Value2& second_argument_type; + typedef Value1& result_type; + + static inline result_type apply(Value1& v1, const Value2& v2) + { + return v1= v2; + } + + result_type operator() (Value1& v1, const Value2& v2) const + { + vampir_trace<27> tracer; + return v1= v2; + } +}; + +template <typename Value1, typename Value2> +struct plus_assign +{ + typedef Value1& first_argument_type; + typedef const Value2& second_argument_type; + typedef Value1& result_type; + + static inline result_type apply(Value1& v1, const Value2& v2) + { + return v1+= v2; + } + + result_type operator() (Value1& v1, const Value2& v2) const + { + vampir_trace<28> tracer; + return v1+= v2; + } +}; + +template <typename Value1, typename Value2> +struct minus_assign +{ + typedef Value1& first_argument_type; + typedef const Value2& second_argument_type; + typedef Value1& result_type; + + static inline result_type apply(Value1& v1, const Value2& v2) + { + return v1-= v2; + } + + result_type operator() (Value1& v1, const Value2& v2) const + { + vampir_trace<29> tracer; + return v1-= v2; + } +}; + +template <typename Value1, typename Value2> +struct times_assign +{ + typedef Value1& first_argument_type; + typedef const Value2& second_argument_type; + typedef Value1& result_type; + + static inline result_type apply(Value1& v1, const Value2& v2) + { + return v1*= v2; + } + + result_type operator() (Value1& v1, const Value2& v2) const + { + vampir_trace<30> tracer; + return v1*= v2; + } +}; + +template <typename Value1, typename Value2> +struct divide_assign +{ + typedef Value1& first_argument_type; + typedef const Value2& second_argument_type; + typedef Value1& result_type; + + static inline result_type apply(Value1& v1, const Value2& v2) + { + return v1/= v2; + } + + result_type operator() (Value1& v1, const Value2& v2) const + { + vampir_trace<31> tracer; + return v1/= v2; + } +}; + + +// Might be helpful for surplus functor arguments +template <typename Value> +struct identity +{ + typedef const Value& argument_type; + typedef Value result_type; + + static inline result_type apply(const Value& v) + { + return v; + } + + result_type operator() (const Value& v) const + { + vampir_trace<32> tracer; + return v; + } +}; + + +template <typename Value> +struct abs +{ + typedef const Value& argument_type; + typedef typename Magnitude<Value>::type result_type; + + static inline result_type apply(const Value& v) + { + using std::abs; + return abs(v); + } + + result_type operator() (const Value& v) + { + vampir_trace<33> tracer; + return apply(v); + } +}; + +template <typename Value> +struct sqrt +{ + typedef const Value& argument_type; + typedef Value result_type; + + static inline result_type apply(const Value& v) + { + using std::sqrt; + return sqrt(v); + } + + result_type operator() (const Value& v) + { + vampir_trace<34> tracer; + return apply(v); + } +}; + +template <typename Value> +struct square +{ + typedef const Value& argument_type; + typedef Value result_type; + + static inline result_type apply(const Value& v) + { + return v * v; + } + + result_type operator() (const Value& v) + { + vampir_trace<35> tracer; + return apply(v); + } +}; + + +template <typename Value> +struct negate +{ + typedef const Value& argument_type; + typedef Value result_type; + + static inline result_type apply(const Value& v) { return -v; } + result_type operator() (const Value& v) const + { + vampir_trace<36> tracer; + return -v; + } +}; + + +/// Compose functors \p F and \p G, i.e. compute f(g(x)). +/** Functors must be models of StaticUnaryFunctor, + StaticUnaryFunctor<G>::result_type must be convertible to + StaticUnaryFunctor<F>::argument_type. + Under these conditions compose<F, G> will be a model of StaticUnaryFunctor. +**/ +template <typename F, typename G> +struct compose +{ + typedef typename StaticUnaryFunctor<G>::argument_type argument_type; + typedef typename StaticUnaryFunctor<F>::result_type result_type; + + static inline result_type apply(argument_type x) + { + return F::apply(G::apply(x)); + } + + result_type operator()(argument_type x) + { + vampir_trace<37> tracer; + return apply(x); + } +}; + + +/// Compose functors \p F and \p G with G in F's first argument, i.e. compute f(g(x), y). +/** F/G must be models of StaticBinaryFunctor/StaticUnaryFunctor, + StaticUnaryFunctor<G>::result_type must be convertible to + StaticBinaryFunctor<F>::first_argument_type. + Under these conditions compose_first<F, G> will be a model of StaticBinaryFunctor. +**/ +template <typename F, typename G> +struct compose_first +{ + typedef typename StaticUnaryFunctor<G>::argument_type first_argument_type; + typedef typename StaticBinaryFunctor<F>::second_argument_type second_argument_type; + typedef typename StaticBinaryFunctor<F>::result_type result_type; + + static inline result_type apply(first_argument_type x, second_argument_type y) + { + return F::apply(G::apply(x), y); + } + + result_type operator()(first_argument_type x, second_argument_type y) + { + vampir_trace<38> tracer; + return apply(x, y); + } +}; + + +/// Compose functors \p F and \p G with G in F's second argument, i.e. compute f(x, g(y)). +/** F/G must be models of StaticBinaryFunctor/StaticUnaryFunctor, + StaticUnaryFunctor<G>::result_type must be convertible to + StaticBinaryFunctor<F>::second_argument_type. + Under these conditions compose_second<F, G> will be a model of StaticBinaryFunctor. +**/ +template <typename F, typename G> +struct compose_second +{ + typedef typename StaticBinaryFunctor<F>::first_argument_type first_argument_type; + typedef typename StaticUnaryFunctor<G>::argument_type second_argument_type; + typedef typename StaticBinaryFunctor<F>::result_type result_type; + + static inline result_type apply(first_argument_type x, second_argument_type y) + { + return F::apply(x, G::apply(y)); + } + + result_type operator()(first_argument_type x, second_argument_type y) + { + vampir_trace<39> tracer; + return apply(x, y); + } +}; + +/// Compose functors \p F, \p G, and \p H with G/H in F's first/second argument, i.e. compute f(g(x), h(y)). +/** F/G must be models of StaticBinaryFunctor/StaticUnaryFunctor, + StaticUnaryFunctor<G>::result_type must be convertible to + StaticBinaryFunctor<F>::first_argument_type and + StaticUnaryFunctor<H>::result_type must be convertible to + StaticBinaryFunctor<F>::second_argument_type. + Under these conditions compose_both<F, G, H> will be a model of StaticBinaryFunctor. +**/ +template <typename F, typename G, typename H> +struct compose_both +{ + typedef typename StaticUnaryFunctor<G>::argument_type first_argument_type; + typedef typename StaticUnaryFunctor<H>::argument_type second_argument_type; + typedef typename StaticBinaryFunctor<F>::result_type result_type; + + static inline result_type apply(first_argument_type x, second_argument_type y) + { + return F::apply(G::apply(x), H::apply(y)); + } + + result_type operator()(first_argument_type x, second_argument_type y) + { + vampir_trace<40> tracer; + return apply(x, y); + } +}; + +/// Compose unary functor \p F with binary functor \p G, i.e. compute f(g(x, y)). +/** F/G must be models of StaticUnaryFunctor/StaticBinaryFunctor, + StaticBinaryFunctor<G>::result_type must be convertible to + StaticUnaryFunctor<F>::argument_type. + Under these conditions compose_binary<F, G> will be a model of StaticBinaryFunctor. +**/ +template <typename F, typename G> +struct compose_binary +{ + typedef typename StaticBinaryFunctor<G>::first_argument_type first_argument_type; + typedef typename StaticBinaryFunctor<G>::second_argument_type second_argument_type; + typedef typename StaticUnaryFunctor<F>::result_type result_type; + + static inline result_type apply(first_argument_type x, second_argument_type y) + { + return F::apply(G::apply(x, y)); + } + + result_type operator()(first_argument_type x, second_argument_type y) + { + vampir_trace<41> tracer; + return apply(x, y); + } +}; + + +/// Templatized example of composition, computes l_2 norm in 2D, i.e. sqrt(abs(x*x + y*y)) +template <typename T> +struct l_2_2D + : public compose_binary<sqrt<typename abs<T>::result_type>, + compose_binary<abs<T>, + compose_both<plus<T, T>, + square<T>, + square<T> > + > + > +{}; + +}} // namespace mtl::sfunctor + +#endif // MTL_SFUNCTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/shift_block.hpp b/install/MTL/include/boost/numeric/mtl/operation/shift_block.hpp new file mode 100644 index 00000000..aceeba06 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/shift_block.hpp @@ -0,0 +1,41 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SHIFT_BLOCKS_INCLUDE +#define MTL_SHIFT_BLOCKS_INCLUDE + +#include <boost/numeric/mtl/operation/shift_block_detail.hpp> + +namespace mtl { namespace operations { + +// Shift blocks in an 1D array to remove unnecessary holes +// inserting holes in other places where needed (e.g. for inserting new values) +// +// Block 'i' is the half-open interval [starts[i], ends[i]) in data +// It will be copied into [new_starts[i], ...) in place +// Blocks are ordered: start[i] <= start[i+1] +// Data between blocks are considered holes and can be overwritten +// +template <typename Size, typename Starts, typename NewStarts, typename Ends, typename Data> +void shift_blocks(Size blocks, Starts const& starts, NewStarts const& new_starts, + Ends const& ends, Data& data) +{ + for (Size i = 0; i < blocks; ) { + detail::copy_blocks_forward(i, blocks, starts, new_starts, ends, data); + detail::copy_blocks_backward(i, blocks, starts, new_starts, ends, data); + } +} + + +}} // namespace mtl::operations + +#endif // MTL_SHIFT_BLOCKS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/shift_block_detail.hpp b/install/MTL/include/boost/numeric/mtl/operation/shift_block_detail.hpp new file mode 100644 index 00000000..7a80661d --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/shift_block_detail.hpp @@ -0,0 +1,58 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SHIFT_BLOCKS_DETAIL_INCLUDE +#define MTL_SHIFT_BLOCKS_DETAIL_INCLUDE + +#include <algorithm> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace operations { namespace detail { + +// &v[i] is replaced by &v[0]+i to enable past-end addresses for STL copy +// otherwise MSVC complaines + +template <typename Size, typename Starts, typename NewStarts, typename Ends, typename Data> +inline void copy_blocks_forward(Size& i, Size blocks, Starts const& starts, NewStarts const& new_starts, + Ends const& ends, Data& data) +{ + using std::copy; + vampir_trace<1005> tracer; + // Copy forward as long as blocks are not shifted + for (; i < blocks && starts[i] >= new_starts[i]; ++i) + if (starts[i] > new_starts[i]) + copy(&data[0] + starts[i], &data[0] + ends[i], &data[0] + new_starts[i]); +} + +template <typename Size, typename Starts, typename NewStarts, typename Ends, typename Data> +inline void copy_blocks_backward(Size& i, Size blocks, Starts const& starts, NewStarts const& new_starts, + Ends const& ends, Data& data) +{ + using std::copy; + using std::copy_backward; + vampir_trace<1006> tracer; + Size first = i; + // find first block to be copied forward (or end) + while (i < blocks && starts[i] < new_starts[i]) ++i; + + for (Size j = i; j-- > first; ) + if (ends[j] <= new_starts[j]) + copy(&data[0] + starts[j], &data[0] + ends[j], &data[0] + new_starts[j]); + else + copy_backward(&data[0] + starts[j], &data[0] + ends[j], &data[0] + (new_starts[j]+ends[j]-starts[j])); +} + +}}} // namespace mtl::operations::detail + +#endif // MTL_SHIFT_BLOCKS_DETAIL_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/signum.hpp b/install/MTL/include/boost/numeric/mtl/operation/signum.hpp new file mode 100644 index 00000000..337b6c95 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/signum.hpp @@ -0,0 +1,63 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SIGNUM_INCLUDE +#define MTL_SIGNUM_INCLUDE + +#include <complex> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/operation/real.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + +namespace sfunctor { + + template <typename Value> + struct signum + { + typedef Value result_type; + + static inline Value apply(const Value& v) + { + using math::zero; using math::one; + return v == zero(v) ? zero(v) : ( v < zero(v) ? -one(v) : one(v) ); + } + }; + + template <typename Value> + struct signum<std::complex<Value> > + { + typedef Value result_type; + + static inline Value apply(const std::complex<Value>& v) + { + return signum<Value>::apply(mtl::real(v)); + } + }; + +} + +/// Sign of scalars +/** For complex numbers, the sign of real part is returned; subject to revision. **/ +template <typename Value> +inline typename sfunctor::signum<Value>::result_type signum(const Value& v) +{ + vampir_trace<6> tracer; + return sfunctor::signum<Value>::apply(v); +} + + +} // namespace mtl + +#endif // MTL_SIGNUM_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/size.hpp b/install/MTL/include/boost/numeric/mtl/operation/size.hpp new file mode 100644 index 00000000..e9000afc --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/size.hpp @@ -0,0 +1,68 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SIZE_INCLUDE +#define MTL_SIZE_INCLUDE + +#include <vector> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + +namespace traits { + + /// General declaration, used to disable unsupported types + template <typename Collection> + struct size {}; + + /// size implementation for STL vectors + template <typename Value> + struct size< std::vector<Value> > + { + typedef std::size_t type; + type operator()(const std::vector<Value>& v) { return v.size(); } + }; + + /// size implementation for (1D) arrays interpreted as vectors + template <typename Value, unsigned Size> + struct size<Value[Size]> + { + vampir_trace<2031> tracer; + typedef std::size_t type; + type operator()(const Value[Size]) { return Size; } + }; + + /// size implementation for (2D and higher) arrays interpreted as matrices + template <typename Value, unsigned Rows, unsigned Cols> + struct size<Value[Rows][Cols]> + { + typedef std::size_t type; + vampir_trace<3033> tracer; + type operator()(const Value[Rows][Cols]) { return Rows * Cols; } + }; +} + + +/// size function for non-MTL types (uses implicit enable_if) +template <typename Collection> +typename traits::size<Collection>::type +inline size(const Collection& c) +{ + + return traits::size<Collection>()(c); +} + + +} // namespace mtl + +#endif // MTL_SIZE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/size1D.hpp b/install/MTL/include/boost/numeric/mtl/operation/size1D.hpp new file mode 100644 index 00000000..c16e2107 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/size1D.hpp @@ -0,0 +1,70 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SIZE1D_INCLUDE +#define MTL_SIZE1D_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/size.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +// #include <boost/utility/enable_if.hpp> + +namespace mtl { + + namespace vec { + +#if 0 + template <typename Vector> + typename Collection<Vector>::size_type + inline size1D(const Vector& v) + { + return size(v); + } +#endif + + // Very ugly hack, very ungeneric + template <typename Value, typename P> + std::size_t inline size1D(const dense_vector<Value, P>& v) + { + return size(v); + } + } + + namespace mat { + + template <typename Vector> + typename Collection<multi_vector<Vector> >::size_type + inline size1D(multi_vector<Vector>& A) + { + vampir_trace<3032> tracer; + return num_cols(A); + } + } + +/// One-dimensional size function +/** Returns size for MTL vectors, STL vector and C arrays. + For multi_vector the number of vectors is returned. + Not defined for other matrix types. + Implementation for standard types uses implicit enable_if to avoid ambiguities. **/ +template <typename Vector> +typename traits::size<Vector>::type +inline size1D(const Vector& v) +{ + vampir_trace<2030> tracer; + return traits::size<Vector>()(v); +} + +} // namespace mtl + +#endif // MTL_SIZE1D_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/smat_dmat_mult.hpp b/install/MTL/include/boost/numeric/mtl/operation/smat_dmat_mult.hpp new file mode 100644 index 00000000..9c8c00aa --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/smat_dmat_mult.hpp @@ -0,0 +1,271 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SMAT_DMAT_MULT_INCLUDE +#define MTL_SMAT_DMAT_MULT_INCLUDE + +#include <boost/numeric/mtl/operation/set_to_zero.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/flatcat.hpp> +#include <boost/numeric/meta_math/loop1.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace functor { + +template <typename Assign= assign::assign_sum, + typename Backup= no_op> // To allow 2nd parameter, is ignored +struct gen_smat_dmat_mult +{ + template <typename MatrixA, typename MatrixB, typename MatrixC> + void operator()(MatrixA const& a, MatrixB const& b, MatrixC& c) + { + vampir_trace<4018> tracer; + apply(a, b, c, typename OrientedCollection<MatrixA>::orientation()); + } + +private: + template <typename MatrixA, typename MatrixB, typename MatrixC> + void apply(MatrixA const& a, MatrixB const& b, MatrixC& c, tag::row_major) + { + using namespace tag; + using traits::range_generator; + typedef typename range_generator<row, MatrixA>::type a_cur_type; + typedef typename range_generator<row, MatrixC>::type c_cur_type; + typedef typename range_generator<col, MatrixB>::type b_cur_type; + + typedef typename range_generator<nz, a_cur_type>::type a_icur_type; + typedef typename range_generator<all, b_cur_type>::type b_icur_type; + typedef typename range_generator<iter::all, c_cur_type>::type c_icur_type; + + typename traits::col<MatrixA>::type col_a(a); + typename traits::const_value<MatrixA>::type value_a(a); + typename traits::const_value<MatrixB>::type value_b(b); + + if (Assign::init_to_zero) set_to_zero(c); + + a_cur_type ac= begin<row>(a), aend= end<row>(a); + for (c_cur_type cc= begin<row>(c); ac != aend; ++ac, ++cc) { + + b_cur_type bc= begin<col>(b), bend= end<col>(b); + for (c_icur_type cic= begin<iter::all>(cc); bc != bend; ++bc, ++cic) { + + typename MatrixC::value_type c_tmp(*cic); + for (a_icur_type aic= begin<nz>(ac), aiend= end<nz>(ac); aic != aiend; ++aic) { + + typename Collection<MatrixA>::size_type ca= col_a(*aic); // column of non-zero + + b_icur_type bic= begin<all>(bc); + bic+= ca; + Assign::update(c_tmp, value_a(*aic) * value_b(*bic)); + } + *cic= c_tmp; + } + } + } + + + template <typename MatrixA, typename MatrixB, typename MatrixC> + void apply(MatrixA const& a, MatrixB const& b, MatrixC& c, tag::col_major) + { + using namespace tag; + using traits::range_generator; + typedef typename range_generator<col, MatrixA>::type a_cur_type; + typedef typename range_generator<nz, a_cur_type>::type a_icur_type; + + typename traits::row<MatrixA>::type row_a(a); + typename traits::const_value<MatrixA>::type value_a(a); + + if (Assign::init_to_zero) set_to_zero(c); + + unsigned rb= 0; // traverse all rows of b + for (a_cur_type ac= begin<col>(a), aend= end<col>(a); ac != aend; ++ac, ++rb) + for (a_icur_type aic= begin<nz>(ac), aiend= end<nz>(ac); aic != aiend; ++aic) { + typename Collection<MatrixA>::size_type ra= row_a(*aic); // row in A and C + typename Collection<MatrixA>::value_type va= value_a(*aic); // value of non-zero + + for (unsigned cb= 0; cb < num_cols(b); ++cb) // column in B and C + Assign::update(c(ra, cb), va * b(rb, cb)); + } + } +}; + + +// ======================= +// Unrolled +// required has_2D_layout +// ======================= + +// Define defaults if not yet given as Compiler flag +#ifndef MTL_SMAT_DMAT_MULT_TILING1 +# define MTL_SMAT_DMAT_MULT_TILING1 8 +#endif + +template <unsigned long Index0, unsigned long Max0, typename Assign> +struct gen_tiling_smat_dmat_mult_block + : public meta_math::loop1<Index0, Max0> +{ + typedef meta_math::loop1<Index0, Max0> base; + typedef gen_tiling_smat_dmat_mult_block<base::next_index0, Max0, Assign> next_t; + + template <typename Value, typename ValueA, typename ValueB, typename Size> + static inline void apply(Value& tmp00, Value& tmp01, Value& tmp02, Value& tmp03, Value& tmp04, + Value& tmp05, Value& tmp06, Value& tmp07, Value& tmp08, Value& tmp09, + Value& tmp10, Value& tmp11, Value& tmp12, Value& tmp13, Value& tmp14, Value& tmp15, + const ValueA& va, ValueB *begin_b, const Size& bci) + { + tmp00+= va * *(begin_b + base::index0 * bci); + next_t::apply(tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, tmp08, tmp09, + tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp00, + va, begin_b, bci); + } + + template <typename Value, typename MatrixC, typename SizeC> + static inline void update(Value& tmp00, Value& tmp01, Value& tmp02, Value& tmp03, Value& tmp04, + Value& tmp05, Value& tmp06, Value& tmp07, Value& tmp08, Value& tmp09, + Value& tmp10, Value& tmp11, Value& tmp12, Value& tmp13, Value& tmp14, Value& tmp15, + MatrixC& c, SizeC i, SizeC k) + { + Assign::update(c(i, k + base::index0), tmp00); + next_t::update(tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, tmp08, tmp09, + tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp00, + c, i, k); + } +}; + + +template <unsigned long Max0, typename Assign> +struct gen_tiling_smat_dmat_mult_block<Max0, Max0, Assign> + : public meta_math::loop1<Max0, Max0> +{ + typedef meta_math::loop1<Max0, Max0> base; + + template <typename Value, typename ValueA, typename ValueB, typename Size> + static inline void apply(Value& tmp00, Value&, Value&, Value&, Value&, + Value&, Value&, Value&, Value&, Value&, + Value&, Value&, Value&, Value&, Value&, Value&, + const ValueA& va, ValueB *begin_b, const Size& bci) + { + tmp00+= va * *(begin_b + base::index0 * bci); + } + + template <typename Value, typename MatrixC, typename SizeC> + static inline void update(Value& tmp00, Value&, Value&, Value&, Value&, + Value&, Value&, Value&, Value&, Value&, + Value&, Value&, Value&, Value&, Value&, Value&, + MatrixC& c, SizeC i, SizeC k) + { + Assign::update(c(i, k + base::index0), tmp00); + } +}; + + +template <unsigned long Tiling1= MTL_SMAT_DMAT_MULT_TILING1, + typename Assign= assign::assign_sum, + typename Backup= gen_smat_dmat_mult<Assign> > +struct gen_tiling_smat_dmat_mult +{ + template <typename MatrixA, typename MatrixB, typename MatrixC> + void operator()(MatrixA const& a, MatrixB const& b, MatrixC& c) + { + vampir_trace<4019> tracer; + apply(a, b, c, traits::layout_flatcat<MatrixC>()); + } + +private: + template <typename MatrixA, typename MatrixB, typename MatrixC> + void apply(MatrixA const& a, MatrixB const& b, MatrixC& c, tag::universe) + { + Backup()(a, b, c); + } + + template <typename MatrixA, typename MatrixB, typename MatrixC> + void apply(MatrixA const& a, MatrixB const& b, MatrixC& c, tag::flat<tag::has_2D_layout>) + { + apply2(a, b, c, typename OrientedCollection<MatrixA>::orientation()); + } + + template <typename MatrixA, typename MatrixB, typename MatrixC> + void apply2(MatrixA const& a, MatrixB const& b, MatrixC& c, tag::col_major) + { + // may be I'll write an optimized version later + Backup()(a, b, c); + } + + + template <typename MatrixA, typename MatrixB, typename MatrixC> + void apply2(MatrixA const& a, MatrixB const& b, MatrixC& c, tag::row_major) + { + using namespace tag; + using traits::range_generator; + + typedef gen_tiling_smat_dmat_mult_block<1, Tiling1, Assign> block; + typedef typename Collection<MatrixA>::size_type size_type; + typedef typename Collection<MatrixC>::value_type value_type; + const value_type z= math::zero(c[0][0]); // if this are matrices we need their size + + typedef typename range_generator<row, MatrixA>::type a_cur_type; + typedef typename range_generator<nz, a_cur_type>::type a_icur_type; + + typename traits::col<MatrixA>::type col_a(a); + typename traits::const_value<MatrixA>::type value_a(a); + + if (Assign::init_to_zero) set_to_zero(c); + + size_type i_max= num_cols(b), i_block= Tiling1 * (i_max / Tiling1); + size_t bci= i_max > 1 ? &b(0, 1) - &b(0, 0) : 1; // offset of incrementing B's column if more than 1 column + + size_type rc= 0; // start in row 0 + for (a_cur_type ac= begin<row>(a), aend= end<row>(a); ac != aend; ++ac, ++rc) { + + for (size_type i= 0; i < i_block; i+= Tiling1) { + + value_type tmp00= z, tmp01= z, tmp02= z, tmp03= z, tmp04= z, + tmp05= z, tmp06= z, tmp07= z, tmp08= z, tmp09= z, + tmp10= z, tmp11= z, tmp12= z, tmp13= z, tmp14= z, tmp15= z; + + for (a_icur_type aic= begin<nz>(ac), aiend= end<nz>(ac); aic != aiend; ++aic) { + typename Collection<MatrixA>::size_type ca= col_a(*aic); // column of non-zero + typename Collection<MatrixA>::value_type va= value_a(*aic); // value of non-zero + + // Element in first vector in block to be multiplied with va; rb==ca + const typename MatrixB::value_type *begin_b= &b(ca, i); + block::apply(tmp00, tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, tmp08, tmp09, + tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, + va, begin_b, bci); + } + block::update(tmp00, tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, tmp08, tmp09, + tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, + c, rc, i); + } + + for (size_type i= i_block; i < i_max; i++) { + value_type tmp00= z; + for (a_icur_type aic= begin<nz>(ac), aiend= end<nz>(ac); aic != aiend; ++aic) { + typename Collection<MatrixA>::size_type ca= col_a(aic); // column of non-zero + tmp00+= value_a(*aic) * b(ca, i); + } + Assign::update(c(rc, i), tmp00); + } + } + } +}; + + + + +}} // namespace mtl::functor + +#endif // MTL_SMAT_DMAT_MULT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/smat_smat_mult.hpp b/install/MTL/include/boost/numeric/mtl/operation/smat_smat_mult.hpp new file mode 100644 index 00000000..3130e555 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/smat_smat_mult.hpp @@ -0,0 +1,198 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SMAT_SMAT_MULT_INCLUDE +#define MTL_SMAT_SMAT_MULT_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/transposed_matrix_type.hpp> +#include <boost/numeric/mtl/operation/mult_assign_mode.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign> +inline void smat_smat_mult(const MatrixA& A, const MatrixB& B, MatrixC& C, Assign, + tag::row_major, // orientation A + tag::row_major) // orientation B +{ + if (Assign::init_to_zero) set_to_zero(C); + + // Average numbers of non-zeros per row + double ava= num_cols(A) ? double(A.nnz()) / num_cols(A) : 0, + avb= num_rows(B) ? double(B.nnz()) / num_rows(B) : 0; + + // Define Updater type corresponding to assign mode + typedef typename Collection<MatrixC>::value_type C_value_type; + typedef typename operations::update_assign_mode<Assign, C_value_type>::type Updater; + + // Reserve 20% over the average's product for entries in C + mat::inserter<MatrixC, Updater> ins(C, int( ava * avb * 1.4 )); + + typename traits::row<MatrixA>::type row_A(A); + typename traits::col<MatrixA>::type col_A(A); + typename traits::const_value<MatrixA>::type value_A(A); + + typename traits::col<MatrixB>::type col_B(B); + typename traits::const_value<MatrixB>::type value_B(B); + + typedef typename traits::range_generator<tag::row, MatrixA>::type cursor_type; + cursor_type cursor = begin<tag::row>(A), cend = end<tag::row>(A); + for (unsigned ra= 0; cursor != cend; ++ra, ++cursor) { + // Iterate over non-zeros of each row of A + typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type; + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) { + typename Collection<MatrixA>::size_type ca= col_A(*icursor); // column of non-zero + typename Collection<MatrixA>::value_type va= value_A(*icursor); // value of non-zero + + // Get cursor corresponding to row 'ca' in matrix B + typedef typename traits::range_generator<tag::row, MatrixB>::type B_cursor_type; + B_cursor_type B_cursor = begin<tag::row>(B); + B_cursor+= ca; + + // Iterate over non-zeros of this row + typedef typename traits::range_generator<tag::nz, B_cursor_type>::type ib_cursor_type; + for (ib_cursor_type ib_cursor = begin<tag::nz>(B_cursor), ib_cend = end<tag::nz>(B_cursor); + ib_cursor != ib_cend; ++ib_cursor) { + typename Collection<MatrixB>::size_type cb= col_B(*ib_cursor); // column of non-zero + typename Collection<MatrixB>::value_type vb= value_B(*ib_cursor); // value of non-zero + ins(ra, cb) << va * vb; + } + } + } +} + +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign> +inline void smat_smat_mult(const MatrixA& A, const MatrixB& B, MatrixC& C, Assign, + tag::col_major, // orientation A + tag::col_major) // orientation B +{ + if (Assign::init_to_zero) set_to_zero(C); + + // Average numbers of non-zeros per column + double ava= double(A.nnz()) / num_cols(A), avb= double(B.nnz()) / num_cols(B); + + // Define Updater type corresponding to assign mode + typedef typename Collection<MatrixC>::value_type C_value_type; + typedef typename operations::update_assign_mode<Assign, C_value_type>::type Updater; + + // Reserve 20% over the average's product for entries in C + mat::inserter<MatrixC, Updater> ins(C, int( ava * avb * 1.2 )); + + typename traits::row<MatrixA>::type row_A(A); + typename traits::col<MatrixA>::type col_A(A); + typename traits::const_value<MatrixA>::type value_A(A); + + typename traits::row<MatrixB>::type row_B(B); + typename traits::col<MatrixB>::type col_B(B); + typename traits::const_value<MatrixB>::type value_B(B); + + typedef typename traits::range_generator<tag::col, MatrixB>::type cursor_type; + cursor_type cursor = begin<tag::col>(B), cend = end<tag::col>(B); + for (unsigned cb= 0; cursor != cend; ++cb, ++cursor) { + // Iterate over non-zeros of each column of B + typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type; + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) { + typename Collection<MatrixB>::size_type rb= row_B(*icursor); // row of non-zero + typename Collection<MatrixB>::value_type vb= value_B(*icursor); // value of non-zero + + // Get cursor corresponding to column 'rb' in matrix A + typedef typename traits::range_generator<tag::col, MatrixA>::type A_cursor_type; + A_cursor_type A_cursor = begin<tag::col>(A); + A_cursor+= rb; + + // Iterate over non-zeros of this column + typedef typename traits::range_generator<tag::nz, A_cursor_type>::type ia_cursor_type; + for (ia_cursor_type ia_cursor = begin<tag::nz>(A_cursor), ia_cend = end<tag::nz>(A_cursor); + ia_cursor != ia_cend; ++ia_cursor) { + typename Collection<MatrixA>::size_type ra= row_A(*ia_cursor); // row of non-zero + typename Collection<MatrixA>::value_type va= value_A(*ia_cursor); // value of non-zero + ins(ra, cb) << va * vb; + } + } + } +} + + +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign> +inline void smat_smat_mult(const MatrixA& A, const MatrixB& B, MatrixC& C, Assign, + tag::col_major, // orientation A + tag::row_major) // orientation B +{ + if (Assign::init_to_zero) set_to_zero(C); + + // Average numbers of non-zeros per row + double ava= double(A.nnz()) / num_rows(A), avb= double(B.nnz()) / num_rows(B); + + // Define Updater type corresponding to assign mode + typedef typename Collection<MatrixC>::value_type C_value_type; + typedef typename operations::update_assign_mode<Assign, C_value_type>::type Updater; + + // Reserve 20% over the average's product for entries in C + mat::inserter<MatrixC, Updater> ins(C, int( ava * avb * 1.2 )); + + typename traits::row<MatrixA>::type row_A(A); + typename traits::col<MatrixA>::type col_A(A); + typename traits::const_value<MatrixA>::type value_A(A); + + typename traits::row<MatrixB>::type row_B(B); + typename traits::col<MatrixB>::type col_B(B); + typename traits::const_value<MatrixB>::type value_B(B); + + typedef typename traits::range_generator<tag::col, MatrixA>::type A_cursor_type; + A_cursor_type A_cursor = begin<tag::col>(A), A_cend = end<tag::col>(A); + + typedef typename traits::range_generator<tag::row, MatrixB>::type B_cursor_type; + B_cursor_type B_cursor = begin<tag::row>(B); + + for (unsigned ca= 0; A_cursor != A_cend; ++ca, ++A_cursor, ++B_cursor) { + + // Iterate over non-zeros of A's column + typedef typename traits::range_generator<tag::nz, A_cursor_type>::type ia_cursor_type; + for (ia_cursor_type ia_cursor = begin<tag::nz>(A_cursor), ia_cend = end<tag::nz>(A_cursor); + ia_cursor != ia_cend; ++ia_cursor) + { + typename Collection<MatrixA>::size_type ra= row_A(*ia_cursor); // row of non-zero + typename Collection<MatrixA>::value_type va= value_A(*ia_cursor); // value of non-zero + + // Iterate over non-zeros of B's row + typedef typename traits::range_generator<tag::nz, B_cursor_type>::type ib_cursor_type; + for (ib_cursor_type ib_cursor = begin<tag::nz>(B_cursor), ib_cend = end<tag::nz>(B_cursor); + ib_cursor != ib_cend; ++ib_cursor) + { + typename Collection<MatrixB>::size_type cb= col_B(*ib_cursor); // column of non-zero + typename Collection<MatrixB>::value_type vb= value_B(*ib_cursor); // value of non-zero + ins(ra, cb) << va * vb; + } + } + } +} + + +template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign> +inline void smat_smat_mult(const MatrixA& A, const MatrixB& B, MatrixC& C, Assign, + tag::row_major, // orientation A + tag::col_major) // orientation B +{ + vampir_trace<4020> tracer; + // Copy B into a sparse row-major matrix + typename mtl::traits::transposed_sparse_matrix_type<MatrixB>::type B_copy(num_rows(B), num_cols(B)); + B_copy= B; + smat_smat_mult(A, B_copy, C, Assign(), tag::row_major(), tag::row_major()); +} + +} // namespace mtl + +#endif // MTL_SMAT_SMAT_MULT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/solve.hpp b/install/MTL/include/boost/numeric/mtl/operation/solve.hpp new file mode 100644 index 00000000..5d5adff7 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/solve.hpp @@ -0,0 +1,55 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_SOLVE_INCLUDE +#define MTL_MATRIX_SOLVE_INCLUDE + +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/lu.hpp> +#include <boost/numeric/mtl/interface/umfpack_solve.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace mat { + + namespace detail { + + template <typename Matrix, typename Vector> + Vector inline solve(const Matrix& A, const Vector& b, tag::dense) + { + vampir_trace<3034> tracer; + return lu_solve(A, b); + } + +# ifdef MTL_HAS_UMFPACK + template <typename Value, typename Parameters, typename Vector> + Vector inline solve(const Matrix& A, const Vector& b, tag::compressed2D) + { + vampir_trace<3035> tracer; + Vector x(num_cols(A)); + umfpack_solve(A, x, b); + return x; + } +# endif + } + + +template <typename Matrix, typename Vector> +Vector inline solve(const Matrix& A, const Vector& b) +{ + return detail::solve(A, b, typename category<Coll>::type()); +} + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_SOLVE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/sort.hpp b/install/MTL/include/boost/numeric/mtl/operation/sort.hpp new file mode 100644 index 00000000..31af0688 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/sort.hpp @@ -0,0 +1,204 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SORT_INCLUDE +#define MTL_SORT_INCLUDE + +#include <algorithm> +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/swap_row.hpp> +#include <boost/numeric/mtl/operation/size.hpp> + +namespace mtl { namespace vec { + +/// sort vector +template <typename Vector> +void inline sort(Vector& x) +{ + std::sort(x.begin(), x.end()); +} + +/// sort vector with qicksort from lo to hi +template <typename Vector> +void quicksort (Vector& a, typename Collection<Vector>::size_type lo, typename Collection<Vector>::size_type hi) +{ + vampir_trace<2032> tracer; + typename Collection<Vector>::size_type i=lo, j=hi; + + // VergleichsÂÂelement x + typename mtl::Collection<Vector>::value_type x=a[(lo+hi)/2]; + // Aufteilung + while (i<=j) + { + while (a[i]<x) i++; + while (a[j]>x) j--; + if (i<=j) + { + swap_row(a, i, j); + i++; j--; + } + } + // Recursion + if (lo<j) quicksort(a, lo, j); + if (i<hi) quicksort(a, i, hi); + std::cout<< "a=" << a << "\n"; +} + +/// sort vector and permutaion with qicksort from lo to hi +template <typename Vector, typename PermVec> +void quicksort (Vector& a, PermVec& p, typename Collection<Vector>::size_type lo, typename Collection<Vector>::size_type hi) +{ + vampir_trace<2033> tracer; + typename Collection<Vector>::size_type i=lo, j=hi; + + // VergleichsÂÂelement x + typename mtl::Collection<Vector>::value_type x=a[(lo+hi)/2]; +// std::cout<< "x=" << x << "\n"; + // Aufteilung + while (i<=j) + { + while (a[i]<x) i++; + while (a[j]>x) j--; + + if (i<=j) + { + swap_row(a, i, j); + swap_row(p, i, j); +// std::cout<< "a=" << a <<"\n"; + i++; + if( j == 0){ + break; + } else { + j--; + } + +// std::cout<< "i=" << i << "\n"; +// std::cout<< "j=" << j << "\n"; + } +// std::cout<< "j=" << j << "\n"; + } +// std::cout<< "aai=" << i << "\n"; +// std::cout<< "aaj=" << j << "\n"; +// std::cout<< "lo=" << lo << "\n"; +// std::cout<< "hi=" << hi << "\n"; + // Recursion + if (lo<j) quicksort(a, p, lo, j); + if (i<hi) quicksort(a, p, i, hi); + + + +} + +template <typename Vector, typename PermVec> +void quicksort (Vector& a, Vector& b, PermVec& p, typename Collection<Vector>::size_type lo, typename Collection<Vector>::size_type hi) +{ + using vec::swap_row; + typename Collection<Vector>::size_type i= lo, j= hi; + + // VergleichsÂÂelement x + typename mtl::Collection<Vector>::value_type x= a[(lo+hi)/2]; +// std::cout<< "x=" << x << "\n"; + // Aufteilung + while (i<=j) + { + while (a[i]<x) i++; + while (a[j]>x) j--; + + if (i<=j) + { + swap_row(a, i, j); + swap_row(b, i, j); + swap_row(p, i, j); + i++; + if( j == 0){ + break; + } else { + j--; + } + } + } + // Recursion + if (lo<j) quicksort(a, b, p, lo, j); + if (i<hi) quicksort(a, b, p, i, hi); +} + +template <typename Vector, typename PermVec> +void quicksort_xy(Vector& a, Vector& b, PermVec& p, typename Collection<Vector>::size_type lo, + typename Collection<Vector>::size_type hi) +{ + using vec::swap_row; + typename Collection<Vector>::size_type i= lo, j= hi; + // pivot element (x, y) + typename mtl::Collection<Vector>::value_type x= a[(lo+hi)/2], y= b[(lo+hi)/2]; + + while (i<=j) { + while (a[i] < x || (a[i] == x && b[i] < y)) i++; + while (a[j] > x || (a[j] == x && b[j] > y)) j--; + + if (i <= j) { + swap_row(a, i, j); + swap_row(b, i, j); + swap_row(p, i, j); + i++; + if (j == 0) + break; + else + j--; + } + } + // Recursion + if (lo < j) quicksort_xy(a, b, p, lo, j); + if (i < hi) quicksort_xy(a, b, p, i, hi); +} + + + +/// sort vector with permutation +template <typename Vector, typename PermVec> +void inline sort(Vector& x, PermVec& p) +{ +// std::cout<< "x=" << x << "\n"; +// std::cout<< "p=" << p << "\n"; + using mtl::size; + assert(size(x) == size(p)); + quicksort(x, p, 0, size(x)-1); + +} + +/// Sort 2 vectors with permutation +template <typename Vector, typename PermVec> +void inline sort(Vector& x, Vector& y, PermVec& p) +{ +// std::cout<< "x=" << x << "\n"; +// std::cout<< "p=" << p << "\n"; + using mtl::size; + assert(size(x) == size(p)); + assert(size(x) == size(y)); + quicksort(x, y, p, 0, size(x)-1); +} + +/// Sort 3 vectors lexicographically after values in x and y +template <typename Vector, typename PermVec> +void inline sort_xy(Vector& x, Vector& y, PermVec& z) +{ + using mtl::size; + assert(size(x) == size(z)); + assert(size(x) == size(y)); + quicksort_xy(x, y, z, 0, size(x)-1); +} + + + +}} // namespace mtl::vector + +#endif // MTL_SORT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/split_complex_matrix.hpp b/install/MTL/include/boost/numeric/mtl/operation/split_complex_matrix.hpp new file mode 100644 index 00000000..ca6c2f6d --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/split_complex_matrix.hpp @@ -0,0 +1,40 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_SPLIT_COMPLEX_MATRIX_INCLUDE +#define MTL_MATRIX_SPLIT_COMPLEX_MATRIX_INCLUDE + +#if 0 // Do we really need this??? + +namespace mtl { namespace matrix { + +// Split one complex-valued matrix into two real-valued matrices. +/* Elements of the real matrix must be assignable from the real and imaginary part of the complex elements. + Real matrices are resized if their size is 0 otherwise the matrices must have + the same dimension. **/ +template <typename MatrixComplex, typename MatrixReal, typename MatrixImaginary> +inline void split_complex_matrix(const MatrixComplex& c, MatrixReal& r, MatrixImaginary& i) +{ + r.checked_change_dim(num_rows(c), num_cols(c)); + i.checked_change_dim(num_rows(c), num_cols(c)); + + c= + + +} + + +}} // namespace mtl::matrix + +#endif + +#endif // MTL_MATRIX_SPLIT_COMPLEX_MATRIX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/split_complex_vector.hpp b/install/MTL/include/boost/numeric/mtl/operation/split_complex_vector.hpp new file mode 100644 index 00000000..7f04fd71 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/split_complex_vector.hpp @@ -0,0 +1,46 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_SPLIT_COMPLEX_VECTOR_INCLUDE +#define MTL_VECTOR_SPLIT_COMPLEX_VECTOR_INCLUDE + +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/size.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace vec { + +/// Split one complex-valued vector into two real-valued vectors. +/** Elements of the real vector must be assignable from the real and imaginary part of the complex elements. + Real vectors are resized if their size is 0 otherwise the vectors must have + the same length. **/ +template <typename VectorComplex, typename VectorReal, typename VectorImaginary> +inline void split_complex_vector(const VectorComplex& c, VectorReal& r, VectorImaginary& i) +{ + using mtl::size; + using mtl::real; + using mtl::imag; + + vampir_trace<2034> tracer; + r.checked_change_dim(size(c)); + i.checked_change_dim(size(c)); + + for (std::size_t j= 0; j < size(c); ++j) + r[j]= real(c[j]), + i[j]= imag(c[j]); +} + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_SPLIT_COMPLEX_VECTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/squared_abs.hpp b/install/MTL/include/boost/numeric/mtl/operation/squared_abs.hpp new file mode 100644 index 00000000..64f0e66b --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/squared_abs.hpp @@ -0,0 +1,59 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SQUARED_ABS_INCLUDE +#define MTL_SQUARED_ABS_INCLUDE + +#include <cmath> +#include <complex> +#include <boost/mpl/or.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_floating_point.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + +/// When squaring magnitudes of intrinsic types the abs can be omitted +template <typename T> +typename boost::enable_if<boost::mpl::or_<boost::is_integral<T>, boost::is_floating_point<T> >, T>::type +inline squared_abs(const T& x) +{ + vampir_trace<10> tracer; + return x * x; +} + +/// Squaring complex numbers can be computed without square root +template <typename T> +T inline squared_abs(const std::complex<T>& z) +{ + vampir_trace<11> tracer; + using std::norm; + return norm(z); +} + +/// When squaring magnitudes of non-intrinsic and non-complex types we use abs for security +template <typename T> +typename boost::disable_if<boost::mpl::or_<boost::is_integral<T>, boost::is_floating_point<T> >, T>::type +inline squared_abs(const T& x) +{ + vampir_trace<12> tracer; + using std::abs; + T a= abs(x); + return a * a; +} + + +} // namespace mtl + +#endif // MTL_SQUARED_ABS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/static_num_cols.hpp b/install/MTL/include/boost/numeric/mtl/operation/static_num_cols.hpp new file mode 100644 index 00000000..c601779e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/static_num_cols.hpp @@ -0,0 +1,89 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_STATIC_NUM_COLS_INCLUDE +#define MTL_STATIC_NUM_COLS_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/matrix/dimension.hpp> +#include <boost/numeric/mtl/vector/dimension.hpp> + +namespace mtl { + +/// Number of columns given at compile time +/** General declaration, used to disable unsupported types **/ +template <typename Collection> +struct static_num_cols { + // typedef xxx type; + // static const type value= yyy; +}; + + +/// static_num_cols implementation for (1D) arrays interpreted as vectors +template <typename Value, unsigned Size> +struct static_num_cols<Value[Size]> +{ + typedef std::size_t type; + static const type value= 1; +}; + +/// static_num_cols implementation for (2D and higher) arrays interpreted as matrices +template <typename Value, unsigned Rows, unsigned Cols> +struct static_num_cols<Value[Rows][Cols]> +{ + typedef std::size_t type; + static const type value= Cols; +}; + + +template <std::size_t Size> +struct static_num_cols< vec::fixed::dimension<Size> > +{ + typedef std::size_t type; + static const type value= Size; +}; + +template <typename V, typename P> +struct static_num_cols<mtl::vec::dense_vector<V, P> > +{ + typedef std::size_t type; + static const type value= traits::is_row_major<P>::value ? static_num_cols<typename P::dimension>::value : 1; +}; + + +template <std::size_t Rows, std::size_t Cols> +struct static_num_cols< fixed::dimensions<Rows, Cols> > +{ + typedef std::size_t type; + static const type value= Cols; +}; + +template <typename V, typename P> +struct static_num_cols<mtl::mat::dense2D<V, P> > + : static_num_cols<typename P::dimensions> +{}; + +template <typename V, std::size_t M, typename P> +struct static_num_cols<mtl::mat::morton_dense<V, M, P> > + : static_num_cols<typename P::dimensions> +{}; + +template <typename V, typename P> +struct static_num_cols<mtl::mat::compressed2D<V, P> > + : static_num_cols<typename P::dimensions> +{}; + +} // namespace mtl + +#endif // MTL_STATIC_NUM_COLS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/static_num_rows.hpp b/install/MTL/include/boost/numeric/mtl/operation/static_num_rows.hpp new file mode 100644 index 00000000..ab7660e1 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/static_num_rows.hpp @@ -0,0 +1,89 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_STATIC_NUM_ROWS_INCLUDE +#define MTL_STATIC_NUM_ROWS_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/matrix/dimension.hpp> +#include <boost/numeric/mtl/vector/dimension.hpp> + +namespace mtl { + +/// Number of rows given at compile time +/** General declaration, used to disable unsupported types **/ +template <typename Collection> +struct static_num_rows { + // typedef xxx type; + // static const type value= yyy; +}; + + +/// static_num_rows implementation for (1D) arrays interpreted as vectors +template <typename Value, unsigned Size> +struct static_num_rows<Value[Size]> +{ + typedef std::size_t type; + static const type value= Size; +}; + +/// static_num_rows implementation for (2D and higher) arrays interpreted as matrices +template <typename Value, unsigned Rows, unsigned Cols> +struct static_num_rows<Value[Rows][Cols]> +{ + typedef std::size_t type; + static const type value= Rows; +}; + + +template <std::size_t Size> +struct static_num_rows< vec::fixed::dimension<Size> > +{ + typedef std::size_t type; + static const type value= Size; +}; + +template <typename V, typename P> +struct static_num_rows<mtl::vec::dense_vector<V, P> > +{ + typedef std::size_t type; + static const type value= traits::is_row_major<P>::value ? 1 : static_num_rows<typename P::dimension>::value; +}; + + +template <std::size_t Rows, std::size_t Cols> +struct static_num_rows< fixed::dimensions<Rows, Cols> > +{ + typedef std::size_t type; + static const type value= Rows; +}; + +template <typename V, typename P> +struct static_num_rows<mtl::mat::dense2D<V, P> > + : static_num_rows<typename P::dimensions> +{}; + +template <typename V, std::size_t M, typename P> +struct static_num_rows<mtl::mat::morton_dense<V, M, P> > + : static_num_rows<typename P::dimensions> +{}; + +template <typename V, typename P> +struct static_num_rows<mtl::mat::compressed2D<V, P> > + : static_num_rows<typename P::dimensions> +{}; + +} // namespace mtl + +#endif // MTL_STATIC_NUM_ROWS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/static_size.hpp b/install/MTL/include/boost/numeric/mtl/operation/static_size.hpp new file mode 100644 index 00000000..baf186c4 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/static_size.hpp @@ -0,0 +1,33 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_STATIC_SIZE_INCLUDE +#define MTL_STATIC_SIZE_INCLUDE + +#include <boost/numeric/mtl/operation/static_num_rows.hpp> +#include <boost/numeric/mtl/operation/static_num_cols.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { + +/// Number of rows times columns given at compile time +/** General declaration, relies on static_num_rows and static_num_cols. **/ +template <typename Collection> +struct static_size { + vampir_trace<1007> tracer; + typedef typename static_num_rows<Collection>::type type; // Might not always work + static const type value= static_num_rows<Collection>::value * static_num_cols<Collection>::value; +}; + +} // namespace mtl + +#endif // MTL_STATIC_SIZE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/std_output_operator.hpp b/install/MTL/include/boost/numeric/mtl/operation/std_output_operator.hpp new file mode 100644 index 00000000..ad9fb6e9 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/std_output_operator.hpp @@ -0,0 +1,64 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_STD_OUTPUT_OPERATOR_INCLUDE +#define MTL_STD_OUTPUT_OPERATOR_INCLUDE + +#ifdef MTL_HAS_STD_OUTPUT_OPERATOR + +#include <iostream> +#include <map> +#include <utility> +#include <vector> + +namespace std { + + /// Print standard vector + /** Only available when compiled with macro flag MTL_HAS_STD_OUTPUT_OPERATOR + to avoid (reduce) conflicts with other libraries. **/ + template <typename T, typename Alloc> + inline ostream& operator<< (ostream& os, vector<T, Alloc> const& v) + { + os << '['; + for (size_t r = 0; r < v.size(); ++r) + os << v[r] << (r < v.size() - 1 ? "," : ""); + return os << ']'; + } + + /// Print standard map + /** Only available when compiled with macro flag MTL_HAS_STD_OUTPUT_OPERATOR + to avoid (reduce) conflicts with other libraries. **/ + template <typename Key, typename Data, typename Compare, typename Alloc> + inline ostream& operator<< (ostream& os, map<Key, Data, Compare, Alloc> const& m) + { + if (m.empty()) return os << "{}"; + typedef typename map<Key, Data, Compare, Alloc>::const_iterator iter_type; + os << '{'; + for (iter_type it= m.begin(), end= m.end(); it != end; ++it) + os << it->first << ": " << it->second << ", "; + return os << "\b\b} "; + } + + /// Print standard pair + /** Only available when compiled with macro flag MTL_HAS_STD_OUTPUT_OPERATOR + to avoid (reduce) conflicts with other libraries. **/ + template <typename T, typename U> + inline ostream& operator<< (ostream& os, pair<T, U> const& p) + { + return os << '(' << p.first << ',' << p.second << ')'; + } + +} // namespace std + +#endif // MTL_HAS_STD_OUTPUT_OPERATOR + +#endif // MTL_STD_OUTPUT_OPERATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/sub_matrix.hpp b/install/MTL/include/boost/numeric/mtl/operation/sub_matrix.hpp new file mode 100644 index 00000000..3ab793bc --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/sub_matrix.hpp @@ -0,0 +1,83 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SUBMATRIX_INCLUDE +#define MTL_SUBMATRIX_INCLUDE + +#include <cmath> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/operation/is_negative.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace mat { + +// Functor type as background for free submatrix function +template <typename Matrix> +struct sub_matrix_t +{ + // typedef *user_defined* sub_matrix_type; + // typedef *user_defined* const_sub_matrix_type; + // typedef *user_defined* size_type; + // sub_matrix_type operator()(Matrix&, size_type, size_type, size_type, size_type); + // const_sub_matrix_type operator()(Matrix const&, size_type, size_type, size_type, size_type); +}; + + namespace impl { + + template <typename Matrix> + inline void correct_sub_matrix_indices(Matrix const& matrix, + typename sub_matrix_t<Matrix>::size_type& begin_row, + typename sub_matrix_t<Matrix>::size_type& end_row, + typename sub_matrix_t<Matrix>::size_type& begin_col, + typename sub_matrix_t<Matrix>::size_type& end_col) + { + vampir_trace<3036> tracer; + using std::min; + MTL_DEBUG_THROW_IF( is_negative(begin_row) || is_negative(end_row), index_out_of_range()); + end_row= min(end_row, num_rows(matrix)); + begin_row= min(begin_row, end_row); // implies min(begin_row, num_rows(matrix)) + + MTL_DEBUG_THROW_IF( is_negative(begin_col) || is_negative(end_col), index_out_of_range()); + end_col= min(end_col, num_cols(matrix)); + begin_col= min(begin_col, end_col); // implies likewise + } + + } // namespace impl + +///Returns sub-matrix B with begin_row, end_row, begin_col, end_col from %matrix A +template <typename Matrix> +inline typename sub_matrix_t<Matrix>::sub_matrix_type +sub_matrix(Matrix& matrix, + typename sub_matrix_t<Matrix>::size_type begin_row, + typename sub_matrix_t<Matrix>::size_type end_row, + typename sub_matrix_t<Matrix>::size_type begin_col, + typename sub_matrix_t<Matrix>::size_type end_col) +{ + impl::correct_sub_matrix_indices(matrix, begin_row, end_row, begin_col, end_col); + return sub_matrix_t<Matrix>()(matrix, begin_row, end_row, begin_col, end_col); +} + +template <typename Matrix> +inline typename sub_matrix_t<Matrix>::const_sub_matrix_type +sub_matrix(Matrix const& matrix, + typename sub_matrix_t<Matrix>::size_type begin_row, + typename sub_matrix_t<Matrix>::size_type end_row, + typename sub_matrix_t<Matrix>::size_type begin_col, + typename sub_matrix_t<Matrix>::size_type end_col) +{ + impl::correct_sub_matrix_indices(matrix, begin_row, end_row, begin_col, end_col); + return sub_matrix_t<Matrix>()(matrix, begin_row, end_row, begin_col, end_col); +} + +}} // namespace mtl::matrix + +#endif // MTL_SUBMATRIX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/sum.hpp b/install/MTL/include/boost/numeric/mtl/operation/sum.hpp new file mode 100644 index 00000000..2cc4c47a --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/sum.hpp @@ -0,0 +1,70 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SUM_INCLUDE +#define MTL_SUM_INCLUDE + +#include <iostream> +#include <cmath> + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/vector/lazy_reduction.hpp> +#include <boost/numeric/mtl/vector/reduction.hpp> +#include <boost/numeric/mtl/vector/reduction_functors.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + + namespace impl { + + // Do we really need this for matrices? + + template <unsigned long Unroll, typename Vector> + typename Collection<Vector>::value_type + inline sum(const Vector& vector, tag::vector) + { + vampir_trace<2035> tracer; + typedef typename Collection<Vector>::value_type result_type; + return vec::reduction<Unroll, vec::sum_functor, result_type>::apply(vector); + } + + } // namespace impl + +///Return sum of all %vector-entries +template <unsigned long Unroll, typename Value> +typename Collection<Value>::value_type +inline sum(const Value& value) +{ + return impl::sum<Unroll>(value, typename traits::category<Value>::type()); +} + +template <typename Value> +typename Collection<Value>::value_type +inline sum(const Value& value) +{ + return sum<8>(value); +} + +namespace vec { + template <typename Vector> + lazy_reduction<Vector, sum_functor> inline lazy_sum(const Vector& v) + { return lazy_reduction<Vector, sum_functor>(v); } +} + +using vec::lazy_sum; + +} // namespace mtl + +#endif // MTL_SUM_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/svd.hpp b/install/MTL/include/boost/numeric/mtl/operation/svd.hpp new file mode 100644 index 00000000..9bbc9e99 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/svd.hpp @@ -0,0 +1,99 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// With contributions from Cornelius Steinhardt + +#ifndef MTL_MATRIX_SVD_INCLUDE +#define MTL_MATRIX_SVD_INCLUDE + +#include <cmath> +#include <limits> +#include <algorithm> +#include <boost/numeric/mtl/matrix/strict_upper.hpp> +#include <boost/numeric/mtl/operation/diagonal.hpp> +#include <boost/numeric/mtl/operation/one_norm.hpp> +#include <boost/numeric/mtl/operation/sub_matrix.hpp> +#include <boost/numeric/mtl/operation/trans.hpp> +#include <boost/numeric/mtl/operation/two_norm.hpp> +#include <boost/tuple/tuple.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace mat { + +/// Returns A=S*V*D' for matrix A as references +template <typename Matrix> +inline void svd(const Matrix& A, Matrix& S, Matrix& V, Matrix& D, double tol= 10e-10) +{ + vampir_trace<3037> tracer; + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + size_type ncols= num_cols(A), nrows= num_rows(A), loops, col= ncols, row= nrows; + value_type ref, zero= math::zero(ref), one= math::one(ref); + double err(std::numeric_limits<double>::max()), e, f; + + if (nrows != ncols) // important for right dimension + std::swap(row, col); + + //init + Matrix Q(row,row), R(row,col), VT(row,col), E(row,col), + QT(col,col), RT(col,row); + + loops= 100 * std::max(nrows,ncols); + S= one; D= one; E= zero; + for (size_type i= 0; err > tol && i < loops; ++i) { + boost::tie(QT, RT)= qr(V); + S*= QT; + VT= trans(RT); + boost::tie(Q, R)= qr(VT); + D*= Q; + E= triu(R,1); + V= trans(R); + + //ready for exit when upper(R)=0 + f= two_norm(diagonal(R)); + e= one_norm(E); + if ( f== zero ) f= 1; + err= e/f; + } //end for + + V= 0; + mtl::mat::inserter<Matrix> ins_V(V); + mtl::mat::inserter<Matrix, mtl::operations::update_times<value_type> > ins_S(S); + + for (size_type i= 0, end= std::min(nrows, ncols); i < end; i++) { + ins_V[i][i] << std::abs(R[i][i]); + if (R[i][i] < zero) + for (size_type j= 0; j < nrows; j++) + ins_S[j][i] << -1; //carefull changing: multiplication with minus one + } +} + +/// Returns A=S*V*D' for matrix A as triplet +template <typename Matrix> +boost::tuple<Matrix, Matrix, Matrix > +inline svd(const Matrix& A, double tol= 10e-10) +{ + vampir_trace<3038> tracer; + typedef typename Collection<Matrix>::size_type size_type; + size_type ncols= num_cols(A), nrows= num_rows(A), col= ncols, row= nrows; + if (nrows != ncols) // important for right dimension + std::swap(row, col); + + Matrix ST(col,col), V(A), D(row,row); + svd(A, ST, V, D, tol); + return boost::make_tuple(ST, V, D); +} + + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_SVD_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/swap_row.hpp b/install/MTL/include/boost/numeric/mtl/operation/swap_row.hpp new file mode 100644 index 00000000..8f369b95 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/swap_row.hpp @@ -0,0 +1,91 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_SWAP_ROW +#define MTL_MATRIX_SWAP_ROW + +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + +namespace mat { + + namespace detail { + + template <typename Matrix, typename Orientation> + inline void swap_row(Matrix& A, typename Collection<Matrix>::size_type i, + typename Collection<Matrix>::size_type j, tag::dense, Orientation) + { + // swap(A[irange(i,i+1)][iall], A[irange(j,j+1)][iall]; + using std::swap; + for (typename Collection<Matrix>::size_type k= 0; k < num_cols(A); k++) + swap(A[i][k], A[j][k]); + } + + template <typename Matrix> + inline void swap_row(Matrix&, typename Collection<Matrix>::size_type, + typename Collection<Matrix>::size_type, tag::sparse, boost::mpl::true_) + { + MTL_THROW(logic_error("This is not implemented yet.")); + } + + template <typename Matrix> + inline void swap_row(Matrix&, typename Collection<Matrix>::size_type, + typename Collection<Matrix>::size_type, tag::sparse, boost::mpl::false_) + { + MTL_THROW(logic_error("This is an ugly operation and not implemented yet.")); + } + + } + ///Row i and j are swapped in %matrix A + template <typename Matrix> + typename mtl::traits::enable_if_matrix<Matrix>::type + inline swap_row(Matrix& A, typename Collection<Matrix>::size_type i, + typename Collection<Matrix>::size_type j) + { + vampir_trace<3039> tracer; + if (i == j) return; + detail::swap_row(A, i, j, typename mtl::traits::category<Matrix>::type(), + mtl::traits::is_row_major<Matrix>()); + } + +} // namespace matrix + + +namespace vec { + ///Entry i and j are swapped in %vector v + template <typename Vector> + typename mtl::traits::enable_if_vector<Vector>::type + inline swap_row(Vector& v, typename Collection<Vector>::size_type i, + typename Collection<Vector>::size_type j) + { + vampir_trace<236> tracer; + using std::swap; + if (i == j) return; + swap(v[i], v[j]); + } + +} // vector + +using mat::swap_row; +using vec::swap_row; + +} // namespace mtl + +#endif // MTL_MATRIX_SWAP_ROW diff --git a/install/MTL/include/boost/numeric/mtl/operation/tfunctor.hpp b/install/MTL/include/boost/numeric/mtl/operation/tfunctor.hpp new file mode 100644 index 00000000..dcb3602c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/tfunctor.hpp @@ -0,0 +1,21 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TFUNCTOR_INCLUDE +#define MTL_TFUNCTOR_INCLUDE + +#include <boost/numeric/mtl/operation/scale.hpp> +#include <boost/numeric/mtl/operation/rscale.hpp> // added by Hui Li +#include <boost/numeric/mtl/operation/divide_by.hpp> // added by Hui Li +#include <boost/numeric/mtl/operation/tfunctor_mixed.hpp> + +#endif // MTL_TFUNCTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/tfunctor_mixed.hpp b/install/MTL/include/boost/numeric/mtl/operation/tfunctor_mixed.hpp new file mode 100644 index 00000000..7cf836f4 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/tfunctor_mixed.hpp @@ -0,0 +1,154 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TFUNCTOR_TFUNCTOR_MIXED_INCLUDE +#define MTL_TFUNCTOR_TFUNCTOR_MIXED_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/std_concept.hpp> + +namespace mtl { namespace tfunctor { + +// Currently we define only scalar concepts +// Eventually this will be expanded like "scale" + +/// Plus functor that stores left summand +template <typename Value1, typename Value2> +struct left_plus +{ + typedef typename Addable<Value1, Value2>::result_type result_type; + explicit left_plus(const Value1& v1) : v1(v1) {} + + result_type operator() (const Value2& v2) const + { + return v1 + v2; + } +private: + Value1 v1; +}; + +/// Plus functor that stores right summand +template <typename Value1, typename Value2> +struct right_plus +{ + typedef typename Addable<Value1, Value2>::result_type result_type; + explicit right_plus(const Value2& v2) : v2(v2) {} + + result_type operator() (const Value1& v1) const + { + return v1 + v2; + } +private: + Value2 v2; +}; + +/// Minus functor that stores left summand +template <typename Value1, typename Value2> +struct left_minus +{ + typedef typename Subtractable<Value1, Value2>::result_type result_type; + explicit left_minus(const Value1& v1) : v1(v1) {} + + result_type operator() (const Value2& v2) const + { + return v1 - v2; + } +private: + Value1 v1; +}; + +/// Minus functor that stores right summand +template <typename Value1, typename Value2> +struct right_minus +{ + typedef typename Subtractable<Value1, Value2>::result_type result_type; + explicit right_minus(const Value2& v2) : v2(v2) {} + + result_type operator() (const Value1& v1) const + { + return v1 - v2; + } +private: + Value2 v2; +}; + +/// Minimum functor that stores left operand +/** Result type is right operand. + This way the min of a scalar and a vector keeps the vector type. **/ +template <typename Value1, typename Value2> +struct left_min +{ + typedef Value2 result_type; + explicit left_min(const Value1& v1) : v1(v1) {} + + result_type operator() (const Value2& v2) const + { + return v1 < v2 ? Value2(v1) : v2; + } +private: + Value1 v1; +}; + +/// Minimum functor that stores right operand +/** Result type is left operand. + This way the min of a vector and a scalar keeps the vector type. **/ +template <typename Value1, typename Value2> +struct right_min +{ + typedef Value1 result_type; + explicit right_min(const Value2& v2) : v2(v2) {} + + result_type operator() (const Value1& v1) const + { + return v1 < v2 ? v1 : Value1(v2); + } +private: + Value2 v2; +}; + +/// Maximum functor that stores left operand +/** Result type is right operand. + This way the max of a scalar and a vector keeps the vector type. **/ +template <typename Value1, typename Value2> +struct left_max +{ + typedef Value2 result_type; + explicit left_max(const Value1& v1) : v1(v1) {} + + result_type operator() (const Value2& v2) const + { + return v1 < v2 ? v2 : Value2(v1); + } +private: + Value1 v1; +}; + +/// Maximum functor that stores right operand +/** Result type is left operand. + This way the max of a vector and a scalar keeps the vector type. **/ +template <typename Value1, typename Value2> +struct right_max +{ + typedef Value1 result_type; + explicit right_max(const Value2& v2) : v2(v2) {} + + result_type operator() (const Value1& v1) const + { + return v1 < v2 ? Value1(v2) : v1; + } +private: + Value2 v2; +}; + +}} // namespace mtl::tfunctor + +#endif // MTL_TFUNCTOR_TFUNCTOR_MIXED_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/trace.hpp b/install/MTL/include/boost/numeric/mtl/operation/trace.hpp new file mode 100644 index 00000000..bf0269f2 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/trace.hpp @@ -0,0 +1,50 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRACE_INCLUDE +#define MTL_TRACE_INCLUDE + +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace mat { + +template <typename Matrix> +typename Collection<Matrix>::value_type +inline trace(const Matrix& matrix) +{ + vampir_trace<3040> tracer; + using math::zero; + typedef typename Collection<Matrix>::value_type value_type; + + MTL_THROW_IF(num_rows(matrix) != num_cols(matrix), matrix_not_square()); + + // If matrix is empty then the result is the identity from the default-constructed value + if (num_rows(matrix) == 0) { + value_type ref; + return zero(ref); + } + + value_type value= matrix[0][0]; + for (unsigned i= 1; i < num_rows(matrix); i++) + value+= matrix[i][i]; + return value; +} + + +}} // namespace mtl::matrix + +#endif // MTL_TRACE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/trans.hpp b/install/MTL/include/boost/numeric/mtl/operation/trans.hpp new file mode 100644 index 00000000..e20e2c53 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/trans.hpp @@ -0,0 +1,124 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRANS_INCLUDE +#define MTL_TRANS_INCLUDE + +#include <boost/mpl/if.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/algebraic_category.hpp> +#include <boost/numeric/mtl/utility/transposed_orientation.hpp> +#include <boost/numeric/mtl/utility/view_code.hpp> +#include <boost/numeric/mtl/utility/viewed_collection.hpp> +#include <boost/numeric/mtl/utility/compose_view.hpp> +#include <boost/numeric/mtl/matrix/transposed_view.hpp> +#include <boost/numeric/mtl/matrix/view_ref.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { + +namespace mat { + + namespace detail { + + // General case is not defined + template <typename Value, typename AlgebraicCategory, unsigned IsConst> + struct trans {}; + + template <typename Matrix, unsigned IsConst> + struct trans<Matrix, tag::matrix, IsConst> + { + static const unsigned code= (mtl::traits::view_code<Matrix>::value | IsConst) ^ 4; + typedef typename mtl::traits::compose_view<code, typename mtl::traits::viewed_collection<Matrix>::type>::type result_type; + + typedef typename boost::mpl::if_c<(IsConst == 1), const Matrix&, Matrix&>::type ref_type; + + static inline result_type apply(ref_type matrix) + { + return result_type(view_ref(matrix)); + } + }; + + } // namespace detail + + + template <typename Value> + typename detail::trans<Value, typename mtl::traits::algebraic_category<Value>::type, 1>::result_type + inline trans(const Value& v) + { + vampir_trace<3041> tracer; + return detail::trans<Value, typename mtl::traits::algebraic_category<Value>::type, 1>::apply(v); + } + + template <typename Value> + typename detail::trans<Value, typename mtl::traits::algebraic_category<Value>::type, 0>::result_type + inline trans(Value& v) + { + vampir_trace<3042> tracer; + return detail::trans<Value, typename mtl::traits::algebraic_category<Value>::type, 0>::apply(v); + } + +} // namespace mtl::matrix + + +namespace vec { + + template <typename Vector> + struct transposed_vector {}; + + template <typename Parameters> + struct transposed_parameters + { + typedef typename mtl::traits::transposed_orientation<typename Parameters::orientation>::type orientation; // switch + typedef parameters<orientation, typename Parameters::dimension, false, typename Parameters::size_type> type; // not on stack!!! + }; + + template <typename Value, typename Parameters> + struct transposed_vector<dense_vector<Value, Parameters> > + { + typedef dense_vector<Value, typename transposed_parameters<Parameters>::type> type; + }; + + template <typename Value, typename Parameters> + struct transposed_vector<strided_vector_ref<Value, Parameters> > + { + typedef strided_vector_ref<Value, typename transposed_parameters<Parameters>::type> type; + }; + +///Returns tranposed view of %vector v + template <typename Vector> + typename transposed_vector<Vector>::type const + inline trans(const Vector& v) + { + vampir_trace<2037> tracer; + typedef typename transposed_vector<Vector>::type type; + return type(size(v), &const_cast<Vector&>(v)[0]); + } + + template <typename Vector> + typename transposed_vector<Vector>::type + inline trans(Vector& v) + { + vampir_trace<2038> tracer; + typedef typename transposed_vector<Vector>::type type; + return type(size(v), &v[0]); + } +} + +} // mtl + + +#endif // MTL_TRANS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/two_norm.hpp b/install/MTL/include/boost/numeric/mtl/operation/two_norm.hpp new file mode 100644 index 00000000..4f6bc6be --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/two_norm.hpp @@ -0,0 +1,73 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TWO_NORM_INCLUDE +#define MTL_TWO_NORM_INCLUDE + +#include <iostream> +#include <cmath> + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/concept/magnitude.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/vector/lazy_reduction.hpp> +#include <boost/numeric/mtl/vector/reduction.hpp> +#include <boost/numeric/mtl/vector/reduction_functors.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + + namespace vec { + + template <unsigned long Unroll, typename Value> + typename RealMagnitude<typename Collection<Value>::value_type>::type + inline two_norm(const Value& value) + { + using std::sqrt; + vampir_trace<2039> tracer; + typedef typename RealMagnitude<typename Collection<Value>::value_type>::type result_type; + return sqrt(reduction<Unroll, two_norm_functor, result_type>::apply(value)); + } + + + /*! Two-norm for vectors: two_norm(x) \f$\rightarrow |x|_2\f$. + \retval The magnitude type of the respective value type, see Magnitude. + The norms are defined as \f$|v|_2=\sqrt{\sum_i |v_i|^2}\f$. + + Vector norms are unrolled 8-fold by default. + An n-fold unrolling can be generated with two_norm<n>(x). + The maximum for n is 8 (it might be increased later). + **/ + template <typename Value> + typename RealMagnitude<typename Collection<Value>::value_type>::type + inline two_norm(const Value& value) + { + return two_norm<4>(value); + } + + template <typename Vector> + lazy_reduction<Vector, two_norm_functor> inline lazy_two_norm(const Vector& v) + { return lazy_reduction<Vector, two_norm_functor>(v); } + + + } // namespace vector + + // two_norm for matrices not implemented (would need enable_if like one_norm) + + using vec::two_norm; + using vec::lazy_two_norm; + +} // namespace mtl + +#endif // MTL_TWO_NORM_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/unary_dot.hpp b/install/MTL/include/boost/numeric/mtl/operation/unary_dot.hpp new file mode 100644 index 00000000..519e2a33 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/unary_dot.hpp @@ -0,0 +1,75 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_UNARY_DOT_INCLUDE +#define MTL_UNARY_DOT_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/vector/lazy_reduction.hpp> +#include <boost/numeric/mtl/vector/reduction.hpp> +#include <boost/numeric/mtl/vector/reduction_functors.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + + namespace vec { + + template <unsigned long Unroll, typename Value> + typename Collection<Value>::value_type + inline unary_dot(const Value& value) + { + vampir_trace<2041> tracer; + typedef typename Collection<Value>::value_type result_type; + return reduction<Unroll, two_norm_functor, result_type>::apply(value); + } + + /*! Dot product of a vector with itself, i.e. unary_dot(v) == dot(v, v). + + Mathematically, it is also identical with the square of the two_norm. + However, unary_dot returns the value_type of v while two_norm yields the + RealMagnitude type, thus + \code + two_norm(v) * two_norm(v) == abs(unary_dot(v)) + \endcode + Internally, the computations are performed in RealMagnitude so that + unary_dot(v) is more efficient than dot(v, v) for complex vectors. + Furthermore, when the dot product is fused with other expressions, + the arguments in dot must be different for the correct semantics of + certain fusions. + + Like vector norms, unary_dot is unrolled 8-fold by default. + An n-fold unrolling can be generated with two_norm<n>(x). + The maximum for n is 8 (it might be increased later). + **/ + template <typename Value> + typename Collection<Value>::value_type + inline unary_dot(const Value& value) + { return unary_dot<8>(value); } + + /// Lazy unary dot product + /** Used for source-to-source transformations. **/ + template <typename Vector> + lazy_reduction<Vector, unary_dot_functor> inline lazy_unary_dot(const Vector& v) + { return lazy_reduction<Vector, unary_dot_functor>(v); } + + + } // namespace vector + + using vec::unary_dot; + using vec::lazy_unary_dot; + +} // namespace mtl + +#endif // MTL_UNARY_DOT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/unroll.hpp b/install/MTL/include/boost/numeric/mtl/operation/unroll.hpp new file mode 100644 index 00000000..a33425fe --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/unroll.hpp @@ -0,0 +1,44 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_UNROLL_INCLUDE +#define MTL_UNROLL_INCLUDE + +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/vector/unrolled1.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { + +/// Helper function for customizing loop unrolling in expressions +/** For instance, + \code + unroll<6>(u)= v + 3. * w; + \endcode + will unroll the loop that computes + \code + u= v + 3. * w; + \endcode + with block size 6. +**/ +template <unsigned BSize, typename Coll> +typename mtl::traits::enable_if_vector<Coll, vec::unrolled1<BSize, Coll> >::type +inline unroll(Coll& v) +{ + vampir_trace<7> tracer; + return vec::unrolled1<BSize, Coll>(v); +} + +} // namespace mtl + +#endif // MTL_UNROLL_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/update.hpp b/install/MTL/include/boost/numeric/mtl/operation/update.hpp new file mode 100644 index 00000000..e37e1f8d --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/update.hpp @@ -0,0 +1,289 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_UPDATE_INCLUDE +#define MTL_UPDATE_INCLUDE + +#include <boost/numeric/mtl/operation/assign_mode.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace operations { + +template <typename Element> +struct update_store +{ + template <typename Value> + Element& operator() (Element& x, Value const& y) + { + vampir_trace<13> tracer; + return x= y; + } + + // How to fill empty entries; typically directly with /p y + template <typename Value> + Element init(Value const& y) + { + return y; + } +}; + +template <typename Element> +struct update_plus +{ + template <typename Value> + Element& operator() (Element& x, Value const& y) + { + vampir_trace<14> tracer; + return x+= y; + } + + // How to fill empty entries; typically directly with /p y + template <typename Value> + Element init(Value const& y) + { + return y; + } +}; + +template <typename Element> +struct update_minus +{ + template <typename Value> + Element& operator() (Element& x, Value const& y) + { + vampir_trace<15> tracer; + return x-= y; + } + + // How to fill empty entries. Here the inverse of /p y is needed!!! + template <typename Value> + Element init(Value const& y) + { + return -y; + } +}; + +template <typename Element> +struct update_times +{ + template <typename Value> + Element& operator() (Element& x, Value const& y) + { + vampir_trace<16> tracer; + return x*= y; + } + + // How to fill empty entries; typically directly with /p y + template <typename Value> + Element init(Value const& y) + { + return y; + } +}; + +template <typename Element, typename MonoidOp> +struct update_adapter +{ + template <typename Value> + Element& operator() (Element& x, Value const& y) + { + vampir_trace<17> tracer; + return x= MonoidOp()(x, y); + } + + // How to fill empty entries + template <typename Value> + Element init(Value const& y) + { + return y; + } +}; + + +template <typename Inserter, typename SizeType = std::size_t> +struct update_proxy +{ + typedef update_proxy self; + typedef typename Inserter::value_type value_type; + + explicit update_proxy(Inserter& ins, SizeType row, SizeType col) + : ins(ins), row(row), col(col) {} + + template <typename Value> + self& operator<< (Value const& val) + { + vampir_trace<20> tracer; + return lshift(val, typename ashape::ashape<Value>::type()); + } + + template <typename Value> + self& operator= (Value const& val) + { + vampir_trace<21> tracer; + ins.template modify<update_store<value_type> > (row, col, val); + return *this; + } + + template <typename Value> + self& operator+= (Value const& val) + { + vampir_trace<22> tracer; + ins.template modify<update_plus<value_type> > (row, col, val); + return *this; + } + + private: + + typedef typename Inserter::matrix_type matrix_type; + typedef typename mtl::ashape::ashape<matrix_type>::type matrix_shape; + typedef typename mtl::ashape::ashape<typename matrix_type::value_type>::type value_shape; + + + // Update scalar value as before + template <typename Value> + self& lshift (Value const& val, value_shape) + { + ins.update (row, col, val); + return *this; + } + + // Update an entire matrix considered as block + template <typename MatrixSrc> + self& lshift (const MatrixSrc& src, matrix_shape) + { + namespace traits = mtl::traits; + typename traits::row<MatrixSrc>::type row(src); + typename traits::col<MatrixSrc>::type col(src); + typename traits::const_value<MatrixSrc>::type value(src); + + typedef typename traits::range_generator<tag::major, MatrixSrc>::type cursor_type; + typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type; + + for (cursor_type cursor = begin<tag::major>(src), cend = end<tag::major>(src); cursor != cend; ++cursor) + for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) + ins.update(row(*icursor) + this->row, col(*icursor) + this->col, value(*icursor)); + return *this; + } + + Inserter& ins; + SizeType row, col; +}; + +/// Compute updater that corresponds to assign_mode +template <typename Assign, typename Value> +struct update_assign_mode {}; + +template <typename Value> +struct update_assign_mode<assign::assign_sum, Value> +{ + typedef update_plus<Value> type; +}; + +template <typename Value> +struct update_assign_mode<assign::plus_sum, Value> +{ + typedef update_plus<Value> type; +}; + +template <typename Value> +struct update_assign_mode<assign::minus_sum, Value> +{ + typedef update_minus<Value> type; +}; + +} // namespace operations + +using operations::update_store; +using operations::update_plus; +using operations::update_minus; +using operations::update_times; + +} // namespace mtl + + + + + + + + + + + + + + + + + + + + +#if 0 +// inconsistent with linear_algebra/identity.hpp + +namespace math { + +// temporary hack, must go to a proper place +template <typename Element, typename MonoidOp> +struct identity {}; + +#if 0 +template <typename Element, typename MonoidOp> +struct identity< Element, mtl::operations::update_adapter< Element, MonoidOp > > + : struct identity< Element, MonoidOp > +{}; +#endif + + +template < class T > +struct identity< T, mtl::operations::update_store<T> > +{ + static const T value = 0 ; + T operator()() const { return value ; } +} ; + +template < class T > +const T identity< T, mtl::operations::update_store< T > >::value ; + + + +template < class T > +struct identity< T, mtl::operations::update_plus<T> > +{ + static const T value = 0 ; + T operator()() const { return value ; } +} ; + +template < class T > +const T identity< T, mtl::operations::update_plus< T > >::value ; + + + +template < class T > +struct identity< T, mtl::operations::update_mult<T> > +{ + static const T value = 1 ; + T operator()() const { return value ; } +} ; + +template < class T > +const T identity< T, mtl::operations::update_mult< T > >::value ; + +} +#endif + +#endif // MTL_UPDATE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operation/upper_trisolve.hpp b/install/MTL/include/boost/numeric/mtl/operation/upper_trisolve.hpp new file mode 100644 index 00000000..44b2f26d --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operation/upper_trisolve.hpp @@ -0,0 +1,281 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_UPPER_TRISOLVE_INCLUDE +#define MTL_UPPER_TRISOLVE_INCLUDE + +#include <boost/mpl/int.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace mat { + + +namespace detail { + + /// Class that implements upper trisolver + /** DiaTag can be tag::regular_diagonal, tag::unit_diagonal, or tag::inverse_diagonal. + CompactStorage means that matrix contains only upper entries (strict upper when DiaTag == unit_diagonal). \sa \ref trisolve_object **/ + template <typename Matrix, typename DiaTag, bool CompactStorage= false> + struct upper_trisolve_t + { + MTL_STATIC_ASSERT((boost::is_same<DiaTag, tag::regular_diagonal>::value + || boost::is_same<DiaTag, tag::unit_diagonal>::value + || boost::is_same<DiaTag, tag::inverse_diagonal>::value), + "DiaTag must be either tag::regular_diagonal, tag::unit_diagonal, or tag::inverse_diagonal."); + + typedef typename Collection<Matrix>::value_type value_type; + typedef typename Collection<Matrix>::size_type size_type; + typedef typename OrientedCollection<Matrix>::orientation my_orientation; + typedef typename mtl::traits::category<Matrix>::type my_category; + typedef typename mtl::traits::range_generator<tag::major, Matrix>::type a_cur_type; // row or col accordingly + typedef typename mtl::traits::range_generator<tag::nz, a_cur_type>::type a_icur_type; + + /// Construction from matrix \p A + upper_trisolve_t(const Matrix& A) : A(A), value_a(A), col_a(A), row_a(A) + { MTL_THROW_IF(num_rows(A) != num_cols(A), matrix_not_square()); } + + template <typename M, typename D, bool C> + struct generic_version + : boost::mpl::int_<mtl::traits::is_row_major<M>::value ? 1 : 2> {}; + + template <typename M, typename D, bool C> + struct version + : generic_version<M, D, C> {}; + + template <typename Value, typename Para, typename D> + struct version<compressed2D<Value, Para>, D, true> + : boost::mpl::if_<mtl::traits::is_row_major<Para>, + boost::mpl::int_<3>, + generic_version<compressed2D<Value, Para>, D, true> + >::type {}; + + /// Solve \p w = A * \p v + template <typename VectorIn, typename VectorOut> + void operator()(const VectorIn& v, VectorOut& w) const + { + apply(v, w, version<Matrix, DiaTag, CompactStorage>()); + } + + /// Solves the upper triangular matrix A with the rhs v returns the solution + template <typename Vector> + Vector operator()(const Vector& v) const + { + Vector w(resource(v)); + (*this)(v, w); + return w; + } + + private: + // Initialization for regular and inverse diagonal is the same + template <typename Cursor, typename Value> + void row_init(size_type MTL_DEBUG_ARG(r), Cursor& aic, Cursor& MTL_DEBUG_ARG(aiend), Value& dia, tag::universe_diagonal) const + { + MTL_DEBUG_THROW_IF(aic == aiend || col_a(*aic) != r, missing_diagonal()); + dia= value_a(*aic); ++aic; + } + + template <typename Cursor, typename Value> + void row_init(size_type, Cursor&, Cursor&, Value&, tag::unit_diagonal) const {} + + template <typename Value> void row_update(Value& res, Value& rr, const Value& dia, tag::regular_diagonal) const { res= rr / dia; } + template <typename Value> void row_update(Value& res, Value& rr, const Value& dia, tag::inverse_diagonal) const { res= rr * dia; } + template <typename Value> void row_update(Value& res, Value& rr, const Value& , tag::unit_diagonal) const { res= rr; } + + template <typename Tag> int dia_inc(Tag) const { return 0; } + int dia_inc(tag::unit_diagonal) const { return 1; } + + // Generic row-major + template <typename VectorIn, typename VectorOut> + void inline apply(const VectorIn& v, VectorOut& w, boost::mpl::int_<1>) const + { + // vampir_trace<5042> tracer; + using namespace tag; + typedef typename mtl::Collection<VectorOut>::value_type out_value_type; + a_cur_type ac= begin<row>(A), aend= end<row>(A); + for (size_type r= num_rows(A) - 1; ac != aend--; --r) { + a_icur_type aic= CompactStorage ? begin<nz>(aend) : lower_bound<nz>(aend, r + dia_inc(DiaTag())), + aiend= end<nz>(aend); + out_value_type rr= v[r], dia; + row_init(r, aic, aiend, dia, DiaTag()); + for (; aic != aiend; ++aic) { + MTL_DEBUG_THROW_IF(col_a(*aic) <= r, logic_error("Matrix entries must be sorted for this.")); + rr-= value_a(*aic) * w[col_a(*aic)]; + } + row_update(w[r], rr, dia, DiaTag()); + } + } + + // Generic column-major + template <typename VectorIn, typename VectorOut> + void apply(const VectorIn& v, VectorOut& w, boost::mpl::int_<2>) const + { + // vampir_trace<5043> tracer; + using namespace tag; + typedef typename mtl::Collection<VectorOut>::value_type out_value_type; + w= v; + a_cur_type ac= begin<col>(A), aend= end<col>(A); + for (size_type r= num_rows(A) - 1; ac != aend--; --r) { + a_icur_type aic= begin<nz>(aend), + aiend= CompactStorage ? end<nz>(aend) : lower_bound<nz>(aend, r + 1 - dia_inc(DiaTag())); + out_value_type rr; + col_init(r, aic, aiend, rr, w[r], DiaTag()); + + for (; aic != aiend; ++aic) { + MTL_DEBUG_THROW_IF(row_a(*aic) >= r, logic_error("Matrix entries must be sorted for this.")); + w[row_a(*aic)]-= value_a(*aic) * rr; + } + } + } + + template <typename Value> + void crs_row_init(size_type MTL_DEBUG_ARG(r), size_type& j0, size_type MTL_DEBUG_ARG(cj1), Value& dia, tag::universe_diagonal) const + { + MTL_DEBUG_THROW_IF(j0 == cj1 || A.ref_minor()[j0] != r, missing_diagonal()); + dia= A.data[j0++]; + } + template <typename Value> void crs_row_init(size_type, size_type&, size_type, Value&, tag::unit_diagonal) const {} + + // Tuning for IC_0 and similar using compressed2D row-major compact + template <typename VectorIn, typename VectorOut> + void apply(const VectorIn& v, VectorOut& w, boost::mpl::int_<3>) const + { + // vampir_trace<5046> tracer; + typedef typename mtl::Collection<VectorOut>::value_type out_value_type; + for (size_type r= num_rows(A); r-- > 0; ) { + size_type j0= A.ref_major()[r]; + const size_type cj1= A.ref_major()[r+1]; + out_value_type rr= v[r], dia; + crs_row_init(r, j0, cj1, dia, DiaTag()); + for (; j0 != cj1; ++j0) { + MTL_DEBUG_THROW_IF(A.ref_minor()[j0] <= r, logic_error("Matrix entries must be sorted for this.")); + rr-= A.data[j0] * w[A.ref_minor()[j0]]; + } + row_update(w[r], rr, dia, DiaTag()); + } + } + + template <typename Cursor, typename Value> + void col_init(size_type MTL_DEBUG_ARG(r), Cursor& MTL_DEBUG_ARG(aic), Cursor& aiend, Value& rr, Value& res, tag::regular_diagonal) const + { + MTL_DEBUG_THROW_IF(aic == aiend, missing_diagonal()); + --aiend; + MTL_DEBUG_THROW_IF(row_a(*aiend) != r, missing_diagonal()); + rr= res/= value_a(*aiend); + } + + template <typename Cursor, typename Value> + void col_init(size_type MTL_DEBUG_ARG(r), Cursor& MTL_DEBUG_ARG(aic), Cursor& aiend, Value& rr, Value& res, tag::inverse_diagonal) const + { + MTL_DEBUG_THROW_IF(aic == aiend, missing_diagonal()); + --aiend; + MTL_DEBUG_THROW_IF(row_a(*aiend) != r, missing_diagonal()); + rr= res*= value_a(*aiend); + } + + template <typename Cursor, typename Value> + void col_init(size_type, Cursor&, Cursor&, Value& rr, Value& res, tag::unit_diagonal) const + { + rr= res; + } + + + const Matrix& A; + typename mtl::traits::const_value<Matrix>::type value_a; + typename mtl::traits::col<Matrix>::type col_a; + typename mtl::traits::row<Matrix>::type row_a; + }; + +} + +/// Solves the upper triangular matrix A with the rhs v and returns the solution vector +template <typename Matrix, typename Vector> +Vector inline upper_trisolve(const Matrix& A, const Vector& v) +{ + // vampir_trace<3043> tracer; + return detail::upper_trisolve_t<Matrix, tag::regular_diagonal>(A)(v); +} + +/// Solves the upper triangular matrix A with the rhs v while solution vector w is passed as reference +template <typename Matrix, typename VectorIn, typename VectorOut> +void inline upper_trisolve(const Matrix& A, const VectorIn& v, VectorOut& w) +{ + // vampir_trace<3043> tracer; + detail::upper_trisolve_t<Matrix, tag::regular_diagonal> solver(A); // use of anonymous variable causes weird error + solver(v, w); +} + +/// Solves the upper triangular matrix A (only one's in the diagonal) with the rhs v and returns the solution vector +template <typename Matrix, typename Vector> +Vector inline unit_upper_trisolve(const Matrix& A, const Vector& v) +{ + // vampir_trace<3044> tracer; + return detail::upper_trisolve_t<Matrix, tag::unit_diagonal>(A)(v); +} + +/// Solves the upper triangular matrix A (only one's in the diagonal) with the rhs v while solution vector w is passed as reference +template <typename Matrix, typename VectorIn, typename VectorOut> +void inline unit_upper_trisolve(const Matrix& A, const VectorIn& v, VectorOut& w) +{ + // vampir_trace<3044> tracer; + detail::upper_trisolve_t<Matrix, tag::unit_diagonal> solver(A); + solver(v, w); +} + +/// Solves the upper triangular matrix A (inverse the diagonal) with the rhs v and returns the solution vector +template <typename Matrix, typename Vector> +Vector inline inverse_upper_trisolve(const Matrix& A, const Vector& v) +{ + // vampir_trace<3045> tracer; + return detail::upper_trisolve_t<Matrix, tag::inverse_diagonal>(A)(v); +} + +/// Solves the upper triangular matrix A (inverse the diagonal) with the rhs v while solution vector w is passed as reference +template <typename Matrix, typename VectorIn, typename VectorOut> +void inline inverse_upper_trisolve(const Matrix& A, const VectorIn& v, VectorOut& w) +{ + // vampir_trace<3045> tracer; + detail::upper_trisolve_t<Matrix, tag::inverse_diagonal> solver(A); + solver(v, w); +} + +/// Solves the upper triangular matrix A with the rhs v and returns the solution vector +template <typename Matrix, typename Vector, typename DiaTag> +Vector inline upper_trisolve(const Matrix& A, const Vector& v, DiaTag) +{ + // vampir_trace<3046> tracer; + return detail::upper_trisolve_t<Matrix, DiaTag>(A)(v); +} + +/// Solves the upper triangular matrix A with the rhs v while solution vector w is passed as reference +template <typename Matrix, typename VectorIn, typename VectorOut, typename DiaTag> +void inline upper_trisolve(const Matrix& A, const VectorIn& v, VectorOut& w, DiaTag) +{ + // vampir_trace<3046> tracer; + detail::upper_trisolve_t<Matrix, DiaTag> solver(A); + solver(v, w); +} + +}} // namespace mtl::matrix + +#endif // MTL_UPPER_TRISOLVE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/operations.hpp b/install/MTL/include/boost/numeric/mtl/operations.hpp new file mode 100644 index 00000000..57e1e447 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/operations.hpp @@ -0,0 +1,113 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_OPERATIONS_INCLUDE +#define MTL_OPERATIONS_INCLUDE + +#include <boost/numeric/mtl/operation/adjoint.hpp> +#include <boost/numeric/mtl/operation/clone.hpp> +#include <boost/numeric/mtl/operation/cholesky.hpp> +#include <boost/numeric/mtl/operation/column_in_matrix.hpp> +#include <boost/numeric/mtl/operation/conj.hpp> +#include <boost/numeric/mtl/operation/copysign.hpp> +#include <boost/numeric/mtl/operation/crop.hpp> +#include <boost/numeric/mtl/operation/cross.hpp> +#include <boost/numeric/mtl/operation/cuppen.hpp> +#include <boost/numeric/mtl/operation/diagonal.hpp> +#include <boost/numeric/mtl/operation/dot.hpp> +#include <boost/numeric/mtl/operation/eigenvalue.hpp> +#include <boost/numeric/mtl/operation/eigenvalue_symmetric.hpp> +#include <boost/numeric/mtl/operation/entry1D.hpp> +#include <boost/numeric/mtl/operation/entry_similar.hpp> +#include <boost/numeric/mtl/operation/evaluate_lazy.hpp> +#include <boost/numeric/mtl/operation/extended_complex.hpp> +#include <boost/numeric/mtl/operation/fill.hpp> +#include <boost/numeric/mtl/operation/fuse.hpp> +#include <boost/numeric/mtl/operation/givens.hpp> +#include <boost/numeric/mtl/operation/hermitian.hpp> +#include <boost/numeric/mtl/operation/hessenberg.hpp> +#include <boost/numeric/mtl/operation/householder.hpp> +#include <boost/numeric/mtl/operation/imag.hpp> +#include <boost/numeric/mtl/operation/inv.hpp> +#include <boost/numeric/mtl/operation/invert_diagonal.hpp> +#include <boost/numeric/mtl/operation/is_negative.hpp> +#include <boost/numeric/mtl/operation/lazy.hpp> +#include <boost/numeric/mtl/operation/left_scale_inplace.hpp> +#include <boost/numeric/mtl/operation/lower_trisolve.hpp> +#include <boost/numeric/mtl/operation/lu.hpp> +#include <boost/numeric/mtl/operation/make_sparse.hpp> +#include <boost/numeric/mtl/operation/make_tag_vector.hpp> +#include <boost/numeric/mtl/operation/merge_complex_vector.hpp> +#include <boost/numeric/mtl/operation/minimal_increase.hpp> +#include <boost/numeric/mtl/operation/misc.hpp> +#include <boost/numeric/mtl/operation/mult.hpp> +#include <boost/numeric/mtl/operation/norms.hpp> +#include <boost/numeric/mtl/operation/ones.hpp> +#include <boost/numeric/mtl/operation/operators.hpp> +#include <boost/numeric/mtl/operation/orth.hpp> +#include <boost/numeric/mtl/operation/print.hpp> +#include <boost/numeric/mtl/operation/product.hpp> +#include <boost/numeric/mtl/operation/qr.hpp> +#include <boost/numeric/mtl/operation/random.hpp> +#include <boost/numeric/mtl/operation/rank_one_update.hpp> +#include <boost/numeric/mtl/operation/rank_two_update.hpp> +#include <boost/numeric/mtl/operation/real.hpp> +#include <boost/numeric/mtl/operation/resource.hpp> +#include <boost/numeric/mtl/operation/right_scale_inplace.hpp> +#include <boost/numeric/mtl/operation/scale.hpp> +#include <boost/numeric/mtl/operation/set_to_zero.hpp> +#include <boost/numeric/mtl/operation/secular.hpp> +#include <boost/numeric/mtl/operation/signum.hpp> +#include <boost/numeric/mtl/operation/split_complex_vector.hpp> +#include <boost/numeric/mtl/operation/sub_matrix.hpp> +#include <boost/numeric/mtl/operation/sum.hpp> +#include <boost/numeric/mtl/operation/min.hpp> +#include <boost/numeric/mtl/operation/min_pos.hpp> +#include <boost/numeric/mtl/operation/max.hpp> +#include <boost/numeric/mtl/operation/max_pos.hpp> +#include <boost/numeric/mtl/operation/max_abs_pos.hpp> +#include <boost/numeric/mtl/operation/num_cols.hpp> +#include <boost/numeric/mtl/operation/num_rows.hpp> +#include <boost/numeric/mtl/operation/row_in_matrix.hpp> +#include <boost/numeric/mtl/operation/size.hpp> +#include <boost/numeric/mtl/operation/size1D.hpp> +#include <boost/numeric/mtl/operation/static_num_cols.hpp> +#include <boost/numeric/mtl/operation/static_num_rows.hpp> +#include <boost/numeric/mtl/operation/static_size.hpp> +#include <boost/numeric/mtl/operation/svd.hpp> +#include <boost/numeric/mtl/operation/swap_row.hpp> +#include <boost/numeric/mtl/operation/trace.hpp> +#include <boost/numeric/mtl/operation/trans.hpp> +#include <boost/numeric/mtl/operation/unary_dot.hpp> +#include <boost/numeric/mtl/operation/unroll.hpp> +#include <boost/numeric/mtl/operation/upper_trisolve.hpp> + +#include <boost/numeric/mtl/matrix/bands.hpp> +#include <boost/numeric/mtl/matrix/identity.hpp> +#include <boost/numeric/mtl/matrix/lower.hpp> +#include <boost/numeric/mtl/matrix/permutation.hpp> +#include <boost/numeric/mtl/matrix/reorder.hpp> +#include <boost/numeric/mtl/matrix/reorder_ref.hpp> +#include <boost/numeric/mtl/matrix/reorder_matrix_rows.hpp> +#include <boost/numeric/mtl/matrix/strict_upper.hpp> +#include <boost/numeric/mtl/matrix/strict_lower.hpp> +#include <boost/numeric/mtl/matrix/upper.hpp> + +#include <boost/numeric/mtl/io/path.hpp> + +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/string_to_enum.hpp> +#include <boost/numeric/mtl/utility/make_copy_or_reference.hpp> + +#include <boost/numeric/mtl/interface/umfpack_solve.hpp> + +#endif // MTL_OPERATIONS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/recursion/base_case_cast.hpp b/install/MTL/include/boost/numeric/mtl/recursion/base_case_cast.hpp new file mode 100644 index 00000000..198d56be --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/recursion/base_case_cast.hpp @@ -0,0 +1,40 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_BASE_CASE_CAST_INCLUDE +#define MTL_BASE_CASE_CAST_INCLUDE + +#include <boost/numeric/mtl/recursion/base_case_matrix.hpp> +#include <boost/numeric/mtl/recursion/simplify_base_case_matrix.hpp> + +namespace mtl { namespace recursion { + + +template <typename BaseCaseTest, typename Matrix> +typename base_case_matrix<Matrix, BaseCaseTest>::type inline +base_case_cast(Matrix const& matrix) +{ + return simplify_base_case_matrix(matrix, BaseCaseTest()); +} + + +template <typename BaseCaseTest, typename Matrix> +typename base_case_matrix<Matrix, BaseCaseTest>::type inline +base_case_cast(Matrix& matrix) +{ + return simplify_base_case_matrix(matrix, BaseCaseTest()); +} + + +}} // namespace mtl::recursion + +#endif // MTL_BASE_CASE_CAST_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/recursion/base_case_matrix.hpp b/install/MTL/include/boost/numeric/mtl/recursion/base_case_matrix.hpp new file mode 100644 index 00000000..6e0d29e3 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/recursion/base_case_matrix.hpp @@ -0,0 +1,50 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_BASE_CASE_MATRIX_INCLUDE +#define MTL_BASE_CASE_MATRIX_INCLUDE + +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/meta_math/is_power_of_2.hpp> +#include <boost/numeric/meta_math/log_2.hpp> +#include <boost/numeric/mtl/recursion/base_case_test.hpp> +#include <boost/numeric/mtl/recursion/bit_masking.hpp> + +namespace mtl { namespace recursion { + +template <typename Matrix, typename BaseCaseTest> +struct base_case_matrix +{ + typedef Matrix type; +}; + +template <typename Elt, unsigned long Mask, typename Parameters, typename BaseCaseTest> +struct base_case_matrix<mtl::mat::morton_dense<Elt, Mask, Parameters>, BaseCaseTest> +{ + MTL_STATIC_ASSERT(meta_math::is_power_of_2<BaseCaseTest::base_case_size>::value, "Static base case size must be power of two"); + static const unsigned long base_case_bits= meta_math::log_2<BaseCaseTest::base_case_size>::value; + + typedef typename boost::mpl::if_< + is_k_power_base_case_row_major<base_case_bits, Mask> + , mtl::mat::dense2D<Elt, mat::parameters<row_major> > + , typename boost::mpl::if_< + is_k_power_base_case_col_major<base_case_bits, Mask> + , mtl::mat::dense2D<Elt, mat::parameters<col_major> > + , mtl::mat::morton_dense<Elt, Mask, Parameters> + >::type + >::type type; +}; + + +}} // namespace mtl::recursion + +#endif // MTL_BASE_CASE_MATRIX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/recursion/base_case_test.hpp b/install/MTL/include/boost/numeric/mtl/recursion/base_case_test.hpp new file mode 100644 index 00000000..059239c9 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/recursion/base_case_test.hpp @@ -0,0 +1,125 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_BASE_CASE_TEST_INCLUDE +#define MTL_BASE_CASE_TEST_INCLUDE + +#include <algorithm> + +namespace mtl { namespace recursion { + +// Minimum of dimensions is less or equal to the reference value +struct min_dim_test +{ + min_dim_test(std::size_t comp) : comp(comp) {} + + template <typename Recursator> + bool operator() (Recursator const& recursator) const + { + return std::min(recursator.get_value().num_rows(), + recursator.get_value().num_cols()) + <= comp; + } + +private: + std::size_t comp; +}; + + +// Minimum of dimensions is less or equal to the reference value +// and it can't be split into 2 sub-matrices less or equal the ref value +struct undivisible_min_dim_test +{ + undivisible_min_dim_test(std::size_t comp) : comp(comp) {} + + template <typename Recursator> + bool operator() (Recursator const& recursator) const + { + std::size_t min_dim= std::min(recursator.get_value().num_rows(), + recursator.get_value().num_cols()), + max_dim= std::max(recursator.get_value().num_rows(), + recursator.get_value().num_cols()); + + return min_dim <= comp && 2 * min_dim > max_dim; + } + +private: + std::size_t comp; +}; + + +// Maximum of dimensions is less or equal to the reference value +struct max_dim_test +{ + max_dim_test(std::size_t comp) : comp(comp) {} + + template <typename Recursator> + bool operator() (Recursator const& recursator) const + { + return std::max(num_rows(*recursator), num_cols(*recursator)) <= comp; + } + +private: + std::size_t comp; +}; + + +// Same with compile-time reference value +template <unsigned long BaseCaseSize> +struct max_dim_test_static +{ + static const unsigned long base_case_size= BaseCaseSize; + + template <typename Recursator> + bool operator() (Recursator const& recursator) const + { + return std::max(recursator.get_value().num_rows(), + recursator.get_value().num_cols()) + <= BaseCaseSize; + } +}; + + +// Upper bound of dimensions in recursator is less or equal to the reference value +struct bound_test +{ + bound_test(std::size_t comp) : comp(comp) {} + + template <typename Recursator> + bool operator() (Recursator const& recursator) const + { + return recursator.bound() <= comp; + } + +private: + std::size_t comp; +}; + + +// Same with compile-time reference value +template <unsigned long BaseCaseSize> +struct bound_test_static +{ + static const unsigned long base_case_size= BaseCaseSize; + + template <typename Recursator> + bool operator() (Recursator const& recursator) const + { + return recursator.bound() <= base_case_size; + } +}; + + + +}} // namespace mtl::recursion + +#endif // MTL_BASE_CASE_TEST_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/recursion/bit_masking.hpp b/install/MTL/include/boost/numeric/mtl/recursion/bit_masking.hpp new file mode 100644 index 00000000..6bb09ffb --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/recursion/bit_masking.hpp @@ -0,0 +1,259 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_BIT_MASKING_INCLUDE +#define MTL_BIT_MASKING_INCLUDE + +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/if.hpp> + +#include <boost/numeric/mtl/utility/tag.hpp> + +namespace mtl { + +/* + The bit masks are row masks, that mean 1s represent rows and 0s columns. + + Bit masks: + + i-order (cyrillic i): + --------------------- + + binary: 01010101 ... 01 + 0x55555555 + + + z-order: + -------- + + binary: 10101010 ... 10 + 0xaaaaaaaa + + row major: + ---------- + + with 2^k columns + binary: 111111111...1000...0 + ------- k 0s at the end (LSB), all bits before 1s (MSB) + + column major: + ------------- + + with 2^k rows + binary: 000000000...0111...1 + ------- k 1s at the end (LSB), all bits before 0s (MSB) + + hybrid (Doppled): + ----------------- + + i-order + with 2^k by 2^k base case + row major + binary 0101....011...10...0 + ----- k 0s at the end (LSB); means columns + ----- k 1s before; means rows + ---------- i order + e.g. 32 by 32 base case 0101...01 11111 00000 = 0x555557e0 + + column major + binary 0101....010...01...1 + ----- k 1s at the end (LSB); means rows + ----- k 0s before; means columns + ---------- i order + e.g. 32 by 32 base case 0101...01 00000 11111 = 0x5555541f + + Shark-tooth base case: + ---------------------- + + 2^t tooth length + in 2^k by 2^k base case (of course t <= k) + row-major + binary 1..1 00..0 1..1 + ---- t 1s at the end (LSB); means 2^t tooth allong rows + ---- k 0s before; means columns + ---- k-t 1s before; means rows + + column-major + binary 0..0 11..1 0..0 + ---- t 0s at the end (LSB); means 2^t tooth allong columns + ---- k 1s before; means rows + ---- k-t 0s before; means columns + + +*/ + + +// Mask for the last N bits +template <unsigned long N> +struct lsb_mask +{ + static const unsigned long value= (lsb_mask<N-1>::value << 1) | 1; +}; + + +template <> +struct lsb_mask<0> +{ + static const unsigned long value= 0; +}; + + +/// Last N bits of Value +template <unsigned long N, unsigned long Value> +struct lsb_bits +{ + static const unsigned long value= lsb_mask<N>::value & Value; +}; + + +/// Compares two masks +template <unsigned long Mask1, unsigned long Mask2> +struct same_mask +{ + static const bool value= false; +}; + +template <unsigned long Mask> +struct same_mask<Mask, Mask> +{ + static const bool value= true; +}; + + +/// Row-major mask for 2^K by 2^K base case +template <unsigned long K> +struct row_major_mask +{ + static const unsigned long value= lsb_mask<K>::value << K; +}; + + +/// Column-major mask for 2^K by 2^K base case +template <unsigned long K> +struct col_major_mask + : public lsb_mask<K> +{}; + + +/// Checks whether 2^K by 2^K base case of hybric matrix, defined by Mask, is a row-major matrix +template <unsigned long K, unsigned long Mask> +struct is_k_power_base_case_row_major +{ + static const bool value= same_mask<lsb_bits<2*K, Mask>::value, row_major_mask<K>::value>::value; + // typedef +}; + + +/// Checks whether 2^K by 2^K base case of hybric matrix, defined by Mask, is a column-major matrix +template <unsigned long K, unsigned long Mask> +struct is_k_power_base_case_col_major +{ + static const bool value= same_mask<lsb_bits<2*K, Mask>::value, col_major_mask<K>::value>::value; +}; + + +/// Checks whether 32x32 base case of hybric matrix, defined by Mask, is a row-major matrix +template <unsigned long Mask> +struct is_32_base_case_row_major + : public is_k_power_base_case_row_major<5, Mask> +{}; + + +/// Checks whether 32x32 base case of hybric matrix, defined by Mask, is a col-major matrix +template <unsigned long Mask> +struct is_32_base_case_col_major + : public is_k_power_base_case_col_major<5, Mask> +{}; + + +/// Row-major mask for 2^K by 2^K base case with 2^T shark teeth +template <unsigned long K, unsigned long T> +struct row_major_shark_mask +{ + static const unsigned long value= (lsb_mask<K-T>::value << (K+T)) | lsb_mask<T>::value; +}; + + +/// Row-major mask for 2^K by 2^K base case with 2^T shark teeth +template <unsigned long K, unsigned long T> +struct col_major_shark_mask +{ + static const unsigned long value= lsb_mask<K>::value << T; +}; + + +/** Checks whether 2^K by 2^K base case of hybric matrix, defined by Mask, + is a row-major matrix shark-tooth with 2^T tooth length +**/ +template <unsigned long K, unsigned long T, unsigned long Mask> +struct is_k_power_base_case_row_major_t_shark +{ + static const bool value= same_mask<lsb_bits<2*K, Mask>::value, row_major_shark_mask<K, T>::value>::value; +}; + + +/** Checks whether 2^K by 2^K base case of hybric matrix, defined by Mask, + is a col-major matrix shark-tooth with 2^T tooth length +**/ +template <unsigned long K, unsigned long T, unsigned long Mask> +struct is_k_power_base_case_col_major_t_shark +{ + static const bool value= same_mask<lsb_bits<2*K, Mask>::value, col_major_shark_mask<K, T>::value>::value; +}; + + // e-order +/// N-order mask of N bits +template <unsigned long N> +struct i_order_mask +{ + // Check if N is even !!! + static const unsigned long value= (i_order_mask<N-2>::value << 2) | 1; +}; + +template<> struct i_order_mask<0> : public lsb_mask<0> {}; // set to 0 + + +/// Z-order mask of N bits +template <unsigned long N> +struct z_order_mask +{ + // Check if N is even !!! + static const unsigned long value= (z_order_mask<N-2>::value << 2) | 2; +}; + +template<> struct z_order_mask<0> : public lsb_mask<0> {}; // set to 0 + + +/** Generate arbitrary hybrid mask. + \param IOrder if true then i-order otherwise z-order + \param K 2^K by 2^K base case + \param Orientation mtl::row_major or mtl::col_major + \param T 2^T tooth length +**/ +template <bool IOrder, unsigned long K, typename Orientation, unsigned long T> +class generate_mask +{ + static const unsigned long rec_size= 8 * sizeof(unsigned long) - 2 * K, + rec_part= (IOrder ? i_order_mask<rec_size>::value : z_order_mask<rec_size>::value) << 2*K; + typedef typename boost::mpl::if_< + boost::is_same<Orientation, row_major> + , row_major_shark_mask<K, T> + , col_major_shark_mask<K, T> + >::type base_part_type; +public: + static const unsigned long value= rec_part | base_part_type::value; +}; + + +} // namespace mtl + +#endif // MTL_BIT_MASKING_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/recursion/dim_splitter.hpp b/install/MTL/include/boost/numeric/mtl/recursion/dim_splitter.hpp new file mode 100644 index 00000000..d1569a4f --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/recursion/dim_splitter.hpp @@ -0,0 +1,154 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_DIM_SPLITTER_INCLUDE +#define MTL_DIM_SPLITTER_INCLUDE + +#include <algorithm> +#include <boost/numeric/mtl/recursion/utility.hpp> + +namespace mtl { namespace recursion { + +// Splits dimensions of a matrix separately into halfs (first value rounded up) +template <typename Matrix> +struct half_splitter +{ + typedef typename Matrix::size_type size_type; + + explicit half_splitter(Matrix const& matrix) + { + size_type nr= matrix.num_rows(), nc= matrix.num_cols(); + nr-= nr / 2; // keep the part (by removind the down-rounded half) + nc-= nc / 2; + my_row_split= matrix.begin_row() + nr; + my_col_split= matrix.begin_col() + nc; + } + + // End of northern half and beginning of southern + size_type row_split() const + { + return my_row_split; + } + + // End of western half and beginning of eastern + size_type col_split() const + { + return my_col_split; + } + +private: + size_type my_row_split, my_col_split; +}; + +// Splits dimensions of a matrix separately into a first part that +// is the largest power of 2 smaller than m or n, plus rest; +// doesn't yield empty submatrices if both dimension > 1 +template <typename Matrix> +struct separate_dim_splitter +{ + typedef typename Matrix::size_type size_type; + + explicit separate_dim_splitter(Matrix const& matrix) + : my_row_split(matrix.begin_row() + first_part(matrix.num_rows())), + my_col_split(matrix.begin_col() + first_part(matrix.num_cols())) + {} + + // End of northern half and beginning of southern + size_type row_split() const + { + return my_row_split; + } + + // End of western half and beginning of eastern + size_type col_split() const + { + return my_col_split; + } + +private: + size_type my_row_split, my_col_split; +}; + +// Splits dimensions of a matrix separately into a first part that +// is the largest power of 2 smaller than the maximum of m and n; +// can yield 1 or two empty submatrices if matrix is rather unproportional; +// helps creating square submatrices +template <typename Matrix> +struct max_dim_splitter +{ + typedef typename Matrix::size_type size_type; + + explicit max_dim_splitter(Matrix const& matrix) + : // matrix(matrix), + my_split(std::max(first_part(matrix.num_rows()), first_part(matrix.num_cols()))), + my_row_split(std::min(matrix.begin_row() + my_split, matrix.end_row())), + my_col_split(std::min(matrix.begin_col() + my_split, matrix.end_col())) + {} + + // End of northern half and beginning of southern (limited to end_row) + size_type row_split() const + { + return my_row_split; + } + + // End of western half and beginning of eastern (limited to end_col) + size_type col_split() const + { + return my_col_split; + } + +private: + // Matrix const& matrix; + size_type my_split, // minimal 2^(k-1) such that 2^k >= max(num_rows, num_cols) + my_row_split, my_col_split; +}; + + +// Splitting within bounding box of power of 2, using recursators +// For instance, the upper left part of a 530 x 17 matrix is +// 530 x 17 if the bound is 2048 or larger +// 512 x 17 if the bound is 1024 +// bound of 512 or smaller is a wrong bound +template <typename Recursator> +struct outer_bound_splitter +{ + typedef typename Recursator::size_type size_type; + + explicit outer_bound_splitter(Recursator const& recursator) + { + typename Recursator::matrix_type const& matrix= recursator.get_value(); + my_row_split= std::min(matrix.begin_row() + recursator.bound() / 2, matrix.end_row()); + my_col_split= std::min(matrix.begin_col() + recursator.bound() / 2, matrix.end_col()); + } + + + // End of northern half and beginning of southern (limited to end_row) + size_type row_split() const + { + return my_row_split; + } + + // End of western half and beginning of eastern (limited to end_col) + size_type col_split() const + { + return my_col_split; + } + +private: + size_type my_row_split, my_col_split; +}; + + + +}} // namespace mtl::recursion + +#endif // MTL_DIM_SPLITTER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/recursion/for_each.hpp b/install/MTL/include/boost/numeric/mtl/recursion/for_each.hpp new file mode 100644 index 00000000..bf751422 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/recursion/for_each.hpp @@ -0,0 +1,63 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_FOR_EACH_INCLUDE +#define MTL_FOR_EACH_INCLUDE + +namespace mtl { namespace recursion { + +// Go recursively down to base case and apply function on it +template <typename Matrix, typename Function, typename BaseCaseTest> +void for_each(mat::recursator<Matrix> const& recursator, Function const& f, BaseCaseTest const& is_base) +{ + if (recursator.is_empty()) + return; + + if (is_base(recursator)) { + f(*recursator); + return; + } + + for_each(recursator.north_west(), f, is_base); + for_each(recursator.south_west(), f, is_base); + for_each(recursator.north_east(), f, is_base); + for_each(recursator.south_east(), f, is_base); +} + + +// Non-const version +template <typename Matrix, typename Function, typename BaseCaseTest> +void for_each(mat::recursator<Matrix>& recursator, Function const& f, BaseCaseTest const& is_base) +{ + typedef mat::recursator<Matrix> recursator_type; + + if (recursator.is_empty()) + return; + + if (is_base(recursator)) { + f(recursator.get_value()); + return; + } + + recursator_type tmp_nw(recursator.north_west()), tmp_sw(recursator.south_west()), + tmp_ne(recursator.north_east()), tmp_se(recursator.south_east()); + for_each(tmp_nw, f, is_base); + for_each(tmp_sw, f, is_base); + for_each(tmp_ne, f, is_base); + for_each(tmp_se, f, is_base); +} + + +}} // namespace mtl::recursion + + +#endif // MTL_FOR_EACH_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/recursion/matrix_recursator.hpp b/install/MTL/include/boost/numeric/mtl/recursion/matrix_recursator.hpp new file mode 100644 index 00000000..4141233d --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/recursion/matrix_recursator.hpp @@ -0,0 +1,543 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_RECURATOR_INCLUDE +#define MTL_MATRIX_RECURATOR_INCLUDE + +#include <cmath> +#include <boost/shared_ptr.hpp> +#include <boost/type_traits/remove_const.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/sub_matrix.hpp> +#include <boost/numeric/mtl/operation/print_matrix.hpp> +#include <boost/numeric/mtl/matrix/transposed_view.hpp> +#include <boost/numeric/mtl/recursion/dim_splitter.hpp> +#include <boost/numeric/mtl/recursion/utility.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> + +namespace mtl { namespace mat { + + +template <typename Recursator1, typename Recursator2> +void inline equalize_depth(Recursator1& r1, Recursator2& r2); + +template <typename Recursator1, typename Recursator2, typename Recursator3> +void inline equalize_depth(Recursator1& r1, Recursator2& r2, Recursator3& r3); + + +/*! Class for matrix recursator + + How to use this class is described in the \ref rec_intro "recursion introduction". + + \sa \ref mtl::mat::north_west, \ref mtl::mat::north_east, + \ref mtl::mat::south_west, \ref mtl::mat::south_east, + \ref mtl::mat::is_empty(const recursator<Matrix>&), + \ref mtl::mat::is_full(const recursator<Matrix>&), + \ref mtl::mat::num_rows(const recursator<Matrix>&), + \ref mtl::mat::num_cols(const recursator<Matrix>&), + \ref mtl::mat::size(const recursator<Matrix>&) +**/ +template <typename Matrix> +struct recursator +{ + typedef recursator self; + typedef Matrix matrix_type; + typedef typename sub_matrix_t<Matrix>::sub_matrix_type sub_matrix_type; + typedef typename sub_matrix_t<Matrix>::const_sub_matrix_type const_sub_matrix_type; + typedef typename Collection<Matrix>::size_type size_type; + typedef typename Collection<Matrix>::value_type matrix_value_type; + typedef recursion::outer_bound_splitter<self> splitter_type; + +private: + + template <typename MatrixType> // why was it templated ??? + sub_matrix_type constructor_helper(MatrixType const& matrix) + { + return sub_matrix(matrix, matrix.begin_row(), matrix.end_row(), + matrix.begin_col(), matrix.end_col()); + } + + // For views without own data, we need to generate a new sub_matrix as shared_ptr + template <typename MatrixType> + sub_matrix_type constructor_helper(transposed_view<MatrixType> const& view) + { + typedef typename boost::remove_const<MatrixType>::type tmp_type; + typedef typename sub_matrix_t<tmp_type>::sub_matrix_type ref_sub_type; + typedef boost::shared_ptr<ref_sub_type> pointer_type; + typedef typename transposed_view<MatrixType>::other ref_type; + + // Submatrix of referred matrix, colums and rows interchanged + // Create a submatrix, whos address will be kept by transposed_view + pointer_type p(new ref_sub_type(sub_matrix(const_cast<ref_type&>(view.ref), view.begin_col(), view.end_col(), + view.begin_row(), view.end_row()))); + return sub_matrix_type(p); + } + +public: + /*! Construct a recursator from a matrix. + \param matrix The matrix to which the recursator refers. + \param bound Explicit bound declaration; must not be smaller than the numbers of rows and the number of columns; + must also be a power of 2. + + Constructor takes the entire matrix as sub-matrix. + This allows to have different type for the matrix and the sub-matrix. + **/ + explicit recursator(Matrix const& matrix, + size_type bound= 0 + ) + : my_sub_matrix(constructor_helper(matrix)), my_bound(recursion::outer_bound(matrix)), + my_first_row(0), my_first_col(0) // splitter(*this) + { + if (bound == 0) + my_bound= recursion::outer_bound(matrix); + else { + MTL_DEBUG_THROW_IF(!recursion::is_power_of_2(bound), range_error("Bound must be a power of 2")); + MTL_DEBUG_THROW_IF(bound < num_rows(matrix) || bound < num_cols(matrix), + range_error("Bound must not be smaller than matrix dimensions")); + my_bound= bound; + } + } + + +private: + + template <typename SubMatrix> + sub_matrix_type get_value_dispatch(const SubMatrix& , + size_type br, size_type er, size_type bc, size_type ec) const + { + return sub_matrix(my_sub_matrix, br, er, bc, ec); + } + + template <typename SubMatrix> + sub_matrix_type get_value_dispatch(transposed_view<SubMatrix> view, + size_type br, size_type er, size_type bc, size_type ec) const + { + typedef typename sub_matrix_t<SubMatrix>::sub_matrix_type ref_sub_type; + typedef boost::shared_ptr<ref_sub_type> pointer_type; + typedef typename transposed_view<SubMatrix>::other ref_type; + + pointer_type p(new ref_sub_type(sub_matrix(const_cast<ref_type&>(view.ref), bc, ec, br, er))); + return sub_matrix_type(p); + } + + +public: + sub_matrix_type get_value() const + { + using std::min; + size_type begin_row= my_sub_matrix.begin_row() + my_first_row, + end_row= min(begin_row + my_bound, my_sub_matrix.end_row()), + begin_col= my_sub_matrix.begin_col() + my_first_col, + end_col= min(begin_col + my_bound, my_sub_matrix.end_col()); + +#if 0 + std::cout << "get_value [" << begin_row << "-" << end_row << "][" + << begin_col << "-" << end_col << "]\n"; +#endif + return get_value_dispatch(my_sub_matrix, begin_row, end_row, begin_col, end_col); + } + + /// Compute the sub-matrix corresponding to this recursator. + sub_matrix_type operator*() const + { + return get_value(); + } + + // Returning quadrants for non-const recursator + + self north_west() const + { + self tmp(*this); + tmp.my_bound >>= 1; // divide by 2 + return tmp; + } + + self south_west() const + { + self tmp(*this); + tmp.my_bound >>= 1; // divide by 2 + tmp.my_first_row += tmp.my_bound; + return tmp; + } + + self north_east() const + { + self tmp(*this); + tmp.my_bound >>= 1; // divide by 2 + tmp.my_first_col += tmp.my_bound; + return tmp; + } + + self south_east() const + { + self tmp(*this); + tmp.my_bound >>= 1; // divide by 20 + tmp.my_first_row += tmp.my_bound; + tmp.my_first_col += tmp.my_bound; + return tmp; + } + + bool is_empty() const + { + return my_first_row >= num_rows(my_sub_matrix) || my_first_col >= num_cols(my_sub_matrix); + } + + + /// Return the bound of the recursator + size_type bound() const + { + return my_bound; + } + + /*! Set the bound of the recursator. + \param b The new virtual bound; must be a power of 2. + + This function allows to declare a virtual bound smaller than the number of rows and/or columns. + It must be used with uttermost care. + **/ + void set_bound(size_type b) + { + my_bound= b; + } + + template <typename R1, typename R2> friend void equalize_depth (R1&, R2&); + template <typename R1, typename R2, typename R3> friend void equalize_depth (R1&, R2&, R3&); + + template <typename M> friend typename recursator<M>::size_type num_rows(const recursator<M>& rec); + template <typename M> friend typename recursator<M>::size_type num_cols(const recursator<M>& rec); + + // Dirty feature to be used with care + matrix_value_type* first_address() + { + return &my_sub_matrix[my_first_row][my_first_col]; + } + + const matrix_value_type* first_address() const + { + return &my_sub_matrix[my_first_row][my_first_col]; + } + + protected: + sub_matrix_type my_sub_matrix; /// Referred matrix (from which the sub-matrices are built) + size_type my_bound, /// Virtual matrix size, i.e. upper bound for size of sub-matrix. + my_first_row, /// Row of first entry in submatrix + my_first_col; /// Row of first entry in submatrix +}; + +#if 0 + +// Obsolete, only left in code because discussed in a paper +// To use recursator with const matrices Reference must be 'Matrix const&' +template <typename Matrix, typename Splitter = recursion::max_dim_splitter<Matrix> > +struct recursator_s +{ + typedef recursator_s self; + typedef Matrix matrix_type; + typedef Splitter splitter_type; + typedef typename sub_matrix_t<Matrix>::sub_matrix_type sub_matrix_type; + typedef typename sub_matrix_t<Matrix>::const_sub_matrix_type const_sub_matrix_type; + typedef typename Matrix::size_type size_type; + // typedef outer_bound_splitter<self> splitter_type; + +private: + + // template <typename Matrix> why was it templated ??? + sub_matrix_type constructor_helper(Matrix const& matrix) + { + return sub_matrix(matrix, matrix.begin_row(), matrix.end_row(), + matrix.begin_col(), matrix.end_col()); + } + + // For views without own data, we need to generate a new sub_matrix as shared_ptr + // template <typename Matrix> + sub_matrix_type constructor_helper(transposed_view<Matrix> const& matrix) + { + typedef typename sub_matrix_t<Matrix>::sub_matrix_type ref_sub_type; + typedef boost::shared_ptr<ref_sub_type> pointer_type; + + // Submatrix of referred matrix, colums and rows interchanged + // Create a submatrix, whos address will be kept by transposed_view + pointer_type p(new ref_sub_type(sub_matrix(matrix.ref, matrix.begin_col(), matrix.end_col(), + matrix.begin_row(), matrix.end_row()))); + return sub_matrix_type(p); + } + +public: + // Constructor takes the whole matrix as sub-matrix + // This allows to have different type for the matrix and the sub-matrix + // This also enables matrices to have references as sub-matrices + explicit recursator_s(Matrix const& matrix, size_type bound= 0) + : my_sub_matrix(constructor_helper(matrix)), my_bound(outer_bound(matrix)), + splitter(my_sub_matrix) + { + if (bound == 0) + my_bound= outer_bound(matrix); + else { + assert(is_power_of_2(bound)); + assert(bound >= matrix.num_rows() && bound >= matrix.num_cols()); + my_bound= bound; + } + } + + // Sub-matrices are copied directly + // explicit recursator(sub_matrix_type sub_matrix) : my_sub_matrix(sub_matrix) {} + + sub_matrix_type& get_value() + { + return my_sub_matrix; + } + + sub_matrix_type const& get_value() const + { + return my_sub_matrix; + } + + // Returning quadrants for non-const recursator + + self north_west() + { + sub_matrix_type sm(sub_matrix(my_sub_matrix, my_sub_matrix.begin_row(), splitter.row_split(), + my_sub_matrix.begin_col(), splitter.col_split())); + self tmp(sm, my_bound / 2); + return tmp; + } + + self south_west() + { + sub_matrix_type sm(sub_matrix(my_sub_matrix, splitter.row_split(), my_sub_matrix.end_row(), + my_sub_matrix.begin_col(), splitter.col_split())); + self tmp(sm, my_bound / 2); + return tmp; + } + + self north_east() + { + sub_matrix_type sm(sub_matrix(my_sub_matrix, my_sub_matrix.begin_row(), splitter.row_split(), + splitter.col_split(), my_sub_matrix.end_col())); + self tmp(sm, my_bound / 2); + return tmp; + } + + self south_east() + { + sub_matrix_type sm(sub_matrix(my_sub_matrix, splitter.row_split(), my_sub_matrix.end_row(), + splitter.col_split(), my_sub_matrix.end_col())); + self tmp(sm, my_bound / 2); + return tmp; + } + + // Returning quadrants for const recursator + + self const north_west() const + { + sub_matrix_type sm(sub_matrix(const_cast<self*>(this)->my_sub_matrix, my_sub_matrix.begin_row(), splitter.row_split(), + my_sub_matrix.begin_col(), splitter.col_split())); + self tmp(sm, my_bound / 2); + return tmp; + } + + self const south_west() const + { + sub_matrix_type sm(sub_matrix(const_cast<self*>(this)->my_sub_matrix, splitter.row_split(), my_sub_matrix.end_row(), + my_sub_matrix.begin_col(), splitter.col_split())); + self tmp(sm, my_bound / 2); + return tmp; + } + + self const north_east() const + { + sub_matrix_type sm(sub_matrix(const_cast<self*>(this)->my_sub_matrix, my_sub_matrix.begin_row(), splitter.row_split(), + splitter.col_split(), my_sub_matrix.end_col())); + self tmp(sm, my_bound / 2); + return tmp; + } + + self const south_east() const + { + sub_matrix_type sm(sub_matrix(const_cast<self*>(this)->my_sub_matrix, splitter.row_split(), my_sub_matrix.end_row(), + splitter.col_split(), my_sub_matrix.end_col())); + self tmp(sm, my_bound / 2); + return tmp; + } + + // Checking whether a quadrant is empty + + // For completeness + bool north_west_empty() const + { + return false; + } + + bool north_east_empty() const + { + return splitter.col_split() == my_sub_matrix.end_col(); + } + + bool south_west_empty() const + { + return splitter.row_split() == my_sub_matrix.end_row(); + } + + bool south_east_empty() const + { + return splitter.row_split() == my_sub_matrix.end_row() + || splitter.col_split() == my_sub_matrix.end_col(); + } + + bool is_empty() const + { + return my_sub_matrix.begin_row() == my_sub_matrix.end_row() + || my_sub_matrix.begin_col() == my_sub_matrix.end_col(); + } + +#if 0 + bool is_leaf() const + { + return my_sub_matrix.num_rows() < 2 || my_sub_matrix.num_cols() < 2; + } +#endif + + size_type bound() const + { + assert(my_bound >= my_sub_matrix.num_rows() && my_bound >= my_sub_matrix.num_cols()); + return my_bound; + } + + template <typename R1, typename R2> friend void equalize_depth (R1&, R2&); + template <typename R1, typename R2, typename R3> friend void equalize_depth (R1&, R2&, R3&); + + protected: + sub_matrix_type my_sub_matrix; + size_type my_bound; + splitter_type splitter; +}; + +#endif + +template <typename Recursator1, typename Recursator2> +void inline equalize_depth(Recursator1& r1, Recursator2& r2) +{ + typename Recursator1::size_type max_bound= std::max(r1.bound(), r2.bound()); + r1.my_bound= max_bound; + r2.my_bound= max_bound; +} + +template <typename Recursator1, typename Recursator2, typename Recursator3> +void inline equalize_depth(Recursator1& r1, Recursator2& r2, Recursator3& r3) +{ + typename Recursator1::size_type max_bound= std::max(std::max(r1.bound(), r2.bound()), r3.bound()); + r1.my_bound= max_bound; + r2.my_bound= max_bound; + r3.my_bound= max_bound; +} + + +// Define free functions (from member functions) + +/*! Compute the north-west quadrant of a recursator (i.e. its referred matrix). + The result is itself a recursator. + \sa \ref rec_intro "recursion intro" +**/ +template <typename Matrix> +recursator<Matrix> inline north_west(const recursator<Matrix>& rec) +{ + return rec.north_west(); +} + +/*! Compute the north-east quadrant of a recursator (i.e. its referred matrix). + The result is itself a recursator. + \sa \ref rec_intro "recursion intro" +**/ +template <typename Matrix> +recursator<Matrix> inline north_east(const recursator<Matrix>& rec) +{ + return rec.north_east(); +} + +/*! Compute the south-west quadrant of a recursator (i.e. its referred matrix). + The result is itself a recursator. + \sa \ref rec_intro "recursion intro" +**/ +template <typename Matrix> +recursator<Matrix> inline south_west(const recursator<Matrix>& rec) +{ + return rec.south_west(); +} + +/*! Compute the south-east quadrant of a recursator (i.e. its referred matrix). + The result is itself a recursator. + \sa \ref rec_intro "recursion intro" +**/ +template <typename Matrix> +recursator<Matrix> inline south_east(const recursator<Matrix>& rec) +{ + return rec.south_east(); +} + + +/*! Check if a recursator (i.e. its referred matrix) is empty. + \sa \ref rec_intro "recursion intro" +**/ +template <typename Matrix> +bool inline is_empty(const recursator<Matrix>& rec) +{ + return rec.is_empty(); +} + +/*! Check if a recursator (i.e. its referred matrix) fills the + entire block, i.e. if the number of rows and columns are both + equal to the virtual bound. + \sa \ref rec_intro "recursion intro" +**/ +template <typename Matrix> +bool inline is_full(const recursator<Matrix>& rec) +{ + return num_rows(rec) == rec.bound() && num_cols(rec) == rec.bound(); +} + +/*! The number of rows that a sub-matrix would have if it was constructed. + \sa \ref rec_intro "recursion intro" +**/ +template <typename Matrix> +typename recursator<Matrix>::size_type +inline num_rows(const recursator<Matrix>& rec) +{ + using std::min; + typename recursator<Matrix>::size_type tmp= num_rows(rec.my_sub_matrix); + return rec.my_first_row >= tmp ? 0 : min(rec.my_bound, tmp - rec.my_first_row); +} + +/*! The number of columns that a sub-matrix would have if it was constructed. + \sa \ref rec_intro "recursion intro" +**/ +template <typename Matrix> +typename recursator<Matrix>::size_type +inline num_cols(const recursator<Matrix>& rec) +{ + using std::min; + typename recursator<Matrix>::size_type tmp= num_cols(rec.my_sub_matrix); + return rec.my_first_col >= tmp ? 0 : min(rec.my_bound, tmp - rec.my_first_col); +} + +/*! The number of elements (rows times columns) that a sub-matrix would have if it was constructed. + \sa \ref rec_intro "recursion intro" +**/ +template <typename Matrix> +typename recursator<Matrix>::size_type +inline size(const recursator<Matrix>& rec) +{ + return num_rows(rec) * num_cols(rec); +} + +}} // namespace mtl::matrix + +#endif // MTL_MATRIX_RECURATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/recursion/predefined_masks.hpp b/install/MTL/include/boost/numeric/mtl/recursion/predefined_masks.hpp new file mode 100644 index 00000000..884478c8 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/recursion/predefined_masks.hpp @@ -0,0 +1,90 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_PREDEFINED_MASKS_INCLUDE +#define MTL_PREDEFINED_MASKS_INCLUDE + +#include <boost/numeric/mtl/recursion/bit_masking.hpp> + +namespace mtl { namespace recursion { + + // Bitmasks: + const unsigned long morton_mask= generate_mask<true, 0, row_major, 0>::value, + morton_z_mask= generate_mask<false, 0, row_major, 0>::value, + doppled_2_row_mask= generate_mask<true, 1, row_major, 0>::value, + doppled_2_col_mask= generate_mask<true, 1, col_major, 0>::value, + doppled_4_row_mask= generate_mask<true, 2, row_major, 0>::value, + doppled_4_col_mask= generate_mask<true, 2, col_major, 0>::value, + doppled_16_row_mask= generate_mask<true, 4, row_major, 0>::value, + doppled_16_col_mask= generate_mask<true, 4, col_major, 0>::value, + doppled_z_16_row_mask= generate_mask<false, 4, row_major, 0>::value, + doppled_z_16_col_mask= generate_mask<false, 4, col_major, 0>::value, + doppled_32_row_mask= generate_mask<true, 5, row_major, 0>::value, + doppled_32_col_mask= generate_mask<true, 5, col_major, 0>::value, + doppled_z_32_row_mask= generate_mask<false, 5, row_major, 0>::value, + doppled_z_32_col_mask= generate_mask<false, 5, col_major, 0>::value, + doppled_64_row_mask= generate_mask<true, 6, row_major, 0>::value, + doppled_64_col_mask= generate_mask<true, 6, col_major, 0>::value, + doppled_z_64_row_mask= generate_mask<false, 6, row_major, 0>::value, + doppled_z_64_col_mask= generate_mask<false, 6, col_major, 0>::value, + doppled_128_row_mask= generate_mask<true, 7, row_major, 0>::value, + doppled_128_col_mask= generate_mask<true, 7, col_major, 0>::value, + doppled_z_128_row_mask= generate_mask<false, 7, row_major, 0>::value, + doppled_z_128_col_mask= generate_mask<false, 7, col_major, 0>::value, + shark_32_row_mask= generate_mask<true, 5, row_major, 1>::value, + shark_32_col_mask= generate_mask<true, 5, col_major, 1>::value, + shark_z_32_row_mask= generate_mask<false, 5, row_major, 1>::value, + shark_z_32_col_mask= generate_mask<false, 5, col_major, 1>::value, + shark_64_row_mask= generate_mask<true, 6, row_major, 1>::value, + shark_64_col_mask= generate_mask<true, 6, col_major, 1>::value, + shark_z_64_row_mask= generate_mask<false, 6, row_major, 1>::value, + shark_z_64_col_mask= generate_mask<false, 6, col_major, 1>::value; + + +} // namespace recursion + +// Export masks into MTL namespace + +using recursion::morton_mask; +using recursion::morton_z_mask; +using recursion::doppled_2_row_mask; +using recursion::doppled_2_col_mask; +using recursion::doppled_4_row_mask; +using recursion::doppled_4_col_mask; +using recursion::doppled_16_row_mask; +using recursion::doppled_16_col_mask; +using recursion::doppled_z_16_row_mask; +using recursion::doppled_z_16_col_mask; +using recursion::doppled_32_row_mask; +using recursion::doppled_32_col_mask; +using recursion::doppled_z_32_row_mask; +using recursion::doppled_z_32_col_mask; +using recursion::doppled_64_row_mask; +using recursion::doppled_64_col_mask; +using recursion::doppled_z_64_row_mask; +using recursion::doppled_z_64_col_mask; +using recursion::doppled_128_row_mask; +using recursion::doppled_128_col_mask; +using recursion::doppled_z_128_row_mask; +using recursion::doppled_z_128_col_mask; +using recursion::shark_32_row_mask; +using recursion::shark_32_col_mask; +using recursion::shark_z_32_row_mask; +using recursion::shark_z_32_col_mask; +using recursion::shark_64_row_mask; +using recursion::shark_64_col_mask; +using recursion::shark_z_64_row_mask; +using recursion::shark_z_64_col_mask; + +} // namespace mtl + +#endif // MTL_PREDEFINED_MASKS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/recursion/simplify_base_case_matrix.hpp b/install/MTL/include/boost/numeric/mtl/recursion/simplify_base_case_matrix.hpp new file mode 100644 index 00000000..91d2781b --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/recursion/simplify_base_case_matrix.hpp @@ -0,0 +1,98 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SIMPLIFY_BASE_CASE_MATRIX_INCLUDE +#define MTL_SIMPLIFY_BASE_CASE_MATRIX_INCLUDE + +#include <boost/numeric/mtl/matrix/dimension.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/operation/sub_matrix.hpp> +#include <boost/numeric/mtl/recursion/base_case_matrix.hpp> + + +namespace mtl { namespace recursion { + + +namespace impl { + + // With conversion, i.e. when target and source type are different + template <typename Matrix, typename BaseCaseMatrix, typename BaseCaseTest> + struct simplify_base_case_matrix + { + BaseCaseMatrix operator()(Matrix const& matrix, BaseCaseTest const) + { + typename Matrix::size_type begin_row= matrix.begin_row(), begin_col= matrix.begin_col(); + + if (matrix.num_rows() == BaseCaseTest::base_case_size + && matrix.num_cols() == BaseCaseTest::base_case_size) + return BaseCaseMatrix(non_fixed::dimensions(matrix.num_rows(), matrix.num_cols()), + &const_cast<Matrix&>(matrix)[begin_row][begin_col]); + + BaseCaseMatrix square(non_fixed::dimensions(BaseCaseTest::base_case_size, BaseCaseTest::base_case_size), + &const_cast<Matrix&>(matrix)[begin_row][begin_col]); + return sub_matrix(square, begin_row, matrix.num_rows(), begin_col, matrix.num_cols()); + } + }; + + template <typename Matrix, typename BaseCaseTest> + struct simplify_base_case_matrix<Matrix, Matrix, BaseCaseTest> + { + Matrix operator()(Matrix const& matrix, BaseCaseTest const) + { + return matrix; + } + }; + + +#if 0 + inline BaseCaseMatrix + simplify_base_case_matrix(Matrix const& matrix, BaseCaseMatrix const&, BaseCaseTest const&) + { + typename Matrix::size_type begin_row= matrix.begin_row(), begin_col= matrix.begin_col(); + + if (matrix.num_rows() == BaseCaseTest::base_case_size + && matrix.num_cols() == BaseCaseTest::base_case_size) + return BaseCaseMatrix(non_fixed::dimensions(matrix.num_rows(), matrix.num_cols()), + &const_cast<Matrix&>(matrix)[begin_row][begin_col]); + + BaseCaseMatrix square(non_fixed::dimensions(BaseCaseTest::base_case_size, BaseCaseTest::base_case_size), + &const_cast<Matrix&>(matrix)[begin_row][begin_col]); + return sub_matrix(square, begin_row, matrix.num_rows(), begin_col, matrix.num_cols()); + } + + // Without conversion, i.e. when target and source type are identical + template <typename Matrix, typename BaseCaseTest> + inline Matrix + simplify_base_case_matrix(Matrix const& matrix, Matrix const&, BaseCaseTest const&) + { + return matrix; + } +#endif + +} // namespace impl + +template <typename Matrix, typename BaseCaseTest> +typename base_case_matrix<Matrix, BaseCaseTest>::type inline +simplify_base_case_matrix(Matrix const& matrix, BaseCaseTest test) +{ + // cout << "simplify dim " << matrix.num_rows() << ", " << matrix.num_cols() << "\n"; + MTL_DEBUG_THROW_IF(num_rows(matrix) > BaseCaseTest::base_case_size || num_cols(matrix) > BaseCaseTest::base_case_size, + logic_error("Matrix dimension is larger than base case")); + + return impl::simplify_base_case_matrix<Matrix, typename base_case_matrix<Matrix, BaseCaseTest>::type, BaseCaseTest>()(matrix, test); + +} + +}} // namespace mtl::recursion + + +#endif // MTL_SIMPLIFY_BASE_CASE_MATRIX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/recursion/utility.hpp b/install/MTL/include/boost/numeric/mtl/recursion/utility.hpp new file mode 100644 index 00000000..d20473ae --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/recursion/utility.hpp @@ -0,0 +1,66 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_RECURSION_UTILITIES_INCLUDE +#define MTL_RECURSION_UTILITIES_INCLUDE + +#include <limits> +#include <cmath> + +namespace mtl { namespace recursion { + + +// Splits a number into a next-smallest power of 2 and rest +std::size_t inline first_part(std::size_t n) +{ + if (n == 0) return 0; + + std::size_t i= std::numeric_limits<std::size_t>::max()/2 + 1; + + while(i >= n) i>>= 1; + return i; +} + + +// The remainder of first part +std::size_t inline second_part(std::size_t n) +{ + return n - first_part(n); +} + + +template <typename Matrix> +std::size_t inline outer_bound(Matrix const& matrix) +{ + std::size_t max_dim=std::max(num_rows(matrix), num_cols(matrix)), bound= 1; + for (; bound < max_dim;) bound<<= 1; + return bound; +} + + +template <typename Integral> +Integral inline least_significant_one_bit(Integral x) +{ + return x & -x; +} + + +template <typename Integral> +bool inline is_power_of_2(Integral x) +{ + return x == least_significant_one_bit(x); +} + + +}} // namespace mtl::recursion + +#endif // MTL_RECURSION_UTILITIES_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/types.hpp b/install/MTL/include/boost/numeric/mtl/types.hpp new file mode 100644 index 00000000..c99938c2 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/types.hpp @@ -0,0 +1,34 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TYPES_INCLUDE +#define MTL_TYPES_INCLUDE + +#include <boost/numeric/mtl/vectors.hpp> +#include <boost/numeric/mtl/matrices.hpp> + +#include <boost/numeric/mtl/utility/different_non_complex.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/utility/srange.hpp> +#include <boost/numeric/mtl/utility/iset.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/range_wrapper.hpp> + +#include <boost/numeric/mtl/io/matrix_market.hpp> +#include <boost/numeric/mtl/io/read_el_matrix.hpp> +#include <boost/numeric/mtl/io/test_ostream.hpp> + +#include <boost/numeric/mtl/interface/arprec.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +#endif // MTL_TYPES_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/add_const.hpp b/install/MTL/include/boost/numeric/mtl/utility/add_const.hpp new file mode 100644 index 00000000..002d7caa --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/add_const.hpp @@ -0,0 +1,72 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_ADD_CONST_INCLUDE +#define MTL_TRAITS_ADD_CONST_INCLUDE + +namespace mtl { namespace traits { + +/// Add const to data +/** In case of pointers, constify data of first level (even if it is a pointer itself) + instead of (outer) address. + Other types are constified like in boost::add_const. + \sa add_const_to_root, add_const_to_all **/ +template <typename T> +struct add_const_to_data +{ + typedef T const type; +}; + +template <typename T*> +struct add_const_to_data +{ + typedef T const * type; +}; + +/// Add const to data at the root +/** In case of pointers, constify data of innermost level and leave other levels as they are. + instead of (outer) address. + Other types are constified like in boost::add_const. + \sa add_const_to_data, add_const_to_all **/ +template <typename T> +struct add_const_to_root +{ + typedef T const type; +}; + +template <typename T*> +struct add_const_to_root +{ + typedef typename add_const_to_root<T>::type * type; +}; + +/// Add const on all levels +/** In case of pointers, constify the address and recursively the type it is pointing to. + Other types are constified like in boost::add_const. + \sa add_const_to_data, add_const_to_all **/ +template <typename T> +struct add_const_to_all +{ + typedef T const type; +}; + +template <typename T*> +struct add_const_to_all +{ + typedef typename add_const_to_all<T>::type * const type; +}; + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_ADD_CONST_INCLUDE + + diff --git a/install/MTL/include/boost/numeric/mtl/utility/algebraic_category.hpp b/install/MTL/include/boost/numeric/mtl/utility/algebraic_category.hpp new file mode 100644 index 00000000..045f30f2 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/algebraic_category.hpp @@ -0,0 +1,39 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_ALGEBRAIC_CATEGORY_INCLUDE +#define MTL_TRAITS_ALGEBRAIC_CATEGORY_INCLUDE + +#include <boost/numeric/mtl/utility/is_what.hpp> + +namespace mtl { namespace traits { + +/// Meta-function for categorizing types into tag::scalar, tag::vector, and tag::matrix +/** Automatically derived from category + @ingroup Tags +*/ +template <typename T> +struct algebraic_category + : boost::mpl::if_< + is_matrix<T> + , tag::matrix + , typename boost::mpl::if_< + is_vector<T> + , tag::vector + , tag::scalar + >::type + > +{}; + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_ALGEBRAIC_CATEGORY_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/ashape.hpp b/install/MTL/include/boost/numeric/mtl/utility/ashape.hpp new file mode 100644 index 00000000..93e628ed --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/ashape.hpp @@ -0,0 +1,724 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ASHAPE_INCLUDE +#define MTL_ASHAPE_INCLUDE + +#include <vector> +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/if.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/root.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> + +// Not elegant but necessary to treat ITL types right +#include <boost/numeric/itl/itl_fwd.hpp> + +#ifdef MTL_WITH_INITLIST +# include <initializer_list> +#endif + +namespace mtl { + +/// Namespace for algebraic shapes; used for sophisticated dispatching between operations +namespace ashape { + +// forward declaration +template <typename T> struct ashape_aux; + +/// Tag for arbitrary algebraic shape +struct universe {}; + +// Types (tags) +/// Scalar algebraic shape +struct scal : universe {}; + +/// Non-scalar algebraic shape +struct nonscal : universe {}; +/// Row vector as algebraic shape +template <typename Value> struct rvec : nonscal {}; +/// Column vector as algebraic shape +template <typename Value> struct cvec : nonscal {}; +/// Matrix as algebraic shape +template <typename Value> struct mat : nonscal {}; +/// Undefined shape, e.g., for undefined results of operations +struct ndef {}; +/// Future shape, i.e. after appropriate evaluation it will have the shape \p Value +template <typename Value> struct future : nonscal {}; + +/// Meta-function for algebraic shape of T +/** Unknown types are treated like scalars. ashape of collections are template + parameterized with ashape of their elements, e.g., ashape< matrix < vector < double > > >::type is + mat< rvec < scal > > >. + Implemented with ashape_aux after type is cleaned up with mtl::traits::root. +**/ +template <typename T> +struct ashape + : ashape_aux<typename mtl::traits::root<T>::type> {}; + +template <typename T> +struct ashape_aux +{ + typedef scal type; +}; + +/// Vectors must be distinguished between row and column vectors +template <typename Value, typename Parameters> +struct ashape_aux<mtl::vec::dense_vector<Value, Parameters> > +{ + typedef typename boost::mpl::if_< + boost::is_same<typename Parameters::orientation, row_major> + , rvec<typename ashape<Value>::type> + , cvec<typename ashape<Value>::type> + >::type type; +}; + +/// Same as dense vector +template <typename Value, typename Parameters> +struct ashape_aux<vec::strided_vector_ref<Value, Parameters> > + : ashape<vec::dense_vector<Value, Parameters> > {}; + +/// Same as dense vector +template <typename Value, typename Parameters> +struct ashape_aux<vec::sparse_vector<Value, Parameters> > + : ashape<vec::dense_vector<Value, Parameters> > {}; + +/// One-dimensional arrays have rvec ashape; 2D arrays are matrices see below +template <typename Value, unsigned Rows> +struct ashape_aux<Value[Rows]> +{ + typedef rvec<typename ashape<Value>::type> type; +}; + +#ifdef MTL_WITH_INITLIST +/// Non-nested initializer_list have rvec ashape, nested lists are matrices see below +template <typename Value> +struct ashape_aux<std::initializer_list<Value> > +{ + typedef rvec<typename ashape<Value>::type> type; +}; +#endif + +/// std::vectors have rvec ashape +template <typename Value, typename Allocator> +struct ashape_aux<std::vector<Value, Allocator> > +{ + typedef rvec<typename ashape<Value>::type> type; +}; + +/// One-dimensional arrays have rvec ashape; 2D arrays are matrices see below +template <typename Value> +struct ashape_aux<Value*> +{ + typedef rvec<typename ashape<Value>::type> type; +}; + +template <typename E1, typename E2, typename SFunctor> +struct ashape_aux< vec::vec_vec_pmop_expr<E1, E2, SFunctor> > +{ + MTL_STATIC_ASSERT((boost::is_same<typename ashape<E1>::type, + typename ashape<E2>::type>::value), "Operands must have same algebraic shape."); + typedef typename ashape<E1>::type type; +}; + +template <typename E1, typename E2, typename SFunctor> +struct ashape_aux< vec::vec_vec_op_expr<E1, E2, SFunctor> > +{ +#if 0 // not sure if this is true in all operations + MTL_STATIC_ASSERT((boost::is_same<typename ashape<E1>::type, + typename ashape<E2>::type>::value), "Operands must have same algebraic shape."); +#endif + typedef typename ashape<E1>::type type; +}; + +template <typename E1, typename E2, typename SFunctor> +struct ashape_aux< vec::vec_vec_aop_expr<E1, E2, SFunctor> > +{ + typedef typename ashape<E1>::type type; +}; + +template <typename E1, typename E2, typename SFunctor> +struct ashape_aux< vec::vec_scal_aop_expr<E1, E2, SFunctor> > +{ + typedef typename ashape<E1>::type type; +}; + +template <typename Vector> +struct ashape_aux< vec::vec_const_ref_expr<Vector> > +{ + typedef typename ashape<Vector>::type type; +}; + + +// ======== +// Matrices +// ======== + +template <typename Value, typename Parameters> +struct ashape_aux<mtl::mat::compressed2D<Value, Parameters> > +{ + typedef mat<typename ashape<Value>::type> type; +}; + +template <typename Value, typename Parameters> +struct ashape_aux<mtl::mat::coordinate2D<Value, Parameters> > +{ + typedef mat<typename ashape<Value>::type> type; +}; + +template <typename Value, typename Parameters> +struct ashape_aux<mtl::mat::sparse_banded<Value, Parameters> > +{ + typedef mat<typename ashape<Value>::type> type; +}; + +template <typename Value, typename Parameters> +struct ashape_aux<mtl::mat::dense2D<Value, Parameters> > +{ + typedef mat<typename ashape<Value>::type> type; +}; + +template <typename Value, std::size_t Mask, typename Parameters> +struct ashape_aux<mtl::mat::morton_dense<Value, Mask, Parameters> > +{ + typedef mat<typename ashape<Value>::type> type; +}; + +template <typename Functor> +struct ashape_aux<mtl::mat::implicit_dense<Functor> > +{ + typedef mat<typename ashape<typename Functor::result_type>::type> type; +}; + +/// Two-dimensional arrays have mat ashape; 1D arrays are vectors see above +template <typename Value, unsigned Rows, unsigned Cols> +struct ashape_aux<Value[Rows][Cols]> +{ + typedef mat<typename ashape<Value>::type> type; +}; + +/// Two-dimensional arrays have mat ashape; 1D arrays are vectors see above +template <typename Value, unsigned Cols> +struct ashape_aux<Value (*)[Cols]> +{ + typedef mat<typename ashape<Value>::type> type; +}; + +#ifdef MTL_WITH_INITLIST +/// Nested initializer_list are matrices, non-nested are vectors see above +template <typename Value> +struct ashape_aux<std::initializer_list<std::initializer_list<Value> > > +{ + typedef mat<typename ashape<Value>::type> type; +}; +#endif + +template <typename Vector> +struct ashape_aux<mtl::mat::multi_vector<Vector> > +{ + typedef mat<typename ashape<typename mtl::Collection<mtl::mat::multi_vector<Vector> >::value_type>::type> type; +}; + +template <typename Value> +struct ashape_aux<mtl::mat::element_structure<Value> > +{ + typedef mat<typename ashape<Value>::type> type; +}; + +template <typename Value, typename Parameters> +struct ashape_aux<mtl::mat::ell_matrix<Value, Parameters> > +{ + typedef mat<typename ashape<Value>::type> type; +}; + + +template <typename Vector> +struct ashape_aux<mtl::mat::multi_vector_range<Vector> > +{ + typedef mat<typename ashape<typename mtl::Collection<mtl::mat::multi_vector_range<Vector> >::value_type>::type> type; +}; + +template <typename E1, typename E2, typename SFunctor> +struct ashape_aux< mtl::mat::mat_mat_op_expr<E1, E2, SFunctor> > +{ + MTL_STATIC_ASSERT((boost::is_same<typename ashape<E1>::type, + typename ashape<E2>::type>::value), "Operands must have same algebraic shape."); + typedef typename ashape<E1>::type type; +}; + +template <typename Vector1, typename Vector2> +struct ashape< mtl::mat::outer_product_matrix<Vector1, Vector2> > +{ + // BOOST_STATIC_ASSERT((boost::is_same<typename ashape<E1>::type, + // typename transposed_shape<typename ashape<E2>::type>::type>::value)); + typedef mat<typename ashape<typename mtl::Collection<Vector1>::value_type>::type> type; +}; + +template <typename Matrix, typename VectorIn> +struct ashape< mtl::vec::mat_cvec_multiplier<Matrix, VectorIn> > +{ + typedef cvec<scal> type; +}; + +// ===== +// Views +// ===== + +template <typename Functor, typename Coll> +struct ashape_aux<mtl::mat::map_view<Functor, Coll> > +{ + typedef typename ashape<Coll>::type type; +}; + +template <typename Functor, typename Coll> +struct ashape_aux<mtl::vec::map_view<Functor, Coll> > +{ + typedef typename ashape<Coll>::type type; +}; + +template <typename Coll> +struct ashape_aux<mtl::vec::conj_view<Coll> > +{ + typedef typename ashape<Coll>::type type; +}; + +template <typename Coll> +struct ashape_aux<mtl::vec::real_view<Coll> > +{ + typedef typename ashape<Coll>::type type; +}; + +template <typename Coll> +struct ashape_aux<mtl::vec::imag_view<Coll> > +{ + typedef typename ashape<Coll>::type type; +}; + +#if 1 +// shouldn't be needed +template <typename Coll> +struct ashape_aux<mtl::mat::transposed_view<const mtl::mat::conj_view<Coll> > > +{ + typedef typename ashape<Coll>::type type; +}; +#endif + +template <typename Matrix> +struct ashape_aux<mtl::mat::transposed_view<Matrix> > +{ + typedef typename ashape<Matrix>::type type; +}; + +template <typename Matrix> +struct ashape_aux<mtl::mat::banded_view<Matrix> > +{ + typedef typename ashape<Matrix>::type type; +}; + +template <typename Matrix> +struct ashape_aux<mtl::mat::indirect<Matrix> > +{ + typedef typename ashape<Matrix>::type type; +}; + +// Rule out other types as algebraic shape +template <typename IFStream, typename OFStream> +struct ashape_aux<io::matrix_file<IFStream, OFStream> > +{ + typedef ndef type; +}; + + +// ===================== +// Shapes of products: +// ===================== + +// a) The result's shape +// b) Classify operation in terms of shape + +// Operation types: + +struct scal_scal_mult {}; +struct cvec_rvec_mult {}; // outer product +struct rvec_cvec_mult {}; // inner product (without conj) +struct rvec_mat_mult {}; +struct mat_cvec_mult {}; +struct mat_mat_mult {}; +struct scal_rvec_mult {}; +struct scal_cvec_mult {}; +struct scal_mat_mult {}; +struct rvec_scal_mult {}; +struct cvec_scal_mult {}; +struct mat_scal_mult {}; + + + +// ===================== +// Results of operations +// ===================== + +/* + s cv rv m +------------------- + s | s cv* rv* m* +cv | cv* x m x +rv | rv* s x rv + m | m* cv x m + + * only on outer level, forbidden for elements of collections + +*/ + +// Results for elements of collections, i.e. scalar * matrix (vector) are excluded + + +/// Algebraic shape of multiplication's result when elements of collections are multiplied. +/** The types are the same as for multiplications of entire collections except that scalar * + matrix (or vector) is excluded to avoid ambiguities. + emult_shape <Shape1, Shape2> is only properly defined if emult_op <Shape1, Shape2>::type is not ndef! +**/ +template <typename Shape1, typename Shape2> +struct emult_shape +{ + typedef ndef type; +}; + +/// Type of operation when values of Shape1 and Shape2 are multiplied (so far only for elements of collections) +/** The types are the same as for multiplications of entire collections except that scalar * + matrix (or vector) is excluded to avoid ambiguities. **/ +template <typename Shape1, typename Shape2> +struct emult_op +{ + typedef ndef type; +}; + + +// Scalar * scalar -> scalar +template <> +struct emult_shape<scal, scal> +{ + typedef scal type; +}; + +template <> +struct emult_op<scal, scal> +{ + typedef scal_scal_mult type; +}; + +// Column times row vector, i.e. outer product +template <typename Value1, typename Value2> +struct emult_shape<cvec<Value1>, rvec<Value2> > +{ + typedef mat<typename emult_shape<Value1, Value2>::type> type; +}; + +template <typename Value1, typename Value2> +struct emult_op<cvec<Value1>, rvec<Value2> > +{ + // if product of elements is undefined then product is undefined too + typedef typename boost::mpl::if_< + boost::is_same<typename emult_op<Value1, Value2>::type, ndef> + , ndef + , cvec_rvec_mult + >::type type; +}; + + +// Row times column vector, i.e. inner product (without conj) +template <typename Value1, typename Value2> +struct emult_shape<rvec<Value1>, cvec<Value2> > +{ + typedef typename emult_shape<Value1, Value2>::type type; +}; + +template <typename Value1, typename Value2> +struct emult_op<rvec<Value1>, cvec<Value2> > +{ + // if product of elements is undefined then product is undefined too + typedef typename boost::mpl::if_< + boost::is_same<typename emult_op<Value1, Value2>::type, ndef> + , ndef + , rvec_cvec_mult + >::type type; +}; + +// Row vector times matrix +template <typename Value1, typename Value2> +struct emult_shape<rvec<Value1>, mat<Value2> > +{ + typedef rvec<typename emult_shape<Value1, Value2>::type> type; +}; + + +template <typename Value1, typename Value2> +struct emult_op<rvec<Value1>, mat<Value2> > +{ + // if product of elements is undefined then product is undefined too + typedef typename boost::mpl::if_< + boost::is_same<typename emult_op<Value1, Value2>::type, ndef> + , ndef + , rvec_mat_mult + >::type type; +}; + +// Matrix times column vector +template <typename Value1, typename Value2> +struct emult_shape<mat<Value1>, cvec<Value2> > +{ + typedef cvec<typename emult_shape<Value1, Value2>::type> type; +}; + +template <typename Value1, typename Value2> +struct emult_op<mat<Value1>, cvec<Value2> > +{ + // if product of elements is undefined then product is undefined too + typedef typename boost::mpl::if_< + boost::is_same<typename emult_op<Value1, Value2>::type, ndef> + , ndef + , mat_cvec_mult + >::type type; +}; + + +// Matrix product +template <typename Value1, typename Value2> +struct emult_shape<mat<Value1>, mat<Value2> > +{ + typedef mat<typename emult_shape<Value1, Value2>::type> type; +}; + +template <typename Value1, typename Value2> +struct emult_op<mat<Value1>, mat<Value2> > +{ + // if product of elements is undefined then product is undefined too + typedef typename boost::mpl::if_< + boost::is_same<typename emult_op<Value1, Value2>::type, ndef> + , ndef + , mat_mat_mult + >::type type; +}; + + +// Results for entire collections, i.e. scalar * matrix (vector) are allowed + +// Multiplying collections as emult + +template <typename Shape1, typename Shape2> +struct mult_shape + : public emult_shape<Shape1, Shape2> +{}; + +template <typename Shape1, typename Shape2> +struct mult_op + : public emult_op<Shape1, Shape2> +{}; + +// Scale collection from left + +template <typename Shape2> +struct mult_shape<scal, Shape2> +{ + typedef Shape2 type; +}; + +template <typename Value2> +struct mult_op<scal, rvec<Value2> > +{ + typedef scal_rvec_mult type; +}; + +template <typename Value2> +struct mult_op<scal, cvec<Value2> > +{ + typedef scal_cvec_mult type; +}; + +template <typename Value2> +struct mult_op<scal, mat<Value2> > +{ + typedef scal_mat_mult type; +}; + +// Scale collection from right + +template <typename Shape1> +struct mult_shape<Shape1, scal> +{ + typedef Shape1 type; +}; + +template <typename Value1> +struct mult_op<rvec<Value1>, scal> +{ + typedef rvec_scal_mult type; +}; + +template <typename Value1> +struct mult_op<cvec<Value1>, scal> +{ + typedef cvec_scal_mult type; +}; + +template <typename Value1> +struct mult_op<mat<Value1>, scal> +{ + typedef mat_scal_mult type; +}; + +// Arbitration +template <> +struct mult_shape<scal, scal> +{ + typedef scal type; +}; + + +// Needs to be verified for nested matrix types, cf. #140 +template <typename E1, typename E2> +struct ashape< mtl::mat::mat_mat_times_expr<E1, E2> > +{ + // typedef typename ashape<E1>::type type; + typedef typename mult_shape<typename ashape<E1>::type, + typename ashape<E2>::type>::type type; +}; + + +template <typename E1, typename E2> +struct ashape< mat_cvec_times_expr<E1, E2> > +{ + // Resulting vector has the same shape as the multiplied + typedef typename ashape<E2>::type type; +}; + +template <typename E1, typename E2> +struct ashape< vec::rvec_mat_times_expr<E1, E2> > +{ + // Resulting vector has the same shape as the multiplied + typedef typename ashape<E1>::type type; +}; + + +// added by Hui Li (below) ----------------------------------------- + +// ===================== +// Shapes of divisions: +// ===================== + +// Operation types: + +struct scal_scal_div {}; +struct cvec_scal_div {}; +struct rvec_scal_div {}; +struct mat_scal_div {}; + +template < typename Shape1, typename Shape2 > +struct div_shape +{ + typedef ndef type; +}; + +template < typename Shape1, typename Shape2 > +struct div_op +{ + typedef ndef type; +}; + +template <> +struct div_shape<scal,scal> +{ + typedef scal type; +}; + +template<> +struct div_op<scal,scal> +{ + typedef scal type; +}; + +template < typename Value1 > +struct div_shape < rvec<Value1>, scal > +{ + typedef typename boost::mpl::if_< + typename boost::is_same<typename div_shape<Value1,scal>::type,ndef>::type, + ndef, + rvec<typename div_shape<Value1,scal>::type> + >::type type; +}; + +template < typename Value1 > +struct div_op< rvec<Value1>, scal > +{ + typedef typename boost::mpl::if_< + typename boost::is_same<typename div_shape<rvec<Value1>,scal>::type,ndef>::type, + ndef, + rvec_scal_div + >::type type; +}; + +template < typename Value1 > +struct div_shape < cvec<Value1>, scal > +{ + typedef typename boost::mpl::if_< + typename boost::is_same<typename div_shape<Value1,scal>::type,ndef>::type, + ndef, + cvec<typename div_shape<Value1,scal>::type> + >::type type; +}; + +template < typename Value1 > +struct div_op< cvec<Value1>, scal > +{ + typedef typename boost::mpl::if_< + typename boost::is_same<typename div_shape<cvec<Value1>,scal>::type,ndef>::type, + ndef, + cvec_scal_div + >::type type; +}; + +template < typename Value1 > +struct div_shape < mat<Value1>, scal > +{ + typedef typename boost::mpl::if_< + typename boost::is_same<typename div_shape<Value1,scal>::type,ndef>::type, + ndef, + mat<typename div_shape<Value1,scal>::type> + >::type type; +}; + +template < typename Value1 > +struct div_op < mat<Value1>, scal > +{ + typedef typename boost::mpl::if_< + typename boost::is_same<typename div_shape<mat<Value1>,scal>::type,ndef>::type, + ndef, + mat_scal_div + >::type type; +}; + +// added by Hui Li (above) ----------------------------------------- + +// ==================== ITL types ================================== + +template <typename PC, typename Vector, bool Adjoint> +struct ashape<itl::pc::solver<PC, Vector, Adjoint> > +{ + typedef future<cvec<scal> > type; // might be a problem with nested matrices and vectors +}; + + +}} // namespace mtl::ashape + +#endif // MTL_ASHAPE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/category.hpp b/install/MTL/include/boost/numeric/mtl/utility/category.hpp new file mode 100644 index 00000000..760a9ec7 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/category.hpp @@ -0,0 +1,304 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_CATEGORY_INCLUDE +#define MTL_CATEGORY_INCLUDE + +#include <vector> + +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/bool.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> + +// Not elegant but necessary to treat ITL types right +#include <boost/numeric/itl/itl_fwd.hpp> + + +namespace mtl { namespace traits { + +/// Meta-function for categorizing MTL and external types +/** Has to be specialized for each %matrix, %vector, ... + Extensively used for dispatching + @ingroup Tags +*/ +template <typename Collection> struct category +{ + typedef tag::unknown type; +}; + +// Const types have the same category as their non-const counterpart +template <typename T> +struct category<const T> +{ + typedef typename category<T>::type type; +}; + +template <typename Value, typename Parameters> +struct category<mtl::mat::dense2D<Value, Parameters> > +{ + typedef tag::dense2D type; +}; + + +template <typename Functor> +struct category<mtl::mat::implicit_dense<Functor> > +{ + typedef tag::implicit_dense type; +}; + +template <typename Value> +struct category<mtl::mat::ones_matrix<Value> > + : public category<mtl::mat::implicit_dense<mtl::mat::ones_functor<Value> > > +{}; + +template <typename Value> +struct category<mtl::mat::hilbert_matrix<Value> > + : public category<mtl::mat::implicit_dense<mtl::mat::hilbert_functor<Value> > > +{}; + +template <typename Vector1, typename Vector2> +struct category<mtl::mat::outer_product_matrix<Vector1, Vector2> > + : public category<mtl::mat::implicit_dense<mtl::mat::outer_product_functor<Vector1, Vector2> > > +{}; + + +template <typename Elt, std::size_t BitMask, typename Parameters> +struct category<mtl::mat::morton_dense<Elt, BitMask, Parameters> > +{ + typedef mtl::tag::morton_dense type; +}; + +template <typename Elt, typename Parameters> +struct category<mtl::mat::compressed2D<Elt, Parameters> > +{ + typedef tag::compressed2D type; +}; + +// should have the same tags as compressed2D +template <typename Elt, typename Parameters> +struct category<mtl::mat::coordinate2D<Elt, Parameters> > +{ + typedef tag::compressed2D type; +}; + +template <typename Elt, typename Parameters> +struct category<mtl::mat::sparse_banded<Elt, Parameters> > +{ + typedef tag::sparse_banded_matrix type; +}; + +template <typename Vector> +struct category<mtl::mat::multi_vector<Vector> > +{ + typedef tag::multi_vector type; +}; + +template <typename Vector> +struct category<mtl::mat::multi_vector_range<Vector> > +{ + typedef tag::multi_vector type; +}; + +template <typename Value> +struct category<mtl::mat::element_structure<Value> > +{ + typedef tag::element_structure type; +}; + +template <typename Value, typename Parameters> +struct category<mtl::mat::ell_matrix<Value, Parameters> > +{ + typedef tag::ell_matrix type; +}; + +template <typename T, typename Parameters> +struct category< mtl::vec::dense_vector<T, Parameters> > +{ + typedef typename boost::mpl::if_< + boost::is_same<typename Parameters::orientation, row_major> + , tag::dense_row_vector + , tag::dense_col_vector + >::type type; +} ; + +template <typename T, typename Parameters> +struct category< mtl::vec::strided_vector_ref<T, Parameters> > +{ + typedef typename boost::mpl::if_< + boost::is_same<typename Parameters::orientation, row_major> + , tag::strided_row_vector + , tag::strided_col_vector + >::type type; +} ; + +template <typename T, typename Parameters> +struct category< mtl::vec::sparse_vector<T, Parameters> > +{ + typedef typename boost::mpl::if_< + boost::is_same<typename Parameters::orientation, row_major> + , tag::sparse_row_vector + , tag::sparse_col_vector + >::type type; +} ; + + +template <class E1, class E2, class SFunctor> +struct category< mtl::vec::vec_vec_pmop_expr<E1,E2, SFunctor> > +{ + typedef category<E1> type; +}; + +template <typename Functor, typename Vector> +struct category< mtl::vec::map_view<Functor, Vector> > + : public category<Vector> +{}; + +template <typename Scaling, typename Vector> +struct category< mtl::vec::scaled_view<Scaling, Vector> > + : public category< mtl::vec::map_view<tfunctor::scale<Scaling, typename Vector::value_type>, + Vector> > +{}; + +// added by Hui Li +template <typename Vector,typename RScaling> +struct category< mtl::vec::rscaled_view<Vector,RScaling> > + : public category< mtl::vec::map_view<tfunctor::rscale<typename Vector::value_type,RScaling>, + Vector> > +{}; + +// added by Hui Li +template <typename Vector,typename Divisor> +struct category< mtl::vec::divide_by_view<Vector,Divisor> > + : public category< mtl::vec::map_view<tfunctor::divide_by<typename Vector::value_type,Divisor>, + Vector> > +{}; + +template <typename Vector> +struct category< mtl::vec::conj_view<Vector> > + : public category< mtl::vec::map_view<sfunctor::conj<typename Vector::value_type>, Vector> > +{}; + +template <typename Vector> +struct category< mtl::vec::negate_view<Vector> > + : public category< mtl::vec::map_view<sfunctor::negate<typename Vector::value_type>, Vector> > +{}; + +// To handle std::vector in algorithms +template <typename T> +struct category< std::vector<T> > +{ + typedef tag::std_vector type; +}; + +namespace detail { + + template <typename Cat> struct view_category { typedef Cat type; }; + + template <> struct view_category<tag::dense2D> { typedef tag::dense2D_view type; }; + template <> struct view_category<tag::morton_dense> { typedef tag::morton_view type; }; + template <> struct view_category<tag::compressed2D> { typedef tag::compressed2D_view type; }; + + template <typename Matrix> + struct simple_matrix_view_category + : view_category<typename category<Matrix>::type> + {}; + +} // detail + + +template <typename Functor, typename Matrix> +struct category<mtl::mat::map_view<Functor, Matrix> > + : public detail::simple_matrix_view_category<Matrix> +{}; + +template <typename Scaling, typename Matrix> +struct category< mtl::mat::scaled_view<Scaling, Matrix> > + : public category< mat::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>, + Matrix> > +{}; + +// added by Hui Li +template <typename Matrix, typename RScaling> +struct category< mtl::mat::rscaled_view<Matrix,RScaling> > + : public category< mat::map_view<tfunctor::rscale<typename Matrix::value_type,RScaling>, + Matrix> > +{}; + +// added by Hui Li +template <typename Matrix, typename Divisor> +struct category< mtl::mat::divide_by_view<Matrix,Divisor> > + : public category< mat::map_view<tfunctor::divide_by<typename Matrix::value_type,Divisor>, + Matrix> > +{}; + +// add dense to view_category +template <typename Matrix> +struct category<mtl::mat::indirect<Matrix> > +{ + typedef mtl::tag::join<typename detail::simple_matrix_view_category<Matrix>::type, mtl::tag::dense> type; +}; + + +template <typename Matrix> +struct category<mtl::mat::transposed_view<Matrix> > + : public category<Matrix> +{}; + +// Specialize on transposed multi-vectors +template <typename Vector> +struct category< mtl::mat::transposed_view< mtl::mat::multi_vector<Vector> > > +{ + typedef tag::transposed_multi_vector type; +}; + +template <typename Matrix> +struct category< mat::conj_view<Matrix> > + : public category< mat::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> > +{}; + +template <typename Matrix> +struct category< mat::hermitian_view<Matrix> > + : public category< mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, + mtl::mat::transposed_view<Matrix> > > +{}; + +// Specialize on Hermiatians of multi-vectors +template <typename Vector> +struct category< mat::hermitian_view<mtl::mat::multi_vector<Vector> > > +{ + typedef tag::hermitian_multi_vector type; +}; + + +template <typename Matrix> +struct category< mtl::mat::banded_view<Matrix> > + : public detail::simple_matrix_view_category<Matrix> +{}; + +template <typename Matrix, typename VectorIn> +struct category< mtl::vec::mat_cvec_multiplier<Matrix, VectorIn> > +{ + typedef tag::mat_cvec_multiplier type; +}; + +template <typename PC, typename Vector, bool Adjoint> +struct category<itl::pc::solver<PC, Vector, Adjoint> > +{ + typedef tag::unevaluated type; // might be a problem with nested matrices and vectors +}; + +}} // namespace mtl::traits + +#endif // MTL_CATEGORY_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/common_include.hpp b/install/MTL/include/boost/numeric/mtl/utility/common_include.hpp new file mode 100644 index 00000000..adf0727d --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/common_include.hpp @@ -0,0 +1,37 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_COMMON_INCLUDES_INCLUDE +#define MTL_COMMON_INCLUDES_INCLUDE + +#include <boost/numeric/mtl/matrix/base_matrix.hpp> +#include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/detail/range_generator.hpp> +#include <boost/numeric/mtl/utility/complexity.hpp> +#include <boost/numeric/mtl/utility/glas_tag.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/matrix/inserter.hpp> +#include <boost/numeric/mtl/operation/matrix_bracket.hpp> +#include <boost/numeric/mtl/operation/sub_matrix.hpp> +#include <boost/numeric/mtl/operation/copy.hpp> +#include <boost/numeric/mtl/utility/maybe.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> + + +// Under construction +// #include <boost/numeric/mtl/utilities/iterator_adaptor_1D.hpp> + +#endif // MTL_COMMON_INCLUDES_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/complexity.hpp b/install/MTL/include/boost/numeric/mtl/utility/complexity.hpp new file mode 100644 index 00000000..eaa7a9bb --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/complexity.hpp @@ -0,0 +1,193 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_COMPLEXITY_INCLUDE +#define MTL_COMPLEXITY_INCLUDE + +#include <boost/mpl/int.hpp> +#include <boost/mpl/max.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/less.hpp> +#include <boost/mpl/less_equal.hpp> + +// This file contains types to characterize time complexities of operations or traversals +// Different traversals over given collections have different run time +// Algorithms implementable with different traversals can use these complexities to dispatch + +// Complexities in a order, which of course will not be changed +// The underlying MPL definitions might be modified to add finer grained distinctions + + + +namespace mtl { +/// Namespace to define complexity classes +namespace complexity_classes { + +/// Constant complexity where the value is expected to be in cache with high probability. +/** Special type for traversals to distinguish between strided or random memory access with 'constant' + (but slow) memory access and consecutive memory access with a good change that only one element + per cache line must be load from memory +**/ +struct cached : boost::mpl::int_<1> {}; + +/// Constant complexity +struct constant : boost::mpl::int_<2> {}; + +/// Logarithmic complexity +struct log_n : boost::mpl::int_<4> {}; + +/// Polynomial logarithm, i.e. log^k n +struct polylog_n : boost::mpl::int_<5> {}; + +/// Product of linear and cached +struct linear_cached : boost::mpl::int_<21> {}; + +/// Linear +struct linear : boost::mpl::int_<22> {}; + +/// Logarithm times linear, i.e. n * log n +struct n_log_n : boost::mpl::int_<24> {}; + +/// Polynomial logarithm times linear, i.e. n * log^k n +struct n_polylog_n : boost::mpl::int_<25> {}; + +struct quadratic : boost::mpl::int_<41> {}; + +/// All complexities larger than quadratic (< infinite) including n^2 log^k n +struct polynomial : boost::mpl::int_<200> {}; + +/// Infinite time complexity, which usually means that the operation or traversal is not available +struct infinite : boost::mpl::int_<1000> {}; + +/// Adding complexities of two operations is the maximal complexity of both operations +template <typename X, typename Y> +struct plus : boost::mpl::if_< boost::mpl::less<X, Y>, Y, X> {}; + +/// Minimal complexity class +template <typename X, typename Y> +struct min : boost::mpl::if_< boost::mpl::less<X, Y>, X, Y> {}; + + +namespace detail +{ + // specializations on first argument + + // polynomial is the most frequent result, otherwise explicit definition later + template <typename X, typename Y> struct times + { + typedef polynomial type; + }; + + template <typename Y> struct times<cached, Y> + { + typedef Y type; + }; + + template <typename Y> struct times<constant, Y> + { + typedef Y type; + }; + + template <> struct times<log_n, log_n> + { + typedef polylog_n type; + }; + + template <> struct times<log_n, polylog_n> : times<log_n, log_n> {}; + + template <> struct times<log_n, linear_cached> + { + typedef n_log_n type; + }; + + template <> struct times<log_n, linear> : times<log_n, linear_cached> {}; + + template <> struct times<log_n, n_log_n> + { + typedef n_polylog_n type; + }; + + template <> struct times<log_n, n_polylog_n> : times<log_n, n_log_n> {}; + + template <> struct times<polylog_n, polylog_n> + { + typedef polylog_n type; + }; + + template <> struct times<polylog_n, linear_cached> + { + typedef n_polylog_n type; + }; + + template <> struct times<polylog_n, linear> : times<polylog_n, linear_cached> {}; + + template <> struct times<polylog_n, n_log_n> : times<polylog_n, linear_cached> {}; + + template <> struct times<polylog_n, n_polylog_n> : times<polylog_n, linear_cached> {}; + + template <> struct times<linear_cached, linear_cached> + { + typedef quadratic type; + }; + + template <> struct times<linear_cached, linear> : times<linear_cached, linear_cached> {}; + + template <> struct times<linear, linear> : times<linear_cached, linear_cached> {}; + +} // namespace detail + +/// Product of complexities +// Multiplication needs to be defined explicitly +// At least is symmetric, so we only consider X <= Y +template <typename X, typename Y> +struct times + : boost::mpl::if_< + boost::mpl::less<X, Y> + , detail::times<X, Y> + , detail::times<Y, X> + >::type +{}; + +// Specializations on second argument (if were ordered) +// Done here to avoid ambiguities + +template <typename X> +struct times<X, infinite> +{ + typedef infinite type; +}; + +template <typename X> struct times<infinite, X> : times<X, infinite> {}; + +}} // namespace mtl::complexity + +#define MTL_PRINT_COMPLEXITY(TYPE, STRING) \ +inline std::ostream& operator<< (std::ostream& os, mtl::complexity_classes::TYPE) \ +{ \ + return os << STRING; \ +} + +MTL_PRINT_COMPLEXITY(cached, "cached constant complexity") +MTL_PRINT_COMPLEXITY(constant, "constant complexity") +MTL_PRINT_COMPLEXITY(log_n, "logarithmic complexity") +MTL_PRINT_COMPLEXITY(polylog_n, "poly-logarithmic complexity") +MTL_PRINT_COMPLEXITY(linear_cached, "cached linear complexity") +MTL_PRINT_COMPLEXITY(linear, "linear complexity") +MTL_PRINT_COMPLEXITY(n_log_n, "n log n complexity") +MTL_PRINT_COMPLEXITY(n_polylog_n, "n poly-log n complexity") +MTL_PRINT_COMPLEXITY(quadratic, "quadratic complexity") +MTL_PRINT_COMPLEXITY(polynomial, "polynomial complexity") +MTL_PRINT_COMPLEXITY(infinite, "infinite complexity") + + + +#endif // MTL_COMPLEXITY_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/compose_view.hpp b/install/MTL/include/boost/numeric/mtl/utility/compose_view.hpp new file mode 100644 index 00000000..3917669e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/compose_view.hpp @@ -0,0 +1,65 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_COMPOSE_VIEW_INCLUDE +#define MTL_TRAITS_COMPOSE_VIEW_INCLUDE + +#include <boost/type_traits/remove_reference.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/utility/is_what.hpp> + +namespace mtl { namespace traits { + +/// Compose matrix view from code and matrix type +template <unsigned Code, typename Matrix> +struct matrix_compose_view +{ + MTL_STATIC_ASSERT(Code <= 7, "Illegal ViewCode!"); + typedef typename boost::remove_reference<typename matrix_compose_view<Code & 1, Matrix>::type>::type matrix_type; + + typedef typename boost::mpl::if_c< + (Code >= 6), + mtl::mat::hermitian_view<matrix_type>, + typename boost::mpl::if_c< + (Code >= 4), + mtl::mat::transposed_view<matrix_type>, + mtl::mat::conj_view<matrix_type> + >::type + >::type type; +}; + +template <typename Matrix> +struct matrix_compose_view<0, Matrix> +{ + typedef Matrix& type; +}; + +template <typename Matrix> +struct matrix_compose_view<1, Matrix> +{ + typedef const Matrix& type; +}; + +// Add vector stuff + +/// Compose view from code and collection type (matrix or vector) +template <unsigned Code, typename Collection> +struct compose_view + : matrix_compose_view<Code, Collection> +{ + MTL_STATIC_ASSERT(is_matrix<Collection>::value, "Currently only matrices are supported."); +}; + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_COMPOSE_VIEW_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/copy_expression_const_ref_container.hpp b/install/MTL/include/boost/numeric/mtl/utility/copy_expression_const_ref_container.hpp new file mode 100644 index 00000000..e534e9a5 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/copy_expression_const_ref_container.hpp @@ -0,0 +1,78 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_COPY_EXPRESSION_CONST_REF_CONTAINER_INCLUDE +#define MTL_TRAITS_COPY_EXPRESSION_CONST_REF_CONTAINER_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace traits { + +/// Type trait that defines the type itself for expressions and a const reference otherwise +/** Needed for re-constructed expression templates because references to expression are + often invalid. **/ +template <typename Container> +struct copy_expression_const_ref_container +{ + typedef const Container& type; +}; + + +template <class E1, class E2, typename SFunctor> +struct copy_expression_const_ref_container< mtl::vec::vec_vec_pmop_expr<E1, E2, SFunctor> > +{ + typedef mtl::vec::vec_vec_pmop_expr<E1, E2, SFunctor> type; +}; + +template <class E1, class E2, typename SFunctor> +struct copy_expression_const_ref_container< mtl::vec::vec_vec_aop_expr<E1, E2, SFunctor> > +{ + typedef mtl::vec::vec_vec_aop_expr<E1, E2, SFunctor> type; +}; + +template <typename Functor, typename Vector> +struct copy_expression_const_ref_container< mtl::vec::map_view<Functor, Vector> > +{ + typedef mtl::vec::map_view<Functor, Vector> type; +}; + +template <typename Scaling, typename Vector> +struct copy_expression_const_ref_container< mtl::vec::scaled_view<Scaling, Vector> > +{ + typedef mtl::vec::scaled_view<Scaling, Vector> type; +}; + +template <typename Vector, typename RScaling> +struct copy_expression_const_ref_container< mtl::vec::rscaled_view<Vector, RScaling> > +{ + typedef mtl::vec::rscaled_view<Vector, RScaling> type; +}; + +template <typename Vector, typename Divisor> +struct copy_expression_const_ref_container< mtl::vec::divide_by_view<Vector, Divisor> > +{ + typedef mtl::vec::divide_by_view<Vector, Divisor> type; +}; + +template <typename Vector> +struct copy_expression_const_ref_container< mtl::vec::conj_view<Vector> > +{ + typedef mtl::vec::conj_view<Vector> type; +}; + + + + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_COPY_EXPRESSION_CONST_REF_CONTAINER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/dense_el_cursor.hpp b/install/MTL/include/boost/numeric/mtl/utility/dense_el_cursor.hpp new file mode 100644 index 00000000..9fbd2497 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/dense_el_cursor.hpp @@ -0,0 +1,53 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_DENSE_EL_CURSOR_INCLUDE +#define MTL_DENSE_EL_CURSOR_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/detail/base_cursor.hpp> + +namespace mtl { + +/// Cursor over every element of matrix, matrix row/column, or vector +template <typename Value> +struct dense_el_cursor : public detail::base_cursor<const Value*> +{ + typedef Value value_type; + typedef const value_type* const_pointer_type; // ? + typedef detail::base_cursor<const Value*> super; + + typedef dense_el_cursor self; + + dense_el_cursor () {} + dense_el_cursor (const_pointer_type me) : super(me) {} + dense_el_cursor (super s) : super(s) {} + + template <typename Parameters> + dense_el_cursor(mtl::mat::dense2D<Value, Parameters> const& ma, size_t r, size_t c) + : super(ma.elements() + ma.indexer(ma, r, c)) + {} + + self operator+(int x) const + { + return self(super::operator+(x)); + } + + int operator-(self const& x) + { + return super::operator-(x); + } +}; + +} // namespace mtl + +#endif // MTL_DENSE_EL_CURSOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/different_non_complex.hpp b/install/MTL/include/boost/numeric/mtl/utility/different_non_complex.hpp new file mode 100644 index 00000000..8558c671 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/different_non_complex.hpp @@ -0,0 +1,34 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_DIFFERENT_NON_COMPLEX_INCLUDE +#define MTL_TRAITS_DIFFERENT_NON_COMPLEX_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/type_traits/is_complex.hpp> +#include <boost/type_traits/is_scalar.hpp> + + +namespace mtl { namespace traits { + +/// Type trait for different non-complex scalars, i.e. pairs of scalars whose complex equivalents are not supported in binary operations +template <typename T, typename U> +struct different_non_complex + : boost::mpl::bool_< !boost::is_same<T, U>::value && !boost::is_complex<T>::value && !boost::is_complex<U>::value + && boost::is_scalar<T>::value && boost::is_scalar<U>::value> +{}; + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_DIFFERENT_NON_COMPLEX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/domain.hpp b/install/MTL/include/boost/numeric/mtl/utility/domain.hpp new file mode 100644 index 00000000..2abb249e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/domain.hpp @@ -0,0 +1,40 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_DOMAIN_INCLUDE +#define MTL_TRAITS_DOMAIN_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/enable_if.hpp> + +namespace mtl { namespace traits { + +// Helper +template <typename Matrix, bool IsMatrix> +struct domain_aux {}; + +template <typename Matrix> +struct domain_aux<Matrix, true> +{ + typedef mtl::vec::dense_vector<typename Collection<Matrix>::value_type, vec::parameters<> > type; +}; + +/// Type trait returning domain type of linear operator (matrix) +template <typename Matrix> +struct domain + : domain_aux<Matrix, is_matrix<Matrix>::value> +{}; + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_DOMAIN_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/enable_if.hpp b/install/MTL/include/boost/numeric/mtl/utility/enable_if.hpp new file mode 100644 index 00000000..3e070ef6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/enable_if.hpp @@ -0,0 +1,53 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ENABLE_IF_INCLUDE +#define MTL_ENABLE_IF_INCLUDE + +#include <boost/utility/enable_if.hpp> +#include <boost/numeric/mtl/utility/is_what.hpp> + +namespace mtl { namespace traits { + +template <typename Value, typename Type = void> +struct enable_if_matrix + : boost::enable_if<is_matrix<Value>, Type> +{}; + +template <typename Value, typename Type = void> +struct enable_if_vector + : boost::enable_if<is_vector<Value>, Type> +{}; + +template <typename Value, typename Type = void> +struct enable_if_scalar + : boost::enable_if<is_scalar<Value>, Type> +{}; + +template <typename Value, typename Type> +struct lazy_enable_if_matrix + : boost::lazy_enable_if<is_matrix<Value>, Type> +{}; + +template <typename Value, typename Type> +struct lazy_enable_if_vector + : boost::lazy_enable_if<is_vector<Value>, Type> +{}; + +template <typename Value, typename Type> +struct lazy_enable_if_scalar + : boost::lazy_enable_if<is_scalar<Value>, Type> +{}; + +}} // namespace mtl + +#endif // MTL_ENABLE_IF_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/eval.hpp b/install/MTL/include/boost/numeric/mtl/utility/eval.hpp new file mode 100644 index 00000000..bc39d2af --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/eval.hpp @@ -0,0 +1,173 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_EVAL_INCLUDE +#define MTL_TRAITS_EVAL_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/matrix/crtp_base_matrix.hpp> +#include <boost/numeric/mtl/matrix/mat_expr.hpp> + +namespace mtl { namespace traits { + + +template <typename T> +struct eval {}; + +#if 0 // To be done later +template <typename Value, typename Parameter> +struct eval< mtl::dense_vector<Value, Parameter> > +{}; + + +template <typename Value1, typename Vector> +struct eval< mtl::scaled_view<Value1, Vector> > +{}; + +template <typename Value1, typename Vector> +struct eval< mtl::rscaled_view<Value1, Vector> > +{}; +#endif + + + namespace impl { + + template<typename T> + struct eval_self_ref + { + typedef const T& const_reference; + + explicit eval_self_ref(const T& ref) : ref(ref) {} + + const_reference value() const { return ref; } + + const T& ref; + }; + } + + +template <typename Value, typename Parameter> +struct eval< mtl::mat::dense2D<Value, Parameter> > + : public impl::eval_self_ref< mtl::mat::dense2D<Value, Parameter> > +{ + eval(const mtl::mat::dense2D<Value, Parameter>& ref) + : impl::eval_self_ref< mtl::mat::dense2D<Value, Parameter> >(ref) + {} +}; + +template <typename Value, std::size_t Mask, typename Parameter> +struct eval< mtl::mat::morton_dense<Value, Mask, Parameter> > + : public impl::eval_self_ref< mtl::mat::morton_dense<Value, Mask, Parameter> > +{ + eval(const mtl::mat::morton_dense<Value, Mask, Parameter>& ref) + : impl::eval_self_ref< mtl::mat::morton_dense<Value, Mask, Parameter> >(ref) + {} +}; + +template <typename Value, typename Parameter> +struct eval< mtl::mat::compressed2D<Value, Parameter> > + : public impl::eval_self_ref< mtl::mat::compressed2D<Value, Parameter> > +{ + eval(const mtl::mat::compressed2D<Value, Parameter>& ref) + : impl::eval_self_ref< mtl::mat::compressed2D<Value, Parameter> >(ref) + {} +}; + + + + +#if 0 // only dummy +template <typename E1, typename E2> +struct eval< mtl::mat::mat_mat_asgn_expr<E1, E2> > +{}; +#endif + + +template <typename E1, typename E2> +struct eval< mtl::mat::mat_mat_plus_expr<E1, E2> > + : public impl::eval_self_ref< mtl::mat::mat_mat_plus_expr<E1, E2> > +{ + eval(const mtl::mat::mat_mat_plus_expr<E1, E2>& ref) + : impl::eval_self_ref< mtl::mat::mat_mat_plus_expr<E1, E2> >(ref) + {} +}; + +template <typename E1, typename E2> +struct eval< mtl::mat::mat_mat_minus_expr<E1, E2> > + : public impl::eval_self_ref< mtl::mat::mat_mat_minus_expr<E1, E2> > +{ + eval(const mtl::mat::mat_mat_minus_expr<E1, E2>& ref) + : impl::eval_self_ref< mtl::mat::mat_mat_minus_expr<E1, E2> >(ref) + {} +}; + +template <typename E1, typename E2> +struct eval< mtl::mat::mat_mat_ele_times_expr<E1, E2> > + : public impl::eval_self_ref< mtl::mat::mat_mat_ele_times_expr<E1, E2> > +{ + eval(const mtl::mat::mat_mat_ele_times_expr<E1, E2>& ref) + : impl::eval_self_ref< mtl::mat::mat_mat_ele_times_expr<E1, E2> >(ref) + {} +}; + + +template <typename E1, typename E2> +struct eval< mtl::mat::mat_mat_times_expr<E1, E2> > +{ + // Needs dramatic improvement!!! Only for testing!!! + typedef mat::dense2D<double> matrix_type; + typedef const matrix_type& const_reference; + + + explicit eval(const mtl::mat::mat_mat_times_expr<E1, E2>& expr) + : prod(expr.first * expr.second) + {} + + const_reference value() { return prod; } + +private: + matrix_type prod; +}; + + + + +template <typename Value1, typename Matrix> +struct eval< mtl::mat::scaled_view<Value1, Matrix> > +{}; + +template <typename Value1, typename Matrix> +struct eval< mtl::mat::rscaled_view<Value1, Matrix> > +{}; + + +template <typename T> +eval<T> inline evaluate(const T& ref) +{ + return eval<T>(ref); +} + + +} // namespace traits + +namespace mat { + using mtl::traits::evaluate; +} + +namespace vec { + using mtl::traits::evaluate; +} + + +} // namespace mtl + +#endif // MTL_TRAITS_EVAL_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/eval_dense.hpp b/install/MTL/include/boost/numeric/mtl/utility/eval_dense.hpp new file mode 100644 index 00000000..7be8f394 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/eval_dense.hpp @@ -0,0 +1,109 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_EVAL_DENSE_INCLUDE +#define MTL_TRAITS_EVAL_DENSE_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace traits { + + +template <typename T> +struct eval_dense + : boost::mpl::false_ +{}; + +template <typename Value, typename Parameter> +struct eval_dense< mtl::vec::dense_vector<Value, Parameter> > + : boost::mpl::true_ +{}; + +template <typename Value, typename Parameter> +struct eval_dense< mtl::mat::dense2D<Value, Parameter> > + : boost::mpl::true_ +{}; + +template <typename Value, std::size_t Mask, typename Parameter> +struct eval_dense< mtl::mat::morton_dense<Value, Mask, Parameter> > + : boost::mpl::true_ +{}; + + + +template <typename Value1, typename Vector> +struct eval_dense< mtl::vec::scaled_view<Value1, Vector> > + : eval_dense<Vector> +{}; + +template <typename Value1, typename Vector> +struct eval_dense< mtl::vec::rscaled_view<Value1, Vector> > + : eval_dense<Vector> +{}; + + + +template <typename E1, typename E2> +struct eval_dense< mtl::mat::mat_mat_asgn_expr<E1, E2> > + : boost::mpl::bool_< eval_dense<E1>::value && eval_dense<E2>::value > +{}; + +template <typename E1, typename E2> +struct eval_dense< mtl::mat::mat_mat_plus_expr<E1, E2> > + : boost::mpl::bool_< eval_dense<E1>::value && eval_dense<E2>::value > +{}; + +template <typename E1, typename E2> +struct eval_dense< mtl::mat::mat_mat_minus_expr<E1, E2> > + : boost::mpl::bool_< eval_dense<E1>::value && eval_dense<E2>::value > +{}; + +template <typename E1, typename E2> +struct eval_dense< mtl::mat::mat_mat_ele_times_expr<E1, E2> > + : boost::mpl::bool_< eval_dense<E1>::value && eval_dense<E2>::value > +{}; + +template <typename Value1, typename Matrix> +struct eval_dense< mtl::mat::scaled_view<Value1, Matrix> > + : eval_dense<Matrix> +{}; + +template <typename Matrix> +struct eval_dense< mtl::mat::negate_view<Matrix > > + : eval_dense<Matrix> +{}; + +template <typename Matrix> +struct eval_dense< mtl::mat::real_view<Matrix > > + : eval_dense<Matrix> +{}; + +template <typename Matrix> +struct eval_dense< mtl::mat::imag_view<Matrix > > + : eval_dense<Matrix> +{}; + +template <typename Functor, typename Matrix> +struct eval_dense< mtl::mat::map_view<Functor, Matrix > > + : eval_dense<Matrix> +{}; + +template <typename Value1, typename Matrix> +struct eval_dense< mtl::mat::rscaled_view<Value1, Matrix> > + : eval_dense<Matrix> +{}; + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_EVAL_DENSE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/exception.hpp b/install/MTL/include/boost/numeric/mtl/utility/exception.hpp new file mode 100644 index 00000000..95f3d070 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/exception.hpp @@ -0,0 +1,243 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MTL_EXCEPTION_INCLUDE +#define MTL_MTL_EXCEPTION_INCLUDE + +#include <cassert> +#include <stdexcept> + +namespace mtl { + +#ifndef NDEBUG +# define MTL_DEBUG_ARG(Arg) Arg +#else +# define MTL_DEBUG_ARG(Arg) +#endif + +#ifndef MTL_ASSERT_FOR_THROW +# define MTL_THROW_ARG(Arg) Arg +#else +# define MTL_THROW_ARG(Arg) +#endif + +// If MTL_ASSERT_FOR_THROW is defined all throws become assert +// MTL_DEBUG_THROW_IF completely disappears if NDEBUG is defined +#ifndef NDEBUG +# ifdef MTL_ASSERT_FOR_THROW +# define MTL_DEBUG_THROW_IF(Test, Exception) \ + { assert(!(Test)); } +# else +# define MTL_DEBUG_THROW_IF(Test, Exception) \ + { if (Test) throw Exception; } +# endif +#else +# define MTL_DEBUG_THROW_IF(Test,Exception) +#endif + + +#if defined(MTL_ASSERT_FOR_THROW) && !defined(NDEBUG) +# define MTL_THROW_IF(Test, Exception) \ + { \ + assert(!(Test)); \ + } +#else +# define MTL_THROW_IF(Test, Exception) \ + { \ + if (Test) throw Exception; \ + } +#endif + + +#if defined(MTL_ASSERT_FOR_THROW) && !defined(NDEBUG) +# define MTL_THROW(Exception) \ + { \ + assert(0); \ + } +#else +# define MTL_THROW(Exception) \ + { \ + throw Exception; \ + } +#endif + + +#if 0 +standard errors: + +exception + logic_error + domain_error + invalid_argument + length_error + out_of_range + runtime_error + range_error + overflow_error + underflow_error +bad_alloc +bad_cast +bad_exception +bad_typeid + +#endif + +/// Exception for indices out of range +struct index_out_of_range : public std::out_of_range +{ + /// Error can be specified more precisely in constructor if desired + explicit index_out_of_range(const char *s= "Index out of range") : std::out_of_range(s) {} +}; + +/// Exception for invalid range definitions, esp. in constructors +struct range_error : public std::range_error +{ + /// Error can be specified more precisely in constructor if desired + explicit range_error(const char *s= "Invalid range") : std::range_error(s) {} +}; + +/// Domain errors in MTL4 +struct domain_error : public std::domain_error +{ + /// Error can be specified more precisely in constructor if desired + explicit domain_error(const char *s= "MTL4 domain error.") : std::domain_error(s) {} +}; + +/// Exception for arguments with incompatible sizes +struct incompatible_size : public domain_error +{ + /// Error can be specified more precisely in constructor if desired + explicit incompatible_size(const char *s= "Arguments have incompatible size.") + : domain_error(s) {} +}; + +/// Exception for arguments that shall not be empty +struct need_nonempty : public domain_error +{ + /// Error can be specified more precisely in constructor if desired + explicit need_nonempty(const char *s= "Argument must be non-empty.") + : domain_error(s) {} +}; + +/// Exception for trying to change a fixed size (to another value) +struct change_static_size : public domain_error +{ + /// Error can be specified more precisely in constructor if desired + explicit change_static_size(const char *s= "You try to change a fixed size (to another value).") + : domain_error(s) {} +}; + +/// Exception for arguments with incompatible shapes, e.g. adding matrices and vectors +struct argument_result_conflict : public domain_error +{ + /// Error can be specified more precisely in constructor if desired + explicit argument_result_conflict(const char *s= "Used same object illegally as argument and result.") + : domain_error(s) {} +}; + +/// Exception for arguments with incompatible shapes, e.g. adding matrices and vectors +struct incompatible_shape : public domain_error +{ + /// Error can be specified more precisely in constructor if desired + explicit incompatible_shape(const char *s= "Arguments have incompatible shape.") + : domain_error(s) {} +}; + +/// Exception for arguments with incompatible sizes +struct matrix_not_square : public domain_error +{ + /// Error can be specified more precisely in constructor if desired + explicit matrix_not_square(const char *s= "Matrix must be square for this operation.") + : domain_error(s) {} +}; + +/// Exception for matrices too small for certain algorithms +struct matrix_too_small : public domain_error +{ + /// Error can be specified more precisely in constructor if desired + explicit matrix_too_small(const char *s= "Matrix is too small for certain algorithms.") + : domain_error(s) {} +}; + +/// Exception for singular matrices in solvers +struct matrix_singular : public domain_error +{ + /// Error can be specified more precisely in constructor if desired + explicit matrix_singular(const char *s= "Matrix singular in solver.") + : domain_error(s) {} +}; + +/// Exception for arguments with incompatible sizes +struct missing_diagonal : public domain_error +{ + /// Error can be specified more precisely in constructor if desired + explicit missing_diagonal(const char *s= "Diagonal entry missing or not where it belongs to.") + : domain_error(s) {} +}; + +/// Accessing (illegally) matrix or vector during insertion phase (dense non-distributed can be accessed always) +struct access_during_insertion : public domain_error +{ + /// Error can be specified more precisely in constructor if desired + explicit access_during_insertion(const char *s= "Diagonal entry missing.") + : domain_error(s) {} +}; + +/// Exception for a result that is not what it should be +struct unexpected_result : public domain_error +{ + /// Error can be specified more precisely in constructor if desired + explicit unexpected_result(const char *s= "The result of an operation is not the expected one.") + : domain_error(s) {} +}; + +/// Exception for run-time errors that doesn't fit into specific categories +struct runtime_error : public std::runtime_error +{ + /// Error can be specified more precisely in constructor if desired + explicit runtime_error(const char *s= "Run-time error") : std::runtime_error(s) {} +}; + +struct division_by_zero : mtl::runtime_error +{ + /// Error can be specified more precisely in constructor if desired + explicit division_by_zero(const char *s= "Division by zero") : runtime_error(s) {} +}; + + +/// Exception for logic errors that doesn't fit into specific categories +struct logic_error : public std::logic_error +{ + /// Error can be specified more precisely in constructor if desired + explicit logic_error(const char *s= "Logic error") : std::logic_error(s) {} +}; + +/// Exception for I/O errors in general +struct io_error : public std::runtime_error +{ + /// Error can be specified more precisely in constructor if desired + explicit io_error(const char *s= "I/O error") : std::runtime_error(s) {} +}; + +/// File not found +struct file_not_found : public io_error +{ + /// Error can be specified more precisely in constructor if desired + explicit file_not_found(const char *s= "File not found") : io_error(s) {} +}; + + + + +} // namespace mtl + +#endif // MTL_MTL_EXCEPTION_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/extended_complex.hpp b/install/MTL/include/boost/numeric/mtl/utility/extended_complex.hpp new file mode 100644 index 00000000..7a5ebc31 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/extended_complex.hpp @@ -0,0 +1,44 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_EXTENDED_COMPLEX_INCLUDE +#define MTL_TRAITS_EXTENDED_COMPLEX_INCLUDE + +#include <complex> +#include <boost/numeric/mtl/utility/different_non_complex.hpp> +#include <boost/numeric/mtl/concept/std_concept.hpp> + +namespace mtl { namespace traits { + + +template <typename T, typename U, bool enable> +struct extended_complex_aux +{}; + +template <typename T, typename U> +struct extended_complex_aux<T, U, true> +{ + typedef std::complex<typename mtl::Addable<T, U>::result_type> type; +}; + + +/// Result type of extended complex binary arithmetic +/** If operation already exist in standard or non-complex are incompatible \p type does not exist. + extended_complex<T,U>::type is an implicit enable_if and avoids ambiguities. **/ +template <typename T, typename U> +struct extended_complex + : extended_complex_aux<T, U, different_non_complex<T, U>::value > +{}; + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_EXTENDED_COMPLEX_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/fast_multi_vector_expr.hpp b/install/MTL/include/boost/numeric/mtl/utility/fast_multi_vector_expr.hpp new file mode 100644 index 00000000..559c0d59 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/fast_multi_vector_expr.hpp @@ -0,0 +1,90 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_FAST_MULTI_VECTOR_EXPR_INCLUDE +#define MTL_TRAITS_FAST_MULTI_VECTOR_EXPR_INCLUDE + +namespace mtl { namespace traits { + + +/// Type trait whether an expression can be evaluated by a single vector operation +template <typename T> +struct fast_multi_vector_expr +{}; + +template <typename Vector> +struct fast_multi_vector_expr< mtl::mat::multi_vector<Vector> > +{ + typedef Vector type; +}; + +// template <typename Vector> +// struct fast_multi_vector_expr< const mtl::mat::multi_vector<Vector> > +// { +// typedef const Vector type; +// }; + +// template <typename E1, typename E2> +// struct fast_multi_vector_expr< mtl::mat::mat_mat_asgn_expr<E1, E2> > +// : boost::mpl::bool_< fast_multi_vector_expr<E1>::value && fast_multi_vector_expr<E2>::value > +// {}; + +template <typename E1, typename E2> +struct fast_multi_vector_expr< mtl::mat::mv_mv_plus_expr<E1, E2> > +{ + typedef typename fast_multi_vector_expr<E1>::type V1; + typedef typename fast_multi_vector_expr<E2>::type V2; + typedef typename mtl::sfunctor::plus<typename V1::value_type, typename V2::value_type> Functor; + + typedef mtl::vec::vec_vec_pmop_expr<V1, V2, Functor> type; +}; + +template <typename E1, typename E2> +struct fast_multi_vector_expr< mtl::mat::mat_mat_minus_expr<E1, E2> > +{ + typedef typename fast_multi_vector_expr<E1>::type V1; + typedef typename fast_multi_vector_expr<E2>::type V2; + typedef typename mtl::sfunctor::minus<typename V1::value_type, typename V2::value_type> Functor; + + typedef mtl::vec::vec_vec_pmop_expr<V1, V2, Functor> type; +}; + +// template <typename E1, typename E2> +// struct fast_multi_vector_expr< mtl::mat::mat_mat_ele_times_expr<E1, E2> > +// { +// typedef mtl::mat::mv_mv_ele_times_expr<typename fast_multi_vector_expr<E1>::type, +// typename fast_multi_vector_expr<E2>::type> type; +// }; + +template <typename Functor, typename Matrix> +struct fast_multi_vector_expr< mtl::mat::map_view<Functor, Matrix> > +{ + typedef mtl::vec::map_view<Functor, typename fast_multi_vector_expr<Matrix>::type> type; +}; + + +template <typename Value1, typename Matrix> +struct fast_multi_vector_expr< mtl::mat::scaled_view<Value1, Matrix> > +{ + typedef mtl::vec::scaled_view<Value1, typename fast_multi_vector_expr<Matrix>::type> type; +}; + +template <typename Value1, typename Matrix> +struct fast_multi_vector_expr< mtl::mat::rscaled_view<Value1, Matrix> > +{ + typedef mtl::vec::rscaled_view<Value1, typename fast_multi_vector_expr<Matrix>::type> type; +}; + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_FAST_MULTI_VECTOR_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/flatcat.hpp b/install/MTL/include/boost/numeric/mtl/utility/flatcat.hpp new file mode 100644 index 00000000..390a3bbf --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/flatcat.hpp @@ -0,0 +1,166 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_FLATCAT_INCLUDE +#define MTL_TRAITS_FLATCAT_INCLUDE + +#include <boost/mpl/if.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/type_traits/is_base_of.hpp> + +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> + +namespace mtl { namespace traits { + + +template <typename C, typename U1> +struct flatcat1_c + : boost::mpl::if_<boost::is_base_of<U1, C>, + tag::flat<U1>, + tag::universe + >::type +{}; + +template <typename T, typename U1> +struct flatcat1 + : flatcat1_c<typename category<T>::type, U1> {}; + +template <typename C, typename U1, typename U2> +struct flatcat2_c + : boost::mpl::if_<boost::is_base_of<U1, C>, + tag::flat<U1>, + flatcat1_c<C, U2> + >::type +{}; + +template <typename T, typename U1, typename U2> +struct flatcat2 + : flatcat2_c<typename category<T>::type, U1, U2> {}; + +template <typename C, typename U1, typename U2, typename U3> +struct flatcat3_c + : boost::mpl::if_<boost::is_base_of<U1, C>, + tag::flat<U1>, + flatcat2_c<C, U2, U3> + >::type +{}; + +template <typename T, typename U1, typename U2, typename U3> +struct flatcat3 + : flatcat3_c<typename category<T>::type, U1, U2, U3> {}; + + +template <typename C, typename U1, typename U2, typename U3, typename U4> +struct flatcat4_c + : boost::mpl::if_<boost::is_base_of<U1, C>, + tag::flat<U1>, + flatcat3_c<C, U2, U3, U4> + >::type +{}; + +template <typename T, typename U1, typename U2, typename U3, typename U4> +struct flatcat4 + : flatcat4_c<typename category<T>::type, U1, U2, U3, U4> {}; + + +template <typename C, typename U1, typename U2, typename U3, typename U4, typename U5> +struct flatcat5_c + : boost::mpl::if_<boost::is_base_of<U1, C>, + tag::flat<U1>, + flatcat4_c<C, U2, U3, U4, U5> + >::type +{}; + +template <typename T, typename U1, typename U2, typename U3, typename U4, typename U5> +struct flatcat5 + : flatcat5_c<typename category<T>::type, U1, U2, U3, U4, U5> {}; + +template <typename C, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6> +struct flatcat6_c + : boost::mpl::if_<boost::is_base_of<U1, C>, + tag::flat<U1>, + flatcat5_c<C, U2, U3, U4, U5, U6> + >::type +{}; + +template <typename T, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6> +struct flatcat6 + : flatcat6_c<typename category<T>::type, U1, U2, U3, U4, U5, U6> {}; + +template <typename C, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6, typename U7> +struct flatcat7_c + : boost::mpl::if_<boost::is_base_of<U1, C>, + tag::flat<U1>, + flatcat6_c<C, U2, U3, U4, U5, U6, U7> + >::type +{}; + +template <typename T, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6, typename U7> +struct flatcat7 + : flatcat7_c<typename category<T>::type, U1, U2, U3, U4, U5, U6, U7> {}; + + +// Some often reused flatcats: + +#if 0 +template <typename Matrix> +struct mat_cvec_flatcat + : flatcat7<Matrix, tag::element_structure, tag::sparse_banded_matrix, tag::transposed_multi_vector, tag::hermitian_multi_vector, tag::multi_vector, tag::dense, tag::sparse> +{}; +#endif + +template <typename Matrix> +struct mat_cvec_flatcat + : flatcat6<Matrix, tag::element_structure, tag::transposed_multi_vector, tag::hermitian_multi_vector, tag::multi_vector, tag::dense, tag::sparse> +{}; + +template <typename Collection> +struct shape_flatcat + : flatcat4<Collection, tag::matrix, tag::col_vector, tag::row_vector, tag::scalar> +{}; + +template <typename Collection> +struct sparsity_flatcat + : flatcat2<Collection, tag::dense, tag::sparse> +{}; + +template <typename Collection> +struct cursor_flatcat + : flatcat3<Collection, tag::has_fast_ra_cursor, tag::has_ra_cursor, tag::has_cursor> +{}; + +template <typename Collection> +struct iterator_flatcat + : flatcat3<Collection, tag::has_fast_ra_iterator, tag::has_ra_iterator, tag::has_iterator> +{}; + +template <typename Collection> +struct has_iterator_flatcat + : flatcat1<Collection, tag::has_iterator> +{}; + + +template <typename Collection> +struct layout_flatcat + : flatcat2<Collection, tag::has_2D_layout, tag::has_1D_layout> +{}; + + +template <typename Matrix> +struct sub_matrix_flatcat + : flatcat3<Matrix, tag::sub_divisible, tag::qsub_divisible, tag::has_sub_matrix> +{}; + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_FLATCAT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/glas_tag.hpp b/install/MTL/include/boost/numeric/mtl/utility/glas_tag.hpp new file mode 100644 index 00000000..2b6bed90 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/glas_tag.hpp @@ -0,0 +1,42 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef GLAS_GLAS_TAG_INCLUDE +#define GLAS_GLAS_TAG_INCLUDE + +#undef major + +namespace glas { namespace tag { + +// To iterate only over non-zero elements +struct nz {}; + +// To iterate over all elements +struct all {}; + +// To iterate over rows +// Generated cursors must provide range generators +struct row {}; + +// To iterate over cols +// Generated cursors must provide range generators +struct col {}; + +// To iterate over the major dimension of matrices (like MTL 2) +struct major {}; + +// Same with minor +struct minor {}; + +}} // namespace glas::tag + +#endif // GLAS_GLAS_TAG_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/gradient.hpp b/install/MTL/include/boost/numeric/mtl/utility/gradient.hpp new file mode 100644 index 00000000..4276ecc0 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/gradient.hpp @@ -0,0 +1,36 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_GRADIENT_INCLUDE +#define MTL_TRAITS_GRADIENT_INCLUDE + +#include <boost/mpl/if.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/linear_operator.hpp> + +namespace mtl { namespace traits { + +/// Type trait returning type for gradient of function with T as argument +template <typename T> +struct gradient + : boost::mpl::if_<is_scalar<T>, mtl::dense_vector<T>, tag::unknown> +{}; + +template <typename Value, typename Para> +struct gradient<mtl::dense_vector<Value, Para> > + : linear_operator<mtl::dense_vector<Value, Para>, mtl::dense_vector<Value, Para> > +{}; + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_GRADIENT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/index_evaluatable.hpp b/install/MTL/include/boost/numeric/mtl/utility/index_evaluatable.hpp new file mode 100644 index 00000000..372ea03a --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/index_evaluatable.hpp @@ -0,0 +1,116 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_INDEX_EVALUATABLE_INCLUDE +#define MTL_TRAITS_INDEX_EVALUATABLE_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/mpl/and.hpp> +#include <boost/mpl/or.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/is_vector_reduction.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +// Not elegant but necessary to treat ITL types right +#include <boost/numeric/itl/itl_fwd.hpp> + +namespace mtl { namespace traits { + +/// Type trait to check whether \p T can be evaluated index-wise (usually in lazy evaluation) +template <typename T> +struct index_evaluatable : boost::mpl::false_ {}; + +#ifndef MTL_WITH_OPENMP + +template <typename T, typename U, typename Assign> +struct index_evaluatable<lazy_assign<T, U, Assign> > + : boost::mpl::or_< + boost::mpl::and_<is_vector<T>, is_scalar<U> >, + boost::mpl::and_<is_vector<T>, is_vector<U> >, + boost::mpl::and_<is_scalar<T>, is_vector_reduction<U> > + > +{}; + +template <typename V1, typename Matrix, typename V2, typename Assign> +struct index_evaluatable<lazy_assign<V1, mtl::mat_cvec_times_expr<Matrix, V2>, Assign> > + : is_row_major<Matrix> {}; + +template <typename V1, typename Matrix, typename V2, typename Assign> +struct index_evaluatable<lazy_assign<V1, mtl::vec::mat_cvec_multiplier<Matrix, V2>, Assign> > + : boost::mpl::false_ +{}; + +template <typename T, typename U> +struct index_evaluatable<fused_expr<T, U> > + : boost::mpl::and_<index_evaluatable<T>, index_evaluatable<U> > +{}; + +#endif // not MTL_WITH_OPENMP + +/// Type trait to control whether evaluation should be unrolled +template <typename T> +struct unrolled_index_evaluatable : boost::mpl::false_ {}; + +#ifndef MTL_WITH_OPENMP + +template <typename T, typename U, typename Assign> +struct unrolled_index_evaluatable<lazy_assign<T, U, Assign> > + : boost::mpl::or_< + boost::mpl::and_<is_vector<T>, is_scalar<U> >, + boost::mpl::and_<is_vector<T>, is_vector<U> >, + boost::mpl::and_<is_scalar<T>, is_vector_reduction<U> > + > +{}; + +template <typename T, typename U> +struct unrolled_index_evaluatable<fused_expr<T, U> > + : boost::mpl::and_<unrolled_index_evaluatable<T>, unrolled_index_evaluatable<U> > +{}; + +#endif // not MTL_WITH_OPENMP + +/// Typetrait for forward evaluation +/** All index_evaluatable types are implicitly forward-evaluatable **/ +template <typename T> +struct forward_index_evaluatable + : index_evaluatable<T> +{}; + +/// Typetrait for backward evaluation +/** All index_evaluatable types are implicitly backward-evaluatable **/ +template <typename T> +struct backward_index_evaluatable + : index_evaluatable<T> +{}; + +#ifndef MTL_WITH_OPENMP + +template <typename V1, typename Matrix, typename Value, typename V2> +struct backward_index_evaluatable<lazy_assign<V1, itl::pc::solver<itl::pc::ic_0<Matrix, Value>, V2, true>, assign::assign_sum> > + : boost::mpl::true_ {}; + +template <typename V1, typename Matrix, typename Factorizer, typename Value, typename V2> +struct backward_index_evaluatable<lazy_assign<V1, itl::pc::solver<itl::pc::ilu<Matrix, Factorizer, Value>, V2, true>, assign::assign_sum> > + : boost::mpl::true_ {}; + +#endif // not MTL_WITH_OPENMP + +}} // namespace mtl::traits + + + + + +#endif // MTL_TRAITS_INDEX_EVALUATABLE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/index_evaluator.hpp b/install/MTL/include/boost/numeric/mtl/utility/index_evaluator.hpp new file mode 100644 index 00000000..864b1d90 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/index_evaluator.hpp @@ -0,0 +1,50 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_INDEX_EVALUATOR_INCLUDE +#define MTL_TRAITS_INDEX_EVALUATOR_INCLUDE + +#include <boost/mpl/if.hpp> +#include <boost/utility/enable_if.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/is_what.hpp> + +namespace mtl { namespace traits { + +/// Result type of index evaluation +template <typename T> +struct index_evaluator {}; + +template <typename T, typename U, typename Assign> +struct index_evaluator<lazy_assign<T, U, Assign> > + : boost::lazy_enable_if<is_vector<T>, + boost::mpl::if_<is_vector<U>, + mtl::vec::vec_vec_aop_expr<T, U, Assign>, + mtl::vec::vec_scal_aop_expr<T, U, Assign> + > + > +{}; + +// ... more + +template <typename T, typename U> +struct index_evaluator<fused_expr<T, U> > +{ + typedef mtl::vec::fused_index_evaluator<T, U> type; +}; + + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_INDEX_EVALUATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/irange.hpp b/install/MTL/include/boost/numeric/mtl/utility/irange.hpp new file mode 100644 index 00000000..5edb4e34 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/irange.hpp @@ -0,0 +1,124 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_IRANGE_INCLUDE +#define MTL_IRANGE_INCLUDE + +#include <limits> +#include <iostream> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/operation/is_negative.hpp> +#include <boost/numeric/mtl/detail/base_cursor.hpp> + + +namespace mtl { + + /// Maximal index + const std::size_t imax= std::numeric_limits<std::size_t>::max(); + + /// Class to define a half open index ranges + class irange + { + public: + + typedef std::size_t size_type; + typedef detail::base_cursor<size_type> cursor_type; + + /// Create an index range of [start, finish) + explicit irange(size_type start, size_type finish) : my_start(start), my_finish(finish) {} + + /// Create an index range of [0, finish) + explicit irange(size_type finish) : my_start(0), my_finish(finish) {} + + /// Create an index range of [0, imax), i.e. all indices + irange() : my_start(0), my_finish(imax) {} + + /// Set the index range to [start, finish) + irange& set(size_type start, size_type finish) + { + my_start= start; my_finish= finish; return *this; + } + + /// Set the index range of [0, finish) + irange& set(size_type finish) + { + my_start= 0; my_finish= finish; return *this; + } + + /// Decrease finish, i.e. [start, finish) -> [start, finish-1) + irange& operator--() + { + --my_finish; return *this; + } + + /// First index in range + size_type start() const { return my_start; } + /// Past-end index in range + size_type finish() const { return my_finish; } + /// Number of indices + size_type size() const { return my_finish > my_start ? my_finish - my_start : 0; } + + /// Whether the range is empty + bool empty() const { return my_finish <= my_start; } + + /// First index in range + cursor_type begin() const { return my_start; } + /// Past-end index in range + cursor_type end() const { return my_finish; } + + /// Maps integers [0, size()) to [start(), finish()) + /** Checks index in debug mode. Inverse of from_range. **/ + size_type to_range(size_type i) const + { + MTL_DEBUG_THROW_IF(is_negative(i) || i >= size(), index_out_of_range()); + return my_start + i; + } + + /// Maps integers [start(), finish()) to [0, size()) + /** Checks index in debug mode. **/ + size_type from_range(size_type i) const + { + MTL_DEBUG_THROW_IF(i < my_start || i >= my_finish, index_out_of_range()); + return i - my_start; + } + + /// Wether index is in range + bool in_range(size_type i) const + { + return i >= my_start && i < my_finish; + } + + friend std::ostream& operator<<(std::ostream& os, const irange& ir) + { return os << "mtl::irange(" << ir.my_start << ", " << ir.my_finish << ")"; } + + private: + size_type my_start, my_finish; + }; + /// All index in range + namespace { + // problems with multiple cpp projects, which include mtl multiple times + static const irange iall(0, imax); + //inline irange iall() { return irange(); } + } + + /// Intersection of two ranges + irange inline intersection(irange const& r1, irange const& r2) + { + return irange(std::max(r1.start(), r2.start()), std::min(r1.finish(), r2.finish())); + } + + +} // namespace mtl + + + +#endif // MTL_IRANGE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/is_composable_vector.hpp b/install/MTL/include/boost/numeric/mtl/utility/is_composable_vector.hpp new file mode 100644 index 00000000..f16e0d4b --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/is_composable_vector.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_IS_COMPOSABLE_VECTOR_INCLUDE +#define MTL_TRAITS_IS_COMPOSABLE_VECTOR_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace traits { + +template <typename T> +struct is_composable_vector + : boost::mpl::false_ +{}; + +template <typename Value, typename Parameters> +struct is_composable_vector< mtl::vec::dense_vector<Value, Parameters> > + : boost::mpl::true_ +{}; + + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_IS_COMPOSABLE_VECTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/is_distributed.hpp b/install/MTL/include/boost/numeric/mtl/utility/is_distributed.hpp new file mode 100644 index 00000000..1db6856a --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/is_distributed.hpp @@ -0,0 +1,31 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_IS_DISTRIBUTED_INCLUDE +#define MTL_TRAITS_IS_DISTRIBUTED_INCLUDE + +namespace mtl { namespace traits { + +template <typename T> +struct is_distributed_aux + : boost::mpl::false_ // by default false +{}; + +/// Meta-function whether a certain type is distributed +template <typename T> +struct is_distributed + : is_distributed_aux<typename root<T>::type> +{}; + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_IS_DISTRIBUTED_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/is_lazy.hpp b/install/MTL/include/boost/numeric/mtl/utility/is_lazy.hpp new file mode 100644 index 00000000..6b465cf0 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/is_lazy.hpp @@ -0,0 +1,36 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_IS_LAZY_INCLUDE +#define MTL_TRAITS_IS_LAZY_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/mpl/and.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace traits { + +/// Type trait for determining wether \p T is to be evaluated lazily +template <typename T> +struct is_lazy : boost::mpl::false_ {}; + +template <typename T, typename U, typename Assign> +struct is_lazy<lazy_assign<T, U, Assign> > : boost::mpl::true_ {}; + +template <typename T, typename U> +struct is_lazy<fused_expr<T, U> > + : boost::mpl::and_<is_lazy<T>, is_lazy<U> > +{}; + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_IS_LAZY_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/is_multi_vector_expr.hpp b/install/MTL/include/boost/numeric/mtl/utility/is_multi_vector_expr.hpp new file mode 100644 index 00000000..42577298 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/is_multi_vector_expr.hpp @@ -0,0 +1,111 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_IS_MULTI_VECTOR_EXPR_INCLUDE +#define MTL_TRAITS_IS_MULTI_VECTOR_EXPR_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/is_composable_vector.hpp> + +namespace mtl { namespace traits { + +/// Type trait whether an expression can be evaluated by multiple vector operations +template <typename T> +struct is_multi_vector_expr + : boost::mpl::false_ +{}; + +template <typename Vector> +struct is_multi_vector_expr< mtl::mat::multi_vector<Vector> > + : boost::mpl::true_ +{}; + +// template <typename E1, typename E2> +// struct is_multi_vector_expr< mtl::mat::mat_mat_asgn_expr<E1, E2> > +// : boost::mpl::bool_< is_multi_vector_expr<E1>::value && is_multi_vector_expr<E2>::value > +// {}; + +template <typename E1, typename E2> +struct is_multi_vector_expr< mtl::mat::mv_mv_plus_expr<E1, E2> > + : boost::mpl::bool_< is_multi_vector_expr<E1>::value && is_multi_vector_expr<E2>::value > +{}; + +template <typename E1, typename E2> +struct is_multi_vector_expr< mtl::mat::mat_mat_minus_expr<E1, E2> > + : boost::mpl::bool_< is_multi_vector_expr<E1>::value && is_multi_vector_expr<E2>::value > +{}; + +// template <typename E1, typename E2> +// struct is_multi_vector_expr< mtl::mat::mat_mat_ele_times_expr<E1, E2> > +// : boost::mpl::bool_< is_multi_vector_expr<E1>::value && is_multi_vector_expr<E2>::value > +// {}; + +template <typename Value1, typename Matrix> +struct is_multi_vector_expr< mtl::mat::scaled_view<Value1, Matrix> > + : is_multi_vector_expr<Matrix> +{}; + +template <typename Value1, typename Matrix> +struct is_multi_vector_expr< mtl::mat::rscaled_view<Value1, Matrix> > + : is_multi_vector_expr<Matrix> +{}; + +// ---------------------------------------------------- + + +/// Type trait whether an expression can be evaluated by a single vector operation +template <typename T> +struct is_fast_multi_vector_expr + : boost::mpl::false_ +{}; + +template <typename Vector> +struct is_fast_multi_vector_expr< mtl::mat::multi_vector<Vector> > + : is_composable_vector<Vector> +{}; + +// template <typename E1, typename E2> +// struct is_fast_multi_vector_expr< mtl::mat::mat_mat_asgn_expr<E1, E2> > +// : boost::mpl::bool_< is_fast_multi_vector_expr<E1>::value && is_fast_multi_vector_expr<E2>::value > +// {}; + +template <typename E1, typename E2> +struct is_fast_multi_vector_expr< mtl::mat::mv_mv_plus_expr<E1, E2> > + : boost::mpl::bool_< is_fast_multi_vector_expr<E1>::value && is_fast_multi_vector_expr<E2>::value > +{}; + +template <typename E1, typename E2> +struct is_fast_multi_vector_expr< mtl::mat::mat_mat_minus_expr<E1, E2> > + : boost::mpl::bool_< is_fast_multi_vector_expr<E1>::value && is_fast_multi_vector_expr<E2>::value > +{}; + +// template <typename E1, typename E2> +// struct is_fast_multi_vector_expr< mtl::mat::mat_mat_ele_times_expr<E1, E2> > +// : boost::mpl::bool_< is_fast_multi_vector_expr<E1>::value && is_fast_multi_vector_expr<E2>::value > +// {}; + +template <typename Value1, typename Matrix> +struct is_fast_multi_vector_expr< mtl::mat::scaled_view<Value1, Matrix> > + : is_fast_multi_vector_expr<Matrix> +{}; + +template <typename Value1, typename Matrix> +struct is_fast_multi_vector_expr< mtl::mat::rscaled_view<Value1, Matrix> > + : is_fast_multi_vector_expr<Matrix> +{}; + + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_IS_MULTI_VECTOR_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/is_row_major.hpp b/install/MTL/include/boost/numeric/mtl/utility/is_row_major.hpp new file mode 100644 index 00000000..0b2f7202 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/is_row_major.hpp @@ -0,0 +1,98 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_IS_ROW_MAJOR_INCLUDE +#define MTL_IS_ROW_MAJOR_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/mpl/not.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> + +namespace mtl { namespace traits { + + /// Meta-function whether a tag is row_major or col_major + /** For convenience, directly applicable to mat::parameter and parameter. + Refined from boost::mpl::true_ or boost::mpl::false_ if defined. + **/ + template <typename Parameter> + struct is_row_major {}; + + template <> + struct is_row_major<row_major> + : boost::mpl::true_ {}; + + template <> + struct is_row_major<col_major> + : boost::mpl::false_ {}; + + template <typename Dimension, bool OnStack, typename SizeType> + struct is_row_major<vec::parameters<row_major, Dimension, OnStack, SizeType> > + : boost::mpl::true_ {}; + + template <typename T> + struct is_row_major<const T> + : is_row_major<T> {}; + + template <typename Dimension, bool OnStack, typename SizeType> + struct is_row_major<vec::parameters<col_major, Dimension, OnStack, SizeType> > + : boost::mpl::false_ {}; + + template <typename Index, typename Dimension, bool OnStack, typename SizeType> + struct is_row_major<mat::parameters<row_major, Index, Dimension, OnStack, SizeType> > + : boost::mpl::true_ {}; + + template <typename Index, typename Dimension, bool OnStack, typename SizeType> + struct is_row_major<mat::parameters<col_major, Index, Dimension, OnStack, SizeType> > + : boost::mpl::false_ {}; + + template <typename Value, typename Parameters> + struct is_row_major<vec::dense_vector<Value, Parameters> > + : is_row_major<Parameters> {}; + + template <typename Value, typename Parameters> + struct is_row_major<vec::strided_vector_ref<Value, Parameters> > + : is_row_major<Parameters> {}; + + template <typename Value, typename Parameters> + struct is_row_major<mtl::mat::compressed2D<Value, Parameters> > + : is_row_major<Parameters> {}; + + template <typename Value, typename Parameters> + struct is_row_major<mtl::mat::ell_matrix<Value, Parameters> > + : is_row_major<Parameters> {}; + + template <typename Value, typename Parameters> + struct is_row_major<mtl::mat::dense2D<Value, Parameters> > + : is_row_major<Parameters> {}; + + template <typename Value, std::size_t Mask, typename Parameters> + struct is_row_major<mtl::mat::morton_dense<Value, Mask, Parameters> > + : is_row_major<Parameters> {}; + + template <typename Matrix> + struct is_row_major<mat::banded_view<Matrix> > + : is_row_major<Matrix> {}; + + template <typename Matrix> + struct is_row_major<mat::transposed_view<Matrix> > + : boost::mpl::not_<is_row_major<Matrix> > {}; + + template <typename Matrix> + struct is_row_major<mat::hermitian_view<Matrix> > + : boost::mpl::not_<is_row_major<Matrix> > {}; + +}} // namespace mtl::traits + +#endif // MTL_IS_ROW_MAJOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/is_static.hpp b/install/MTL/include/boost/numeric/mtl/utility/is_static.hpp new file mode 100644 index 00000000..a951105c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/is_static.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_IS_STATIC_INCLUDE +#define MTL_TRAITS_IS_STATIC_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace traits { + + /// Meta-function whether a certain type has static size + template <typename T> struct is_static : boost::mpl::false_ {}; + + template <std::size_t Size> struct is_static<mtl::vec::fixed::dimension<Size> > : boost::mpl::true_ {}; + template <std::size_t Rows, std::size_t Cols> struct is_static<mtl::fixed::dimensions<Rows, Cols> > : boost::mpl::true_ {}; + + template <typename V, typename P> struct is_static<mtl::vec::dense_vector<V, P> > : is_static<typename P::dimension> {}; + + template <typename V, typename P> struct is_static<mtl::mat::dense2D<V, P> > : is_static<typename P::dimensions> {}; + template <typename V, std::size_t M, typename P> struct is_static<mtl::mat::morton_dense<V, M, P> > : is_static<typename P::dimensions> {}; + template <typename V, typename P> struct is_static<mtl::mat::compressed2D<V, P> > : is_static<typename P::dimensions> {}; + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_IS_STATIC_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/is_vector_reduction.hpp b/install/MTL/include/boost/numeric/mtl/utility/is_vector_reduction.hpp new file mode 100644 index 00000000..f8c8e5c4 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/is_vector_reduction.hpp @@ -0,0 +1,37 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_IS_VECTOR_REDUCTION_INCLUDE +#define MTL_TRAITS_IS_VECTOR_REDUCTION_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/mpl/bool.hpp> + +namespace mtl { namespace traits { + +/// Type trait to check whether \p T is a vector reduction (i.e. an ET class for its lazy evaluation) +template <typename T> +struct is_vector_reduction : boost::mpl::false_ {}; + +template <unsigned long Unroll, typename Vector1, typename Vector2, typename ConjOpt> +struct is_vector_reduction<mtl::vec::dot_class<Unroll, Vector1, Vector2, ConjOpt> > + : boost::mpl::true_ {}; + +template<typename Vector, typename Functor> +struct is_vector_reduction<mtl::vec::lazy_reduction<Vector, Functor> > + : boost::mpl::true_ {}; + + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_IS_VECTOR_REDUCTION_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/is_what.hpp b/install/MTL/include/boost/numeric/mtl/utility/is_what.hpp new file mode 100644 index 00000000..205d5f04 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/is_what.hpp @@ -0,0 +1,93 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_IS_WHAT_INCLUDE +#define MTL_TRAITS_IS_WHAT_INCLUDE + +#include <boost/type_traits/is_base_of.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/or.hpp> +#include <boost/mpl/bool.hpp> + +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/category.hpp> + +namespace mtl { namespace traits { + +// Matrix, vector and scalar deduced from ashape not from category +template <typename T> +struct is_scalar + : boost::is_same<typename ashape::ashape<T>::type, ashape::scal> +{}; + +template <typename Shape> +struct is_matrix_aux + : boost::mpl::false_ +{}; + +template <typename Shape> +struct is_matrix_aux<ashape::mat<Shape> > + : boost::mpl::true_ +{}; + +template <typename T> +struct is_matrix + : is_matrix_aux<typename ashape::ashape<T>::type> +{}; + +template <typename Shape> +struct is_vector_aux + : boost::mpl::false_ +{}; + +template <typename Shape> +struct is_vector_aux<ashape::cvec<Shape> > + : boost::mpl::true_ +{}; + +template <typename Shape> +struct is_vector_aux<ashape::rvec<Shape> > + : boost::mpl::true_ +{}; + +template <typename T> +struct is_vector + : is_vector_aux<typename ashape::ashape<T>::type> +{}; + +template <typename T> +struct is_dense + : boost::is_base_of<tag::dense, typename category<T>::type> +{}; + + +template <typename T> +struct is_unevaluated + : boost::is_base_of<tag::unevaluated, typename category<T>::type> +{}; + +template <typename T> +struct is_sparse + : boost::is_base_of<tag::sparse, typename category<T>::type> +{}; + +// So far nothing is symmetric on the type level +template <typename T> +struct is_symmetric + : boost::mpl::false_ +{}; + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_IS_WHAT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/iset.hpp b/install/MTL/include/boost/numeric/mtl/utility/iset.hpp new file mode 100644 index 00000000..9782be76 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/iset.hpp @@ -0,0 +1,102 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ISET_INCLUDE +#define MTL_ISET_INCLUDE + +#include <vector> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/numeric/mtl/utility/push_back_comma_inserter.hpp> +#include <boost/numeric/mtl/operation/is_negative.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> + +namespace mtl { + + /// Class for arbitrary index sets + class iset + { + public: + /// Size type + typedef std::size_t size_type; + + void check(size_type MTL_DEBUG_ARG(i)) const + { MTL_DEBUG_THROW_IF(is_negative(i) || i >= indices.size(), index_out_of_range()); } + + iset() {} ///< Default constructor + + /// Construct from array + template <long Size> + iset(const size_type (&array)[Size]) : indices(&array[0], &array[Size]) {} + + /// Constructor from std::vector; size_type must be identic + explicit iset(const std::vector<size_type>& src) : indices(src) {} + +# ifdef MTL_WITH_MOVE + /// Constructor from std::vector; size_type must be identic + explicit iset(std::vector<size_type>&& src) : indices(std::move(src)) {} +# endif + + /// Assign comma-separated list + template <typename Source> + typename boost::enable_if<boost::is_integral<Source>, push_back_comma_inserter<iset> >::type + operator=(const Source& src) + { + indices.clear(); + indices.push_back(src); + return push_back_comma_inserter<iset>(*this); + } + + /// Return i-th index + size_type operator[](size_type i) const { check(i); return indices[i]; } + + /// Insert a new index at the end + void push_back(size_type i) { indices.push_back(i); } + + /// Size of the set + size_type size() const { return indices.size(); } + + /// Equality + bool operator==(const iset& that) const + { + if (size() != that.size()) + return false; + for (size_type i= 0; i < size(); i++) + if (indices[i] != that.indices[i]) + return false; + return true; + } + + bool operator!=(const iset& that) const { return !(*this == that); } ///< Inequality + + /// Print iset + friend std::ostream& operator<<(std::ostream& os, const iset& is) + { os << "{"; + for (size_type i= 0; i < is.indices.size(); i++) { + os << is.indices[i]; + if (i+1 < is.indices.size()) + os << ", "; + } + return os << "}"; + } + + private: + std::vector<size_type> indices; + }; + + /// Size of an index set (as free function) + std::size_t inline size(const iset& i) + { return i.size(); } + +} // namespace mtl + +#endif // MTL_ISET_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/iterator_adaptor.hpp b/install/MTL/include/boost/numeric/mtl/utility/iterator_adaptor.hpp new file mode 100644 index 00000000..ed48ae72 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/iterator_adaptor.hpp @@ -0,0 +1,64 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ITERATOR_ADAPTOR_INCLUDE +#define MTL_ITERATOR_ADAPTOR_INCLUDE + +#include <boost/numeric/mtl/utility/iterator_adaptor_detail.hpp> + +namespace mtl { namespace utilities { + + +// Should be distinguished between random access and forward iterator +// So far all (dense) cursors (within rows/columns) have random access + +template <typename PropertyMap, typename Cursor, typename ValueType> +struct const_iterator_adaptor + : public detail::ra_adaptor_operators< const_iterator_adaptor<PropertyMap, Cursor, ValueType> > +{ + typedef detail::const_iterator_proxy<PropertyMap, Cursor, ValueType> proxy; + + const_iterator_adaptor(PropertyMap map, Cursor cursor) + : map(map), cursor(cursor) {} + + proxy operator*() const + { + return proxy(map, cursor); + } + + PropertyMap map; + Cursor cursor; +}; + + +template <typename PropertyMap, typename Cursor, typename ValueType> +struct iterator_adaptor + : public detail::ra_adaptor_operators< iterator_adaptor<PropertyMap, Cursor, ValueType> > +{ + typedef detail::iterator_proxy<PropertyMap, Cursor, ValueType> proxy; + + iterator_adaptor(PropertyMap map, Cursor cursor) + : map(map), cursor(cursor) {} + + proxy operator*() + { + return proxy(map, cursor); + } + + PropertyMap map; + Cursor cursor; +}; + + +}} // namespace mtl::utilities + +#endif // MTL_ITERATOR_ADAPTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/iterator_adaptor_1D.hpp b/install/MTL/include/boost/numeric/mtl/utility/iterator_adaptor_1D.hpp new file mode 100644 index 00000000..4e7bf02a --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/iterator_adaptor_1D.hpp @@ -0,0 +1,161 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ITERATOR_ADAPTOR_1D_INCLUDE +#define MTL_ITERATOR_ADAPTOR_1D_INCLUDE + +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/glas_tag.hpp> +#include <boost/numeric/mtl/utility/iterator_adaptor.hpp> + +namespace mtl { namespace traits { + +// Range generator for one-dimensional iterators +// Implemented by means of cursors and value map + +template <typename Matrix> +struct range_generator<tag::const_iter::nz, Matrix> +{ + typedef typename traits::const_value<Matrix>::type map_type; + typedef typename glas::tag::nz cursor_tag; + typedef range_generator<cursor_tag, Matrix> cursor_range; + typedef typename cursor_range::type cursor_type; + typedef typename Matrix::value_type value_type; + typedef typename cursor_range::complexity complexity; + static int const level = cursor_range::level; + + // iterator is type of range generator + typedef utilities::const_iterator_adaptor<map_type, cursor_type, value_type> type; + + type begin(const Matrix& matrix) const + { + return type(map_type(matrix), cursor_range().begin(matrix)); + } + + type end(const Matrix& matrix) const + { + return type(map_type(matrix), cursor_range().end(matrix)); + } +}; + + +#if 0 +template <typename Matrix> +struct range_generator<tag::iter::nz, Matrix> +{ + typedef typename traits::value<Matrix>::type map_type; + typedef typename glas::tag::nz cursor_tag; + typedef typename range_generator<cursor_tag, Matrix>::type cursor_type; + typedef typename Matrix::value_type value_type; + typedef typename range_generator<cursor_tag, Matrix>::complexity complexity; + static int const level = range_generator<cursor_tag, Matrix>::level; + + // iterator is type of range generator + typedef utilities::const_iterator_adaptor<map_type, cursor_type, value_type> type; + + type begin(const Matrix& matrix) const + { + map_type map(matrix); + return type(map, begin<cursor_tag>(matrix)); + } + + type end(const Matrix& matrix) const + { + map_type map(matrix); + return type(map, end<cursor_tag>(matrix)); + } +}; + + +template <typename Matrix> +struct range_generator<tag::const_iter::all, Matrix> +{ + typedef typename traits::const_value<Matrix>::type map_type; + typedef typename glas::tag::all cursor_tag; + typedef typename range_generator<cursor_tag, Matrix>::type cursor_type; + typedef typename Matrix::value_type value_type; + typedef typename range_generator<cursor_tag, Matrix>::complexity complexity; + static int const level = range_generator<cursor_tag, Matrix>::level; + + // iterator is type of range generator + typedef utilities::const_iterator_adaptor<map_type, cursor_type, value_type> type; + + type begin(const Matrix& matrix) const + { + return type(map_type(matrix), begin<cursor_tag>(matrix)); + } + + type end(const Matrix& matrix) const + { + return type(map_type(matrix), end<cursor_tag>(matrix)); + } +}; + +template <typename Matrix> +struct range_generator<tag::iter::all, Matrix> +{ + typedef typename traits::value<Matrix>::type map_type; + typedef typename glas::tag::all cursor_tag; + typedef typename range_generator<cursor_tag, Matrix>::type cursor_type; + typedef typename Matrix::value_type value_type; + typedef typename range_generator<cursor_tag, Matrix>::complexity complexity; + static int const level = range_generator<cursor_tag, Matrix>::level; + + // iterator is type of range generator + typedef utilities::const_iterator_adaptor<map_type, cursor_type, value_type> type; + + type begin(const Matrix& matrix) const + { + map_type map(matrix); + return type(map, begin<cursor_tag>(matrix)); + } + + type end(const Matrix& matrix) const + { + map_type map(matrix); + return type(map, end<cursor_tag>(matrix)); + } +}; + + +#endif + + + + + + +#if 0 +template <typename Matrix> +struct morton_dense_row_const_iterator + : utilities::const_iterator_adaptor<typename traits::const_value<Matrix>::type, morton_dense_row_cursor<Matrix::mask>, + typename Matrix::value_type> +{ + static const unsigned long mask= Matrix::mask; + typedef morton_dense_row_cursor<mask> cursor_type; + typedef typename traits::const_value<Matrix>::type map_type; + typedef typename Matrix::value_type value_type; + typedef typename Matrix::size_type size_type; + typedef utilities::iterator_adaptor<map_type, cursor_type, value_type> base; + + morton_dense_row_const_iterator(const Matrix& matrix, size_type row, size_type col) + : base(map_type(matrix), cursor_type(row, col)) + {} +}; + +utilities::const_iterator_adaptor<typename traits::const_value<Matrix>::type, morton_dense_row_cursor<Matrix::mask>, + typename Matrix::value_type> +#endif + +}} // namespace mtl::traits + +#endif // MTL_ITERATOR_ADAPTOR_1D_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/iterator_adaptor_detail.hpp b/install/MTL/include/boost/numeric/mtl/utility/iterator_adaptor_detail.hpp new file mode 100644 index 00000000..e0e982f0 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/iterator_adaptor_detail.hpp @@ -0,0 +1,121 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ITERATOR_ADAPTOR_DETAIL_INCLUDE +#define MTL_ITERATOR_ADAPTOR_DETAIL_INCLUDE + +namespace mtl { namespace utilities { namespace detail { + + +template <typename Adaptor> +struct adaptor_operators +{ + Adaptor& operator++() + { + Adaptor& me = static_cast<Adaptor&>(*this); + ++me.cursor; + return me; + } + + Adaptor& operator++(int) + { + Adaptor& me = static_cast<Adaptor&>(*this); + Adaptor tmp(me); + ++me.cursor; + return tmp; + } + + bool operator==(Adaptor const& x) const + { + Adaptor const& me = static_cast<Adaptor const&>(*this); + + // Sloppy, nothing tested about property map + return me.cursor == x.cursor; + + // Compare addresses of property maps + // Problem: different addresses doesn't imply that the maps are different + // return &me.map == &x.map && me.cursor == x.cursor; + + // Certainly better they provide comparison + // Problem: not guaranteed to exist or can be ridiculously expensive + // return me.map == x.map && me.cursor == x.cursor; + } + + bool operator!=(Adaptor const& x) const + { + return !operator==(x); + } +}; + +template <typename Adaptor> +struct ra_adaptor_operators + : public adaptor_operators<Adaptor> +{ + Adaptor operator+(int i) const + { + const Adaptor& me = static_cast<const Adaptor&>(*this); + return Adaptor(me.map, me.cursor + i); + } + + Adaptor& operator+=(int i) + { + Adaptor& me = static_cast<Adaptor&>(*this); + me.cursor+= i; + return me; + } +}; + + + + +template <typename PropertyMap, typename Cursor, typename ValueType> +struct const_iterator_proxy +{ + const_iterator_proxy(PropertyMap map, Cursor cursor) + : map(map), cursor(cursor) {} + + operator ValueType() const + { + return map(*cursor); + } + + PropertyMap map; + Cursor cursor; +}; + + +template <typename PropertyMap, typename Cursor, typename ValueType> +struct iterator_proxy +{ + typedef iterator_proxy self; + + iterator_proxy(PropertyMap map, Cursor cursor) + : map(map), cursor(cursor) {} + + operator ValueType() const + { + return map(*cursor); + } + + self& operator=(ValueType const& value) + { + map(*cursor, value); + return *this; + } + + PropertyMap map; + Cursor cursor; +}; + +}}} // namespace mtl::utilities::detail + +#endif // MTL_ITERATOR_ADAPTOR_DETAIL_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/linear_operator.hpp b/install/MTL/include/boost/numeric/mtl/utility/linear_operator.hpp new file mode 100644 index 00000000..315ff86e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/linear_operator.hpp @@ -0,0 +1,34 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_LINEAR_OPERATOR_INCLUDE +#define MTL_TRAITS_LINEAR_OPERATOR_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace traits { + +/// Type trait returning type of linear operator projecting from vector space Vector1 to vector space Vector2 +/** The operator is dense. **/ +template <typename Vector1, typename Vector2> +struct linear_operator {}; + +template <typename Value1, typename Para1, typename Value2, typename Para2> +struct linear_operator<mtl::dense_vector<Value1, Para1>, mtl::dense_vector<Value2, Para2> > +{ + typedef mtl::mat::dense2D<Value1> type; +}; + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_LINEAR_OPERATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/lu_matrix_type.hpp b/install/MTL/include/boost/numeric/mtl/utility/lu_matrix_type.hpp new file mode 100644 index 00000000..6ebbdfbc --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/lu_matrix_type.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_LU_MATRIX_TYPE_INCLUDE +#define MTL_TRAITS_LU_MATRIX_TYPE_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace traits { + +template <typename Matrix> +struct lu_matrix_type +{ + typedef Matrix type; +}; + +template <typename Value, typename Parameters> +struct lu_matrix_type<mat::compressed2D<Value, Parameters> > +{ + typedef mat::dense2D<Value, Parameters> type; +}; + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_LU_MATRIX_TYPE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/make_copy_or_reference.hpp b/install/MTL/include/boost/numeric/mtl/utility/make_copy_or_reference.hpp new file mode 100644 index 00000000..53184101 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/make_copy_or_reference.hpp @@ -0,0 +1,94 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAKE_COPY_OR_REFERENCE_INCLUDE +#define MTL_MAKE_COPY_OR_REFERENCE_INCLUDE + +namespace mtl { + + +/// Helper class to avoid avoidable copies for input parameters +/** Container is referred if it has already target type, otherwise copied. + Create an object of this type and pass the value member variable to the function, + e.g. make_in_copy_or_reference<Tgt, Src> copy_or_ref(v); f(copy_or_ref.value); + where Src is the type of v and Tgt the type of f's argument. +**/ +template <typename Target, typename Source> +struct make_in_copy_or_reference +{ + typedef Target type; + explicit make_in_copy_or_reference(const Source& src) : value(src) {} + Target value; +}; + +template <typename Target> +struct make_in_copy_or_reference<Target, Target> +{ + typedef const Target& type; + explicit make_in_copy_or_reference(const Target& src) : value(src) {} + const Target& value; +}; + + +/// Helper class to avoid avoidable copies for output parameters. +/** Container is referred if it has already target type, otherwise copied at destruction. + Create an object of this type and pass the value member variable to the function, + e.g. make_in_copy_or_reference<Tgt, Src> copy_or_ref(v); f(copy_or_ref.value); + where Src is the type of v and Tgt the type of f's argument. + Target must be DefaultConstructible. +**/ +template <typename Target, typename Source> +struct make_out_copy_or_reference +{ + explicit make_out_copy_or_reference(Source& src) : src(src) {} + ~make_out_copy_or_reference() { src= value; } + + Target value; +private: + Source& src; +}; + +template <typename Target> +struct make_out_copy_or_reference<Target, Target> +{ + explicit make_out_copy_or_reference(Target& src) : value(src) {} + Target& value; +}; + + +/// Helper class to avoid avoidable copies for input-output parameters. +/** Container is referred if it has already target type, otherwise copied construction and destruction. + Create an object of this type and pass the value member variable to the function, + e.g. make_in_copy_or_reference<Tgt, Src> copy_or_ref(v); f(copy_or_ref.value); + where Src is the type of v and Tgt the type of f's argument. +**/ +template <typename Target, typename Source> +struct make_in_out_copy_or_reference +{ + explicit make_in_out_copy_or_reference(Source& src) : value(src), src(src) {} + ~make_in_out_copy_or_reference() { src= value; } + + Target value; +private: + Source& src; +}; + +template <typename Target> +struct make_in_out_copy_or_reference<Target, Target> +{ + explicit make_in_out_copy_or_reference(Target& src) : value(src) {} + Target& value; +}; + +} // namespace mtl + +#endif // MTL_MAKE_COPY_OR_REFERENCE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/matrix_type_generator.hpp b/install/MTL/include/boost/numeric/mtl/utility/matrix_type_generator.hpp new file mode 100644 index 00000000..8e756539 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/matrix_type_generator.hpp @@ -0,0 +1,185 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_MATRIX_TYPE_GENERATOR_INCLUDE +#define MTL_MATRIX_TYPE_GENERATOR_INCLUDE + +#ifdef MTL_WITH_VARIADIC_TEMPLATE + +#include <cstddef> +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/map.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/if.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/type_parameter.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/matrix/dimension.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> +#include <boost/numeric/mtl/recursion/predefined_masks.hpp> + +namespace mtl { + + + namespace type_para { + + template <typename DimPara> + struct set_matrix_dimensions + { + MTL_STATIC_ASSERT((! boost::is_same<DimPara, DimPara>::value), "Unsupported argument for matrix dimension."); + }; + + template <> + struct set_matrix_dimensions<none> + { + typedef mtl::non_fixed::dimensions type; + }; + + template <std::size_t ...Values> + struct set_matrix_dimensions<dim<Values...> > + { + MTL_STATIC_ASSERT((sizeof...(Values) == 2), "dim<rows, columns> must have exactly 2 arguments for matrices!"); + }; + + template <std::size_t Rows, std::size_t Cols> + struct set_matrix_dimensions<dim<Rows, Cols> > + { + typedef mtl::fixed::dimensions<Rows, Cols> type; + }; + + + template <typename TypePara> + struct matrix_parameter_generator + { + typedef typename boost::mpl::at<TypePara, orientation>::type ori1; + typedef typename boost::mpl::if_<boost::is_same<ori1, none>, + row_major, + ori1>::type ori2; + + typedef typename set_matrix_dimensions<typename boost::mpl::at<TypePara, dimensionality>::type>::type dim_type; + typedef typename boost::mpl::at<TypePara, size_type>::type as_size; + typedef mtl::mat::parameters< + ori2, + index::c_index, + dim_type, + boost::is_same<typename boost::mpl::at<TypePara, location>::type, on_stack>::value, + typename as_size::type + > type; + }; + + template <typename TypePara> + struct matrix_default_density + { + typedef typename boost::mpl::at<TypePara, density>::type init_density; + + typedef boost::mpl::map< + boost::mpl::pair<banded, sparse>, // Will be removed when dense banded is available + boost::mpl::pair<compressed, sparse>, + boost::mpl::pair<coordinate, sparse>, + boost::mpl::pair<ellpack, sparse>, + boost::mpl::pair<morton, dense>, + boost::mpl::pair<none, dense> + > default_map; + + typedef typename boost::mpl::if_< + boost::is_same<init_density, none>, + typename boost::mpl::at<default_map, typename boost::mpl::at<TypePara, layout>::type>::type, + init_density + >::type type; + }; + + template <typename T> + struct morton_matrix_mask + { + MTL_STATIC_ASSERT(( !boost::is_same<T, T>::value), "Unknown type argument for Morton-order mask (internal error?)."); + }; + + template <> + struct morton_matrix_mask<none> + { + static const std::size_t value= morton_mask; + }; + + template <std::size_t ...Values> + struct morton_matrix_mask<mask<Values...> > + { + MTL_STATIC_ASSERT((sizeof...(Values) != 1), "Morton-order matrices must have exactly one mask"); + }; + + template <std::size_t Value> + struct morton_matrix_mask<mask<Value> > + { + static const std::size_t value= Value; + }; + + + // Generate dense matrix (Density should be dense or none) + template <typename Value, typename Density, typename TypePara, typename MatrixPara> + struct matrix_density_generator + { + MTL_STATIC_ASSERT((boost::is_same<Density, dense>::value || boost::is_same<Density, none>::value), + "Internal programm error."); + static const std::size_t my_mask= morton_matrix_mask<typename boost::mpl::at<TypePara, masking>::type>::value; + typedef boost::mpl::map< + boost::mpl::pair<none, mat::dense2D<Value, MatrixPara> >, + boost::mpl::pair<morton, mat::morton_dense<Value, my_mask, MatrixPara> > + > type_map; + + typedef typename boost::mpl::at<type_map, typename boost::mpl::at<TypePara, layout>::type>::type type; + MTL_STATIC_ASSERT(( !boost::is_same<type, mpl_::void_>::value), + "The layout you providing cannot be used for dense matrices."); + }; + + + // Generate sparse matrix + template <typename Value, typename TypePara, typename MatrixPara> + struct matrix_density_generator<Value, sparse, TypePara, MatrixPara> + { + typedef boost::mpl::map< + boost::mpl::pair<banded, mat::sparse_banded<Value, MatrixPara> >, + boost::mpl::pair<compressed, mat::compressed2D<Value, MatrixPara> >, + boost::mpl::pair<none, mat::compressed2D<Value, MatrixPara> >, + boost::mpl::pair<coordinate, mat::coordinate2D<Value, MatrixPara> >, + boost::mpl::pair<ellpack, mat::ell_matrix<Value, MatrixPara> > + > type_map; + + typedef typename boost::mpl::at<type_map, typename boost::mpl::at<TypePara, layout>::type>::type type; + MTL_STATIC_ASSERT(( !boost::is_same<type, mpl_::void_>::value), + "The layout you providing cannot be used for sparse matrices."); + }; + + + template <typename Value, typename TypePara> + struct matrix_type_generator + { + typedef typename matrix_parameter_generator<TypePara>::type matrix_parameters; + // Imply density by layout + typedef typename matrix_default_density<TypePara>::type my_density; + // Dispatch for density + typedef typename matrix_density_generator<Value, my_density, TypePara, matrix_parameters>::type type; + }; + + } // namespace type_para + +# ifdef MTL_WITH_TEMPLATE_ALIAS + /// Generated matrix type, see \ref type_generator + template <typename Value, typename ...Parameters> + using matrix= typename type_para::matrix_type_generator<Value, typename set_parameters<Parameters...>::type>::type; +# endif + +} // namespace mtl + +#endif // MTL_WITH_VARIADIC_TEMPLATE + +#endif // MTL_MATRIX_TYPE_GENERATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/maybe.hpp b/install/MTL/include/boost/numeric/mtl/utility/maybe.hpp new file mode 100644 index 00000000..2811e3d3 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/maybe.hpp @@ -0,0 +1,61 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MAYBE_INCLUDE +#define MTL_MAYBE_INCLUDE + +#include <iostream> + +namespace mtl { namespace utilities { + +template <class Value> +struct maybe : public std::pair<Value, bool> +{ + typedef std::pair<Value, bool> base; + typedef maybe<Value> self; + + maybe(bool b) : base(Value(), b) {} + maybe(Value v) : base(v, true) {} + maybe(Value v, bool b) : base(v, b) {} + maybe(base b) : base(b) {} + + operator bool() const + { + return this->second; + } + operator Value() const + { + return this->first; + } + bool has_value() const + { + return this->second; + } + Value value() const + { + return this->first; + } +}; + +template <class Value> +inline std::ostream& operator<< (std::ostream& os, maybe<Value> const& m) +{ + return os << '(' << m.value() << ", " << (m ? "true" : "false") << ')'; +} + +} // namespace utilities + +using utilities::maybe; + +} // namespace mtl + +#endif // MTL_MAYBE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/multi_tmp.hpp b/install/MTL/include/boost/numeric/mtl/utility/multi_tmp.hpp new file mode 100644 index 00000000..f06b836d --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/multi_tmp.hpp @@ -0,0 +1,66 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_MULTI_TMP_INCLUDE +#define MTL_MULTI_TMP_INCLUDE + +namespace mtl { + +/// Helper class to define a set of temporaries +template <unsigned Size, typename Value> +struct multi_tmp +{ + typedef multi_tmp<Size-1, Value> sub_type; + + multi_tmp() {} + multi_tmp(const Value& v) : value(v), sub(v) {} + + Value sum() { return value + sub.sum(); } + + Value value; + sub_type sub; +}; + +template <typename Value> +struct multi_tmp<0, Value> +{ + multi_tmp() {} + multi_tmp(const Value&) {} + Value sum() { return 0; } +}; + +/// Helper class to define a set of constants and initialize it from an array +template <unsigned Index, unsigned Size, typename Value> +struct multi_constant_from_array +{ + typedef multi_constant_from_array<Index+1, Size, Value> sub_type; + + template <typename Array, typename IndexType> + multi_constant_from_array(const Array& x, IndexType i) : value(x[i+Index]), sub(x, i) {} + + const Value value; + sub_type sub; +}; + + +template <unsigned Size, typename Value> +struct multi_constant_from_array<Size, Size, Value> +{ + template <typename Array, typename IndexType> + multi_constant_from_array(const Array&, IndexType) {} +}; + + + +} // namespace mtl + +#endif // MTL_MULTI_TMP_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/omp_size_type.hpp b/install/MTL/include/boost/numeric/mtl/utility/omp_size_type.hpp new file mode 100644 index 00000000..27300216 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/omp_size_type.hpp @@ -0,0 +1,42 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_OMP_SIZE_TYPE_INCLUDE +#define MTL_TRAITS_OMP_SIZE_TYPE_INCLUDE + +#include <boost/mpl/if.hpp> + +namespace mtl { namespace traits { + +# ifdef MTL_WITH_OPENMP + + template <typename T> + struct omp_size_type + : boost::mpl::if_c<(sizeof(T) > sizeof(int)), long int, int> + {}; + +# else + + /// Type trait to provide size type w/wo OpenMP uniformely + /** OpenMP emits warnings for unsigned ints and we therefor use signed ints only. + Furthermore, we dispatch between int and long int. **/ + template <typename T> + struct omp_size_type + { + typedef T type; + }; + +# endif + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_OMP_SIZE_TYPE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/papi.hpp b/install/MTL/include/boost/numeric/mtl/utility/papi.hpp new file mode 100644 index 00000000..ef7dcf21 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/papi.hpp @@ -0,0 +1,200 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_PAPI_INCLUDE +#define MTL_PAPI_INCLUDE + +#ifdef MTL_HAS_PAPI + +#include <papi.h> +#include <boost/numeric/mtl/utility/exception.hpp> + +#endif // MTL_HAS_PAPI + +namespace mtl { namespace utility { + +/// Exception for errors with PAPI, is sub-divided further +struct papi_error : public runtime_error +{ + explicit papi_error(const char *s= "PAPI error") : runtime_error(s) {} +}; + +struct papi_version_mismatch : public papi_error +{ + explicit papi_version_mismatch(const char *s= "PAPI: version mismatch") : papi_error(s) {} +}; + +struct papi_no_counters : public papi_error +{ + explicit papi_no_counters(const char *s= "PAPI: no counters") : papi_error(s) {} +}; + +struct papi_create_eventset_error : public papi_error +{ + explicit papi_create_eventset_error(const char *s= "PAPI: create event set error") : papi_error(s) {} +}; + +struct papi_name_to_code_error : public papi_error +{ + explicit papi_name_to_code_error(const char *s= "PAPI: name to code error") : papi_error(s) {} +}; + +struct papi_query_event_error : public papi_error +{ + explicit papi_query_event_error(const char *s= "PAPI: query event error") : papi_error(s) {} +}; + +struct papi_start_event_error : public papi_error +{ + explicit papi_start_event_error(const char *s= "PAPI: start event error") : papi_error(s) {} +}; + +struct papi_add_event_error : public papi_error +{ + explicit papi_add_event_error(const char *s= "PAPI: add event error") : papi_error(s) {} +}; + +struct papi_reset_error : public papi_error +{ + explicit papi_reset_error(const char *s= "PAPI: reset error") : papi_error(s) {} +}; + +struct papi_read_error : public papi_error +{ + explicit papi_read_error(const char *s= "PAPI: read error") : papi_error(s) {} +}; + +struct papi_index_range_error : public papi_error +{ + explicit papi_index_range_error(const char *s= "PAPI: index range error") : papi_error(s) {} +}; + + +#ifdef MTL_HAS_PAPI + +class papi_t +{ + void init_papi() + { + static bool initialized= false; + if (!initialized) { + + MTL_THROW_IF(PAPI_library_init(PAPI_VER_CURRENT) != PAPI_VER_CURRENT, + papi_version_mismatch()); + + num_counters = PAPI_get_opt(PAPI_MAX_HWCTRS, NULL); + MTL_THROW_IF(num_counters <= 0, papi_no_counters()); + + counters= new long_long[num_counters]; + + MTL_THROW_IF(PAPI_create_eventset(&event_set) != PAPI_OK, papi_create_eventset_error()); + initialized= true; + } + } + +public: + const static bool true_papi = true; + + papi_t() : event_set(PAPI_NULL), active_events(0) + { + init_papi(); + } + + + ~papi_t() + { + delete[](counters); + } + + + // returns index of added event + int add_event(const char* name) + { + int code; + MTL_THROW_IF(PAPI_event_name_to_code(const_cast<char*>(name), &code) != PAPI_OK, + papi_name_to_code_error()); + // std::cout << "add event " << const_cast<char*>(name) << " " << code << "\n"; + MTL_THROW_IF (PAPI_query_event(code) != PAPI_OK, + papi_query_event_error()); + MTL_THROW_IF (PAPI_add_event(event_set, code) != PAPI_OK, + papi_add_event_error()); + list_events(); + return active_events++; + } + + void start() + { + MTL_THROW_IF (PAPI_start(event_set) != PAPI_OK, + papi_start_event_error()); + reset(); + } + + void list_events() + { +#if 0 + int evv[8], num= 8; + PAPI_list_events(event_set, evv, &num); + for (int i= 0; i < num; i++ ) std::cout << evv[i] << "\n"; +#endif + } + + bool is_event_supported(const char* name) const + { + int code; + return PAPI_event_name_to_code(const_cast<char*>(name), &code) == PAPI_OK + && PAPI_query_event(code) == PAPI_OK; + } + + void reset() + { + MTL_THROW_IF(PAPI_reset(event_set) != PAPI_OK, papi_reset_error()); + } + + void read() + { + list_events(); + MTL_THROW_IF (PAPI_read(event_set, counters) != PAPI_OK, papi_read_error()); + // std::cout << "counters read, first value: " << *counters << "\n"; + } + + long_long operator[](int index) const + { + if (index < 0 || index >= active_events) throw papi_index_range_error(); + return counters[index]; + } + + //private: + int num_counters, event_set, active_events; + long_long *counters; +}; + +#else // no papi + +// Faked papi type: + +struct papi_t +{ + const static bool true_papi = false; + int add_event(const char* name) { return 0;} + void start() {} + bool is_event_supported(const char* name) const { return false;} + void reset() {} + void read() {} + long long operator[](int index) const { return 0; } +}; + +#endif + +}} // namespace mtl::utility + + +#endif // MTL_PAPI_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/parameters.hpp b/install/MTL/include/boost/numeric/mtl/utility/parameters.hpp new file mode 100644 index 00000000..0dff5e4c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/parameters.hpp @@ -0,0 +1,57 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_PARAMETERS_INCLUDE +#define MTL_TRAITS_PARAMETERS_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/matrix/parameter.hpp> + +namespace mtl { namespace traits { + +template <typename T> +struct parameters +{ + typedef typename T::parameters type; +}; + +template <typename Vector> +struct parameters<mtl::mat::multi_vector<Vector> > +{ + typedef mtl::mat::parameters<> type; +}; + +template <typename Functor> +struct parameters<mtl::mat::implicit_dense<Functor> > +{ + typedef mtl::mat::parameters<> type; +}; + +template <typename Value> +struct parameters<mtl::mat::ones_matrix<Value> > + : public parameters<mtl::mat::implicit_dense<mtl::mat::ones_functor<Value> > > +{}; + +template <typename Value> +struct parameters<mtl::mat::hilbert_matrix<Value> > + : public parameters<mtl::mat::implicit_dense<mtl::mat::hilbert_functor<Value> > > +{}; + +template <typename Vector1, typename Vector2> +struct parameters<mtl::mat::outer_product_matrix<Vector1, Vector2> > + : public parameters<mtl::mat::implicit_dense<mtl::mat::outer_product_functor<Vector1, Vector2> > > +{}; + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_PARAMETERS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/pos_type.hpp b/install/MTL/include/boost/numeric/mtl/utility/pos_type.hpp new file mode 100644 index 00000000..be847f3c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/pos_type.hpp @@ -0,0 +1,50 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_POS_TYPE_INCLUDE +#define MTL_TRAITS_POS_TYPE_INCLUDE + +#include <utility> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> + +namespace mtl { namespace traits { + +// Not a matrix -> should be a vector +template <typename T, bool IsMatrix> +struct pos_type_aux +{ + typedef typename Collection<T>::size_type type; +}; + +// Matrix specialization +template <typename T> +struct pos_type_aux<T, true> +{ + private: + typedef typename Collection<T>::size_type size_type; + public: + typedef std::pair<size_type, size_type> type; +}; + +/// Type trait for position type +/** This is size_type for a vector and for a matrix a pair of size_types. + N.B.: The implementation considers everything that is not a matrix as vector, to be improved one day. **/ +template <typename T> +struct pos_type + : pos_type_aux<T, is_matrix<T>::value> +{}; + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_POS_TYPE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/property_map.hpp b/install/MTL/include/boost/numeric/mtl/utility/property_map.hpp new file mode 100644 index 00000000..d7f8cb2e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/property_map.hpp @@ -0,0 +1,410 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_PROPERTY_MAP_INCLUDE +#define MTL_PROPERTY_MAP_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/property_map_impl.hpp> + +namespace mtl { namespace traits { + +template <class Matrix> struct row {}; +template <class Matrix> struct col {}; +template <class Matrix> struct const_value {}; +template <class Matrix> struct value {}; +template <class Matrix> struct offset {}; + +// For vectors +template <class Vector> struct index {}; + +// =========== +// For dense2D +// =========== + +template <typename Value, class Parameters> +struct row<mtl::mat::dense2D<Value, Parameters> > +{ + typedef mtl::detail::indexer_row_ref<mtl::mat::dense2D<Value, Parameters> > type; +}; + +template <typename Value, class Parameters> +struct col<mtl::mat::dense2D<Value, Parameters> > +{ + typedef mtl::detail::indexer_col_ref<mtl::mat::dense2D<Value, Parameters> > type; +}; + +template <typename Value, class Parameters> +struct const_value<mtl::mat::dense2D<Value, Parameters> > +{ + typedef mtl::detail::direct_const_value<mtl::mat::dense2D<Value, Parameters> > type; +}; + +template <typename Value, class Parameters> +struct value<mtl::mat::dense2D<Value, Parameters> > +{ + typedef mtl::detail::direct_value<mtl::mat::dense2D<Value, Parameters> > type; +}; + + +// ================ +// For morton_dense +// ================ + + +template <class Elt, std::size_t BitMask, class Parameters> +struct row<mtl::mat::morton_dense<Elt, BitMask, Parameters> > +{ + typedef mtl::detail::row_in_key<mtl::mat::morton_dense<Elt, BitMask, Parameters> > type; +}; + +template <class Elt, std::size_t BitMask, class Parameters> +struct col<mtl::mat::morton_dense<Elt, BitMask, Parameters> > +{ + typedef mtl::detail::col_in_key<mtl::mat::morton_dense<Elt, BitMask, Parameters> > type; +}; + +template <class Elt, std::size_t BitMask, class Parameters> +struct const_value<mtl::mat::morton_dense<Elt, BitMask, Parameters> > +{ + typedef mtl::detail::matrix_const_value_ref<mtl::mat::morton_dense<Elt, BitMask, Parameters> > type; +}; + +template <class Elt, std::size_t BitMask, class Parameters> +struct value<mtl::mat::morton_dense<Elt, BitMask, Parameters> > +{ + typedef mtl::detail::matrix_value_ref<mtl::mat::morton_dense<Elt, BitMask, Parameters> > type; +}; + + +// ================ +// For compressed2D +// ================ + +template <class Elt, class Parameters> +struct row<mtl::mat::compressed2D<Elt, Parameters> > +{ + typedef typename boost::mpl::if_< + boost::is_same<typename Parameters::orientation, row_major> + , mtl::detail::major_in_key<mtl::mat::compressed2D<Elt, Parameters> > + , mtl::detail::indexer_minor_ref<mtl::mat::compressed2D<Elt, Parameters> > + >::type type; +}; + +template <class Elt, class Parameters> +struct col<mtl::mat::compressed2D<Elt, Parameters> > +{ + typedef typename boost::mpl::if_< + boost::is_same<typename Parameters::orientation, row_major> + , mtl::detail::indexer_minor_ref<mtl::mat::compressed2D<Elt, Parameters> > + , mtl::detail::major_in_key<mtl::mat::compressed2D<Elt, Parameters> > + >::type type; +}; + +template <class Elt, class Parameters> +struct const_value<mtl::mat::compressed2D<Elt, Parameters> > +{ + typedef mtl::detail::matrix_offset_const_value<mtl::mat::compressed2D<Elt, Parameters> > type; +}; + +template <class Elt, class Parameters> +struct value<mtl::mat::compressed2D<Elt, Parameters> > +{ + typedef mtl::detail::matrix_offset_value<mtl::mat::compressed2D<Elt, Parameters> > type; +}; + +// Offset that corresponds to cursor, e.g. to set values in a matrix with same pattern +// needed in ILU_0, so far only for compressed2D, could be useful for algos on sparse and dense +template <class Elt, class Parameters> +struct offset<mtl::mat::compressed2D<Elt, Parameters> > +{ + typedef mtl::detail::offset_from_key<mtl::mat::compressed2D<Elt, Parameters> > type; +}; + + +// ================ +// For coordinate2D +// ================ + +template <class Value, class Parameters> +struct row<mtl::mat::coordinate2D<Value, Parameters> > +{ + typedef mtl::detail::coordinate2D_row<Value, Parameters> type; +}; + +template <class Value, class Parameters> +struct col<mtl::mat::coordinate2D<Value, Parameters> > +{ + typedef mtl::detail::coordinate2D_col<Value, Parameters> type; +}; + +template <class Value, class Parameters> +struct const_value<mtl::mat::coordinate2D<Value, Parameters> > +{ + typedef mtl::detail::coordinate2D_const_value<Value, Parameters> type; +}; + +// ================= +// For sparse_banded +// ================= + +template <class Value, class Parameters> +struct row<mtl::mat::sparse_banded<Value, Parameters> > +{ + typedef mtl::detail::sparse_banded_row<Value, Parameters> type; +}; + +template <class Value, class Parameters> +struct col<mtl::mat::sparse_banded<Value, Parameters> > +{ + typedef mtl::detail::sparse_banded_col<Value, Parameters> type; +}; + +template <class Value, class Parameters> +struct const_value<mtl::mat::sparse_banded<Value, Parameters> > +{ + typedef mtl::detail::sparse_banded_const_value<Value, Parameters> type; +}; + +// ================== +// For implicit_dense +// ================== + +template <typename Functor> +struct row<mtl::mat::implicit_dense<Functor> > +{ + typedef mtl::detail::row_in_element_key<mtl::mat::implicit_dense<Functor> > type; +}; + +template <typename Functor> +struct col<mtl::mat::implicit_dense<Functor> > +{ + typedef mtl::detail::col_in_element_key<mtl::mat::implicit_dense<Functor> > type; +}; + +template <typename Functor> +struct const_value<mtl::mat::implicit_dense<Functor> > +{ + typedef mtl::detail::const_value_in_element_key<mtl::mat::implicit_dense<Functor> > type; +}; + + +// =============== +// For ones_matrix +// =============== + +template <typename Value> +struct row<mtl::mat::ones_matrix<Value> > + : public row<mtl::mat::implicit_dense<mtl::mat::ones_functor<Value> > > +{}; + +template <typename Value> +struct col<mtl::mat::ones_matrix<Value> > + : public col<mtl::mat::implicit_dense<mtl::mat::ones_functor<Value> > > +{}; + +template <typename Value> +struct const_value<mtl::mat::ones_matrix<Value> > + : public const_value<mtl::mat::implicit_dense<mtl::mat::ones_functor<Value> > > +{}; + + +// =============== +// For hilbert_matrix +// =============== + +template <typename Value> +struct row<mtl::mat::hilbert_matrix<Value> > + : public row<mtl::mat::implicit_dense<mtl::mat::hilbert_functor<Value> > > +{}; + +template <typename Value> +struct col<mtl::mat::hilbert_matrix<Value> > + : public col<mtl::mat::implicit_dense<mtl::mat::hilbert_functor<Value> > > +{}; + +template <typename Value> +struct const_value<mtl::mat::hilbert_matrix<Value> > + : public const_value<mtl::mat::implicit_dense<mtl::mat::hilbert_functor<Value> > > +{}; + + +// ======================== +// For outer_product_matrix +// ======================== + +template <typename Vector1, typename Vector2> +struct row<mtl::mat::outer_product_matrix<Vector1, Vector2> > + : public row<mtl::mat::implicit_dense<mtl::mat::outer_product_functor<Vector1, Vector2> > > +{}; + +template <typename Vector1, typename Vector2> +struct col<mtl::mat::outer_product_matrix<Vector1, Vector2> > + : public col<mtl::mat::implicit_dense<mtl::mat::outer_product_functor<Vector1, Vector2> > > +{}; + +template <typename Vector1, typename Vector2> +struct const_value<mtl::mat::outer_product_matrix<Vector1, Vector2> > + : public const_value<mtl::mat::implicit_dense<mtl::mat::outer_product_functor<Vector1, Vector2> > > +{}; + + +// ==================== +// For mat::indirect +// ==================== + +template <typename Matrix> +struct row<mtl::mat::indirect<Matrix> > +{ + typedef mtl::detail::row_in_element_key<mtl::mat::indirect<Matrix> > type; +}; + +template <typename Matrix> +struct col<mtl::mat::indirect<Matrix> > +{ + typedef mtl::detail::col_in_element_key<mtl::mat::indirect<Matrix> > type; +}; + +template <typename Matrix> +struct const_value<mtl::mat::indirect<Matrix> > +{ + typedef mtl::detail::const_value_in_element_key<mtl::mat::indirect<Matrix> > type; +}; + + +// ================ +// For dense_vector +// ================ + +template <class Elt, class Parameters> +struct index<mtl::vec::dense_vector<Elt, Parameters> > +{ + typedef mtl::detail::index_from_offset< mtl::vec::dense_vector<Elt, Parameters> > type; +}; + +template <typename Value, class Parameters> +struct const_value<mtl::vec::dense_vector<Value, Parameters> > +{ + typedef mtl::detail::direct_const_value<mtl::vec::dense_vector<Value, Parameters> > type; +}; + +template <typename Value, class Parameters> +struct value<mtl::vec::dense_vector<Value, Parameters> > +{ + typedef mtl::detail::direct_value<mtl::vec::dense_vector<Value, Parameters> > type; +}; +// ================ +// For strided_vector_ref +// ================ + +template <class Elt, class Parameters> +struct index<mtl::vec::strided_vector_ref<Elt, Parameters> > +{ + typedef mtl::detail::index_from_offset< vec::strided_vector_ref<Elt, Parameters> > type; +}; + +template <typename Value, class Parameters> +struct const_value<mtl::vec::strided_vector_ref<Value, Parameters> > +{ + typedef mtl::detail::direct_const_value<vec::strided_vector_ref<Value, Parameters> > type; +}; + +template <typename Value, class Parameters> +struct value<mtl::vec::strided_vector_ref<Value, Parameters> > +{ + typedef mtl::detail::direct_value<vec::strided_vector_ref<Value, Parameters> > type; +}; + + + + +}} // namespace mtl::traits + +namespace mtl { namespace mat { + +// Helpers + +/// Row map of matrix A +template <typename Matrix> +typename mtl::traits::row<Matrix>::type +inline row_map(const Matrix& A) +{ + return typename mtl::traits::row<Matrix>::type(A); +} + +/// Column map of matrix A +template <typename Matrix> +typename mtl::traits::col<Matrix>::type +inline col_map(const Matrix& A) +{ + return typename mtl::traits::col<Matrix>::type(A); +} + +/// Constant value map of matrix A +template <typename Matrix> +typename mtl::traits::const_value<Matrix>::type +inline const_value_map(const Matrix& A) +{ + return typename mtl::traits::const_value<Matrix>::type(A); +} + +/// Value map of matrix A +template <typename Matrix> +typename mtl::traits::value<Matrix>::type +inline value_map(Matrix& A) +{ + return typename mtl::traits::value<Matrix>::type(A); +} + +/// Offset map of matrix A +template <typename Matrix> +typename mtl::traits::offset<Matrix>::type +inline offset_map(const Matrix& A) +{ + return typename mtl::traits::offset<Matrix>::type(A); +} + +}} // namespace typename mtl::matrix + +namespace mtl { namespace vec { + +/// Index map of vector A +template <typename Vector> +typename mtl::traits::index<Vector>::type +inline index_map(const Vector& A) +{ + return typename mtl::traits::index<Vector>::type(A); +} + +/// Constant value map of vector A +template <typename Vector> +typename mtl::traits::const_value<Vector>::type +inline const_value_map(const Vector& A) +{ + return typename mtl::traits::const_value<Vector>::type(A); +} + +/// Value map of vector A +template <typename Vector> +typename mtl::traits::value<Vector>::type +inline value_map(Vector& A) +{ + return typename mtl::traits::value<Vector>::type(A); +} + +}} // namespace typename mtl::vector + + + +#endif // MTL_PROPERTY_MAP_INCLUDE + + diff --git a/install/MTL/include/boost/numeric/mtl/utility/property_map_impl.hpp b/install/MTL/include/boost/numeric/mtl/utility/property_map_impl.hpp new file mode 100644 index 00000000..21630509 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/property_map_impl.hpp @@ -0,0 +1,431 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_PROPERTY_MAP_IMPL_INCLUDE +#define MTL_PROPERTY_MAP_IMPL_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> + +namespace mtl { namespace detail { + +// functor with matrix reference to access rows +template <class Matrix> struct indexer_row_ref +{ + typedef Matrix matrix_type; + typedef typename Matrix::key_type key_type; + indexer_row_ref(const matrix_type& ma) : ma(ma) {} + + typename Matrix::size_type operator() (key_type const& key) const + { + return ma.indexer.row(ma, key); + } + const matrix_type& ma; +}; + + +// functor to access rows using the key itself +template <class Matrix> struct row_in_key +{ + typedef Matrix matrix_type; + typedef typename Matrix::key_type key_type; + row_in_key(const matrix_type&) {} + + typename Matrix::size_type operator() (key_type const& key) const + { + return key.row(); + } +}; + +// functor to access rows using the key itself +template <class Matrix> struct row_in_element_key +{ + typedef Matrix matrix_type; + row_in_element_key(const matrix_type&) {} + + template <typename Key> + typename Matrix::size_type operator() (Key const& key) const + { + return key.indices[0]; + } +}; + + +// functor access the major dimension in key itself +template <class Matrix> struct major_in_key +{ + typedef Matrix matrix_type; + typedef typename Matrix::key_type key_type; + major_in_key(const matrix_type&) {} + + typename Matrix::size_type operator() (key_type const& key) const + { + return key.major; + } +}; + +// functor to access rows using the key itself +template <class Matrix> struct major_in_element_key +{ + typedef Matrix matrix_type; + major_in_element_key(const matrix_type&) {} + + template <typename Key> + typename Matrix::size_type operator() (Key const& key) const + { + return key.indices[0]; + } +}; + +template <class Matrix> struct indexer_minor_ref +{ + typedef Matrix matrix_type; + typedef typename Matrix::key_type key_type; + indexer_minor_ref(const matrix_type& ma) : ma(ma) {} + + typename Matrix::size_type operator() (key_type const& key) const + { + return ma.indexer.minor_from_offset(ma, key.offset); + } + const matrix_type& ma; +}; + + +template <class Matrix> struct indexer_col_ref +{ + typedef Matrix matrix_type; + typedef typename Matrix::key_type key_type; + indexer_col_ref(const matrix_type& ma) : ma(ma) {} + + typename Matrix::size_type operator() (key_type const& key) const + { + return ma.indexer.col(ma, key); + } + const matrix_type& ma; +}; + + +template <class Matrix> struct col_in_key +{ + typedef Matrix matrix_type; + typedef typename Matrix::key_type key_type; + col_in_key(const matrix_type&) {} + + typename Matrix::size_type operator() (key_type const& key) const + { + return key.col(); + } +}; + +// functor to access columns using the key itself +template <class Matrix> struct col_in_element_key +{ + typedef Matrix matrix_type; + col_in_element_key(const matrix_type&) {} + + template <typename Key> + typename Matrix::size_type operator() (Key const& key) const + { + return key.indices[1]; + } +}; + +// Collection must be derived from contiguous_memory_block +// key must contain pointer +template <class Collection> struct index_from_offset +{ + typedef Collection collection_type; + + index_from_offset(const collection_type& coll) : coll(coll) {} + + template <typename Key> + typename Collection::size_type operator() (Key const& key) const + { + return coll.offset(&*key); + } +private: + const collection_type& coll; +}; + +template <typename Matrix> +struct const_value_from_other +{ + typedef typename Matrix::other other; + typedef typename other::key_type key_type; + typedef typename other::value_type value_type; + + explicit const_value_from_other(Matrix const& matrix) + : its_const_value(matrix.ref) {} + + const value_type operator() (key_type const& key) const + { + return its_const_value(key); + } + + protected: + typename traits::const_value<typename boost::remove_const<other>::type>::type its_const_value; +}; + + + + +template <typename Matrix> +struct value_from_other +{ + typedef typename Matrix::other other; + typedef typename other::key_type key_type; + typedef typename other::value_type value_type; + + explicit value_from_other(Matrix const& matrix) + : its_value(matrix.ref) {} + + const value_type operator() (key_type const& key) const + { + return its_value(key); + } + + void operator() (key_type const& key, value_type value) const + { + its_value(key, value); + } + + protected: + typename traits::value<other>::type its_value; +}; + + +// property map to read value if key is referring to value, e.g. pointer +template <class Matrix> struct direct_const_value +{ + direct_const_value(const Matrix&) {} // for compatibility + typename Matrix::value_type const operator() (const typename Matrix::key_type key) const + { + return *key; + } +}; + + +// same with writing +template <class Matrix> struct direct_value + : public direct_const_value<Matrix> +{ + typedef typename Matrix::value_type value_type; + + direct_value(const Matrix& ma) + : direct_const_value<Matrix>(ma) + {} // for compatibility + + // May be to be replaced by inserter + void operator() (typename Matrix::key_type const& key, value_type value) + { + * const_cast<value_type *>(key) = value; + } + + // should be inherited + typename Matrix::value_type operator() (typename Matrix::key_type const& key) const + { + return *key; + } +}; + + +template <class Matrix> struct matrix_const_value_ref +{ + typedef Matrix matrix_type; + typedef typename Matrix::key_type key_type; + matrix_const_value_ref(const matrix_type& ma) : ma(ma) {} + + typename Matrix::value_type operator() (key_type const& key) const + { + return ma(key); + } + const matrix_type& ma; +}; + + +template <class Matrix> struct matrix_value_ref +{ + typedef Matrix matrix_type; + typedef typename Matrix::key_type key_type; + typedef typename Matrix::value_type value_type; + matrix_value_ref(matrix_type& ma) : ma(ma) {} + + typename Matrix::value_type operator() (key_type const& key) const + { + return ma(key); + } + + // Much better with inserters + void operator() (typename Matrix::key_type const& key, value_type const& value) + { + ma(key, value); + } + + matrix_type& ma; +}; + + +template <class Matrix> struct matrix_offset_const_value +{ + typedef Matrix matrix_type; + typedef typename Matrix::key_type key_type; + matrix_offset_const_value(const matrix_type& ma) : ma(ma) {} + + typename Matrix::value_type operator() (key_type const& key) const + { + return ma.value_from_offset(key.offset); + } + const matrix_type& ma; +}; + + +template <class Matrix> struct matrix_offset_value +{ + typedef Matrix matrix_type; + typedef typename Matrix::key_type key_type; + typedef typename Matrix::value_type value_type; + matrix_offset_value(matrix_type& ma) : ma(ma) {} + + typename Matrix::value_type operator() (key_type const& key) const + { + return ma.value_from_offset(key.offset); + } + + // Much better with inserters + void operator() (typename Matrix::key_type const& key, value_type const& value) + { + ma.value_from_offset(key.offset) = value; + } + + matrix_type& ma; +}; + +template <class Matrix> struct offset_from_key +{ + typedef Matrix matrix_type; + typedef typename Matrix::key_type key_type; + typedef typename Matrix::size_type size_type; + offset_from_key(const matrix_type& ) {} + + size_type operator() (key_type const& key) const + { + return key.offset; + } +}; + +// functor to access columns using the key itself +template <class Matrix> struct const_value_in_element_key +{ + typedef Matrix matrix_type; + const_value_in_element_key(const matrix_type&) {} + + template <typename Key> + typename Matrix::value_type operator() (Key const& key) const + { + return key.ref[key.indices[0]][key.indices[1]]; + } +}; + +template <class Value, class Parameters> +struct coordinate2D_row +{ + typedef const mtl::mat::coordinate2D<Value, Parameters>& matrix_ref_type; + explicit coordinate2D_row(matrix_ref_type A) : A(A) {} + + template <typename Key> + typename Parameters::size_type operator() (Key key) const + { return A.row_index_array()[key.offset]; } + + matrix_ref_type A; +}; + +template <class Value, class Parameters> +struct coordinate2D_col +{ + typedef const mtl::mat::coordinate2D<Value, Parameters>& matrix_ref_type; + explicit coordinate2D_col(matrix_ref_type A) : A(A) {} + + template <typename Key> + typename Parameters::size_type operator() (Key key) const + { return A.column_index_array()[key.offset]; } + + matrix_ref_type A; +}; + +template <class Value, class Parameters> +struct coordinate2D_const_value +{ + typedef const mtl::mat::coordinate2D<Value, Parameters>& matrix_ref_type; + explicit coordinate2D_const_value(matrix_ref_type A) : A(A) {} + + template <typename Key> + Value operator() (Key key) const + { return A.value_array()[key.offset]; } + + matrix_ref_type A; +}; + +template <class Value, class Parameters> +struct sparse_banded_row // maybe refactor into sparse_banded_major +{ + MTL_STATIC_ASSERT((mtl::traits::is_row_major<Parameters>::value), "Only row-major sparse banded matrices supported so far."); + typedef const mtl::mat::sparse_banded<Value, Parameters>& matrix_ref_type; + typedef typename Parameters::size_type size_type; + explicit sparse_banded_row(matrix_ref_type A) : A(A) {} + + template <typename Key> + size_type operator() (Key key) const + { return key.offset / A.ref_bands().size(); } + + matrix_ref_type A; +}; + +template <class Value, class Parameters> +struct sparse_banded_col // maybe refactor into sparse_banded_minor +{ + MTL_STATIC_ASSERT((mtl::traits::is_row_major<Parameters>::value), "Only row-major sparse banded matrices supported so far."); + typedef const mtl::mat::sparse_banded<Value, Parameters>& matrix_ref_type; + typedef typename Parameters::size_type size_type; + + explicit sparse_banded_col(matrix_ref_type A) : A(A) {} + + template <typename Key> + size_type operator() (Key key) const + { + size_type bs= A.ref_bands().size(), major= key.offset / bs, b= key.offset % bs; + return major + A.ref_bands()[b]; + } + + matrix_ref_type A; +}; + +template <class Value, class Parameters> +struct sparse_banded_const_value +{ + typedef const mtl::mat::sparse_banded<Value, Parameters>& matrix_ref_type; + explicit sparse_banded_const_value(matrix_ref_type A) : A(A) {} + + template <typename Key> + Value operator() (Key key) const + { return A.ref_data()[key.offset]; } + + matrix_ref_type A; +}; + + +}} // namespace mtl::detail + + +#endif // MTL_PROPERTY_MAP_IMPL_INCLUDE + + diff --git a/install/MTL/include/boost/numeric/mtl/utility/push_back_comma_inserter.hpp b/install/MTL/include/boost/numeric/mtl/utility/push_back_comma_inserter.hpp new file mode 100644 index 00000000..76f1ccca --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/push_back_comma_inserter.hpp @@ -0,0 +1,38 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_PUSH_BACK_COMMA_INSERTER_INCLUDE +#define MTL_PUSH_BACK_COMMA_INSERTER_INCLUDE + +namespace mtl { + + /// Helper class to inserter with push_back using comma separation + template <typename T> + class push_back_comma_inserter + { + typedef push_back_comma_inserter self; + public: + /// Constructor takes a mutable reference of the object inserted into + push_back_comma_inserter(T& ref) : ref(ref) {} + + /// Overloaded comma operator performs push_back + template <typename Source> + self& operator, (Source val) + { ref.push_back(val); return *this; } + + private: + T& ref; + }; + +} // namespace mtl + +#endif // MTL_PUSH_BACK_COMMA_INSERTER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/range_generator.hpp b/install/MTL/include/boost/numeric/mtl/utility/range_generator.hpp new file mode 100644 index 00000000..e1cd7040 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/range_generator.hpp @@ -0,0 +1,224 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_RANGE_GENERATOR_INCLUDE +#define MTL_RANGE_GENERATOR_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/detail/range_generator.hpp> +#include <boost/numeric/mtl/utility/complexity.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/if.hpp> + +namespace mtl { + +namespace traits +{ + /// Functor for generating begin and end cursors over a collection + /** Thus functor must contain begin and end member functions which are used by free functions + The cursor type must be defined as 'typedef xxx type;' + complexity characterizes the run time of a traveral, cf. utility/complexity.hpp + complexity can be used to dispatch between different traversals depending on algorithm + and on collection (corr. subset represented by cursor) + level indicates the maximal level of nesting + - level 0: there is no traversal of this Tag for this collection + - level 1: cursor refers directly to elements + - level 2: cursor iterates over sets of elements or is only an intermediate cursor + cursor e.g. over rows, + its generated ranges are level 1 and iterate over elements + - level 3: cursor over sets of sets of elements, + its generated ranges are level 2 or 1 depending on the tag used on the cursor + - level 4: for instance blocked matrix -> level 4: block rows -> level 3: block elements + -> level 2: regular rows -> level 1: matrix elements + if an element cursor range was generated from the block element then the nesting + would be only 3 (since the last two levels collapse) + Cursors of level > 1 represent subsets of a collection and thus, it is only logical that + there must be range generators for these subset, which are applied on the cursor. + **/ + template <typename Tag, typename Collection> + struct range_generator + { + typedef complexity_classes::infinite complexity; + static int const level = 0; + typedef Tag tag; + + // MTL_STATIC_ASSERT(false, "range generator not implemented for these arguments (e.g. wrong combination)."); + + // specializations must contain the following members + // typedef xxx type; + // type begin() { ... } + // type end() { ... } + }; +} // namespace traits + + + +/// Returns begin cursor over the Collection or a subset of the Collection +/** Form of traversal depends on Tag, cf utility/glas_tag.hpp + On nested traversals, cursors of level > 1 must provide at least one range generator + \sa end() **/ +template <class Tag, class Collection> +typename traits::range_generator<Tag, Collection>::type +inline begin(Collection const& c) +{ + typedef traits::range_generator<Tag, Collection> gen_type; + MTL_STATIC_ASSERT(gen_type::level != 0, + "Template arguments not supported, probably traversal with unsupported tag combination."); + return gen_type().begin(c); +} + +template <class Tag, class Collection> +typename traits::range_generator<Tag, Collection>::type +inline begin(Collection& c) +{ + typedef traits::range_generator<Tag, Collection> gen_type; + MTL_STATIC_ASSERT(gen_type::level != 0, + "Template arguments not supported, probably traversal with unsupported tag combination."); + return gen_type().begin(c); +} + +/// Corresponding end cursor +/** \sa begin() **/ +template <class Tag, class Collection> +typename traits::range_generator<Tag, Collection>::type +inline end(Collection const& c) +{ + return traits::range_generator<Tag, Collection>().end(c); +} + +template <class Tag, class Collection> +typename traits::range_generator<Tag, Collection>::type +inline end(Collection& c) +{ + return traits::range_generator<Tag, Collection>().end(c); +} + +/// Cursor to an element with index equal or larger than \p position in a one-dimensional traversion. +/** This function is only defined where Tag represents an obvious one-dimensional traversion + of Collection allowing for an interpretation of position. + Examples are tag::row for a dense matrix or row-major compressed matrix. + tag::all regarding an entire matrix (i.e. going over all entries of a matrix) + does not characterize a one-dimensional traversion + so that \p position has no unique meaning. + Traversing all entries of a matrix row is one-dimensional and \p position is understood as looking for + a column index, i.e. lower_bound<tag::all>(row_cursor, 7) returns a cursor to a matrix element whose row + is the one of row_cursor and whose column is 7. + Likewise traversing all non-zeros of a row will return a cursor that points to an entry with according + row index and column index at least 7. + If the searched index could not be found in the one-dimensional collection the returned cursor will be + identical to the one returned by the end function. +**/ +template <class Tag, class Coll> +typename traits::range_generator<Tag, Coll>::type +inline lower_bound(Coll const& c, typename Collection<Coll>::size_type position) +{ + return traits::range_generator<Tag, Coll>().lower_bound(c, position); +} + +template <class Tag, class Coll> +typename traits::range_generator<Tag, Coll>::type +inline lower_bound(Coll& c, typename Collection<Coll>::size_type position) +{ + return traits::range_generator<Tag, Coll>().lower_bound(c, position); +} + + +namespace traits { + + // Dispatch between row and column-major traversal + template <typename Matrix> + struct range_generator<tag::major, Matrix> + : public range_generator< + typename boost::mpl::if_< + boost::is_same<typename OrientedCollection<Matrix>::orientation, row_major> + , ::mtl::tag::row + , ::mtl::tag::col + >::type, + Matrix> + {}; + + // Dispatch between row and column-major traversal + template <typename Matrix> + struct range_generator<tag::minor, Matrix> + : public range_generator< + typename boost::mpl::if_< + boost::is_same<typename OrientedCollection<Matrix>::orientation, row_major> + , ::mtl::tag::col + , ::mtl::tag::row + >::type, + Matrix> + {}; + + //=== Range generators for mat::indirect ==================== + + // Range generator over all rows + template <typename Matrix> + struct range_generator<glas::tag::row, mtl::mat::indirect<Matrix> > + : detail::all_rows_range_generator<mtl::mat::indirect<Matrix>, complexity_classes::linear, 2> + {}; + + // Range generator over all entries within a row + template <typename Matrix> + struct range_generator<glas::tag::all, + mtl::traits::detail::sub_matrix_cursor<mtl::mat::indirect<Matrix>, glas::tag::row, 2> > + : detail::all_cols_in_row_range_generator< + mtl::traits::detail::sub_matrix_cursor<mtl::mat::indirect<Matrix>, glas::tag::row, 2> > + {}; + + // Range generator over all non-zero entries within a row, same as all entries + template <typename Matrix> + struct range_generator<glas::tag::nz, + mtl::traits::detail::sub_matrix_cursor<mtl::mat::indirect<Matrix>, glas::tag::row, 2> > + : detail::all_cols_in_row_range_generator< + mtl::traits::detail::sub_matrix_cursor<mtl::mat::indirect<Matrix>, glas::tag::row, 2> > + {}; + + // - same for columns first + + // Range generator over all colums + template <typename Matrix> + struct range_generator<glas::tag::col, mtl::mat::indirect<Matrix> > + : detail::all_cols_range_generator<mtl::mat::indirect<Matrix>, complexity_classes::linear, 2> + {}; + + // Range generator over all entries within a column + template <typename Matrix> + struct range_generator<glas::tag::all, + mtl::traits::detail::sub_matrix_cursor<mtl::mat::indirect<Matrix>, glas::tag::col, 2> > + : detail::all_rows_in_col_range_generator< + mtl::traits::detail::sub_matrix_cursor<mtl::mat::indirect<Matrix>, glas::tag::col, 2> > + {}; + + // Range generator over all non-zero entries within a column, same as all entries + template <typename Matrix> + struct range_generator<glas::tag::nz, + mtl::traits::detail::sub_matrix_cursor<mtl::mat::indirect<Matrix>, glas::tag::col, 2> > + : detail::all_rows_in_col_range_generator< + mtl::traits::detail::sub_matrix_cursor<mtl::mat::indirect<Matrix>, glas::tag::col, 2> > + {}; + + // Take major same as row + // Not necessarily best choice but shouldn't matter here + template <typename Matrix> + struct range_generator<glas::tag::major, mtl::mat::indirect<Matrix> > + : detail::all_rows_range_generator<mtl::mat::indirect<Matrix>, complexity_classes::linear, 2> + {}; + +} + + +} // namespace mtl + +#endif // MTL_RANGE_GENERATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/range_wrapper.hpp b/install/MTL/include/boost/numeric/mtl/utility/range_wrapper.hpp new file mode 100644 index 00000000..1405c206 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/range_wrapper.hpp @@ -0,0 +1,120 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_RANGE_WRAPPER_INCLUDE +#define MTL_TRAITS_RANGE_WRAPPER_INCLUDE + +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> + +namespace mtl { namespace traits { + +/// Wrapper for range_generator +/** Instead of passing the collection or cursor to the begin() and end() function, + it is passed to the constructor. + As a consequence, it can be used with ranged for from C++11. **/ +template <typename Tag, typename Collection> +struct range_wrapper + : range_generator<Tag, Collection> +{ + typedef range_generator<Tag, Collection> gen_type; + MTL_STATIC_ASSERT(gen_type::level != 0, "Template arguments not supported, probably traversal with unsupported tag combination."); + typedef typename gen_type::type type; + + explicit range_wrapper(const Collection& c) : c(c) {} //< Initialize with collection + + type begin() const { return gen_type::begin(c); } //< nullary begin + type end() const { return gen_type::end(c); } //< nullary end + + private: + const Collection& c; +}; + +}} // namespace mtl::traits + +namespace mtl { + +/// Cursor over rows of a collection +template <typename T> +mtl::traits::range_wrapper<tag::row, T> +inline rows_of(const T& x) +{ + return mtl::traits::range_wrapper<tag::row, T>(x); +} + +/// Cursor over cols of a collection +template <typename T> +mtl::traits::range_wrapper<tag::col, T> +inline cols_of(const T& x) +{ + return mtl::traits::range_wrapper<tag::col, T>(x); +} + +/// Cursor over major index of a collection +template <typename T> +mtl::traits::range_wrapper<tag::major, T> +inline major_of(const T& x) +{ + return mtl::traits::range_wrapper<tag::major, T>(x); +} + +/// Cursor over minor index of a collection +template <typename T> +mtl::traits::range_wrapper<tag::minor, T> +inline minor_of(const T& x) +{ + return mtl::traits::range_wrapper<tag::minor, T>(x); +} + +/// Cursor over non-zero elements of a collection +template <typename T> +mtl::traits::range_wrapper<tag::nz, T> +inline nz_of(const T& x) +{ + return mtl::traits::range_wrapper<tag::nz, T>(x); +} + +/// Cursor over all elements of a collection +template <typename T> +mtl::traits::range_wrapper<tag::all, T> +inline all_of(const T& x) +{ + return mtl::traits::range_wrapper<tag::all, T>(x); +} + +/// Cursor over tagged range of a collection +template <typename Tag, typename T> +mtl::traits::range_wrapper<Tag, T> +inline range_of(const T& x) +{ + return mtl::traits::range_wrapper<Tag, T>(x); +} + + +namespace mat { + using mtl::rows_of; + using mtl::cols_of; + using mtl::major_of; + using mtl::minor_of; + using mtl::nz_of; + using mtl::all_of; + using mtl::range_of; +} // matrix + + + + +} // mtl + + +#endif // MTL_TRAITS_RANGE_WRAPPER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/root.hpp b/install/MTL/include/boost/numeric/mtl/utility/root.hpp new file mode 100644 index 00000000..b5dcfc8c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/root.hpp @@ -0,0 +1,249 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_ROOT_INCLUDE +#define MTL_TRAITS_ROOT_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> + +namespace mtl { namespace traits { + + +/// Type trait to reduce types to their essentials by removing const, reference, ... and gearing derived types to their bases +template <typename T> +struct root +{ + typedef T type; +}; + +// ========================== +// Remove language attributes +// ========================== + +template <typename T> +struct root<T&> + : public root<T> {}; + +template <typename T> +struct root<const T> + : public root<T> {}; + +// Redundant specialization to make xlc++ happy +template <typename T, int R, int C> +struct root<const T[R][C]> + : public root<T[R][C]> {}; + + +// ============ +// Base classes +// ============ + +// Implicit dense matrices + +template <typename Value> +struct root<mtl::mat::ones_matrix<Value> > +{ + typedef mtl::mat::implicit_dense<mtl::mat::ones_functor<Value> > type; +}; + +template <typename Value> +struct root<mtl::mat::hilbert_matrix<Value> > +{ + typedef mtl::mat::implicit_dense<mtl::mat::hilbert_functor<Value> > type; +}; + +template <typename Vector1, typename Vector2> +struct root<mtl::mat::outer_product_matrix<Vector1, Vector2> > +{ + typedef mtl::mat::implicit_dense<mtl::mat::outer_product_functor<Vector1, Vector2> > type; +}; + +// Matrix map views + +template <typename Scaling, typename Matrix> +struct root< mtl::mat::scaled_view<Scaling, Matrix> > +{ + typedef mtl::mat::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>, Matrix> type; +}; + +template <typename Matrix> +struct root< mtl::mat::conj_view<Matrix> > +{ + typedef mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> type; +}; + +template <typename Matrix> +struct root< mtl::mat::negate_view<Matrix> > +{ + typedef mtl::mat::map_view<sfunctor::negate<typename Matrix::value_type>, Matrix> type; +}; + +template <typename Matrix> +struct root< mtl::mat::imag_view<Matrix> > +{ + typedef mtl::mat::map_view<sfunctor::imag<typename Matrix::value_type>, Matrix> type; +}; + +template <typename Matrix> +struct root< mtl::mat::real_view<Matrix> > +{ + typedef mtl::mat::map_view<sfunctor::real<typename Matrix::value_type>, Matrix> type; +}; + +template <typename Matrix> +struct root< mtl::mat::hermitian_view<Matrix> > +{ + typedef mtl::mat::map_view<sfunctor::conj<typename Matrix::value_type>, mtl::mat::transposed_view<Matrix> > type; +}; + +template <typename Matrix, typename RScaling> +struct root< mtl::mat::rscaled_view<Matrix, RScaling> > +{ + typedef mtl::mat::map_view<tfunctor::rscale<typename Matrix::value_type, RScaling>, Matrix> type; +}; + +template <typename Matrix, typename Divisor> +struct root< mtl::mat::divide_by_view<Matrix, Divisor> > +{ + typedef mtl::mat::map_view<tfunctor::divide_by<typename Matrix::value_type, Divisor>, Matrix> type; +}; + +// Matrix operations +template <typename M1, typename M2> +struct root< mtl::mat::mat_mat_plus_expr<M1, M2> > +{ + typedef mtl::sfunctor::plus<typename Collection<M1>::value_type, typename Collection<M2>::value_type> f_type; + typedef mtl::mat::mat_mat_op_expr<M1, M2, f_type> type; +}; + +template <typename M1, typename M2> +struct root< mtl::mat::mv_mv_plus_expr<M1, M2> > +{ + typedef typename root< mtl::mat::mat_mat_plus_expr<M1, M2> >::type type; +}; + +template <typename M1, typename M2> +struct root< mtl::mat::mat_mat_minus_expr<M1, M2> > +{ + typedef mtl::sfunctor::minus<typename Collection<M1>::value_type, typename Collection<M2>::value_type> f_type; + typedef mtl::mat::mat_mat_op_expr<M1, M2, f_type> type; +}; + +template <typename M1, typename M2> +struct root< mtl::mat::mv_mv_minus_expr<M1, M2> > +{ + typedef typename root< mtl::mat::mat_mat_minus_expr<M1, M2> >::type type; +}; + +template <typename M1, typename M2> +struct root< mtl::mat::mat_mat_times_expr<M1, M2> > +{ + typedef mtl::sfunctor::times<typename Collection<M1>::value_type, typename Collection<M2>::value_type> f_type; + typedef mtl::mat::mat_mat_op_expr<M1, M2, f_type> type; +}; + +template <typename M1, typename M2> +struct root< mtl::mat::mat_mat_ele_times_expr<M1, M2> > +{ + typedef mtl::sfunctor::times<typename Collection<M1>::value_type, typename Collection<M2>::value_type> f_type; + typedef mtl::mat::mat_mat_op_expr<M1, M2, f_type> type; +}; + + +// Vector assignment expressions + +template <typename E1, typename E2> +struct root< vec::vec_vec_asgn_expr<E1, E2> > +{ + typedef vec::vec_vec_aop_expr< E1, E2, mtl::sfunctor::assign<typename E1::value_type, typename E2::value_type> > type; +}; + +template <typename E1, typename E2> +struct root< vec::vec_vec_plus_asgn_expr<E1, E2> > +{ + typedef vec::vec_vec_aop_expr< E1, E2, mtl::sfunctor::plus_assign<typename E1::value_type, typename E2::value_type> > type; +}; + +template <typename E1, typename E2> +struct root< vec::vec_vec_minus_asgn_expr<E1, E2> > +{ + typedef vec::vec_vec_aop_expr< E1, E2, mtl::sfunctor::minus_assign<typename E1::value_type, typename E2::value_type> > type; +}; + +template <typename E1, typename E2> +struct root< vec::vec_scal_asgn_expr<E1, E2> > +{ + typedef vec::vec_scal_aop_expr< E1, E2, mtl::sfunctor::assign<typename E1::value_type, E2> > type; +}; + +template <typename E1, typename E2> +struct root< vec::vec_scal_times_asgn_expr<E1, E2> > +{ + typedef vec::vec_scal_aop_expr< E1, E2, mtl::sfunctor::times_assign<typename E1::value_type, E2> > type; +}; + +template <typename E1, typename E2> +struct root< vec::vec_scal_div_asgn_expr<E1, E2> > +{ + typedef vec::vec_scal_aop_expr< E1, E2, mtl::sfunctor::divide_assign<typename E1::value_type, E2> > type; +}; + +template <typename Scaling, typename Vector> +struct root< vec::scaled_view<Scaling, Vector> > +{ + typedef vec::map_view<tfunctor::scale<Scaling, typename Vector::value_type>, Vector> type; +}; + +template <typename Vector, typename RScaling> +struct root< vec::rscaled_view<Vector, RScaling> > +{ + typedef vec::map_view<tfunctor::rscale<typename Vector::value_type, RScaling>, Vector> type; +}; + +template <typename Vector, typename Divisor> +struct root< vec::divide_by_view<Vector, Divisor> > +{ + typedef vec::map_view<tfunctor::divide_by<typename Vector::value_type, Divisor>, Vector> type; +}; + +template <typename Vector> +struct root< vec::conj_view<Vector> > +{ + typedef vec::map_view<mtl::sfunctor::conj<typename Vector::value_type>, Vector> type; +}; + +template <typename Vector> +struct root< vec::negate_view<Vector> > +{ + typedef vec::map_view<mtl::sfunctor::negate<typename Vector::value_type>, Vector> type; +}; + +template <unsigned BSize, typename Vector> +struct root< vec::unrolled1<BSize, Vector> > +{ + typedef Vector type; +}; + + + +#if 0 // template +struct root +{ + typedef type; +}; +#endif + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_ROOT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/shrink_stl_vector.hpp b/install/MTL/include/boost/numeric/mtl/utility/shrink_stl_vector.hpp new file mode 100644 index 00000000..a12d148f --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/shrink_stl_vector.hpp @@ -0,0 +1,31 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_SHRINK_STL_VECTOR_INCLUDE +#define MTL_SHRINK_STL_VECTOR_INCLUDE + +namespace mtl { + +/// Shrink memory consumption of an STL vector to its size +template <typename Value, typename Allocator> +void inline shrink_stl_vector(std::vector<Value, Allocator>& v) +{ + if (v.capacity() > v.size()) { + std::vector<Value, Allocator> tmp(v.begin(), v.end()); + swap(tmp, v); + } +} + + +} // namespace mtl + +#endif // MTL_SHRINK_STL_VECTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/sometimes_data.hpp b/install/MTL/include/boost/numeric/mtl/utility/sometimes_data.hpp new file mode 100644 index 00000000..6a602486 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/sometimes_data.hpp @@ -0,0 +1,37 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_UTILITY_SOMETIMES_DATA_INCLUDE +#define MTL_UTILITY_SOMETIMES_DATA_INCLUDE + +namespace mtl { namespace utility { + +template <bool C, typename T> +struct sometimes_data +{ + sometimes_data(const T& data) : data(data) {} + T data; +}; + +template <typename T> +struct sometimes_data<false, T> +{ + sometimes_data(const T&) {} +}; + +} // namespace utility + +using utility::sometimes_data; + +} // namespace mtl + +#endif // MTL_UTILITY_SOMETIMES_DATA_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/srange.hpp b/install/MTL/include/boost/numeric/mtl/utility/srange.hpp new file mode 100644 index 00000000..98176ca7 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/srange.hpp @@ -0,0 +1,69 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_SRANGE_INCLUDE +#define MTL_SRANGE_INCLUDE + +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> + +namespace mtl { + +class srange +{ + public: + typedef std::size_t size_type; + + /// Create a strided index range of [start, finish) + explicit srange(size_type start, size_type finish, size_type stride) + : my_start(start), my_finish(finish), my_stride(stride) {} + + /// First index in range + size_type start() const { return my_start; } + /// Past-end index in range + size_type finish() const { return my_finish; } + /// Stride + size_type stride() const { return my_stride; } + + /// Number of indices + size_type size() const { return my_finish > my_start ? my_finish - my_start / my_stride : 0; } + + /// Maps integers [0, size()) to [start(), start()+stride(), ..., finish()) + /** Checks index in debug mode. Inverse of from_range. **/ + size_type to_range(size_type i) const + { + MTL_DEBUG_THROW_IF(is_negative(i) || i >= size(), index_out_of_range()); + return my_start + i * my_stride; + } + + /// Maps integers [start(), finish()) to [0, size()) + /** Checks index in debug mode. **/ + size_type from_range(size_type i) const + { + MTL_DEBUG_THROW_IF(i < my_start || i >= my_finish, index_out_of_range()); + MTL_DEBUG_THROW_IF((i - my_start) % my_stride != 0, runtime_error("Index not on stride.")); + return i - my_start; + } + + /// Wether index is in range + bool in_range(size_type i) const + { + return i >= my_start && i < my_finish && (i - my_start) % my_stride == 0; + } + + private: + size_type my_start, my_finish, my_stride; +}; + +} // namespace mtl + +#endif // MTL_SRANGE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/static_assert.hpp b/install/MTL/include/boost/numeric/mtl/utility/static_assert.hpp new file mode 100644 index 00000000..1e5a5978 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/static_assert.hpp @@ -0,0 +1,28 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_STATIC_ASSERT_INCLUDE +#define MTL_STATIC_ASSERT_INCLUDE + +#include <boost/static_assert.hpp> + +namespace mtl { + +#ifdef MTL_WITH_STATICASSERT +# define MTL_STATIC_ASSERT(Condition, Message) static_assert(Condition, Message) +#else +# define MTL_STATIC_ASSERT(Condition, Message) BOOST_STATIC_ASSERT(Condition) +#endif + +} // namespace mtl + +#endif // MTL_STATIC_ASSERT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/static_vector.hpp b/install/MTL/include/boost/numeric/mtl/utility/static_vector.hpp new file mode 100644 index 00000000..955cb3c6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/static_vector.hpp @@ -0,0 +1,74 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_STATIC_VECTOR_INCLUDE +#define MTL_STATIC_VECTOR_INCLUDE + +#if defined(MTL_WITH_STATICASSERT) && defined(MTL_WITH_VARIADIC_TEMPLATE) && defined(MTL_WITH_TEMPLATE_ALIAS) + +#include <cstddef> + +namespace mtl { + + namespace impl { + + // Need helper, cannot specialize class inside class + template <typename Vector, std::size_t Pos> + struct static_vector_get + { + static_assert(Pos < Vector::length, "Position is out of range."); + typedef typename static_vector_get<typename Vector::tail, Pos - 1>::type type; + }; + + template <typename Vector> + struct static_vector_get<Vector, 0> + { + static_assert(Vector::length >= 1, "Position is out of range."); + typedef Vector type; + }; + + } + + + template <typename ValueType, ValueType FirstValue, ValueType ...Values> + struct static_vector + { + typedef ValueType value_type; + typedef static_vector<ValueType, FirstValue, Values...> self; + + static const std::size_t length= sizeof...(Values) + 1; + static const ValueType value= FirstValue; + + typedef static_vector<ValueType, Values...> tail; + + template <std::size_t Pos> + using get= typename impl::static_vector_get<self, Pos>::type; + }; + + template <typename ValueType, ValueType FirstValue> + struct static_vector<ValueType, FirstValue> + { + typedef ValueType value_type; + typedef static_vector<ValueType, FirstValue> self; + + static const std::size_t length= 1; + static const ValueType value= FirstValue; + + template <std::size_t Pos> + using get= typename impl::static_vector_get<self, Pos>::type; + }; + +} // namespace mtl + +#endif // required C++11 features + +#endif // MTL_STATIC_VECTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/strided_dense_el_cursor.hpp b/install/MTL/include/boost/numeric/mtl/utility/strided_dense_el_cursor.hpp new file mode 100644 index 00000000..5e4fa265 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/strided_dense_el_cursor.hpp @@ -0,0 +1,49 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_STRIDED_DENSE_EL_CURSOR_INCLUDE +#define MTL_STRIDED_DENSE_EL_CURSOR_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/detail/strided_base_cursor.hpp> + +namespace mtl { + +/// Cursor going in strides over element of matrix, matrix row/column, or vector +template <typename Value> +struct strided_dense_el_cursor : public detail::strided_base_cursor<const Value*> +{ + typedef Value value_type; + typedef const value_type* const_pointer_type; + typedef detail::strided_base_cursor<const Value*> super; + typedef strided_dense_el_cursor self; + + // strided_dense_el_cursor () {} + strided_dense_el_cursor (const_pointer_type me, size_t stride) : super(me, stride) {} + + template <typename Parameters> + strided_dense_el_cursor(mtl::mat::dense2D<Value, Parameters> const& ma, size_t r, size_t c, size_t stride) + : super(ma.elements() + ma.indexer(ma, r, c), stride) + {} + + // Why do we need this? + strided_dense_el_cursor(super const& x) : super(x) {} + + self operator+(int x) const + { + return super::operator+(x); + } +}; + +} // namespace mtl + +#endif // MTL_STRIDED_DENSE_EL_CURSOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/strided_dense_el_iterator.hpp b/install/MTL/include/boost/numeric/mtl/utility/strided_dense_el_iterator.hpp new file mode 100644 index 00000000..82c0d3bd --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/strided_dense_el_iterator.hpp @@ -0,0 +1,87 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_STRIDED_DENSE_EL_ITERATOR_INCLUDE +#define MTL_STRIDED_DENSE_EL_ITERATOR_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/detail/strided_base_cursor.hpp> + +namespace mtl { + + +/// Iterator going in strides over element of matrix, matrix row/column, or vector +/** - Strided iterator *operator returns (const) reference to Value instead of key + - row(i) and col(i) don't work +**/ +template <typename Value> +struct strided_dense_el_const_iterator + : public detail::strided_base_cursor<const Value*> +{ + typedef const Value* key_type; + typedef detail::strided_base_cursor<key_type> super; + typedef strided_dense_el_const_iterator self; + + strided_dense_el_const_iterator(key_type me, size_t stride) : super(me, stride) {} + + template <typename Parameters> + strided_dense_el_const_iterator(mtl::mat::dense2D<Value, Parameters> const& ma, size_t r, size_t c, size_t stride) + : super(ma.elements() + ma.indexer(ma, r, c), stride) + {} + + self operator+(int x) const + { + return super::operator+(x); + } + + const Value& operator*() const + { + return *(this->key); + } +}; + +/// Iterator going in strides over element of matrix, matrix row/column, or vector +/** - Strided iterator *operator returns (const) reference to Value instead of key + - row(i) and col(i) don't work +**/ +template <typename Value> +struct strided_dense_el_iterator + : public detail::strided_base_cursor<Value*> +{ + typedef Value* key_type; + typedef detail::strided_base_cursor<key_type> super; + typedef strided_dense_el_iterator self; + + strided_dense_el_iterator(key_type me, size_t stride) : super(me, stride) {} + + template <typename Parameters> + strided_dense_el_iterator(mtl::mat::dense2D<Value, Parameters>& ma, size_t r, size_t c, size_t stride) + : super(ma.elements() + ma.indexer(ma, r, c), stride) + {} + + self operator+(int x) const + { + self tmp(*this); + tmp+= x; + return tmp; + } + + Value& operator*() const + { + return *(this->key); + } +}; + + +} // namespace mtl + +#endif // MTL_STRIDED_DENSE_EL_ITERATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/string_to_enum.hpp b/install/MTL/include/boost/numeric/mtl/utility/string_to_enum.hpp new file mode 100644 index 00000000..6043e135 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/string_to_enum.hpp @@ -0,0 +1,39 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_STRING_TO_ENUM_INCLUDE +#define MTL_STRING_TO_ENUM_INCLUDE + +#include <string> +#include <boost/numeric/mtl/operation/size.hpp> + +namespace mtl { + +/** Searches string \p s in list \p l of strings and returns enum + + List \p l is given as array of const char*, which is the easiest to + initialize. The search is case sensitive, thus (de)-capitalize + your string upfront, e.g., with boost::to_lower(). + If the string is not found then a runtime_error is thrown. +**/ +template <typename EnumType, typename Array> +EnumType inline string_to_enum(const std::string& s, const Array& l, EnumType) +{ + std::size_t i; + for (i= 0; i < size(l) && std::string(l[i]) != s; i++) {} + MTL_THROW_IF(i == size(l), runtime_error("Search string not found")); + return EnumType(i); +} + +} // namespace mtl + +#endif // MTL_STRING_TO_ENUM_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/tag.hpp b/install/MTL/include/boost/numeric/mtl/utility/tag.hpp new file mode 100644 index 00000000..30061356 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/tag.hpp @@ -0,0 +1,454 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TAG_INCLUDE +#define MTL_TAG_INCLUDE + +#include <cstddef> +#include <boost/numeric/mtl/utility/glas_tag.hpp> + + +namespace mtl { namespace tag { + +/** @defgroup Tags Tags for concept-free dispatching + * @{ + */ + +// For internal use (e.g., to invalidate range generators) +// Is this the same as bottom? +struct unsupported {}; + +// Name says it +struct dummy3 {}; +struct dummy4 {}; + +/// Tag for all types +struct universe {}; + +/// Tag used to flatten categories +/** The virtual derivation causes perceivable run-time overhead that can be avoided with this struct using traits::flatcat1 and such. **/ +template <typename T> struct flat : universe {}; + +// Tag for any scalar value +/** At the moment default for unknown types (will be precised later) */ +struct scalar : virtual universe {}; + +/// For non-MTL types with category not explicitly defined +/** At the moment all treated as scalars (will be precised later) */ +struct unknown : virtual scalar {}; + +/// Tag for intermediate objects that require explicit evaluation +struct unevaluated : virtual universe {}; + +/// Any collection, i.e. vectors, matrices or higher-dimensional tensor +struct collection : virtual universe {}; + +/// Tag for any MTL vector (and user-declared MTL vectors) +struct vector : virtual collection {}; + +/// Tag for references to vector +/** For instance to not access memory directly but use functions, e.g. in set_to_zero. **/ +struct vector_ref : virtual vector {}; + +/// Tag for any MTL column vector (and user-declared MTL vectors) +struct col_vector : virtual vector {}; + +/// Tag for any MTL row vector (and user-declared MTL vectors) +struct row_vector : virtual vector {}; + +/// Tag for any MTL matrix (and user-declared MTL matrices) +struct matrix : virtual collection {}; + +/// Tag for any dense collection +struct dense : virtual universe {}; + +/// Tag for vectors with one-dimensional memory addressing +/** offet v_i is x*i for some x */ +struct has_1D_layout : virtual dense {}; + +/// Tag for matrices with two-dimensional memory addressing +/** offet a_ij is x*i + y*j for some x and y */ +struct has_2D_layout : virtual dense {}; + +/// Tag for any sparse collection +struct sparse : virtual universe {}; + +// for distinction between dense and sparse matrices +struct dense_matrix : virtual dense, virtual matrix {}; +struct sparse_matrix : virtual sparse, virtual matrix {}; + +/// Tag for collections where values are stored contigously in memory +struct contiguous_memory : virtual universe {}; + +/// Tag for dense and contiguous collections +/** Only short cut */ +struct contiguous_dense : virtual dense, virtual contiguous_memory {}; + +/// Collection with iterator +struct has_iterator : virtual universe {}; + +/// Collection with random-access iterator +struct has_ra_iterator : virtual has_iterator {}; + +/// Collection with fast random-access iterator +/** Meaning: unrolling is probably beneficial. Counter-example: Morton-ordered matrices have + random access but this is so slow that regular traversal is favorable */ +struct has_fast_ra_iterator : virtual has_ra_iterator {}; + +/// Collection with cursor +struct has_cursor : virtual universe {}; + +/// Collection with random-access cursor +struct has_ra_cursor : virtual has_cursor {}; + +/// Collection with fast random-access cursor +/** Meaning: unrolling is probably beneficial. Counter-example: Morton-ordered matrices have + random access but this is so slow that regular traversal is favorable */ +struct has_fast_ra_cursor : virtual has_ra_cursor {}; + +/// Tag for matrices with sub_matrix function exist and doesn't say for which ranges it is defined +struct has_sub_matrix : virtual universe {}; + +/// Sub-divisible into quadrants, i.e. arbitrary sub-matrices not necessarily supported but recursion works +// more explanation needed +struct qsub_divisible : virtual has_sub_matrix {}; + +/// Tag for sub-divisible matrix, i.e. sub_matrix works +struct sub_divisible : virtual qsub_divisible {}; + +/// Tag for dense row vector in the category lattice +struct dense_row_vector + : virtual row_vector, virtual contiguous_dense, + virtual has_fast_ra_iterator, virtual has_fast_ra_cursor, virtual has_1D_layout +{}; + +/// Tag for dense column vector in the category lattice +struct dense_col_vector + : virtual col_vector, virtual contiguous_dense, + virtual has_fast_ra_iterator, virtual has_fast_ra_cursor, virtual has_1D_layout +{}; + +/// Tag for strided row vector in the category lattice +struct strided_row_vector + : virtual row_vector, virtual vector_ref, + virtual has_fast_ra_iterator, virtual has_fast_ra_cursor, virtual has_1D_layout +{}; + +/// Tag for strided column vector in the category lattice +struct strided_col_vector + : virtual col_vector, virtual vector_ref, + virtual has_fast_ra_iterator, virtual has_fast_ra_cursor, virtual has_1D_layout +{}; + +/// Tag for sparse row vector in the category lattice +struct sparse_row_vector + : virtual row_vector, virtual sparse +{}; + +/// Tag for sparse column vector in the category lattice +struct sparse_col_vector + : virtual col_vector, virtual sparse +{}; + +/// Tag to handle std::vector in the category lattice +struct std_vector + : virtual vector, virtual contiguous_dense, virtual has_1D_layout +{}; + +/// Tag for a view on a (regular) dense matrix in the category lattice +/** The map perform address computation and has therefore no 2D-layout. + It is also not (yet) assumed that the view provides iterators. */ +struct dense2D_view + : virtual matrix, virtual contiguous_dense, virtual has_fast_ra_cursor + // , virtual sub_divisible // is currently not sub-divisible +{}; + +/// Tag for (regular) dense matrix in the category lattice +struct dense2D + : virtual dense2D_view, virtual has_fast_ra_iterator, virtual has_2D_layout, virtual sub_divisible +{}; + +struct implicit_dense + : virtual matrix, virtual dense, virtual has_fast_ra_cursor +{}; + +/// Tag for a view on a Morton-order matrix in the category lattice +/** It is not (yet) assumed that the view provides iterators. */ +struct morton_view + : virtual matrix, virtual contiguous_dense, + virtual has_ra_cursor // , virtual qsub_divisible // is currently not sub-divisible +{}; + + +/// Tag for Morton-order matrix in the category lattice +struct morton_dense + : virtual morton_view, virtual has_ra_iterator, virtual qsub_divisible +{}; + +/// Tag for a view on a compressed matrix in the category lattice +/** It is not (yet) assumed that the view provides iterators. */ +struct compressed2D_view + : virtual matrix, virtual sparse, virtual has_cursor +{}; + +/// Tag for compressed matrix in the category lattice +struct compressed2D + : virtual compressed2D_view, virtual has_iterator +{}; + +/// Tag for multi_vector +// Maybe splitting later into sparse and dense form +struct multi_vector + : virtual matrix, virtual dense +{}; + +/// Tag for transposed multi_vector +// Maybe splitting later into sparse and dense form +struct transposed_multi_vector + : virtual matrix, virtual dense +{}; + +/// Tag for transposed multi_vector +// Maybe splitting later into sparse and dense form +struct hermitian_multi_vector + : virtual matrix, virtual dense +{}; + +/// Tag for ell_matrix (preliminary) +struct ell_matrix + : sparse_matrix +{}; + +/// Tag for element structure matrix +struct element_structure + : sparse_matrix +{}; + +/// Tag for element structure matrix +struct sparse_banded_matrix + : sparse_matrix +{}; + +/// Tag for mat_cvec_multiplier +struct mat_cvec_multiplier + : col_vector +{}; + +/// Tag for implicit dense matrices + + +/// Tag for bottom of the category lattice +/** Only for completeness; probably not needed in practice. */ +struct bottom + : virtual compressed2D, virtual morton_dense, virtual dense2D, + virtual dense_col_vector, virtual dense_row_vector, virtual unknown, + virtual multi_vector +{}; + +template <typename Tag1, typename Tag2, typename Tag3= dummy3, typename Tag4= dummy4> +struct join + : virtual Tag1, virtual Tag2, virtual Tag3, virtual Tag4 +{}; + + +// ===================== +// Types for orientation +// ===================== + + +/// Characterizes row-major orientation in matrices and row vector in 1D +struct row_major {}; + +/// Characterizes column-major orientation in matrices and column vector in 1D +struct col_major {}; + +/// Synonym for col_major +typedef col_major column_major; + +/// Common base for diagonal tags +struct universe_diagonal {}; + +/// Tag indicating that diagonal is stored regularly +struct regular_diagonal : universe_diagonal {}; + +/// Tag indicating that diagonal contains unit elements +struct unit_diagonal : universe_diagonal {}; + +/// Tag indicating that diagonal entries are stored as inverses +/** Storing value in different ways can be faster in several algorithms. + By the time of this writing it is experimental and only used + in upper_trisolve and lower_trisolve. **/ +struct inverse_diagonal : universe_diagonal {}; + + + + +/*@}*/ // end of group Tags + +} // namespace mtl::tag + +/** @addtogroup Tags + * @{ + */ + +// Import in mtl namespace +using tag::row_major; +using tag::col_major; +using tag::column_major; +using tag::sparse; +using tag::dense; + +#ifdef MTL_DOX_ONLY +// using is not documented therefor the redeclaration here + +/// Characterizes row-major orientation in matrices and row vector in 1D, import of tag::row_major +struct row_major {}; + +/// Characterizes column-major orientation in matrices and column vector in 1D, import of tag::col_major +struct col_major {}; + +/// Synonym for col_major, import of tag::column_major +struct column_major {}; + +/// Tag for any sparse collection, import of tag::sparse +struct sparse {}; + +/// Tag for any dense collection, import of tag::dense +struct dense {}; + +#endif + + +/// Tag for any banded collection +struct banded {}; + +/// Tag for any compressed collection +struct compressed {}; + +/// Tag for coordinate matrix +struct coordinate {}; + +/// Tag for Ellpack matrices +struct ellpack {}; + +/// Tag synonym for Ellpack matrices +typedef ellpack ell; + +/// Tag for any morton-orded collection +struct morton {}; + +/// Tag for any symmetric collection +struct symmetric {}; + +/// Tag for any anti-symmetric collection +struct anti_symmetric {}; + +/// Tag for any self-adjoint, i.e. Hermitian collection +struct self_adjoint {}; + +/// Tag for specifying size type in type generators +template <typename T> +struct as_size_type +{ + typedef T type; +}; + +/// Tag for any collection stored on stack +struct on_stack {}; + +/// Tag for any collection stored on heap +struct on_heap {}; + +#ifdef MTL_WITH_VARIADIC_TEMPLATE + +/// To define compile-time dimension in type generators +template <std::size_t ...Values> +struct dim {}; + +/// To define mask for Morton-order +template <std::size_t ...Values> +struct mask {}; + +#endif + +/*@}*/ // end of group Tags + +// ===================== +// Tags for traversals +// Import some from GLAS +// ===================== + +namespace tag { + +/** @addtogroup Tags + * @{ + */ + + /// Tag for cursor traversal of non-zero elements of a collection + /** Also used for elements within rows and columns */ + using glas::tag::nz; + + /// Tag for cursor traversal of all elements of a collection + /** Also used for elements within rows and columns */ + using glas::tag::all; + + /// Tag for traversal of all rows in a matrix + using glas::tag::row; + /// Tag for traversal of all columns in a matrix + using glas::tag::col; + + /// Tag for traversal of a matrix's major dimension + /** Is equivalent to glas::tag::row for row-major matrices and + glas::tag::col for column-major matrices */ + using glas::tag::major; + + /// Tag for traversal of a matrix's minor dimension + /** Is equivalent to glas::tag::row for row-major matrices and + glas::tag::col for column-major matrices */ + using glas::tag::minor; + + // To define iterators over matrices or rows/cols of it, vectors + + namespace iter { + + /// Tag for iterator traversal of non-zero elements of a collection + /** Also used for elements within rows and columns */ + struct nz {}; + + /// Tag for iterator traversal of all elements of a collection + /** Also used for elements within rows and columns */ + struct all {}; + + } // namespace mtl::tag::iter + + // Same with const iterators + + namespace const_iter { + + /// Tag for const-iterator traversal of non-zero elements of a collection + /** Also used for elements within rows and columns */ + struct nz {}; + + /// Tag for const-iterator traversal of all elements of a collection + /** Also used for elements within rows and columns */ + struct all {}; + + } // namespace mtl::tag::const_iter + +/*@}*/ // end of group Tags + +} // namespace mtl::tag + + +} // namespace mtl + +#endif // MTL_TAG_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/transposed_matrix_type.hpp b/install/MTL/include/boost/numeric/mtl/utility/transposed_matrix_type.hpp new file mode 100644 index 00000000..fc48d83f --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/transposed_matrix_type.hpp @@ -0,0 +1,81 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_TRANSPOSED_MATRIX_TYPE_INCLUDE +#define MTL_TRAITS_TRANSPOSED_MATRIX_TYPE_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/transposed_orientation.hpp> + +namespace mtl { namespace traits { + +template <class T> struct transposed_matrix_parameter {}; + +template <typename O, typename I, typename D, bool S, typename ST> +struct transposed_matrix_parameter<mat::parameters<O, I, D, S, ST> > +{ + typedef mat::parameters<typename transposed_orientation<O>::type, I, D, S, ST> type; +}; + +template <class T> struct transposed_matrix_type {}; + +template <typename Value, typename Parameters> +struct transposed_matrix_type<mat::dense2D<Value, Parameters> > +{ + typedef mat::dense2D<Value, typename transposed_matrix_parameter<Parameters>::type> type; +}; + +template <typename Value, typename Parameters> +struct transposed_matrix_type<mat::compressed2D<Value, Parameters> > +{ + typedef mat::compressed2D<Value, typename transposed_matrix_parameter<Parameters>::type> type; +}; + +template <typename Value, std::size_t Mask, typename Parameters> +struct transposed_matrix_type<mat::morton_dense<Value, Mask, Parameters> > +{ + typedef mat::morton_dense<Value, Mask, typename transposed_matrix_parameter<Parameters>::type> type; +}; + + + + +template <class T> struct transposed_sparse_matrix_type {}; + +template <typename Value, typename Parameters> +struct transposed_sparse_matrix_type<mat::compressed2D<Value, Parameters> > +{ + typedef mat::compressed2D<Value, typename transposed_matrix_parameter<Parameters>::type> type; +}; + +template <typename Matrix> +struct transposed_sparse_matrix_type<mat::banded_view<Matrix> > +{ + typedef typename transposed_sparse_matrix_type<Matrix>::type type; +}; + + +template <typename Value, typename Parameters> +struct transposed_sparse_matrix_type<mat::transposed_view<mat::compressed2D<Value, Parameters> > > +{ + typedef mat::compressed2D<Value, Parameters> type; +}; + +template <typename Value, typename Parameters> +struct transposed_sparse_matrix_type<mat::transposed_view<const mat::compressed2D<Value, Parameters> > > +{ + typedef mat::compressed2D<Value, Parameters> type; +}; + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_TRANSPOSED_MATRIX_TYPE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/transposed_orientation.hpp b/install/MTL/include/boost/numeric/mtl/utility/transposed_orientation.hpp new file mode 100644 index 00000000..96d0f068 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/transposed_orientation.hpp @@ -0,0 +1,36 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_TRANSPOSED_ORIENTATION_INCLUDE +#define MTL_TRAITS_TRANSPOSED_ORIENTATION_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace traits { + +/// Orientation type for transposed matrices and vectors +template <class T> struct transposed_orientation {}; + +template<> struct transposed_orientation<tag::row_major> +{ + typedef tag::col_major type; +}; + +template<> struct transposed_orientation<tag::col_major> +{ + typedef tag::row_major type; +}; + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_TRANSPOSED_ORIENTATION_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/true_copy.hpp b/install/MTL/include/boost/numeric/mtl/utility/true_copy.hpp new file mode 100644 index 00000000..20332d97 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/true_copy.hpp @@ -0,0 +1,33 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_TRUE_COPY_INCLUDE +#define MTL_TRAITS_TRUE_COPY_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace traits { + +/// Type trait to force copy +/** Some libs define types to force shallow copy. This causes stale references in expression templates. + To counter-act we substitute the types, e.g. mp_real_tmp with mp_real, to force a copy. **/ +template <typename T> +struct true_copy +{ + typedef T type; +}; + + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_TRUE_COPY_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/type_parameter.hpp b/install/MTL/include/boost/numeric/mtl/utility/type_parameter.hpp new file mode 100644 index 00000000..5b903ae8 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/type_parameter.hpp @@ -0,0 +1,98 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TYPE_PARAMETER_INCLUDE +#define MTL_TYPE_PARAMETER_INCLUDE + +#if defined(MTL_WITH_VARIADIC_TEMPLATE) && defined(MTL_WITH_STATICASSERT) + +#include <boost/numeric/mtl/utility/type_parameter_local.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/erase_key.hpp> +#include <boost/mpl/insert.hpp> + +namespace mtl { + + namespace type_para { + + typedef init_local init; + typedef kind_map_local kind_map; + + // Error message that this kind of parameter is already set + template <typename Kind> + struct error_message + : error_message_local<Kind> {}; + + // Print an error message if the value is not none, i.e. the parameter is already set + template <typename Element> + struct check + : error_message<typename Element::first> {}; + + // Spezialize for virgin parameters, nothing to do + template <typename Key> + struct check<boost::mpl::pair<Key, none> > { typedef int type; }; + + + // Set parameter Value by replacing according entry in TypePara + template <typename TypePara, typename Value> + struct set_para + { + typedef typename find_kind<kind_map, Value>::type kind; + + // find entry in type paras + typedef typename boost::mpl::at<TypePara, kind>::type value; + + // check whether is not yet set + typedef typename check<boost::mpl::pair<kind, value> >::type check_dummy; + + // erase empty entry + typedef typename boost::mpl::erase_key<TypePara, kind>::type short_para; + + // insert new entry + typedef typename boost::mpl::insert<short_para, short_para, boost::mpl::pair<kind, Value> >::type type; + }; + + + template <typename TypePara, typename ...Values> + struct set_parameters + { + typedef TypePara type; + }; + + template <typename TypePara, typename FirstValue, typename ...Values> + struct set_parameters<TypePara, FirstValue, Values...> + { + typedef typename set_para<TypePara, FirstValue>::type next_parameters; + typedef typename set_parameters<next_parameters, Values...>::type type; + }; + + template <typename TypePara> + struct replace_defaults + : replace_defaults_local<TypePara> {}; + + + + } // namespace type_para + + template <typename ...Values> + struct set_parameters + { + typedef typename type_para::set_parameters<type_para::init, Values...>::type parameters_by_user; + typedef typename type_para::replace_defaults<parameters_by_user>::type type; + }; + + +} // namespace mtl + +#endif // defined(MTL_WITH_VARIADIC_TEMPLATE) && defined(MTL_WITH_STATICASSERT) + +#endif // MTL_TYPE_PARAMETER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/type_parameter_common.hpp b/install/MTL/include/boost/numeric/mtl/utility/type_parameter_common.hpp new file mode 100644 index 00000000..83f531a2 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/type_parameter_common.hpp @@ -0,0 +1,162 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TYPE_PARAMETER_COMMON_INCLUDE +#define MTL_TYPE_PARAMETER_COMMON_INCLUDE + +#if defined(MTL_WITH_VARIADIC_TEMPLATE) && defined(MTL_WITH_STATICASSERT) + +#include <utility> +#include <cstddef> + +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/pair.hpp> +#include <boost/mpl/map.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/if.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> + + +namespace mtl { + + namespace type_para { + + // Helper type for still unset parameter + struct none {}; + + // Parameter kinds (extensible) + struct density {}; + struct layout {}; + struct symmetry {}; + struct orientation {}; + struct dimensionality {}; + struct size_type {}; + struct location {}; + struct masking {}; + + // Initial map for common parameter kinds (extensible) + typedef boost::mpl::map< + boost::mpl::pair<density, none>, + boost::mpl::pair<layout, none>, + boost::mpl::pair<symmetry, none>, + boost::mpl::pair<orientation, none>, + boost::mpl::pair<dimensionality, none>, + boost::mpl::pair<size_type, none>, + boost::mpl::pair<location, none>, + boost::mpl::pair<masking, none> + > init_common; + + // The kinds of common parameters except templated parameters + typedef boost::mpl::map< + boost::mpl::pair<sparse, density>, + boost::mpl::pair<dense, density>, + boost::mpl::pair<banded, layout>, + boost::mpl::pair<compressed, layout>, + boost::mpl::pair<coordinate, layout>, + boost::mpl::pair<ellpack, layout>, + boost::mpl::pair<morton, layout>, + boost::mpl::pair<symmetric, symmetry>, + boost::mpl::pair<anti_symmetric, symmetry>, + boost::mpl::pair<self_adjoint, symmetry>, + boost::mpl::pair<row_major, orientation>, + boost::mpl::pair<col_major, orientation>, + boost::mpl::pair<on_stack, location>, + boost::mpl::pair<on_heap, location> + > kind_map_common; + + // Find the kind of a parameter + // templated parameters are handled by specialization + // Spezialization can be extended in including headers + template <typename KindMap, typename Kind> + struct find_kind + { + typedef typename boost::mpl::at<KindMap, Kind>::type type; + static_assert( !boost::is_same<type, mpl_::void_>::value, + "The type you providing (the second parameter of find_kind) is not used in the type generator."); + }; + + template <typename KindMap, std::size_t ...Values> + struct find_kind<KindMap, dim<Values...> > + { + typedef dimensionality type; + }; + + template <typename KindMap, std::size_t ...Values> + struct find_kind<KindMap, mask<Values...> > + { + typedef masking type; + }; + + template <typename KindMap, typename Index> + struct find_kind<KindMap, as_size_type<Index> > + { + typedef size_type type; + }; + + + // Error message that this kind of parameter is already set + template <typename Kind> + struct error_message_common + { + static_assert( !boost::is_same<Kind, density>::value, "Density (dense, sparse) is set twice."); + static_assert( !boost::is_same<Kind, layout>::value, "Layout (banded, compressed, ...) is set twice."); + static_assert( !boost::is_same<Kind, symmetry>::value, "Symmetry is set twice."); + static_assert( !boost::is_same<Kind, orientation>::value, "Orientation (row_major, col_major) is set twice."); + static_assert( !boost::is_same<Kind, location>::value, "Location (on_heap, on_stack) is set twice."); + typedef int type; + }; + + template <typename TypePara> + struct replace_defaults_common + { + typedef typename boost::mpl::at<TypePara, dimensionality>::type dim1; + typedef typename boost::mpl::at<TypePara, location>::type loc1; + + static_assert( !boost::is_same<loc1, on_stack>::value || boost::is_same<dim1, none>::value, + "Types to be stored on stack must provide static size."); + + // if location not set take stack as default when dim is given otherwise heap + typedef typename boost::mpl::if_< + boost::is_same<loc1, none>, + typename boost::mpl::if_<boost::is_same<dim1, none>, + on_heap, + on_stack>::type, + loc1>::type loc2; + + typedef typename boost::mpl::at<TypePara, size_type>::type size1; + typedef typename boost::mpl::if_<boost::is_same<size1, none>, + as_size_type<std::size_t>, + size1>::type size2; + + typedef boost::mpl::map< + boost::mpl::pair<density, typename boost::mpl::at<TypePara, density>::type>, + boost::mpl::pair<layout, typename boost::mpl::at<TypePara, layout>::type>, + boost::mpl::pair<symmetry, typename boost::mpl::at<TypePara, symmetry>::type>, + boost::mpl::pair<orientation, typename boost::mpl::at<TypePara, orientation>::type>, + boost::mpl::pair<dimensionality, dim1>, + boost::mpl::pair<size_type, size2>, + boost::mpl::pair<location, loc2>, + boost::mpl::pair<masking, typename boost::mpl::at<TypePara, masking>::type> + > type; + }; + + + } // namespace type_para + +} // namespace mtl + +#endif // defined(MTL_WITH_VARIADIC_TEMPLATE) && defined(MTL_WITH_STATICASSERT) + +#endif // MTL_TYPE_PARAMETER_COMMON_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/type_parameter_local.hpp b/install/MTL/include/boost/numeric/mtl/utility/type_parameter_local.hpp new file mode 100644 index 00000000..13af3f9c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/type_parameter_local.hpp @@ -0,0 +1,43 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TYPE_PARAMETER_LOCAL_INCLUDE +#define MTL_TYPE_PARAMETER_LOCAL_INCLUDE + +#if defined(MTL_WITH_VARIADIC_TEMPLATE) && defined(MTL_WITH_STATICASSERT) + +#include <boost/numeric/mtl/utility/type_parameter_common.hpp> + +namespace mtl { + + namespace type_para { + + typedef init_common init_local; + typedef kind_map_common kind_map_local; + + // Error message that kind is already set + template <typename Kind> + struct error_message_local + : error_message_common<Kind> {}; + + template <typename TypePara> + struct replace_defaults_local + : replace_defaults_common<TypePara> {}; + + + } + +} // namespace mtl + +#endif // defined(MTL_WITH_VARIADIC_TEMPLATE) && defined(MTL_WITH_STATICASSERT) + +#endif // MTL_TYPE_PARAMETER_LOCAL_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/unroll_size1.hpp b/install/MTL/include/boost/numeric/mtl/utility/unroll_size1.hpp new file mode 100644 index 00000000..3b063965 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/unroll_size1.hpp @@ -0,0 +1,36 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_UNROLL_SIZE1_INCLUDE +#define MTL_TRAITS_UNROLL_SIZE1_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace traits { + +/// Type trait for one-dimensional unrolling, default is 4. +template <typename Collection> +struct unroll_size1 +{ + static const unsigned value0= 4; +}; + +template <unsigned BSize, typename Vector> +struct unroll_size1<vec::unrolled1<BSize, Vector> > +{ + static const unsigned value0= BSize; +}; + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_UNROLL_SIZE1_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/updater_to_assigner.hpp b/install/MTL/include/boost/numeric/mtl/utility/updater_to_assigner.hpp new file mode 100644 index 00000000..8300761e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/updater_to_assigner.hpp @@ -0,0 +1,45 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_UPDATER_TO_ASSIGNER_INCLUDE +#define MTL_TRAITS_UPDATER_TO_ASSIGNER_INCLUDE + +#include <boost/numeric/mtl/operation/assign_mode.hpp> +#include <boost/numeric/mtl/operation/update.hpp> + +namespace mtl { namespace traits { + +template <typename Updater> +struct updater_to_assigner +{}; + +template <typename Element> +struct updater_to_assigner<mtl::operations::update_store<Element> > +{ + typedef mtl::assign::assign_sum type; +}; + +template <typename Element> +struct updater_to_assigner<mtl::operations::update_plus<Element> > +{ + typedef mtl::assign::plus_sum type; +}; + +template <typename Element> +struct updater_to_assigner<mtl::operations::update_minus<Element> > +{ + typedef mtl::assign::minus_sum type; +}; + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_UPDATER_TO_ASSIGNER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/vector_type_generator.hpp b/install/MTL/include/boost/numeric/mtl/utility/vector_type_generator.hpp new file mode 100644 index 00000000..51dbd4d2 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/vector_type_generator.hpp @@ -0,0 +1,101 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_TYPE_GENERATOR_INCLUDE +#define MTL_VECTOR_TYPE_GENERATOR_INCLUDE + +#if defined(MTL_WITH_VARIADIC_TEMPLATE) && defined(MTL_WITH_STATICASSERT) + +#include <cstddef> +#include <boost/type_traits/is_same.hpp> +#include <boost/mpl/map.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/if.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/type_parameter.hpp> +#include <boost/numeric/mtl/vector/dimension.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> +#include <boost/numeric/mtl/recursion/predefined_masks.hpp> + +namespace mtl { + + + namespace type_para { + + template <typename DimPara> + struct set_vector_dimensions + { + static_assert(! boost::is_same<DimPara, DimPara>::value, "Unsupported argument for vector dimension."); + }; + + template <> + struct set_vector_dimensions<none> + { + typedef mtl::vec::non_fixed::dimension type; + }; + + template <std::size_t ...Values> + struct set_vector_dimensions<dim<Values...> > + { + static_assert(sizeof...(Values) == 1, "dim<size> must have exactly 1 argument for vectors!"); + }; + + template <std::size_t Size> + struct set_vector_dimensions<dim<Size> > + { + typedef mtl::vec::fixed::dimension<Size> type; + }; + + + template <typename TypePara> + struct vector_parameter_generator + { + typedef typename boost::mpl::at<TypePara, orientation>::type ori1; + typedef typename boost::mpl::if_<boost::is_same<ori1, none>, + col_major, + ori1>::type ori2; + + typedef typename set_vector_dimensions<typename boost::mpl::at<TypePara, dimensionality>::type>::type dim_type; + typedef typename boost::mpl::at<TypePara, size_type>::type as_size; + typedef mtl::vec::parameters< + ori2, + dim_type, + boost::is_same<typename boost::mpl::at<TypePara, location>::type, on_stack>::value, + typename as_size::type + > type; + }; + + + template <typename Value, typename TypePara> + struct vector_type_generator + { + typedef typename vector_parameter_generator<TypePara>::type vector_parameters; + typedef typename boost::mpl::if_< + boost::is_same<typename boost::mpl::at<TypePara, density>::type, sparse>, + mtl::vec::sparse_vector<Value, vector_parameters>, + mtl::vec::dense_vector<Value, vector_parameters> + >::type type; + }; + + } // namespace type_para + +# ifdef MTL_WITH_TEMPLATE_ALIAS + template <typename Value, typename ...Parameters> + using vector= typename type_para::vector_type_generator<Value, typename set_parameters<Parameters...>::type>::type; +# endif + +} // namespace mtl + +#endif // defined(MTL_WITH_VARIADIC_TEMPLATE) && defined(MTL_WITH_STATICASSERT) + +#endif // MTL_VECTOR_TYPE_GENERATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/view_code.hpp b/install/MTL/include/boost/numeric/mtl/utility/view_code.hpp new file mode 100644 index 00000000..a5e33270 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/view_code.hpp @@ -0,0 +1,98 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_VIEW_CODE_INCLUDE +#define MTL_TRAITS_VIEW_CODE_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/is_what.hpp> + +namespace mtl { namespace traits { + +/// Represent views by code (quite advanced feature for internal use) +/** 1-bit: constant + 2-bit: conjugated + 4-bit: transposed + -> hermitian_view of constant matrix is 7. **/ +template <typename T> +struct view_code +{ + MTL_STATIC_ASSERT(is_matrix<T>::value, "Currently only matrices are supported."); + static const unsigned value= 0; ///< Default is zero +}; + +template <typename T> +struct view_code<const T> +{ + static const unsigned value= view_code<T>::value | 1; ///< Toggle constancy bit +}; + +template <typename Matrix> +struct view_code< mat::conj_view<Matrix> > +{ + static const unsigned value= view_code<Matrix>::value ^ 2; ///< Toggle conjugation bit +}; + +template <typename Matrix> +struct view_code<mtl::mat::transposed_view<Matrix> > +{ + static const unsigned value= view_code<Matrix>::value ^ 4; ///< Toggle transposition bit +}; + +template <typename Matrix> +struct view_code<mtl::mat::hermitian_view<Matrix> > +{ + static const unsigned value= view_code<Matrix>::value ^ 6; ///< Toggle transposition and conjugation bit +}; + +// add vector stuff + +template <unsigned Value> +struct view_normalize_const +{ + static const unsigned tmp2= Value == 0 || Value == 4 ? Value | 1 : Value, // if matrix ref or transposed, make it const + value= (tmp2 & 3) == 3 ? tmp2 ^ 1 : tmp2; // for conj turn off const +}; + +template <typename ViewCode> +struct view_add_const +{ + static const unsigned value= ViewCode::value | 1; +}; + +template <typename ViewCode> +struct view_remove_const +{ + static const unsigned value= ViewCode::value & ~1; +}; + +template <typename ViewCode> +struct view_toggle_conj +{ + static const unsigned value= view_normalize_const<ViewCode::value ^ 2>::value; +}; + +template <typename ViewCode> +struct view_toggle_trans +{ + static const unsigned value= ViewCode::value ^ 4; +}; + +template <typename ViewCode> +struct view_toggle_hermitian +{ + static const unsigned value= view_normalize_const<ViewCode::value ^ 6>::value; +}; + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_VIEW_CODE_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/viewed_collection.hpp b/install/MTL/include/boost/numeric/mtl/utility/viewed_collection.hpp new file mode 100644 index 00000000..c012769c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/viewed_collection.hpp @@ -0,0 +1,49 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_VIEWED_COLLECTION_INCLUDE +#define MTL_TRAITS_VIEWED_COLLECTION_INCLUDE + +#include <boost/type_traits/remove_const.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/is_what.hpp> + +namespace mtl { namespace traits { + +/// Type of the viewed matrix or vector, by default itself +template <typename T> +struct viewed_collection +{ + MTL_STATIC_ASSERT(is_matrix<T>::value, "Currently only matrices are supported."); + typedef typename boost::remove_const<T>::type type; +}; + +template <typename Matrix> +struct viewed_collection< mat::conj_view<Matrix> > + : viewed_collection<Matrix> +{}; + +template <typename Matrix> +struct viewed_collection< mat::transposed_view<Matrix> > + : viewed_collection<Matrix> +{}; + +template <typename Matrix> +struct viewed_collection< mat::hermitian_view<Matrix> > + : viewed_collection<Matrix> +{}; + +// add vector stuff + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_VIEWED_COLLECTION_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/with_unroll1.hpp b/install/MTL/include/boost/numeric/mtl/utility/with_unroll1.hpp new file mode 100644 index 00000000..20092e0e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/with_unroll1.hpp @@ -0,0 +1,33 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_TRAITS_WITH_UNROLL1_INCLUDE +#define MTL_TRAITS_WITH_UNROLL1_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace traits { + +/// Type trait for enabling one-dimensional unrolling, default is false. +template <typename Collection> +struct with_unroll1 + : boost::mpl::false_ {}; + +template <unsigned BSize, typename Vector> +struct with_unroll1<vec::unrolled1<BSize, Vector> > + : boost::mpl::true_ {}; + + +}} // namespace mtl::traits + +#endif // MTL_TRAITS_WITH_UNROLL1_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/wrapped_object.hpp b/install/MTL/include/boost/numeric/mtl/utility/wrapped_object.hpp new file mode 100644 index 00000000..aa4493cf --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/wrapped_object.hpp @@ -0,0 +1,37 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_WRAPPED_OBJECT_INCLUDE +#define MTL_WRAPPED_OBJECT_INCLUDE + +namespace mtl { + +/// Wrapper for objects +/** Can be referred in base classes to preserve initialization order + and avoid ambiguities. Using the object as base class can cause + name clashes and as member it cannot be initialized after all + base classes with pedantic warnings. **/ +template <typename View> +struct wrapped_object +{ + template <typename T> + wrapped_object(T& x) : wrapped_object_member(x) {} + + template <typename T, typename U> + wrapped_object(const T& x, const U& y) : wrapped_object_member(x, y) {} + + View wrapped_object_member; // ugly name avoid ambiguities in derived classes +}; + +} // namespace mtl + +#endif // MTL_WRAPPED_OBJECT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/utility/zipped_sort.hpp b/install/MTL/include/boost/numeric/mtl/utility/zipped_sort.hpp new file mode 100644 index 00000000..b4bb0934 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/utility/zipped_sort.hpp @@ -0,0 +1,212 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ZIPPED_SORT_INCLUDE +#define MTL_ZIPPED_SORT_INCLUDE + +// Designed for pointers so far and not tested for general iterators +// For internal use only + +#include <cmath> +#include <utility> +#include <iterator> +#include <boost/numeric/mtl/utility/exception.hpp> + +namespace mtl { namespace utility { + +template <typename T, typename U> struct zip_ref; +template <typename T, typename U> struct zip_it; +template <typename T, typename U> struct zip_value; + +struct less_0 +{ + template <typename T, typename U> + bool operator()(const zip_ref<T, U>& x, const zip_ref<T, U>& y) const + { + return x.a[x.p] < y.a[y.p]; + } + + template <typename T, typename U> + bool operator()(const zip_ref<T, U>& x, const zip_value<T, U>& y) const + { + return x.a[x.p] < y.x; + } + + template <typename T, typename U> + bool operator()(const zip_value<T, U>& x, const zip_ref<T, U>& y) const + { + return x.x < y.a[y.p]; + } +}; + +struct greater_0 +{ + template <typename T, typename U> + bool operator()(const zip_ref<T, U>& x, const zip_ref<T, U>& y) const + { + return x.a[x.p] > y.a[y.p]; + } + + template <typename T, typename U> + bool operator()(const zip_ref<T, U>& x, const zip_value<T, U>& y) const + { + return x.a[x.p] > y.x; + } + + template <typename T, typename U> + bool operator()(const zip_value<T, U>& x, const zip_ref<T, U>& y) const + { + return x.x > y.a[y.p]; + } +}; + +struct abs_greater_0 +{ + template <typename T, typename U> + bool operator()(const zip_ref<T, U>& x, const zip_ref<T, U>& y) const + { + using std::abs; + return abs(x.a[x.p]) > abs(y.a[y.p]); + } + + template <typename T, typename U> + bool operator()(const zip_ref<T, U>& x, const zip_value<T, U>& y) const + { + using std::abs; + return abs(x.a[x.p]) > abs(y.x); + } + + template <typename T, typename U> + bool operator()(const zip_value<T, U>& x, const zip_ref<T, U>& y) const + { + using std::abs; + return abs(x.x) > abs(y.a[y.p]); + } +}; + + +template <typename T, typename U> +struct zip_it +{ + typedef zip_ref<T, U> ref_type; + typedef long diff_type; + // typedef std::difference_type diff_type; + + explicit zip_it(T* a, U* v, diff_type p) : a(a), v(v), p(p) {} + + ref_type operator*() { return ref_type(a, v, p); } + zip_it& operator++() { p++; return *this;} + zip_it operator++(int) { zip_it tmp(a, v, p); p++; return tmp;} + zip_it& operator--() { p--; return *this;} + zip_it operator--(int) { zip_it tmp(a, v, p); p--; return tmp;} + + void check(const zip_it& MTL_DEBUG_ARG(other)) const { assert(a == other.a); assert(v == other.v); } + + bool operator==(const zip_it& other) const { check(other); return p == other.p; } + bool operator!=(const zip_it& other) const { check(other); return p != other.p; } + bool operator<=(const zip_it& other) const { check(other); return p <= other.p; } + bool operator<(const zip_it& other) const { check(other); return p < other.p; } + bool operator>=(const zip_it& other) const { check(other); return p >= other.p; } + bool operator>(const zip_it& other) const { check(other); return p > other.p; } + diff_type operator-(const zip_it& other) const { check(other); return p - other.p; } + zip_it operator+(diff_type i) const { return zip_it(a, v, p+i); } + zip_it& operator+=(diff_type i) { p+= i; return *this; } + zip_it operator-(diff_type i) const { return zip_it(a, v, p-i); } + zip_it& operator=(const zip_it& other) { check(other); p= other.p; return *this; } + + T* a; + U* v; + diff_type p; +}; + + +template <typename T, typename U> +struct zip_ref +{ + typedef zip_ref self; + + zip_ref(T* a, U* v, int p) : a(a), v(v), p(p) {} + + void check(const zip_ref& MTL_DEBUG_ARG(other)) const { assert(a == other.a); assert(v == other.v); } + + bool operator<(const zip_ref& r) const { check(r); return a[p] < r.a[r.p]; } + zip_ref& operator=(const zip_ref& r) + { + check(r); + if (p == r.p) + return *this; + a[p]= r.a[r.p]; v[p]= r.v[r.p]; + p= r.p; + return *this; + } +#ifdef MTL_WITH_MOVE + zip_ref& operator=(zip_value<T, U>&& zv) + { + a[p]= zv.x; + v[p]= zv.y; + return *this; + } +#endif + + zip_ref& operator=(const zip_value<T, U>& zv) + { + a[p]= zv.x; + v[p]= zv.y; + return *this; + } + + T *a; + U *v; + int p; + +}; + +// const ref is ugly but mutable ref doesn't work with temporaries and copy is not as good as overload +template <typename T, typename U> +inline void swap(const zip_ref<T, U>& x, const zip_ref<T, U>& y) +{ + using std::swap; + + swap(x.a[x.p], y.a[y.p]); + swap(x.v[x.p], y.v[y.p]); +} + +template <typename T, typename U> +struct zip_value +{ + zip_value(const zip_ref<T, U>& r) : x(r.a[r.p]), y(r.v[r.p]) {} + + T x; + U y; +}; + + +}} // namespace mtl::utility + +namespace std { + template <typename T, typename U> + struct iterator_traits<mtl::utility::zip_it<T, U> > + { + typedef mtl::utility::zip_ref<T, U> ref_type; + typedef mtl::utility::zip_value<T, U> value_type; + typedef ref_type& reference; + typedef ref_type* pointer; + typedef int difference_type; + typedef random_access_iterator_tag iterator_category; + }; +} + +// usage: +// sort(zip_it<T, U>(a, v, 0), zip_it<T, U>(a, v, S), less_0()); +// where a and v are pointers or arrays and S the size of both arrays + +#endif // MTL_ZIPPED_SORT_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/all_vec_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/all_vec_expr.hpp new file mode 100644 index 00000000..839e7cee --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/all_vec_expr.hpp @@ -0,0 +1,34 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ALL_VEC_EXPR_INCLUDE +#define MTL_ALL_VEC_EXPR_INCLUDE + +#include <boost/numeric/mtl/vector/vec_expr.hpp> +#include <boost/numeric/mtl/vector/vec_negate_expr.hpp> +#include <boost/numeric/mtl/vector/vec_vec_ele_prod_expr.hpp> +#include <boost/numeric/mtl/vector/vec_vec_ele_quot_expr.hpp> +#include <boost/numeric/mtl/vector/vec_vec_plus_expr.hpp> +#include <boost/numeric/mtl/vector/vec_vec_minus_expr.hpp> +#include <boost/numeric/mtl/vector/vec_vec_asgn_expr.hpp> +#include <boost/numeric/mtl/vector/vec_vec_plus_asgn_expr.hpp> +#include <boost/numeric/mtl/vector/vec_vec_minus_asgn_expr.hpp> +#include <boost/numeric/mtl/vector/vec_vec_times_asgn_expr.hpp> +#include <boost/numeric/mtl/vector/vec_vec_div_asgn_expr.hpp> +#include <boost/numeric/mtl/vector/vec_scal_plus_asgn_expr.hpp> +#include <boost/numeric/mtl/vector/vec_scal_minus_asgn_expr.hpp> +#include <boost/numeric/mtl/vector/vec_scal_times_asgn_expr.hpp> +#include <boost/numeric/mtl/vector/vec_scal_div_asgn_expr.hpp> // added by Hui Li +#include <boost/numeric/mtl/vector/vec_scal_asgn_expr.hpp> +#include <boost/numeric/mtl/vector/vec_scal_mixed_expr.hpp> + +#endif // MTL_ALL_VEC_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/assign_expression.hpp b/install/MTL/include/boost/numeric/mtl/vector/assign_expression.hpp new file mode 100644 index 00000000..a0d090b6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/assign_expression.hpp @@ -0,0 +1,89 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Adapted from GLAS implementation by Karl Meerbergen and Toon Knappen + + +#ifndef MTL_VEC_VEC_ASGN_EXPR_INCLUDE +#define MTL_VEC_VEC_ASGN_EXPR_INCLUDE + + +namespace mtl { namespace vec { + +// Model of VectorExpression +template <class E1, class E2> +class vec_vec_asgn_expr +{ +public: + // temporary solution + typedef typename E1::value_type value_type; + // typedef typename glas::value< glas::scalar::vec_vec_asgn_expr<typename E1::value_type, typename E2::value_type > >::type value_type ; + + // temporary solution + typedef typename E1::size_type size_type; + //typedef typename utilities::smallest< typename E1::size_type, typename E2::size_type >::type size_type ; + + typedef value_type const_dereference_type ; + + typedef E1 first_argument_type ; + typedef E2 second_argument_type ; + + + vec_vec_asgn_expr( first_argument_type& v1, second_argument_type const& v2 ) + : first( v1 ), second( v2 ), delayed_assign( false ) + {} + + ~vec_vec_asgn_expr() + { + if (!delayed_assign) + for (size_type i= 0; i < size(first); ++i) + first( i )= second( i ); + } + + void delay_assign() { delayed_assign= true; } + + size_type size() const { + assert( size(first) == second_.size() ) ; + return size(first) ; + } + + const_dereference_type operator() ( size_type i ) const { + assert( delayed_assign ); + return first( i )= second( i ) ; + } + + const_dereference_type operator[] ( size_type i ) const { + assert( delayed_assign ); + return first( i )= second( i ) ; + } + + private: + first_argument_type& first ; + second_argument_type const& second ; + bool delayed_assign; + } ; // vec_vec_asgn_expr + +} } // Namespace mtl::vector + + +namespace mtl { namespace traits { + + template <class E1, class E2> + struct category< vec_vec_asgn_expr<E1,E2> > + { + typedef vec type ; + } ; + +}} // Namespace mtl::traits + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vector/assigner.hpp b/install/MTL/include/boost/numeric/mtl/vector/assigner.hpp new file mode 100644 index 00000000..7edc36c6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/assigner.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_ASSIGNER_INCLUDE +#define MTL_VECTOR_ASSIGNER_INCLUDE + +namespace mtl { namespace vec { + +struct assigner_base {}; + +/// CRTP class to assign the result of the derived class to a vector +template <typename Derived> +struct assigner : assigner_base +{ + /// Function that must be defined in \p Derived where it is called by static down-cast + template <typename Vector> + void assign_to(Vector& tgt) const + { + static_cast<const Derived&>(*this).assign_to(tgt); + } + +}; + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_ASSIGNER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/crtp_base_vector.hpp b/install/MTL/include/boost/numeric/mtl/vector/crtp_base_vector.hpp new file mode 100644 index 00000000..a679feb8 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/crtp_base_vector.hpp @@ -0,0 +1,554 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_CRTP_BASE_VECTOR_INCLUDE +#define MTL_CRTP_BASE_VECTOR_INCLUDE + +#include <boost/mpl/if.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/type_traits/is_base_of.hpp> + +#include <boost/utility/enable_if.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/vector/all_vec_expr.hpp> +#include <boost/numeric/mtl/vector/assigner.hpp> +#include <boost/numeric/mtl/vector/decrementer.hpp> +#include <boost/numeric/mtl/vector/incrementer.hpp> +#include <boost/numeric/mtl/operation/mat_cvec_times_expr.hpp> +#include <boost/numeric/mtl/operation/mult.hpp> +#include <boost/numeric/mtl/operation/mat_vec_mult.hpp> +#include <boost/numeric/mtl/operation/mult_assign_mode.hpp> +#include <boost/numeric/mtl/operation/right_scale_inplace.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/flatcat.hpp> +#include <boost/numeric/mtl/utility/is_distributed.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> + +#include <boost/numeric/itl/itl_fwd.hpp> + +namespace mtl { namespace vec { + + +namespace detail { + + template <typename Vector, typename Source, typename SCat, typename VCat> + struct crtp_assign {}; + + /// Assign scalar to a vector by setting all values to the scalar + template <typename Vector, typename Source, typename VCat> + struct crtp_assign<Vector, Source, VCat, ashape::scal> + { + typedef vec_scal_asgn_expr<Vector, Source> type; + type operator()(Vector& vector, const Source& src) + { + return type(vector, src); + } + }; + + /// Assign vector to a vector + template <typename Vector, typename Source, typename Cat> + struct crtp_assign<Vector, Source, Cat, Cat> + { + typedef vec_vec_asgn_expr<Vector, Source> type; + type operator()(Vector& vector, const Source& src) + { + return type(vector, src); + } + }; + + template <typename Vector, typename Source> + struct assign_assigner + { + typedef const Vector& type; + type operator()(Vector& vector, const Source& src) + { + src.assign_to(vector); + return vector; + } + }; + +} // namespace detail + +template <typename Vector, typename Source> +struct crtp_assign + : boost::mpl::if_ + <boost::is_base_of<assigner_base, Source>, + detail::assign_assigner <Vector, Source>, + detail::crtp_assign<Vector, Source, typename ashape::ashape<Vector>::type, typename ashape::ashape<Source>::type> + >::type +{}; + +/// Assign matrix vector product by calling mult +/** Note that this does not work for arbitrary expressions. **/ +template <typename Vector, typename E1, typename E2> +struct crtp_assign<Vector, mat_cvec_times_expr<E1, E2> > +{ + typedef Vector& type; + type operator()(Vector& vector, const mat_cvec_times_expr<E1, E2>& src) + { + vector.checked_change_resource(src); + set_to_zero(vector); + mat_cvec_mult(src.first, src.second, vector, assign::assign_sum(), traits::mat_cvec_flatcat<E1>()); + return vector; + } +}; + + +/// Assign vector matrix product by calling mult +/** Note that this does not work for arbitrary expressions. **/ +template <typename Vector, typename E1, typename E2> +struct crtp_assign<Vector, rvec_mat_times_expr<E1, E2> > +{ + typedef Vector& type; + type operator()(Vector& vector, const rvec_mat_times_expr<E1, E2>& src) + { + vector.checked_change_resource(src); + rvec_mat_mult(src.first, src.second, vector, assign::assign_sum(), traits::mat_cvec_flatcat<E2>()); + return vector; + } +}; + +/// Assign c-style 1D-array, because it's easier to initialize. +template <typename Vector, typename Value, unsigned Rows> +struct crtp_assign<Vector, Value[Rows]> +{ + typedef Vector& type; + type operator()(Vector& vector, const Value src[Rows]) + { + typedef typename Collection<Vector>::size_type size_type; + + vector.checked_change_dim(Rows); + + for (size_type r= 0; r < Rows; ++r) + vector[r]= src[r]; + return vector; + } +}; + + +namespace detail { + + template <typename Vector, typename Source, typename SCat, typename VCat> + struct crtp_plus_assign {}; + + /// Assign-add vector to a vector + template <typename Vector, typename Source, typename Cat> + struct crtp_plus_assign<Vector, Source, Cat, Cat> + { + typedef vec_vec_plus_asgn_expr<Vector, Source> type; + type operator()(Vector& vector, const Source& src) + { + return type( vector, src ); + } + }; + + /// Increment a vector by a scalar + template <typename Vector, typename Source, typename VCat> + struct crtp_plus_assign<Vector, Source, VCat, ashape::scal> + { + typedef vec_scal_plus_asgn_expr<Vector, Source> type; + type operator()(Vector& vector, const Source& src) + { + return type(vector, src); + } + }; + + template <typename Vector, typename Source> + struct assign_incrementer + { + typedef const Vector& type; + type operator()(Vector& vector, const Source& src) + { + src.increment_it(vector); + return vector; + } + }; + +} // namespace detail + +template <typename Vector, typename Source> +struct crtp_plus_assign + : boost::mpl::if_ + <boost::is_base_of<incrementer_base, Source>, + detail::assign_incrementer<Vector, Source>, + detail::crtp_plus_assign<Vector, Source, typename ashape::ashape<Vector>::type, + typename ashape::ashape<Source>::type> + >::type +{}; + +/// Assign-add matrix vector product by calling mult +/** Note that this does not work for arbitrary expressions. **/ +template <typename Vector, typename E1, typename E2> +struct crtp_plus_assign<Vector, mat_cvec_times_expr<E1, E2> > +{ + typedef Vector& type; + type operator()(Vector& vector, const mat_cvec_times_expr<E1, E2>& src) + { + mat_cvec_mult(src.first, src.second, vector, assign::plus_sum(), traits::mat_cvec_flatcat<E1>()); + return vector; + } +}; + +/// Assign-add vector matrix product by calling mult +/** Note that this does not work for arbitrary expressions. **/ +template <typename Vector, typename E1, typename E2> +struct crtp_plus_assign<Vector, rvec_mat_times_expr<E1, E2> > +{ + typedef Vector& type; + type operator()(Vector& vector, const rvec_mat_times_expr<E1, E2>& src) + { + rvec_mat_mult(src.first, src.second, vector, assign::plus_sum(), traits::mat_cvec_flatcat<E2>()); + return vector; + } +}; + + +namespace detail { + + template <typename Vector, typename Source, typename VCat, typename SCat> + struct crtp_minus_assign {}; + + /// Assign-add vector to a vector + template <typename Vector, typename Source, typename Cat> + struct crtp_minus_assign<Vector, Source, Cat, Cat> + { + typedef vec_vec_minus_asgn_expr<Vector, Source> type; + type operator()(Vector& vector, const Source& src) + { + return type(vector, src); + } + }; + + /// Decrement a vector by a scalar + template <typename Vector, typename Source, typename VCat> + struct crtp_minus_assign<Vector, Source, VCat, ashape::scal> + { + typedef vec_scal_minus_asgn_expr<Vector, Source> type; + type operator()(Vector& vector, const Source& src) + { + return type(vector, src); + } + }; + + template <typename Vector, typename Source> + struct assign_decrementer + { + typedef const Vector& type; + type operator()(Vector& vector, const Source& src) + { + src.decrement_it(vector); + return vector; + } + }; + +} // namespace detail + +template <typename Vector, typename Source> +struct crtp_minus_assign + : boost::mpl::if_ + <boost::is_base_of<decrementer_base, Source>, + detail::assign_decrementer<Vector, Source>, + detail::crtp_minus_assign<Vector, Source, typename ashape::ashape<Vector>::type, + typename ashape::ashape<Source>::type> + >::type +{}; + +/// Assign-subtract matrix vector product by calling mult +/** Note that this does not work for arbitrary expressions. **/ +template <typename Vector, typename E1, typename E2> +struct crtp_minus_assign<Vector, mat_cvec_times_expr<E1, E2> > +{ + typedef Vector& type; + type operator()(Vector& vector, const mat_cvec_times_expr<E1, E2>& src) + { + mat_cvec_mult(src.first, src.second, vector, assign::minus_sum(), traits::mat_cvec_flatcat<E1>()); + return vector; + } +}; + +/// Assign-subtract vector matrix product by calling mult +/** Note that this does not work for arbitrary expressions. **/ +template <typename Vector, typename E1, typename E2> +struct crtp_minus_assign<Vector, rvec_mat_times_expr<E1, E2> > +{ + typedef Vector& type; + type operator()(Vector& vector, const rvec_mat_times_expr<E1, E2>& src) + { + rvec_mat_mult(src.first, src.second, vector, assign::minus_sum(), traits::mat_cvec_flatcat<E2>()); + return vector; + } +}; + +#if 1 +namespace detail { + + template <typename Vector, typename Source, typename SCat, typename VCat> + struct crtp_times_assign {}; + + /// Assign-add vector to a vector + template <typename Vector, typename Source, typename Cat> + struct crtp_times_assign<Vector, Source, Cat, Cat> + { + typedef vec_vec_times_asgn_expr<Vector, Source> type; + type operator()(Vector& vector, const Source& src) + { + return type( vector, src ); + } + }; + + /// Increment a vector by a scalar + template <typename Vector, typename Source, typename VCat> + struct crtp_times_assign<Vector, Source, VCat, ashape::scal> + { + typedef vec_scal_times_asgn_expr<Vector, Source> type; + type operator()(Vector& vector, const Source& src) + { + return type(vector, src); + } + }; + + template <typename Vector, typename Source> + struct assign_multiplyer + { + typedef const Vector& type; + type operator()(Vector& vector, const Source& src) + { + src.multiply_it(vector); + return vector; + } + }; + +} // namespace detail + +template <typename Vector, typename Source> +struct crtp_times_assign + : boost::mpl::if_ + <boost::is_base_of<incrementer_base, Source>, + detail::assign_multiplyer<Vector, Source>, + detail::crtp_times_assign<Vector, Source, typename ashape::ashape<Vector>::type, + typename ashape::ashape<Source>::type> + >::type +{}; + +/// Assign-add matrix vector product by calling mult +/** Note that this does not work for arbitrary expressions. **/ +template <typename Vector, typename E1, typename E2> +struct crtp_times_assign<Vector, mat_cvec_times_expr<E1, E2> > +{ + typedef Vector& type; + type operator()(Vector& vector, const mat_cvec_times_expr<E1, E2>& src) + { + mat_cvec_mult(src.first, src.second, vector, assign::times_sum(), traits::mat_cvec_flatcat<E1>()); + return vector; + } +}; + +/// Assign-add vector matrix product by calling mult +/** Note that this does not work for arbitrary expressions. **/ +template <typename Vector, typename E1, typename E2> +struct crtp_times_assign<Vector, rvec_mat_times_expr<E1, E2> > +{ + typedef Vector& type; + type operator()(Vector& vector, const rvec_mat_times_expr<E1, E2>& src) + { + rvec_mat_mult(src.first, src.second, vector, assign::times_sum(), traits::mat_cvec_flatcat<E2>()); + return vector; + } +}; + + +namespace detail { + + template <typename Vector, typename Source, typename SCat, typename VCat> + struct crtp_div_assign {}; + + /// Assign-divide vector to a vector + template <typename Vector, typename Source, typename Cat> + struct crtp_div_assign<Vector, Source, Cat, Cat> + { + typedef vec_vec_div_asgn_expr<Vector, Source> type; + type operator()(Vector& vector, const Source& src) + { + return type( vector, src ); + } + }; + + /// Divide a vector by a scalar + template <typename Vector, typename Source, typename VCat> + struct crtp_div_assign<Vector, Source, VCat, ashape::scal> + { + typedef vec_scal_div_asgn_expr<Vector, Source> type; + type operator()(Vector& vector, const Source& src) + { + return type(vector, src); + } + }; + + template <typename Vector, typename Source> + struct assign_divider + { + typedef const Vector& type; + type operator()(Vector& vector, const Source& src) + { + src.divide_it(vector); + return vector; + } + }; + +} // namespace detail + +template <typename Vector, typename Source> +struct crtp_div_assign + : boost::mpl::if_ + <boost::is_base_of<incrementer_base, Source>, + detail::assign_divider<Vector, Source>, + detail::crtp_div_assign<Vector, Source, typename ashape::ashape<Vector>::type, + typename ashape::ashape<Source>::type> + >::type +{}; + +/// Assign-divide matrix vector product by calling mult +/** Note that this does not work for arbitrary expressions. **/ +template <typename Vector, typename E1, typename E2> +struct crtp_div_assign<Vector, mat_cvec_times_expr<E1, E2> > +{ + typedef Vector& type; + type operator()(Vector& vector, const mat_cvec_times_expr<E1, E2>& src) + { + mat_cvec_mult(src.first, src.second, vector, assign::divide_sum(), traits::mat_cvec_flatcat<E1>()); + return vector; + } +}; + +/// Assign-divide vector matrix product by calling mult +/** Note that this does not work for arbitrary expressions. **/ +template <typename Vector, typename E1, typename E2> +struct crtp_div_assign<Vector, rvec_mat_times_expr<E1, E2> > +{ + typedef Vector& type; + type operator()(Vector& vector, const rvec_mat_times_expr<E1, E2>& src) + { + rvec_mat_mult(src.first, src.second, vector, assign::divide_sum(), traits::mat_cvec_flatcat<E2>()); + return vector; + } +}; + +#endif + + + +/// Base class to provide vector assignment operators generically +template <typename Vector, typename ValueType, typename SizeType> +struct crtp_vector_assign +{ + /// Templated assignment implemented by functor to allow for partial specialization + template <typename E> + typename boost::disable_if<boost::is_same<Vector, E>, + typename crtp_assign<Vector, E>::type>::type + operator=(const E& e) + { + return crtp_assign<Vector, E>()(static_cast<Vector&>(*this), e); + } + + /// Assign-add vector expression + template <class E> + typename crtp_plus_assign<Vector, E>::type operator+=(const E& e) + { + return crtp_plus_assign<Vector, E>()(static_cast<Vector&>(*this), e); + } + + /// Assign-subtract vector expression + template <class E> + typename crtp_minus_assign<Vector, E>::type operator-=(const E& e) + { + return crtp_minus_assign<Vector, E>()(static_cast<Vector&>(*this), e); + } + + +#if 1 + /// Assign-times vector expression + template <class E> + typename crtp_times_assign<Vector, E>::type operator*=(const E& e) + { + return crtp_times_assign<Vector, E>()(static_cast<Vector&>(*this), e); + } + + /// Assign-div vector expression + template <class E> + typename crtp_div_assign<Vector, E>::type operator/=(const E& e) + { + return crtp_div_assign<Vector, E>()(static_cast<Vector&>(*this), e); + } +#endif + +#if 0 + /// Scale vector (in place) with scalar value + /** In the future, row vectors be possibly scaled by a matrix **/ + template <typename Factor> + vec_scal_times_asgn_expr<Vector, Factor> operator*=(const Factor& alpha) + { + return vec_scal_times_asgn_expr<Vector, Factor>( static_cast<Vector&>(*this), alpha ); + } + + /// Devide vector (in place) by a scalar value + // added by Hui Li 12/11/2007 + template <typename Factor> + vec_scal_div_asgn_expr<Vector, Factor> operator/=(const Factor& alpha) + { + return vec_scal_div_asgn_expr<Vector, Factor>( static_cast<Vector&>(*this), alpha ); + } +#endif + /// Check whether source and target have compatible resources and adapt empty target + /** For expressions like u= v + w, u can be set to the size of v and w if still is 0. **/ + template <typename Src> + void checked_change_resource(const Src& src) + { checked_change_resource_aux(src, typename mtl::traits::is_distributed<Vector>::type()); } + + template <typename Src> + void checked_change_resource_aux(const Src& src, boost::mpl::false_) + { checked_change_dim(mtl::vec::size(src)); } + + + /// Check whether vector size is compatible or if vector is 0 change it s. + void checked_change_dim(SizeType s) + { + Vector& vector= static_cast<Vector&>(*this); + vector.check_dim(s); + vector.change_dim(s); + } +}; + + +template <typename Vector, typename ValueType, typename SizeType> +struct const_crtp_base_vector +{}; + +template <typename Vector, typename ValueType, typename SizeType> +struct mutable_crtp_base_vector + : public crtp_vector_assign<Vector, ValueType, SizeType> +{}; + + + +template <typename Vector, typename ValueType, typename SizeType> +struct crtp_base_vector + : boost::mpl::if_<boost::is_const<Vector>, + const_crtp_base_vector<Vector, ValueType, SizeType>, + mutable_crtp_base_vector<Vector, ValueType, SizeType> + >::type +{}; + + +}} // namespace mtl::vector + +#endif // MTL_CRTP_BASE_VECTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/decrementer.hpp b/install/MTL/include/boost/numeric/mtl/vector/decrementer.hpp new file mode 100644 index 00000000..159601ef --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/decrementer.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_DECREMENTER_INCLUDE +#define MTL_VECTOR_DECREMENTER_INCLUDE + +namespace mtl { namespace vec { + +struct decrementer_base {}; + +/// CRTP class to decrement a vector with the result of the derived class +template <typename Derived> +struct decrementer : decrementer_base +{ + /// Function that must be defined in \p Derived where it is called by static down-cast + template <typename Vector> + void decrement_it(Vector& tgt) const + { + static_cast<const Derived&>(*this).decrement_it(tgt); + } + +}; + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_DECREMENTER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/dense_vector.hpp b/install/MTL/include/boost/numeric/mtl/vector/dense_vector.hpp new file mode 100644 index 00000000..4b08ce08 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/dense_vector.hpp @@ -0,0 +1,432 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Adapted from GLAS implementation by Karl Meerbergen and Toon Knappen + + +#ifndef MTL_DENSE_VECTOR_INCLUDE +#define MTL_DENSE_VECTOR_INCLUDE + + +#include <iostream> +#include <cassert> +#include <vector> +#include <algorithm> +#include <boost/static_assert.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_integral.hpp> + +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/vector/all_vec_expr.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> +#include <boost/numeric/mtl/detail/contiguous_memory_block.hpp> +#include <boost/numeric/mtl/vector/crtp_base_vector.hpp> +#include <boost/numeric/mtl/utility/dense_el_cursor.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/utility/is_static.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/transposed_orientation.hpp> +#include <boost/numeric/mtl/operation/is_negative.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +#ifdef MTL_WITH_INITLIST +# include <initializer_list> +#endif + +namespace mtl { namespace vec { + +/// Dense vector +template <class Value, typename Parameters = parameters<> > +class dense_vector + : public vec_expr<dense_vector<Value, Parameters> >, + public ::mtl::detail::contiguous_memory_block< Value, Parameters::on_stack, Parameters::dimension::value >, + public crtp_base_vector< dense_vector<Value, Parameters>, Value, std::size_t > +{ + public: + typedef dense_vector<Value, Parameters> self; + typedef ::mtl::detail::contiguous_memory_block< Value, Parameters::on_stack, + Parameters::dimension::value > memory_base; + typedef crtp_base_vector< self, Value, std::size_t > crtp_base; + typedef crtp_vector_assign< self, Value, std::size_t > assign_base; + typedef vec_expr<dense_vector<Value, Parameters> > expr_base; + typedef Value value_type ; + typedef std::size_t size_type ; + typedef value_type& reference ; + typedef value_type const& const_reference ; + typedef Value* pointer ; + typedef Value const* const_pointer ; + typedef typename Parameters::orientation orientation; + + typedef const_pointer key_type; + + /// Check whether index is non-negative and less than size + void check_index( size_type MTL_DEBUG_ARG(i) ) const + { + MTL_DEBUG_THROW_IF( is_negative(i) || i >= this->used_memory(), index_out_of_range()); + } + + /// Check for a given vector if the sizes are equal or this has size 0 (and can take the size of source) + void check_dim( size_type MTL_DEBUG_ARG(s) ) const + { + MTL_DEBUG_THROW_IF( this->used_memory() != 0 && this->used_memory() != s, incompatible_size()); + } + + /// Check at compile time for a given vector if the sizes are equal + void static_check( size_type MTL_DEBUG_ARG(s) ) const + { + assert(!traits::is_static<self>::value || s == size(typename Parameters::dimension())); + } + + /// Check if a given vector expression whether it has the same shape as the object + /** Both must be row vectors or column vectors. The elements must have the same + algebraic shape, e.g. a row vector of scalars is not compatible with a row + vector of matrices. **/ + template <class E> + void check_consistent_shape( vec_expr<E> const& ) const + { + MTL_DEBUG_THROW_IF((!boost::is_same< + typename ashape::ashape<self>::type + , typename ashape::ashape<E>::type + >::value), + incompatible_shape()); + } + + /// Default constructor + dense_vector( ) : memory_base( Parameters::dimension::value ) {} + + /// Constructor for size \p n + explicit dense_vector( size_type n ) : memory_base( n ) { static_check( n ); } + + /// Constructor for size \p n and value \p value that is set in all entries + explicit dense_vector( size_type n, value_type value ) + : memory_base( n ) + { + static_check( n ); + std::fill(begin(), end(), value); + } + + /// Constructor for size \p n and \p address + /** Can be used to handle vectors from other libraries, even in other languages like Fortran **/ + explicit dense_vector( size_type n, value_type *address ) + : memory_base( address, n, true ) + { static_check( n ); } + + /// Copy constructor + dense_vector( const self& src ) + : memory_base( src ) + { + vampir_trace<2042> tracer; + using std::copy; + copy(src.begin(), src.end(), this->begin()); + } + + /// Clone constructor + /** Copies every vector, even those that refer to external data, sub-vectors, or rows and columns in a matrix **/ + dense_vector( const self& src, clone_ctor ) + : memory_base( src, clone_ctor()) {} + + struct dummy_type {}; + + /// Constructor from vector expressions + template <typename VectorSrc> + explicit dense_vector(const VectorSrc& src, + typename boost::disable_if<boost::is_integral<VectorSrc>, dummy_type>::type= dummy_type()) + { vampir_trace<2043> tracer; *this= src; } + +#ifdef MTL_WITH_INITLIST + /// Constructor for initializer list \p values + template <typename Value2> + dense_vector(std::initializer_list<Value2> values) + : memory_base(values.size()) + { + static_check(values.size()); + std::copy(values.begin(), values.end(), begin()); + } + + /// Assignment from initializer list \p values + template <typename Value2> + self& operator=(std::initializer_list<Value2> values) + { + checked_change_dim(values.size()); + std::copy(values.begin(), values.end(), begin()); + return *this; + } +#endif + + /// Constructor from std::vector; value_type must be identic + explicit dense_vector(const std::vector<value_type>& src) + : memory_base(src.size()) + { std::copy(src.begin(), src.end(), this->begin()); } + + /// Stride is always 1 + size_type stride() const { return 1 ; } + + /// i-th entry + reference operator()( size_type i ) + { + check_index(i); + return this->value_n( i ) ; + } + + /// i-th entry (constant) + const_reference operator()( size_type i ) const + { + check_index(i); + return this->value_n( i ) ; + } + + reference operator[]( size_type i ) { return (*this)( i ) ; } ///< i-th entry + const_reference operator[]( size_type i ) const { return (*this)( i ) ; } ///< i-th entry (constant) + + self operator[]( irange r ) { return sub_vector(*this, r.start(), r.finish()); } ///< sub-vector + const self operator[]( irange r ) const { return sub_vector(*this, r.start(), r.finish()); } ///< sub-vector + + void delay_assign() const {} + + // Compatibility with STL + const_pointer begin() const { return this->elements() ; } + const_pointer end() const { return this->elements() + this->used_memory(); } + pointer begin() { return this->elements() ; } + pointer end() { return this->elements() + this->used_memory(); } + bool empty() const { return this->used_memory() == 0; } ///< Whether it is empty + + + /// Address of first data entry; to be used with care. + value_type* address_data() { return begin(); } + const value_type* address_data() const { return begin(); } + + +#ifdef MTL_VECTOR_MOVE_EMULATION + /// Move assignment + self& operator=(self src) + { + // Self-copy would be an indication of an error + assert(this != &src); + + checked_change_dim(src.used_memory()); + memory_base::move_assignment(src); + return *this; + } +#else +// #if defined(_MSC_VER) && !defined(MTL_VECTOR_MOVE_EMULATION) + /// Copy assignment + self& operator=(const self& src) + { + if (this == &src) + return *this; + + checked_change_dim(src.used_memory()); + memory_base::operator=(src); + return *this; + } +#endif + +#ifdef MTL_WITH_MOVE + self& operator=(self&& src) + { + checked_change_dim(src.used_memory()); + memory_base::move_assignment(src); + return *this; + } +#endif + +#if 0 // def __PGI + using crtp_base::operator=; +#else + using assign_base::operator=; +#endif + + template <typename Value2> friend void fill(self&, const Value2&); + + /// swap two vectors + friend void swap(self& vector1, self& vector2) + { + swap(static_cast<memory_base&>(vector1), static_cast<memory_base&>(vector2)); + } + + void change_resource(size_type n) { this->realloc(n); } ///< Change resource, like \ref change_dim + void change_dim(size_type n) { this->realloc(n); } ///< Change dimension of vector + void checked_change_dim(size_type n) { check_dim(n); change_dim(n); } ///< Only change dim if it was empty before + + void crop() {} ///< Delete structural zeros, only dummy here for completeness + +} ; // dense_vector + + +/// Size of v +template <typename Value, typename Parameters> +inline typename dense_vector<Value, Parameters>::size_type +size(const dense_vector<Value, Parameters>& v) +{ return v.used_memory() ; } + + + +// ================ +// Free functions +// ================ + +/// Fill \p vector with \p value +template <typename Value, typename Parameters, typename Value2> +inline void fill(dense_vector<Value, Parameters>& vector, const Value2& value) +{ + std::fill(vector.begin(), vector.end(), value); +} + + +template <typename Value, typename Parameters> +typename dense_vector<Value, Parameters>::size_type +inline num_rows_aux(const dense_vector<Value, Parameters>& , tag::row_major) +{ + return 1; +} + +template <typename Value, typename Parameters> +typename dense_vector<Value, Parameters>::size_type +inline num_rows_aux(const dense_vector<Value, Parameters>& vector, tag::col_major) +{ + return vector.used_memory(); +} + +/// Number of rows: is size for column vectors and 1 for row vectors +template <typename Value, typename Parameters> +typename dense_vector<Value, Parameters>::size_type +inline num_rows(const dense_vector<Value, Parameters>& vector) +{ + return num_rows_aux(vector, typename Parameters::orientation()); +} + + +/// Number of columns: is size for row vectors and 1 for column vectors +template <typename Value, typename Parameters> +typename dense_vector<Value, Parameters>::size_type +inline num_cols(const dense_vector<Value, Parameters>& vector) +{ + return num_rows_aux(vector, typename mtl::traits::transposed_orientation<typename Parameters::orientation>::type()); +} + +/// Sub-vector function, more convenient with irange +template <typename Value, typename Parameters> +dense_vector<Value, Parameters> +inline sub_vector(dense_vector<Value, Parameters>& v, + typename dense_vector<Value, Parameters>::size_type start, + typename dense_vector<Value, Parameters>::size_type finish) +{ + typedef dense_vector<Value, Parameters> Vector; + + MTL_DEBUG_THROW_IF( is_negative(start) || is_negative(finish), index_out_of_range()); + irange r= intersection(irange(start, finish), irange(0, mtl::vec::size(v))); + return r.empty() ? Vector() : Vector(r.size(), &v[r.start()]); + +#if 0 + finish= min(finish, size(v)); + start= min(start, finish); // implies min(start, size(v)) + return start < finish ? Vector(finish - start, &v[start]) : Vector(); +#endif +} + +template <typename Value, typename Parameters> +const dense_vector<Value, Parameters> +inline sub_vector(const dense_vector<Value, Parameters>& v, + typename dense_vector<Value, Parameters>::size_type start, + typename dense_vector<Value, Parameters>::size_type finish) +{ + typedef dense_vector<Value, Parameters> Vector; + return sub_vector(const_cast<Vector&>(v), start, finish); +} + + +}} // namespace mtl::vector + +namespace mtl { + + // Enable cloning of dense vectors + template <typename Value, typename Parameters> + struct is_clonable< vec::dense_vector<Value, Parameters> > : boost::mpl::true_ {}; + +} // namespace mtl + +namespace mtl { namespace traits { + + +// ================ +// Range generators +// For cursors +// ================ + + template <typename Value, class Parameters> + struct range_generator<tag::all, mtl::vec::dense_vector<Value, Parameters> > + : public detail::dense_element_range_generator<mtl::vec::dense_vector<Value, Parameters>, + dense_el_cursor<Value>, complexity_classes::linear_cached> + {}; + + template <typename Value, class Parameters> + struct range_generator<tag::nz, mtl::vec::dense_vector<Value, Parameters> > + : public range_generator<tag::all, mtl::vec::dense_vector<Value, Parameters> > + {}; + + template <typename Value, class Parameters> + struct range_generator<tag::iter::all, mtl::vec::dense_vector<Value, Parameters> > + { + typedef mtl::vec::dense_vector<Value, Parameters> collection_t; + typedef complexity_classes::linear_cached complexity; + static int const level = 1; + typedef typename collection_t::pointer type; + + type begin(collection_t& collection) + { + return collection.begin(); + } + type end(collection_t& collection) + { + return collection.end(); + } + }; + + template <typename Value, class Parameters> + struct range_generator<tag::iter::nz, mtl::vec::dense_vector<Value, Parameters> > + : public range_generator<tag::iter::all, mtl::vec::dense_vector<Value, Parameters> > + {}; + + template <typename Value, class Parameters> + struct range_generator<tag::const_iter::all, mtl::vec::dense_vector<Value, Parameters> > + { + typedef mtl::vec::dense_vector<Value, Parameters> collection_t; + typedef complexity_classes::linear_cached complexity; + static int const level = 1; + typedef typename collection_t::const_pointer type; + + type begin(const collection_t& collection) const + { + return collection.begin(); + } + type end(const collection_t& collection) const + { + return collection.end(); + } + }; + + template <typename Value, class Parameters> + struct range_generator<tag::const_iter::nz, mtl::vec::dense_vector<Value, Parameters> > + : public range_generator<tag::const_iter::all, mtl::vec::dense_vector<Value, Parameters> > + {}; + + +}} // namespace mtl::traits + +namespace mtl { + using vec::dense_vector; +} + +#endif // MTL_DENSE_VECTOR_INCLUDE + diff --git a/install/MTL/include/boost/numeric/mtl/vector/dimension.hpp b/install/MTL/include/boost/numeric/mtl/vector/dimension.hpp new file mode 100644 index 00000000..5771c7ff --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/dimension.hpp @@ -0,0 +1,54 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_DIMENSION_INCLUDE +#define MTL_DIMENSION_INCLUDE + +namespace mtl { namespace vec { + +// Compile time version +namespace fixed { + + /// Compile-time dimension + template <std::size_t Size> + struct dimension + { + typedef std::size_t size_type; + static size_type const value= Size; + friend inline size_type size(const dimension&) { return dimension::value; } ///< Size + + /// To check whether it is static + static bool const is_static= true; + }; +} + +namespace non_fixed { + + /// Run-time dimension + struct dimension + { + typedef std::size_t size_type; + + static size_type const value= 0; // for compatibility + dimension(size_type v= 0) : my_size(v) {} /// Constructor with default zero + friend inline size_type size(const dimension& d) { return d.my_size; } ///< Size + + /// To check whether it is static + static bool const is_static= false; + protected: + size_type my_size; + }; +} + +}} // namespace mtl::vec + +#endif // MTL_DIMENSION_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/dot_index_evaluator.hpp b/install/MTL/include/boost/numeric/mtl/vector/dot_index_evaluator.hpp new file mode 100644 index 00000000..06794d0b --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/dot_index_evaluator.hpp @@ -0,0 +1,56 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_DOT_INDEX_EVALUATOR_INCLUDE +#define MTL_VECTOR_DOT_INDEX_EVALUATOR_INCLUDE + +namespace mtl { namespace vec { + +/// Class for index-wise computation of dot product +template <typename Scalar, typename Vector1, typename Vector2, typename ConjOpt, typename Assign> +struct dot_index_evaluator +{ + dot_index_evaluator(Scalar& scalar, const Vector1& v1, const Vector2& v2) + : scalar(scalar), v1(v1), v2(v2) + { + tmp[0]= tmp[1]= tmp[2]= tmp[3]= Scalar(0); + } + + ~dot_index_evaluator() + { + Scalar s(tmp[0] + tmp[1] + tmp[2] + tmp[3]); + Assign::apply(scalar, s); + } + + void operator() (std::size_t i) { tmp[0]+= ConjOpt()(v1[i]) * v2[i]; } + void operator[] (std::size_t i) { (*this)(i); } + + template <unsigned Offset> + void at(std::size_t i) + { tmp[Offset]+= ConjOpt()(v1[i+Offset]) * v2[i+Offset]; } + + Scalar& scalar; + Scalar tmp[4]; + const Vector1& v1; + const Vector2& v2; +}; + +template <typename Scalar, typename Vector1, typename Vector2, typename ConjOpt, typename Assign> +inline std::size_t size(const dot_index_evaluator<Scalar, Vector1, Vector2, ConjOpt, Assign>& eval) +{ + return size(eval.v1); +} + + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_DOT_INDEX_EVALUATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/extracter.hpp b/install/MTL/include/boost/numeric/mtl/vector/extracter.hpp new file mode 100644 index 00000000..e374ced7 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/extracter.hpp @@ -0,0 +1,78 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.short.txt in the distribution. + +#ifndef MTL_VECTOR_EXTRACTER_INCLUDE +#define MTL_VECTOR_EXTRACTER_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> + +namespace mtl { namespace vec { + +template< typename Vector > +struct indexbuffer +{ + typedef typename Collection<Vector>::value_type value_type; + typedef typename Collection<Vector>::size_type size_type; + typedef indexbuffer self; + + indexbuffer(const Vector& v) : vec(v) {} + + inline self& operator()(const size_type p, value_type& dest) + { + dest = vec[p]; + return *this; + } + + inline void update() {} + private: + const Vector& vec; +}; + + +template< typename Vector > +class extracter +{ + public: + typedef typename Collection<Vector>::value_type value_type; + typedef typename Collection<Vector>::size_type size_type; + typedef indexbuffer< Vector > buffer_type; + + extracter(const Vector& vec): + destroyBuffer(true), buffer(new buffer_type(vec)) + {} + extracter(buffer_type& buf): + destroyBuffer(false), buffer(&buf) + {} + + struct bracket_proxy + { + const size_type p; + buffer_type& buffer; + bracket_proxy(const size_type p, buffer_type& b) : p(p), buffer(b) {} + + inline buffer_type& operator>>(value_type& dest) { return buffer(p, dest); } + }; + + inline bracket_proxy operator[](const size_type p) { return bracket_proxy(p, *buffer); } + + ~extracter() { + buffer->update(); + if(destroyBuffer) + delete buffer; + } + private: + const bool destroyBuffer; + buffer_type* buffer; +}; + +}} //namespace mtl::vector +#endif diff --git a/install/MTL/include/boost/numeric/mtl/vector/incrementer.hpp b/install/MTL/include/boost/numeric/mtl/vector/incrementer.hpp new file mode 100644 index 00000000..a4d55385 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/incrementer.hpp @@ -0,0 +1,34 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_INCREMENTER_INCLUDE +#define MTL_VECTOR_INCREMENTER_INCLUDE + +namespace mtl { namespace vec { + +struct incrementer_base {}; + +/// CRTP class to increment a vector with the result of the derived class +template <typename Derived> +struct incrementer : incrementer_base +{ + /// Function that must be defined in \p Derived where it is called by static down-cast + template <typename Vector> + void increment_it(Vector& tgt) const + { + static_cast<const Derived&>(*this).increment_it(tgt); + } +}; + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_INCREMENTER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/inserter.hpp b/install/MTL/include/boost/numeric/mtl/vector/inserter.hpp new file mode 100644 index 00000000..ba000564 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/inserter.hpp @@ -0,0 +1,91 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_INSERTER_INCLUDE +#define MTL_VECTOR_INSERTER_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/operation/update.hpp> + +namespace mtl { namespace vec { + +/// Class for generic insertion into vectors +/** \param Vector is the type of the vector in which will be inserted + \param Updater is a functor that determine how existed entries are updated + \b Remark: For regular vectors, one can set the entries directly without inserter. + An inserter is needed when vectors are distributed. + Reversely, setting vectors with an inserter works for both distributed and non-distributed + vector types and is therefore more generic. + To understand how to use inserters it is best to read the page \ref matrix_insertion. + This applies all to vector insertion except that only one index is used. +**/ +template <typename Vector, typename Updater> +struct inserter +{ + typedef inserter self; + typedef typename Collection<Vector>::size_type size_type; + typedef typename Collection<Vector>::value_type value_type; + typedef update_proxy<self, size_type> proxy_type; + + explicit inserter(Vector& vector) : vector(vector) {} + + proxy_type operator() (size_type n) { return proxy_type(*this, n); } + proxy_type operator[] (size_type n) { return proxy_type(*this, n); } + + template <typename Modifier> + void modify(size_type n, value_type value) { Modifier()(vector[n], value); } + + void update(size_type n, value_type value) { modify<Updater>(n, value); } + +protected: + Vector& vector; +}; + + +// Not to confuse with the equally-named class in operations (which should be in matrix anyway) +template <typename Inserter, typename Size> +struct update_proxy +{ + typedef update_proxy self; + typedef typename Inserter::value_type value_type; + + explicit update_proxy(Inserter& ins, Size n) : ins(ins), n(n) {} + + template <typename Value> + self& operator<< (Value const& val) + { + ins.update(n, val); + return *this; + } + + template <typename Value> + self& operator= (Value const& val) + { + ins.template modify<update_store<value_type> > (n, val); + return *this; + } + + template <typename Value> + self& operator+= (Value const& val) + { + ins.template modify<update_plus<value_type> > (n, val); + return *this; + } + + private: + Inserter& ins; + Size n; +}; + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_INSERTER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/lazy_reduction.hpp b/install/MTL/include/boost/numeric/mtl/vector/lazy_reduction.hpp new file mode 100644 index 00000000..f0a7800e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/lazy_reduction.hpp @@ -0,0 +1,34 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_LAZY_REDUCTION_INCLUDE +#define MTL_VECTOR_LAZY_REDUCTION_INCLUDE + +namespace mtl { namespace vec { + +/// Helper class for lazy evaluation +template <typename Vector, typename Functor> +struct lazy_reduction +{ + lazy_reduction(const Vector& v) : v(v) {} + const Vector& v; +}; + +template <typename Vector, typename Functor> +inline std::size_t size(const lazy_reduction<Vector, Functor>& lazy) +{ + return size(lazy.v); +} + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_LAZY_REDUCTION_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/map_view.hpp b/install/MTL/include/boost/numeric/mtl/vector/map_view.hpp new file mode 100644 index 00000000..1134789c --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/map_view.hpp @@ -0,0 +1,340 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_MAP_VIEW_INCLUDE +#define MTL_VECTOR_MAP_VIEW_INCLUDE + +#include <utility> +#include <boost/shared_ptr.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/copy_expression_const_ref_container.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> +#include <boost/numeric/mtl/operation/tfunctor.hpp> +#include <boost/numeric/mtl/operation/conj.hpp> +#include <boost/numeric/mtl/operation/real.hpp> +#include <boost/numeric/mtl/operation/imag.hpp> +#include <boost/numeric/mtl/vector/vec_expr.hpp> + + +namespace mtl { namespace vec { namespace detail { + // Forward declaration for friend declaration + template <typename, typename> struct map_value; +}}} + +namespace mtl { namespace vec { + +template <typename Functor, typename Vector> +struct map_view + : public vec_expr< map_view<Functor, Vector> > +{ + typedef map_view self; + typedef vec_expr< self > expr_base; + typedef Vector other; + + typedef typename Functor::result_type value_type; + typedef typename Functor::result_type const_reference; + typedef typename Collection<Vector>::size_type size_type; + + map_view (const Functor& functor, const other& ref) + : expr_base(*this), functor(functor), ref(ref) + { + ref.delay_assign(); + } + + map_view (const Functor& functor, boost::shared_ptr<Vector> p) + : expr_base(*this), functor(functor), my_copy(p), ref(*p) + { + ref.delay_assign(); + } + +#ifdef MTL_WITH_CPP11_MOVE + map_view (self&& that) : functor(that.functor), my_copy(std::move(that.my_copy)), ref(that.ref) {} + map_view (const self& that) : functor(that.functor), ref(that.ref) { assert(that.my_copy.use_count() == 0); } +#endif + + friend size_type inline num_rows(const self& v) { return num_rows(v.ref); } + friend size_type inline num_cols(const self& v) { return num_cols(v.ref); } + + size_type stride() const { return ref.stride(); } + const_reference operator() (size_type i) const { return functor(ref(i)); } + const_reference operator[] (size_type i) const { return functor(ref[i]); } + void delay_assign() const {} + + template <typename, typename> friend struct detail::map_value; + + protected: + boost::shared_ptr<Vector> my_copy; + public: + Functor functor; + // ref is a const& if Vector is a true vector and a copy if it is an expression + typename mtl::traits::copy_expression_const_ref_container<Vector>::type ref; +}; + + +template <typename Functor, typename Vector> +inline std::size_t size(const map_view<Functor, Vector>& v) +{ return mtl::vec::size(v.ref); } + +// ================ +// Free functions +// ================ + + + namespace detail { + + template <typename Functor, typename Vector> + struct map_value + { + typedef typename Vector::key_type key_type; + typedef typename vec::map_view<Functor, Vector>::value_type value_type; + + map_value(vec::map_view<Functor, Vector> const& map_vector) + : map_vector(map_vector), its_value(map_vector.ref) + {} + + value_type operator() (key_type const& key) const + { + return map_vector.functor(its_value(key)); + } + + protected: + vec::map_view<Functor, Vector> const& map_vector; + typename ::mtl::traits::const_value<Vector>::type its_value; + }; + + } // detail + +}} // namespace mtl::vector + + + +namespace mtl { namespace traits { + + // ================ + // Property maps + // ================ + + template <typename Functor, typename Vector> + struct index<vec::map_view<Functor, Vector> > + : public index<Vector> + {}; + + template <typename Functor, typename Vector> + struct const_value<vec::map_view<Functor, Vector> > + { + typedef vec::detail::map_value<Functor, Vector> type; + }; + + + // ================ + // Range generators + // ================ + + // Use range_generator of original vector + template <typename Tag, typename Functor, typename Vector> + struct range_generator<Tag, vec::map_view<Functor, Vector> > + : public range_generator<Tag, Vector> + {}; + +}} // mtl::traits + +namespace mtl { namespace vec { + +template <typename Scaling, typename Vector> +struct scaled_view + : public map_view<tfunctor::scale<Scaling, typename Vector::value_type>, Vector> +{ + typedef tfunctor::scale<Scaling, typename Vector::value_type> functor_type; + typedef map_view<functor_type, Vector> base; + typedef scaled_view self; + + explicit scaled_view(const Scaling& scaling, const Vector& vector) + : base(functor_type(scaling), vector) + {} + + explicit scaled_view(const Scaling& scaling, boost::shared_ptr<Vector> p) + : base(functor_type(scaling), p) + {} + +#ifdef MTL_WITH_CPP11_MOVE + scaled_view (self&& that) : base(that) {} + scaled_view (const self& that) : base(that) {} +#endif +}; + +// added by Hui Li +template <typename Vector, typename RScaling> +struct rscaled_view + : public map_view<tfunctor::rscale<typename Vector::value_type, RScaling>, Vector> +{ + typedef tfunctor::rscale<typename Vector::value_type, RScaling> functor_type; + typedef map_view<functor_type, Vector> base; + typedef rscaled_view self; + + explicit rscaled_view(const Vector& vector, const RScaling& rscaling) + : base(functor_type(rscaling), vector) + {} + + explicit rscaled_view(boost::shared_ptr<Vector> p, const RScaling& rscaling) + : base(functor_type(rscaling), p) + {} + +#ifdef MTL_WITH_CPP11_MOVE + rscaled_view (self&& that) : base(that) {} + rscaled_view (const self& that) : base(that) {} +#endif +}; + + +// added by Hui Li +template <typename Vector, typename Divisor> +struct divide_by_view + : public map_view<tfunctor::divide_by<typename Vector::value_type, Divisor>, Vector> +{ + typedef tfunctor::divide_by<typename Vector::value_type, Divisor> functor_type; + typedef map_view<functor_type, Vector> base; + typedef divide_by_view self; + + explicit divide_by_view(const Vector& vector, const Divisor& div) + : base(functor_type(div), vector) + {} + + explicit divide_by_view(boost::shared_ptr<Vector> p, const Divisor& div) + : base(functor_type(div), p) + {} + +#ifdef MTL_WITH_CPP11_MOVE + divide_by_view (self&& that) : base(that) {} + divide_by_view (const self& that) : base(that) {} +#endif +}; + + +template <typename Vector> +struct conj_view + : public map_view<mtl::sfunctor::conj<typename Vector::value_type>, Vector> +{ + typedef mtl::sfunctor::conj<typename Vector::value_type> functor_type; + typedef map_view<functor_type, Vector> base; + typedef conj_view self; + + explicit conj_view(const Vector& vector) + : base(functor_type(), vector) + {} + + explicit conj_view(boost::shared_ptr<Vector> p) + : base(functor_type(), p) + {} + +#ifdef MTL_WITH_CPP11_MOVE + conj_view (self&& that) : base(that) {} + conj_view (const self& that) : base(that) {} +#endif +}; + +template <typename Vector> +struct real_view + : public map_view<mtl::sfunctor::real<typename Vector::value_type>, Vector> +{ + typedef mtl::sfunctor::real<typename Vector::value_type> functor_type; + typedef map_view<functor_type, Vector> base; + typedef real_view self; + + explicit real_view(const Vector& vector) + : base(functor_type(), vector) + {} + + explicit real_view(boost::shared_ptr<Vector> p) + : base(functor_type(), p) + {} + +#ifdef MTL_WITH_CPP11_MOVE + real_view (self&& that) : base(that) {} + real_view (const self& that) : base(that) {} +#endif +}; + +template <typename Vector> +struct imag_view + : public map_view<mtl::sfunctor::imag<typename Vector::value_type>, Vector> +{ + typedef mtl::sfunctor::imag<typename Vector::value_type> functor_type; + typedef map_view<functor_type, Vector> base; + typedef imag_view self; + + explicit imag_view(const Vector& vector) + : base(functor_type(), vector) + {} + + explicit imag_view(boost::shared_ptr<Vector> p) + : base(functor_type(), p) + {} + +#ifdef MTL_WITH_CPP11_MOVE + imag_view (self&& that) : base(that) {} + imag_view (const self& that) : base(that) {} +#endif +}; + +template <typename Vector> +struct negate_view + : public map_view<mtl::sfunctor::negate<typename Vector::value_type>, Vector> +{ + typedef mtl::sfunctor::negate<typename Vector::value_type> functor_type; + typedef map_view<functor_type, Vector> base; + typedef negate_view self; + + explicit negate_view(const Vector& vector) + : base(functor_type(), vector) + {} + + explicit negate_view(boost::shared_ptr<Vector> p) + : base(functor_type(), p) + {} + +#ifdef MTL_WITH_CPP11_MOVE + negate_view (self&& that) : base(that) {} + negate_view (const self& that) : base(that) {} +#endif +}; + + +}} // namespace mtl::vector + +namespace mtl { namespace sfunctor { + + + template <typename Vector> + struct conj_aux<Vector, tag::vector> + { + typedef mtl::vec::conj_view<Vector> result_type; + + static inline result_type apply(const Vector& vector) + { + return result_type(vector); + } + + result_type operator() (const Vector& vector) const + { + return apply(vector); + } + }; + +}} + + + + +#endif // MTL_VECTOR_MAP_VIEW_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/mapped_inserter.hpp b/install/MTL/include/boost/numeric/mtl/vector/mapped_inserter.hpp new file mode 100644 index 00000000..f026bc15 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/mapped_inserter.hpp @@ -0,0 +1,55 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_MAPPED_INSERTER_INCLUDE +#define MTL_VECTOR_MAPPED_INSERTER_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/operation/update.hpp> + +namespace mtl { +namespace vec { + +/// Inserter with shifted indices +/** The main work is performed by the underlying base inserter whose type is given as template + argument. **/ +template <typename BaseInserter, typename Mapper > +class mapped_inserter +{ + public: + typedef mapped_inserter self; + typedef typename BaseInserter::size_type size_type; + typedef update_proxy<BaseInserter, size_type> proxy_type; + + /// Constructor with matrix \p A, the mapping, and the slot size + mapped_inserter(BaseInserter& A, Mapper& map) + : ins(A), map(map) {} + + public: + /// To be used in ins(r, c) << value; + proxy_type operator[] (size_type row) + { return proxy_type(ins, map.row(row)); } + + /// To be used in ins(r, c) << value; + proxy_type operator() (size_type row) + { return proxy_type(ins, map.row(row)); } + + // update, modify and operator<< are used from BaseInserter + +private: + BaseInserter ins; + Mapper& map; +}; + +} // namespace vector +} // namespace mtl +#endif //MTL_VECTOR_MAPPED_INSERTER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/mat_cvec_multiplier.hpp b/install/MTL/include/boost/numeric/mtl/vector/mat_cvec_multiplier.hpp new file mode 100644 index 00000000..da217c59 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/mat_cvec_multiplier.hpp @@ -0,0 +1,102 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_MAT_CVEC_MULTIPLIER_INCLUDE +#define MTL_VECTOR_MAT_CVEC_MULTIPLIER_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/concept/std_concept.hpp> + +#include <boost/numeric/mtl/vector/vec_expr.hpp> +#include <boost/numeric/mtl/vector/assigner.hpp> +#include <boost/numeric/mtl/vector/decrementer.hpp> +#include <boost/numeric/mtl/vector/incrementer.hpp> +#include <boost/numeric/mtl/operation/assign_mode.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace vec { + +/// Helper class for delaying matrix vector multiplication, e.g. for matrix-free operators +template <typename Matrix, typename VectorIn> +struct mat_cvec_multiplier + : assigner<mat_cvec_multiplier<Matrix, VectorIn> >, + incrementer<mat_cvec_multiplier<Matrix, VectorIn> >, + decrementer<mat_cvec_multiplier<Matrix, VectorIn> >, + vec_expr<mat_cvec_multiplier<Matrix, VectorIn> > +{ + typedef typename Multiplicable<typename Collection<Matrix>::value_type, + typename Collection<VectorIn>::value_type>::result_type value_type; + + + /// Construct with matrix \p A and vector \p v + mat_cvec_multiplier(const Matrix& A, const VectorIn& v) : A(A), v(v) {} + + /// Assing the product to vector \p w, if possible directly within w's memory without copying + template <typename VectorOut> + void assign_to(VectorOut& w) const + { + vampir_trace<3068> tracer; + A.mult(v, w, mtl::assign::assign_sum()); + } + + /// Increment vector \p w with the product, if possible directly within w's memory without copying + template <typename VectorOut> + void increment_it(VectorOut& w) const + { + vampir_trace<3068> tracer; + A.mult(v, w, mtl::assign::plus_sum()); + } + + /// Decrement vector \p w with the product, if possible directly within w's memory without copying + template <typename VectorOut> + void decrement_it(VectorOut& w) const + { + vampir_trace<3068> tracer; + A.mult(v, w, mtl::assign::minus_sum()); + } + +#if 1 + /// Multiply vector \p w with the product, if possible directly within w's memory without copying + template <typename VectorOut> + void multiply_it(VectorOut& w) const + { + vampir_trace<3068> tracer; + A.mult(v, w, mtl::assign::times_sum()); + } + + /// Divide vector \p w with the product, if possible directly within w's memory without copying + template <typename VectorOut> + void divide_it(VectorOut& w) const + { + vampir_trace<3068> tracer; + A.mult(v, w, mtl::assign::divide_sum()); + } +#endif + void delay_assign() const { } + + const Matrix& A; + const VectorIn& v; +}; + +template <typename Matrix, typename VectorIn> +inline std::size_t size(const mat_cvec_multiplier<Matrix, VectorIn>& m) +{ return num_rows(m.A); } + +template <typename Matrix, typename VectorIn> +inline std::size_t num_rows(const mat_cvec_multiplier<Matrix, VectorIn>& m) { return num_rows(m.A); } + +template <typename Matrix, typename VectorIn> +inline std::size_t num_cols(const mat_cvec_multiplier<Matrix, VectorIn>&) { return 1; } + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_MAT_CVEC_MULTIPLIER_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/parameter.hpp b/install/MTL/include/boost/numeric/mtl/vector/parameter.hpp new file mode 100644 index 00000000..4ae5fedb --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/parameter.hpp @@ -0,0 +1,46 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_PARAMETERS_INCLUDE +#define MTL_VECTOR_PARAMETERS_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/vector/dimension.hpp> +#include <boost/numeric/mtl/utility/is_static.hpp> + +namespace mtl { namespace vec { + +/// This type exist only for bundling template parameters (to reduce typing) +/** OnStack = true can only be used with fixed::dimension. + \sa \ref tuning_fsize + \sa \ref tuning_sizetype **/ +template <typename Orientation= col_major, + typename Dimension= non_fixed::dimension, + bool OnStack= mtl::traits::is_static<Dimension>::value, + typename SizeType= std::size_t> +struct parameters +{ + typedef Orientation orientation; + typedef Dimension dimension; + static const bool on_stack= OnStack; + typedef SizeType size_type; + + // Vector dimension must be known at compile time to be on the stack + MTL_STATIC_ASSERT(( !on_stack || dimension::is_static ), "Types to be stored on stack must provide static size."); +}; + + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_PARAMETERS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/reduction.hpp b/install/MTL/include/boost/numeric/mtl/vector/reduction.hpp new file mode 100644 index 00000000..de9eec13 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/reduction.hpp @@ -0,0 +1,182 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_REDUCTION_INCLUDE +#define MTL_REDUCTION_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/meta_math/loop1.hpp> +#include <boost/numeric/mtl/utility/omp_size_type.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> + +namespace mtl { namespace vec { + + + namespace impl { + + template <unsigned long Index0, unsigned long Max0, typename Functor> + struct reduction + { + typedef reduction<Index0+1, Max0, Functor> next; + + template <typename Value> + static inline void init(Value& tmp00, Value& tmp01, Value& tmp02, Value& tmp03, Value& tmp04, + Value& tmp05, Value& tmp06, Value& tmp07) + { + Functor::init(tmp00); + next::init(tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, tmp00); + } + + template <typename Value, typename Vector, typename Size> + static inline void update(Value& tmp00, Value& tmp01, Value& tmp02, Value& tmp03, Value& tmp04, + Value& tmp05, Value& tmp06, Value& tmp07, const Vector& v, Size i) + { + Functor::update(tmp00, v[ i + Index0-1 ]); + next::update(tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, tmp00, v, i); + } + + template <typename Value> + static inline void finish(Value& tmp00, Value& tmp01, Value& tmp02, Value& tmp03, Value& tmp04, + Value& tmp05, Value& tmp06, Value& tmp07) + { + next::finish(tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07, tmp00); + Functor::finish(tmp00, tmp01); + } + }; + + template <unsigned long Max0, typename Functor> + struct reduction<Max0, Max0, Functor> + { + template <typename Value> + static inline void init(Value& tmp00, Value&, Value&, Value&, Value&, Value&, Value&, Value&) + { + Functor::init(tmp00); + } + + template <typename Value, typename Vector, typename Size> + static inline void update(Value& tmp00, Value&, Value&, Value&, Value&, Value&, Value&, Value&, + const Vector& v, Size i) + { + Functor::update(tmp00, v[ i + Max0-1 ]); + } + + template <typename Value> + static inline void finish(Value&, Value&, Value&, Value&, Value&, Value&, Value&, Value&) {} + }; + + } // namespace impl + + +// Will need distinction between dense and sparse in the future +template <unsigned long Unroll, typename Functor, typename Result> +struct reduction +{ + template <typename Vector> + Result static inline apply(const Vector& v) + { + vampir_trace<2009> tracer; + return apply(v, typename mtl::traits::is_sparse<Vector>()); + } + + private: + template <typename Vector> + Result static inline apply(const Vector& v, boost::mpl::true_) + { + Result tmp00; + Functor::init(tmp00); + + for (std::size_t i= 0, n= v.nnz(); i < n; i++) + Functor::update(tmp00, v.value(i)); + // std::cout << "i == " << i << " + +#if 0 + typename mtl::traits::const_value<Vector>::type value(v); + typedef typename mtl::traits::range_generator<tag::nz, Vector>::type cursor_type; + + for (cursor_type cursor = begin<tag::nz>(v), cend = end<tag::nz>(v); cursor != cend; ++cursor) + Functor::update(tmp00, value(*cursor)); +#endif + return tmp00; + } + +# ifdef MTL_WITH_OPENMP + + template <typename Vector> + Result static inline apply(const Vector& v, boost::mpl::false_) + { + MTL_STATIC_ASSERT((Unroll >= 1), "Unroll size must be at least 1."); + MTL_STATIC_ASSERT((Unroll <= 8), "Maximal unrolling is 8."); // Might be relaxed in future versions + + Result result; + Functor::init(result); + + typedef typename mtl::traits::omp_size_type<typename Collection<Vector>::size_type>::type size_type; + const size_type i_max= mtl::size(v), i_block= Unroll * (i_max / Unroll); + + #pragma omp parallel + { + vampir_trace<8002> tracer; + Result tmp00, tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07; + impl::reduction<1, Unroll, Functor>::init(tmp00, tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07); + + #pragma omp for + for (size_type i= 0; i < i_block; i+= Unroll) + impl::reduction<1, Unroll, Functor>::update(tmp00, tmp01, tmp02, tmp03, + tmp04, tmp05, tmp06, tmp07, v, i); + + impl::reduction<1, Unroll, Functor>::finish(tmp00, tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07); + + #pragma omp critical + Functor::finish(result, tmp00); + } + + for (size_type i= i_block; i < i_max; i++) + Functor::update(result, v[i]); + + return result; + } + +# else + + template <typename Vector> + Result static inline apply(const Vector& v, boost::mpl::false_) + { + MTL_STATIC_ASSERT((Unroll >= 1), "Unroll size must be at least 1."); + MTL_STATIC_ASSERT((Unroll <= 8), "Maximal unrolling is 8."); // Might be relaxed in future versions + + Result tmp00, tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07; + impl::reduction<1, Unroll, Functor>::init(tmp00, tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07); + + typedef typename Collection<Vector>::size_type size_type; + const size_type i_max= mtl::vec::size(v), i_block= Unroll * (i_max / Unroll); + for (size_type i= 0; i < i_block; i+= Unroll) + impl::reduction<1, Unroll, Functor>::update(tmp00, tmp01, tmp02, tmp03, + tmp04, tmp05, tmp06, tmp07, v, i); + for (size_type i= i_block; i < i_max; i++) + Functor::update(tmp00, v[i]); + + impl::reduction<1, Unroll, Functor>::finish(tmp00, tmp01, tmp02, tmp03, tmp04, tmp05, tmp06, tmp07); + return tmp00; + } + +# endif + + +}; + +}} // namespace mtl + +#endif // MTL_REDUCTION_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/reduction_functors.hpp b/install/MTL/include/boost/numeric/mtl/vector/reduction_functors.hpp new file mode 100644 index 00000000..1c96903f --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/reduction_functors.hpp @@ -0,0 +1,244 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_REDUCTION_FUNCTORS_INCLUDE +#define MTL_REDUCTION_FUNCTORS_INCLUDE + +#include <cmath> +#include <boost/numeric/linear_algebra/identity.hpp> +#include <boost/numeric/mtl/operation/squared_abs.hpp> + +namespace mtl { namespace vec { + +struct one_norm_functor +{ + template <typename Value> + static inline void init(Value& value) + { + using math::zero; + value= zero(value); + } + + template <typename Value, typename Element> + static inline void update(Value& value, const Element& x) + { + using std::abs; + value+= abs(x); + } + + template <typename Value> + static inline void finish(Value& value, const Value& value2) + { + value+= value2; + } + + template <typename Value> + static inline Value post_reduction(const Value& value) + { + return value; + } +}; + + +// sub-optimal if abs is not needed +struct two_norm_functor +{ + template <typename Value> + static inline void init(Value& value) + { + using math::zero; + value= zero(value); + } + + template <typename Value, typename Element> + static inline void update(Value& value, const Element& x) + { + using mtl::squared_abs; + value+= squared_abs(x); + } + + template <typename Value> + static inline void finish(Value& value, const Value& value2) + { + value+= value2; + } + + // After reduction compute square root + template <typename Value> + static inline Value post_reduction(const Value& value) + { + using std::sqrt; + return sqrt(value); + } +}; + +// same as two-norm without the root at the end +struct unary_dot_functor + : two_norm_functor +{ + template <typename Value> + static inline Value post_reduction(const Value& value) + { + return value; + } +}; + +struct infinity_norm_functor +{ + template <typename Value> + static inline void init(Value& value) + { + using math::zero; + value= zero(value); + } + + template <typename Value, typename Element> + static inline void update(Value& value, const Element& x) + { + using std::abs; using std::max; + value= max(value, Value(abs(x))); + } + + template <typename Value> + static inline void finish(Value& value, const Value& value2) + { + using std::abs; using std::max; + value= max(value, Value(abs(value2))); + } + + template <typename Value> + static inline Value post_reduction(const Value& value) + { + return value; + } +}; + + +struct sum_functor +{ + template <typename Value> + static inline void init(Value& value) + { + using math::zero; + value= zero(value); + } + + template <typename Value, typename Element> + static inline void update(Value& value, const Element& x) + { + value+= x; + } + + template <typename Value> + static inline void finish(Value& value, const Value& value2) + { + value+= value2; + } + + template <typename Value> + static inline Value post_reduction(const Value& value) + { + return value; + } +}; + + +struct product_functor +{ + template <typename Value> + static inline void init(Value& value) + { + using math::one; + value= one(value); + } + + template <typename Value, typename Element> + static inline void update(Value& value, const Element& x) + { + value*= x; + } + + template <typename Value> + static inline void finish(Value& value, const Value& value2) + { + value*= value2; + } + + template <typename Value> + static inline Value post_reduction(const Value& value) + { + return value; + } +}; + + +struct max_functor +{ + template <typename Value> + static inline void init(Value& value) + { + using math::identity; + value= math::identity(math::max<Value>(), value); // ADL doesn't work here in g++ 4.4 + } + + template <typename Value, typename Element> + static inline void update(Value& value, const Element& x) + { + value= math::max<Value>()(value, x); + } + + template <typename Value> + static inline void finish(Value& value, const Value& value2) + { + value= math::max<Value>()(value, value2); + } + + template <typename Value> + static inline Value post_reduction(const Value& value) + { + return value; + } +}; + + +struct min_functor +{ + template <typename Value> + static inline void init(Value& value) + { + using math::identity; + value= math::identity(math::min<Value>(), value); // ADL doesn't work here in g++ 4.4 + } + + template <typename Value, typename Element> + static inline void update(Value& value, const Element& x) + { + value= math::min<Value>()(value, x); + } + + template <typename Value> + static inline void finish(Value& value, const Value& value2) + { + value= math::min<Value>()(value, value2); + } + + template <typename Value> + static inline Value post_reduction(const Value& value) + { + return value; + } +}; + + +}} // namespace mtl::vector + +#endif // MTL_REDUCTION_FUNCTORS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/reduction_index_evaluator.hpp b/install/MTL/include/boost/numeric/mtl/vector/reduction_index_evaluator.hpp new file mode 100644 index 00000000..542da70b --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/reduction_index_evaluator.hpp @@ -0,0 +1,58 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_REDUCTION_INDEX_EVALUATOR_INCLUDE +#define MTL_VECTOR_REDUCTION_INDEX_EVALUATOR_INCLUDE + +namespace mtl { namespace vec { + +/// Class for index-wise vector reductions +template <typename Scalar, typename Vector, typename Functor, typename Assign> +struct reduction_index_evaluator +{ + reduction_index_evaluator(Scalar& scalar, const Vector& v) + : scalar(scalar), v(v) + { + Functor::init(tmp[0]); + tmp[1]= tmp[2]= tmp[3]= tmp[0]; + } + + ~reduction_index_evaluator() + { + Functor::finish(tmp[0], tmp[1]); + Functor::finish(tmp[2], tmp[3]); + Functor::finish(tmp[0], tmp[2]); + Assign::apply(scalar, Functor::post_reduction(tmp[0])); // compute sqrt or such if necessary + } + + template <unsigned Offset> + void at(std::size_t i) + { + Functor::update(tmp[Offset], v[i+Offset]); + } + + void operator[] (std::size_t i) { at<0>(i); } + void operator() (std::size_t i) { at<0>(i); } + + Scalar& scalar; + Scalar tmp[4]; + const Vector& v; +}; + +template <typename Scalar, typename Vector, typename Functor, typename Assign> +inline std::size_t size(const reduction_index_evaluator<Scalar, Vector, Functor, Assign>& eval) +{ return size(eval.v); } + + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_REDUCTION_INDEX_EVALUATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/row_mat_cvec_index_evaluator.hpp b/install/MTL/include/boost/numeric/mtl/vector/row_mat_cvec_index_evaluator.hpp new file mode 100644 index 00000000..0354c0e1 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/row_mat_cvec_index_evaluator.hpp @@ -0,0 +1,78 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_ROW_MAT_CVEC_INDEX_EVALUATOR_INCLUDE +#define MTL_ROW_MAT_CVEC_INDEX_EVALUATOR_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> + +namespace mtl { namespace vec { + +/// ET class to evaluate the product of a row-major matrix and a column vector row by row +template <typename VectorOut, typename Matrix, typename VectorIn, typename Assign> +struct row_mat_cvec_index_evaluator +{ + MTL_STATIC_ASSERT((mtl::traits::is_row_major<Matrix>::value), "Only row-major matrices supported here."); + typedef typename mtl::Collection<VectorOut>::value_type value_type; + typedef typename mtl::Collection<Matrix>::size_type size_type; + + row_mat_cvec_index_evaluator(VectorOut& w, const Matrix& A, const VectorIn& v) : w(w), A(A), v(v) {} + + template <unsigned Offset> + void at(size_type i, boost::mpl::true_) + { + // value_type tmp(math::zero(w[i+Offset])); + value_type tmp(0); + const size_type cj0= A.ref_major()[i+Offset], cj1= A.ref_major()[i+Offset+1]; + for (size_type j= cj0; j != cj1; ++j) + tmp+= A.data[j] * v[A.ref_minor()[j]]; + Assign::first_update(w[i+Offset], tmp); + } + + template <unsigned Offset> + void at(size_type i, boost::mpl::false_) + { + value_type tmp(math::zero(w[i+Offset])); + for (size_type j= 0; j < num_cols(A); j++) + tmp+= A[i][j] * v[j]; + Assign::first_update(w[i+Offset], tmp); + } + + template <unsigned Offset> + void at(size_type i) + { + at<Offset>(i, typename mtl::traits::is_sparse<Matrix>::type()); + } + + void operator()(size_type i) { at<0>(i); } + void operator[](size_type i) { at<0>(i); } + + VectorOut& w; + const Matrix& A; + const VectorIn& v; +}; + +template <typename VectorOut, typename Matrix, typename VectorIn, typename Assign> +inline std::size_t size(const row_mat_cvec_index_evaluator<VectorOut, Matrix, VectorIn, Assign>& eval) +{ + return size(eval.w); +} + + +}} // namespace mtl::vector + +#endif // MTL_ROW_MAT_CVEC_INDEX_EVALUATOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/rvec_mat_times_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/rvec_mat_times_expr.hpp new file mode 100644 index 00000000..9291ef70 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/rvec_mat_times_expr.hpp @@ -0,0 +1,42 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_RVEC_MAT_TIMES_EXPR_INCLUDE +#define MTL_RVEC_MAT_TIMES_EXPR_INCLUDE + +#include <boost/numeric/mtl/operation/bin_op_expr.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace vec { + +template <typename E1, typename E2> +struct rvec_mat_times_expr + : public bin_op_expr< E1, E2 >, + public mtl::vec::vec_expr< rvec_mat_times_expr<E1, E2> > +{ + typedef bin_op_expr< E1, E2 > base; + typedef rvec_mat_times_expr<E1, E2> self; + + typedef typename Multiplicable<typename Collection<E1>::value_type, + typename Collection<E2>::value_type>::result_type value_type; + typedef typename Collection<E2>::size_type size_type; + + rvec_mat_times_expr( E1 const& v, E2 const& A ) : base(v, A) {} +}; + +template <typename E1, typename E2> +std::size_t inline size(const rvec_mat_times_expr<E1, E2>& x) +{ return num_cols(x.first); } + +}} // namespace mtl::vector + +#endif // MTL_RVEC_MAT_TIMES_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/sparse_vector.hpp b/install/MTL/include/boost/numeric/mtl/vector/sparse_vector.hpp new file mode 100644 index 00000000..b457b6c8 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/sparse_vector.hpp @@ -0,0 +1,173 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_SPARSE_VECTOR_INCLUDE +#define MTL_VECTOR_SPARSE_VECTOR_INCLUDE + +#include <iostream> +#include <vector> +#include <algorithm> + +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/zipped_sort.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace vec { + +/// This is not (yet) a full numeric class!!! It is only a helper for factorization with very limited functionality. DO NOT USE in numeric code (yet)!!! +template <typename Value, typename Parameter= parameters<> > +class sparse_vector +{ + typedef Value value_type; + typedef std::vector<value_type> vv_type; + typedef typename Parameter::size_type size_type; + typedef std::vector<size_type> sv_type; + typedef typename Parameter::orientation orientation; + typedef sparse_vector self; + + void check(size_type MTL_DEBUG_ARG(j)) const + { MTL_DEBUG_THROW_IF(is_negative(j) || j > size_type(indices.size()), mtl::index_out_of_range()); } + + public: + sparse_vector(size_type n= 0) : n(n), on_indices(true) /*, longest(0) */ {} + + // ~sparse_vector() { std::cout << "longest vector was " << longest << '\n'; } + + std::size_t nnz() const { assert(indices.size() == data.size()); return indices.size(); } + + bool exists(size_type i) const + { return find(indices.begin(), indices.end(), i) != indices.end(); } + + value_type operator[](size_type i) const + { + typename sv_type::iterator it= find(indices.begin(), indices.end(), i); + // size_type j= distance(indices.begin(), it); + return it != indices.end() ? data[distance(indices.begin(), it)] : value_type(0); + } + + void insert(size_type i, const value_type& v) + { + // vampir_trace<9901> tracer; + typename sv_type::iterator it= std::lower_bound(indices.begin(), indices.end(), i); + if (it == indices.end()) { + // std::cout << "Insert entry " << i << " at the end\n"; + indices.push_back(i); + data.push_back(v); + return; + } + + // std::cout << "Insert entry " << i << " at position " << distance(indices.begin(), it) << '\n'; + typename vv_type::iterator dit= data.begin(); + // std::cout << "*dit == " << *dit << '\n'; + advance(dit, distance(indices.begin(), it)); + // std::cout << "*dit == " << *dit << ", distance(data.begin(), dit) == " << distance(data.begin(), dit) << '\n'; + data.insert(dit, v); // insert v at same position + indices.insert(it, i); + } + + size_type pos(size_type i) const + { + typename sv_type::const_iterator it= std::lower_bound(indices.begin(), indices.end(), i); + MTL_DEBUG_THROW_IF(it == indices.end(), logic_error("Position doesn't exists")); + return distance(indices.begin(), it); + } + + value_type& operator[](size_type i) + { + if (!exists(i)) + insert(i, value_type(0)); + return data[pos(i)]; + } + + void make_empty() { data.resize(0); indices.resize(0); } + + void crop(value_type threshold= value_type(0)) + { + using std::abs; + std::size_t j= 0; + for (std::size_t i= 0, end= data.size(); i < end; i++) + if (abs(data[i]) > threshold) { + if (i > j) { + data[j]= data[i]; + indices[j]= indices[i]; + } + ++j; + } + data.resize(j); + indices.resize(j); + } + + void sort_on_data() // largest magnitude first + { + // vampir_trace<9903> tracer; + if (n > 0) + std::sort(utility::zip_it<value_type, size_type>(&data[0], &indices[0], 0), + utility::zip_it<value_type, size_type>(&data[0], &indices[0], indices.size()), + utility::abs_greater_0()); + on_indices= false; + + // if (indices.size() > longest) longest= indices.size(); + } + + void sort_on_indices() + { + if (n > 0) + std::sort(utility::zip_it<size_type, value_type>(&indices[0], &data[0], 0), + utility::zip_it<size_type, value_type>(&indices[0], &data[0], indices.size()), + utility::less_0()); + on_indices= true; + } + + size_type index(size_type j) const { check(j); return indices[j]; } + value_type const& value(size_type j) const { check(j); return data[j]; } + value_type& value(size_type j) { check(j); return data[j]; } + + std::pair<size_type, value_type> entry(size_type j) const + { return std::make_pair(indices[j], data[j]); } + + std::pair<size_type, value_type> largest(size_type j) const + { + MTL_DEBUG_THROW_IF(on_indices, logic_error("Vector must be sorted on values to use this function")); + MTL_DEBUG_THROW_IF(j > size_type(data.size()), logic_error("There are less than j entries.")); + return std::make_pair(indices[j], data[j]); + } + + friend std::ostream& operator<<(std::ostream& out, const self& v) + { + out << '{' << v.n << (traits::is_row_major<orientation>::value ? "R" : "C") << "}["; + for (std::size_t i= 0, end= v.data.size(); i < end; i++) + out << v.indices[i] << ':' << v.data[i] << (i+1 < end ? ", " : ""); + return out << ']'; + } + + private: + size_type n; + sv_type indices; + vv_type data; + bool on_indices; // if true sorted on indices, otherwise on values + + // std::size_t longest; +}; + +template <typename Value, typename Parameter> +std::size_t inline size(const sparse_vector<Value, Parameter>& v) +{ return v.n; } + + +}} // namespace mtl::vector + +namespace mtl { + using vec::sparse_vector; +} + +#endif // MTL_VECTOR_SPARSE_VECTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/strided_vector_ref.hpp b/install/MTL/include/boost/numeric/mtl/vector/strided_vector_ref.hpp new file mode 100644 index 00000000..9b7d0181 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/strided_vector_ref.hpp @@ -0,0 +1,274 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_STRIDED_VECTOR_REF_INCLUDE +#define MTL_STRIDED_VECTOR_REF_INCLUDE + + +#include <iostream> +#include <cassert> +#include <vector> +#include <algorithm> +#include <boost/static_assert.hpp> +#include <boost/utility/enable_if.hpp> + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/common_include.hpp> +#include <boost/numeric/mtl/vector/all_vec_expr.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> +#include <boost/numeric/mtl/vector/crtp_base_vector.hpp> +#include <boost/numeric/mtl/utility/dense_el_cursor.hpp> +#include <boost/numeric/mtl/utility/range_generator.hpp> +#include <boost/numeric/mtl/utility/property_map.hpp> +#include <boost/numeric/mtl/utility/irange.hpp> +#include <boost/numeric/mtl/utility/is_row_major.hpp> +#include <boost/numeric/mtl/utility/strided_dense_el_iterator.hpp> +#include <boost/numeric/mtl/utility/strided_dense_el_cursor.hpp> +#include <boost/numeric/mtl/operation/is_negative.hpp> + + +namespace mtl { namespace vec { + + +/// Class for referring vectors stored in strides, e.g. columns in a row-major matrix +template <class Value, typename Parameters = parameters<> > +class strided_vector_ref + : public vec_expr<strided_vector_ref<Value, Parameters> >, + public crtp_base_vector< strided_vector_ref<Value, Parameters>, Value, std::size_t > +{ + typedef strided_vector_ref self; + typedef crtp_base_vector< self, Value, std::size_t > crtp_base; + typedef crtp_vector_assign< self, Value, std::size_t > assign_base; + typedef vec_expr<strided_vector_ref<Value, Parameters> > expr_base; + public: + typedef typename boost::remove_const<Value>::type value_type ; + typedef std::size_t size_type ; + typedef Value& reference ; + typedef Value const& const_reference ; + typedef Value* pointer ; + typedef Value const* const_pointer ; + typedef const_pointer key_type; + typedef mtl::strided_dense_el_cursor<Value> cursor_type; + typedef mtl::strided_dense_el_const_iterator<Value> const_iterator; + typedef mtl::strided_dense_el_iterator<Value> iterator; + typedef typename Parameters::orientation orientation; + + void check_index( size_type MTL_DEBUG_ARG(i) ) const + { + MTL_DEBUG_THROW_IF( is_negative(i) || i >= size(*this), index_out_of_range()); + } + + void check_dim( size_type MTL_DEBUG_ARG(s) ) const + { + MTL_DEBUG_THROW_IF( size(*this) != 0 && size(*this) != s, incompatible_size()); + } + + template <class E> + void check_consistent_shape( vec_expr<E> const& ) const + { + MTL_DEBUG_THROW_IF((!boost::is_same< + typename ashape::ashape<self>::type + , typename ashape::ashape<E>::type + >::value), + incompatible_shape()); + } + + private: + /// Make default constructor invisible + strided_vector_ref(); + + public: + + /// Constructor take address, length and stride + strided_vector_ref( size_type length, pointer start_address, size_type stride= 1) + : data(start_address), my_size(length), my_stride(stride), cloned(false) {} + + /// Clone constructor + strided_vector_ref(const strided_vector_ref& other, clone_ctor) + : data(new Value[other.my_size]), my_size(other.my_size), my_stride(1), cloned(true) + { + *this= other; + } + + // Default copy constructor refers to same vector which is okay + + ~strided_vector_ref() { if (cloned && data) delete[] data; } + + // friend size_type inline size(const self& v) { return v.my_size; } // impedes explicit namespace qualification + + template <typename V2, typename P2> + friend std::size_t size(const strided_vector_ref<V2, P2>& v); + + size_type stride() const { return my_stride ; } + + reference operator()( size_type i ) { check_index(i); return data[i * my_stride]; } + const_reference operator()( size_type i ) const { check_index(i); return data[i * my_stride]; } + + reference operator[]( size_type i ) { return (*this)( i ) ; } + const_reference operator[]( size_type i ) const { return (*this)( i ) ; } + + self operator[]( irange r ) { return sub_vector(*this, r.start(), r.finish()); } + const self operator[]( irange r ) const { return sub_vector(*this, r.start(), r.finish()); } + + void delay_assign() const {} + + const_iterator begin() const { return const_iterator(data, my_stride); } + const_iterator end() const { return const_iterator(data + my_size * my_stride, my_stride); } + + iterator begin() { return iterator(data, my_stride); } + iterator end() { return iterator(data + my_size * my_stride, my_stride); } + + /// Address of first data entry; to be used with care. + pointer address_data() { return data; } + const_pointer address_data() const { return data; } + + // from pointer to index + size_type offset(const_pointer p) const + { + size_type o= p - data, i= o / my_stride; + MTL_DEBUG_THROW_IF(o % my_stride, logic_error("Address not consistent with stride.")); + check_index(i); + return i; + } + + friend size_type inline num_rows(const self& v) { return mtl::traits::is_row_major<self>::value ? 1 : size(v); } + friend size_type inline num_cols(const self& v) { return mtl::traits::is_row_major<self>::value ? size(v) : 1; } + + vec_vec_asgn_expr<self, self> operator=( self const& e ) + { + return vec_vec_asgn_expr<self, self>( *this, e ); + } + + // self& operator=(self src) Cannot move! + + using assign_base::operator=; + + template <typename Value2> friend void fill(self& vector, const Value2& value) + { + std::fill(vector.begin(), vector.end(), value); + } + + /// Swapping not efficient since elements have to be swapped for not owning the data + friend void swap(self& vector1, self& vector2) + { + vector1.check_dim(vector2.size()); // size(vector2) doesn't compiled with ICC 10.1 + for (size_type i= 0; i < vector1.size(); ++i) + swap(vector1[i], vector2[i]); + } + + void change_dim(size_type MTL_DEBUG_ARG(n)) { MTL_DEBUG_THROW_IF(my_size != n, incompatible_size()); } + void crop() {} // Only dummy here + + private: + pointer data; + size_type my_size, my_stride; + bool cloned; +} ; // strided_vector_ref + + +template <typename Value, typename Parameters> +inline std::size_t size(const strided_vector_ref<Value, Parameters>& v) +{ + return v.my_size; +} + + +template <typename Value, typename Parameters> +strided_vector_ref<Value, Parameters> +inline sub_vector(strided_vector_ref<Value, Parameters>& v, + typename strided_vector_ref<Value, Parameters>::size_type start, + typename strided_vector_ref<Value, Parameters>::size_type finish) +{ + using std::min; + typedef strided_vector_ref<Value, Parameters> Vector; + typedef typename Vector::size_type size_type; + + MTL_DEBUG_THROW_IF( is_negative(start) || is_negative(finish), index_out_of_range()); + finish= min(finish, size(v)); + start= min(start, finish); // implies min(start, size(v)) + return Vector(start <= finish ? finish - start : size_type(0), &v[start], v.stride()); +} + +template <typename Value, typename Parameters> +const strided_vector_ref<Value, Parameters> +inline sub_vector(const strided_vector_ref<Value, Parameters>& v, + typename strided_vector_ref<Value, Parameters>::size_type start, + typename strided_vector_ref<Value, Parameters>::size_type finish) +{ + typedef strided_vector_ref<Value, Parameters> Vector; + return sub_vector(const_cast<Vector&>(v), start, finish); +} + + +}} // namespace mtl::vector + +namespace mtl { + + // Enable cloning of strided_vector_ref + template <typename Value, typename Parameters> + struct is_clonable< vec::strided_vector_ref<Value, Parameters> > : boost::mpl::true_ {}; + +} // namespace mtl + +namespace mtl { namespace traits { + + +// ================ +// Range generators +// For cursors +// ================ + + template <typename Value, class Parameters> + struct range_generator<tag::all, vec::strided_vector_ref<Value, Parameters> > + : public detail::strided_element_range_generator< + vec::strided_vector_ref<Value, Parameters>, + const vec::strided_vector_ref<Value, Parameters>, + mtl::strided_dense_el_cursor<Value> + > {}; + + template <typename Value, class Parameters> + struct range_generator<tag::nz, vec::strided_vector_ref<Value, Parameters> > + : public range_generator<tag::all, vec::strided_vector_ref<Value, Parameters> > {}; + + template <typename Value, class Parameters> + struct range_generator<tag::iter::all, vec::strided_vector_ref<Value, Parameters> > + : public detail::strided_element_range_generator< + vec::strided_vector_ref<Value, Parameters>, + vec::strided_vector_ref<Value, Parameters>, + mtl::strided_dense_el_iterator<Value> + > {}; + + template <typename Value, class Parameters> + struct range_generator<tag::iter::nz, vec::strided_vector_ref<Value, Parameters> > + : public range_generator<tag::iter::all, vec::strided_vector_ref<Value, Parameters> > {}; + + template <typename Value, class Parameters> + struct range_generator<tag::const_iter::all, vec::strided_vector_ref<Value, Parameters> > + : public detail::strided_element_range_generator< + vec::strided_vector_ref<Value, Parameters>, + const vec::strided_vector_ref<Value, Parameters>, + mtl::strided_dense_el_const_iterator<Value> + > {}; + + template <typename Value, class Parameters> + struct range_generator<tag::const_iter::nz, vec::strided_vector_ref<Value, Parameters> > + : public range_generator<tag::const_iter::all, vec::strided_vector_ref<Value, Parameters> > + {}; + + +}} // namespace mtl::traits + + +#endif // MTL_STRIDED_VECTOR_REF_INCLUDE + diff --git a/install/MTL/include/boost/numeric/mtl/vector/unit_vector.hpp b/install/MTL/include/boost/numeric/mtl/vector/unit_vector.hpp new file mode 100644 index 00000000..15240d05 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/unit_vector.hpp @@ -0,0 +1,64 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_UNIT_VECTOR_INCLUDE +#define MTL_VECTOR_UNIT_VECTOR_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> + +namespace mtl { + +namespace traits { + + /// Type of unit_vector; will be changed later to a proxy for the sake of efficiency + template <typename Value= double> + struct unit_vector + { + typedef mtl::vec::dense_vector<Value, mtl::vec::parameters<> > type; + }; +} + +namespace vec { + + /// Return k-th unit vector of size n + /** The result is a dense column vector. In the future this will + be replaced by a proxy for the sake of efficiency. + If you use unit_vector in an expression you will not encounter + this change. If you define a variable you should use + traits::unit_vector, e.g.: + \code + typename mtl::traits::unit_vector<float>::type e_k(mtl::unit_vector(k, n)); + \endcode + **/ + template <typename Value> + typename traits::unit_vector<Value>::type + inline unit_vector(std::size_t k, std::size_t n) + { + using math::zero; using math::one; + dense_vector<Value> v(n, zero(Value())); + v[k]= one(Value()); + return v; + } + + /// Unit vector of type double + traits::unit_vector<double>::type + inline unit_vector(std::size_t k, std::size_t n) + { + return unit_vector<double>(k, n); + } + +} // namespace mtl::vector + +} // namespace mtl + +#endif // MTL_VECTOR_UNIT_VECTOR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/unrolled1.hpp b/install/MTL/include/boost/numeric/mtl/vector/unrolled1.hpp new file mode 100644 index 00000000..2b05ae51 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/unrolled1.hpp @@ -0,0 +1,61 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_UNROLLED1_INCLUDE +#define MTL_VECTOR_UNROLLED1_INCLUDE + +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/vector/crtp_base_vector.hpp> + +namespace mtl { namespace vec { + +/// Helper class for unrolling loops \sa \ref mtl::unroll +template <unsigned BSize, typename Vector> +class unrolled1 + : public crtp_base_vector< unrolled1<BSize, Vector>, typename Collection<Vector>::value_type, std::size_t > +{ + typedef unrolled1 self; + public: + typedef typename Collection<Vector>::value_type value_type; + typedef typename Collection<Vector>::size_type size_type; + typedef value_type& reference ; + typedef crtp_vector_assign< self, value_type, std::size_t > assign_base; // base of crtp_base_vector + + unrolled1(Vector& ref) : ref(ref) {} + + reference operator()(size_type i) { return ref(i); } + reference operator[](size_type i) { return (*this)(i); } + // const versions shouldn't be needed because it is supposed to be a lvalue + + //friend inline size_type size(const self& v) { return size(v.ref); } + friend inline size_type num_rows(const self& v) { return num_rows(v.ref); } + friend inline size_type num_cols(const self& v) { return num_cols(v.ref); } + + void change_dim(size_type d) { ref.change_dim(d); } + + using assign_base::operator=; + +#if !defined(_MSC_VER) || _MSC_VER != 1400 // Bug in MSVC 2005 + template <unsigned BBSize, typename VVector> + friend inline std::size_t size(const unrolled1<BBSize, VVector>& v); + private: +#endif + Vector& ref; +}; + +template <unsigned BSize, typename Vector> +inline std::size_t size(const unrolled1<BSize, Vector>& v) +{ return size(v.ref); } + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_UNROLLED1_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_const_ref_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_const_ref_expr.hpp new file mode 100644 index 00000000..de266847 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_const_ref_expr.hpp @@ -0,0 +1,42 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_VEC_CONST_REF_EXPR_INCLUDE +#define MTL_VECTOR_VEC_CONST_REF_EXPR_INCLUDE + +namespace mtl { namespace vec { + + +/// Class for providing interface for a vector given as reference +template <typename Vector> +struct vec_const_ref_expr + : vec_expr< vec_const_ref_expr<Vector> > +{ + typedef vec_const_ref_expr self; + typedef typename Vector::size_type size_type; + typedef typename Vector::value_type value_type; + typedef value_type const_dereference_type ; + + vec_const_ref_expr(const Vector& ref) : ref(ref) {} + void delay_assign() const {} + const_dereference_type operator() ( size_type i ) const { return ref(i); } + const_dereference_type operator[] ( size_type i ) const { return ref[i]; } + + friend inline size_type size(const self& v) { return size(v.ref); } + private: + const Vector& ref; +}; + + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_VEC_CONST_REF_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_expr.hpp new file mode 100644 index 00000000..4dfae5b0 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_expr.hpp @@ -0,0 +1,25 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VEC_EXPR_INCLUDE +#define MTL_VEC_EXPR_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> + +namespace mtl { namespace vec { + +template <typename Vector> +struct vec_expr {}; + +}} // namespace mtl::vector + +#endif // MTL_VEC_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_negate_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_negate_expr.hpp new file mode 100644 index 00000000..051bbb70 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_negate_expr.hpp @@ -0,0 +1,30 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VEC_NEGATE_EXPR_INCLUDE +#define MTL_VEC_NEGATE_EXPR_INCLUDE + +#include <boost/numeric/mtl/vector/map_view.hpp> + +namespace mtl { namespace vec { + +template <typename E1> +inline negate_view< E1 > +operator- (const vec_expr<E1>& e1) +{ + return negate_view< E1 >(static_cast<const E1&>(e1)); +} + +} } // Namespace mtl::vector + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_scal_aop_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_aop_expr.hpp new file mode 100644 index 00000000..c2b399b8 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_aop_expr.hpp @@ -0,0 +1,124 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VEC_SCAL_AOP_EXPR_INCLUDE +#define MTL_VEC_SCAL_AOP_EXPR_INCLUDE + +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/vector/vec_expr.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + + +namespace mtl { namespace vec { + +// Generic assign operation expression template for vectors +// Model of VectorExpression +template <class E1, class E2, typename SFunctor> +struct vec_scal_aop_expr + : public vec_expr< vec_scal_aop_expr<E1, E2, SFunctor> > +{ + typedef vec_expr< vec_scal_aop_expr<E1, E2, SFunctor> > expr_base; + typedef vec_scal_aop_expr self; + typedef typename E1::value_type value_type; + + // temporary solution + typedef typename E1::size_type size_type; + //typedef typename utilities::smallest< typename E1::size_type, typename E2::size_type >::type size_type ; + + typedef value_type reference_type ; + + typedef E1 first_argument_type ; + typedef E2 second_argument_type ; + + vec_scal_aop_expr( first_argument_type& v1, second_argument_type const& v2, bool delay= false ) + : first( v1 ), second( v2 ), delayed_assign( delay ), with_comma( false ), index(0) + {} + + ~vec_scal_aop_expr() + { + if (!delayed_assign) { + vampir_trace<2018> tracer; + if (with_comma) { + MTL_DEBUG_THROW_IF(index != mtl::vec::size(first), incompatible_size("Not all vector entries initialized!")); + } else + for (size_type i= 0; i < mtl::vec::size(first); ++i) + SFunctor::apply( first(i), second ); + } + } + + void delay_assign() const + { + MTL_DEBUG_THROW_IF(with_comma, logic_error("Comma notation conflicts with rich expression templates.")); + delayed_assign= true; + } + + //friend size_type inline size(const self& v) { return size(v.first); } + template <typename EE1, typename EE2, typename SSFunctor> + friend std::size_t size(const vec_scal_aop_expr<EE1, EE2, SSFunctor>& v); + + value_type& operator() ( size_type i ) const + { + assert( delayed_assign && !with_comma); + return SFunctor::apply( first(i), second ); + } + + value_type& operator[] ( size_type i ) const + { + assert( delayed_assign ); + return SFunctor::apply( first(i), second ); + } + + template <unsigned Offset> + value_type& at(size_type i) const { + assert(delayed_assign); + return SFunctor::apply(first(i+Offset), second); + } + + template <typename Source> + self& operator, (Source val) + { + //std::cout << "vec_scal_aop_expr::operator,\n"; + if (!with_comma) { + with_comma= true; + assert(index == 0); + SFunctor::apply( first(index++), second); // We haven't set v[0] yet + } + MTL_DEBUG_THROW_IF(index >= mtl::vec::size(first), range_error()); + SFunctor::apply( first(index++), val); + return *this; + } + + private: + first_argument_type& first ; + second_argument_type const& second ; + mutable bool delayed_assign, with_comma; + size_type index; +} ; // vec_scal_aop_expr + + +template <typename E1, typename E2, typename SFunctor> +inline std::size_t size(const vec_scal_aop_expr<E1, E2, SFunctor>& v) +{ + return size(v.first); +} + + + +} } // Namespace mtl::vector + + + + + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_scal_asgn_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_asgn_expr.hpp new file mode 100644 index 00000000..cea78081 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_asgn_expr.hpp @@ -0,0 +1,39 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + + +#ifndef MTL_VEC_SCAL_ASGN_EXPR_INCLUDE +#define MTL_VEC_SCAL_ASGN_EXPR_INCLUDE + +#include <boost/static_assert.hpp> + +#include <boost/numeric/mtl/vector/vec_scal_aop_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + +// Model of VectorExpression +template <class E1, class E2> +struct vec_scal_asgn_expr + : public vec_scal_aop_expr< E1, E2, mtl::sfunctor::assign<typename E1::value_type, E2> > +{ + typedef vec_scal_aop_expr< E1, E2, mtl::sfunctor::assign<typename E1::value_type, E2> > base; + vec_scal_asgn_expr( E1& v1, E2 const& v2 ) + : base( v1, v2 ) + {} +}; + +} } // Namespace mtl::vector + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_scal_div_asgn_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_div_asgn_expr.hpp new file mode 100644 index 00000000..6ad539c1 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_div_asgn_expr.hpp @@ -0,0 +1,34 @@ +/* + * vec_scal_div_asgn_expr.h + * MTL4 + * + * Created by Hui Li (huil@Princeton.EDU) + * + */ + +#ifndef MTL_VEC_SCAL_DIV_ASGN_EXPR_INCLUDE +#define MTL_VEC_SCAL_DIV_ASGN_EXPR_INCLUDE + +#include <boost/static_assert.hpp> + +#include <boost/numeric/mtl/vector/vec_scal_aop_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + + // Model of VectorExpression + template <class E1, class E2> + struct vec_scal_div_asgn_expr + : public vec_scal_aop_expr< E1, E2, mtl::sfunctor::divide_assign<typename E1::value_type, E2> > + { + typedef vec_scal_aop_expr< E1, E2, mtl::sfunctor::divide_assign<typename E1::value_type, E2> > base; + vec_scal_div_asgn_expr( E1& v1, E2 const& v2 ) + : base( v1, v2 ) + {} + }; + +} } // Namespace mtl::vector + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_scal_minus_asgn_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_minus_asgn_expr.hpp new file mode 100644 index 00000000..9e836d6d --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_minus_asgn_expr.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_VEC_SCAL_MINUS_ASGN_EXPR_INCLUDE +#define MTL_VECTOR_VEC_SCAL_MINUS_ASGN_EXPR_INCLUDE + +#include <boost/numeric/mtl/vector/vec_scal_aop_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + +// Model of VectorExpression +template <class E1, class E2> +struct vec_scal_minus_asgn_expr + : public vec_scal_aop_expr< E1, E2, mtl::sfunctor::minus_assign<typename E1::value_type, E2> > +{ + typedef vec_scal_aop_expr< E1, E2, mtl::sfunctor::minus_assign<typename E1::value_type, E2> > base; + vec_scal_minus_asgn_expr( E1& v1, E2 const& v2 ) + : base( v1, v2 ) + {} +}; + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_VEC_SCAL_MINUS_ASGN_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_scal_mixed_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_mixed_expr.hpp new file mode 100644 index 00000000..2ebe0ba3 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_mixed_expr.hpp @@ -0,0 +1,104 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_VEC_SCAL_MIXED_EXPR_INCLUDE +#define MTL_VECTOR_VEC_SCAL_MIXED_EXPR_INCLUDE + +#include <boost/numeric/mtl/utility/enable_if.hpp> +#include <boost/numeric/mtl/vector/map_view.hpp> +#include <boost/numeric/mtl/operation/tfunctor_mixed.hpp> + +namespace mtl { namespace vec { + +template <typename E1, typename E2> +typename mtl::traits::enable_if_scalar<E1, map_view<tfunctor::left_plus<E1, typename E2::value_type>, E2> >::type +inline operator+(const E1& e1, const vec_expr<E2>& e2) +{ + typedef tfunctor::left_plus<E1, typename E2::value_type> ftype; + typedef map_view<ftype, E2> type; + + return type(ftype(e1), static_cast<const E2&>(e2)); +} + +template <typename E1, typename E2> +typename mtl::traits::enable_if_scalar<E2, map_view<tfunctor::right_plus<typename E1::value_type, E2>, E1> >::type +inline operator+(const vec_expr<E1>& e1, const E2& e2) +{ + typedef tfunctor::right_plus<typename E1::value_type, E2>ftype; + typedef map_view<ftype, E1> type; + + return type(ftype(e2), static_cast<const E1&>(e1)); +} + +template <typename E1, typename E2> +typename mtl::traits::enable_if_scalar<E1, map_view<tfunctor::left_minus<E1, typename E2::value_type>, E2> >::type +inline operator-(const E1& e1, const vec_expr<E2>& e2) +{ + typedef tfunctor::left_minus<E1, typename E2::value_type> ftype; + typedef map_view<ftype, E2> type; + + return type(ftype(e1), static_cast<const E2&>(e2)); +} + +template <typename E1, typename E2> +typename mtl::traits::enable_if_scalar<E2, map_view<tfunctor::right_minus<typename E1::value_type, E2>, E1> >::type +inline operator-(const vec_expr<E1>& e1, const E2& e2) +{ + typedef tfunctor::right_minus<typename E1::value_type, E2>ftype; + typedef map_view<ftype, E1> type; + + return type(ftype(e2), static_cast<const E1&>(e1)); +} + +template <typename E1, typename E2> +typename mtl::traits::enable_if_scalar<E1, map_view<tfunctor::left_min<E1, typename E2::value_type>, E2> >::type +inline min(const E1& e1, const vec_expr<E2>& e2) +{ + typedef tfunctor::left_min<E1, typename E2::value_type> ftype; + typedef map_view<ftype, E2> type; + + return type(ftype(e1), static_cast<const E2&>(e2)); +} + +template <typename E1, typename E2> +typename mtl::traits::enable_if_scalar<E2, map_view<tfunctor::right_min<typename E1::value_type, E2>, E1> >::type +inline min(const vec_expr<E1>& e1, const E2& e2) +{ + typedef tfunctor::right_min<typename E1::value_type, E2>ftype; + typedef map_view<ftype, E1> type; + + return type(ftype(e2), static_cast<const E1&>(e1)); +} + +template <typename E1, typename E2> +typename mtl::traits::enable_if_scalar<E1, map_view<tfunctor::left_max<E1, typename E2::value_type>, E2> >::type +inline max(const E1& e1, const vec_expr<E2>& e2) +{ + typedef tfunctor::left_max<E1, typename E2::value_type> ftype; + typedef map_view<ftype, E2> type; + + return type(ftype(e1), static_cast<const E2&>(e2)); +} + +template <typename E1, typename E2> +typename mtl::traits::enable_if_scalar<E2, map_view<tfunctor::right_max<typename E1::value_type, E2>, E1> >::type +inline max(const vec_expr<E1>& e1, const E2& e2) +{ + typedef tfunctor::right_max<typename E1::value_type, E2>ftype; + typedef map_view<ftype, E1> type; + + return type(ftype(e2), static_cast<const E1&>(e1)); +} + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_VEC_SCAL_MIXED_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_scal_plus_asgn_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_plus_asgn_expr.hpp new file mode 100644 index 00000000..dd77e643 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_plus_asgn_expr.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG, www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also tools/license/license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_VEC_SCAL_PLUS_ASGN_EXPR_INCLUDE +#define MTL_VECTOR_VEC_SCAL_PLUS_ASGN_EXPR_INCLUDE + +#include <boost/numeric/mtl/vector/vec_scal_aop_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + +// Model of VectorExpression +template <class E1, class E2> +struct vec_scal_plus_asgn_expr + : public vec_scal_aop_expr< E1, E2, mtl::sfunctor::plus_assign<typename E1::value_type, E2> > +{ + typedef vec_scal_aop_expr< E1, E2, mtl::sfunctor::plus_assign<typename E1::value_type, E2> > base; + vec_scal_plus_asgn_expr( E1& v1, E2 const& v2 ) + : base( v1, v2 ) + {} +}; + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_VEC_SCAL_PLUS_ASGN_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_scal_times_asgn_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_times_asgn_expr.hpp new file mode 100644 index 00000000..f1655507 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_scal_times_asgn_expr.hpp @@ -0,0 +1,37 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + + +#ifndef MTL_VEC_SCAL_TIMES_ASGN_EXPR_INCLUDE +#define MTL_VEC_SCAL_TIMES_ASGN_EXPR_INCLUDE + +#include <boost/numeric/mtl/vector/vec_scal_aop_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + +// Model of VectorExpression +template <class E1, class E2> +struct vec_scal_times_asgn_expr + : public vec_scal_aop_expr< E1, E2, mtl::sfunctor::times_assign<typename E1::value_type, E2> > +{ + typedef vec_scal_aop_expr< E1, E2, mtl::sfunctor::times_assign<typename E1::value_type, E2> > base; + vec_scal_times_asgn_expr( E1& v1, E2 const& v2 ) + : base( v1, v2 ) + {} +}; + +} } // Namespace mtl::vector + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_vec_aop_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_aop_expr.hpp new file mode 100644 index 00000000..c0644fdc --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_aop_expr.hpp @@ -0,0 +1,196 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VEC_VEC_AOP_EXPR_INCLUDE +#define MTL_VEC_VEC_AOP_EXPR_INCLUDE + +#include <boost/mpl/bool.hpp> +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/vector/vec_expr.hpp> +#include <boost/numeric/mtl/operation/static_size.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> +#include <boost/numeric/mtl/utility/is_static.hpp> +#include <boost/numeric/mtl/utility/tag.hpp> +#include <boost/numeric/mtl/utility/category.hpp> +#include <boost/numeric/mtl/utility/omp_size_type.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/utility/unroll_size1.hpp> +#include <boost/numeric/mtl/utility/with_unroll1.hpp> +#include <boost/numeric/mtl/interface/vpt.hpp> + +namespace mtl { namespace vec { + + namespace impl { + + template <unsigned long Index, unsigned long Max, typename SFunctor> + struct assign + { + typedef assign<Index+1, Max, SFunctor> next; + + template <typename E1, typename E2, typename Size> + static inline void apply(E1& first, const E2& second, Size i) + { + SFunctor::apply( first(i+Index), second(i+Index) ); + next::apply( first, second, i ); + } + }; + + template <unsigned long Max, typename SFunctor> + struct assign<Max, Max, SFunctor> + { + template <typename E1, typename E2, typename Size> + static inline void apply(E1& first, const E2& second, Size i) + { + SFunctor::apply( first(i+Max), second(i+Max) ); + } + }; + } + +// Generic assign operation expression template for vectors +// Model of VectorExpression +template <typename E1, typename E2, typename SFunctor> +struct vec_vec_aop_expr + : public vec_expr< vec_vec_aop_expr<E1, E2, SFunctor> > +{ + typedef vec_expr< vec_vec_aop_expr<E1, E2, SFunctor> > expr_base; + typedef vec_vec_aop_expr<E1, E2, SFunctor> self; + typedef typename Collection<E1>::value_type value_type; + + typedef typename Collection<E1>::size_type size_type; + typedef value_type reference_type ; + + typedef E1 first_argument_type ; + typedef E2 second_argument_type ; + + vec_vec_aop_expr( first_argument_type& v1, second_argument_type const& v2, bool delay= false ) + : first(v1), second(v2), delayed_assign(delay) + { + second.delay_assign(); + } + + private: + void dynamic_assign(boost::mpl::false_) // Without unrolling + { + typedef typename traits::omp_size_type<size_type>::type size_type; + size_type s= size_type(mtl::vec::size(first)); + + #ifdef MTL_WITH_OPENMP + # pragma omp parallel + { + vampir_trace<8003> tracer; + #pragma omp for + for (size_type i= 0; i < s; ++i) + SFunctor::apply( first(i), second(i) ); + } + #else + for (size_type i= 0; i < s; ++i) + SFunctor::apply( first(i), second(i) ); + #endif + } + + void dynamic_assign(boost::mpl::true_) // With unrolling + { + typedef typename traits::omp_size_type<size_type>::type size_type; + const size_type BSize= traits::unroll_size1<E1>::value0; + size_type s= mtl::vec::size(first), sb= s / BSize * BSize; + + #ifdef MTL_WITH_OPENMP + # pragma omp parallel + { + vampir_trace<8003> tracer; + #pragma omp for + for (size_type i= 0; i < sb; i+= BSize) + impl::assign<0, BSize-1, SFunctor>::apply(first, second, i); + } + #else + for (size_type i= 0; i < sb; i+= BSize) + impl::assign<0, BSize-1, SFunctor>::apply(first, second, i); + #endif + + for (size_type i= sb; i < s; i++) + SFunctor::apply( first(i), second(i) ); + } + + + void assign(boost::mpl::false_) + { + vampir_trace<2017> tracer; + // If target is constructed by default it takes size of source + //int a= size(second); + //int b= second; + if (mtl::vec::size(first) == 0) first.change_dim(mtl::size(second)); + MTL_DEBUG_THROW_IF(mtl::vec::size(first) != mtl::vec::size(second), incompatible_size()); // otherwise error + + // need to do more benchmarking before making unrolling default + dynamic_assign(traits::with_unroll1<E1>()); + } + + void assign(boost::mpl::true_) + { + vampir_trace<1001> tracer; + MTL_DEBUG_THROW_IF(mtl::vec::size(first) != mtl::vec::size(second), incompatible_size()); // We cannot resize, only check + + // impl::assign<0, static_size<E1>::value-1, SFunctor>::apply(first, second); // Slower, at least on gcc + for (size_type i= 0; i < mtl::vec::size(first); ++i) // Do an ordinary loop instead + SFunctor::apply(first(i), second(i)); + } + + public: + ~vec_vec_aop_expr() + { + if (!delayed_assign) + assign(traits::is_static<E1>()); + } + + void delay_assign() const { delayed_assign= true; } + + template <typename EE1, typename EE2, typename SSFunctor> + friend std::size_t size(const vec_vec_aop_expr<EE1, EE2, SSFunctor>& v); + + value_type& operator() (size_type i) const { + assert( delayed_assign ); + return SFunctor::apply(first(i), second(i)); + } + + value_type& operator[] (size_type i) const { return (*this)(i); } + + template <unsigned Offset> + value_type& at(size_type i) const { + assert(delayed_assign); + return SFunctor::apply(first(i+Offset), second(i+Offset)); + } + + first_argument_type const& first_argument() const { return first; } + second_argument_type const& second_argument() const { return second; } + + private: + first_argument_type& first ; + second_argument_type const& second ; + mutable bool delayed_assign; +} ; // vec_vec_aop_expr + +template <typename E1, typename E2, typename SFunctor> +inline std::size_t size(const vec_vec_aop_expr<E1, E2, SFunctor>& v) +{ + MTL_DEBUG_THROW_IF( size(v.first) != 0 && size(v.first) != size(v.second), incompatible_size()); + return size(v.second); +} + +} } // Namespace mtl::vector + + + + +#endif + + diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_vec_asgn_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_asgn_expr.hpp new file mode 100644 index 00000000..3e856069 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_asgn_expr.hpp @@ -0,0 +1,44 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Adapted from GLAS implementation by Karl Meerbergen and Toon Knappen + + +#ifndef MTL_VEC_VEC_ASGN_EXPR_INCLUDE +#define MTL_VEC_VEC_ASGN_EXPR_INCLUDE + +#include <boost/static_assert.hpp> + +#include <boost/numeric/mtl/vector/vec_vec_aop_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + +// Model of VectorExpression +template <class E1, class E2> +struct vec_vec_asgn_expr + : public vec_vec_aop_expr< E1, E2, mtl::sfunctor::assign<typename E1::value_type, typename E2::value_type> > +{ + typedef vec_vec_aop_expr< E1, E2, mtl::sfunctor::assign<typename E1::value_type, typename E2::value_type> > base; + vec_vec_asgn_expr( E1& v1, E2 const& v2 ) + : base( v1, v2 ) + {} +}; + +} } // Namespace mtl::vector + + + + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_vec_div_asgn_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_div_asgn_expr.hpp new file mode 100644 index 00000000..026ca91d --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_div_asgn_expr.hpp @@ -0,0 +1,41 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Adapted from GLAS implementation by Karl Meerbergen and Toon Knappen + + +#ifndef MTL_VEC_VEC_DIV_ASGN_EXPR_INCLUDE +#define MTL_VEC_VEC_DIV_ASGN_EXPR_INCLUDE + +#include <boost/static_assert.hpp> + +#include <boost/numeric/mtl/vector/vec_vec_aop_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + +// Model of VectorExpression +template <class E1, class E2> +struct vec_vec_div_asgn_expr + : public vec_vec_aop_expr< E1, E2, mtl::sfunctor::divide_assign<typename E1::value_type, typename E2::value_type> > +{ + typedef vec_vec_aop_expr< E1, E2, mtl::sfunctor::divide_assign<typename E1::value_type, typename E2::value_type> > base; + vec_vec_div_asgn_expr( E1& v1, E2 const& v2 ) + : base( v1, v2 ) + {} +}; + +} } // Namespace mtl::vector + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_vec_ele_prod_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_ele_prod_expr.hpp new file mode 100644 index 00000000..35e831de --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_ele_prod_expr.hpp @@ -0,0 +1,41 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_VEC_VEC_ELE_PROD_EXPR_INCLUDE +#define MTL_VECTOR_VEC_VEC_ELE_PROD_EXPR_INCLUDE + +#include <boost/static_assert.hpp> + +#include <boost/numeric/mtl/vector/vec_vec_op_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + +template <typename E1, typename E2> +inline vec_vec_op_expr< E1, E2, mtl::sfunctor::times<typename E1::value_type, typename E2::value_type> > +ele_prod(const vec_expr<E1>& e1, const vec_expr<E2>& e2) +{ + // do not add row and column vectors (or inconsistent value types) + MTL_STATIC_ASSERT((boost::is_same<typename ashape::ashape<E1>::type, + typename ashape::ashape<E2>::type>::value), + "Vectors do not have consistent algebraic shape (i.e. nested types)."); + typedef vec_vec_op_expr< E1, E2, mtl::sfunctor::times<typename E1::value_type, typename E2::value_type> > type; + return type(static_cast<const E1&>(e1), static_cast<const E2&>(e2)); +} + + + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_VEC_VEC_ELE_PROD_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_vec_ele_quot_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_ele_quot_expr.hpp new file mode 100644 index 00000000..7ac82716 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_ele_quot_expr.hpp @@ -0,0 +1,39 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_VEC_VEC_ELE_QUOT_EXPR_INCLUDE +#define MTL_VECTOR_VEC_VEC_ELE_QUOT_EXPR_INCLUDE + +#include <boost/numeric/mtl/vector/vec_vec_op_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + +template <typename E1, typename E2> +inline vec_vec_op_expr< E1, E2, mtl::sfunctor::divide<typename E1::value_type, typename E2::value_type> > +ele_quot(const vec_expr<E1>& e1, const vec_expr<E2>& e2) +{ + // do not add row and column vectors (or inconsistent value types) + MTL_STATIC_ASSERT((boost::is_same<typename ashape::ashape<E1>::type, + typename ashape::ashape<E2>::type>::value), + "Vectors do not have consistent algebraic shape (i.e. nested types)."); + typedef vec_vec_op_expr< E1, E2, mtl::sfunctor::divide<typename E1::value_type, typename E2::value_type> > type; + return type(static_cast<const E1&>(e1), static_cast<const E2&>(e2)); +} + + + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_VEC_VEC_ELE_QUOT_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_vec_minus_asgn_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_minus_asgn_expr.hpp new file mode 100644 index 00000000..18ff07ef --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_minus_asgn_expr.hpp @@ -0,0 +1,41 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Adapted from GLAS implementation by Karl Meerbergen and Toon Knappen + + +#ifndef MTL_VEC_VEC_MINUS_ASGN_EXPR_INCLUDE +#define MTL_VEC_VEC_MINUS_ASGN_EXPR_INCLUDE + +#include <boost/static_assert.hpp> + +#include <boost/numeric/mtl/vector/vec_vec_aop_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + +// Model of VectorExpression +template <class E1, class E2> +struct vec_vec_minus_asgn_expr + : public vec_vec_aop_expr< E1, E2, mtl::sfunctor::minus_assign<typename E1::value_type, typename E2::value_type> > +{ + typedef vec_vec_aop_expr< E1, E2, mtl::sfunctor::minus_assign<typename E1::value_type, typename E2::value_type> > base; + vec_vec_minus_asgn_expr( E1& v1, E2 const& v2 ) + : base( v1, v2 ) + {} +}; + +} } // Namespace mtl::vector + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_vec_minus_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_minus_expr.hpp new file mode 100644 index 00000000..8951eaf6 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_minus_expr.hpp @@ -0,0 +1,43 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Adapted from GLAS implementation by Karl Meerbergen and Toon Knappen + + +#ifndef MTL_VEC_VEC_MINUS_EXPR_INCLUDE +#define MTL_VEC_VEC_MINUS_EXPR_INCLUDE + +#include <boost/static_assert.hpp> + +#include <boost/numeric/mtl/vector/vec_vec_pmop_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + +template <typename E1, typename E2> +inline vec_vec_pmop_expr< E1, E2, mtl::sfunctor::minus<typename E1::value_type, typename E2::value_type> > +operator- (const vec_expr<E1>& e1, const vec_expr<E2>& e2) +{ + // do not subtract row and column vectors (or inconsistent value types) + MTL_STATIC_ASSERT((boost::is_same<typename ashape::ashape<E1>::type, + typename ashape::ashape<E1>::type>::value), + "Vectors do not have consistent algebraic shape (i.e. nested types)."); + typedef vec_vec_pmop_expr< E1, E2, mtl::sfunctor::minus<typename E1::value_type, typename E2::value_type> > type; + return type(static_cast<const E1&>(e1), static_cast<const E2&>(e2)); +} + +} } // Namespace mtl::vector + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_vec_op_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_op_expr.hpp new file mode 100644 index 00000000..cb41ce76 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_op_expr.hpp @@ -0,0 +1,89 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Adapted from GLAS implementation by Karl Meerbergen and Toon Knappen + + +#ifndef MTL_VEC_VEC_OP_EXPR_INCLUDE +#define MTL_VEC_VEC_OP_EXPR_INCLUDE + +#include <boost/numeric/mtl/vector/vec_expr.hpp> + +namespace mtl { namespace vec { + +// Model of VectorExpression +template <typename E1, typename E2, typename SFunctor> +struct vec_vec_op_expr + : public vec_expr< vec_vec_op_expr<E1, E2, SFunctor> > +{ + typedef vec_expr< vec_vec_op_expr<E1, E2, SFunctor> > expr_base; + typedef vec_vec_op_expr self; + + // temporary solution + // typedef typename E1::value_type value_type; + // typedef typename glas::value< glas::scalar::vec_vec_op_expr<typename E1::value_type, typename E2::value_type > >::type value_type ; + typedef typename SFunctor::result_type value_type; + + // temporary solution + typedef typename E1::size_type size_type; + //typedef typename utilities::smallest< typename E1::size_type, typename E2::size_type >::type size_type ; + + typedef value_type const_dereference_type ; + + typedef E1 first_argument_type ; + typedef E2 second_argument_type ; + +public: + vec_vec_op_expr( first_argument_type const& v1, second_argument_type const& v2 ) + : first( v1 ), second( v2 ) + { + // std::cerr << "vec_vec_op_expr.vec_vec_op_expr() " << size(first) << " " << size(second) << "\n"; + first.delay_assign(); + second.delay_assign(); + } + + void delay_assign() const {} + + template <typename EE1, typename EE2, typename SSFunctor> + friend std::size_t size(const vec_vec_op_expr<EE1, EE2, SSFunctor>& v); + + const_dereference_type operator() ( size_type i ) const + { + return SFunctor::apply( first( i ), second( i ) ) ; + } + + const_dereference_type operator[] ( size_type i ) const + { + return SFunctor::apply( first( i ), second( i ) ) ; + } + + private: + first_argument_type const& first ; + second_argument_type const& second ; +} ; // vec_vec_op_expr + + +template <typename E1, typename E2, typename SFunctor> +inline std::size_t size(const vec_vec_op_expr<E1, E2, SFunctor>& v) +{ + // std::cerr << "vec_vec_op_expr.size() " << first.size() << " " << second.size() << "\n"; + assert( size(v.first) == size(v.second) ) ; + return size(v.first) ; +} + + + +} } // Namespace mtl::vector + + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_vec_plus_asgn_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_plus_asgn_expr.hpp new file mode 100644 index 00000000..1d8a7eed --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_plus_asgn_expr.hpp @@ -0,0 +1,41 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Adapted from GLAS implementation by Karl Meerbergen and Toon Knappen + + +#ifndef MTL_VEC_VEC_PLUS_ASGN_EXPR_INCLUDE +#define MTL_VEC_VEC_PLUS_ASGN_EXPR_INCLUDE + +#include <boost/static_assert.hpp> + +#include <boost/numeric/mtl/vector/vec_vec_aop_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + +// Model of VectorExpression +template <class E1, class E2> +struct vec_vec_plus_asgn_expr + : public vec_vec_aop_expr< E1, E2, mtl::sfunctor::plus_assign<typename E1::value_type, typename E2::value_type> > +{ + typedef vec_vec_aop_expr< E1, E2, mtl::sfunctor::plus_assign<typename E1::value_type, typename E2::value_type> > base; + vec_vec_plus_asgn_expr( E1& v1, E2 const& v2 ) + : base( v1, v2 ) + {} +}; + +} } // Namespace mtl::vector + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_vec_plus_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_plus_expr.hpp new file mode 100644 index 00000000..a0c3ec8e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_plus_expr.hpp @@ -0,0 +1,41 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Adapted from GLAS implementation by Karl Meerbergen and Toon Knappen + + +#ifndef MTL_VEC_VEC_PLUS_EXPR_INCLUDE +#define MTL_VEC_VEC_PLUS_EXPR_INCLUDE + +#include <boost/numeric/mtl/vector/vec_vec_pmop_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/utility/static_assert.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + +template <typename E1, typename E2> +inline vec_vec_pmop_expr< E1, E2, mtl::sfunctor::plus<typename E1::value_type, typename E2::value_type> > +operator+ (const vec_expr<E1>& e1, const vec_expr<E2>& e2) +{ + // do not add row and column vectors (or inconsistent value types) + MTL_STATIC_ASSERT((boost::is_same<typename ashape::ashape<E1>::type, + typename ashape::ashape<E2>::type>::value), + "Vectors do not have consistent algebraic shape (i.e. nested types)."); + typedef vec_vec_pmop_expr< E1, E2, mtl::sfunctor::plus<typename E1::value_type, typename E2::value_type> > type; + return type(static_cast<const E1&>(e1), static_cast<const E2&>(e2)); +} + +} } // Namespace mtl::vector + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_vec_pmop_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_pmop_expr.hpp new file mode 100644 index 00000000..4ee7db09 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_pmop_expr.hpp @@ -0,0 +1,88 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTOR_VEC_VEC_PMOP_EXPR_INCLUDE +#define MTL_VECTOR_VEC_VEC_PMOP_EXPR_INCLUDE + +#include <boost/numeric/mtl/mtl_fwd.hpp> +#include <boost/numeric/mtl/concept/collection.hpp> +#include <boost/numeric/mtl/vector/vec_expr.hpp> +#include <boost/numeric/mtl/operation/compute_summand.hpp> +#include <boost/numeric/mtl/utility/exception.hpp> + +namespace mtl { namespace vec { + +// Model of VectorExpression +template <class E1, class E2, typename SFunctor> +struct vec_vec_pmop_expr + : vec_expr< vec_vec_pmop_expr<E1, E2, SFunctor> > +{ + typedef vec_vec_pmop_expr<E1, E2, SFunctor> self; + typedef typename mtl::operation::compute_summand<E1>::type first_argument_type; + typedef typename mtl::operation::compute_summand<E2>::type second_argument_type; + typedef SFunctor functor_type; + + typedef typename SFunctor::result_type const_dereference_type; + + typedef const_dereference_type value_type; + typedef typename Collection<first_argument_type>::size_type size_type; + + vec_vec_pmop_expr( E1 const& v1, E2 const& v2 ) + : first(v1), second(v2) + { + first.value.delay_assign(); second.value.delay_assign(); + } + + void delay_assign() const {} + +#if 0 + friend size_type inline size(const self& x) + { + assert( size(x.first.value) == 0 || size(x.first.value) == size(x.second.value) ); + return size(x.first.value); + } +#endif + + template <typename EE1, typename EE2, typename SSFunctor> + friend std::size_t size(const vec_vec_pmop_expr<EE1, EE2, SSFunctor>&); + + const_dereference_type operator() (size_type i) const + { + return SFunctor::apply(first.value(i), second.value(i)); + } + + const_dereference_type operator[] (size_type i) const + { + return SFunctor::apply(first.value(i), second.value(i)); + } + + operation::compute_summand<E1> const& first_argument() const { return first; } + operation::compute_summand<E2> const& second_argument() const { return second; } + + private: + operation::compute_summand<E1> first; + operation::compute_summand<E2> second; +}; + +template <typename E1, typename E2, typename SFunctor> +inline std::size_t size(const vec_vec_pmop_expr<E1, E2, SFunctor>& v) +{ + MTL_DEBUG_THROW_IF(mtl::vec::size(v.first.value) != 0 + && mtl::vec::size(v.first.value) != mtl::vec::size(v.second.value), incompatible_size()); + return mtl::vec::size(v.first.value); +} + + + +}} // namespace mtl::vector + +#endif // MTL_VECTOR_VEC_VEC_PMOP_EXPR_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/vector/vec_vec_times_asgn_expr.hpp b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_times_asgn_expr.hpp new file mode 100644 index 00000000..229aae16 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vector/vec_vec_times_asgn_expr.hpp @@ -0,0 +1,41 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +// Adapted from GLAS implementation by Karl Meerbergen and Toon Knappen + + +#ifndef MTL_VEC_VEC_TIMES_ASGN_EXPR_INCLUDE +#define MTL_VEC_VEC_TIMES_ASGN_EXPR_INCLUDE + +#include <boost/static_assert.hpp> + +#include <boost/numeric/mtl/vector/vec_vec_aop_expr.hpp> +#include <boost/numeric/mtl/utility/ashape.hpp> +#include <boost/numeric/mtl/operation/sfunctor.hpp> + +namespace mtl { namespace vec { + +// Model of VectorExpression +template <class E1, class E2> +struct vec_vec_times_asgn_expr + : public vec_vec_aop_expr< E1, E2, mtl::sfunctor::times_assign<typename E1::value_type, typename E2::value_type> > +{ + typedef vec_vec_aop_expr< E1, E2, mtl::sfunctor::times_assign<typename E1::value_type, typename E2::value_type> > base; + vec_vec_times_asgn_expr( E1& v1, E2 const& v2 ) + : base( v1, v2 ) + {} +}; + +} } // Namespace mtl::vector + +#endif + diff --git a/install/MTL/include/boost/numeric/mtl/vectors.hpp b/install/MTL/include/boost/numeric/mtl/vectors.hpp new file mode 100644 index 00000000..df9c79e2 --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/vectors.hpp @@ -0,0 +1,35 @@ +// Software License for MTL +// +// Copyright (c) 2007 The Trustees of Indiana University. +// 2008 Dresden University of Technology and the Trustees of Indiana University. +// 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +// All rights reserved. +// Authors: Peter Gottschling and Andrew Lumsdaine +// +// This file is part of the Matrix Template Library +// +// See also license.mtl.txt in the distribution. + +#ifndef MTL_VECTORS_INCLUDE +#define MTL_VECTORS_INCLUDE + +#include <boost/numeric/mtl/vector/dense_vector.hpp> +#include <boost/numeric/mtl/vector/unit_vector.hpp> +#include <boost/numeric/mtl/vector/strided_vector_ref.hpp> +#include <boost/numeric/mtl/vector/parameter.hpp> +#include <boost/numeric/mtl/vector/inserter.hpp> +#include <boost/numeric/mtl/vector/mapped_inserter.hpp> +#include <boost/numeric/mtl/vector/extracter.hpp> +#include <boost/numeric/mtl/vector/sparse_vector.hpp> + +#include <boost/numeric/mtl/vector/assigner.hpp> +#include <boost/numeric/mtl/vector/decrementer.hpp> +#include <boost/numeric/mtl/vector/incrementer.hpp> + +// To find operators +#include <boost/numeric/mtl/vector/vec_vec_minus_expr.hpp> +#include <boost/numeric/mtl/vector/vec_vec_plus_expr.hpp> + +#include <boost/numeric/mtl/utility/vector_type_generator.hpp> + +#endif // MTL_VECTORS_INCLUDE diff --git a/install/MTL/include/boost/numeric/mtl/version.hpp.in b/install/MTL/include/boost/numeric/mtl/version.hpp.in new file mode 100644 index 00000000..c43d4d4e --- /dev/null +++ b/install/MTL/include/boost/numeric/mtl/version.hpp.in @@ -0,0 +1,6 @@ +#ifndef MTL_VERSION_HPP +#define MTL_VERSION_HPP + +#define MTL_VERSION @MTL_MINOR_VERSION@ + +#endif diff --git a/install/MTL/share/mtl/MTLConfig.cmake b/install/MTL/share/mtl/MTLConfig.cmake new file mode 100644 index 00000000..8b44981d --- /dev/null +++ b/install/MTL/share/mtl/MTLConfig.cmake @@ -0,0 +1,6 @@ +set(MTL_COMMON_CONFIG "${MTL_DIR}/tools/cmake/MTLCommon.cmake") +if( EXISTS ${MTL_COMMON_CONFIG}) + include(${MTL_COMMON_CONFIG}) +else() + message(ERROR "could not find the common mtl configuration. this is possibly a wrong installation of mtl.") +endif() diff --git a/install/MTL/share/mtl/README b/install/MTL/share/mtl/README new file mode 100644 index 00000000..a0988f98 --- /dev/null +++ b/install/MTL/share/mtl/README @@ -0,0 +1,118 @@ +-*- text -*- + +Software License for MTL + +Copyright (c) 2007-2008 The Trustees of Indiana University. All rights reserved. +Authors: Peter Gottschling and Andrew Lumsdaine + +This file is part of the Matrix Template Library + +See also license.mtl.txt in the distribution. +--------------------------------------------------------------- + + The Matrix Template Library + Version 4 + +I. Introduction +=============== + +The Matrix Template Library is a C++ class library for basic linear +algebra. The MTL is designed for high-performance while at the same +time taking advantage of the generic programming paradigm (ala the +STL) to allow much greater flexibility and breadth of +functionality. Many new and advanced programming techniques were used +in the construction of this library. + +The MTL is a low level library in the sense that the user must be +conscious of the matrix type being used, and that all computationally +expensive operations are explicit. The MTL is not a C++ Matlab or +Mathematica. Nevertheless, the interface is designed to be simple and easy +to use. + +The matrix types provided include compressed sparse row/column, +traditional row- and column-major dense, Morton-order, and block-recursive +matrices. All matrix types share a common and easy to use interface. + +The algorithms consist of the traditional basic linear algebra +routines (from the BLAS level-1 to 3) which includes matrix and vector +arithmetic. + + +II. Compilers +============= + +The Matrix Template Library is written in compliance with the C++ standard +and should be compilable with every compiler compliant with the standard. +It has been tested (and passed) with the following compilers and architectures: + +Linux & MacOS +------------- + clang++ 3.0 (32 bit) + g++ 4.1.3 (32 and 64 bit) + g++ 4.2.4 (64bit) + g++ 4.3.4 (32 and 64 bit) + g++ 4.4.3 (32 and 64 bit) + g++ 4.5.1 (64 bit) + g++ 4.6.0 (64 bit) + g++ 4.6.1 (64 bit) + icc 9.1 (32 and 64 bit) + icc 10.0 (32 and 64 bit) + icc 10.1 (32 and 64 bit) + icc 11.0 (32 and 64 bit) + icc 11.1 (32 and 64 bit) + +Windows +------- + VC 8.0 from Visual Studio 2005 (32 bit) + VC 9.0 from Visual Studio 2008 (32 bit) + VC 10.0 from Visual Studio 2010 (32 bit) + +Compilers that are not standard-compliant (e.g. VC 6.0 from VS 2003) are not subject to support. + + +III. Documentation +================== + +The documentation can be generated with doxygen in the main directory and +is found in the /libs/numeric/mtl/doc. You +can also view the documentation at our web site: +http://www.simunova.com/node/184 +At the moment, the documentation illustrates the basic operations and +partially provides a reference manual of some classes and functions. +A detailed description of more features, especially tuning opportunities, +is in the works. + +There are also a large number of examples in the /libs/numeric/mtl/examples +directory. + + +IV. Installation Procedure +========================== + +See the file INSTALL in this directory. + + + +V. Contact Information +======================= + +The Matrix Template Library is available at the main distribution site: + + http://www.mtl4.org + +This distribution includes: + + - Source code for the MTL (all header files /boost/numeric/mtl) + - Some completing sources (header files /boost/numeric/meta_math) + - A test suite (/libs/numeric/mtl/test) + - Some example code (/libs/numeric/mtl/examples) + +Bug reports should be sent to mtl4@osl.iu.edu. + +Questions, comments, suggestions, and requests for additional +information should also be directed to mtl4@osl.iu.edu. + +Subscribe at: + + http://www.osl.iu.edu/mailman/listinfo.cgi/mtl4 + diff --git a/install/MTL/share/mtl/license.mtl.txt b/install/MTL/share/mtl/license.mtl.txt new file mode 100644 index 00000000..ead095a7 --- /dev/null +++ b/install/MTL/share/mtl/license.mtl.txt @@ -0,0 +1,53 @@ +Software License for MTL + +Copyright (c) 2007 The Trustees of Indiana University. + 2008 Dresden University of Technology and the Trustees of Indiana University. + 2010 SimuNova UG (haftungsbeschränkt), www.simunova.com. +All rights reserved. +Authors: Peter Gottschling and Andrew Lumsdaine + +This file is part of the Matrix Template Library + +Dresden University of Technology -- short TUD -- and Indiana University -- short IU -- +have the exclusive rights to license this product under the following license. + +Redistribution and use in source and binary forms, with or without modification, are permitted +provided that the following conditions are met: + 1. All redistributions of source code must retain the above copyright notice, + the list of authors in the original source code, this list of conditions and + the disclaimer listed in this license; + 2. All redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the disclaimer listed in this license in the + documentation and/or other materials provided with the distribution; + 3. Any documentation included with all redistributions must include the + following acknowledgement: + "This product includes software developed at the University of Notre Dame, + the Pervasive Technology Labs at Indiana University, and Dresden University of + Technology. For technical information + contact Andrew Lumsdaine at the Pervasive Technology Labs at Indiana University. + For administrative and license questions contact the Advanced Research and + Technology Institute at 1100 Waterway Blvd. Indianapolis, Indiana 46202, + phone 317-274-5905, fax 317-274-5902." + Alternatively, this acknowledgement may appear in the software itself, and + wherever such third-party acknowledgments normally appear. + 4. The name "MTL" shall not be used to endorse or promote products derived from + this software without prior written permission from IU or TUD. For + written permission, please contact Indiana University Advanced Research + & Technology Institute. + 5. Products derived from this software may not be called "MTL", nor may "MTL" + appear in their name, without prior written permission of Indiana University + Advanced Research & Technology Institute. + +TUD and IU provide no reassurances that the source code provided does not infringe the +patent or any other intellectual property rights of any other entity. TUD and IU disclaim +any liability to any recipient for claims brought by any other entity based on infringement of +intellectual property rights or otherwise. + +LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO WARRANTIES AS TO CAPABILITIES +OR ACCURACY ARE MADE. DRESDEN UNIVERSITY OF TECHNOLOGY AND INDIANA UNIVERSITY GIVE NO WARRANTIES +AND MAKE NO REPRESENTATION THAT SOFTWARE IS FREE OF INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, +OR OTHER PROPRIETARY RIGHTS. DRESDEN UNIVERSITY OF TECHNOLOGY AND INDIANA UNIVERSITY MAKE NO +WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", "VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", +OR OTHER HARMFUL CODE. LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR +ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION GENERATED USING SOFTWARE. + diff --git a/install/MTL/share/mtl/tools/cmake/ARPREC.cmake b/install/MTL/share/mtl/tools/cmake/ARPREC.cmake new file mode 100644 index 00000000..d1844227 --- /dev/null +++ b/install/MTL/share/mtl/tools/cmake/ARPREC.cmake @@ -0,0 +1,9 @@ +find_file(MP_REAL_H "arprec/mp_real.h" PATHS $ENV{ARPREC_HEADER_HINT} DOC "The arprec header mp_real.h; you can provide the path of it in the environment variable ARPREC_HEADER_HINT.") +find_library(ARPREC_LIBRARY arprec PATHS $ENV{ARPREC_LIBRARY_HINT} DOC "the arprec library arprec; you can provide the path of it in the environment variable ARPREC_LIBRARY_HINT.") +set(HAVE_ARPREC false) +if(MP_REAL_H AND ARPREC_LIBRARY) + get_filename_component(ARPREC_INCLUDE_DIRS ${MP_REAL_H} PATH) + set(ARPREC_INCLUDE_DIRS "${ARPREC_INCLUDE_DIRS}/../") + set(HAVE_ARPREC true) + set(ARPREC_LIBRARIES ${ARPREC_LIBRARY}) +endif() diff --git a/install/MTL/share/mtl/tools/cmake/AUTO_CHECK.cpp b/install/MTL/share/mtl/tools/cmake/AUTO_CHECK.cpp new file mode 100644 index 00000000..fbc281df --- /dev/null +++ b/install/MTL/share/mtl/tools/cmake/AUTO_CHECK.cpp @@ -0,0 +1,7 @@ + +int main() +{ + auto x= 8.3 - 7u; + + return 0; +} diff --git a/install/MTL/share/mtl/tools/cmake/C++11Features.cmake b/install/MTL/share/mtl/tools/cmake/C++11Features.cmake new file mode 100644 index 00000000..c0947f38 --- /dev/null +++ b/install/MTL/share/mtl/tools/cmake/C++11Features.cmake @@ -0,0 +1,52 @@ +include(CheckCXXCompilerFlag) + +option(MTL_VERBOSE_TRYCOMPILE "Print error message when C++11 feature is not supported" OFF) + +# Compiler flag for C++11: special case for VC only, everything else should be equal +# Might need later adaption, once compilers don't support this flag any longer +if(MSVC) + set(CXX_ELEVEN_FLAG "/Qstd=c++0x") +else() + set(CXX_ELEVEN_FLAG "-std=c++0x") +endif() + +# only performed once (to reevaluated delete CMakeCache.txt) +check_cxx_compiler_flag("${CXX_ELEVEN_FLAG}" CXX_ELEVEN_FLAG_SUPPORTED) + +if (NOT CXX_ELEVEN_FLAG_SUPPORTED) + if (ENABLE_CXX_ELEVEN) + message("C++11 flag not supported by your compiler (probably too old).") + endif() + return() +endif() + +if (NOT ENABLE_CXX_ELEVEN) + return() +endif() + +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(CXX_ELEVEN_FLAG "${CXX_ELEVEN_FLAG} -stdlib=libc++") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lc++") +endif() + +message(STATUS "Add ${CXX_ELEVEN_FLAG}") +list(APPEND MTL_CXX_DEFINITIONS ${CXX_ELEVEN_FLAG}) +#add_definitions("${CXX_ELEVEN_FLAG}") + +# set (CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL") +file(GLOB CHECKS "${MTL_DIR}/tools/cmake/*_CHECK.cpp") + +foreach (CURFILE ${CHECKS}) + get_filename_component(FNAME ${CURFILE} NAME_WE) + string(REPLACE "_CHECK" "" feature ${FNAME}) + # message(STATUS "${feature}") + try_compile(${feature}_RESULT ${CMAKE_BINARY_DIR} "${CURFILE}" COMPILE_DEFINITIONS "${CXX_ELEVEN_FLAG}" OUTPUT_VARIABLE errors) + message(STATUS "Support C++11's ${feature} - ${${feature}_RESULT}") + if (${feature}_RESULT) + list(APPEND MTL_CXX_DEFINITIONS "-DMTL_WITH_${feature}") + elseif (MTL_VERBOSE_TRYCOMPILE) + message(STATUS "Failed because: ${errors}") + endif() +endforeach() + +# message(STATUS "C++11 flags: ${MTL_CXX_DEFINITIONS}") diff --git a/install/MTL/share/mtl/tools/cmake/DEFAULTIMPL_CHECK.cpp b/install/MTL/share/mtl/tools/cmake/DEFAULTIMPL_CHECK.cpp new file mode 100644 index 00000000..587c6b6c --- /dev/null +++ b/install/MTL/share/mtl/tools/cmake/DEFAULTIMPL_CHECK.cpp @@ -0,0 +1,9 @@ +struct dings +{ + dings(const dings&) = default; +}; + +int main() +{ + return 0; +} diff --git a/install/MTL/share/mtl/tools/cmake/INITLIST_CHECK.cpp b/install/MTL/share/mtl/tools/cmake/INITLIST_CHECK.cpp new file mode 100644 index 00000000..4cbf89f1 --- /dev/null +++ b/install/MTL/share/mtl/tools/cmake/INITLIST_CHECK.cpp @@ -0,0 +1,31 @@ +#include <initializer_list> + +struct ctor {}; + +template <typename V> +struct my_vector +{ + typedef my_vector<V> self; + + template <typename T> + my_vector(std::initializer_list<T> ls) + { + for (auto l : ls); + } + + my_vector(self&&) {} + my_vector(const self&) {} + my_vector(const self&, ctor) {} + + self& operator=(self&&) {} +}; + +int main() +{ + my_vector<double> v= {3, 4, 5}; + v= {4, 5, 6}; + + const my_vector<double> w= {3, 4, 5}; + + return 0; +} diff --git a/install/MTL/share/mtl/tools/cmake/MOVE_CHECK.cpp b/install/MTL/share/mtl/tools/cmake/MOVE_CHECK.cpp new file mode 100644 index 00000000..73ea06d6 --- /dev/null +++ b/install/MTL/share/mtl/tools/cmake/MOVE_CHECK.cpp @@ -0,0 +1,9 @@ +struct dings +{ + dings(dings&&) {} +}; + +int main() +{ + return 0; +} diff --git a/install/MTL/share/mtl/tools/cmake/MTLCommon.cmake b/install/MTL/share/mtl/tools/cmake/MTLCommon.cmake new file mode 100644 index 00000000..068c7f67 --- /dev/null +++ b/install/MTL/share/mtl/tools/cmake/MTLCommon.cmake @@ -0,0 +1,136 @@ +############################ +#This configuration file defines some cmake variables: +#MTL_INCLUDE_DIRS: list of include directories for the mtl +#MTL_LIBRARIES: libraries needed for interfaces like umfpack and arprec, see below +#MTL_CXX_DEFINITIONS: definitions to enable the requested interfaces +#MTL_VERSION: version (current: 4) +#MTL_MINOR_VERSION: minor version +# +#supported components: +#Umfpack, Arprec + +option(ENABLE_OPENMP "switch on to enable OpenMP flags for mtl" OFF) +option(ENABLE_SHORT_ELE_PROD "enable short notation for element-wise product" OFF) +option(ENABLE_CXX_ELEVEN "enable C++11 features as far as compiler permits" ON) +option(USE_ASSERTS "Use assert instead of throwing exceptions" ON) + + +unset(MTL_LIBRARIES ) +unset(MTL_CXX_DEFINITIONS ) +unset(MTL_INCLUDE_DIRS ) + +find_package(Boost 1.40 REQUIRED) +if(Boost_FOUND) + LIST(APPEND MTL_INCLUDE_DIRS ${Boost_INCLUDE_DIRS}) +endif(Boost_FOUND) + +include(${MTL_DIR}/tools/cmake/Vampir.cmake) +include(${MTL_DIR}/tools/cmake/UMFPACK.cmake) +include(${MTL_DIR}/tools/cmake/ARPREC.cmake) + +find_package(Subversion) +set(MTL_VERSION "4") +if(Subversion_FOUND) + if(EXISTS "${CMAKE_SOURCE_DIR}/.svn") + Subversion_WC_INFO(${MTL_DIR} mtlSubinfo) + set(MTL_MINOR_VERSION ${mtlSubinfo_WC_REVISION}) + # message("current revision: ${mtlSubinfo_WC_REVISION}") + else () + set(MTL_MINOR_VERSION "0") + endif() +else(Subversion_FOUND) + set(MTL_MINOR_VERSION "0") +endif(Subversion_FOUND) + +if(EXISTS ${MTL_DIR}/tools/cmake/C++11Features.cmake) + include(${MTL_DIR}/tools/cmake/C++11Features.cmake) +endif() + +if (USE_ASSERTS) + list(APPEND MTL_CXX_DEFINITIONS "-DMTL_ASSERT_FOR_THROW") +endif() + +if(HAVE_UMFPACK) + list(APPEND MTL_CXX_DEFINITIONS "-DMTL_HAS_UMFPACK") + include_directories(${UMFPACK_INCLUDE_DIRS}) + list(APPEND MTL_LIBRARIES ${UMFPACK_LIBRARIES}) +endif() +if(HAVE_ARPREC) + list(APPEND MTL_CXX_DEFINITIONS "-DMTL_HAS_ARPREC") + include_directories(${ARPREC_INCLUDE_DIRS}) + list(APPEND MTL_LIBRARIES ${ARPREC_LIBRARIES}) +endif() +if(EXISTS ${MTL_DIR}/boost/numeric/mtl/mtl.hpp) + list(APPEND MTL_INCLUDE_DIRS "${MTL_DIR}") +else() + list(APPEND MTL_INCLUDE_DIRS "${MTL_DIR}/../../include") +endif(EXISTS ${MTL_DIR}/boost/numeric/mtl/mtl.hpp) + +if(ENABLE_VAMPIR AND VAMPIR_FOUND) +#add_definitions("-DMTL_HAS_VPT -DVTRACE -vt:inst manual") + list(APPEND MTL_CXX_DEFINITIONS "-DMTL_HAS_VPT" "-DVTRACE") + list(APPEND MTL_CXX_DEFINITIONS ${VT_COMPILE_FLAGS}) + set(MTL_LINK_FLAGS "${MTL_LINK_FLAGS} ${VT_LINK_FLAGS}") + if(EXISTS ${MTL_DIR}/boost/numeric/mtl/interface/vpt.cpp) + set(VAMPIR_SRC ${MTL_DIR}/boost/numeric/mtl/interface/vpt.cpp) + else() + set(VAMPIR_SRC ${MTL_DIR}/vpt.cpp) + endif() + get_target_property(MTL_VAMPIR_ADDED mtl_vampir TYPE) + if(NOT MTL_VAMPIR_ADDED) + add_library(mtl_vampir ${VAMPIR_SRC}) + endif() + list(APPEND MTL_LIBRARIES ${VT_LIBRARIES} mtl_vampir) + set(HAVE_VAMPIR TRUE) +else() + set(HAVE_VAMPIR FALSE) +endif(ENABLE_VAMPIR AND VAMPIR_FOUND) + +if(ENABLE_OPENMP ) + find_package(OpenMP REQUIRED) + if(OPENMP_FOUND) + list(APPEND MTL_CXX_DEFINITIONS "-DMTL_WITH_OPENMP") + list(APPEND MTL_CXX_DEFINITIONS ${OpenMP_CXX_FLAGS}) + list(APPEND MTL_LIBRARIES ${OpenMP_CXX_FLAGS}) + else() + message(FATAL_ERROR "OpenMP not found") + endif() +endif() +#message("find components: ${MTL_FIND_COMPONENTS}") +#we found nothing.. +set(MTL_NOT_FOUND ) +#remove? +foreach(CURCOMP ${MTL_FIND_COMPONENTS}) +#look for a file called COMPONENT.cmake in the mtl-directory (/usr/share/mtl/) + string(TOUPPER ${CURCOMP} CURCOMP_UPPER) + set(curfile "${MTL_DIR}/tools/cmake/${CURCOMP_UPPER}.cmake") + if(EXISTS ${curfile}) + include(${curfile}) + #look for component + #check if the component was correctly found + if(HAVE_${CURCOMP_UPPER}) + list(APPEND MTL_INCLUDE_DIRS ${${CURCOMP_UPPER}_INCLUDE_DIRS}) + list(APPEND MTL_LIBRARIES ${${CURCOMP_UPPER}_LIBRARIES}) + list(APPEND MTL_CXX_DEFINITIONS "-DMTL_HAS_${CURCOMP_UPPER}") + else() + list(APPEND MTL_NOT_FOUND ${CURCOMP}) + endif() + else() + list(APPEND MTL_NOT_FOUND ${CURCOMP}) + endif() +endforeach() + +if(MTL_FIND_REQUIRED AND MTL_NOT_FOUND) + message(SEND_ERROR "could not find all components: ${MTL_NOT_FOUND}") +endif() +#include_directories(${MTL_INCLUDE_DIRS}) + +macro(mtl_check_cxx_compiler_flag FLAG RESULT) + # counts entirely on compiler's return code, maybe better to combine it with check_cxx_compiler_flag + file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx" "int main() { return 0;}\n") + try_compile(${RESULT} + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx + COMPILE_DEFINITIONS ${FLAG}) +endmacro() + diff --git a/install/MTL/share/mtl/tools/cmake/RANGEDFOR_CHECK.cpp b/install/MTL/share/mtl/tools/cmake/RANGEDFOR_CHECK.cpp new file mode 100644 index 00000000..b82def0b --- /dev/null +++ b/install/MTL/share/mtl/tools/cmake/RANGEDFOR_CHECK.cpp @@ -0,0 +1,12 @@ +// #include <iostream> + +int main() +{ + int array[]= {3, 7, 9, 4}; + + int s= 0; + for (int i : array) + s+= i; + // std::cout << "s = " << s << '\n'; + return 0; +} diff --git a/install/MTL/share/mtl/tools/cmake/STATICASSERT_CHECK.cpp b/install/MTL/share/mtl/tools/cmake/STATICASSERT_CHECK.cpp new file mode 100644 index 00000000..a9956986 --- /dev/null +++ b/install/MTL/share/mtl/tools/cmake/STATICASSERT_CHECK.cpp @@ -0,0 +1,6 @@ + +int main() +{ + static_assert(sizeof(int) > 1, "int too small"); + return 0; +} diff --git a/install/MTL/share/mtl/tools/cmake/TEMPLATE_ALIAS_CHECK.cpp b/install/MTL/share/mtl/tools/cmake/TEMPLATE_ALIAS_CHECK.cpp new file mode 100644 index 00000000..28f3ca7f --- /dev/null +++ b/install/MTL/share/mtl/tools/cmake/TEMPLATE_ALIAS_CHECK.cpp @@ -0,0 +1,15 @@ +// #include <iostream> + + +template <typename T, typename U> +struct dings {}; + +template <typename T> +using bums= dings<T, T>; + +int main() +{ + typedef bums<int> bi; + + return 0; +} diff --git a/install/MTL/share/mtl/tools/cmake/UMFPACK.cmake b/install/MTL/share/mtl/tools/cmake/UMFPACK.cmake new file mode 100644 index 00000000..1341ff22 --- /dev/null +++ b/install/MTL/share/mtl/tools/cmake/UMFPACK.cmake @@ -0,0 +1,12 @@ +find_file(UMFPACK_H umfpack.h) +find_library(UMFPACK_LIBRARY umfpack) +set(HAVE_UMFPACK false) +if(UMFPACK_H AND UMFPACK_LIBRARY) + get_filename_component(UMFPACK_INCLUDE_DIRS ${UMFPACK_H} PATH) + find_library(AMD_LIBRARY amd) + find_library(BLAS_LIBRARY blas) + if(AMD_LIBRARY AND BLAS_LIBRARY) + set(UMFPACK_LIBRARIES "${UMFPACK_LIBRARY};${AMD_LIBRARY};${BLAS_LIBRARY}") + set(HAVE_UMFPACK true) + endif() +endif() diff --git a/install/MTL/share/mtl/tools/cmake/VARIADIC_TEMPLATE_CHECK.cpp b/install/MTL/share/mtl/tools/cmake/VARIADIC_TEMPLATE_CHECK.cpp new file mode 100644 index 00000000..6ba6044b --- /dev/null +++ b/install/MTL/share/mtl/tools/cmake/VARIADIC_TEMPLATE_CHECK.cpp @@ -0,0 +1,20 @@ +#include <cstddef> + +// Should be extended to be sure that support is sufficient + +template <typename ValueType, ValueType FirstValue, ValueType ...Values> +struct static_vector +{ + static const std::size_t length= sizeof...(Values) + 1; +}; + +template <typename ValueType, ValueType FirstValue> +struct static_vector<ValueType, FirstValue> +{}; + +int main() +{ + typedef static_vector<int, 3, 4> sv; + + return 0; +} diff --git a/install/MTL/share/mtl/tools/cmake/Vampir.cmake b/install/MTL/share/mtl/tools/cmake/Vampir.cmake new file mode 100644 index 00000000..785a339c --- /dev/null +++ b/install/MTL/share/mtl/tools/cmake/Vampir.cmake @@ -0,0 +1,150 @@ +find_program(VAMPIR_CXX vtc++) +option(ENABLE_VAMPIR "enable or disable vampir trace" OFF) +if(VAMPIR_CXX) + #function to compute the compile flags, libraries, linker directories and linker flags used by the vampir compiler + #cflags: name of the global variable which will contain the compilerflags + #libs: name of the global variable which will contain the libraries + #ldirs: name of the global variable which will contain the linker directories + #lflags: name of the global variable which will contain the linker flags + #addArgs: additional arguments passed to the vampir compiler + function(GetVampirData cflags libs ldirs lflags _addArgs) + set(addArgs "${${_addArgs}}") + #request only compile arguments + execute_process(COMMAND ${VAMPIR_CXX} "-vt:show" "-vt:inst" "manual" ${addArgs} "-c" RESULT_VARIABLE VT_RES OUTPUT_VARIABLE VT_OUT) + #message("vt_res: ${VT_RES}") + #message("vt_out: ${VT_OUT}") + string(REPLACE " " ";" asList ${VT_OUT} ) + list(LENGTH asList length) + #message("asList: ${asList}") + #message("length: ${length}") + list(GET asList 0 VT_COMPILER) + #remove the compiler + list(REMOVE_AT asList 0) + #add each flag except the last to the vampir compile flags + while(length GREATER 1) + list(GET asList 0 CURFLAG) + #save the results in internal variable + list(APPEND _VT_COMPILE_FLAGS ${CURFLAG}) + list(REMOVE_AT asList 0) + list(LENGTH asList length) + endwhile() + #message("asList: ${asList}") + #request all other flags + execute_process(COMMAND ${VAMPIR_CXX} "-vt:show" "-vt:inst" "manual" ${addArgs} RESULT_VARIABLE VT_RES OUTPUT_VARIABLE VT_OUT) + string(REPLACE " " ";" asList ${VT_OUT} ) + list(LENGTH asList length) + #remove the compiler + list(REMOVE_AT asList 0) + while(length GREATER 1) + list(GET asList 0 CURFLAG) + #if the current flag is not a compile flag, add it + list(FIND _VT_COMPILE_FLAGS ${CURFLAG} ISCOMPILEFLAG) + #message("iscompileflag: ${ISCOMPILEFLAG}") + if(ISCOMPILEFLAG EQUAL -1) + string(SUBSTRING "${CURFLAG}" 0 2 FLAGBEG) + + string(REGEX MATCHALL "-L([^\" ]+|\"[^\"]+\")" CURLINKDIR "${CURFLAG}") + set(CURLINKDIR ${CMAKE_MATCH_1}) + if(CURLINKDIR) + list(APPEND _VT_LINKER_DIRECTORIES ${CURLINKDIR}) + endif() + #save the results in internal variable + #list(APPEND _VT_LINKER_DIRECTORIES ${CURLINKDIR}) + + string(REGEX MATCHALL "-l([^\" ]+|\"[^\"]+\")" CURLIBRARY "${CURFLAG}") + set(CURLIBRARY ${CMAKE_MATCH_1}) + if(CURLIBRARY) + list(APPEND _VT_LIBRARIES ${CURLIBRARY}) + endif() + #save the results in internal variable + #list(APPEND _VT_LIBRARIES ${CURLIBRARY}) + #set(_VT_LINK_FLAGS "${_VT_LINK_FLAGS} ${CURFLAG}") + if(NOT (CURLIBRARY OR CURLINKDIR)) + set(VT_LINK_FLAGS "${VT_LINK_FLAGS} ${CURFLAG}") + endif() + + endif() + list(REMOVE_AT asList 0) + list(LENGTH asList length) + endwhile() + #propagate the values to parent scope + set(${cflags} ${_VT_COMPILE_FLAGS} PARENT_SCOPE) + set(${libs} ${_VT_LIBRARIES} PARENT_SCOPE) + set(${ldirs} ${_VT_LINKER_DIRECTORIES} PARENT_SCOPE) + set(${lflags} "${_VT_LINK_FLAGS}" PARENT_SCOPE) + endfunction() + set(VAMPIR_FOUND TRUE) + #request only compile arguments +# execute_process(COMMAND ${VAMPIR_CXX} "-vt:show" "-vt:mt" "-vt:noopari" "-vt:inst" "manual" "-c" RESULT_VARIABLE VT_RES OUTPUT_VARIABLE VT_OUT) +# string(REPLACE " " ";" asList ${VT_OUT} ) +# list(LENGTH asList length) +# list(GET asList 0 VT_COMPILER) + #remove the compiler +# list(REMOVE_AT asList 0) + #add each flag except the last to the vampir compile flags +# set(VT_COMPILE_FLAGS ) +# while(length GREATER 1) +# list(GET asList 0 CURFLAG) +# list(APPEND VT_COMPILE_FLAGS ${CURFLAG}) +# list(REMOVE_AT asList 0) +# list(LENGTH asList length) +# endwhile() + #request all other flags +# execute_process(COMMAND ${VAMPIR_CXX} "-vt:show" "-vt:mt" "-vt:noopari" "-vt:inst" "manual" RESULT_VARIABLE VT_RES OUTPUT_VARIABLE VT_OUT) +# string(REPLACE " " ";" asList ${VT_OUT} ) +# list(LENGTH asList length) + #remove the compiler +# list(REMOVE_AT asList 0) +# set(VT_LIBRARIES ) +# set(VT_LINKER_DIRECTORIES ) +# set(VT_LINK_FLAGS "") +# while(length GREATER 1) +# list(GET asList 0 CURFLAG) + #if the current flag is not a compile flag, add it +# list(FIND VT_COMPILE_FLAGS ${CURFLAG} ISCOMPILEFLAG) +# if(ISCOMPILEFLAG EQUAL -1) +# string(SUBSTRING "${CURFLAG}" 0 2 FLAGBEG) + +# string(REGEX MATCHALL "-L([^\" ]+|\"[^\"]+\")" CURLINKDIR "${CURFLAG}") +# set(CURLINKDIR ${CMAKE_MATCH_1}) +# if(CURLINKDIR) +# list(APPEND VT_LINKER_DIRECTORIES ${CURLINKDIR}) +# endif() + +# string(REGEX MATCHALL "-l([^\" ]+|\"[^\"]+\")" CURLIBRARY "${CURFLAG}") +# set(CURLIBRARY ${CMAKE_MATCH_1}) +# if(CURLIBRARY) +# list(APPEND VT_LIBRARIES_REL ${CURLIBRARY}) +# endif() + +# if(NOT (CURLIBRARY OR CURLINKDIR)) +# set(VT_LINK_FLAGS "${VT_LINK_FLAGS} ${CURFLAG}") +# endif() +# endif() +# list(REMOVE_AT asList 0) +# list(LENGTH asList length) +# endwhile() + +set(_ADD_VT_FLAGS "") +if(ENABLE_OPENMP) + set(_ADD_VT_FLAGS "${VT_FLGAS};-vt:mt;-vt:noopari") +endif(ENABLE_OPENMP) +GetVampirData(VT_COMPILE_FLAGS VT_LIBRARIES_REL VT_LINKER_DIRECTORIES VT_LINK_FLAGS _ADD_VT_FLAGS) + +#look for fullpath of vampir libraries +foreach(curLib IN LISTS VT_LIBRARIES_REL) + find_library(CURRELLIB_${curLib} ${curLib} PATHS ${VT_LINKER_DIRECTORIES} NO_DEFAULT_PATH) + if(CURRELLIB_${curLib}) + list(APPEND VT_LIBRARIES ${CURRELLIB_${curLib}}) + else() + list(APPEND VT_LIBRARIES ${curLib}) + endif() +endforeach() +#message("vt_compiler: ${VT_COMPILER}") +#message("vt_compiler flags: ${VT_COMPILE_FLAGS}") +#message("vt_linker flags: ${VT_LINK_FLAGS}") +#message("vt_linker directories: ${VT_LINKER_DIRECTORIES}") +#message("vt_linker libraries: ${VT_LIBRARIES}") +else(VAMPIR_CXX) + set(VAMPIR_FOUND FALSE) +endif() diff --git a/install/MTL/share/mtl/vpt.cpp b/install/MTL/share/mtl/vpt.cpp new file mode 100644 index 00000000..de9bf722 --- /dev/null +++ b/install/MTL/share/mtl/vpt.cpp @@ -0,0 +1,443 @@ +#include <boost/numeric/mtl/interface/vpt.hpp> + +#ifdef MTL_HAS_VPT +namespace mtl { + +/// Namespace for Vampir Trace interface +namespace vpt { + +// Categories: +// Utilities + very small functions: 0000 +// Static size operations: 1000 +// Vector operations: 2000 +// Matrix Vector & single matrix: 3000 +// Matrix matrix operations: 4000 +// Factorizations, preconditioners: 5000 +// Fused operations: 6000 +// Iterative solvers: 7000 +// Multigrid: 8000 + + +// Utilities: < 1000 +template <> std::string vampir_trace<1>::name("copysign"); +template <> std::string vampir_trace<2>::name("Elem_raw_copy"); +template <> std::string vampir_trace<3>::name("Get_real_part"); +template <> std::string vampir_trace<4>::name("Info_contruct_vector"); +template <> std::string vampir_trace<5>::name("right_scale_inplace"); +template <> std::string vampir_trace<6>::name("sign_real_part_of_complex"); +template <> std::string vampir_trace<7>::name("unrolling_expresion"); +template <> std::string vampir_trace<8>::name(""); +template <> std::string vampir_trace<9>::name(""); +template <> std::string vampir_trace<10>::name("squared_abs_magnitudes"); +template <> std::string vampir_trace<11>::name("squared_abs_complex"); +template <> std::string vampir_trace<12>::name("squared_abs_magnitudes_template"); +template <> std::string vampir_trace<13>::name("update_store"); +template <> std::string vampir_trace<14>::name("update_plus"); +template <> std::string vampir_trace<15>::name("update_minus"); +template <> std::string vampir_trace<16>::name("update_times"); +template <> std::string vampir_trace<17>::name("update_adapter"); +template <> std::string vampir_trace<18>::name(""); +template <> std::string vampir_trace<19>::name(""); +template <> std::string vampir_trace<20>::name("update_proxy_<<"); +template <> std::string vampir_trace<21>::name("update_proxy_="); +template <> std::string vampir_trace<22>::name("update_proxy_+="); +template <> std::string vampir_trace<23>::name("sfunctor::plus"); +template <> std::string vampir_trace<24>::name("sfunctor::minus"); +template <> std::string vampir_trace<25>::name("sfunctor::times"); +template <> std::string vampir_trace<26>::name("sfunctor::divide"); +template <> std::string vampir_trace<27>::name("sfunctor::assign"); +template <> std::string vampir_trace<28>::name("sfunctor::plus_assign"); +template <> std::string vampir_trace<29>::name("sfunctor::minus_assign"); +template <> std::string vampir_trace<30>::name("sfunctor::times_assign"); +template <> std::string vampir_trace<31>::name("sfunctor::divide_assign"); +template <> std::string vampir_trace<32>::name("sfunctor::identity"); +template <> std::string vampir_trace<33>::name("sfunctor::abs"); +template <> std::string vampir_trace<34>::name("sfunctor::sqrt"); +template <> std::string vampir_trace<35>::name("sfunctor::square"); +template <> std::string vampir_trace<36>::name("sfunctor::negate"); +template <> std::string vampir_trace<37>::name("sfunctor::compose"); +template <> std::string vampir_trace<38>::name("sfunctor::compose_first"); +template <> std::string vampir_trace<39>::name("sfunctor::compose_second"); +template <> std::string vampir_trace<40>::name("sfunctor::compose_both"); +template <> std::string vampir_trace<41>::name("sfunctor::compose_binary"); +template <> std::string vampir_trace<42>::name(""); +template <> std::string vampir_trace<43>::name(""); +template <> std::string vampir_trace<44>::name(""); +template <> std::string vampir_trace<45>::name(""); + +// Fine-grained vector operations +template <> std::string vampir_trace<236>::name("Vector_swapped_row"); + + +// Static size operations: 1000 +template <> std::string vampir_trace<1001>::name("stat_vec_expr"); +template <> std::string vampir_trace<1002>::name("fsize_dmat_dmat_mult"); +template <> std::string vampir_trace<1003>::name("vector_size_static"); +template <> std::string vampir_trace<1004>::name("static_dispatch"); // ?? row_in_matrix.hpp:74 +template <> std::string vampir_trace<1005>::name("copy_blocks_forward"); +template <> std::string vampir_trace<1006>::name("copy_blocks_backward"); +template <> std::string vampir_trace<1007>::name("Static_Size"); +template <> std::string vampir_trace<1008>::name("fsize_mat_vect_mult"); +template <> std::string vampir_trace<1009>::name(""); +template <> std::string vampir_trace<1010>::name(""); +template <> std::string vampir_trace<1011>::name(""); +template <> std::string vampir_trace<1012>::name(""); +template <> std::string vampir_trace<1013>::name(""); +template <> std::string vampir_trace<1014>::name(""); +template <> std::string vampir_trace<1015>::name(""); +template <> std::string vampir_trace<1016>::name(""); +template <> std::string vampir_trace<1017>::name(""); +template <> std::string vampir_trace<1018>::name(""); +template <> std::string vampir_trace<1019>::name(""); +template <> std::string vampir_trace<1020>::name(""); + + + + + +// Vector operations: 2000 +template <> std::string vampir_trace<2001>::name("gen_vector_copy"); +template <> std::string vampir_trace<2002>::name("cross"); +template <> std::string vampir_trace<2003>::name("dot"); +template <> std::string vampir_trace<2004>::name("householder"); +template <> std::string vampir_trace<2005>::name("householder_s"); +template <> std::string vampir_trace<2006>::name("infinity_norm"); +template <> std::string vampir_trace<2007>::name("look_at_each_nonzero"); +template <> std::string vampir_trace<2008>::name("look_at_each_nonzero_pos"); +template <> std::string vampir_trace<2009>::name("reduction"); +template <> std::string vampir_trace<2010>::name("max"); +template <> std::string vampir_trace<2011>::name("max_abs_pos"); +template <> std::string vampir_trace<2012>::name("max_of_sums"); +template <> std::string vampir_trace<2013>::name("max_pos"); +template <> std::string vampir_trace<2014>::name("merge_complex_vector"); +template <> std::string vampir_trace<2015>::name("one_norm"); +template <> std::string vampir_trace<2016>::name("diagonal"); +template <> std::string vampir_trace<2017>::name("dyn_vec_expr"); +template <> std::string vampir_trace<2018>::name("Orthogonalize_Vectors"); +template <> std::string vampir_trace<2019>::name("Orthogonalize_Factors"); +template <> std::string vampir_trace<2020>::name("Vector_product"); +template <> std::string vampir_trace<2021>::name("Vector_random"); +template <> std::string vampir_trace<2022>::name("Vec_Vec_rank_update"); +template <> std::string vampir_trace<2023>::name("Vector_dispatch"); +template <> std::string vampir_trace<2024>::name("Vector_rscale"); +template <> std::string vampir_trace<2025>::name("Multi-vector_mult"); +template <> std::string vampir_trace<2026>::name("Transp_Multi-vector_mult"); +template <> std::string vampir_trace<2027>::name("Hermitian_Multi-vector_mult"); +template <> std::string vampir_trace<2028>::name("Vector_scal"); +template <> std::string vampir_trace<2029>::name("Vector_set_zero"); +template <> std::string vampir_trace<2030>::name("Vector_size1D"); +template <> std::string vampir_trace<2031>::name("Vector_size_runtime"); +template <> std::string vampir_trace<2032>::name("Vect_quicksort_lo_to_hi"); +template <> std::string vampir_trace<2033>::name("Vect_quicksort_permutaion_lo_to_hi"); +template <> std::string vampir_trace<2034>::name("split_complex_vector"); +template <> std::string vampir_trace<2035>::name("Vect_entries_sum"); +template <> std::string vampir_trace<2037>::name("Vector_const_trans"); +template <> std::string vampir_trace<2038>::name("Vector_trans"); +template <> std::string vampir_trace<2039>::name("two_norm"); +template <> std::string vampir_trace<2040>::name("dot_simple"); +template <> std::string vampir_trace<2041>::name("unary_dot"); +template <> std::string vampir_trace<2042>::name("dense_copy_ctor"); +template <> std::string vampir_trace<2043>::name("dense_tpl_copy_ctor"); +template <> std::string vampir_trace<2044>::name(""); +template <> std::string vampir_trace<2045>::name(""); +template <> std::string vampir_trace<2046>::name(""); +template <> std::string vampir_trace<2047>::name(""); +template <> std::string vampir_trace<2048>::name(""); +template <> std::string vampir_trace<2049>::name(""); +template <> std::string vampir_trace<2050>::name(""); +template <> std::string vampir_trace<2051>::name(""); +template <> std::string vampir_trace<2052>::name(""); + + +// Matrix Vector & single matrix: 3000 +template <> std::string vampir_trace<3001>::name("matrix_copy_ele_times"); +template <> std::string vampir_trace<3002>::name("gen_matrix_copy"); +template <> std::string vampir_trace<3003>::name("copy"); +template <> std::string vampir_trace<3004>::name("clone"); +template <> std::string vampir_trace<3005>::name("compute_summand"); +template <> std::string vampir_trace<3006>::name("crop"); +template <> std::string vampir_trace<3007>::name("mat::diagonal"); +template <> std::string vampir_trace<3008>::name("assign_each_nonzero"); +template <> std::string vampir_trace<3009>::name("fill"); +template <> std::string vampir_trace<3010>::name("frobenius_norm"); +template <> std::string vampir_trace<3011>::name("mat::infinity_norm"); +template <> std::string vampir_trace<3012>::name("invert_diagonal"); +template <> std::string vampir_trace<3013>::name("iota"); +template <> std::string vampir_trace<3014>::name("left_scale_inplace"); +template <> std::string vampir_trace<3015>::name("mat::look_at_each_nonzero"); +template <> std::string vampir_trace<3016>::name("mat::look_at_each_nonzero_pos"); +template <> std::string vampir_trace<3017>::name("fsize_dense_mat_cvec_mult"); +template <> std::string vampir_trace<3018>::name("dense_mat_cvec_mult"); +template <> std::string vampir_trace<3019>::name("mvec_cvec_mult"); +template <> std::string vampir_trace<3020>::name("trans_mvec_cvec_mult"); +template <> std::string vampir_trace<3021>::name("herm_mvec_cvec_mult"); +template <> std::string vampir_trace<3022>::name("sparse_row_cvec_mult"); // generic row-major sparse +template <> std::string vampir_trace<3023>::name("ccs_cvec_mult"); +template <> std::string vampir_trace<3024>::name("mat::max_abs_pos"); +template <> std::string vampir_trace<3025>::name("mat::one_norm"); +template <> std::string vampir_trace<3026>::name("invert_diagonal(compressed)"); +template <> std::string vampir_trace<3027>::name("mat_vect_mult"); +template <> std::string vampir_trace<3028>::name("Vect_sparse_mat_mult"); +template <> std::string vampir_trace<3029>::name("Matrix_scal"); +template <> std::string vampir_trace<3030>::name("Vector_Secular_Equation"); +template <> std::string vampir_trace<3031>::name("Matrix_set_zero"); +template <> std::string vampir_trace<3032>::name("Matrix_size1D"); +template <> std::string vampir_trace<3033>::name("Matrix_size_runtime"); +template <> std::string vampir_trace<3034>::name("Matrix_LU"); +template <> std::string vampir_trace<3035>::name("Vector_Matrix_LU"); +template <> std::string vampir_trace<3036>::name("Sub_matrix_indices"); +template <> std::string vampir_trace<3037>::name("Matrix_svd_reference"); +template <> std::string vampir_trace<3038>::name("Matrix_svd_triplet"); +template <> std::string vampir_trace<3039>::name("Matrix_swapped"); +template <> std::string vampir_trace<3040>::name("Matrix_Trace"); +template <> std::string vampir_trace<3041>::name("Matrix_const_trans"); +template <> std::string vampir_trace<3042>::name("Matrix_trans"); +template <> std::string vampir_trace<3043>::name("Matrix_upper_trisolve"); +template <> std::string vampir_trace<3044>::name("Matrix_upper_trisolve_diagonal"); +template <> std::string vampir_trace<3045>::name("Matrix_upper_trisolve_invers_diag"); +template <> std::string vampir_trace<3046>::name("Matrix_upper_trisolve_DiaTag"); +template <> std::string vampir_trace<3047>::name("scalar_assign"); +template <> std::string vampir_trace<3048>::name("elest_cvec_mult"); +template <> std::string vampir_trace<3049>::name("crs_cvec_mult"); +template <> std::string vampir_trace<3050>::name("sparse_ins::ctor"); +template <> std::string vampir_trace<3051>::name("sparse_ins::dtor"); +template <> std::string vampir_trace<3052>::name("sparse_ins::stretch"); +template <> std::string vampir_trace<3053>::name("sparse_ins::final_place"); +template <> std::string vampir_trace<3054>::name("sparse_ins::insert_spare"); +template <> std::string vampir_trace<3055>::name("mat_crtp_scal_assign"); +template <> std::string vampir_trace<3056>::name("mat_crtp_mat_assign"); +template <> std::string vampir_trace<3057>::name("mat_crtp_sum_assign"); +template <> std::string vampir_trace<3058>::name("mat_crtp_diff_assign"); +template <> std::string vampir_trace<3059>::name("mat_crtp_array_assign"); +template <> std::string vampir_trace<3060>::name("mat_crtp_mvec_assign"); +template <> std::string vampir_trace<3061>::name("copy_band_to_sparse"); +template <> std::string vampir_trace<3062>::name("block_dia_times_cvec"); +template <> std::string vampir_trace<3063>::name("laplacian_setup"); +template <> std::string vampir_trace<3064>::name("vsmat_cvec_mult"); +template <> std::string vampir_trace<3065>::name("adapt_crs_cvec_mult"); +template <> std::string vampir_trace<3066>::name("dense2D_cvec_mult"); +template <> std::string vampir_trace<3067>::name("square_cvec_mult"); +template <> std::string vampir_trace<3068>::name("mat_crtp_mult_assign"); +template <> std::string vampir_trace<3069>::name("sbanded_cvec_mult"); +template <> std::string vampir_trace<3070>::name("mat_cvec_multiplier"); +template <> std::string vampir_trace<3071>::name(""); +template <> std::string vampir_trace<3072>::name(""); +template <> std::string vampir_trace<3073>::name(""); +template <> std::string vampir_trace<3074>::name(""); +template <> std::string vampir_trace<3075>::name(""); +template <> std::string vampir_trace<3076>::name(""); +template <> std::string vampir_trace<3077>::name(""); +template <> std::string vampir_trace<3078>::name(""); +template <> std::string vampir_trace<3079>::name(""); + + +// Matrix matrix operations: 4000 +template <> std::string vampir_trace<4001>::name("cursor_dmat_dmat_mult"); +template <> std::string vampir_trace<4002>::name("dmat_dmat_mult"); +template <> std::string vampir_trace<4003>::name("tiling_dmat_dmat_mult"); +template <> std::string vampir_trace<4004>::name("tiling_44_dmat_dmat_mult"); +template <> std::string vampir_trace<4005>::name("tiling_22_dmat_dmat_mult"); +template <> std::string vampir_trace<4006>::name("wrec_dmat_dmat_mult"); +template <> std::string vampir_trace<4007>::name("recursive_dmat_dmat_mult"); +template <> std::string vampir_trace<4008>::name("xgemm"); +template <> std::string vampir_trace<4009>::name(""); +template <> std::string vampir_trace<4010>::name("mult"); +template <> std::string vampir_trace<4011>::name("gen_mult"); +template <> std::string vampir_trace<4012>::name("mat_mat_mult"); +template <> std::string vampir_trace<4013>::name("matrix_qr"); +template <> std::string vampir_trace<4014>::name("matrix_qr_factors"); +template <> std::string vampir_trace<4015>::name("matrix_random"); +template <> std::string vampir_trace<4016>::name("matrix_scale_inplace"); +template <> std::string vampir_trace<4017>::name("matrix_rscale"); +template <> std::string vampir_trace<4018>::name("matrix_gen_smat_dmat_mult"); +template <> std::string vampir_trace<4019>::name("matrix_gen_tiling_smat_dmat_mult"); +template <> std::string vampir_trace<4020>::name("matrix_smat_smat_mult"); +template <> std::string vampir_trace<4021>::name(""); +template <> std::string vampir_trace<4022>::name(""); +template <> std::string vampir_trace<4023>::name(""); +template <> std::string vampir_trace<4024>::name(""); +template <> std::string vampir_trace<4025>::name(""); +template <> std::string vampir_trace<4026>::name(""); +template <> std::string vampir_trace<4027>::name(""); +template <> std::string vampir_trace<4028>::name(""); +template <> std::string vampir_trace<4029>::name(""); +template <> std::string vampir_trace<4030>::name(""); +template <> std::string vampir_trace<4031>::name(""); +template <> std::string vampir_trace<4032>::name(""); +template <> std::string vampir_trace<4033>::name(""); +template <> std::string vampir_trace<4034>::name(""); +template <> std::string vampir_trace<4035>::name(""); +template <> std::string vampir_trace<4036>::name("read_el_matrix"); +template <> std::string vampir_trace<4037>::name(""); +template <> std::string vampir_trace<4038>::name(""); +template <> std::string vampir_trace<4039>::name(""); +template <> std::string vampir_trace<4040>::name(""); +template <> std::string vampir_trace<4041>::name(""); + + +// Factorizations, preconditioners: 5000 +template <> std::string vampir_trace<5001>::name("cholesky_base"); +template <> std::string vampir_trace<5002>::name("cholesky_solve_base"); +template <> std::string vampir_trace<5003>::name("cholesky_schur_base"); +template <> std::string vampir_trace<5004>::name("cholesky_update_base"); +template <> std::string vampir_trace<5005>::name("cholesky_schur_update"); +template <> std::string vampir_trace<5006>::name("cholesky_tri_solve"); +template <> std::string vampir_trace<5007>::name("cholesky_tri_schur"); +template <> std::string vampir_trace<5008>::name("recursive cholesky"); +template <> std::string vampir_trace<5009>::name("fill_matrix_for_cholesky"); +template <> std::string vampir_trace<5010>::name("qr_sym_imp"); +template <> std::string vampir_trace<5011>::name("qr_algo"); +template <> std::string vampir_trace<5012>::name("eigenvalue_symmetric"); +template <> std::string vampir_trace<5013>::name("hessenberg_q"); +template <> std::string vampir_trace<5014>::name("hessenberg_factors"); +template <> std::string vampir_trace<5015>::name("extract_householder_hessenberg"); +template <> std::string vampir_trace<5016>::name("householder_hessenberg"); +template <> std::string vampir_trace<5017>::name("extract_hessenberg"); +template <> std::string vampir_trace<5018>::name("hessenberg"); +template <> std::string vampir_trace<5019>::name("inv_upper"); +template <> std::string vampir_trace<5020>::name("inv_lower"); +template <> std::string vampir_trace<5021>::name("inv"); +template <> std::string vampir_trace<5022>::name("lower_trisolve"); +template <> std::string vampir_trace<5023>::name("lu"); +template <> std::string vampir_trace<5024>::name("lu(pivot)"); +template <> std::string vampir_trace<5025>::name("lu_f"); +template <> std::string vampir_trace<5026>::name("lu_solve_straight"); +template <> std::string vampir_trace<5027>::name("lu_apply"); +template <> std::string vampir_trace<5028>::name("lu_solve"); +template <> std::string vampir_trace<5029>::name("lu_adjoint_apply"); +template <> std::string vampir_trace<5030>::name("lu_adjoint_solve"); +template <> std::string vampir_trace<5031>::name("pc::id::solve"); +template <> std::string vampir_trace<5032>::name("pc::id.solve"); +template <> std::string vampir_trace<5033>::name("pc::id::adjoint_solve"); +template <> std::string vampir_trace<5034>::name("pc::id.adjoint_solve"); +template <> std::string vampir_trace<5035>::name("ic_0::factorize"); +template <> std::string vampir_trace<5036>::name("ic_0::solve"); +template <> std::string vampir_trace<5037>::name("ic_0::solve_nocopy"); +template <> std::string vampir_trace<5038>::name("ilu_0::factorize"); +template <> std::string vampir_trace<5039>::name("ilu_0::solve"); +template <> std::string vampir_trace<5040>::name("ilu_0::adjoint_solve"); +template <> std::string vampir_trace<5041>::name("lower_trisolve_kernel"); +template <> std::string vampir_trace<5042>::name("upper_trisolve_row"); +template <> std::string vampir_trace<5043>::name("upper_trisolve_col"); +template <> std::string vampir_trace<5044>::name("ic_0::adjoint_solve"); +template <> std::string vampir_trace<5045>::name("ic_0::adjoint_solve_nocopy"); +template <> std::string vampir_trace<5046>::name("upper_trisolve_crs_compact"); +template <> std::string vampir_trace<5047>::name("lower_trisolve_crs_compact"); +template <> std::string vampir_trace<5048>::name("lower_unit_trisolve_crs_compact"); +template <> std::string vampir_trace<5049>::name("ilut::factorize"); +template <> std::string vampir_trace<5050>::name("diagonal::setup"); +template <> std::string vampir_trace<5051>::name("diagonal::solve"); +template <> std::string vampir_trace<5052>::name("imf::factor"); +template <> std::string vampir_trace<5053>::name("imf::ctor"); +template <> std::string vampir_trace<5054>::name("imf::solve"); +template <> std::string vampir_trace<5055>::name("pc::solver::assign_to"); +template <> std::string vampir_trace<5056>::name("sub_matrix_pc::solve"); +template <> std::string vampir_trace<5057>::name("sub_matrix_pc::adjoint_solve"); +template <> std::string vampir_trace<5058>::name("pc::concat::solve"); +template <> std::string vampir_trace<5059>::name("pc::concat::adjoint_solve"); +template <> std::string vampir_trace<5060>::name("umfpack::solver::ctor"); +template <> std::string vampir_trace<5061>::name("umfpack::solver::dtor"); +template <> std::string vampir_trace<5062>::name("umfpack::solve"); + + +// Fused operations: 6000 +template <> std::string vampir_trace<6001>::name("fused::fwd_eval_loop"); +template <> std::string vampir_trace<6002>::name("fused::fwd_eval_loop_unrolled"); +template <> std::string vampir_trace<6003>::name("fused::bwd_eval_loop"); +template <> std::string vampir_trace<6004>::name("fused::bwd_eval_loop_unrolled"); + + + +// Iterative solvers: 7000 +template <> std::string vampir_trace<7001>::name("cg_without_pc"); +template <> std::string vampir_trace<7002>::name("cg"); +template <> std::string vampir_trace<7003>::name("bicg"); +template <> std::string vampir_trace<7004>::name("bicgstab"); +template <> std::string vampir_trace<7005>::name("bicgstab_2"); +template <> std::string vampir_trace<7006>::name("bicgstab_ell"); +template <> std::string vampir_trace<7007>::name("cgs"); +template <> std::string vampir_trace<7008>::name("qmr"); +template <> std::string vampir_trace<7009>::name("tfqmr"); +template <> std::string vampir_trace<7010>::name("idr_s"); + + +// OpenMP +template <> std::string vampir_trace<8001>::name("omp::dot"); +template <> std::string vampir_trace<8002>::name("omp::reduction"); +template <> std::string vampir_trace<8003>::name("omp::dyn_vec_expr"); +template <> std::string vampir_trace<8004>::name("omp::crs_cvec_mult"); + + + +// multigrid +template <> std::string vampir_trace<8501>::name("mtl::mg::v_cycle"); +template <> std::string vampir_trace<8502>::name("mtl::mg::w_cycle"); +template <> std::string vampir_trace<8503>::name("mtl::mg::fmg"); +template <> std::string vampir_trace<8504>::name("mtl::mg::two_grid_cycle"); + +template <> std::string vampir_trace<8510>::name("mtl::mg::geometric_multigrid_solver_impl"); +template <> std::string vampir_trace<8511>::name("mtl::mg::geometric_multigrid_solver_solve1"); +template <> std::string vampir_trace<8512>::name("mtl::mg::geometric_multigrid_solver_solve2"); + +template <> std::string vampir_trace<8515>::name("mtl::mg::algebraic_multigrid_solver"); +template <> std::string vampir_trace<8516>::name("amg_pc::solve"); + +template <> std::string vampir_trace<8520>::name("mtl::mg::linear_restriction"); +template <> std::string vampir_trace<8521>::name("mtl::mg::linear_prolongation"); + +template <> std::string vampir_trace<8530>::name("mtl::mg::gauss_elimination"); +template <> std::string vampir_trace<8531>::name("mtl::mg::back_substitution"); + +template <> std::string vampir_trace<8550>::name("mtl::mg::jacobi"); +template <> std::string vampir_trace<8551>::name("mtl::mg::gauss_seidel"); +template <> std::string vampir_trace<8552>::name("mtl::mg::jor"); +template <> std::string vampir_trace<8553>::name("mtl::mg::sor"); + +template <> std::string vampir_trace<8572>::name("boundaries"); +template <> std::string vampir_trace<8573>::name("viscosity"); +template <> std::string vampir_trace<8574>::name("pressure_correction"); + +template <> std::string vampir_trace<8590>::name("mtl::mg::util::vtk_exporter"); +template <> std::string vampir_trace<8591>::name("mtl::mg::util::csv_exporter"); + +template <> std::string vampir_trace<8610>::name("amg::amg_matrix_hierarchy"); +template <> std::string vampir_trace<8611>::name("amg::compute_influence"); +template <> std::string vampir_trace<8612>::name("amg::default_coarse_grid_detection::compute_C"); +template <> std::string vampir_trace<8614>::name("amg::utils::compute_potentials"); +template <> std::string vampir_trace<8615>::name("amg::utils::find_max_pos"); + +template <> std::string vampir_trace<8617>::name("amg::amg_prolongation"); +template <> std::string vampir_trace<8618>::name("amg::compute_weight"); +template <> std::string vampir_trace<8619>::name("amg::compute_mfactors"); + +template <> std::string vampir_trace<8620>::name("amg::strongly_influenced_points"); +template <> std::string vampir_trace<8621>::name("amg::is_strongly_influenced"); +template <> std::string vampir_trace<8622>::name("amg::strongly_influencing_points"); + +template <> std::string vampir_trace<8630>::name("amg::amg_operators::amg_restriction"); +template <> std::string vampir_trace<8631>::name("amg::amg_operators::amg_prolongation"); +template <> std::string vampir_trace<8635>::name("amg::amg_operators::amg_weight"); + +template <> std::string vampir_trace<8900>::name("NaSto::solve()"); +template <> std::string vampir_trace<8910>::name("NaSto::computeGamma()"); +template <> std::string vampir_trace<8920>::name("NaSto::computeBoundaries()"); +template <> std::string vampir_trace<8930>::name("NaSto::computeImplViscosity()"); +template <> std::string vampir_trace<8940>::name("NaSto::computePressureCorr()"); + +// Test blocks for performance debugging +template <> std::string vampir_trace<9901>::name("tb1"); +template <> std::string vampir_trace<9902>::name("tb2"); +template <> std::string vampir_trace<9903>::name("tb3"); +template <> std::string vampir_trace<9904>::name("tb4"); +template <> std::string vampir_trace<9999>::name("main"); + + +// Only for testing +template <> std::string vampir_trace<9990>::name("helper_function"); +template <> std::string vampir_trace<9991>::name("function"); + + + +}} //mtl::vpt + +#endif //MTL_HAS_VPT -- GitLab