diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/numeric/ublas | |
parent | Initial commit. (diff) | |
download | ceph-upstream/16.2.11+ds.tar.xz ceph-upstream/16.2.11+ds.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/numeric/ublas')
183 files changed, 19327 insertions, 0 deletions
diff --git a/src/boost/libs/numeric/ublas/Changelog b/src/boost/libs/numeric/ublas/Changelog new file mode 100644 index 000000000..0d71a949c --- /dev/null +++ b/src/boost/libs/numeric/ublas/Changelog @@ -0,0 +1,25 @@ +Version 1.1.0 +------------- + +2014-09-16: Nasos Iliopoulos <> + * feature: Merged matrix row and column facades ( matrix as a vector of rows/columns ) + +2014-05-03: David Bellot <david.bellot@gmail.com> + * removed doxygen documentation from main source + * changed the changelog file for GNU format + * changed doc extension to a more "standard" .html + +2014-04-08 Nasos Iliopoulos <> + + * bugfix: introduced an additional swap implementation for index_pair_array and + index_triple_array to allow proper compilation of sparse containers + with g++>4.8 (4.7 also?) in C++11 mode. + +2014-04-02 Nasos Iliopoulos <> + + * Added changelog + * bugfix: corrected a big number of warnings coming from stray typedefs. Other + similar issues may be present that are not triggered by the unit tests + * bugfix: Corrected the banded matrix bug (https://svn.boost.org/trac/boost/ticket/7549) + and updated appropriate unit tests. To enable the old (incorrect though) + behaviour one should define BOOST_UBLAS_LEGACY_BANDED. diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/configuration.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/configuration.pri new file mode 100644 index 000000000..59e3f1a92 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/configuration.pri @@ -0,0 +1,18 @@ +CONFIG -= qt +CONFIG += depend_includepath +win*: CONFIG += console + +# ublas include directory +INCLUDEPATH += \ + ../../../../../include + +QMAKE_CXXFLAGS += -fno-inline +QMAKE_CXXFLAGS += -std=c++17 + +# If ublas tests are build with boost source code then, +# then boost headers and boost libraries should be used. +exists(../../../../../../boost-build.jam) { + INCLUDEPATH += ../../../../../../.. + LIBS += -L../../../../../../../stage/lib + QMAKE_RPATHDIR += ../../../../../../../stage/lib +} diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/examples.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/examples.pro new file mode 100644 index 000000000..d2c3b3cc6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/examples.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = tensor diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/construction_access/example_construction_access.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/construction_access/example_construction_access.pro new file mode 100644 index 000000000..8d6abef37 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/construction_access/example_construction_access.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = construction_access + +include (../../configuration.pri) + +SOURCES += \ + ../../../../../examples/tensor/construction_access.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/einstein_notation/example_einstein_notation.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/einstein_notation/example_einstein_notation.pro new file mode 100644 index 000000000..302b02a10 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/einstein_notation/example_einstein_notation.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = einstein_notation + +include (../../configuration.pri) + +SOURCES += \ + ../../../../../examples/tensor/einstein_notation.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/prod_expressions/example_prod_expressions.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/prod_expressions/example_prod_expressions.pro new file mode 100644 index 000000000..2e210c249 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/prod_expressions/example_prod_expressions.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = prod_expression + +include (../../configuration.pri) + +SOURCES += \ + ../../../../../examples/tensor/prod_expressions.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/simple_expressions/example_simple_expressions.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/simple_expressions/example_simple_expressions.pro new file mode 100644 index 000000000..3b106c9f3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/simple_expressions/example_simple_expressions.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = simple_expressions + +include (../../configuration.pri) + +SOURCES += \ + ../../../../../examples/tensor/simple_expressions.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/tensor.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/tensor.pro new file mode 100644 index 000000000..d50e56c61 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/examples/tensor/tensor.pro @@ -0,0 +1,9 @@ +TEMPLATE = subdirs +SUBDIRS = construction_access simple_expressions prod_expressions einstein_notation + + +construction_access.file = construction_access/example_construction_access.pro +simple_expressions.file = simple_expressions/example_simple_expressions.pro +prod_expressions.file = prod_expressions/example_prod_expressions.pro +einstein_notation.file = einstein_notation/example_einstein_notation.pro + diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/detail/detail.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/detail/detail.pri new file mode 100644 index 000000000..711972db4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/detail/detail.pri @@ -0,0 +1,12 @@ +HEADERS += \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/vector_assign.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/temporary.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/returntype_deduction.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/raw.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/matrix_assign.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/iterator.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/duff.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/documentation.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/definitions.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/config.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/detail/concepts.hpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/experimental/experimental.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/experimental/experimental.pri new file mode 100644 index 000000000..41dc6c46b --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/experimental/experimental.pri @@ -0,0 +1,2 @@ +HEADERS += \ + $${INCLUDE_DIR}/boost/numeric/ublas/experimental/sparse_view.hpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/include.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/include.pro new file mode 100644 index 000000000..185254103 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/include.pro @@ -0,0 +1,52 @@ +TEMPLATE = lib +TARGET = ublas + +CONFIG += \ + staticlib \ + depend_includepath +CONFIG -= qt + +INCLUDE_DIR = ../../../include + +include(detail/detail.pri) +include(experimental/experimental.pri) +include(operation/operation.pri) +include(traits/traits.pri) + +include(tensor/tensor.pri) + +INCLUDEPATH += $${INCLUDE_DIR} + +HEADERS += \ + $${INCLUDE_DIR}/boost/numeric/ublas/vector_sparse.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/vector_proxy.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/vector_of_vector.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/vector_expression.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/vector.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/triangular.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/traits.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tags.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/symmetric.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/storage_sparse.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/storage.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation_sparse.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operations.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation_blocked.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/matrix_sparse.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/matrix_proxy.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/matrix_expression.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/matrix.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/lu.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/io.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/hermitian.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/fwd.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/functional.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/expression_types.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/exception.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/doxydoc.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/blas.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/banded.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/assignment.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/matrix_vector.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor.hpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/operation/operation.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/operation/operation.pri new file mode 100644 index 000000000..519c4f4a6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/operation/operation.pri @@ -0,0 +1,7 @@ +HEADERS += \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation/size.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation/num_rows.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation/num_columns.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation/end.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation/c_array.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/operation/begin.hpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/tensor/tensor.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/tensor/tensor.pri new file mode 100644 index 000000000..503aacb68 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/tensor/tensor.pri @@ -0,0 +1,15 @@ +HEADERS += \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/tensor.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/extents.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/strides.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/expression.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/ostream.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/multiplication.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/functions.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/algorithms.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/expression_evaluation.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/operators_comparison.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/operators_arithmetic.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/multi_index.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/multi_index_utility.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/tensor/index.hpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/traits/traits.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/traits/traits.pri new file mode 100644 index 000000000..de327dc68 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/include/traits/traits.pri @@ -0,0 +1,4 @@ +HEADERS += \ + $${INCLUDE_DIR}/boost/numeric/ublas/traits/iterator_type.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/traits/const_iterator_type.hpp \ + $${INCLUDE_DIR}/boost/numeric/ublas/traits/c_array.hpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/begin_end.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/begin_end.pro new file mode 100644 index 000000000..56fc9fbd4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/begin_end.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = begin_end + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/begin_end.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/comp_mat_erase.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/comp_mat_erase.pro new file mode 100644 index 000000000..b61828bc4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/comp_mat_erase.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +TARGET = comp_mat_erase + +win*: QMAKE_CXXFLAGS += /EHa + +include (configuration.pri) + +SOURCES += \ + ../../../test/comp_mat_erase.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/concepts.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/concepts.pro new file mode 100644 index 000000000..b35d7cb75 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/concepts.pro @@ -0,0 +1,16 @@ +TEMPLATE = app +TARGET = concepts + +include (configuration.pri) + +DEFINES += \ + EXTERNAL +# INTERAL +# SKIP_BAD + +linux: icc: QMAKE_CXXFLAGS += -Xc +macx: QMAKE_CXXFLAGS += -fabi-version=0 + + +SOURCES += \ + ../../../test/concepts.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/configuration.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/configuration.pri new file mode 100644 index 000000000..8233c9b34 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/configuration.pri @@ -0,0 +1,55 @@ +CONFIG -= qt +CONFIG += \ + depend_includepath \ + debug +win*: CONFIG += console + +QMAKE_CXXFLAGS += -fno-inline + +# Create a directory for each test. +DESTDIR = $${TARGET} +OBJECTS_DIR = $${TARGET} + +UBLAS_TESTSET = \ + USE_DOUBLE USE_STD_COMPLEX \ + USE_RANGE USE_SLICE \ + USE_UNBOUNDED_ARRAY USE_STD_VECTOR USE_BOUNDED_VECTOR USE_MATRIX + +UBLAS_TESTSET_SPARSE = \ + USE_DOUBLE USE_STD_COMPLEX \ + USE_UNBOUNDED_ARRAY \ + USE_MAP_ARRAY USE_STD_MAP \ + USE_MAPPED_VECTOR USE_COMPRESSED_VECTOR \ + USE_MAPPED_MATRIX USE_COMPRESSED_MATRIX + # USE_RANGE USE_SLICE # Too complex for regression testing + +UBLAS_TESTSET_SPARSE_COO = \ + USE_DOUBLE USE_STD_COMPLEX \ + USE_UNBOUNDED_ARRAY \ + USE_COORDINATE_VECTOR \ + USE_COORDINATE_MATRIX + +DEFINES += BOOST_UBLAS_NO_EXCEPTIONS + +win*: DEFINES += _SCL_SECURE_NO_WARNINGS + +#Visual age IBM +xlc: DEFINES += BOOST_UBLAS_NO_ELEMENT_PROXIES + +# ublas include and test directory are included +INCLUDEPATH += \ + ../../../include \ + ../../../test + +# If ublas tests are build with boost source code then, +# then boost headers and boost libraries should be used. +exists(../../../../../../boost-build.jam) { + INCLUDEPATH += ../../../../../.. + LIBS += -L../../../../../../stage/lib + QMAKE_RPATHDIR += ../../../../../../stage/lib +} + +# Execute test once compiled. +win*: QMAKE_POST_LINK = .\\$${DESTDIR}\\$${TARGET}.exe +else: QMAKE_POST_LINK = ./$${DESTDIR}/$${TARGET} + diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/num_columns.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/num_columns.pro new file mode 100644 index 000000000..ee1d890dd --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/num_columns.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = num_columns + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/num_columns.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/num_rows.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/num_rows.pro new file mode 100644 index 000000000..9de32bf95 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/num_rows.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = num_rows + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/num_rows.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/placement_new.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/placement_new.pro new file mode 100644 index 000000000..11a05cec0 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/placement_new.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = placement_new + +include (configuration.pri) + +SOURCES += \ + ../../../test/placement_new.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/size.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/size.pro new file mode 100644 index 000000000..69aee624e --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/size.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = size + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/size.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/sparse_view_test.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/sparse_view_test.pro new file mode 100644 index 000000000..cd8172c98 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/sparse_view_test.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = sparse_view_test + +win*:QMAKE_CXXFLAGS += /EHa +# Support asynchronous structured exception handling +# (SEH) with the native C++ catch(...) clause. + +include (configuration.pri) + +SOURCES += \ + ../../../test/sparse_view_test.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test1.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test1.pro new file mode 100644 index 000000000..dae81d57c --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test1.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = test1 + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET + +HEADERS += ../../../test/test1.hpp + +SOURCES += \ + ../../../test/test13.cpp \ + ../../../test/test12.cpp \ + ../../../test/test11.cpp \ + ../../../test/test1.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test2.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test2.pro new file mode 100644 index 000000000..e967a474a --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test2.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = test2 + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET + +HEADERS += ../../../test/test2.hpp + +SOURCES += \ + ../../../test/test23.cpp \ + ../../../test/test22.cpp \ + ../../../test/test21.cpp \ + ../../../test/test2.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3.pro new file mode 100644 index 000000000..69d0f4530 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = test3 + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET_SPARSE + +HEADERS += ../../../test/test3.hpp + +SOURCES += \ + ../../../test/test33.cpp \ + ../../../test/test32.cpp \ + ../../../test/test31.cpp \ + ../../../test/test3.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3_coo.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3_coo.pro new file mode 100644 index 000000000..4af41c9d1 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3_coo.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = test3_coo + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET_SPARSE_COO + +HEADERS += ../../../test/test3.hpp + +SOURCES += \ + ../../../test/test33.cpp \ + ../../../test/test32.cpp \ + ../../../test/test31.cpp \ + ../../../test/test3.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3_mvov.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3_mvov.pro new file mode 100644 index 000000000..7009bdb17 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test3_mvov.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +TARGET = test3_mvov + +include (configuration.pri) + +DEFINES += \ + USE_FLOAT \ + USE_DOUBLE \ + USE_STD_COMPLEX \ + USE_STD_MAP \ + USE_MAPPED_VECTOR_OF_MAPPED_VECTOR + +HEADERS += ../../../test/test3.hpp + +SOURCES += \ + ../../../test/test33.cpp \ + ../../../test/test32.cpp \ + ../../../test/test31.cpp \ + ../../../test/test3.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test4.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test4.pro new file mode 100644 index 000000000..0072a06a0 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test4.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test4 + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET + +HEADERS += ../../../test/test4.hpp + +SOURCES += \ + ../../../test/test43.cpp \ + ../../../test/test42.cpp \ + ../../../test/test4.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test5.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test5.pro new file mode 100644 index 000000000..7dfcb5c0b --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test5.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test5 + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET + +HEADERS += ../../../test/test5.hpp + +SOURCES += \ + ../../../test/test53.cpp \ + ../../../test/test52.cpp \ + ../../../test/test5.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test6.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test6.pro new file mode 100644 index 000000000..5721c8a83 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test6.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test6 + +include (configuration.pri) + +DEFINES += $$UBLAS_TESTSET + +HEADERS += ../../../test/test6.hpp + +SOURCES += \ + ../../../test/test63.cpp \ + ../../../test/test62.cpp \ + ../../../test/test6.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test7.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test7.pro new file mode 100644 index 000000000..c34e201c8 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test7.pro @@ -0,0 +1,16 @@ +TEMPLATE = app +TARGET = test7 + +include (configuration.pri) + +DEFINES += \ + BOOST_UBLAS_USE_INTERVAL \ + $${UBLAS_TESTSET} + +HEADERS += ../../../test/test7.hpp + +SOURCES += \ + ../../../test/test73.cpp \ + ../../../test/test72.cpp \ + ../../../test/test71.cpp \ + ../../../test/test7.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_assignment.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_assignment.pro new file mode 100644 index 000000000..1956d82fc --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_assignment.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test_assignment + +include (configuration.pri) + +DEFINES += \ + BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_assignment.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_banded_storage_layout.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_banded_storage_layout.pro new file mode 100644 index 000000000..3cd992cf8 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_banded_storage_layout.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_banded_storage_layout + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_banded_storage_layout.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_complex_norms.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_complex_norms.pro new file mode 100644 index 000000000..3bc6ae59b --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_complex_norms.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_complex_norms + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_complex_norms.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_always_do_full_sort.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_always_do_full_sort.pro new file mode 100644 index 000000000..ef1ece33a --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_always_do_full_sort.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test_coordinate_matrix_always_do_full_sort + +include (configuration.pri) + +DEFINES += \ + BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_coordinate_matrix_sort.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_inplace_merge.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_inplace_merge.pro new file mode 100644 index 000000000..c1b790116 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_inplace_merge.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_coordinate_matrix_inplace_merge + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_coordinate_matrix_inplace_merge.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_sort.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_sort.pro new file mode 100644 index 000000000..ba109cf1e --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_matrix_sort.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_coordinate_matrix_sort + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_coordinate_matrix_sort.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_vector_inplace_merge.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_vector_inplace_merge.pro new file mode 100644 index 000000000..c1b4e9a7d --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_coordinate_vector_inplace_merge.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +TARGET = test_coordinate_vector_inplace_merge + +include (configuration.pri) +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_coordinate_vector_inplace_merge.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_fixed_containers.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_fixed_containers.pro new file mode 100644 index 000000000..bb7910546 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_fixed_containers.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_fixed_containers + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_fixed_containers.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_basic.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_basic.pro new file mode 100644 index 000000000..c13f6af1d --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_basic.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test_inplace_solve_basic + +include (configuration.pri) + +DEFINES += \ + $$UBLAS_TESTSET + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_inplace_solve.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_mvov.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_mvov.pro new file mode 100644 index 000000000..3f3870e5d --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_mvov.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test_inplace_solve_mvov + +include (configuration.pri) + +DEFINES += \ + USE_MAPPED_VECTOR_OF_MAPPED_VECTOR + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_inplace_solve.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_sparse.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_sparse.pro new file mode 100644 index 000000000..47ebeffe4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_inplace_solve_sparse.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = test_inplace_solve_sparse + +include (configuration.pri) + +DEFINES += \ + $$UBLAS_TESTSET_SPARSE \ + $$UBLAS_TESTSET_SPARSE_COO + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_inplace_solve.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_lu.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_lu.pro new file mode 100644 index 000000000..c44e45875 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_lu.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_lu + +include (configuration.pri) + +HEADERS += \ + ../../../test/common/testhelper.hpp + +SOURCES += \ + ../../../test/test_lu.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_matrix_vector.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_matrix_vector.pro new file mode 100644 index 000000000..f8fd541e9 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_matrix_vector.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = test_matrix_vector + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_matrix_vector.cpp + +INCLUDEPATH += \ + ../../../include diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_tensor.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_tensor.pro new file mode 100644 index 000000000..539546631 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_tensor.pro @@ -0,0 +1,54 @@ +TEMPLATE = app +TARGET = test + +CONFIG -= qt +CONFIG += depend_includepath debug +win*: CONFIG += console + +QMAKE_CXXFLAGS += -fno-inline +QMAKE_CXXFLAGS += -std=c++17 +QMAKE_CXXFLAGS += -Wno-unknown-pragmas +#QMAKE_CXXFLAGS += --coverage + + +DEFINES += BOOST_UBLAS_NO_EXCEPTIONS +win*: DEFINES += _SCL_SECURE_NO_WARNINGS + +#Visual age IBM +xlc: DEFINES += BOOST_UBLAS_NO_ELEMENT_PROXIES + +# If ublas tests are build with boost source code then, +# then boost headers and boost libraries should be used. +exists(../../../../../../boost-build.jam) { + INCLUDEPATH += ../../../../../.. + LIBS += -L../../../../../../stage/lib + QMAKE_RPATHDIR += ../../../../../../stage/lib +} + + +LIBS +=-lboost_unit_test_framework +# -lgcov + +HEADERS += \ + ../../../test/tensor/utility.hpp + +SOURCES += \ + ../../../test/tensor/test_tensor.cpp \ + ../../../test/tensor/test_extents.cpp \ + ../../../test/tensor/test_strides.cpp \ + ../../../test/tensor/test_expression.cpp \ + ../../../test/tensor/test_expression_evaluation.cpp \ + ../../../test/tensor/test_functions.cpp \ + ../../../test/tensor/test_operators_comparison.cpp \ + ../../../test/tensor/test_operators_arithmetic.cpp \ + ../../../test/tensor/test_tensor_matrix_vector.cpp \ + ../../../test/tensor/test_multiplication.cpp \ + ../../../test/tensor/test_algorithms.cpp \ + ../../../test/tensor/test_einstein_notation.cpp \ + ../../../test/tensor/test_multi_index.cpp \ + ../../../test/tensor/test_multi_index_utility.cpp + + + +INCLUDEPATH += \ + ../../../include diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_ticket7296.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_ticket7296.pro new file mode 100644 index 000000000..b57af941d --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_ticket7296.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = test_ticket7296 + +include (configuration.pri) + +HEADERS += \ + ../../../test/utils.hpp + +SOURCES += \ + ../../../test/test_ticket7296.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_triangular.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_triangular.pro new file mode 100644 index 000000000..734c985de --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/test_triangular.pro @@ -0,0 +1,16 @@ +TEMPLATE = app +TARGET = test_triangular + +include (configuration.pri) + +DEFINES += \ + BOOST_CHRONO_DYN_LINK=1 \ + BOOST_CHRONO_THREAD_DISABLED \ + BOOST_SYSTEM_DYN_LINK=1 \ + BOOST_SYSTEM_NO_DEPRECATED \ + BOOST_TIMER_DYN_LINK=1 + +SOURCES += \ + ../../../test/test_triangular.cpp + +LIBS += -lboost_timer -lboost_system -lboost_chrono diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/triangular_access.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/triangular_access.pro new file mode 100644 index 000000000..ac6da4ff3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/triangular_access.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = triangular_access + +include (configuration.pri) + +DEFINES += NOMESSAGES + +HEADERS += \ + ../../../test/common/testhelper.hpp + +SOURCES += \ + ../../../test/triangular_access.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/triangular_layout.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/triangular_layout.pro new file mode 100644 index 000000000..1a16842e5 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/test/triangular_layout.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = triangular_layout + +include (configuration.pri) + +SOURCES += \ + ../../../test/triangular_layout.cpp diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/tests.pri b/src/boost/libs/numeric/ublas/IDEs/qtcreator/tests.pri new file mode 100644 index 000000000..7b55d478c --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/tests.pri @@ -0,0 +1,72 @@ +SUBDIRS += \ + begin_end \ + comp_mat_erase \ + concepts \ + num_columns \ + num_rows \ + placement_new \ + size \ + sparse_view_test \ + test1 \ + test2 \ + test3 \ + test3_coo \ + test3_mvov \ + test4 \ + test5 \ + test6 \ + test7 \ + test_assignment \ + test_banded_storage_layout \ + test_complex_norms \ + test_coordinate_matrix_inplace_merge \ + test_coordinate_matrix_sort \ + test_coordinate_matrix_always_do_full_sort \ + test_coordinate_vector_inplace_merge \ + test_fixed_containers \ + test_inplace_solve_basic \ + test_inplace_solve_sparse \ + test_inplace_solve_mvov \ + test_lu \ + test_matrix_vector \ + test_ticket7296 \ + test_triangular \ + triangular_access \ + triangular_layout \ + test_tensor + +begin_end.file = test/begin_end.pro +comp_mat_erase.file = test/comp_mat_erase.pro +concepts.file = test/concepts.pro +num_columns.file = test/num_columns.pro +num_rows.file = test/num_rows.pro +placement_new.file = test/placement_new.pro +size.file = test/size.pro +sparse_view_test.file = test/sparse_view_test.pro +test1.file = test/test1.pro +test2.file = test/test2.pro +test3.file = test/test3.pro +test3_coo.file = test/test3_coo.pro +test3_mvov.file = test/test3_mvov.pro +test4.file = test/test4.pro +test5.file = test/test5.pro +test6.file = test/test6.pro +test7.file = test/test7.pro +test_assignment.file = test/test_assignment.pro +test_banded_storage_layout.file = test/test_banded_storage_layout.pro +test_complex_norms.file = test/test_complex_norms.pro +test_coordinate_matrix_inplace_merge.file = test/test_coordinate_matrix_inplace_merge.pro +test_coordinate_matrix_sort.file = test/test_coordinate_matrix_sort.pro +test_coordinate_matrix_always_do_full_sort.file = test/test_coordinate_matrix_always_do_full_sort.pro +test_coordinate_vector_inplace_merge.file = test/test_coordinate_vector_inplace_merge.pro +test_fixed_containers.file = test/test_fixed_containers.pro +test_inplace_solve_basic.file = test/test_inplace_solve_basic.pro +test_inplace_solve_sparse.file = test/test_inplace_solve_sparse.pro +test_inplace_solve_mvov.file = test/test_inplace_solve_mvov.pro +test_lu.file = test/test_lu.pro +test_matrix_vector.file = test/test_matrix_vector.pro +test_ticket7296.file = test/test_ticket7296.pro +test_triangular.file = test/test_triangular.pro +triangular_access.file = test/triangular_access.pro +triangular_layout.file = test/triangular_layout.pro +test_tensor.file = test/test_tensor.pro diff --git a/src/boost/libs/numeric/ublas/IDEs/qtcreator/ublas_develop.pro b/src/boost/libs/numeric/ublas/IDEs/qtcreator/ublas_develop.pro new file mode 100644 index 000000000..8139f2493 --- /dev/null +++ b/src/boost/libs/numeric/ublas/IDEs/qtcreator/ublas_develop.pro @@ -0,0 +1,17 @@ +TEMPLATE = subdirs +CONFIG += ordered +SUBDIRS = include examples # benchmarks +OTHER_FILES += ../../changelog.txt + + +include (tests.pri) + + + + + + + + + + diff --git a/src/boost/libs/numeric/ublas/README.md b/src/boost/libs/numeric/ublas/README.md new file mode 100644 index 000000000..66e2b271f --- /dev/null +++ b/src/boost/libs/numeric/ublas/README.md @@ -0,0 +1,46 @@ +Boost.uBLAS Linear Algebra Library +===== +Boost.uBLAS is part of the [Boost C++ Libraries](http://github.com/boostorg). It is directed towards scientific computing on the level of basic linear algebra constructions with matrices and vectors and their corresponding abstract operations. + + +## Documentation +uBLAS is documented at [boost.org](https://www.boost.org/doc/libs/1_69_0/libs/numeric/ublas/doc/index.html). +The development has a [wiki page](https://github.com/uBLAS/ublas/wiki). +The tensor extension has a separate [wiki page](https://github.com/BoostGSoC18/tensor/wiki). + +## License +Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). + +## Properties +* Header-only +* Tensor extension requires C++17 compatible compiler, compiles with + * gcc 7.3.0 + * clang 6.0 + * msvc 14.1 +* Unit-tests require Boost.Test + +## Build Status + +Branch | Travis | Appveyor | codecov.io | Docs | +:-------------: | ------ | -------- | ---------- | ---- | +[`master`](https://github.com/boostorg/ublas/tree/master) | [![Build Status](https://travis-ci.org/boostorg/ublas.svg?branch=master)](https://travis-ci.org/boostorg/ublas) | [![Build status](https://ci.appveyor.com/api/projects/status/ctu3wnfowa627ful/branch/master?svg=true)](https://ci.appveyor.com/project/stefanseefeld/ublas/branch/master) | [![codecov](https://codecov.io/gh/boostorg/ublas/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/ublas/branch/master) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/release/libs/numeric) +[`develop`](https://github.com/boostorg/ublas/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/ublas.svg?branch=develop)](https://travis-ci.org/boostorg/ublas) | [![Build status](https://ci.appveyor.com/api/projects/status/ctu3wnfowa627ful/branch/develop?svg=true)](https://ci.appveyor.com/project/stefanseefeld/ublas/branch/develop) | [![codecov](https://codecov.io/gh/boostorg/ublas/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/ublas/branch/develop) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/release/libs/numeric) + + +## Directories + +| Name | Purpose | +| ----------- | ------------------------------ | +| `doc` | documentation | +| `examples` | example files | +| `include` | headers | +| `test` | unit tests | +| `benchmarks`| timing and benchmarking | + +## More information + +* Ask questions in [stackoverflow](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-ublas) with `boost-ublas` or `ublas` tags. +* Report [bugs](https://github.com/boostorg/ublas/issues) and be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. +* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). +* Developer discussions about the library are held on the [Boost developers mailing list](https://lists.boost.org/mailman/listinfo.cgi/ublas). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[ublas]` tag at the beginning of the subject line +* For any other questions, you can contact David, Stefan or Cem: david.bellot-AT-gmail-DOT-com, cem.bassoy-AT-gmail-DOT-com stefan-AT-seefeld-DOT-name diff --git a/src/boost/libs/numeric/ublas/benchmarks/Jamfile b/src/boost/libs/numeric/ublas/benchmarks/Jamfile new file mode 100644 index 000000000..ab2f77e82 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/Jamfile @@ -0,0 +1,23 @@ +# +# Copyright (c) 2018 Stefan Seefeld +# Use, modification and distribution are subject to the +# Boost Software License, Version 1.0. (See accompanying file +# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +project boost/ublas/benchmarks + : requirements <library>/boost/program_options//boost_program_options + ; + +exe add : add.cpp ; +exe mm_prod : mm_prod.cpp ; +exe mv_prod : mv_prod.cpp ; +exe inner_prod : inner_prod.cpp ; +exe outer_prod : outer_prod.cpp ; + +exe reference/add : reference/add.cpp ; +exe reference/mm_prod : reference/mm_prod.cpp ; +exe reference/mv_prod : reference/mv_prod.cpp ; +exe reference/inner_prod : reference/inner_prod.cpp ; +exe reference/outer_prod : reference/outer_prod.cpp ; + +build-project opencl ; diff --git a/src/boost/libs/numeric/ublas/benchmarks/add.cpp b/src/boost/libs/numeric/ublas/benchmarks/add.cpp new file mode 100644 index 000000000..0bab90bc1 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/add.cpp @@ -0,0 +1,63 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/program_options.hpp> +#include "add.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + bm::add<vector(vector, vector)> a("add(vector<" + type + ">, vector<" + type + ">)"); + a.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Vector-vector addition\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/add.hpp b/src/boost/libs/numeric/ublas/benchmarks/add.hpp new file mode 100644 index 000000000..d5d03d09f --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/add.hpp @@ -0,0 +1,36 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include "init.hpp" +#include "benchmark.hpp" + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class add; + +template <typename R, typename O1, typename O2> +class add<R(O1, O2)> : public benchmark +{ +public: + add(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = a + b; + } +private: + O1 a; + O2 b; + R c; +}; + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/benchmark.hpp b/src/boost/libs/numeric/ublas/benchmarks/benchmark.hpp new file mode 100644 index 000000000..b06cbe55f --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/benchmark.hpp @@ -0,0 +1,52 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#pragma once + +#include <iostream> +#include <chrono> +#include <ctime> +#include <cmath> +#include <string> +#include <vector> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +class benchmark +{ + using clock = std::chrono::system_clock; +public: + benchmark(std::string const &name) : name_(name) {} + void print_header() + { + std::cout << "# benchmark : " << name_ << '\n' + << "# size \ttime (ms)" << std::endl; + } + virtual void setup(long) {} + virtual void operation(long) {} + virtual void teardown() {} + + void run(std::vector<long> const &sizes, unsigned times = 10) + { + print_header(); + for (auto s : sizes) + { + setup(s); + auto start = clock::now(); + for (unsigned i = 0; i != times; ++i) + operation(s); + auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(clock::now() - start); + teardown(); + std::cout << s << '\t' << duration.count()*1./times << std::endl; + } + } +private: + std::string name_; +}; + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/init.hpp b/src/boost/libs/numeric/ublas/benchmarks/init.hpp new file mode 100644 index 000000000..1528389c3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/init.hpp @@ -0,0 +1,37 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +void init(vector<T> &v, unsigned long size, int max_value) +{ + v = vector<T>(size); + for (unsigned long i = 0; i < v.size(); ++i) + v(i) = std::rand() % max_value; +} + +template <typename T, typename L> +void init(matrix<T, L> &m, unsigned long size1, unsigned long size2, int max_value) +{ + m = matrix<T, L>(size1, size2); + for (unsigned long i = 0; i < m.size1(); ++i) + for (unsigned long j = 0; j < m.size2(); ++j) + m(i, j) = std::rand() % max_value; +} + +template <typename T, typename L> +void init(matrix<T, L> &m, unsigned long size, int max_value) +{ + return init(m, size, size, max_value); +} + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/inner_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/inner_prod.cpp new file mode 100644 index 000000000..9d95a3339 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/inner_prod.cpp @@ -0,0 +1,89 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "init.hpp" +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class inner_prod; + +template <typename R, typename V1, typename V2> +class inner_prod<R(V1, V2)> : public benchmark +{ +public: + inner_prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = ublas::inner_prod(a, b); + } +private: + V1 a; + V2 b; + R c; +}; + +}}}} + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + bm::inner_prod<T(vector, vector)> p("inner_prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Inner product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/mm_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/mm_prod.cpp new file mode 100644 index 000000000..f87271c7e --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/mm_prod.cpp @@ -0,0 +1,62 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/program_options.hpp> +#include "prod.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using matrix = ublas::matrix<T, ublas::basic_row_major<>>; + bm::prod<matrix(matrix, matrix)> p("prod(matrix<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512}));//, 1024})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Matrix product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/mv_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/mv_prod.cpp new file mode 100644 index 000000000..bc6da2046 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/mv_prod.cpp @@ -0,0 +1,64 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/program_options.hpp> +#include "prod.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using matrix = ublas::matrix<T, ublas::basic_row_major<>>; + using vector = ublas::vector<T>; + bm::prod<vector(matrix, vector)> p("prod(matrix<" + type + ">, vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Matrix-vector product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/Jamfile b/src/boost/libs/numeric/ublas/benchmarks/opencl/Jamfile new file mode 100644 index 000000000..670ec66b8 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/Jamfile @@ -0,0 +1,27 @@ +# +# Copyright (c) 2018 Stefan Seefeld +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or +# copy at http://www.boost.org/LICENSE_1_0.txt) + +import ac ; + +# work around a bug in Boost.Build +import ../../opencl ; +import ../../clblas ; +using opencl ; +using clblas ; + +project boost/ublas/benchmarks/opencl + : requirements + <library>/boost/program_options//boost_program_options + <toolset>gcc:<cxxflags>-Wno-ignored-attributes + [ ac.check-library /clblas//clblas : <library>/clblas//clblas <library>/opencl//opencl : <build>no ] + ; + +exe add : add.cpp ; +exe mm_prod : mm_prod.cpp ; +exe mv_prod : mv_prod.cpp ; +exe inner_prod : inner_prod.cpp ; +exe outer_prod : outer_prod.cpp ; diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/add.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/add.cpp new file mode 100644 index 000000000..b998cd2c0 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/add.cpp @@ -0,0 +1,93 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or +// copy at http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class add; + +template <typename V, bool C> +class add<void(V,V,V), C> : public benchmark<void(V,V,V), C> +{ +public: + add(std::string const &name) : benchmark<void(V,V,V), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::element_add(*this->a, *this->b, *this->c, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using vector = ublas::vector<T>; + std::string name = "opencl::elementwise_add(vector<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}); + if (copy) + { + bm::opencl::add<void(vector, vector, vector), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::add<void(vector, vector, vector), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Matrix-vector product (OpenCL)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>", copy); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/benchmark.hpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/benchmark.hpp new file mode 100644 index 000000000..fb6075992 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/benchmark.hpp @@ -0,0 +1,214 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or +// copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef opencl_benchmark_hpp_ +#define opencl_benchmark_hpp_ +#define BOOST_UBLAS_ENABLE_OPENCL + +#include <boost/numeric/ublas/opencl.hpp> +#include "../benchmark.hpp" +#include "init.hpp" +#include <memory> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { +namespace opencl { + +struct base +{ + base(compute::device d = compute::system::default_device()) + : context(d), + queue(context, d) + {} + compute::context context; + compute::command_queue queue; +}; + +template <typename T, bool C> struct data_factory; +template <typename T> +struct data_factory<T, true> +{ + typedef T type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long) { return ptr_type(new T());} +}; +template <typename T> +struct data_factory<T, false> +{ + typedef T type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long, compute::context) { return ptr_type(new T());} +}; +template <> +struct data_factory<void, true> +{ + typedef void type; + typedef void *ptr_type; + static ptr_type create(long) { return 0;} +}; +template <> +struct data_factory<void, false> +{ + typedef void type; + typedef void *ptr_type; + static ptr_type create(long, compute::context) { return 0;} +}; +template <typename T> +struct data_factory<ublas::vector<T>, true> +{ + typedef ublas::vector<T> type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long l) { return ptr_type(new type(l));} +}; +template <typename T> +struct data_factory<ublas::vector<T>, false> +{ + typedef ublas::vector<T, ublas::opencl::storage> type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long l, compute::context c) + { return ptr_type(new type(l, c));} +}; +template <typename T, typename L> +struct data_factory<ublas::matrix<T, L>, true> +{ + typedef ublas::matrix<T, L> type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long l) + { return ptr_type(new type(l, l));} +}; +template <typename T, typename L> +struct data_factory<ublas::matrix<T, L>, false> +{ + typedef ublas::matrix<T, L, ublas::opencl::storage> type; + typedef std::unique_ptr<type> ptr_type; + static ptr_type create(long l, compute::context c) + { return ptr_type(new type(l, l, c));} +}; + +template <typename S, bool> class benchmark; + +template <typename R, typename O> +class benchmark<R(O), true> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) + : base(), + ublas::benchmark::benchmark(name + " with copy") + {} + virtual void setup(long l) + { + r = data_factory<R, true>::create(l); + a = data_factory<O, true>::create(l); + init(*a, l, 200); + } + typename data_factory<R, true>::ptr_type r; + typename data_factory<O, true>::ptr_type a; +}; + +template <typename R, typename O1, typename O2> +class benchmark<R(O1, O2), true> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) + : base(), + ublas::benchmark::benchmark(name + " with copy") + {} + virtual void setup(long l) + { + r = data_factory<R, true>::create(l); + a = data_factory<O1, true>::create(l); + init(*a, l, 200); + b = data_factory<O2, true>::create(l); + init(*b, l, 200); + } + typename data_factory<R, true>::ptr_type r; + typename data_factory<O1, true>::ptr_type a; + typename data_factory<O2, true>::ptr_type b; +}; + +template <typename R, typename O1, typename O2, typename O3> +class benchmark<R(O1, O2, O3), true> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) + : base(), + ublas::benchmark::benchmark(name + " with copy") + {} + virtual void setup(long l) + { + r = data_factory<R, true>::create(l); + a = data_factory<O1, true>::create(l); + init(*a, l, 200); + b = data_factory<O2, true>::create(l); + init(*b, l, 200); + c = data_factory<O3, true>::create(l); + init(*c, l, 200); + } + typename data_factory<R, true>::ptr_type r; + typename data_factory<O1, true>::ptr_type a; + typename data_factory<O2, true>::ptr_type b; + typename data_factory<O3, true>::ptr_type c; +}; + +template <typename R, typename O> +class benchmark<R(O), false> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) + : base(), + ublas::benchmark::benchmark(name + " w/o copy") + {} + virtual void setup(long l) + { + r = data_factory<R, false>::create(l, context); + a = data_factory<O, false>::create(l, context); + init(*a, l, 200); + } + typename data_factory<R, false>::ptr_type r; + typename data_factory<O, false>::ptr_type a; +}; + +template <typename R, typename O1, typename O2> +class benchmark<R(O1, O2), false> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) : base(), ublas::benchmark::benchmark(name + " w/o copy") {} + virtual void setup(long l) + { + r = data_factory<R, false>::create(l, context); + a = data_factory<O1, false>::create(l, context); + init(*a, l, 200); + b = data_factory<O2, false>::create(l, context); + init(*b, l, 200); + } + typename data_factory<R, false>::ptr_type r; + typename data_factory<O1, false>::ptr_type a; + typename data_factory<O2, false>::ptr_type b; +}; + +template <typename R, typename O1, typename O2, typename O3> +class benchmark<R(O1, O2, O3), false> : public base, public ublas::benchmark::benchmark +{ +public: + benchmark(std::string const &name) : base(), ublas::benchmark::benchmark(name + " w/o copy") {} + virtual void setup(long l) + { + r = data_factory<R, false>::create(l, context); + a = data_factory<O1, false>::create(l, context); + init(*a, l, 200); + b = data_factory<O2, false>::create(l, context); + init(*b, l, 200); + c = data_factory<O3, false>::create(l, context); + init(*c, l, 200); + } + typename data_factory<R, false>::ptr_type r; + typename data_factory<O1, false>::ptr_type a; + typename data_factory<O2, false>::ptr_type b; + typename data_factory<O3, false>::ptr_type c; +}; +}}}}} + +#endif diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/init.hpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/init.hpp new file mode 100644 index 000000000..a11410283 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/init.hpp @@ -0,0 +1,40 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#pragma once + +#include <boost/numeric/ublas/opencl.hpp> +#include "../init.hpp" + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +void init(T &v, unsigned long size, int max_value) +{ + // TBD +} + +template <typename T> +void init(vector<T, opencl::storage> &v, unsigned long size, int max_value) +{ + // TBD +} + +template <typename T> +void init(matrix<T, opencl::storage> &m, unsigned long size1, unsigned long size2, int max_value) +{ + // TBD +} + +template <typename T> +void init(matrix<T, opencl::storage> &m, unsigned long size, int max_value) +{ + init(m, size, size, max_value); +} + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/inner_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/inner_prod.cpp new file mode 100644 index 000000000..a25664cbf --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/inner_prod.cpp @@ -0,0 +1,94 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class inner_prod; + +template <typename R, typename V, bool C> +class inner_prod<R(V,V), C> : public benchmark<R(V,V), C> +{ +public: + inner_prod(std::string const &name) : benchmark<R(V,V), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::inner_prod(*this->a, *this->b, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using vector = ublas::vector<T>; + std::string name = "opencl::inner_prod(vector<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536}); + if (copy) + { + bm::opencl::inner_prod<T(vector,vector), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::inner_prod<T(vector,vector), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Inner product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + // else if (type == "fcomplex") + // benchmark<std::complex<float>>("std::complex<float>", copy); + // else if (type == "dcomplex") + // benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/mm_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/mm_prod.cpp new file mode 100644 index 000000000..e306031fe --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/mm_prod.cpp @@ -0,0 +1,94 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class prod; + +template <typename M, bool C> +class prod<void(M,M,M), C> : public benchmark<void(M,M,M), C> +{ +public: + prod(std::string const &name) : benchmark<void(M,M,M), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::prod(*this->a, *this->b, *this->c, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using matrix = ublas::matrix<T>; + std::string name = "opencl::prod(matrix<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}); + if (copy) + { + bm::opencl::prod<void(matrix, matrix, matrix), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::prod<void(matrix, matrix, matrix), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Matrix product (OpenCL)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>", copy); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/mv_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/mv_prod.cpp new file mode 100644 index 000000000..70344a4b6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/mv_prod.cpp @@ -0,0 +1,95 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class prod; + +template <typename M, typename V, bool C> +class prod<void(M,V,V), C> : public benchmark<void(M,V,V), C> +{ +public: + prod(std::string const &name) : benchmark<void(M,V,V), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::prod(*this->a, *this->b, *this->c, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using vector = ublas::vector<T>; + using matrix = ublas::matrix<T>; + std::string name = "opencl::prod(matrix<" + type + ", vector<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}); + if (copy) + { + bm::opencl::prod<void(matrix, vector, vector), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::prod<void(matrix, vector, vector), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Matrix-vector product (OpenCL)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>", copy); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/opencl/outer_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/opencl/outer_prod.cpp new file mode 100644 index 000000000..b00bb840c --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/opencl/outer_prod.cpp @@ -0,0 +1,95 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/program_options.hpp> +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; +namespace opencl = boost::numeric::ublas::opencl; + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { namespace opencl { + +template <typename S, bool C> class outer_prod; + +template <typename V, typename M, bool C> +class outer_prod<void(V,V,M), C> : public benchmark<void(V,V,M), C> +{ +public: + outer_prod(std::string const &name) : benchmark<void(V,V,M), C>(name) {} + virtual void operation(long l) + { + ublas::opencl::outer_prod(*this->a, *this->b, *this->c, this->queue); + } +}; + +}}}}} + +template <typename T> +void benchmark(std::string const &type, bool copy) +{ + using vector = ublas::vector<T>; + using matrix = ublas::matrix<T>; + std::string name = "opencl::outer_prod(vector<" + type + ">)"; + std::vector<long> sizes({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}); + if (copy) + { + bm::opencl::outer_prod<void(vector, vector, matrix), true> p(name); + p.run(sizes); + } + else + { + bm::opencl::outer_prod<void(vector, vector, matrix), false> p(name); + p.run(sizes); + } +} + +int main(int argc, char **argv) +{ + opencl::library lib; + po::variables_map vm; + try + { + po::options_description desc("Outer product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + desc.add_options()("copy,c", po::value<bool>(), "include host<->device copy in timing"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + bool copy = vm.count("copy") ? vm["copy"].as<bool>() : false; + if (type == "float") + benchmark<float>("float", copy); + else if (type == "double") + benchmark<double>("double", copy); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>", copy); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>", copy); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/outer_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/outer_prod.cpp new file mode 100644 index 000000000..b907c360f --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/outer_prod.cpp @@ -0,0 +1,90 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "init.hpp" +#include "benchmark.hpp" +#include <complex> +#include <string> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class outer_prod; + +template <typename R, typename V1, typename V2> +class outer_prod<R(V1, V2)> : public benchmark +{ +public: + outer_prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = ublas::outer_prod(a, b); + } +private: + V1 a; + V2 b; + R c; +}; + +}}}} + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + using matrix = ublas::matrix<T>; + bm::outer_prod<matrix(vector, vector)> p("outer_prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Outer product\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/plot.py b/src/boost/libs/numeric/ublas/benchmarks/plot.py new file mode 100755 index 000000000..1ca5e5a7f --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/plot.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# +# Copyright (c) 2018 Stefan Seefeld +# All rights reserved. +# +# This file is part of Boost.uBLAS. It is made available under the +# Boost Software License, Version 1.0. +# (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +import argparse +import matplotlib.pyplot as plt +import numpy as np + + +class plot(object): + + def __init__(self, label, data): + self.label = label + self.data = data + + +def load_file(filename): + + lines = open(filename, 'r').readlines() + label = lines[0][1:-1].strip() + lines = [l.strip() for l in lines] + lines = [l.split('#', 1)[0] for l in lines] + lines = [l for l in lines if l] + data = [l.split() for l in lines] + return plot(label, list(zip(*data))) + + +def main(argv): + + parser = argparse.ArgumentParser(prog=argv[0], description='benchmark plotter') + parser.add_argument('data', nargs='+', help='benchmark data to plot') + parser.add_argument('--log', choices=['no', 'all', 'x', 'y'], help='use a logarithmic scale') + args = parser.parse_args(argv[1:]) + runs = [load_file(d) for d in args.data] + plt.title('Benchmark plot') + plt.xlabel('size') + plt.ylabel('time (s)') + if args.log == 'all': + plot = plt.loglog + elif args.log == 'x': + plot = plt.semilogx + elif args.log == 'y': + plot = plt.semilogy + else: + plot = plt.plot + plots = [plot(r.data[0], r.data[1], label=r.label) for r in runs] + plt.legend() + plt.show() + return True + + +if __name__ == '__main__': + + import sys + sys.exit(0 if main(sys.argv) else 1) diff --git a/src/boost/libs/numeric/ublas/benchmarks/prod.hpp b/src/boost/libs/numeric/ublas/benchmarks/prod.hpp new file mode 100644 index 000000000..243bafcba --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/prod.hpp @@ -0,0 +1,36 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include "init.hpp" +#include "benchmark.hpp" + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class prod; + +template <typename R, typename O1, typename O2> +class prod<R(O1, O2)> : public benchmark +{ +public: + prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = ublas::prod(a, b); + } +private: + O1 a; + O2 b; + R c; +}; + +}}}} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/add.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/add.cpp new file mode 100644 index 000000000..d5b988701 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/add.cpp @@ -0,0 +1,88 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +class add : public benchmark +{ +public: + add(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + for (int i = 0; i < l; ++i) + c(i) = a(i) + b(i); + } +private: + ublas::vector<T> a; + ublas::vector<T> b; + ublas::vector<T> c; +}; + +}}}} + +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + bm::add<T> p("ref::add(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Vector-vector addition (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/inner_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/inner_prod.cpp new file mode 100644 index 000000000..dc1752579 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/inner_prod.cpp @@ -0,0 +1,91 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class inner_prod; + +template <typename R, typename V1, typename V2> +class inner_prod<R(V1, V2)> : public benchmark +{ +public: + inner_prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + c = R(0); + for (int i = 0; i < l; ++i) + c += a(i) * b(i); + } +private: + V1 a; + V2 b; + R c; +}; + +}}}} + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + bm::inner_prod<T(vector, vector)> p("ref::inner_prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Inner product (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/mm_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/mm_prod.cpp new file mode 100644 index 000000000..4b4363167 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/mm_prod.cpp @@ -0,0 +1,93 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +class prod : public benchmark +{ +public: + prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + for (int i = 0; i < l; ++i) + for (int j = 0; j < l; ++j) + { + c(i,j) = 0; + for (int k = 0; k < l; ++k) + c(i,j) += a(i,k) * b(k,j); + } + } +private: + ublas::matrix<T> a; + ublas::matrix<T> b; + ublas::matrix<T> c; +}; + +}}}} + +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + // using matrix = ublas::matrix<T, ublas::basic_row_major<>>; + bm::prod<T> p("ref::prod(matrix<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512}));//, 1024})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Matrix product (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/mv_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/mv_prod.cpp new file mode 100644 index 000000000..e3a157454 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/mv_prod.cpp @@ -0,0 +1,92 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename T> +class prod : public benchmark +{ +public: + prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + for (int i = 0; i < l; ++i) + { + c(i) = 0; + for (int j = 0; j < l; ++j) + c(i) += a(i,j) * b(j); + } + } +private: + ublas::matrix<T> a; + ublas::vector<T> b; + ublas::vector<T> c; +}; + +}}}} + +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + bm::prod<T> p("ref::prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Matrix-vector product (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/benchmarks/reference/outer_prod.cpp b/src/boost/libs/numeric/ublas/benchmarks/reference/outer_prod.cpp new file mode 100644 index 000000000..a300066c2 --- /dev/null +++ b/src/boost/libs/numeric/ublas/benchmarks/reference/outer_prod.cpp @@ -0,0 +1,92 @@ +// +// Copyright (c) 2018 Stefan Seefeld +// All rights reserved. +// +// This file is part of Boost.uBLAS. It is made available under the +// Boost Software License, Version 1.0. +// (Consult LICENSE or http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/program_options.hpp> +#include "../init.hpp" +#include "../benchmark.hpp" +#include <complex> +#include <string> + +namespace boost { namespace numeric { namespace ublas { namespace benchmark { + +template <typename S> class outer_prod; + +template <typename R, typename V1, typename V2> +class outer_prod<R(V1, V2)> : public benchmark +{ +public: + outer_prod(std::string const &name) : benchmark(name) {} + virtual void setup(long l) + { + init(a, l, 200); + init(b, l, 200); + } + virtual void operation(long l) + { + for (int i = 0; i < l; ++i) + for (int j = 0; j < l; ++j) + c(i,j) = - a(i) * b(j); + } +private: + V1 a; + V2 b; + R c; +}; + +}}}} + +namespace po = boost::program_options; +namespace ublas = boost::numeric::ublas; +namespace bm = boost::numeric::ublas::benchmark; + +template <typename T> +void benchmark(std::string const &type) +{ + using vector = ublas::vector<T>; + using matrix = ublas::matrix<T>; + bm::outer_prod<matrix(vector, vector)> p("ref::outer_prod(vector<" + type + ">)"); + p.run(std::vector<long>({1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096})); +} + +int main(int argc, char **argv) +{ + po::variables_map vm; + try + { + po::options_description desc("Outer product (reference implementation)\n" + "Allowed options"); + desc.add_options()("help,h", "produce help message"); + desc.add_options()("type,t", po::value<std::string>(), "select value-type (float, double, fcomplex, dcomplex)"); + + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + std::cout << desc << std::endl; + return 0; + } + } + catch(std::exception &e) + { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + std::string type = vm.count("type") ? vm["type"].as<std::string>() : "float"; + if (type == "float") + benchmark<float>("float"); + else if (type == "double") + benchmark<double>("double"); + else if (type == "fcomplex") + benchmark<std::complex<float>>("std::complex<float>"); + else if (type == "dcomplex") + benchmark<std::complex<double>>("std::complex<double>"); + else + std::cerr << "unsupported value-type \"" << vm["type"].as<std::string>() << '\"' << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/clblas.jam b/src/boost/libs/numeric/ublas/clblas.jam new file mode 100644 index 000000000..d4fa247e3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/clblas.jam @@ -0,0 +1,114 @@ +# Copyright (c) 2018 Stefan Seefeld +# +# Use, modification and distribution is subject to the Boost Software +# License Version 1.0. (See accompanying file LICENSE_1_0.txt or +# http://www.boost.org/LICENSE_1_0.txt) + +# Supports the clblas library +# +# After 'using clblas', the following targets are available: +# +# /clblas//clblas -- The clblas library + +import project ; +import ac ; +import errors ; +import feature ; +import "class" : new ; +import targets ; +import modules ; +import property-set ; +import toolset : using ; + +using opencl ; + +header = clBLAS.h ; +names = clBLAS ; + +library-id = 0 ; + +if --debug-configuration in [ modules.peek : ARGV ] +{ + .debug = true ; +} + +# Initializes the clblas library. +# +# Options for configuring clblas:: +# +# <search> +# The directory containing the clblas library. +# <name> +# Overrides the default library name. +# <include> +# The directory containing the clblas headers. +# +# Examples:: +# +# # Find clblas in the default system location +# using clblas ; +# # Find clblas in /usr/local +# using clblas : 1.2.7 +# : <include>/usr/local/include <search>/usr/local/lib ; +# +rule init ( version ? : # The clblas version (currently ignored) + options * : # A list of the options to use + requirements * ) # The requirements for the clblas target +{ + local caller = [ project.current ] ; + + if ! $(.initialized) + { + .initialized = true ; + + project.initialize $(__name__) ; + .project = [ project.current ] ; + project clblas ; + } + + local library-path = [ feature.get-values <search> : $(options) ] ; + local include-path = [ feature.get-values <include> : $(options) ] ; + local library-name = [ feature.get-values <name> : $(options) ] ; + + if ! $(library-path) && ! $(include-path) && ! $(library-name) + { + is-default = true ; + } + + condition = [ property-set.create $(requirements) ] ; + condition = [ property-set.create [ $(condition).base ] ] ; + + if $(.configured.$(condition)) + { + if $(is-default) + { + if $(.debug) + { + ECHO "notice: [clblas] clblas is already configured" ; + } + } + else + { + errors.user-error "clblas is already configured" ; + } + return ; + } + else + { + if $(.debug) + { + ECHO "notice: [clblas] Using pre-installed library" ; + if $(condition) + { + ECHO "notice: [clblas] Condition" [ $(condition).raw ] ; + } + } + + local mt = [ new ac-library clblas : $(.project) : $(condition) : + $(include-path) : $(library-path) : $(library-name) ] ; + $(mt).set-header $(header) ; + $(mt).set-default-names $(names) ; + targets.main-target-alternative $(mt) ; + } + .configured.$(condition) = true ; +} diff --git a/src/boost/libs/numeric/ublas/examples/tensor/Jamfile b/src/boost/libs/numeric/ublas/examples/tensor/Jamfile new file mode 100644 index 000000000..42f2fe633 --- /dev/null +++ b/src/boost/libs/numeric/ublas/examples/tensor/Jamfile @@ -0,0 +1,25 @@ +# Boost.uBLAS +# +# Copyright (c) 2018 Cem Bassoy +# +# Use, modification and distribution is subject to the Boost Software License, +# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + + +# Project settings +project boost-ublas-tensor-example + : requirements + # these tests require C++17 + <cxxstd>11:<build>no + <define>BOOST_UBLAS_NO_EXCEPTIONS + <toolset>vacpp:<define>"BOOST_UBLAS_NO_ELEMENT_PROXIES" + <toolset>gcc:<cxxflags>"-Wall -pedantic -Wextra -std=c++17" + <toolset>gcc:<cxxflags>"-Wno-unknown-pragmas" + <toolset>msvc:<cxxflags>"/W4" # == all + ; + +exe construction_access : construction_access.cpp ; +exe simple_expressions : simple_expressions.cpp ; +exe prod_expressions : prod_expressions.cpp ; +exe einstein_notation : einstein_notation.cpp ;
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/examples/tensor/construction_access.cpp b/src/boost/libs/numeric/ublas/examples/tensor/construction_access.cpp new file mode 100644 index 000000000..053690c79 --- /dev/null +++ b/src/boost/libs/numeric/ublas/examples/tensor/construction_access.cpp @@ -0,0 +1,89 @@ +// +// Copyright (c) 2018-2019, Cem Bassoy, cem.bassoy@gmail.com +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer IOSB, Ettlingen, Germany +// + +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/multiprecision/cpp_bin_float.hpp> + +#include <ostream> + +int main() +{ + using namespace boost::numeric::ublas; + using namespace boost::multiprecision; + + + // creates a three-dimensional tensor with extents 3,4 and 2 + // tensor A stores single-precision floating-point number according + // to the first-order storage format + using ftype = float; + auto A = tensor<ftype>{3,4,2}; + + // initializes the tensor with increasing values along the first-index + // using a single index. + auto vf = ftype(0); + for(auto i = 0u; i < A.size(); ++i, vf += ftype(1)) + A[i] = vf; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "A=" << A << ";" << std::endl << std::endl; + + // creates a four-dimensional tensor with extents 5,4,3 and 2 + // tensor A stores complex floating-point extended double precision numbers + // according to the last-order storage format + // and initializes it with the default value. + using ctype = std::complex<cpp_bin_float_double_extended>; + auto B = tensor<ctype,last_order>(shape{5,4,3,2},ctype{}); + + // initializes the tensor with increasing values along the last-index + // using a single-index + auto vc = ctype(0,0); + for(auto i = 0u; i < B.size(); ++i, vc += ctype(1,1)) + B[i] = vc; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "B=" << B << ";" << std::endl << std::endl; + + + + auto C = tensor<ctype,last_order>(B.extents()); + // computes the complex conjugate of elements of B + // using multi-index notation. + for(auto i = 0u; i < B.size(0); ++i) + for(auto j = 0u; j < B.size(1); ++j) + for(auto k = 0u; k < B.size(2); ++k) + for(auto l = 0u; l < B.size(3); ++l) + C.at(i,j,k,l) = std::conj(B.at(i,j,k,l)); + + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "C=" << C << ";" << std::endl << std::endl; + + + // computes the complex conjugate of elements of B + // using iterators. + auto D = tensor<ctype,last_order>(B.extents()); + std::transform(B.begin(), B.end(), D.begin(), [](auto const& b){ return std::conj(b); }); + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "D=" << D << ";" << std::endl << std::endl; + + // reshaping tensors. + auto new_extents = B.extents().base(); + std::next_permutation( new_extents.begin(), new_extents.end() ); + D.reshape( shape(new_extents) ); + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "newD=" << D << ";" << std::endl << std::endl; +} diff --git a/src/boost/libs/numeric/ublas/examples/tensor/einstein_notation.cpp b/src/boost/libs/numeric/ublas/examples/tensor/einstein_notation.cpp new file mode 100644 index 000000000..1d95fc06b --- /dev/null +++ b/src/boost/libs/numeric/ublas/examples/tensor/einstein_notation.cpp @@ -0,0 +1,139 @@ +// +// Copyright (c) 2018-2019, Cem Bassoy, cem.bassoy@gmail.com +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer IOSB, Ettlingen, Germany +// + + +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <iostream> + +int main() +{ + using namespace boost::numeric::ublas; + + using format_t = column_major; + using value_t = float; + using tensor_t = tensor<value_t,format_t>; + using matrix_t = matrix<value_t,format_t>; + using namespace boost::numeric::ublas::index; + + // Tensor-Vector-Multiplications - Including Transposition + { + + auto n = shape{3,4,2}; + auto A = tensor_t(n,1); + auto B1 = matrix_t(n[1],n[2],2); + auto v1 = tensor_t(shape{n[0],1},2); + auto v2 = tensor_t(shape{n[1],1},2); +// auto v3 = tensor_t(shape{n[2],1},2); + + // C1(j,k) = B1(j,k) + A(i,j,k)*v1(i); + // tensor_t C1 = B1 + prod(A,vector_t(n[0],1),1); +// tensor_t C1 = B1 + A(_i,_,_) * v1(_i,_); + + // C2(i,k) = A(i,j,k)*v2(j) + 4; + //tensor_t C2 = prod(A,vector_t(n[1],1),2) + 4; +// tensor_t C2 = A(_,_i,_) * v2(_i,_) + 4; + + // not yet implemented! + // C3() = A(i,j,k)*T1(i)*T2(j)*T2(k); + // tensor_t C3 = prod(prod(prod(A,v1,1),v2,1),v3,1); + // tensor_t C3 = A(_i,_j,_k) * v1(_i,_) * v2(_j,_) * v3(_k,_); + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C1(j,k) = B1(j,k) + A(i,j,k)*v1(i);" << std::endl << std::endl; +// std::cout << "C1=" << C1 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C2(i,k) = A(i,j,k)*v2(j) + 4;" << std::endl << std::endl; +// std::cout << "C2=" << C2 << ";" << std::endl << std::endl; + + } + + + // Tensor-Matrix-Multiplications - Including Transposition + { + auto n = shape{3,4,2}; + auto m = 5u; + auto A = tensor_t(n,2); + auto B = tensor_t(shape{n[1],n[2],m},2); + auto B1 = tensor_t(shape{m,n[0]},1); + auto B2 = tensor_t(shape{m,n[1]},1); + + + // C1(l,j,k) = B(j,k,l) + A(i,j,k)*B1(l,i); + // tensor_t C1 = B + prod(A,B1,1); +// tensor_t C1 = B + A(_i,_,_) * B1(_,_i); + + // C2(i,l,k) = A(i,j,k)*B2(l,j) + 4; + // tensor_t C2 = prod(A,B2) + 4; +// tensor_t C2 = A(_,_j,_) * B2(_,_j) + 4; + + // C3(i,l1,l2) = A(i,j,k)*T1(l1,j)*T2(l2,k); + // not yet implemented. + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C1(l,j,k) = B(j,k,l) + A(i,j,k)*B1(l,i);" << std::endl << std::endl; +// std::cout << "C1=" << C1 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C2(i,l,k) = A(i,j,k)*B2(l,j) + 4;" << std::endl << std::endl; +// std::cout << "C2=" << C2 << ";" << std::endl << std::endl; + +// // formatted output +// std::cout << "% --------------------------- " << std::endl; +// std::cout << "% --------------------------- " << std::endl << std::endl; +// std::cout << "% C3(i,l1,l2) = A(i,j,k)*T1(l1,j)*T2(l2,k);" << std::endl << std::endl; +// std::cout << "C3=" << C3 << ";" << std::endl << std::endl; + } + + + // Tensor-Tensor-Multiplications Including Transposition + { + auto na = shape{3,4,5}; + auto nb = shape{4,6,3,2}; + auto A = tensor_t(na,2); + auto B = tensor_t(nb,3); + auto T1 = tensor_t(shape{na[2],na[2]},2); + auto T2 = tensor_t(shape{na[2],nb[1],nb[3]},2); + + + // C1(j,l) = T1(j,l) + A(i,j,k)*A(i,j,l) + 5; + // tensor_t C1 = T1 + prod(A,A,perm_t{1,2}) + 5; +// tensor_t C1 = T1 + A(_i,_j,_m)*A(_i,_j,_l) + 5; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C1(k,l) = T1(k,l) + A(i,j,k)*A(i,j,l) + 5;" << std::endl << std::endl; +// std::cout << "C1=" << C1 << ";" << std::endl << std::endl; + + + // C2(k,l,m) = T2(k,l,m) + A(i,j,k)*B(j,l,i,m) + 5; + //tensor_t C2 = T2 + prod(A,B,perm_t{1,2},perm_t{3,1}) + 5; +// tensor_t C2 = T2 + A(_i,_j,_k)*B(_j,_l,_i,_m) + 5; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C2(k,l,m) = T2(k,l,m) + A(i,j,k)*B(j,l,i,m) + 5;" << std::endl << std::endl; +// std::cout << "C2=" << C2 << ";" << std::endl << std::endl; + + } +} diff --git a/src/boost/libs/numeric/ublas/examples/tensor/prod_expressions.cpp b/src/boost/libs/numeric/ublas/examples/tensor/prod_expressions.cpp new file mode 100644 index 000000000..6ff725214 --- /dev/null +++ b/src/boost/libs/numeric/ublas/examples/tensor/prod_expressions.cpp @@ -0,0 +1,183 @@ +// +// Copyright (c) 2018-2019, Cem Bassoy, cem.bassoy@gmail.com +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer IOSB, Ettlingen, Germany +// + + +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <iostream> + +int main() +{ + using namespace boost::numeric::ublas; + + using format_t = column_major; + using value_t = float; // std::complex<double>; + using tensor_t = tensor<value_t,format_t>; + using matrix_t = matrix<value_t,format_t>; + using vector_t = vector<value_t>; + + // Tensor-Vector-Multiplications - Including Transposition + { + + auto n = shape{3,4,2}; + auto A = tensor_t(n,2); + auto q = 0u; // contraction mode + + // C1(j,k) = T2(j,k) + A(i,j,k)*T1(i); + q = 1u; + tensor_t C1 = matrix_t(n[1],n[2],2) + prod(A,vector_t(n[q-1],1),q); + + // C2(i,k) = A(i,j,k)*T1(j) + 4; + q = 2u; + tensor_t C2 = prod(A,vector_t(n[q-1],1),q) + 4; + + // C3() = A(i,j,k)*T1(i)*T2(j)*T2(k); + tensor_t C3 = prod(prod(prod(A,vector_t(n[0],1),1),vector_t(n[1],1),1),vector_t(n[2],1),1); + + // C4(i,j) = A(k,i,j)*T1(k) + 4; + q = 1u; + tensor_t C4 = prod(trans(A,{2,3,1}),vector_t(n[2],1),q) + 4; + + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C1(j,k) = T2(j,k) + A(i,j,k)*T1(i);" << std::endl << std::endl; + std::cout << "C1=" << C1 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C2(i,k) = A(i,j,k)*T1(j) + 4;" << std::endl << std::endl; + std::cout << "C2=" << C2 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C3() = A(i,j,k)*T1(i)*T2(j)*T2(k);" << std::endl << std::endl; + std::cout << "C3()=" << C3(0) << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C4(i,j) = A(k,i,j)*T1(k) + 4;" << std::endl << std::endl; + std::cout << "C4=" << C4 << ";" << std::endl << std::endl; + + } + + + // Tensor-Matrix-Multiplications - Including Transposition + { + + auto n = shape{3,4,2}; + auto A = tensor_t(n,2); + auto m = 5u; + auto q = 0u; // contraction mode + + // C1(l,j,k) = T2(l,j,k) + A(i,j,k)*T1(l,i); + q = 1u; + tensor_t C1 = tensor_t(shape{m,n[1],n[2]},2) + prod(A,matrix_t(m,n[q-1],1),q); + + // C2(i,l,k) = A(i,j,k)*T1(l,j) + 4; + q = 2u; + tensor_t C2 = prod(A,matrix_t(m,n[q-1],1),q) + 4; + + // C3(i,l1,l2) = A(i,j,k)*T1(l1,j)*T2(l2,k); + q = 3u; + tensor_t C3 = prod(prod(A,matrix_t(m+1,n[q-2],1),q-1),matrix_t(m+2,n[q-1],1),q); + + // C4(i,l1,l2) = A(i,j,k)*T2(l2,k)*T1(l1,j); + tensor_t C4 = prod(prod(A,matrix_t(m+2,n[q-1],1),q),matrix_t(m+1,n[q-2],1),q-1); + + // C5(i,k,l) = A(i,k,j)*T1(l,j) + 4; + q = 3u; + tensor_t C5 = prod(trans(A,{1,3,2}),matrix_t(m,n[1],1),q) + 4; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C1(l,j,k) = T2(l,j,k) + A(i,j,k)*T1(l,i);" << std::endl << std::endl; + std::cout << "C1=" << C1 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C2(i,l,k) = A(i,j,k)*T1(l,j) + 4;" << std::endl << std::endl; + std::cout << "C2=" << C2 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C3(i,l1,l2) = A(i,j,k)*T1(l1,j)*T2(l2,k);" << std::endl << std::endl; + std::cout << "C3=" << C3 << ";" << std::endl << std::endl; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C4(i,l1,l2) = A(i,j,k)*T2(l2,k)*T1(l1,j);" << std::endl << std::endl; + std::cout << "C4=" << C4 << ";" << std::endl << std::endl; + std::cout << "% C3 and C4 should have the same values, true? " << std::boolalpha << (C3 == C4) << "!" << std::endl; + + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C5(i,k,l) = A(i,k,j)*T1(l,j) + 4;" << std::endl << std::endl; + std::cout << "C5=" << C5 << ";" << std::endl << std::endl; + } + + + + + + // Tensor-Tensor-Multiplications Including Transposition + { + + using perm_t = std::vector<std::size_t>; + + auto na = shape{3,4,5}; + auto nb = shape{4,6,3,2}; + auto A = tensor_t(na,2); + auto B = tensor_t(nb,3); + + + // C1(j,l) = T(j,l) + A(i,j,k)*A(i,j,l) + 5; + tensor_t C1 = tensor_t(shape{na[2],na[2]},2) + prod(A,A,perm_t{1,2}) + 5; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C1(k,l) = T(k,l) + A(i,j,k)*A(i,j,l) + 5;" << std::endl << std::endl; + std::cout << "C1=" << C1 << ";" << std::endl << std::endl; + + + // C2(k,l,m) = T(k,l,m) + A(i,j,k)*B(j,l,i,m) + 5; + tensor_t C2 = tensor_t(shape{na[2],nb[1],nb[3]},2) + prod(A,B,perm_t{1,2},perm_t{3,1}) + 5; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C2(k,l,m) = T(k,l,m) + A(i,j,k)*B(j,l,i,m) + 5;" << std::endl << std::endl; + std::cout << "C2=" << C2 << ";" << std::endl << std::endl; + + + // C3(k,l,m) = T(k,l,m) + A(i,j,k)*trans(B(j,l,i,m),{2,3,1,4})+ 5; + tensor_t C3 = tensor_t(shape{na[2],nb[1],nb[3]},2) + prod(A,trans(B,{2,3,1,4}),perm_t{1,2}) + 5; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "% C3(k,l,m) = T(k,l,m) + A(i,j,k)*trans(B(j,l,i,m),{2,3,1,4})+ 5;" << std::endl << std::endl; + std::cout << "C3=" << C3 << ";" << std::endl << std::endl; + + } +} diff --git a/src/boost/libs/numeric/ublas/examples/tensor/simple_expressions.cpp b/src/boost/libs/numeric/ublas/examples/tensor/simple_expressions.cpp new file mode 100644 index 000000000..fabb00f4b --- /dev/null +++ b/src/boost/libs/numeric/ublas/examples/tensor/simple_expressions.cpp @@ -0,0 +1,63 @@ +// +// Copyright (c) 2018-2019, Cem Bassoy, cem.bassoy@gmail.com +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer IOSB, Ettlingen, Germany +// + + +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <ostream> + +int main() +{ + using namespace boost::numeric::ublas; + + using tensorf = tensor<float>; + using matrixf = matrix<float>; + using vectorf = vector<float>; + + auto A = tensorf{3,4,2}; + auto B = A = 2; + + // Calling overloaded operators + // and using simple tensor expression templates. + if( A != (B+1) ) + A += 2*B - 1; + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "A=" << A << ";" << std::endl << std::endl; + + auto n = shape{3,4}; + auto D = matrixf(n[0],n[1],1); + auto e = vectorf(n[1],1); + auto f = vectorf(n[0],2); + + // Calling constructor with + // vector expression templates + tensorf C = 2*f; + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "C=" << C << ";" << std::endl << std::endl; + + + // Calling overloaded operators + // and mixing simple tensor and matrix expression templates + tensorf F = 3*C + 4*prod(2*D,e); + + // formatted output + std::cout << "% --------------------------- " << std::endl; + std::cout << "% --------------------------- " << std::endl << std::endl; + std::cout << "F=" << F << ";" << std::endl << std::endl; + + +} diff --git a/src/boost/libs/numeric/ublas/index.html b/src/boost/libs/numeric/ublas/index.html new file mode 100644 index 000000000..16cd00158 --- /dev/null +++ b/src/boost/libs/numeric/ublas/index.html @@ -0,0 +1,10 @@ +<html> +<head> +<meta http-equiv="refresh" content="0; URL=doc/index.html"> +</head> +<body> +Automatic redirection failed, please go to +<a href="doc/index.html">doc/index.html</a> <hr> +<p>Distributed under the Boost Software License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p> +</body> +</html> diff --git a/src/boost/libs/numeric/ublas/meta/libraries.json b/src/boost/libs/numeric/ublas/meta/libraries.json new file mode 100644 index 000000000..df121c3c3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/meta/libraries.json @@ -0,0 +1,16 @@ +{ + "key": "numeric/ublas", + "name": "uBLAS", + "authors": [ + "Joerg Walter", + "Mathias Koch" + ], + "description": "uBLAS provides tensor, matrix, and vector classes as well as basic linear algebra routines. Several dense, packed and sparse storage schemes are supported.", + "category": [ + "Math" + ], + "maintainers": [ + "David Bellot <david.bellot -at- gmail.com>", + "Stefan Seefeld <stefan -at- seefeld.name>" + ] +} diff --git a/src/boost/libs/numeric/ublas/opencl.jam b/src/boost/libs/numeric/ublas/opencl.jam new file mode 100644 index 000000000..f16193a92 --- /dev/null +++ b/src/boost/libs/numeric/ublas/opencl.jam @@ -0,0 +1,111 @@ +# Copyright (c) 2018 Stefan Seefeld +# +# Use, modification and distribution is subject to the Boost Software +# License Version 1.0. (See accompanying file LICENSE_1_0.txt or +# http://www.boost.org/LICENSE_1_0.txt) + +# Supports the opencl library +# +# After 'using opencl', the following targets are available: +# +# /opencl//opencl -- The OpenCL library + +import project ; +import ac ; +import errors ; +import feature ; +import "class" : new ; +import targets ; +import modules ; +import property-set ; + +header = CL/cl.h ; +names = OpenCL ; + +library-id = 0 ; + +if --debug-configuration in [ modules.peek : ARGV ] +{ + .debug = true ; +} + +# Initializes the opencl library. +# +# Options for configuring opencl:: +# +# <search> +# The directory containing the OpenCL library. +# <name> +# Overrides the default library name. +# <include> +# The directory containing the OpenCL headers. +# +# Examples:: +# +# # Find OpenCL in the default system location +# using opencl ; +# # Find opencl in /usr/local +# using opencl : 1.2.7 +# : <include>/usr/local/include <search>/usr/local/lib ; +# +rule init ( version ? : # The opencl version (currently ignored) + options * : # A list of the options to use + requirements * ) # The requirements for the opencl target +{ + local caller = [ project.current ] ; + + if ! $(.initialized) + { + .initialized = true ; + + project.initialize $(__name__) ; + .project = [ project.current ] ; + project opencl ; + } + + local library-path = [ feature.get-values <search> : $(options) ] ; + local include-path = [ feature.get-values <include> : $(options) ] ; + local library-name = [ feature.get-values <name> : $(options) ] ; + + if ! $(library-path) && ! $(include-path) && ! $(library-name) + { + is-default = true ; + } + + condition = [ property-set.create $(requirements) ] ; + condition = [ property-set.create [ $(condition).base ] ] ; + + if $(.configured.$(condition)) + { + if $(is-default) + { + if $(.debug) + { + ECHO "notice: [opencl] opencl is already configured" ; + } + } + else + { + errors.user-error "opencl is already configured" ; + } + return ; + } + else + { + if $(.debug) + { + ECHO "notice: [opencl] Using pre-installed library" ; + if $(condition) + { + ECHO "notice: [opencl] Condition" [ $(condition).raw ] ; + } + } + + local mt = [ new ac-library opencl : $(.project) : $(condition) : + $(include-path) : $(library-path) : $(library-name) ] ; + $(mt).set-header $(header) ; + $(mt).set-default-names $(names) ; + targets.main-target-alternative $(mt) ; + } + .configured.$(condition) = true ; +} diff --git a/src/boost/libs/numeric/ublas/test/Jamfile b/src/boost/libs/numeric/ublas/test/Jamfile new file mode 100644 index 000000000..26b67b045 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/Jamfile @@ -0,0 +1,258 @@ +# Copyright (c) 2004-2011 Michael Stevens, David Bellot +# Use, modification and distribution are subject to the +# Boost Software License, Version 1.0. (See accompanying file +# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +# Bring in rules for testing +import testing ; + +# Define features to test: +# Value types: USE_FLOAT USE_DOUBLE USE_STD_COMPLEX +# Proxies: USE_RANGE USE_SLICE +# Storage types: USE_BOUNDED_ARRAY USE_UNBOUNDED_ARRAY +# Vector types: USE_STD_VECTOR USE_BOUNDED_VECTOR +# Matrix types: USE_MATRIX USE_BOUNDED_MATRIX USE_VECTOR_OF_VECTOR +# Adaptors: USE_ADAPTOR + +UBLAS_TESTSET = [ modules.peek : UBLAS_TESTSET ] ; +UBLAS_TESTSET ?= + USE_DOUBLE USE_STD_COMPLEX + USE_RANGE USE_SLICE + USE_UNBOUNDED_ARRAY USE_STD_VECTOR USE_BOUNDED_VECTOR USE_MATRIX + ; + +# Sparse storage: USE_MAP_ARRAY USE_STD_MAP +# Sparse vectors: USE_MAPPED_VECTOR USE_COMPRESSED_VECTOR USE_COORDINATE_VECTOR +# Sparse matrices: USE_MAPPED_MATRIX USE_COMPRESSED_MATRIX USE_COORDINATE_MATRIX USE_MAPPED_VECTOR_OF_MAPPED_VECTOR USE_GENERALIZED_VECTOR_OF_VECTOR + +UBLAS_TESTSET_SPARSE = [ modules.peek : UBLAS_TESTSET_SPARSE ] ; +UBLAS_TESTSET_SPARSE ?= + USE_DOUBLE USE_STD_COMPLEX + # USE_RANGE USE_SLICE # Too complex for regression testing + USE_UNBOUNDED_ARRAY + USE_MAP_ARRAY USE_STD_MAP + USE_MAPPED_VECTOR USE_COMPRESSED_VECTOR + USE_MAPPED_MATRIX USE_COMPRESSED_MATRIX + ; +# Generalize VofV still failing +# USE_GENERALIZED_VECTOR_OF_VECTOR + +UBLAS_TESTSET_SPARSE_COO = [ modules.peek : UBLAS_TESTSET_SPARSE_COO ] ; +UBLAS_TESTSET_SPARSE_COO ?= + USE_DOUBLE USE_STD_COMPLEX + USE_UNBOUNDED_ARRAY + USE_COORDINATE_VECTOR + USE_COORDINATE_MATRIX + ; + + +# Project settings +project boost-ublas-test + : requirements + <define>BOOST_UBLAS_NO_EXCEPTIONS + <toolset>vacpp:<define>"BOOST_UBLAS_NO_ELEMENT_PROXIES" + <toolset>gcc:<cxxflags>"-Wall -Wno-unknown-pragmas" + <toolset>msvc:<cxxflags>/bigobj + <toolset>msvc:<cxxflags>"/W4" # == all + # The define of macros below prevent warnings about the checked versions of SCL and CRT libraries. + # Most Boost code does not need these versions (as they are markedly slower). + <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS + <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE + <toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS + <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE + <toolset>msvc:<define>_CRT_NONSTDC_NO_DEPRECATE # Suppresses other warnings about using standard POSIX and C9X. + # Alternatively, you can just suppress the warnings (perhaps not the best way). + #<toolset>msvc:<cxxflags>/wd4996 # 'putenv': The POSIX name for this item is deprecated. + #<toolset>msvc:<cxxflags>/wd4512 # assignment operator could not be generated. + #<toolset>msvc:<cxxflags>/wd4224 # nonstandard extension used : formal parameter 'arg' was previously defined as a type. + #<toolset>msvc:<cxxflags>/wd4127 # expression is constant. + #<toolset>msvc:<cxxflags>/wd4701 # unreachable code - needed for lexical cast - temporary for Boost 1.40 & earlier. + ; + + + + +test-suite numeric/uBLAS + : [ run test1.cpp + test11.cpp + test12.cpp + test13.cpp + : # args + : # input files + : # requirements + <define>$(UBLAS_TESTSET) + ] + [ run test2.cpp + test21.cpp + test22.cpp + test23.cpp + : : : + <define>$(UBLAS_TESTSET) + ] + [ run test3.cpp + test31.cpp + test32.cpp + test33.cpp + : : : + <define>$(UBLAS_TESTSET_SPARSE) + ] + [ run test3.cpp + test31.cpp + test32.cpp + test33.cpp + : : : + <define>$(UBLAS_TESTSET_SPARSE_COO) + : test3_coo + : + ] + [ run test3.cpp + test31.cpp + test32.cpp + test33.cpp + : : : + <define>USE_FLOAT + <define>USE_DOUBLE + <define>USE_STD_COMPLEX + <define>USE_STD_MAP + <define>USE_MAPPED_VECTOR_OF_MAPPED_VECTOR + : test3_mvov + : + ] + [ run test4.cpp + test42.cpp + test43.cpp + : : : + <define>$(UBLAS_TESTSET) + ] + [ run test5.cpp + test52.cpp + test53.cpp + : : : + <define>$(UBLAS_TESTSET) + ] + [ run test6.cpp + test62.cpp + test63.cpp + : : : + <define>$(UBLAS_TESTSET) + ] +# Test commented out because boost::interval does not behave like a scalar type +# [ run test7.cpp +# test71.cpp +# test72.cpp +# test73.cpp +# : : : +# <define>BOOST_UBLAS_USE_INTERVAL +# <define>$(UBLAS_TESTSET) +# ] + + [ run placement_new.cpp + ] + [ compile concepts.cpp + : # requirements + <define>EXTERNAL +# <define>INTERAL +# <define>SKIP_BAD + <toolset>intel-linux:<cxxflags>"-Xc" + <toolset>darwin:<cxxflags>"-fabi-version=0" + ] + [ run test_lu.cpp + : : : + ] + [ run triangular_access.cpp + : : : + <define>NOMESSAGES + ] + [ run triangular_layout.cpp + ] + [ run comp_mat_erase.cpp + : : : + <toolset>msvc:<asynch-exceptions>on + ] + [ run sparse_view_test.cpp + : : : + <toolset>msvc:<asynch-exceptions>on + ] + [ run begin_end.cpp + ] + [ run num_columns.cpp + ] + [ run num_rows.cpp + ] + [ run size.cpp + ] + [ run test_coordinate_matrix_sort.cpp + ] + [ run test_coordinate_matrix_sort.cpp + : + : + : <define>BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT + : test_coordinate_matrix_always_do_full_sort + : + ] + [ run test_complex_norms.cpp + ] + [ run test_scaled_norm.cpp + : : : + <define>BOOST_UBLAS_SCALED_NORM + ] + [ run test_assignment.cpp + : : : + <define>BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT + ] + [ run test_triangular.cpp + : + : + : <library>/boost/timer//boost_timer + ] + [ run test_ticket7296.cpp + : + : + : <toolset>msvc:<cxxflags>/wd4127 # The program checks that test facilities work fine. The warning appears many times. + : + : + ] + [ run test_inplace_solve.cpp + : + : + : <define>$(UBLAS_TESTSET) + : test_inplace_solve_basic + : + ] + [ run test_inplace_solve.cpp + : + : + : <define>$(UBLAS_TESTSET_SPARSE) + <define>$(UBLAS_TESTSET_SPARSE_COO) + : test_inplace_solve_sparse + : + ] + [ run test_inplace_solve.cpp + : + : + : <define>USE_MAPPED_VECTOR_OF_MAPPED_VECTOR + : test_inplace_solve_mvov + : + ] + [ run test_coordinate_vector_inplace_merge.cpp + ] + [ run test_coordinate_matrix_inplace_merge.cpp + ] + [ run test_banded_storage_layout.cpp + : + : + : + : + : + ] + [ run test_fixed_containers.cpp + : + : + : + ] + [ run test_matrix_vector.cpp + ] + ; + +build-project opencl ; +build-project tensor ; diff --git a/src/boost/libs/numeric/ublas/test/README b/src/boost/libs/numeric/ublas/test/README new file mode 100644 index 000000000..761123141 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/README @@ -0,0 +1,31 @@ +Copyright (c) 2000-2011 Joerg Walter, Mathias Koch, David Bellot + +Distributed under the Boost Software License, Version 1.0. (See +accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) + +uBLAS test director + Use boost::test to test various uBLAS containers and expressions + +The tests can be used individually or automaticaly as part of the uBLAS regression tests. + +The tests are broken down in directorys as follows: + +test1 - dense vector and matrix tests +test2 - BLAS tests +test3 - sparse vector and matrix tests +test4 - banded/diagonal matrix tests +test5 - triangular matrix tests +test6 - symmetric matrix tests +test7 - dense vector and matrix tests with boost::numeric::internal values + +Each test directory contains: + testX.hpp Headers and types to be tested + testX.cpp Call the test functions for the defined types + testX1.cpp Implements vector tests + testX2.cpp Implements vector/matrix tests + testX3.cpp Implements matrix tests + +Missing in these tests + a) Runtime result validation. + b) Iterator interface tests. Only complete container expressions are tested diff --git a/src/boost/libs/numeric/ublas/test/begin_end.cpp b/src/boost/libs/numeric/ublas/test/begin_end.cpp new file mode 100644 index 000000000..769a51faf --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/begin_end.cpp @@ -0,0 +1,181 @@ +// Copyright (c) 2011 David Bellot +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <cmath> +#include <boost/numeric/ublas/traits/const_iterator_type.hpp> +#include <boost/numeric/ublas/traits/iterator_type.hpp> +#include <boost/numeric/ublas/traits/c_array.hpp> +#include <boost/numeric/ublas/fwd.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_expression.hpp> +#include <boost/numeric/ublas/operation/begin.hpp> +#include <boost/numeric/ublas/operation/end.hpp> +#include <boost/numeric/ublas/tags.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_expression.hpp> +#include <iostream> +#include "utils.hpp" + + +static const double TOL(1.0e-5); ///< Used for comparing two real numbers. + +#ifdef BOOST_UBLAS_NO_NESTED_CLASS_RELATION +#error "sorry this feature is not supported by your compiler" +#endif + +BOOST_UBLAS_TEST_DEF( test_vector_iteration ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Iteration" ); + + typedef double value_type; + typedef boost::numeric::ublas::vector<value_type> vector_type; + + vector_type v(5); + + v(0) = 0.555950; + v(1) = 0.108929; + v(2) = 0.948014; + v(3) = 0.023787; + v(4) = 1.023787; + + + vector_type::size_type ix = 0; + for ( + boost::numeric::ublas::iterator_type<vector_type>::type it = boost::numeric::ublas::begin<vector_type>(v); + it != boost::numeric::ublas::end<vector_type>(v); + ++it + ) { + BOOST_UBLAS_DEBUG_TRACE( "*it = " << *it << " ==> " << v(ix) ); + BOOST_UBLAS_TEST_CHECK( std::abs(*it - v(ix)) <= TOL ); + ++ix; + } +} + + +BOOST_UBLAS_TEST_DEF( test_vector_const_iteration ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Const Iteration" ); + + typedef double value_type; + typedef boost::numeric::ublas::vector<value_type> vector_type; + + vector_type v(5); + + v(0) = 0.555950; + v(1) = 0.108929; + v(2) = 0.948014; + v(3) = 0.023787; + v(4) = 1.023787; + + + vector_type::size_type ix = 0; + for ( + boost::numeric::ublas::const_iterator_type<vector_type>::type it = boost::numeric::ublas::begin<vector_type>(v); + it != boost::numeric::ublas::end<vector_type>(v); + ++it + ) { + BOOST_UBLAS_DEBUG_TRACE( "*it = " << *it << " ==> " << v(ix) ); + BOOST_UBLAS_TEST_CHECK( std::abs(*it - v(ix)) <= TOL ); + ++ix; + } +} + + +BOOST_UBLAS_TEST_DEF( test_row_major_matrix_iteration ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Row-major Matrix Iteration" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::row_major> matrix_type; + typedef boost::numeric::ublas::iterator_type<matrix_type, boost::numeric::ublas::tag::major>::type outer_iterator_type; + typedef boost::numeric::ublas::iterator_type<matrix_type, boost::numeric::ublas::tag::minor>::type inner_iterator_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + matrix_type::size_type row(0); + for ( + outer_iterator_type outer_it = boost::numeric::ublas::begin<boost::numeric::ublas::tag::major>(A); + outer_it != boost::numeric::ublas::end<boost::numeric::ublas::tag::major>(A); + ++outer_it + ) { + matrix_type::size_type col(0); + + for ( + inner_iterator_type inner_it = boost::numeric::ublas::begin(outer_it); + inner_it != boost::numeric::ublas::end(outer_it); + ++inner_it + ) { + BOOST_UBLAS_DEBUG_TRACE( "*it = " << *inner_it << " ==> " << A(row,col) ); + BOOST_UBLAS_TEST_CHECK( std::abs(*inner_it - A(row,col)) <= TOL ); + + ++col; + } + + ++row; + } +} + + +BOOST_UBLAS_TEST_DEF( test_col_major_matrix_iteration ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Column-major Matrix Iteration" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major> matrix_type; + typedef boost::numeric::ublas::iterator_type<matrix_type, boost::numeric::ublas::tag::major>::type outer_iterator_type; + typedef boost::numeric::ublas::iterator_type<matrix_type, boost::numeric::ublas::tag::minor>::type inner_iterator_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + matrix_type::size_type col(0); + for ( + outer_iterator_type outer_it = boost::numeric::ublas::begin<boost::numeric::ublas::tag::major>(A); + outer_it != boost::numeric::ublas::end<boost::numeric::ublas::tag::major>(A); + ++outer_it + ) { + matrix_type::size_type row(0); + + for ( + inner_iterator_type inner_it = boost::numeric::ublas::begin(outer_it); + inner_it != boost::numeric::ublas::end(outer_it); + ++inner_it + ) { + BOOST_UBLAS_DEBUG_TRACE( "*it = " << *inner_it << " ==> " << A(row,col) ); + BOOST_UBLAS_TEST_CHECK( std::abs(*inner_it - A(row,col)) <= TOL ); + + ++row; + } + + ++col; + } +} + + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_vector_iteration ); + BOOST_UBLAS_TEST_DO( test_vector_const_iteration ); + BOOST_UBLAS_TEST_DO( test_row_major_matrix_iteration ); + BOOST_UBLAS_TEST_DO( test_col_major_matrix_iteration ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/common/init.hpp b/src/boost/libs/numeric/ublas/test/common/init.hpp new file mode 100644 index 000000000..a9691b4ed --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/common/init.hpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2004 Michael Stevens + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +/* + * Default construct test when possible + */ + +template <class E> +struct default_construct +{ + static void test() {} +}; +template <class VC> +struct default_construct<boost::numeric::ublas::vector_container<VC> > +{ + static void test () + { + VC default_constuct; + initialize_vector (default_constuct); + std::cout << "default construct = " << default_constuct << std::endl; + } +}; +template <class MC> +struct default_construct<boost::numeric::ublas::matrix_container<MC> > +{ + static void test () + { + MC default_constuct; + initialize_vector (default_constuct); + std::cout << "default construct = " << default_constuct << std::endl; + } +}; + +/* + * Initialise test values in vector/matrix + */ + +template<class V> +void initialize_vector (V &v) { + typename V::size_type size = v.size (); + for (typename V::size_type i = 0; i < size; ++ i) + v [i] = typename V::value_type ( i + 1.f ); +} + +template<class M> +void initialize_matrix_impl (M &m, ublas::packed_proxy_tag) { + typename M::size_type size1 = m.size1 (); +#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION + for (typename M::iterator1 i = m.begin1(); i != m.end1(); ++ i) + for (typename M::iterator2 j = i.begin(); j != i.end(); ++ j) + *j = typename M::value_type ( i.index1() * size1 + j.index2() + 1.f ); +#else + for (typename M::iterator1 i = m.begin1(); i != m.end1(); ++ i) + for (typename M::iterator2 j = ublas::begin (i, ublas::iterator1_tag ()); j != ublas::end (i, ublas::iterator1_tag ()); ++ j) + *j = typename M::value_type ( i.index1() * size1 + j.index2() + 1.f ); +#endif +} + +template<class M> +void initialize_matrix_impl (M &m, ublas::sparse_proxy_tag) { + typename M::size_type size1 = m.size1 (); + typename M::size_type size2 = m.size2 (); + for (typename M::size_type i = 0; i < size1; ++ i) + for (typename M::size_type j = 0; j < size2; ++ j) + m (i, j) = typename M::value_type (i * size1 + j + 1.f); +} + +template<class M> +void initialize_matrix (M &m) { + initialize_matrix_impl (m, typename M::storage_category()); +} + +template<class M> +void initialize_matrix (M &m, ublas::lower_tag) { + typename M::size_type size1 = m.size1 (); + typename M::size_type size2 = m.size2 (); + for (typename M::size_type i = 0; i < size1; ++ i) { + typename M::size_type j = 0; + for (; j <= i; ++ j) + m (i, j) = i * size1 + j + 1.f; + for (; j < size2; ++ j) + m (i, j) = 0.f; + } +} +template<class M> +void initialize_matrix (M &m, ublas::upper_tag) { + typename M::size_type size1 = m.size1 (); + typename M::size_type size2 = m.size2 (); + for (typename M::size_type i = 0; i < size1; ++ i) { + typename M::size_type j = 0; + for (; j < i; ++ j) + m (i, j) = 0.f; + for (; j < size2; ++ j) + m (i, j) = i * size1 + j + 1.f; + } +} diff --git a/src/boost/libs/numeric/ublas/test/common/testhelper.hpp b/src/boost/libs/numeric/ublas/test/common/testhelper.hpp new file mode 100644 index 000000000..4bc152ca3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/common/testhelper.hpp @@ -0,0 +1,165 @@ +// Copyright 2008 Gunter Winkler <guwi17@gmx.de> +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef _HPP_TESTHELPER_ +#define _HPP_TESTHELPER_ + +#include <utility> +#include <iostream> +#include <boost/numeric/ublas/vector_expression.hpp> +#include <boost/numeric/ublas/matrix_expression.hpp> +#include <boost/mpl/if.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/numeric/ublas/traits.hpp> + +static unsigned _success_counter = 0; +static unsigned _fail_counter = 0; + +static inline +void assertTrue(const char* message, bool condition) { +#ifndef NOMESSAGES + std::cout << message; +#else + (void)message; +#endif + if ( condition ) { + ++ _success_counter; + std::cout << "1\n"; // success + } else { + ++ _fail_counter; + std::cout << "0\n"; // failed + } +} + +template < class T > +void assertEquals(const char* message, T expected, T actual) { +#ifndef NOMESSAGES + std::cout << message; +#else + (void)message; +#endif + if ( expected == actual ) { + ++ _success_counter; + std::cout << "1\n"; // success + } else { + #ifndef NOMESSAGES + std::cout << " expected " << expected << " actual " << actual << " "; + #endif + ++ _fail_counter; + std::cout << "0\n"; // failed + } +} + +inline static +std::pair<unsigned, unsigned> getResults() { + return std::make_pair(_success_counter, _fail_counter); +} + +template < class M1, class M2 > +bool compare( const boost::numeric::ublas::matrix_expression<M1> & m1, + const boost::numeric::ublas::matrix_expression<M2> & m2 ) { + if ((m1().size1() != m2().size1()) || + (m1().size2() != m2().size2())) { + return false; + } + + size_t size1 = m1().size1(); + size_t size2 = m1().size2(); + for (size_t i=0; i < size1; ++i) { + for (size_t j=0; j < size2; ++j) { + if ( m1()(i,j) != m2()(i,j) ) return false; + } + } + return true; +} + +template < class M1, class M2 > +bool compare( const boost::numeric::ublas::vector_expression<M1> & m1, + const boost::numeric::ublas::vector_expression<M2> & m2 ) { + if (m1().size() != m2().size()) { + return false; + } + + size_t size = m1().size(); + for (size_t i=0; i < size; ++i) { + if ( m1()(i) != m2()(i) ) return false; + } + return true; +} + +// Compare if two matrices or vectors are equals based on distance. + +template <typename T> +struct promote_distance { + typedef typename boost::mpl::if_c<boost::is_integral<T>::value, + long double, + T>::type type; +}; + +template <typename M1, typename M2 = void> +struct distance { +private: + typedef typename boost::numeric::ublas::promote_traits<typename M1::value_type, + typename M2::value_type>::promote_type value_type; + +public: + typedef typename promote_distance<value_type>::type type; +}; + +template <typename AE> +struct distance<AE, void> { + typedef typename promote_distance<typename AE::value_type>::type type; +}; + + +template <class AE> +typename distance<AE>::type mean_square(const boost::numeric::ublas::matrix_expression<AE> &me) { + typename distance<AE>::type s(0); + typename AE::size_type i, j; + for (i=0; i!= me().size1(); i++) { + for (j=0; j!= me().size2(); j++) { + s += boost::numeric::ublas::scalar_traits<typename AE::value_type>::type_abs(me()(i,j)); + } + } + return s / (me().size1() * me().size2()); +} + +template <class AE> +typename distance<AE>::type mean_square(const boost::numeric::ublas::vector_expression<AE> &ve) { + // We could have use norm2 here, but ublas' ABS does not support unsigned types. + typename distance<AE>::type s(0); + typename AE::size_type i; + for (i = 0; i != ve().size(); i++) { + s += boost::numeric::ublas::scalar_traits<typename AE::value_type>::type_abs(ve()(i)); + } + return s / ve().size(); +} + +template < class M1, class M2 > +bool compare_distance( const boost::numeric::ublas::matrix_expression<M1> & m1, + const boost::numeric::ublas::matrix_expression<M2> & m2, + typename distance<M1, M2>::type tolerance = 0 ) { + if ((m1().size1() != m2().size1()) || + (m1().size2() != m2().size2())) { + return false; + } + + return mean_square(m2() - m1()) <= tolerance; +} + +template < class M1, class M2 > +bool compare_distance( const boost::numeric::ublas::vector_expression<M1> & m1, + const boost::numeric::ublas::vector_expression<M2> & m2, + typename distance<M1, M2>::type tolerance = 0 ) { + if (m1().size() != m2().size()) { + return false; + } + + return mean_square(m2() - m1()) <= tolerance; +} + + +#endif diff --git a/src/boost/libs/numeric/ublas/test/comp_mat_erase.cpp b/src/boost/libs/numeric/ublas/test/comp_mat_erase.cpp new file mode 100644 index 000000000..70018908d --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/comp_mat_erase.cpp @@ -0,0 +1,106 @@ +// Copyright (c) 2011 David Bellot +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/matrix_sparse.hpp> + +#define BOOST_TEST_MODULE SparseMatrixErasureTest +#include <boost/test/included/unit_test.hpp> + + +BOOST_AUTO_TEST_CASE( compressed_matrix_erase_after_end ) +{ + boost::numeric::ublas::compressed_matrix<int, boost::numeric::ublas::row_major > A(2, 2); + + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + + A(0,0) = 1; + + BOOST_CHECK_EQUAL( A.nnz(), (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + + // check new element + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.value_data()[0], 1 ); + // check end of list marker + BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 1 ); + + A.erase_element(1,0); + + BOOST_CHECK_EQUAL( A.nnz(), (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 1 ); + + // check new element + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.value_data()[0], 1 ); + // check end of list marker + BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 1 ); + + A.erase_element(0,0); + + BOOST_CHECK_EQUAL( A.nnz(), (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + BOOST_CHECK_EQUAL( A.filled2(),(std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + +} + +BOOST_AUTO_TEST_CASE( compressed_matrix_erase_in_the_middle ) +{ + boost::numeric::ublas::compressed_matrix<int, boost::numeric::ublas::row_major > A(2, 2); + + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + + A.insert_element(0,1,5); + + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 1 ); + + // check new element + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.value_data()[0], 5 ); + // check end of list marker + BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 1 ); + + A.insert_element(0,0,4); + + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 2 ); + + // check new element + BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.value_data()[0], 4 ); + // check previous element + BOOST_CHECK_EQUAL( A.index2_data()[1], (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.value_data()[1], 5 ); + // check end of list marker + BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 2 ); + + A.erase_element(0,0); + + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 1 ); + + BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 1 ); + BOOST_CHECK_EQUAL( A.value_data()[0], 5 ); + + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 1 ); + + A.erase_element(0,1); + + BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 ); + BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 ); + BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 0 ); + +} diff --git a/src/boost/libs/numeric/ublas/test/concepts.cpp b/src/boost/libs/numeric/ublas/test/concepts.cpp new file mode 100644 index 000000000..ba9812923 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/concepts.cpp @@ -0,0 +1,34 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_proxy.hpp> +#include <boost/numeric/ublas/vector_sparse.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/banded.hpp> +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/numeric/ublas/symmetric.hpp> +#include <boost/numeric/ublas/hermitian.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/vector_of_vector.hpp> +#include <boost/numeric/ublas/detail/concepts.hpp> +#include <boost/numeric/ublas/experimental/sparse_view.hpp> +//#include <boost/numeric/ublas/vector_view.hpp> + +namespace ublas = boost::numeric::ublas; + + +int main () { + void (* check) (void) = ublas::concept_checks; + boost::ignore_unused_variable_warning (check); +} diff --git a/src/boost/libs/numeric/ublas/test/manual/Jamfile.v2 b/src/boost/libs/numeric/ublas/test/manual/Jamfile.v2 new file mode 100644 index 000000000..5ef982db0 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/manual/Jamfile.v2 @@ -0,0 +1,8 @@ +# Copyright (c) 2006 Michael Stevens +# Use, modification and distribution are subject to the +# Boost Software License, Version 1.0. (See accompanying file +# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +exe sp_resize : sp_resize.cpp ; + +exe test_move_semantics : test_move_semantics.cpp ; diff --git a/src/boost/libs/numeric/ublas/test/manual/sp_resize.cpp b/src/boost/libs/numeric/ublas/test/manual/sp_resize.cpp new file mode 100644 index 000000000..2d52dbbd9 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/manual/sp_resize.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2006 Michael Stevens + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include <iostream> + +#include <boost/numeric/ublas/vector_sparse.hpp> + +typedef double Real; + +template <class V> +void printV(const V& v) { + std::cout << "size: " << v.size() << " nnz_capacity: " << v.nnz_capacity() << " nnz: " << v.nnz() << std::endl; + for (typename V::const_iterator i = v.begin(); i != v.end(); i++) { + std::cout << i.index() << ":" << (*i) << " "; + } + std::cout << std::endl; +} + +template <class V> +void run_test() +{ + V v(10); + + v[0] = 1; + v[5] = 1; + v[8] = 1; + v[9] = 1; + + printV(v); + + v.resize(9); printV(v); + v.resize(12); printV(v); + v.resize(2); printV(v); + v.resize(0); printV(v); + + v.resize(5); v[0] = 1; printV(v); + v.resize(5,false); printV(v); +} + +int main(int, char **) { + + std::cout << "---- MAPPED ----\n"; + run_test< boost::numeric::ublas::mapped_vector<Real> >(); + std::cout << "---- COMPRESSED ----\n"; + run_test< boost::numeric::ublas::compressed_vector<Real> >(); + std::cout << "---- COORDINATE ----\n"; + run_test< boost::numeric::ublas::coordinate_vector<Real> >(); + + return 0; +} + diff --git a/src/boost/libs/numeric/ublas/test/manual/test_move_semantics.cpp b/src/boost/libs/numeric/ublas/test/manual/test_move_semantics.cpp new file mode 100644 index 000000000..188491e4f --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/manual/test_move_semantics.cpp @@ -0,0 +1,127 @@ +/** test move semantics - run with and without BOOST_UBLAS_MOVE_SEMANTICS defined */ + +// Copyright Nasos Iliopoulos, Gunter Winkler 2009. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_UBLAS_MOVE_SEMANTICS +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/io.hpp> + +namespace ublas= boost::numeric::ublas; +std::vector<double> a; + +ublas::vector<double> doubleit(ublas::vector<double> m) +{ + ublas::vector<double> r; + r=2.0*m; + std::cout << "Temporary pointer: " << &r[0] << std::endl; + return r; +} +template <class T,size_t N> +ublas::bounded_vector<T,N > doubleit(ublas::bounded_vector<T, N> m) +{ + ublas::bounded_vector<T,N> r; + r=2.0*m; + std::cout << "Temporary pointer: " << &r[0] << std::endl; + return r; +} + +template <class T,size_t N> +ublas::c_vector<T,N > doubleit(ublas::c_vector<T, N> m) +{ + ublas::c_vector<T,N> r; + r=2.0*m; + std::cout << "Temporary pointer: " << &r[0] << std::endl; + return r; +} + +ublas::matrix<double> doubleit(ublas::matrix<double> m) +{ + ublas::matrix<double> r; + r=2.0*m; + std::cout << "Temporary pointer r: " << &r(0,0) << std::endl; + return r; +} +template <class T,size_t N, size_t M> +ublas::bounded_matrix<T,N, M > doubleit(ublas::bounded_matrix<T, N, M> m) +{ + ublas::bounded_matrix<T,N, M> r; + r=2.0*m; + std::cout << "Temporary pointer: " << &(r(0,0)) << std::endl; + return r; +} + +template <class T,size_t N, size_t M> +ublas::c_matrix<T,N, M > doubleit(ublas::c_matrix<T, N, M> m) +{ + ublas::c_matrix<T,N, M> r; + r=2.0*m; + std::cout << "Temporary pointer: " << &(r(0,0)) << std::endl; + return r; +} + + +void test1() +{ + std::cout << "vector<double> --------------------------------------------------------------------" << std::endl; + ublas::vector<double> a(ublas::scalar_vector<double>(2,2.0)); + a = doubleit(a); + std::cout << "Pointer (must be equal to temp. pointer if move semantics are enabled) : " << &a[0] << std::endl; + + std::cout << a << std::endl; + + std::cout << "bounded_vector<double,2> --------------------------------------------------------------------" << std::endl; + ublas::bounded_vector<double,2> b(ublas::scalar_vector<double>(2,2.0)); + ublas::bounded_vector<double,2> c; + noalias(c)=doubleit(b); + std::cout << "Pointer (bounded_vector swaps by copy this should be different than temp. pointer) : " << &c[0] << std::endl; + c(1)=0.0; + std::cout << b << std::endl; + std::cout << c << std::endl; + + std::cout << "c_vector<double,2> --------------------------------------------------------------------" << std::endl; + ublas::c_vector<double,2> e=ublas::scalar_vector<double>(2,2.0); + ublas::c_vector<double,2> f; + f=doubleit(e); + std::cout << "Pointer (c_vector swaps by copy this should be different than temp. pointer) : " << &f[0] << std::endl; + f(1)=0; + std::cout << e << std::endl; + std::cout << f << std::endl; + +} + +void test2() { + std::cout << "matrix<double> --------------------------------------------------------------------" << std::endl; + ublas::matrix<double> a(ublas::scalar_matrix<double>(2, 3, 2.0)); + a = doubleit(a); + std::cout << "Pointer (must be equal to temp. pointer if move semantics are enabled) : " << &(a(0,0)) << std::endl; + std::cout << a << std::endl; + + std::cout << "bounded_matrix<double,2, 3> --------------------------------------------------------------------" << std::endl; + ublas::bounded_matrix<double,2, 3> b(ublas::scalar_matrix<double>(2,3, 2.0)); + ublas::bounded_matrix<double,2, 3> c; + noalias(c)=doubleit(b); + std::cout << "Pointer (bounded_matrix swaps by copy this should be different than temp. pointer) : " << &(c(0,0)) << std::endl; + c(1,1)=0.0; + std::cout << b << std::endl; + std::cout << c << std::endl; + + std::cout << "c_matrix<double,2 ,3> --------------------------------------------------------------------" << std::endl; + ublas::c_matrix<double,2, 3> e=ublas::scalar_matrix<double>(2,3, 2.0); + ublas::c_matrix<double,2, 3> f; + f=doubleit(e); + std::cout << "Pointer (c_matrix swaps by copy this should be different than temp. pointer) : " << &(f(0,0)) << std::endl; + f(1,1)=0; + std::cout << e << std::endl; + std::cout << f << std::endl; +} + +int main(){ + test1(); + test2(); + return 0; +} + diff --git a/src/boost/libs/numeric/ublas/test/num_columns.cpp b/src/boost/libs/numeric/ublas/test/num_columns.cpp new file mode 100644 index 000000000..68c9770af --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/num_columns.cpp @@ -0,0 +1,110 @@ +// Copyright (c) 2011 David Bellot +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/fwd.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_expression.hpp> +#include <boost/numeric/ublas/operation/num_columns.hpp> +#include <iostream> +#include "utils.hpp" + + +BOOST_UBLAS_TEST_DEF( test_row_major_matrix_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Row-major Matrix Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::row_major> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_columns(A) = " << boost::numeric::ublas::num_columns(A) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_columns(A) == A.size2() ); +} + + +BOOST_UBLAS_TEST_DEF( test_col_major_matrix_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Column-major Matrix Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_columns(A) = " << boost::numeric::ublas::num_columns(A) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_columns(A) == A.size2() ); +} + + +BOOST_UBLAS_TEST_DEF( test_matrix_expression ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Expression" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_columns(A') = " << boost::numeric::ublas::num_columns(boost::numeric::ublas::trans(A)) << " ==> " << boost::numeric::ublas::trans(A).size2() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_columns(boost::numeric::ublas::trans(A)) == boost::numeric::ublas::trans(A).size2() ); +} + + +BOOST_UBLAS_TEST_DEF( test_matrix_reference ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Reference" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type> matrix_type; + typedef boost::numeric::ublas::matrix_reference<matrix_type> matrix_reference_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_columns(reference(A)) = " << boost::numeric::ublas::num_columns(matrix_reference_type(A)) << " ==> " << matrix_reference_type(A).size2() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_columns(matrix_reference_type(A)) == matrix_reference_type(A).size2() ); +} + + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_row_major_matrix_container ); + BOOST_UBLAS_TEST_DO( test_col_major_matrix_container ); + BOOST_UBLAS_TEST_DO( test_matrix_expression ); + BOOST_UBLAS_TEST_DO( test_matrix_reference ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/num_rows.cpp b/src/boost/libs/numeric/ublas/test/num_rows.cpp new file mode 100644 index 000000000..1e3a1e70a --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/num_rows.cpp @@ -0,0 +1,110 @@ +// Copyright (c) 2011 David Bellot +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/fwd.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_expression.hpp> +#include <boost/numeric/ublas/operation/num_rows.hpp> +#include <iostream> +#include "utils.hpp" + + +BOOST_UBLAS_TEST_DEF( test_row_major_matrix_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Row-major Matrix Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::row_major> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_rows(A) = " << boost::numeric::ublas::num_rows(A) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_rows(A) == A.size1() ); +} + + +BOOST_UBLAS_TEST_DEF( test_col_major_matrix_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Column-major Matrix Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_rows(A) = " << boost::numeric::ublas::num_rows(A) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_rows(A) == A.size1() ); +} + + +BOOST_UBLAS_TEST_DEF( test_matrix_expression ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Expression" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_rows(A') = " << boost::numeric::ublas::num_rows(boost::numeric::ublas::trans(A)) << " ==> " << boost::numeric::ublas::trans(A).size1() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_rows(boost::numeric::ublas::trans(A)) == boost::numeric::ublas::trans(A).size1() ); +} + + +BOOST_UBLAS_TEST_DEF( test_matrix_reference ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Reference" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type> matrix_type; + typedef boost::numeric::ublas::matrix_reference<matrix_type> matrix_reference_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + BOOST_UBLAS_DEBUG_TRACE( "num_rows(reference(A)) = " << boost::numeric::ublas::num_rows(matrix_reference_type(A)) << " ==> " << matrix_reference_type(A).size1() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_rows(matrix_reference_type(A)) == matrix_reference_type(A).size1() ); +} + + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_row_major_matrix_container ); + BOOST_UBLAS_TEST_DO( test_col_major_matrix_container ); + BOOST_UBLAS_TEST_DO( test_matrix_expression ); + BOOST_UBLAS_TEST_DO( test_matrix_reference ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/opencl/Jamfile b/src/boost/libs/numeric/ublas/test/opencl/Jamfile new file mode 100644 index 000000000..51c74675e --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/Jamfile @@ -0,0 +1,31 @@ +# +# Copyright (c) 2018 Stefan Seefeld +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or +# copy at http://www.boost.org/LICENSE_1_0.txt) + +import ac ; + +# work around a bug in Boost.Build +import ../../opencl ; +import ../../clblas ; +using opencl ; +using clblas ; + +project boost/ublas/test/opencl + : requirements + <toolset>gcc:<cxxflags>-Wno-ignored-attributes + [ ac.check-library /clblas//clblas : <library>/clblas//clblas <library>/opencl//opencl : <build>no ] + ; + +test-suite ocl + : [ run prod_test.cpp ] + [ run elementwise_operations_test.cpp ] + [ run inner_prod_test.cpp ] + [ run outer_prod_test.cpp ] + [ run transposition_test.cpp ] + [ run norm_test.cpp ] + [ run norm2_test.cpp ] + [ run elementwise_operations_with_constants_test.cpp ] + ; diff --git a/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_test.cpp new file mode 100644 index 000000000..60c76e74d --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_test.cpp @@ -0,0 +1,44 @@ +#include "elementwise_operations_test.hpp" + +int main() +{ + + ///testing row major flaot elementwise operations + bench_elementwise <float, ublas::basic_row_major<>, 10, 10> b1; + + ///testing row major complex float elementwise operations + bench_elementwise <std::complex<float>, ublas::basic_row_major<>, 10, 10> b2; + + ///testing row major double elementwise operations + bench_elementwise <double, ublas::basic_row_major<>, 10, 10> b5; + + ///testing row major complex double elementwise operations + bench_elementwise <std::complex<double>, ublas::basic_row_major<>, 10, 10> b6; + + ///testing column major flaot elementwise operations + bench_elementwise <float, ublas::basic_column_major<>, 10, 10> b3; + + ///testing column major complex float elementwise operations + bench_elementwise <std::complex<float>, ublas::basic_column_major<>, 10, 10> b4; + + ///testing column major double elementwise operations + bench_elementwise <double, ublas::basic_column_major<>, 10, 10> b7; + + ///testing column major complex double elementwise operations + bench_elementwise <std::complex<double>, ublas::basic_column_major<>, 10, 10> b8; + + + std::cout << "row major:" << std::endl; + b1.run(); + b2.run(); + b5.run(); + b6.run(); + + + std::cout << "column major:" << std::endl; + b3.run(); + b4.run(); + b7.run(); + b8.run(); + +} diff --git a/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_test.hpp new file mode 100644 index 000000000..2fe2e571a --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_test.hpp @@ -0,0 +1,114 @@ +#ifndef ELEMENT_OPENCL_HH +#define ELEMENT_OPENCL_HH +#include "test_opencl.hpp" + +template <class T, class F, int number_of_tests, int max_dimension> +class bench_elementwise +{ +public: + typedef test_opencl<T, F> test; + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::matrix<T, F> a; + ublas::matrix<T, F> b; + + //matrix-matrix operations of cpu + ublas::matrix<T, F> result_m_add; + ublas::matrix<T, F> result_m_sub; + ublas::matrix<T, F> result_m_mul; + + //matrix-matrix operations of gpu + ublas::matrix<T, F> result_m_add_cl; + ublas::matrix<T, F> result_m_sub_cl; + ublas::matrix<T, F> result_m_mul_cl; + + + ublas::vector<T> va; + ublas::vector<T> vb; + + //vector-vector operations of cpu + ublas::vector<T> result_v_add; + ublas::vector<T> result_v_sub; + ublas::vector<T> result_v_mul; + + //vector-vector operations of gpu + ublas::vector<T> result_v_add_cl; + ublas::vector<T> result_v_sub_cl; + ublas::vector<T> result_v_mul_cl; + + + for (int i = 0; i<number_of_tests; i++) + { + int rows = std::rand() % max_dimension + 1; + int cols = std::rand() % max_dimension + 1; + + a.resize(rows, cols); + b.resize(rows, cols); + va.resize(rows); + vb.resize(rows); + + + test::init_matrix(a, 200); + test::init_matrix(b, 200); + test::init_vector(va, 200); + test::init_vector(vb, 200); + + result_m_add = a + b; + result_m_add_cl = opencl::element_add(a, b, queue); + + result_m_sub = a - b; + result_m_sub_cl = opencl::element_sub(a, b, queue); + + result_m_mul = ublas::element_prod(a, b); + result_m_mul_cl = opencl::element_prod(a, b, queue); + + + result_v_add = va + vb; + result_v_add_cl = opencl::element_add(va, vb, queue); + + result_v_sub = va - vb; + result_v_sub_cl = opencl::element_sub(va, vb, queue); + + result_v_mul = ublas::element_prod(va, vb); + result_v_mul_cl = opencl::element_prod(va, vb, queue); + + + + + + + if ((!test::compare(result_m_add, result_m_add_cl)) || + (!test::compare(result_m_sub, result_m_sub_cl)) || + (!test::compare(result_m_mul, result_m_mul_cl)) || + (!test::compare(result_v_add, result_v_add_cl)) || + (!test::compare(result_v_sub, result_v_sub_cl)) || + (!test::compare(result_v_mul, result_v_mul_cl)) + ) + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (matrix opencl element wise operations) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif diff --git a/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_with_constants_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_with_constants_test.cpp new file mode 100644 index 000000000..4ec03f99c --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_with_constants_test.cpp @@ -0,0 +1,48 @@ +#include "elementwise_operations_with_constants_test.hpp" +#include <boost/numeric/ublas/matrix.hpp> + +int main() +{ + + ///testing row major flaot prod + bench_elementwise_constant<float, ublas::basic_row_major<>, 10, 10> b1; + + ///testing row major complex float prod + bench_elementwise_constant<std::complex<float>, ublas::basic_row_major<>, 10, 10> b2; + + + ///testing row major double prod + bench_elementwise_constant<double, ublas::basic_row_major<>, 10, 10> b3; + + ///testing row major complex float elementwise operations with constants + bench_elementwise_constant<std::complex<double>, ublas::basic_row_major<>, 10, 10> b4; + + + ///testing column major flaot elementwise operations with constants + bench_elementwise_constant<float, ublas::basic_column_major<>, 10, 10> b5; + + ///testing column major complex float elementwise operations with constants + bench_elementwise_constant<std::complex<float>, ublas::basic_column_major<>, 10, 10> b6; + + ///testing column major double elementwise operations with constants + bench_elementwise_constant<double, ublas::basic_column_major<>, 10, 10> b7; + + ///testing column major complex double elementwise operations with constants + bench_elementwise_constant<std::complex<double>, ublas::basic_column_major<>, 10, 10> b8; + + + std::cout << "Row major:" << std::endl; + b1.run(); + b2.run(); + b3.run(); + b4.run(); + + std::cout << "Column major:" << std::endl; + b5.run(); + b6.run(); + b7.run(); + b8.run(); + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_with_constants_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_with_constants_test.hpp new file mode 100644 index 000000000..f78a73827 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/elementwise_operations_with_constants_test.hpp @@ -0,0 +1,86 @@ +#ifndef TEST_ELEMENT_CONSTANT_OPENCL_HH +#define TEST_ELEMENT_CONSTANT_OPENCL_HH +#include "test_opencl.hpp" + + +template <class T, class F, int number_of_tests, int max_dimension> +class bench_elementwise_constant +{ +public: + + typedef test_opencl<T, F> test; + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::matrix<T, F> m; + ublas::matrix<T, F> m_result_add_ublas; + ublas::matrix<T, F> m_result_sub_ublas; + ublas::matrix<T, F> m_result_add_opencl; + ublas::matrix<T, F> m_result_sub_opencl; + ublas::vector<T> v; + ublas::vector<T> v_result_add_ublas; + ublas::vector<T> v_result_sub_ublas; + ublas::vector<T> v_result_add_opencl; + ublas::vector<T> v_result_sub_opencl; + + + + for (int i = 0; i<number_of_tests; i++) + { + int rows = std::rand() % max_dimension + 1; + int cols = std::rand() % max_dimension + 1; + + m.resize(rows, cols); + v.resize(rows); + + test::init_matrix(m, 200); + test::init_vector(v, 200); + + T constant = rand() % max_dimension; + ublas::matrix<T, F> m_constant_holder(rows, cols, constant); + ublas::vector<T> v_constant_holder(rows, constant); + + m_result_add_ublas = m + m_constant_holder; + m_result_sub_ublas = m - m_constant_holder; + m_result_add_opencl = opencl::element_add(m, constant, queue); + m_result_sub_opencl = opencl::element_sub(m, constant, queue); + + v_result_add_ublas = v + v_constant_holder; + v_result_sub_ublas = v - v_constant_holder; + v_result_add_opencl = opencl::element_add(v, constant, queue); + v_result_sub_opencl = opencl::element_sub(v, constant, queue); + + + + if ((!test::compare(m_result_add_ublas, m_result_add_opencl)) + || (!test::compare(m_result_sub_ublas, m_result_sub_opencl)) || + (!test::compare(v_result_add_ublas, v_result_add_opencl)) + || (!test::compare(v_result_sub_ublas, v_result_sub_opencl))) + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (matrix opencl elementwise operations with constants) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/inner_prod_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/inner_prod_test.cpp new file mode 100644 index 000000000..3f1480e06 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/inner_prod_test.cpp @@ -0,0 +1,23 @@ +#include "inner_prod_test.hpp" +#include <boost/numeric/ublas/matrix.hpp> + +int main() +{ + ///testing row major int inner prod + bench_inner_prod<int, 10, 10> b1; + + ///testing row major float inner prod + bench_inner_prod<float, 10, 10> b2; + + + ///testing row major double inner prod + bench_inner_prod<double, 10, 10> b3; + + + b1.run(); + b2.run(); + b3.run(); + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/inner_prod_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/inner_prod_test.hpp new file mode 100644 index 000000000..cf9dc6465 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/inner_prod_test.hpp @@ -0,0 +1,64 @@ +#ifndef TEST_INNER_PROD_HH +#define TEST_INNER_PROD_HH +#include "test_opencl.hpp" + + +template <class T, int number_of_tests, int max_dimension> +class bench_inner_prod +{ +public: + + typedef test_opencl<T> test; + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::vector<T> va; + ublas::vector<T> vb; + T result_inner_prod_ublas; + T result_inner_prod_opencl; + + + for (int i = 0; i<number_of_tests; i++) + { + int size = std::rand() % max_dimension + 1; + + va.resize(size); + vb.resize(size); + + test::init_vector(va, 200); + test::init_vector(vb, 200); + + result_inner_prod_ublas = ublas::inner_prod(va, vb); + + result_inner_prod_opencl = opencl::inner_prod(va, vb, queue); + + + if (( result_inner_prod_ublas != result_inner_prod_opencl )) + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (matrix opencl inner prod) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif diff --git a/src/boost/libs/numeric/ublas/test/opencl/norm2_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/norm2_test.cpp new file mode 100644 index 000000000..1838ff320 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/norm2_test.cpp @@ -0,0 +1,32 @@ +#include "norm2_test.hpp" +#include <boost/numeric/ublas/matrix.hpp> + +int main() +{ + + ///testing float norm2 + bench_norm2<float, 10, 10> b1; + + + ///testing double norm2 + bench_norm2<double, 10, 10> b2; + + + ///testing float norm2 + bench_norm2<std::complex<float>, 10, 10> b3; + + + ///testing double norm2 + bench_norm2<std::complex<double>, 10, 10> b4; + + + + b1.run(); + b2.run(); + b3.run(); + b4.run(); + + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/norm2_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/norm2_test.hpp new file mode 100644 index 000000000..8a7d6919c --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/norm2_test.hpp @@ -0,0 +1,59 @@ +#ifndef TEST_NORM2_OPENCL_HH +#define TEST_NORM2_OPENCL_HH +#include "test_opencl.hpp" + + +template <class T, int number_of_tests, int max_dimension> +class bench_norm2 +{ +public: + + typedef test_opencl<T, ublas::basic_row_major<>> test; + + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::vector<T> v; + + + for (int i = 0; i<number_of_tests; i++) + { + int size = std::rand() % max_dimension + 1; + + v.resize(size); + test::init_vector(v, 200); + + + T norm2_cpu = ublas::norm_2(v); + T norm2_opencl = opencl::norm_2(v, queue); + + + if ((abs(norm2_cpu - norm2_opencl) / abs(norm2_cpu)) > 1e-6) //precision of float + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (vector opencl a_sum) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/norm_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/norm_test.cpp new file mode 100644 index 000000000..79d6eabff --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/norm_test.cpp @@ -0,0 +1,22 @@ +#include "norm_test.hpp" +#include <boost/numeric/ublas/matrix.hpp> + +int main() +{ + + ///testing float norm1 + bench_norm<float, 10, 10> b1; + + + ///testing double norm1 + bench_norm<double, 10, 10> b2; + + + + b1.run(); + b2.run(); + + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/norm_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/norm_test.hpp new file mode 100644 index 000000000..9623de908 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/norm_test.hpp @@ -0,0 +1,59 @@ +#ifndef TEST_NORM_OPENCL_HH +#define TEST_NORM_OPENCL_HH +#include "test_opencl.hpp" + + +template <class T, int number_of_tests, int max_dimension> +class bench_norm +{ +public: + + typedef test_opencl<T, ublas::basic_row_major<>> test; + + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::vector<T> v; + + + for (int i = 0; i<number_of_tests; i++) + { + int size = std::rand() % max_dimension + 1; + + v.resize(size); + test::init_vector(v, 200); + + + T norm_cpu = ublas::norm_1(v); + T norm_opencl = opencl::norm_1(v, queue); + + + if (norm_cpu != norm_opencl) //precision of float + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (vector opencl a_sum) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/outer_prod_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/outer_prod_test.cpp new file mode 100644 index 000000000..e7195ecbd --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/outer_prod_test.cpp @@ -0,0 +1,31 @@ +#include "outer_prod_test.hpp" + +int main() +{ + + + ///testing float outer prod + bench_outer_prod<float, 10, 10> b1; + + + ///testing double outer prod + bench_outer_prod<double, 10, 10> b2; + + + ///testing complex of float outer prod + bench_outer_prod<std::complex<float>, 10, 10> b3; + + + ///testing complex of double outer prod + bench_outer_prod<std::complex<double>, 10, 10> b4; + + + + b1.run(); + b2.run(); + b3.run(); + b4.run(); + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/outer_prod_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/outer_prod_test.hpp new file mode 100644 index 000000000..348d0b1d6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/outer_prod_test.hpp @@ -0,0 +1,65 @@ +#ifndef TEST_PROD_OPENCL_HH +#define TEST_PROD_OPENCL_HH +#include "test_opencl.hpp" + + +template <class T, int number_of_tests, int max_dimension> +class bench_outer_prod +{ +public: + + typedef test_opencl<T> test; + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::vector<T> va; + ublas::vector<T> vb; + ublas::matrix<T> resultUBLAS; + ublas::matrix<T> resultOPENCL; + + + for (int i = 0; i<number_of_tests; i++) + { + int rows = std::rand() % max_dimension + 1; + int cols = std::rand() % max_dimension + 1; + + va.resize(rows); + vb.resize(cols); + + test::init_vector(va, 200); + test::init_vector(vb, 200); + + //matrix_matrix + resultUBLAS = ublas::outer_prod(va, vb); + resultOPENCL = opencl::outer_prod(va, vb, queue); + + + if (!test::compare(resultUBLAS, resultOPENCL)) + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (matrix opencl outer prod) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/prod_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/prod_test.cpp new file mode 100644 index 000000000..28c39007e --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/prod_test.cpp @@ -0,0 +1,48 @@ +#include "prod_test.hpp" +#include <boost/numeric/ublas/matrix.hpp> + +int main() +{ + + ///testing row major flaot prod + bench_prod<float, ublas::basic_row_major<>, 10, 10> b1; + + ///testing row major complex float prod + bench_prod<std::complex<float>, ublas::basic_row_major<>, 10, 10> b2; + + + ///testing row major double prod + bench_prod<double, ublas::basic_row_major<>, 10, 10> b3; + + ///testing row major complex float prod + bench_prod<std::complex<double>, ublas::basic_row_major<>, 10, 10> b4; + + + ///testing column major flaot prod + bench_prod<float, ublas::basic_column_major<>, 10, 10> b5; + + ///testing column major complex float prod + bench_prod<std::complex<float>, ublas::basic_column_major<>, 10, 10> b6; + + ///testing column major double prod + bench_prod<double, ublas::basic_column_major<>, 10, 10> b7; + + ///testing column major complex double prod + bench_prod<std::complex<double>, ublas::basic_column_major<>, 10, 10> b8; + + + std::cout << "Row major:" << std::endl; + b1.run(); + b2.run(); + b3.run(); + b4.run(); + + std::cout << "Column major:" << std::endl; + b5.run(); + b6.run(); + b7.run(); + b8.run(); + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/prod_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/prod_test.hpp new file mode 100644 index 000000000..e760a842c --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/prod_test.hpp @@ -0,0 +1,88 @@ +#ifndef TEST_PROD_OPENCL_HH +#define TEST_PROD_OPENCL_HH +#include "test_opencl.hpp" + + +template <class T, class F, int number_of_tests, int max_dimension> +class bench_prod +{ +public: + + typedef test_opencl<T, F> test; + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::matrix<T, F> a; + ublas::matrix<T, F> b; + ublas::matrix<T, F> resultUBLAS; + ublas::matrix<T, F> resultOPENCL; + ublas::vector<T> va; + ublas::vector<T> vb; + ublas::vector<T> result_vector_ublas_mv; + ublas::vector<T> result_vector_ublas_vm; + ublas::vector<T> result_vector_opencl_mv; + ublas::vector<T> result_vector_opencl_vm; + + + + for (int i = 0; i<number_of_tests; i++) + { + int rowsA = std::rand() % max_dimension + 1; + int colsA = std::rand() % max_dimension + 1; + int colsB = std::rand() % max_dimension + 1; + + a.resize(rowsA, colsA); + b.resize(colsA, colsB); + va.resize(colsA); + vb.resize(rowsA); + + + test::init_matrix(a, 200); + test::init_matrix(b, 200); + test::init_vector(va, 200); + test::init_vector(vb, 200); + + //matrix_matrix + resultUBLAS = prod(a, b); + resultOPENCL = opencl::prod(a, b, queue); + + + //matrix_vector + result_vector_ublas_mv = ublas::prod(a, va); + result_vector_opencl_mv = opencl::prod(a, va, queue); + + + //vector-matrix + result_vector_ublas_vm = ublas::prod(vb, a); + result_vector_opencl_vm = opencl::prod(vb, a, queue); + + + if ((!test::compare(resultUBLAS, resultOPENCL)) || (!test::compare(result_vector_opencl_mv, result_vector_ublas_mv)) || (!test::compare(result_vector_opencl_vm, result_vector_ublas_vm))) + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (matrix opencl prod) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/test_opencl.hpp b/src/boost/libs/numeric/ublas/test/opencl/test_opencl.hpp new file mode 100644 index 000000000..fe1af32ef --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/test_opencl.hpp @@ -0,0 +1,84 @@ +#ifndef TEST_OPENCL_HEADER_HH +#define TEST_OPENCL_HEADER_HH +#include <stdio.h> + +#define BOOST_UBLAS_ENABLE_OPENCL +#include <boost/numeric/ublas/opencl.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <time.h> +#include <math.h> + + + + +namespace ublas = boost::numeric::ublas; +namespace opencl = boost::numeric::ublas::opencl; +namespace compute = boost::compute; + +template <class T, class F = ublas::basic_row_major<>> +class test_opencl +{ +public: + static bool compare(ublas::matrix<T, F>& a, ublas::matrix<T, F>& b) + { + typedef typename ublas::matrix<T, F>::size_type size_type; + if ((a.size1() != b.size1()) || (a.size2() != b.size2())) + return false; + + for (size_type i = 0; i<a.size1(); i++) + for (size_type j = 0; j<a.size2(); j++) + if (a(i, j) != b(i, j)) + { + return false; + } + return true; + + } + + + static bool compare(ublas::vector<T>& a, ublas::vector<T>& b) + { + typedef typename ublas::vector<T>::size_type size_type; + if (a.size() != b.size()) + return false; + + for (size_type i = 0; i<a.size(); i++) + if ((a[i] != b[i])) + { + return false; + } + return true; + + } + + + + static void init_matrix(ublas::matrix<T, F>& m, int max_value) + { + typedef typename ublas::matrix<T, F>::size_type size_type; + for (size_type i = 0; i < m.size1(); i++) + { + for (size_type j = 0; j<m.size2(); j++) + m(i, j) = (std::rand() % max_value) + 1; + + } + } + + + static void init_vector(ublas::vector<T>& v, int max_value) + { + typedef typename ublas::vector<T>::size_type size_type; + for (size_type i = 0; i <v.size(); i++) + { + v[i] = (std::rand() % max_value) + 1; + } + } + + + virtual void run() + { + } + +}; + +#endif diff --git a/src/boost/libs/numeric/ublas/test/opencl/transposition_test.cpp b/src/boost/libs/numeric/ublas/test/opencl/transposition_test.cpp new file mode 100644 index 000000000..f6dd6782f --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/transposition_test.cpp @@ -0,0 +1,33 @@ +#include "transposition_test.hpp" + +int main() +{ + + //Row-major + bench_trans<float, ublas::basic_row_major<>, 10, 10> b1; + bench_trans<double, ublas::basic_row_major<>, 10, 10> b2; + bench_trans<std::complex<float>, ublas::basic_row_major<>, 10, 10> b3; + bench_trans<std::complex<double>, ublas::basic_row_major<>, 10, 10> b4; + + //Column-major + bench_trans<float, ublas::basic_column_major<>, 10, 10> b5; + bench_trans<double, ublas::basic_column_major<>, 10, 10> b6; + bench_trans<std::complex<float>, ublas::basic_column_major<>, 10, 10> b7; + bench_trans<std::complex<double>, ublas::basic_column_major<>, 10, 10> b8; + + std::cout << "Row-major:" << std::endl; + b1.run(); + b2.run(); + b3.run(); + b4.run(); + + std::cout << std::endl << "Column-major:" << std::endl; + + b5.run(); + b6.run(); + b7.run(); + b8.run(); + + return 0; + +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/opencl/transposition_test.hpp b/src/boost/libs/numeric/ublas/test/opencl/transposition_test.hpp new file mode 100644 index 000000000..eca469f92 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/opencl/transposition_test.hpp @@ -0,0 +1,61 @@ +#ifndef TEST_TRANS_OPENCL_HH +#define TEST_TRANS_OPENCL_HH +#include "test_opencl.hpp" + + +template <class T, class F, int number_of_tests, int max_dimension> +class bench_trans +{ +public: + + typedef test_opencl<T, F> test; + + void run() + { + opencl::library lib; + int passedOperations = 0; + // get default device and setup context + compute::device device = compute::system::default_device(); + compute::context context(device); + compute::command_queue queue(context, device); + + std::srand(time(0)); + + ublas::matrix<T, F> a; + ublas::matrix<T, F> resultUBLAS; + ublas::matrix<T, F> resultOPENCL; + + + for (int i = 0; i<number_of_tests; i++) + { + int rowsA = std::rand() % max_dimension + 1; + int colsA = std::rand() % max_dimension + 1; + + a.resize(rowsA, colsA); + + test::init_matrix(a, 200); + + resultUBLAS = ublas::trans(a); + resultOPENCL = opencl::trans(a, queue); + + + if (!test::compare(resultUBLAS, resultOPENCL)) + { + std::cout << "Error in calculations" << std::endl; + + std::cout << "passed: " << passedOperations << std::endl; + return; + } + + passedOperations++; + + } + std::cout << "All is well (matrix opencl prod) of " << typeid(T).name() << std::endl; + + + + } + +}; + +#endif
\ No newline at end of file diff --git a/src/boost/libs/numeric/ublas/test/placement_new.cpp b/src/boost/libs/numeric/ublas/test/placement_new.cpp new file mode 100644 index 000000000..940da7dab --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/placement_new.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2004 Michael Stevens + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +/* + * Test placement new and array placement new for uBLAS + * See if base pointer is effected by array count cookie + */ + +#include <boost/numeric/ublas/storage.hpp> +#include <iostream> +#include <new> + +// User defined type to capture base pointer on construction + +class udt { +public: + udt () { + base_pointer = this; + } + ~udt () {} // required for GCC prior to 3.4 to generate cookie + + static udt* base_pointer; +}; + +udt* udt::base_pointer; + +int main () +{ + udt a; + udt* ap = &a; + + // Capture placement new offsets for a udt + new (ap) udt; + int new_offset = int (udt::base_pointer - ap); + new (ap) udt [1]; + int array_new_offset = int (udt::base_pointer - ap); + + // Print offsets - we expect 0,0 or 0,sizeof(std::size_t) + std::cout << new_offset <<','<< array_new_offset << std::endl; + + // Return status + if (new_offset != 0) + return -1; // Very bad if new has an offset + +#ifdef BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW + bool expect_array_offset = false; +#else + bool expect_array_offset = true; +#endif + // Check match between config and array + if (!expect_array_offset && array_new_offset != 0) { + return -2; // Bad config should not enable array new + } + if (expect_array_offset && array_new_offset == 0) { + return -3; // Config could enable array new + } + + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/size.cpp b/src/boost/libs/numeric/ublas/test/size.cpp new file mode 100644 index 000000000..1fd2f9de6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/size.cpp @@ -0,0 +1,275 @@ +// Copyright (c) 2011 David Bellot +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/fwd.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_expression.hpp> +#include <boost/numeric/ublas/operation/size.hpp> +#include <boost/numeric/ublas/tags.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_expression.hpp> +#include <iostream> +#include "utils.hpp" + + +BOOST_UBLAS_TEST_DEF( test_vector_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::vector<value_type> vector_type; + + vector_type v(5); + + v(0) = 0.555950; + v(1) = 0.108929; + v(2) = 0.948014; + v(3) = 0.023787; + v(4) = 1.023787; + + + // size(v) + BOOST_UBLAS_DEBUG_TRACE( "size(v) = " << boost::numeric::ublas::size(v) << " ==> " << v.size() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::size(v) == v.size() ); + + // size<1>(v) + BOOST_UBLAS_DEBUG_TRACE( "size<1>(v) = " << (boost::numeric::ublas::size<1>(v)) << " ==> " << v.size() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(v) == v.size()) ); + + // [NOT_COMPILE]: this should *correctly* cause a compilation error + // size<2>(v) + //BOOST_UBLAS_DEBUG_TRACE( "size<2>(v) = " << (boost::numeric::ublas::size<vector_type,2>(v)) << " ==> " << v.size() ); + //BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(v) == v.size()) ); + // [/NOT_COMPILE] +} + + +BOOST_UBLAS_TEST_DEF( test_vector_expression ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Expression" ); + + typedef double value_type; + typedef boost::numeric::ublas::vector<value_type> vector_type; + + vector_type v(5); + + v(0) = 0.555950; + v(1) = 0.108929; + v(2) = 0.948014; + v(3) = 0.023787; + v(4) = 1.023787; + + + // size(-v) + BOOST_UBLAS_DEBUG_TRACE( "size(-v) = " << boost::numeric::ublas::size(-v) << " ==> " << (-v).size() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::size(-v) == (-v).size() ); + + // size<1>(-v) + BOOST_UBLAS_DEBUG_TRACE( "size<1>(-v) = " << (boost::numeric::ublas::size<1>(-v)) << " ==> " << (-v).size() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(-v) == (-v).size()) ); +} + + +BOOST_UBLAS_TEST_DEF( test_vector_reference ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Reference" ); + + typedef double value_type; + typedef boost::numeric::ublas::vector<value_type> vector_type; + typedef boost::numeric::ublas::vector_reference<vector_type> vector_reference_type; + + vector_type v(5); + + v(0) = 0.555950; + v(1) = 0.108929; + v(2) = 0.948014; + v(3) = 0.023787; + v(4) = 1.023787; + + + // size(reference(v) + BOOST_UBLAS_DEBUG_TRACE( "size(reference(v)) = " << boost::numeric::ublas::size(vector_reference_type(v)) << " ==> " << vector_reference_type(v).size() ); + BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::size(vector_reference_type(v)) == vector_reference_type(v).size() ); + + // size<1>(reference(v)) + BOOST_UBLAS_DEBUG_TRACE( "size<1>(reference(v)) = " << (boost::numeric::ublas::size<1>(vector_reference_type(v))) << " ==> " << vector_reference_type(v).size() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(vector_reference_type(v)) == vector_reference_type(v).size()) ); +} + + +BOOST_UBLAS_TEST_DEF( test_row_major_matrix_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Row-major Matrix Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::row_major> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + // [NOT_COMPILE] + // size(A) + //BOOST_UBLAS_DEBUG_TRACE( "size(A) = " << boost::numeric::ublas::size(A) << " ==> " << A.size1() ); + //BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::size(A) == A.size1() ); + // [/NOT_COMPILE] + + // size<1>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<1>(A) = " << (boost::numeric::ublas::size<1>(A)) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(A) == A.size1()) ); + + // size<2>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<2>(A) = " << (boost::numeric::ublas::size<2>(A)) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(A) == A.size2()) ); + + // size<major>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<major>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(A)) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(A) == A.size1()) ); + + // size<minor>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<minor>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(A)) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(A) == A.size2()) ); + + // size<leading>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<leading>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(A)) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(A) == A.size2()) ); +} + + +BOOST_UBLAS_TEST_DEF( test_col_major_matrix_container ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Column-major Matrix Container" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + // size<1>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<1>(A) = " << (boost::numeric::ublas::size<1>(A)) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(A) == A.size1()) ); + + // size<2>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<2>(A) = " << (boost::numeric::ublas::size<2>(A)) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(A) == A.size2()) ); + + // size<major>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<major>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(A)) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(A) == A.size2()) ); + + // size<minor>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<minor>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(A)) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(A) == A.size1()) ); + + // size<leading>(A) + BOOST_UBLAS_DEBUG_TRACE( "size<leading>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(A)) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(A) == A.size1()) ); +} + + +BOOST_UBLAS_TEST_DEF( test_matrix_expression ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Expression" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type> matrix_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + // size<1>(A') + BOOST_UBLAS_DEBUG_TRACE( "size<1>(A') = " << (boost::numeric::ublas::size<1>(boost::numeric::ublas::trans(A))) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(boost::numeric::ublas::trans(A)) == A.size2()) ); + + // size<2>(A') + BOOST_UBLAS_DEBUG_TRACE( "size<2>(A') = " << (boost::numeric::ublas::size<2>(boost::numeric::ublas::trans(A))) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(boost::numeric::ublas::trans(A)) == A.size1()) ); + + // size<major>(A') [A is row-major => A' column-major, and viceversa] + BOOST_UBLAS_DEBUG_TRACE( "size<major>(A') = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(boost::numeric::ublas::trans(A))) << " ==> " << A.size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(boost::numeric::ublas::trans(A)) == A.size1()) ); + + // size<minor>(A') [A is row-major => A' column-major, and viceversa] + BOOST_UBLAS_DEBUG_TRACE( "size<minor>(A') = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(boost::numeric::ublas::trans(A))) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(boost::numeric::ublas::trans(A)) == A.size2()) ); + + // size<leading>(A') [A row-major => A' column-major, and viceversa] + BOOST_UBLAS_DEBUG_TRACE( "size<leading>(A') = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(boost::numeric::ublas::trans(A))) << " ==> " << A.size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(boost::numeric::ublas::trans(A)) == A.size2()) ); +} + + +BOOST_UBLAS_TEST_DEF( test_matrix_reference ) +{ + BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Reference" ); + + typedef double value_type; + typedef boost::numeric::ublas::matrix<value_type> matrix_type; + typedef boost::numeric::ublas::matrix_reference<matrix_type> matrix_reference_type; + + matrix_type A(5,4); + + A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938; + A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283; + A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152; + A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332; + A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332; + + + // size<1>(reference(A)) + BOOST_UBLAS_DEBUG_TRACE( "size<1>(reference(A)) = " << (boost::numeric::ublas::size<1>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(matrix_reference_type(A)) == matrix_reference_type(A).size1()) ); + + // size<2>(reference(A)) + BOOST_UBLAS_DEBUG_TRACE( "size<2>(reference(A)) = " << (boost::numeric::ublas::size<2>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(matrix_reference_type(A)) == matrix_reference_type(A).size2()) ); + + // size<major>(reference(A)) + BOOST_UBLAS_DEBUG_TRACE( "size<major>(reference(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size1() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(matrix_reference_type(A)) == matrix_reference_type(A).size1()) ); + + // size<minor>(reference(A)) + BOOST_UBLAS_DEBUG_TRACE( "size<minor>(reference(A)) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(matrix_reference_type(A)) == matrix_reference_type(A).size2()) ); + + // size<leading>(reference(A)) + BOOST_UBLAS_DEBUG_TRACE( "size<leading>(reference(A)) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size2() ); + BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(matrix_reference_type(A)) == matrix_reference_type(A).size2()) ); +} + + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_vector_container ); + BOOST_UBLAS_TEST_DO( test_vector_expression ); + BOOST_UBLAS_TEST_DO( test_vector_reference ); + BOOST_UBLAS_TEST_DO( test_row_major_matrix_container ); + BOOST_UBLAS_TEST_DO( test_col_major_matrix_container ); + BOOST_UBLAS_TEST_DO( test_matrix_expression ); + BOOST_UBLAS_TEST_DO( test_matrix_reference ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/sparse_view_test.cpp b/src/boost/libs/numeric/ublas/test/sparse_view_test.cpp new file mode 100644 index 000000000..178e44427 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/sparse_view_test.cpp @@ -0,0 +1,106 @@ +// Copyright (c) 2009-2011 Gunter Winkler, David Bellot +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// ublas headers + +#include <boost/numeric/ublas/experimental/sparse_view.hpp> + +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/io.hpp> + +#include <boost/numeric/ublas/traits/c_array.hpp> + +// other boost headers + +// headers for testcase + +#define BOOST_TEST_MODULE SparseMatrixErasureTest +#include <boost/test/included/unit_test.hpp> + +// standard and system headers + +#include <iostream> +#include <string> + +namespace ublas = boost::numeric::ublas; + + /* + sparse input matrix: + + 1 2 0 0 + 0 3 9 0 + 0 1 4 0 + */ + + static const std::string inputMatrix = "[3,4]((1,2,0,0),(0,3,9,0),(0,1,4,0))\n"; + + const unsigned int NNZ = 6; + const unsigned int IB = 1; + const double VA[] = { 1.0, 2.0, 3.0, 9.0, 1.0, 4.0 }; + const unsigned int IA[] = { 1, 3, 5, 7 }; + const unsigned int JA[] = { 1, 2, 2, 3, 2, 3 }; + +BOOST_AUTO_TEST_CASE( test_construction_and_basic_operations ) +{ + + typedef ublas::matrix<double> DENSE_MATRIX; + + // prepare data + + DENSE_MATRIX A; + + std::istringstream iss(inputMatrix); + iss >> A; + + std::cout << A << std::endl; + + std::cout << ( ublas::make_compressed_matrix_view<ublas::row_major,IB>(3,4,NNZ,IA,JA,VA) ) << std::endl; + + typedef ublas::compressed_matrix_view<ublas::row_major, IB, unsigned int [4], unsigned int [NNZ], double[NNZ]> COMPMATVIEW; + + COMPMATVIEW viewA(3,4,NNZ,IA,JA,VA); + + std::cout << viewA << std::endl; + +} + + + +BOOST_AUTO_TEST_CASE( test_construction_from_pointers ) +{ + + std::cout << ( ublas::make_compressed_matrix_view<ublas::column_major,IB>(4,3,NNZ + , ublas::c_array_view<const unsigned int>(4,&(IA[0])) + , ublas::c_array_view<const unsigned int>(6,&(JA[0])) + , ublas::c_array_view<const double>(6,&(VA[0]))) ) << std::endl; + + unsigned int * ia = new unsigned int[4](); + unsigned int * ja = new unsigned int[6](); + double * va = new double[6](); + + std::copy(&(IA[0]),&(IA[4]),ia); + std::copy(&(JA[0]),&(JA[6]),ja); + std::copy(&(VA[0]),&(VA[6]),va); + + typedef ublas::compressed_matrix_view<ublas::column_major + , IB + , ublas::c_array_view<unsigned int> + , ublas::c_array_view<unsigned int> + , ublas::c_array_view<double> > COMPMATVIEW; + + COMPMATVIEW viewA(4,3,NNZ + , ublas::c_array_view<unsigned int>(4,ia) + , ublas::c_array_view<unsigned int>(6,ja) + , ublas::c_array_view<double>(6,va)); + + std::cout << viewA << std::endl; + + delete[] va; + delete[] ja; + delete[] ia; + +} diff --git a/src/boost/libs/numeric/ublas/test/tensor/Jamfile b/src/boost/libs/numeric/ublas/test/tensor/Jamfile new file mode 100644 index 000000000..0bbf2c569 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/Jamfile @@ -0,0 +1,42 @@ +# Boost.uBLAS +# +# Copyright (c) 2018 Cem Bassoy +# +# Use, modification and distribution is subject to the Boost Software License, +# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +project boost/ublas/test/tensor + : requirements + # these tests require C++17 + <cxxstd>11:<build>no + <toolset>gcc:<cxxflags>"-Wall -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-but-set-variable" + ; + +alias unit_test_framework + : # sources + /boost//unit_test_framework + ; + +# make aliases explicit so the libraries will only be built when requested +explicit unit_test_framework ; + + + +test-suite boost-ublas-tensor-test + : + [ run test_tensor.cpp + test_strides.cpp + test_operators_comparison.cpp + test_operators_arithmetic.cpp + test_multiplication.cpp + test_multi_index_utility.cpp + test_multi_index.cpp + test_functions.cpp + test_extents.cpp + test_expression_evaluation.cpp + test_einstein_notation.cpp + test_algorithms.cpp + test_tensor_matrix_vector.cpp + unit_test_framework ] + ; diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_algorithms.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_algorithms.cpp new file mode 100644 index 000000000..4215fc2a1 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_algorithms.cpp @@ -0,0 +1,288 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + +#include <iostream> +#include <algorithm> +#include <vector> +#include <boost/numeric/ublas/tensor/algorithms.hpp> +#include <boost/numeric/ublas/tensor/extents.hpp> +#include <boost/numeric/ublas/tensor/strides.hpp> +#include "utility.hpp" + +#include <boost/test/unit_test.hpp> + + +BOOST_AUTO_TEST_SUITE ( test_tensor_algorithms, + * boost::unit_test::depends_on("test_extents") + * boost::unit_test::depends_on("test_strides")) + + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; +using test_types2 = std::tuple<int,long,float,double,std::complex<float>>; + +struct fixture +{ + using extents_type = boost::numeric::ublas::shape; + fixture() + : extents { + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{4,1,3}, // 6 + extents_type{1,2,3}, // 7 + extents_type{4,2,3}, // 8 + extents_type{4,2,3,5} } // 9 + { + } + std::vector<extents_type> extents; +}; + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_algorithms_copy, value, test_types2, fixture ) +{ + using namespace boost::numeric; + using value_type = value; + using vector_type = std::vector<value_type>; + + + for(auto const& n : extents) { + + auto a = vector_type(n.product()); + auto b = vector_type(n.product()); + auto c = vector_type(n.product()); + + auto wa = ublas::strides<ublas::first_order>(n); + auto wb = ublas::strides<ublas::last_order> (n); + auto wc = ublas::strides<ublas::first_order>(n); + + auto v = value_type{}; + for(auto i = 0ul; i < a.size(); ++i, v+=1){ + a[i]=v; + } + + ublas::copy( n.size(), n.data(), b.data(), wb.data(), a.data(), wa.data() ); + ublas::copy( n.size(), n.data(), c.data(), wc.data(), b.data(), wb.data() ); + + for(auto i = 1ul; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i], a[i] ); + + using size_type = typename ublas::strides<ublas::first_order>::value_type; + size_type const*const p0 = nullptr; + BOOST_CHECK_THROW( ublas::copy( n.size(), p0, c.data(), wc.data(), b.data(), wb.data() ), std::length_error ); + BOOST_CHECK_THROW( ublas::copy( n.size(), n.data(), c.data(), p0, b.data(), wb.data() ), std::length_error ); + BOOST_CHECK_THROW( ublas::copy( n.size(), n.data(), c.data(), wc.data(), b.data(), p0 ), std::length_error ); + + value_type* c0 = nullptr; + BOOST_CHECK_THROW( ublas::copy( n.size(), n.data(), c0, wc.data(), b.data(), wb.data() ), std::length_error ); + } + + // special case rank == 0 + { + auto n = ublas::shape{}; + + auto a = vector_type(n.product()); + auto b = vector_type(n.product()); + auto c = vector_type(n.product()); + + + auto wa = ublas::strides<ublas::first_order>(n); + auto wb = ublas::strides<ublas::last_order> (n); + auto wc = ublas::strides<ublas::first_order>(n); + + ublas::copy( n.size(), n.data(), b.data(), wb.data(), a.data(), wa.data() ); + ublas::copy( n.size(), n.data(), c.data(), wc.data(), b.data(), wb.data() ); + + + + BOOST_CHECK_NO_THROW( ublas::copy( n.size(), n.data(), c.data(), wc.data(), b.data(), wb.data() ) ); + + } + + + + + +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_algorithms_transform, value, test_types2, fixture ) +{ + using namespace boost::numeric; + using value_type = value; + using vector_type = std::vector<value_type>; + + + for(auto const& n : extents) { + + auto a = vector_type(n.product()); + auto b = vector_type(n.product()); + auto c = vector_type(n.product()); + + auto wa = ublas::strides<ublas::first_order>(n); + auto wb = ublas::strides<ublas::last_order> (n); + auto wc = ublas::strides<ublas::first_order>(n); + + auto v = value_type{}; + for(auto i = 0ul; i < a.size(); ++i, v+=1){ + a[i]=v; + } + + ublas::transform( n.size(), n.data(), b.data(), wb.data(), a.data(), wa.data(), [](value_type const& a){ return a + value_type(1);} ); + ublas::transform( n.size(), n.data(), c.data(), wc.data(), b.data(), wb.data(), [](value_type const& a){ return a - value_type(1);} ); + + for(auto i = 1ul; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i], a[i] ); + + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_algorithms_accumulate, value, test_types2, fixture ) +{ + using namespace boost::numeric; + using value_type = value; + using vector_type = std::vector<value_type>; + + + for(auto const& n : extents) { + + auto const s = n.product(); + + auto a = vector_type(n.product()); + // auto b = vector_type(n.product()); + // auto c = vector_type(n.product()); + + auto wa = ublas::strides<ublas::first_order>(n); + // auto wb = ublas::strides<ublas::last_order> (n); + // auto wc = ublas::strides<ublas::first_order>(n); + + auto v = value_type{}; + for(auto i = 0ul; i < a.size(); ++i, v+=value_type(1)){ + a[i]=v; + } + + auto acc = ublas::accumulate( n.size(), n.data(), a.data(), wa.data(), v); + + BOOST_CHECK_EQUAL( acc, value_type( s*(s+1) / 2 ) ); + + + auto acc2 = ublas::accumulate( n.size(), n.data(), a.data(), wa.data(), v, + [](auto const& l, auto const& r){return l + r; }); + + BOOST_CHECK_EQUAL( acc2, value_type( s*(s+1) / 2 ) ); + + } +} + + + + +template<class V> +void init(std::vector<V>& a) +{ + auto v = V(1); + for(auto i = 0u; i < a.size(); ++i, ++v){ + a[i] = v; + } +} + +template<class V> +void init(std::vector<std::complex<V>>& a) +{ + auto v = std::complex<V>(1,1); + for(auto i = 0u; i < a.size(); ++i){ + a[i] = v; + v.real(v.real()+1); + v.imag(v.imag()+1); + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_algorithms_trans, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using vector_type = std::vector<value_type>; + using strides_type = ublas::strides<layout_type>; + using extents_type = ublas::shape; + using size_type = typename extents_type::value_type; + using permutation_type = std::vector<size_type>; + + + for(auto const& n : extents) { + + auto p = n.size(); + auto s = n.product(); + + auto pi = permutation_type(p); + auto a = vector_type(s); + auto b1 = vector_type(s); + auto b2 = vector_type(s); + auto c1 = vector_type(s); + auto c2 = vector_type(s); + + auto wa = strides_type(n); + + init(a); + + // so wie last-order. + for(auto i = size_type(0), j = p; i < n.size(); ++i, --j) + pi[i] = j; + + auto nc = typename extents_type::base_type (p); + for(auto i = 0u; i < p; ++i) + nc[pi[i]-1] = n[i]; + + auto wc = strides_type(extents_type(nc)); + auto wc_pi = typename strides_type::base_type (p); + for(auto i = 0u; i < p; ++i) + wc_pi[pi[i]-1] = wc[i]; + + ublas::copy ( p, n.data(), c1.data(), wc_pi.data(), a.data(), wa.data()); + ublas::trans( p, n.data(), pi.data(), c2.data(), wc.data(), a.data(), wa.data() ); + + if(!std::is_compound_v<value_type>) + for(auto i = 0ul; i < s; ++i) + BOOST_CHECK_EQUAL( c1[i], c2[i] ); + + + auto nb = typename extents_type::base_type (p); + for(auto i = 0u; i < p; ++i) + nb[pi[i]-1] = nc[i]; + + auto wb = strides_type (extents_type(nb)); + auto wb_pi = typename strides_type::base_type (p); + for(auto i = 0u; i < p; ++i) + wb_pi[pi[i]-1] = wb[i]; + + ublas::copy ( p, nc.data(), b1.data(), wb_pi.data(), c1.data(), wc.data()); + ublas::trans( p, nc.data(), pi.data(), b2.data(), wb.data(), c2.data(), wc.data() ); + + if(!std::is_compound_v<value_type>) + for(auto i = 0ul; i < s; ++i) + BOOST_CHECK_EQUAL( b1[i], b2[i] ); + + for(auto i = 0ul; i < s; ++i) + BOOST_CHECK_EQUAL( a[i], b2[i] ); + + } +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_einstein_notation.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_einstein_notation.cpp new file mode 100644 index 000000000..b0326c80c --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_einstein_notation.cpp @@ -0,0 +1,122 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// +// And we acknowledge the support from all contributors. + + +#include <iostream> +#include <algorithm> +#include <boost/numeric/ublas/tensor.hpp> + +#include <boost/test/unit_test.hpp> + +#include "utility.hpp" + +BOOST_AUTO_TEST_SUITE ( test_einstein_notation, * boost::unit_test::depends_on("test_multi_index") ) + + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + +//using test_types = zip<int>::with_t<boost::numeric::ublas::first_order>; + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_einstein_multiplication, value, test_types ) +{ + using namespace boost::numeric::ublas; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = tensor<value_type,layout_type>; + using namespace boost::numeric::ublas::index; + + { + auto A = tensor_type{5,3}; + auto B = tensor_type{3,4}; + // auto C = tensor_type{4,5,6}; + + for(auto j = 0u; j < A.extents().at(1); ++j) + for(auto i = 0u; i < A.extents().at(0); ++i) + A.at( i,j ) = value_type(i+1); + + for(auto j = 0u; j < B.extents().at(1); ++j) + for(auto i = 0u; i < B.extents().at(0); ++i) + B.at( i,j ) = value_type(i+1); + + + + auto AB = A(_,_e) * B(_e,_); + + // std::cout << "A = " << A << std::endl; + // std::cout << "B = " << B << std::endl; + // std::cout << "AB = " << AB << std::endl; + + for(auto j = 0u; j < AB.extents().at(1); ++j) + for(auto i = 0u; i < AB.extents().at(0); ++i) + BOOST_CHECK_EQUAL( AB.at( i,j ) , value_type(A.at( i,0 ) * ( B.extents().at(0) * (B.extents().at(0)+1) / 2 )) ); + + + } + + + { + auto A = tensor_type{4,5,3}; + auto B = tensor_type{3,4,2}; + + for(auto k = 0u; k < A.extents().at(2); ++k) + for(auto j = 0u; j < A.extents().at(1); ++j) + for(auto i = 0u; i < A.extents().at(0); ++i) + A.at( i,j,k ) = value_type(i+1); + + for(auto k = 0u; k < B.extents().at(2); ++k) + for(auto j = 0u; j < B.extents().at(1); ++j) + for(auto i = 0u; i < B.extents().at(0); ++i) + B.at( i,j,k ) = value_type(i+1); + + auto AB = A(_d,_,_f) * B(_f,_d,_); + + // std::cout << "A = " << A << std::endl; + // std::cout << "B = " << B << std::endl; + // std::cout << "AB = " << AB << std::endl; + // n*(n+1)/2; + auto const nf = ( B.extents().at(0) * (B.extents().at(0)+1) / 2 ); + auto const nd = ( A.extents().at(0) * (A.extents().at(0)+1) / 2 ); + + for(auto j = 0u; j < AB.extents().at(1); ++j) + for(auto i = 0u; i < AB.extents().at(0); ++i) + BOOST_CHECK_EQUAL( AB.at( i,j ) , value_type(nf * nd) ); + + } + + + { + auto A = tensor_type{4,3}; + auto B = tensor_type{3,4,2}; + + for(auto j = 0u; j < A.extents().at(1); ++j) + for(auto i = 0u; i < A.extents().at(0); ++i) + A.at( i,j ) = value_type(i+1); + + for(auto k = 0u; k < B.extents().at(2); ++k) + for(auto j = 0u; j < B.extents().at(1); ++j) + for(auto i = 0u; i < B.extents().at(0); ++i) + B.at( i,j,k ) = value_type(i+1); + + auto AB = A(_d,_f) * B(_f,_d,_); + + // n*(n+1)/2; + auto const nf = ( B.extents().at(0) * (B.extents().at(0)+1) / 2 ); + auto const nd = ( A.extents().at(0) * (A.extents().at(0)+1) / 2 ); + + for(auto i = 0u; i < AB.extents().at(0); ++i) + BOOST_CHECK_EQUAL ( AB.at( i ) , value_type(nf * nd) ); + + } +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_expression.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_expression.cpp new file mode 100644 index 000000000..ae3ce2050 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_expression.cpp @@ -0,0 +1,170 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + + + +#include <boost/numeric/ublas/tensor/expression.hpp> +#include <boost/numeric/ublas/tensor/tensor.hpp> +#include <boost/test/unit_test.hpp> +#include "utility.hpp" + +#include <functional> +#include <complex> + + + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + + +struct fixture +{ + using extents_type = boost::numeric::ublas::shape; + fixture() + : extents { + extents_type{}, // 0 + + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{1,2,3}, // 6 + extents_type{1,1,2,3}, // 7 + extents_type{1,2,3,1,1}, // 8 + + extents_type{4,2,3}, // 9 + extents_type{4,2,1,3}, // 10 + extents_type{4,2,1,3,1}, // 11 + extents_type{1,4,2,1,3,1} } // 12 + { + } + std::vector<extents_type> extents; +}; + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_expression_access, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using tensor_expression_type = typename tensor_type::super_type; + + + for(auto const& e : extents) { + + auto v = value_type{}; + auto t = tensor_type(e); + + for(auto& tt: t){ tt = v; v+=value_type{1}; } + const auto& tensor_expression_const = static_cast<tensor_expression_type const&>( t ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( tensor_expression_const()(i), t(i) ); + + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_unary_expression, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto uplus1 = std::bind( std::plus<value_type>{}, std::placeholders::_1, value_type(1) ); + + for(auto const& e : extents) { + + auto t = tensor_type(e); + auto v = value_type{}; + for(auto& tt: t) { tt = v; v+=value_type{1}; } + + const auto uexpr = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus1 ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( uexpr(i), uplus1(t(i)) ); + + auto uexpr_uexpr = ublas::detail::make_unary_tensor_expression<tensor_type>( uexpr, uplus1 ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( uexpr_uexpr(i), uplus1(uplus1(t(i))) ); + + const auto & uexpr_e = uexpr.e; + + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(uexpr_e) >, tensor_type > ) ); + + const auto & uexpr_uexpr_e_e = uexpr_uexpr.e.e; + + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(uexpr_uexpr_e_e) >, tensor_type > ) ); + + + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_binary_expression, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto uplus1 = std::bind( std::plus<value_type>{}, std::placeholders::_1, value_type(1) ); + auto uplus2 = std::bind( std::plus<value_type>{}, std::placeholders::_1, value_type(2) ); + auto bplus = std::plus <value_type>{}; + auto bminus = std::minus<value_type>{}; + + for(auto const& e : extents) { + + auto t = tensor_type(e); + auto v = value_type{}; + for(auto& tt: t){ tt = v; v+=value_type{1}; } + + auto uexpr1 = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus1 ); + auto uexpr2 = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus2 ); + + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(uexpr1.e) >, tensor_type > ) ); + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(uexpr2.e) >, tensor_type > ) ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( uexpr1(i), uplus1(t(i)) ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( uexpr2(i), uplus2(t(i)) ); + + auto bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( uexpr1, uexpr2, bplus ); + + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(bexpr_uexpr.el.e) >, tensor_type > ) ); + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(bexpr_uexpr.er.e) >, tensor_type > ) ); + + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( bexpr_uexpr(i), bplus(uexpr1(i),uexpr2(i)) ); + + auto bexpr_bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( bexpr_uexpr, t, bminus ); + + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(bexpr_bexpr_uexpr.el.el.e) >, tensor_type > ) ); + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(bexpr_bexpr_uexpr.el.er.e) >, tensor_type > ) ); + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(bexpr_bexpr_uexpr.er) >, tensor_type > ) ); + BOOST_CHECK( ( std::is_same_v< std::decay_t< decltype(bexpr_bexpr_uexpr.er) >, tensor_type > ) ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( bexpr_bexpr_uexpr(i), bminus(bexpr_uexpr(i),t(i)) ); + + } + + +} diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_expression_evaluation.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_expression_evaluation.cpp new file mode 100644 index 000000000..002d51a2b --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_expression_evaluation.cpp @@ -0,0 +1,240 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + + +#include <boost/numeric/ublas/tensor/expression_evaluation.hpp> +#include <boost/numeric/ublas/tensor/expression.hpp> +#include <boost/numeric/ublas/tensor/tensor.hpp> +#include <boost/test/unit_test.hpp> +#include "utility.hpp" + +#include <functional> + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + + +struct fixture +{ + using extents_type = boost::numeric::ublas::shape; + fixture() + : extents{ + extents_type{}, // 0 + + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{1,2,3}, // 6 + extents_type{1,1,2,3}, // 7 + extents_type{1,2,3,1,1}, // 8 + + extents_type{4,2,3}, // 9 + extents_type{4,2,1,3}, // 10 + extents_type{4,2,1,3,1}, // 11 + extents_type{1,4,2,1,3,1}} // 12 + { + } + std::vector<extents_type> extents; +}; + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_expression_retrieve_extents, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto uplus1 = std::bind( std::plus<value_type>{}, std::placeholders::_1, value_type(1) ); + auto uplus2 = std::bind( std::plus<value_type>{}, value_type(2), std::placeholders::_2 ); + auto bplus = std::plus <value_type>{}; + auto bminus = std::minus<value_type>{}; + + for(auto const& e : extents) { + + auto t = tensor_type(e); + auto v = value_type{}; + for(auto& tt: t){ tt = v; v+=value_type{1}; } + + + BOOST_CHECK( ublas::detail::retrieve_extents( t ) == e ); + + + // uexpr1 = t+1 + // uexpr2 = 2+t + auto uexpr1 = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus1 ); + auto uexpr2 = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus2 ); + + BOOST_CHECK( ublas::detail::retrieve_extents( uexpr1 ) == e ); + BOOST_CHECK( ublas::detail::retrieve_extents( uexpr2 ) == e ); + + // bexpr_uexpr = (t+1) + (2+t) + auto bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( uexpr1, uexpr2, bplus ); + + BOOST_CHECK( ublas::detail::retrieve_extents( bexpr_uexpr ) == e ); + + + // bexpr_bexpr_uexpr = ((t+1) + (2+t)) - t + auto bexpr_bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( bexpr_uexpr, t, bminus ); + + BOOST_CHECK( ublas::detail::retrieve_extents( bexpr_bexpr_uexpr ) == e ); + + } + + + for(auto i = 0u; i < extents.size()-1; ++i) + { + + auto v = value_type{}; + + auto t1 = tensor_type(extents[i]); + for(auto& tt: t1){ tt = v; v+=value_type{1}; } + + auto t2 = tensor_type(extents[i+1]); + for(auto& tt: t2){ tt = v; v+=value_type{2}; } + + BOOST_CHECK( ublas::detail::retrieve_extents( t1 ) != ublas::detail::retrieve_extents( t2 ) ); + + // uexpr1 = t1+1 + // uexpr2 = 2+t2 + auto uexpr1 = ublas::detail::make_unary_tensor_expression<tensor_type>( t1, uplus1 ); + auto uexpr2 = ublas::detail::make_unary_tensor_expression<tensor_type>( t2, uplus2 ); + + BOOST_CHECK( ublas::detail::retrieve_extents( t1 ) == ublas::detail::retrieve_extents( uexpr1 ) ); + BOOST_CHECK( ublas::detail::retrieve_extents( t2 ) == ublas::detail::retrieve_extents( uexpr2 ) ); + BOOST_CHECK( ublas::detail::retrieve_extents( uexpr1 ) != ublas::detail::retrieve_extents( uexpr2 ) ); + + // bexpr_uexpr = (t1+1) + (2+t2) + auto bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( uexpr1, uexpr2, bplus ); + + BOOST_CHECK( ublas::detail::retrieve_extents( bexpr_uexpr ) == ublas::detail::retrieve_extents(t1) ); + + + // bexpr_bexpr_uexpr = ((t1+1) + (2+t2)) - t2 + auto bexpr_bexpr_uexpr1 = ublas::detail::make_binary_tensor_expression<tensor_type>( bexpr_uexpr, t2, bminus ); + + BOOST_CHECK( ublas::detail::retrieve_extents( bexpr_bexpr_uexpr1 ) == ublas::detail::retrieve_extents(t2) ); + + + // bexpr_bexpr_uexpr = t2 - ((t1+1) + (2+t2)) + auto bexpr_bexpr_uexpr2 = ublas::detail::make_binary_tensor_expression<tensor_type>( t2, bexpr_uexpr, bminus ); + + BOOST_CHECK( ublas::detail::retrieve_extents( bexpr_bexpr_uexpr2 ) == ublas::detail::retrieve_extents(t2) ); + } +} + + + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_expression_all_extents_equal, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto uplus1 = std::bind( std::plus<value_type>{}, std::placeholders::_1, value_type(1) ); + auto uplus2 = std::bind( std::plus<value_type>{}, value_type(2), std::placeholders::_2 ); + auto bplus = std::plus <value_type>{}; + auto bminus = std::minus<value_type>{}; + + for(auto const& e : extents) { + + auto t = tensor_type(e); + auto v = value_type{}; + for(auto& tt: t){ tt = v; v+=value_type{1}; } + + + BOOST_CHECK( ublas::detail::all_extents_equal( t , e ) ); + + + // uexpr1 = t+1 + // uexpr2 = 2+t + auto uexpr1 = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus1 ); + auto uexpr2 = ublas::detail::make_unary_tensor_expression<tensor_type>( t, uplus2 ); + + BOOST_CHECK( ublas::detail::all_extents_equal( uexpr1, e ) ); + BOOST_CHECK( ublas::detail::all_extents_equal( uexpr2, e ) ); + + // bexpr_uexpr = (t+1) + (2+t) + auto bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( uexpr1, uexpr2, bplus ); + + BOOST_CHECK( ublas::detail::all_extents_equal( bexpr_uexpr, e ) ); + + + // bexpr_bexpr_uexpr = ((t+1) + (2+t)) - t + auto bexpr_bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( bexpr_uexpr, t, bminus ); + + BOOST_CHECK( ublas::detail::all_extents_equal( bexpr_bexpr_uexpr , e ) ); + + } + + + for(auto i = 0u; i < extents.size()-1; ++i) + { + + auto v = value_type{}; + + auto t1 = tensor_type(extents[i]); + for(auto& tt: t1){ tt = v; v+=value_type{1}; } + + auto t2 = tensor_type(extents[i+1]); + for(auto& tt: t2){ tt = v; v+=value_type{2}; } + + BOOST_CHECK( ublas::detail::all_extents_equal( t1, ublas::detail::retrieve_extents(t1) ) ); + BOOST_CHECK( ublas::detail::all_extents_equal( t2, ublas::detail::retrieve_extents(t2) ) ); + + // uexpr1 = t1+1 + // uexpr2 = 2+t2 + auto uexpr1 = ublas::detail::make_unary_tensor_expression<tensor_type>( t1, uplus1 ); + auto uexpr2 = ublas::detail::make_unary_tensor_expression<tensor_type>( t2, uplus2 ); + + BOOST_CHECK( ublas::detail::all_extents_equal( uexpr1, ublas::detail::retrieve_extents(uexpr1) ) ); + BOOST_CHECK( ublas::detail::all_extents_equal( uexpr2, ublas::detail::retrieve_extents(uexpr2) ) ); + + // bexpr_uexpr = (t1+1) + (2+t2) + auto bexpr_uexpr = ublas::detail::make_binary_tensor_expression<tensor_type>( uexpr1, uexpr2, bplus ); + + BOOST_CHECK( ! ublas::detail::all_extents_equal( bexpr_uexpr, ublas::detail::retrieve_extents( bexpr_uexpr ) ) ); + + // bexpr_bexpr_uexpr = ((t1+1) + (2+t2)) - t2 + auto bexpr_bexpr_uexpr1 = ublas::detail::make_binary_tensor_expression<tensor_type>( bexpr_uexpr, t2, bminus ); + + BOOST_CHECK( ! ublas::detail::all_extents_equal( bexpr_bexpr_uexpr1, ublas::detail::retrieve_extents( bexpr_bexpr_uexpr1 ) ) ); + + // bexpr_bexpr_uexpr = t2 - ((t1+1) + (2+t2)) + auto bexpr_bexpr_uexpr2 = ublas::detail::make_binary_tensor_expression<tensor_type>( t2, bexpr_uexpr, bminus ); + + BOOST_CHECK( ! ublas::detail::all_extents_equal( bexpr_bexpr_uexpr2, ublas::detail::retrieve_extents( bexpr_bexpr_uexpr2 ) ) ); + + + // bexpr_uexpr2 = (t1+1) + t2 + auto bexpr_uexpr2 = ublas::detail::make_binary_tensor_expression<tensor_type>( uexpr1, t2, bplus ); + BOOST_CHECK( ! ublas::detail::all_extents_equal( bexpr_uexpr2, ublas::detail::retrieve_extents( bexpr_uexpr2 ) ) ); + + + // bexpr_uexpr2 = ((t1+1) + t2) + t1 + auto bexpr_bexpr_uexpr3 = ublas::detail::make_binary_tensor_expression<tensor_type>( bexpr_uexpr2, t1, bplus ); + BOOST_CHECK( ! ublas::detail::all_extents_equal( bexpr_bexpr_uexpr3, ublas::detail::retrieve_extents( bexpr_bexpr_uexpr3 ) ) ); + + // bexpr_uexpr2 = t1 + (((t1+1) + t2) + t1) + auto bexpr_bexpr_uexpr4 = ublas::detail::make_binary_tensor_expression<tensor_type>( t1, bexpr_bexpr_uexpr3, bplus ); + BOOST_CHECK( ! ublas::detail::all_extents_equal( bexpr_bexpr_uexpr4, ublas::detail::retrieve_extents( bexpr_bexpr_uexpr4 ) ) ); + + } +} diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_extents.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_extents.cpp new file mode 100644 index 000000000..9fbeee949 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_extents.cpp @@ -0,0 +1,449 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/test/unit_test.hpp> +#include <boost/numeric/ublas/tensor/extents.hpp> +#include <vector> + +BOOST_AUTO_TEST_SUITE ( test_extents ) + + +//*boost::unit_test::label("extents") +//*boost::unit_test::label("constructor") + +BOOST_AUTO_TEST_CASE(test_extents_ctor) +{ + using namespace boost::numeric; + using extents = ublas::basic_extents<unsigned>; + + + auto e0 = extents{}; + BOOST_CHECK( e0.empty()); + BOOST_CHECK_EQUAL ( e0.size(),0); + + auto e1 = extents{1,1}; + BOOST_CHECK(!e1.empty()); + BOOST_CHECK_EQUAL ( e1.size(),2); + + auto e2 = extents{1,2}; + BOOST_CHECK(!e2.empty()); + BOOST_CHECK_EQUAL ( e2.size(),2); + + auto e3 = extents{2,1}; + BOOST_CHECK (!e3.empty()); + BOOST_CHECK_EQUAL ( e3.size(),2); + + auto e4 = extents{2,3}; + BOOST_CHECK(!e4.empty()); + BOOST_CHECK_EQUAL ( e4.size(),2); + + auto e5 = extents{2,3,1}; + BOOST_CHECK (!e5.empty()); + BOOST_CHECK_EQUAL ( e5.size(),3); + + auto e6 = extents{1,2,3}; // 6 + BOOST_CHECK(!e6.empty()); + BOOST_CHECK_EQUAL ( e6.size(),3); + + auto e7 = extents{4,2,3}; // 7 + BOOST_CHECK(!e7.empty()); + BOOST_CHECK_EQUAL ( e7.size(),3); + + BOOST_CHECK_THROW( extents({1,0}), std::length_error ); + BOOST_CHECK_THROW( extents({0} ), std::length_error ); + BOOST_CHECK_THROW( extents({3} ), std::length_error ); + BOOST_CHECK_THROW( extents({0,1}), std::length_error ); +} + + + + +struct fixture { + using extents_type = boost::numeric::ublas::basic_extents<unsigned>; + fixture() : extents{ + extents_type{}, // 0 + + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{1,2,3}, // 6 + extents_type{1,1,2,3}, // 7 + extents_type{1,2,3,1,1}, // 8 + + extents_type{4,2,3}, // 9 + extents_type{4,2,1,3}, // 10 + extents_type{4,2,1,3,1}, // 11 + extents_type{1,4,2,1,3,1}, // 12 +} // 13 + {} + std::vector<extents_type> extents; +}; + +BOOST_FIXTURE_TEST_CASE(test_extents_access, fixture, *boost::unit_test::label("extents") *boost::unit_test::label("access")) +{ + using namespace boost::numeric; + + BOOST_REQUIRE_EQUAL(extents.size(),13); + + BOOST_CHECK_EQUAL (extents[ 0].size(), 0); + BOOST_CHECK (extents[ 0].empty() ); + + BOOST_REQUIRE_EQUAL(extents[ 1].size(), 2); + BOOST_REQUIRE_EQUAL(extents[ 2].size(), 2); + BOOST_REQUIRE_EQUAL(extents[ 3].size(), 2); + BOOST_REQUIRE_EQUAL(extents[ 4].size(), 2); + BOOST_REQUIRE_EQUAL(extents[ 5].size(), 3); + BOOST_REQUIRE_EQUAL(extents[ 6].size(), 3); + BOOST_REQUIRE_EQUAL(extents[ 7].size(), 4); + BOOST_REQUIRE_EQUAL(extents[ 8].size(), 5); + BOOST_REQUIRE_EQUAL(extents[ 9].size(), 3); + BOOST_REQUIRE_EQUAL(extents[10].size(), 4); + BOOST_REQUIRE_EQUAL(extents[11].size(), 5); + BOOST_REQUIRE_EQUAL(extents[12].size(), 6); + + + BOOST_CHECK_EQUAL(extents[1][0],1); + BOOST_CHECK_EQUAL(extents[1][1],1); + + BOOST_CHECK_EQUAL(extents[2][0],1); + BOOST_CHECK_EQUAL(extents[2][1],2); + + BOOST_CHECK_EQUAL(extents[3][0],2); + BOOST_CHECK_EQUAL(extents[3][1],1); + + BOOST_CHECK_EQUAL(extents[4][0],2); + BOOST_CHECK_EQUAL(extents[4][1],3); + + BOOST_CHECK_EQUAL(extents[5][0],2); + BOOST_CHECK_EQUAL(extents[5][1],3); + BOOST_CHECK_EQUAL(extents[5][2],1); + + BOOST_CHECK_EQUAL(extents[6][0],1); + BOOST_CHECK_EQUAL(extents[6][1],2); + BOOST_CHECK_EQUAL(extents[6][2],3); + + BOOST_CHECK_EQUAL(extents[7][0],1); + BOOST_CHECK_EQUAL(extents[7][1],1); + BOOST_CHECK_EQUAL(extents[7][2],2); + BOOST_CHECK_EQUAL(extents[7][3],3); + + BOOST_CHECK_EQUAL(extents[8][0],1); + BOOST_CHECK_EQUAL(extents[8][1],2); + BOOST_CHECK_EQUAL(extents[8][2],3); + BOOST_CHECK_EQUAL(extents[8][3],1); + BOOST_CHECK_EQUAL(extents[8][4],1); + + BOOST_CHECK_EQUAL(extents[9][0],4); + BOOST_CHECK_EQUAL(extents[9][1],2); + BOOST_CHECK_EQUAL(extents[9][2],3); + + BOOST_CHECK_EQUAL(extents[10][0],4); + BOOST_CHECK_EQUAL(extents[10][1],2); + BOOST_CHECK_EQUAL(extents[10][2],1); + BOOST_CHECK_EQUAL(extents[10][3],3); + + BOOST_CHECK_EQUAL(extents[11][0],4); + BOOST_CHECK_EQUAL(extents[11][1],2); + BOOST_CHECK_EQUAL(extents[11][2],1); + BOOST_CHECK_EQUAL(extents[11][3],3); + BOOST_CHECK_EQUAL(extents[11][4],1); + + BOOST_CHECK_EQUAL(extents[12][0],1); + BOOST_CHECK_EQUAL(extents[12][1],4); + BOOST_CHECK_EQUAL(extents[12][2],2); + BOOST_CHECK_EQUAL(extents[12][3],1); + BOOST_CHECK_EQUAL(extents[12][4],3); + BOOST_CHECK_EQUAL(extents[12][5],1); +} + +BOOST_FIXTURE_TEST_CASE(test_extents_copy_ctor, fixture, *boost::unit_test::label("extents") *boost::unit_test::label("copy_ctor")) +{ + BOOST_REQUIRE_EQUAL(extents.size(),13); + + auto e0 = extents[ 0]; // {} + auto e1 = extents[ 1]; // {1,1} + auto e2 = extents[ 2]; // {1,2} + auto e3 = extents[ 3]; // {2,1} + auto e4 = extents[ 4]; // {2,3} + auto e5 = extents[ 5]; // {2,3,1} + auto e6 = extents[ 6]; // {1,2,3} + auto e7 = extents[ 7]; // {1,1,2,3} + auto e8 = extents[ 8]; // {1,2,3,1,1} + auto e9 = extents[ 9]; // {4,2,3} + auto e10 = extents[10]; // {4,2,1,3} + auto e11 = extents[11]; // {4,2,1,3,1} + auto e12 = extents[12]; // {1,4,2,1,3,1} + + BOOST_CHECK_EQUAL (e0.size(), 0); + BOOST_CHECK (e0.empty() ); + + BOOST_REQUIRE_EQUAL(e1 .size(), 2); + BOOST_REQUIRE_EQUAL(e2 .size(), 2); + BOOST_REQUIRE_EQUAL(e3 .size(), 2); + BOOST_REQUIRE_EQUAL(e4 .size(), 2); + BOOST_REQUIRE_EQUAL(e5 .size(), 3); + BOOST_REQUIRE_EQUAL(e6 .size(), 3); + BOOST_REQUIRE_EQUAL(e7 .size(), 4); + BOOST_REQUIRE_EQUAL(e8 .size(), 5); + BOOST_REQUIRE_EQUAL(e9 .size(), 3); + BOOST_REQUIRE_EQUAL(e10.size(), 4); + BOOST_REQUIRE_EQUAL(e11.size(), 5); + BOOST_REQUIRE_EQUAL(e12.size(), 6); + + + BOOST_CHECK_EQUAL(e1[0],1); + BOOST_CHECK_EQUAL(e1[1],1); + + BOOST_CHECK_EQUAL(e2[0],1); + BOOST_CHECK_EQUAL(e2[1],2); + + BOOST_CHECK_EQUAL(e3[0],2); + BOOST_CHECK_EQUAL(e3[1],1); + + BOOST_CHECK_EQUAL(e4[0],2); + BOOST_CHECK_EQUAL(e4[1],3); + + BOOST_CHECK_EQUAL(e5[0],2); + BOOST_CHECK_EQUAL(e5[1],3); + BOOST_CHECK_EQUAL(e5[2],1); + + BOOST_CHECK_EQUAL(e6[0],1); + BOOST_CHECK_EQUAL(e6[1],2); + BOOST_CHECK_EQUAL(e6[2],3); + + BOOST_CHECK_EQUAL(e7[0],1); + BOOST_CHECK_EQUAL(e7[1],1); + BOOST_CHECK_EQUAL(e7[2],2); + BOOST_CHECK_EQUAL(e7[3],3); + + BOOST_CHECK_EQUAL(e8[0],1); + BOOST_CHECK_EQUAL(e8[1],2); + BOOST_CHECK_EQUAL(e8[2],3); + BOOST_CHECK_EQUAL(e8[3],1); + BOOST_CHECK_EQUAL(e8[4],1); + + BOOST_CHECK_EQUAL(e9[0],4); + BOOST_CHECK_EQUAL(e9[1],2); + BOOST_CHECK_EQUAL(e9[2],3); + + BOOST_CHECK_EQUAL(e10[0],4); + BOOST_CHECK_EQUAL(e10[1],2); + BOOST_CHECK_EQUAL(e10[2],1); + BOOST_CHECK_EQUAL(e10[3],3); + + BOOST_CHECK_EQUAL(e11[0],4); + BOOST_CHECK_EQUAL(e11[1],2); + BOOST_CHECK_EQUAL(e11[2],1); + BOOST_CHECK_EQUAL(e11[3],3); + BOOST_CHECK_EQUAL(e11[4],1); + + BOOST_CHECK_EQUAL(e12[0],1); + BOOST_CHECK_EQUAL(e12[1],4); + BOOST_CHECK_EQUAL(e12[2],2); + BOOST_CHECK_EQUAL(e12[3],1); + BOOST_CHECK_EQUAL(e12[4],3); + BOOST_CHECK_EQUAL(e12[5],1); + +} + +BOOST_FIXTURE_TEST_CASE(test_extents_is, fixture, *boost::unit_test::label("extents") *boost::unit_test::label("query")) +{ + BOOST_REQUIRE_EQUAL(extents.size(),13); + + auto e0 = extents[ 0]; // {} + auto e1 = extents[ 1]; // {1,1} + auto e2 = extents[ 2]; // {1,2} + auto e3 = extents[ 3]; // {2,1} + auto e4 = extents[ 4]; // {2,3} + auto e5 = extents[ 5]; // {2,3,1} + auto e6 = extents[ 6]; // {1,2,3} + auto e7 = extents[ 7]; // {1,1,2,3} + auto e8 = extents[ 8]; // {1,2,3,1,1} + auto e9 = extents[ 9]; // {4,2,3} + auto e10 = extents[10]; // {4,2,1,3} + auto e11 = extents[11]; // {4,2,1,3,1} + auto e12 = extents[12]; // {1,4,2,1,3,1} + + BOOST_CHECK( e0.empty ()); + BOOST_CHECK( ! e0.is_scalar()); + BOOST_CHECK( ! e0.is_vector()); + BOOST_CHECK( ! e0.is_matrix()); + BOOST_CHECK( ! e0.is_tensor()); + + BOOST_CHECK( ! e1.empty () ); + BOOST_CHECK( e1.is_scalar() ); + BOOST_CHECK( ! e1.is_vector() ); + BOOST_CHECK( ! e1.is_matrix() ); + BOOST_CHECK( ! e1.is_tensor() ); + + BOOST_CHECK( ! e2.empty () ); + BOOST_CHECK( ! e2.is_scalar() ); + BOOST_CHECK( e2.is_vector() ); + BOOST_CHECK( ! e2.is_matrix() ); + BOOST_CHECK( ! e2.is_tensor() ); + + BOOST_CHECK( ! e3.empty () ); + BOOST_CHECK( ! e3.is_scalar() ); + BOOST_CHECK( e3.is_vector() ); + BOOST_CHECK( ! e3.is_matrix() ); + BOOST_CHECK( ! e3.is_tensor() ); + + BOOST_CHECK( ! e4.empty () ); + BOOST_CHECK( ! e4.is_scalar() ); + BOOST_CHECK( ! e4.is_vector() ); + BOOST_CHECK( e4.is_matrix() ); + BOOST_CHECK( ! e4.is_tensor() ); + + BOOST_CHECK( ! e5.empty () ); + BOOST_CHECK( ! e5.is_scalar() ); + BOOST_CHECK( ! e5.is_vector() ); + BOOST_CHECK( e5.is_matrix() ); + BOOST_CHECK( ! e5.is_tensor() ); + + BOOST_CHECK( ! e6.empty () ); + BOOST_CHECK( ! e6.is_scalar() ); + BOOST_CHECK( ! e6.is_vector() ); + BOOST_CHECK( ! e6.is_matrix() ); + BOOST_CHECK( e6.is_tensor() ); + + BOOST_CHECK( ! e7.empty () ); + BOOST_CHECK( ! e7.is_scalar() ); + BOOST_CHECK( ! e7.is_vector() ); + BOOST_CHECK( ! e7.is_matrix() ); + BOOST_CHECK( e7.is_tensor() ); + + BOOST_CHECK( ! e8.empty () ); + BOOST_CHECK( ! e8.is_scalar() ); + BOOST_CHECK( ! e8.is_vector() ); + BOOST_CHECK( ! e8.is_matrix() ); + BOOST_CHECK( e8.is_tensor() ); + + BOOST_CHECK( ! e9.empty () ); + BOOST_CHECK( ! e9.is_scalar() ); + BOOST_CHECK( ! e9.is_vector() ); + BOOST_CHECK( ! e9.is_matrix() ); + BOOST_CHECK( e9.is_tensor() ); + + BOOST_CHECK( ! e10.empty () ); + BOOST_CHECK( ! e10.is_scalar() ); + BOOST_CHECK( ! e10.is_vector() ); + BOOST_CHECK( ! e10.is_matrix() ); + BOOST_CHECK( e10.is_tensor() ); + + BOOST_CHECK( ! e11.empty () ); + BOOST_CHECK( ! e11.is_scalar() ); + BOOST_CHECK( ! e11.is_vector() ); + BOOST_CHECK( ! e11.is_matrix() ); + BOOST_CHECK( e11.is_tensor() ); + + BOOST_CHECK( ! e12.empty () ); + BOOST_CHECK( ! e12.is_scalar() ); + BOOST_CHECK( ! e12.is_vector() ); + BOOST_CHECK( ! e12.is_matrix() ); + BOOST_CHECK( e12.is_tensor() ); +} + + +BOOST_FIXTURE_TEST_CASE(test_extents_squeeze, fixture, *boost::unit_test::label("extents") *boost::unit_test::label("squeeze")) +{ + BOOST_REQUIRE_EQUAL(extents.size(),13); + + auto e0 = extents[ 0].squeeze(); // {} + auto e1 = extents[ 1].squeeze(); // {1,1} + auto e2 = extents[ 2].squeeze(); // {1,2} + auto e3 = extents[ 3].squeeze(); // {2,1} + + auto e4 = extents[ 4].squeeze(); // {2,3} + auto e5 = extents[ 5].squeeze(); // {2,3} + auto e6 = extents[ 6].squeeze(); // {2,3} + auto e7 = extents[ 7].squeeze(); // {2,3} + auto e8 = extents[ 8].squeeze(); // {2,3} + + auto e9 = extents[ 9].squeeze(); // {4,2,3} + auto e10 = extents[10].squeeze(); // {4,2,3} + auto e11 = extents[11].squeeze(); // {4,2,3} + auto e12 = extents[12].squeeze(); // {4,2,3} + + BOOST_CHECK( (e0 == extents_type{} ) ); + BOOST_CHECK( (e1 == extents_type{1,1}) ); + BOOST_CHECK( (e2 == extents_type{1,2}) ); + BOOST_CHECK( (e3 == extents_type{2,1}) ); + + BOOST_CHECK( (e4 == extents_type{2,3}) ); + BOOST_CHECK( (e5 == extents_type{2,3}) ); + BOOST_CHECK( (e6 == extents_type{2,3}) ); + BOOST_CHECK( (e7 == extents_type{2,3}) ); + BOOST_CHECK( (e8 == extents_type{2,3}) ); + + BOOST_CHECK( (e9 == extents_type{4,2,3}) ); + BOOST_CHECK( (e10 == extents_type{4,2,3}) ); + BOOST_CHECK( (e11 == extents_type{4,2,3}) ); + BOOST_CHECK( (e12 == extents_type{4,2,3}) ); + +} + + +BOOST_FIXTURE_TEST_CASE(test_extents_valid, fixture, *boost::unit_test::label("extents") *boost::unit_test::label("valid")) +{ + + using namespace boost::numeric; + + BOOST_REQUIRE_EQUAL(extents.size(),13); + + for(auto const& e : extents){ + if(e.empty()) + BOOST_CHECK_EQUAL(e.valid(),false); + else + BOOST_CHECK_EQUAL(e.valid(), true ); + } + + BOOST_CHECK_EQUAL( extents_type{}.valid() , false ); + + BOOST_CHECK_THROW( ublas::basic_extents<unsigned>({0,1}), std::length_error ); + BOOST_CHECK_THROW( ublas::basic_extents<unsigned>({1,0,1}), std::length_error ); + +} + + +BOOST_FIXTURE_TEST_CASE(test_extents_product, fixture, *boost::unit_test::label("extents") *boost::unit_test::label("product")) +{ + + auto e0 = extents[ 0].product(); // {} + auto e1 = extents[ 1].product(); // {1,1} + auto e2 = extents[ 2].product(); // {1,2} + auto e3 = extents[ 3].product(); // {2,1} + auto e4 = extents[ 4].product(); // {2,3} + auto e5 = extents[ 5].product(); // {2,3,1} + auto e6 = extents[ 6].product(); // {1,2,3} + auto e7 = extents[ 7].product(); // {1,1,2,3} + auto e8 = extents[ 8].product(); // {1,2,3,1,1} + auto e9 = extents[ 9].product(); // {4,2,3} + auto e10 = extents[10].product(); // {4,2,1,3} + auto e11 = extents[11].product(); // {4,2,1,3,1} + auto e12 = extents[12].product(); // {1,4,2,1,3,1} + + BOOST_CHECK_EQUAL( e0 , 0 ); + BOOST_CHECK_EQUAL( e1 , 1 ); + BOOST_CHECK_EQUAL( e2 , 2 ); + BOOST_CHECK_EQUAL( e3 , 2 ); + BOOST_CHECK_EQUAL( e4 , 6 ); + BOOST_CHECK_EQUAL( e5 , 6 ); + BOOST_CHECK_EQUAL( e6 , 6 ); + BOOST_CHECK_EQUAL( e7 , 6 ); + BOOST_CHECK_EQUAL( e8 , 6 ); + BOOST_CHECK_EQUAL( e9 , 24 ); + BOOST_CHECK_EQUAL( e10, 24 ); + BOOST_CHECK_EQUAL( e11, 24 ); + BOOST_CHECK_EQUAL( e12, 24 ); + + +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_functions.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_functions.cpp new file mode 100644 index 000000000..64ecda396 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_functions.cpp @@ -0,0 +1,453 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// +// And we acknowledge the support from all contributors. + + +#include <iostream> +#include <algorithm> +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> + +#include <boost/test/unit_test.hpp> + +#include "utility.hpp" + +BOOST_AUTO_TEST_SUITE ( test_tensor_functions, * boost::unit_test::depends_on("test_tensor_contraction") ) + + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + +//using test_types = zip<int>::with_t<boost::numeric::ublas::first_order>; + + +struct fixture +{ + using extents_type = boost::numeric::ublas::shape; + fixture() + : extents { + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{4,1,3}, // 6 + extents_type{1,2,3}, // 7 + extents_type{4,2,3}, // 8 + extents_type{4,2,3,5}} // 9 + { + } + std::vector<extents_type> extents; +}; + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_prod_vector, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + using vector_type = typename tensor_type::vector_type; + + + for(auto const& n : extents){ + + auto a = tensor_type(n, value_type{2}); + + for(auto m = 0u; m < n.size(); ++m){ + + auto b = vector_type (n[m], value_type{1} ); + + auto c = ublas::prod(a, b, m+1); + + for(auto i = 0u; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , value_type(n[m]) * a[i] ); + + } + } +} + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_prod_matrix, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + using matrix_type = typename tensor_type::matrix_type; + + + for(auto const& n : extents) { + + auto a = tensor_type(n, value_type{2}); + + for(auto m = 0u; m < n.size(); ++m){ + + auto b = matrix_type ( n[m], n[m], value_type{1} ); + + auto c = ublas::prod(a, b, m+1); + + for(auto i = 0u; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , value_type(n[m]) * a[i] ); + + } + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_prod_tensor_1, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + + // left-hand and right-hand side have the + // the same number of elements + + for(auto const& na : extents) { + + auto a = tensor_type( na, value_type{2} ); + auto b = tensor_type( na, value_type{3} ); + + auto const pa = a.rank(); + + // the number of contractions is changed. + for( auto q = 0ul; q <= pa; ++q) { // pa + + auto phi = std::vector<std::size_t> ( q ); + + std::iota(phi.begin(), phi.end(), 1ul); + + auto c = ublas::prod(a, b, phi); + + auto acc = value_type(1); + for(auto i = 0ul; i < q; ++i) + acc *= a.extents().at(phi.at(i)-1); + + for(auto i = 0ul; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , acc * a[0] * b[0] ); + + } + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_prod_tensor_2, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + + + auto compute_factorial = [](auto const& p){ + auto f = 1ul; + for(auto i = 1u; i <= p; ++i) + f *= i; + return f; + }; + + auto permute_extents = [](auto const& pi, auto const& na){ + auto nb = na; + assert(pi.size() == na.size()); + for(auto j = 0u; j < pi.size(); ++j) + nb[pi[j]-1] = na[j]; + return nb; + }; + + + // left-hand and right-hand side have the + // the same number of elements + + for(auto const& na : extents) { + + auto a = tensor_type( na, value_type{2} ); + auto const pa = a.rank(); + + + auto pi = std::vector<std::size_t>(pa); + auto fac = compute_factorial(pa); + std::iota( pi.begin(), pi.end(), 1 ); + + for(auto f = 0ul; f < fac; ++f) + { + auto nb = permute_extents( pi, na ); + auto b = tensor_type( nb, value_type{3} ); + + // the number of contractions is changed. + for( auto q = 0ul; q <= pa; ++q) { // pa + + auto phia = std::vector<std::size_t> ( q ); // concatenation for a + auto phib = std::vector<std::size_t> ( q ); // concatenation for b + + std::iota(phia.begin(), phia.end(), 1ul); + std::transform( phia.begin(), phia.end(), phib.begin(), + [&pi] ( std::size_t i ) { return pi.at(i-1); } ); + + auto c = ublas::prod(a, b, phia, phib); + + auto acc = value_type(1); + for(auto i = 0ul; i < q; ++i) + acc *= a.extents().at(phia.at(i)-1); + + for(auto i = 0ul; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , acc * a[0] * b[0] ); + + } + + std::next_permutation(pi.begin(), pi.end()); + } + } +} + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_inner_prod, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + + + for(auto const& n : extents) { + + auto a = tensor_type(n, value_type(2)); + auto b = tensor_type(n, value_type(1)); + + auto c = ublas::inner_prod(a, b); + auto r = std::inner_product(a.begin(),a.end(), b.begin(),value_type(0)); + + BOOST_CHECK_EQUAL( c , r ); + + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_norm, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + + + for(auto const& n : extents) { + + auto a = tensor_type(n); + + auto one = value_type(1); + auto v = one; + for(auto& aa: a) + aa = v, v += one; + + + auto c = ublas::inner_prod(a, a); + auto r = std::inner_product(a.begin(),a.end(), a.begin(),value_type(0)); + + auto r2 = ublas::norm( (a+a) / 2 ); + + BOOST_CHECK_EQUAL( c , r ); + BOOST_CHECK_EQUAL( std::sqrt( c ) , r2 ); + + } +} + + +BOOST_FIXTURE_TEST_CASE( test_tensor_real_imag_conj, fixture ) +{ + using namespace boost::numeric; + using value_type = float; + using complex_type = std::complex<value_type>; + using layout_type = ublas::first_order; + + using tensor_complex_type = ublas::tensor<complex_type,layout_type>; + using tensor_type = ublas::tensor<value_type,layout_type>; + + for(auto const& n : extents) { + + auto a = tensor_type(n); + auto r0 = tensor_type(n); + auto r00 = tensor_complex_type(n); + + + auto one = value_type(1); + auto v = one; + for(auto& aa: a) + aa = v, v += one; + + tensor_type b = (a+a) / value_type( 2 ); + tensor_type r1 = ublas::real( (a+a) / value_type( 2 ) ); + std::transform( b.begin(), b.end(), r0.begin(), [](auto const& l){ return std::real( l ); } ); + BOOST_CHECK( r0 == r1 ); + + tensor_type r2 = ublas::imag( (a+a) / value_type( 2 ) ); + std::transform( b.begin(), b.end(), r0.begin(), [](auto const& l){ return std::imag( l ); } ); + BOOST_CHECK( r0 == r2 ); + + tensor_complex_type r3 = ublas::conj( (a+a) / value_type( 2 ) ); + std::transform( b.begin(), b.end(), r00.begin(), [](auto const& l){ return std::conj( l ); } ); + BOOST_CHECK( r00 == r3 ); + + } + + for(auto const& n : extents) { + + + + + auto a = tensor_complex_type(n); + + auto r00 = tensor_complex_type(n); + auto r0 = tensor_type(n); + + + auto one = complex_type(1,1); + auto v = one; + for(auto& aa: a) + aa = v, v = v + one; + + tensor_complex_type b = (a+a) / complex_type( 2,2 ); + + + tensor_type r1 = ublas::real( (a+a) / complex_type( 2,2 ) ); + std::transform( b.begin(), b.end(), r0.begin(), [](auto const& l){ return std::real( l ); } ); + BOOST_CHECK( r0 == r1 ); + + tensor_type r2 = ublas::imag( (a+a) / complex_type( 2,2 ) ); + std::transform( b.begin(), b.end(), r0.begin(), [](auto const& l){ return std::imag( l ); } ); + BOOST_CHECK( r0 == r2 ); + + tensor_complex_type r3 = ublas::conj( (a+a) / complex_type( 2,2 ) ); + std::transform( b.begin(), b.end(), r00.begin(), [](auto const& l){ return std::conj( l ); } ); + BOOST_CHECK( r00 == r3 ); + + + + } + + + +} + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_outer_prod, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + + for(auto const& n1 : extents) { + auto a = tensor_type(n1, value_type(2)); + for(auto const& n2 : extents) { + + auto b = tensor_type(n2, value_type(1)); + auto c = ublas::outer_prod(a, b); + + for(auto const& cc : c) + BOOST_CHECK_EQUAL( cc , a[0]*b[0] ); + } + } +} + + + +template<class V> +void init(std::vector<V>& a) +{ + auto v = V(1); + for(auto i = 0u; i < a.size(); ++i, ++v){ + a[i] = v; + } +} + +template<class V> +void init(std::vector<std::complex<V>>& a) +{ + auto v = std::complex<V>(1,1); + for(auto i = 0u; i < a.size(); ++i){ + a[i] = v; + v.real(v.real()+1); + v.imag(v.imag()+1); + } +} + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_trans, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type,layout_type>; + + auto fak = [](auto const& p){ + auto f = 1ul; + for(auto i = 1u; i <= p; ++i) + f *= i; + return f; + }; + + auto inverse = [](auto const& pi){ + auto pi_inv = pi; + for(auto j = 0u; j < pi.size(); ++j) + pi_inv[pi[j]-1] = j+1; + return pi_inv; + }; + + for(auto const& n : extents) + { + auto const p = n.size(); + auto const s = n.product(); + auto aref = tensor_type(n); + auto v = value_type{}; + for(auto i = 0u; i < s; ++i, v+=1) + aref[i] = v; + auto a = aref; + + + auto pi = std::vector<std::size_t>(p); + std::iota(pi.begin(), pi.end(), 1); + a = ublas::trans( a, pi ); + BOOST_CHECK( a == aref ); + + + auto const pfak = fak(p); + auto i = 0u; + for(; i < pfak-1; ++i) { + std::next_permutation(pi.begin(), pi.end()); + a = ublas::trans( a, pi ); + } + std::next_permutation(pi.begin(), pi.end()); + for(; i > 0; --i) { + std::prev_permutation(pi.begin(), pi.end()); + auto pi_inv = inverse(pi); + a = ublas::trans( a, pi_inv ); + } + + BOOST_CHECK( a == aref ); + + } +} + + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_multi_index.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_multi_index.cpp new file mode 100644 index 000000000..d6448de22 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_multi_index.cpp @@ -0,0 +1,146 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + +#include <iostream> +#include <algorithm> +#include <complex> +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/numeric/ublas/tensor/multi_index.hpp> + + +#include <boost/test/unit_test.hpp> + +#include "utility.hpp" + + +BOOST_AUTO_TEST_SUITE ( test_multi_index ) + + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + + +BOOST_AUTO_TEST_CASE ( test_index_classes ) +{ + using namespace boost::numeric::ublas::index; + + + BOOST_CHECK_EQUAL ( _a.value , 1 ) ; + BOOST_CHECK_EQUAL ( _b.value , 2 ) ; + BOOST_CHECK_EQUAL ( _c.value , 3 ) ; + BOOST_CHECK_EQUAL ( _d.value , 4 ) ; + BOOST_CHECK_EQUAL ( _e.value , 5 ) ; + BOOST_CHECK_EQUAL ( _f.value , 6 ) ; + BOOST_CHECK_EQUAL ( _g.value , 7 ) ; + BOOST_CHECK_EQUAL ( _h.value , 8 ) ; + BOOST_CHECK_EQUAL ( _i.value , 9 ) ; + BOOST_CHECK_EQUAL ( _j.value , 10 ) ; + BOOST_CHECK_EQUAL ( _k.value , 11 ) ; + BOOST_CHECK_EQUAL ( _l.value , 12 ) ; + BOOST_CHECK_EQUAL ( _m.value , 13 ) ; + BOOST_CHECK_EQUAL ( _n.value , 14 ) ; + BOOST_CHECK_EQUAL ( _o.value , 15 ) ; + BOOST_CHECK_EQUAL ( _p.value , 16 ) ; + BOOST_CHECK_EQUAL ( _q.value , 17 ) ; + BOOST_CHECK_EQUAL ( _r.value , 18 ) ; + BOOST_CHECK_EQUAL ( _s.value , 19 ) ; + BOOST_CHECK_EQUAL ( _t.value , 20 ) ; + BOOST_CHECK_EQUAL ( _u.value , 21 ) ; + BOOST_CHECK_EQUAL ( _v.value , 22 ) ; + BOOST_CHECK_EQUAL ( _w.value , 23 ) ; + BOOST_CHECK_EQUAL ( _x.value , 24 ) ; + BOOST_CHECK_EQUAL ( _y.value , 25 ) ; + BOOST_CHECK_EQUAL ( _z.value , 26 ) ; + +} + +BOOST_AUTO_TEST_CASE ( test_multi_index_class_construction ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + + { + multi_index<2> ind(_a, _b); + + BOOST_CHECK_EQUAL ( get<0>( ind ), 1 ) ; + BOOST_CHECK_EQUAL ( get<1>( ind ), 2 ) ; + } + + + { + multi_index<2> ind(_d,_c); + + BOOST_CHECK_EQUAL ( ind[0] , 4 ) ; + BOOST_CHECK_EQUAL ( ind[1] , 3 ) ; + } +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_tensor_multi_index_class_generation, value, test_types ) +{ + using namespace boost::numeric::ublas; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = tensor<value_type,layout_type>; + + auto t = std::make_tuple ( + index::_a, // 0 + index::_b, // 1 + index::_c, // 2 + index::_d, // 3 + index::_e // 4 + ); + + { + auto a = tensor_type(shape{2,3}, value_type{2}); + auto a_ind = a( std::get<0>(t), std::get<2>(t) ); + + BOOST_CHECK_EQUAL ( std::addressof( a_ind.first ), std::addressof( a ) ) ; + + BOOST_CHECK_EQUAL (std::get<0>(a_ind.second)(), index::_a() ) ; + BOOST_CHECK_EQUAL (std::get<1>(a_ind.second)(), index::_c() ) ; + } + + { + auto a = tensor_type(shape{2,3}, value_type{2}); + auto a_ind = a( std::get<2>(t), std::get<0>(t) ); + + BOOST_CHECK_EQUAL ( std::addressof( a_ind.first ), std::addressof( a ) ) ; + + BOOST_CHECK_EQUAL (std::get<0>(a_ind.second)(), index::_c() ) ; + BOOST_CHECK_EQUAL (std::get<1>(a_ind.second)(), index::_a() ) ; + } + + { + auto a = tensor_type(shape{2,3}, value_type{2}); + auto a_ind = a( std::get<2>(t), std::get<3>(t) ); + + BOOST_CHECK_EQUAL (std::addressof( a_ind.first ), std::addressof( a ) ) ; + + BOOST_CHECK_EQUAL (std::get<0>(a_ind.second)(), index::_c() ) ; + BOOST_CHECK_EQUAL (std::get<1>(a_ind.second)(), index::_d() ) ; + } + + { + auto a = tensor_type(shape{2,3,4}, value_type{2}); + auto a_ind = a( std::get<2>(t), std::get<3>(t), std::get<0>(t) ); + + BOOST_CHECK_EQUAL (std::addressof( a_ind.first ), std::addressof( a ) ) ; + + BOOST_CHECK_EQUAL (std::get<0>(a_ind.second)(), index::_c() ) ; + BOOST_CHECK_EQUAL (std::get<1>(a_ind.second)(), index::_d() ) ; + BOOST_CHECK_EQUAL (std::get<2>(a_ind.second)(), index::_a() ) ; + } + +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_multi_index_utility.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_multi_index_utility.cpp new file mode 100644 index 000000000..2f31a58f2 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_multi_index_utility.cpp @@ -0,0 +1,564 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The author gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + +#include <boost/numeric/ublas/tensor.hpp> + +#include <boost/test/unit_test.hpp> + +BOOST_AUTO_TEST_SUITE ( test_multi_index_utility ) + + +BOOST_AUTO_TEST_CASE ( test_multi_index_has_index ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + { + constexpr auto tuple = std::tuple<>{}; + constexpr auto has_a = has_index<decltype(_a),decltype(tuple)>::value; + constexpr auto has_b = has_index<decltype(_b),decltype(tuple)>::value; + BOOST_CHECK( !has_a ); + BOOST_CHECK( !has_b ); + } + + + { + constexpr auto tuple = std::make_tuple(_a); + constexpr auto has_a = has_index<decltype(_a),decltype(tuple)>::value; + constexpr auto has_b = has_index<decltype(_b),decltype(tuple)>::value; + BOOST_CHECK( has_a ); + BOOST_CHECK( !has_b ); + } + + { + constexpr auto tuple = std::make_tuple(_a,_b,_,_c,_d); + constexpr auto has_a = has_index<decltype(_a),decltype(tuple)>::value; + constexpr auto has_b = has_index<decltype(_b),decltype(tuple)>::value; + constexpr auto has_c = has_index<decltype(_c),decltype(tuple)>::value; + constexpr auto has_d = has_index<decltype(_d),decltype(tuple)>::value; + constexpr auto has_e = has_index<decltype(_e),decltype(tuple)>::value; + constexpr auto has__ = has_index<decltype( _),decltype(tuple)>::value; + BOOST_CHECK( has_a ); + BOOST_CHECK( has_b ); + BOOST_CHECK( has_c ); + BOOST_CHECK( has_d ); + BOOST_CHECK( !has_e ); + BOOST_CHECK( has__ ); + } +} + + + +BOOST_AUTO_TEST_CASE ( test_multi_index_valid ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + { + constexpr auto tuple = std::tuple<>{}; + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( valid ); + } + + + { + constexpr auto tuple = std::make_tuple(_a); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( valid ); + } + + { + constexpr auto tuple = std::make_tuple(_a,_,_b); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( valid ); + } + + { + constexpr auto tuple = std::make_tuple(_a,_,_b,_b); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( !valid ); + } + + { + constexpr auto tuple = std::make_tuple(_c,_a,_,_b,_b); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( !valid ); + } + + { + constexpr auto tuple = std::make_tuple(_c,_a,_,_b); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( valid ); + } + + { + constexpr auto tuple = std::make_tuple(_,_c,_a,_,_b); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( valid ); + } + + { + constexpr auto tuple = std::make_tuple(_,_c,_a,_,_b,_); + constexpr auto valid = valid_multi_index<decltype(tuple)>::value; + BOOST_CHECK( valid ); + } +} + + + + + +BOOST_AUTO_TEST_CASE ( test_multi_index_number_equal_indices ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + { + constexpr auto lhs = std::tuple<>{}; + constexpr auto rhs = std::tuple<>{}; + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_a); + constexpr auto rhs = std::tuple<>{}; + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 0 ); + } + + { + constexpr auto lhs = std::tuple<>{}; + constexpr auto rhs = std::make_tuple(_a); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_b); + constexpr auto rhs = std::make_tuple(_a); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 0 ); + } + + + + { + constexpr auto lhs = std::make_tuple(_a); + constexpr auto rhs = std::make_tuple(_a); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 1 ); + } + + { + constexpr auto lhs = std::make_tuple(_a,_b); + constexpr auto rhs = std::make_tuple(_a); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 1 ); + } + + { + constexpr auto lhs = std::make_tuple(_b); + constexpr auto rhs = std::make_tuple(_a,_b); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 1 ); + } + + { + constexpr auto lhs = std::make_tuple(_a); + constexpr auto rhs = std::make_tuple(_a); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 1 ); + } + + + + { + constexpr auto lhs = std::make_tuple(_a,_b); + constexpr auto rhs = std::make_tuple(_a,_b); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a); + constexpr auto rhs = std::make_tuple(_a,_b); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_c); + constexpr auto rhs = std::make_tuple(_a,_b); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_c); + constexpr auto rhs = std::make_tuple(_a,_b,_d); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d); + constexpr auto rhs = std::make_tuple(_a,_b,_d); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 3 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d); + constexpr auto rhs = std::make_tuple(_a,_b,_d,_); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 3 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d,_); + constexpr auto rhs = std::make_tuple(_a,_b,_d,_); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 3 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d,_); + constexpr auto rhs = std::make_tuple( _,_b,_d,_); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_,_a,_d,_); + constexpr auto rhs = std::make_tuple(_,_b,_d,_); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 1 ); + } + + { + constexpr auto lhs = std::make_tuple(_,_a,_d,_); + constexpr auto rhs = std::make_tuple(_,_b,_d,_,_); + constexpr auto num = number_equal_indexes<decltype(lhs), decltype(rhs)>::value; + BOOST_CHECK_EQUAL( num, 1 ); + } +} + + + + + + + +BOOST_AUTO_TEST_CASE ( test_multi_index_index_position ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + { + constexpr auto tuple = std::tuple<>{}; + constexpr auto ind = index_position<decltype(_),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,0); + } + + { + constexpr auto tuple = std::make_tuple(_); + constexpr auto ind = index_position<decltype(_),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,0); + } + + { + constexpr auto tuple = std::make_tuple(_); + constexpr auto ind = index_position<decltype(_a),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,1); + } + + { + constexpr auto tuple = std::make_tuple(_,_a); + constexpr auto ind = index_position<decltype(_),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,0); + } + + { + constexpr auto tuple = std::make_tuple(_,_a); + constexpr auto ind = index_position<decltype(_a),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,1); + } + + { + constexpr auto tuple = std::make_tuple(_,_a); + constexpr auto ind = index_position<decltype(_b),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,2); + } + + + + + { + constexpr auto tuple = std::make_tuple(_c,_,_a); + constexpr auto ind = index_position<decltype(_c),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,0); + } + + { + constexpr auto tuple = std::make_tuple(_c,_,_a,_); + constexpr auto ind = index_position<decltype(_),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,1); + } + + { + constexpr auto tuple = std::make_tuple(_c,_,_a); + constexpr auto ind = index_position<decltype(_a),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,2); + } + + { + constexpr auto tuple = std::make_tuple(_c,_,_a); + constexpr auto ind = index_position<decltype(_d),decltype(tuple)>::value; + BOOST_CHECK_EQUAL(ind,3); + } + +} + + + + + + + + +BOOST_AUTO_TEST_CASE ( test_multi_index_index_position_pairs ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + { + constexpr auto lhs = std::tuple<>{}; + constexpr auto rhs = std::tuple<>{}; + auto array = index_position_pairs(lhs, rhs); + BOOST_CHECK_EQUAL(array.size(), 0ul ); + } + + { + constexpr auto lhs = std::make_tuple(_a); + constexpr auto rhs = std::tuple<>{}; + auto array = index_position_pairs(lhs, rhs); + BOOST_CHECK_EQUAL(array.size(), 0ul ); + } + + { + constexpr auto lhs = std::tuple<>{}; + constexpr auto rhs = std::make_tuple(_a); + auto array = index_position_pairs(lhs, rhs); + BOOST_CHECK_EQUAL(array.size(), 0ul ); + } + + { + constexpr auto lhs = std::make_tuple(_b); + constexpr auto rhs = std::make_tuple(_a); + auto array = index_position_pairs(lhs, rhs); + BOOST_CHECK_EQUAL(array.size(), 0ul ); + } + + + + { + constexpr auto lhs = std::make_tuple(_a); + constexpr auto rhs = std::make_tuple(_a); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 1ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_a,_b); + constexpr auto rhs = std::make_tuple(_a); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 1ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_b); + constexpr auto rhs = std::make_tuple(_a,_b); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 1ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + } + + { + constexpr auto lhs = std::make_tuple(_a); + constexpr auto rhs = std::make_tuple(_a); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 1ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 0 ); + } + + + + { + constexpr auto lhs = std::make_tuple(_a,_b); + constexpr auto rhs = std::make_tuple(_a,_b); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 2ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 0 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 1 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a); + constexpr auto rhs = std::make_tuple(_a,_b); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 2ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_c); + constexpr auto rhs = std::make_tuple(_a,_b); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 2ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_c); + constexpr auto rhs = std::make_tuple(_a,_b,_d); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 2ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 0 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d); + constexpr auto rhs = std::make_tuple(_a,_b,_d); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 3ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 0 ); + BOOST_CHECK_EQUAL(array[2].first , 2 ); + BOOST_CHECK_EQUAL(array[2].second, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d); + constexpr auto rhs = std::make_tuple(_a,_b,_d,_); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 3ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 0 ); + BOOST_CHECK_EQUAL(array[2].first , 2 ); + BOOST_CHECK_EQUAL(array[2].second, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d,_); + constexpr auto rhs = std::make_tuple(_a,_b,_d,_); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 3ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 1 ); + BOOST_CHECK_EQUAL(array[1].second, 0 ); + BOOST_CHECK_EQUAL(array[2].first , 2 ); + BOOST_CHECK_EQUAL(array[2].second, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_b,_a,_d,_); + constexpr auto rhs = std::make_tuple( _,_b,_d,_); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 2ul ); + BOOST_CHECK_EQUAL(array[0].first , 0 ); + BOOST_CHECK_EQUAL(array[0].second, 1 ); + BOOST_CHECK_EQUAL(array[1].first , 2 ); + BOOST_CHECK_EQUAL(array[1].second, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_,_a,_d,_); + constexpr auto rhs = std::make_tuple(_,_b,_d,_); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 1ul ); + BOOST_CHECK_EQUAL(array[0].first , 2 ); + BOOST_CHECK_EQUAL(array[0].second, 2 ); + } + + { + constexpr auto lhs = std::make_tuple(_,_a,_d,_); + constexpr auto rhs = std::make_tuple(_,_b,_d,_,_); + auto array = index_position_pairs(lhs, rhs); + BOOST_ASSERT(array.size() == 1ul ); + BOOST_CHECK_EQUAL(array[0].first , 2 ); + BOOST_CHECK_EQUAL(array[0].second, 2 ); + } +} + + + +BOOST_AUTO_TEST_CASE ( test_multi_index_array_to_vector ) +{ + using namespace boost::numeric::ublas; + using namespace boost::numeric::ublas::index; + + auto check = [](auto const& lhs, auto const& rhs) + { + auto array = index_position_pairs(lhs, rhs); + + auto vector_pair = array_to_vector( array ); + + BOOST_CHECK_EQUAL(vector_pair.first .size(), array.size() ); + BOOST_CHECK_EQUAL(vector_pair.second.size(), array.size() ); + + for(auto i = 0ul; i < array.size(); ++i) + { + BOOST_CHECK_EQUAL(vector_pair.first [i], array[i].first +1 ); + BOOST_CHECK_EQUAL(vector_pair.second[i], array[i].second+1 ); + } + + }; + + check(std::tuple<>{} , std::tuple<>{}); + check(std::make_tuple(_a) , std::tuple<>{}); + check(std::tuple<>{} , std::make_tuple(_a)); + check(std::make_tuple(_a) , std::make_tuple(_b)); + check(std::make_tuple(_a) , std::make_tuple(_a)); + check(std::make_tuple(_a,_b), std::make_tuple(_a)); + check(std::make_tuple(_a) , std::make_tuple(_a,_b)); + check(std::make_tuple(_a,_b), std::make_tuple(_a,_b)); + check(std::make_tuple(_b,_a), std::make_tuple(_a,_b)); + check(std::make_tuple(_b,_a,_c), std::make_tuple(_a,_b,_d)); +} + + + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_multiplication.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_multiplication.cpp new file mode 100644 index 000000000..2f1570d15 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_multiplication.cpp @@ -0,0 +1,491 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + +#include <iostream> +#include <algorithm> +#include <vector> + +#include <boost/numeric/ublas/tensor/multiplication.hpp> +#include <boost/numeric/ublas/tensor/extents.hpp> +#include <boost/numeric/ublas/tensor/strides.hpp> +#include "utility.hpp" + +#include <boost/test/unit_test.hpp> + + +BOOST_AUTO_TEST_SUITE (test_tensor_contraction) + + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + +//using test_types = zip<int>::with_t<boost::numeric::ublas::first_order>; + + +struct fixture +{ + using extents_type = boost::numeric::ublas::shape; + fixture() + : extents { + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{5,4}, // 5 + extents_type{2,3,1}, // 6 + extents_type{4,1,3}, // 7 + extents_type{1,2,3}, // 8 + extents_type{4,2,3}, // 9 + extents_type{4,2,3,5}} // 10 + { + } + std::vector<extents_type> extents; +}; + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE(test_tensor_mtv, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + using extents_type = ublas::shape; + using extents_type_base = typename extents_type::base_type; + using size_type = typename extents_type_base::value_type; + + + for(auto const& na : extents) { + + if(na.size() > 2) + continue; + + auto a = vector_type(na.product(), value_type{2}); + auto wa = strides_type(na); + for(auto m = 0u; m < na.size(); ++m){ + auto nb = extents_type {na[m],1}; + auto wb = strides_type (nb); + auto b = vector_type (nb.product(), value_type{1} ); + + auto nc_base = extents_type_base(std::max(na.size()-1, size_type{2}), 1); + + for(auto i = 0u, j = 0u; i < na.size(); ++i) + if(i != m) + nc_base[j++] = na[i]; + + auto nc = extents_type (nc_base); + auto wc = strides_type (nc); + auto c = vector_type (nc.product(), value_type{0}); + + ublas::detail::recursive::mtv( + size_type(m), + c.data(), nc.data(), wc.data(), + a.data(), na.data(), wa.data(), + b.data()); + + + for(auto i = 0u; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , value_type(na[m]) * a[i] ); + + } + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_mtm, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + using extents_type = ublas::shape; + // using extents_type_base = typename extents_type::base_type; + + + for(auto const& na : extents) { + + if(na.size() != 2) + continue; + + auto a = vector_type (na.product(), value_type{2}); + auto wa = strides_type (na); + + auto nb = extents_type {na[1],na[0]}; + auto wb = strides_type (nb); + auto b = vector_type (nb.product(), value_type{1} ); + + auto nc = extents_type {na[0],nb[1]}; +auto wc = strides_type (nc); +auto c = vector_type (nc.product()); + + +ublas::detail::recursive::mtm( + c.data(), nc.data(), wc.data(), + a.data(), na.data(), wa.data(), + b.data(), nb.data(), wb.data()); + + +for(auto i = 0u; i < c.size(); ++i) +BOOST_CHECK_EQUAL( c[i] , value_type(na[1]) * a[0] ); + + +} +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ttv, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + using extents_type = ublas::shape; + using extents_type_base = typename extents_type::base_type; + using size_type = typename extents_type_base::value_type; + + + for(auto const& na : extents) { + + auto a = vector_type(na.product(), value_type{2}); + auto wa = strides_type(na); + for(auto m = 0u; m < na.size(); ++m){ + auto b = vector_type (na[m], value_type{1} ); + auto nb = extents_type {na[m],1}; + auto wb = strides_type (nb); + + auto nc_base = extents_type_base(std::max(na.size()-1, size_type(2)),1); + + for(auto i = 0ul, j = 0ul; i < na.size(); ++i) + if(i != m) + nc_base[j++] = na[i]; + + auto nc = extents_type (nc_base); + auto wc = strides_type (nc); + auto c = vector_type (nc.product(), value_type{0}); + + ublas::ttv(size_type(m+1), na.size(), + c.data(), nc.data(), wc.data(), + a.data(), na.data(), wa.data(), + b.data(), nb.data(), wb.data()); + + + for(auto i = 0u; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , value_type(na[m]) * a[i] ); + + } + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ttm, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + using extents_type = ublas::shape; + using size_type = typename extents_type::value_type; + + + for(auto const& na : extents) { + + auto a = vector_type(na.product(), value_type{2}); + auto wa = strides_type(na); + for(auto m = 0u; m < na.size(); ++m){ + auto nb = extents_type {na[m], na[m] }; + auto b = vector_type (nb.product(), value_type{1} ); + auto wb = strides_type (nb); + + + auto nc = na; + auto wc = strides_type (nc); + auto c = vector_type (nc.product(), value_type{0}); + + ublas::ttm(size_type(m+1), na.size(), + c.data(), nc.data(), wc.data(), + a.data(), na.data(), wa.data(), + b.data(), nb.data(), wb.data()); + + for(auto i = 0u; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , value_type(na[m]) * a[i] ); + + } + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ttt_permutation, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + using extents_type = ublas::shape; + using size_type = typename strides_type::value_type; + + + auto compute_factorial = [](auto const& p){ + auto f = 1ul; + for(auto i = 1u; i <= p; ++i) + f *= i; + return f; + }; + + + auto compute_inverse_permutation = [](auto const& pi){ + auto pi_inv = pi; + for(auto j = 0u; j < pi.size(); ++j) + pi_inv[pi[j]-1] = j+1; + return pi_inv; + }; + + auto permute_extents = [](auto const& pi, auto const& na){ + auto nb = na; + assert(pi.size() == na.size()); + for(auto j = 0u; j < pi.size(); ++j) + nb[j] = na[pi[j]-1]; + return nb; + }; + + + // left-hand and right-hand side have the + // the same number of elements + + // computing the inner product with + // different permutation tuples for + // right-hand side + + for(auto const& na : extents) { + + auto wa = strides_type(na); + auto a = vector_type(na.product(), value_type{2}); + auto pa = na.size(); + auto pia = std::vector<size_type>(pa); + std::iota( pia.begin(), pia.end(), 1 ); + + auto pib = pia; + auto pib_inv = compute_inverse_permutation(pib); + + auto f = compute_factorial(pa); + + // for the number of possible permutations + // only permutation tuple pib is changed. + for(auto i = 0u; i < f; ++i) { + + auto nb = permute_extents( pib, na ); + auto wb = strides_type(nb); + auto b = vector_type(nb.product(), value_type{3}); + auto pb = nb.size(); + + // the number of contractions is changed. + for( auto q = size_type(0); q <= pa; ++q) { + + auto r = pa - q; + auto s = pb - q; + + auto pc = r+s > 0 ? std::max(r+s,size_type(2)) : size_type(2); + + auto nc_base = std::vector<size_type>( pc , 1 ); + + for(auto i = 0u; i < r; ++i) + nc_base[ i ] = na[ pia[i]-1 ]; + + for(auto i = 0u; i < s; ++i) + nc_base[ r + i ] = nb[ pib_inv[i]-1 ]; + + auto nc = extents_type ( nc_base ); + auto wc = strides_type ( nc ); + auto c = vector_type ( nc.product(), value_type(0) ); + + ublas::ttt(pa,pb,q, + pia.data(), pib_inv.data(), + c.data(), nc.data(), wc.data(), + a.data(), na.data(), wa.data(), + b.data(), nb.data(), wb.data()); + + + auto acc = value_type(1); + for(auto i = r; i < pa; ++i) + acc *= value_type(na[pia[i]-1]); + + for(auto i = 0ul; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , acc * a[0] * b[0] ); + + } + + std::next_permutation(pib.begin(), pib.end()); + pib_inv = compute_inverse_permutation(pib); + } + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ttt, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + using extents_type = ublas::shape; + using size_type = typename strides_type::value_type; + + // left-hand and right-hand side have the + // the same number of elements + + // computing the inner product with + // different permutation tuples for + // right-hand side + + for(auto const& na : extents) { + + auto wa = strides_type(na); + auto a = vector_type(na.product(), value_type{2}); + auto pa = na.size(); + + auto nb = na; + auto wb = strides_type(nb); + auto b = vector_type(nb.product(), value_type{3}); + auto pb = nb.size(); + + // std::cout << "na = "; + // std::copy(na.begin(), na.end(), std::ostream_iterator<size_type>(std::cout, " ")); + // std::cout << std::endl; + + // std::cout << "nb = "; + // std::copy(nb.begin(), nb.end(), std::ostream_iterator<size_type>(std::cout, " ")); + // std::cout << std::endl; + + + // the number of contractions is changed. + for( auto q = size_type(0); q <= pa; ++q) { // pa + + auto r = pa - q; + auto s = pb - q; + + auto pc = r+s > 0 ? std::max(r+s, size_type(2)) : size_type(2); + + auto nc_base = std::vector<size_type>( pc , 1 ); + + for(auto i = 0u; i < r; ++i) + nc_base[ i ] = na[ i ]; + + for(auto i = 0u; i < s; ++i) + nc_base[ r + i ] = nb[ i ]; + + auto nc = extents_type ( nc_base ); + auto wc = strides_type ( nc ); + auto c = vector_type ( nc.product(), value_type{0} ); + + // std::cout << "nc = "; + // std::copy(nc.begin(), nc.end(), std::ostream_iterator<size_type>(std::cout, " ")); + // std::cout << std::endl; + + ublas::ttt(pa,pb,q, + c.data(), nc.data(), wc.data(), + a.data(), na.data(), wa.data(), + b.data(), nb.data(), wb.data()); + + + auto acc = value_type(1); + for(auto i = r; i < pa; ++i) + acc *= value_type(na[i]); + + for(auto i = 0u; i < c.size(); ++i) + BOOST_CHECK_EQUAL( c[i] , acc * a[0] * b[0] ); + + } + + } +} + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_inner, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + + + for(auto const& n : extents) { + + auto a = vector_type(n.product(), value_type{2}); + auto b = vector_type(n.product(), value_type{3}); + auto w = strides_type(n); + + auto c = ublas::inner(n.size(), n.data(), a.data(), w.data(), b.data(), w.data(), value_type(0)); + auto cref = std::inner_product(a.begin(), a.end(), b.begin(), value_type(0)); + + + BOOST_CHECK_EQUAL( c , cref ); + + } + +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_outer, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using extents_type = ublas::shape; + using strides_type = ublas::strides<layout_type>; + using vector_type = std::vector<value_type>; + + + for(auto const& na : extents) { + + auto a = vector_type(na.product(), value_type{2}); + auto wa = strides_type(na); + + for(auto const& nb : extents) { + + auto b = vector_type(nb.product(), value_type{3}); + auto wb = strides_type(nb); + + auto c = vector_type(nb.product()*na.product()); + auto nc = typename extents_type::base_type(na.size()+nb.size()); + + for(auto i = 0u; i < na.size(); ++i) + nc[i] = na[i]; + for(auto i = 0u; i < nb.size(); ++i) + nc[i+na.size()] = nb[i]; + + auto wc = strides_type(extents_type(nc)); + + ublas::outer(c.data(), nc.size(), nc.data(), wc.data(), + a.data(), na.size(), na.data(), wa.data(), + b.data(), nb.size(), nb.data(), wb.data()); + + for(auto const& cc : c) + BOOST_CHECK_EQUAL( cc , a[0]*b[0] ); + } + + } + +} + + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_operators_arithmetic.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_operators_arithmetic.cpp new file mode 100644 index 000000000..8bab76192 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_operators_arithmetic.cpp @@ -0,0 +1,267 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + + +#include <boost/numeric/ublas/tensor.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/multiprecision/cpp_bin_float.hpp> +#include "utility.hpp" + + +using double_extended = boost::multiprecision::cpp_bin_float_double_extended; + +using test_types = zip<int,long,float,double,double_extended>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + +struct fixture +{ + using extents_type = boost::numeric::ublas::basic_extents<std::size_t>; + fixture() + : extents{ + extents_type{}, // 0 + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{4,1,3}, // 6 + extents_type{1,2,3}, // 7 + extents_type{4,2,3}, // 8 + extents_type{4,2,3,5}} // 9 + { + } + std::vector<extents_type> extents; +}; + +BOOST_AUTO_TEST_SUITE(test_tensor_arithmetic_operations, * boost::unit_test::depends_on("test_tensor")) + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_binary_arithmetic_operations, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + auto check = [](auto const& e) + { + auto t = tensor_type (e); + auto t2 = tensor_type (e); + auto r = tensor_type (e); + auto v = value_type {}; + + std::iota(t.begin(), t.end(), v); + std::iota(t2.begin(), t2.end(), v+2); + + r = t + t + t + t2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 3*t(i) + t2(i) ); + + + r = t2 / (t+3) * (t+1) - t2; // r = ( t2/ ((t+3)*(t+1)) ) - t2 + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), t2(i) / (t(i)+3)*(t(i)+1) - t2(i) ); + + r = 3+t2 / (t+3) * (t+1) * t - t2; // r = 3+( t2/ ((t+3)*(t+1)*t) ) - t2 + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 3+t2(i) / (t(i)+3)*(t(i)+1)*t(i) - t2(i) ); + + r = t2 - t + t2 - t; + + for(auto i = 0ul; i < r.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 4 ); + + + r = tensor_type (e,1) + tensor_type (e,1); + + for(auto i = 0ul; i < r.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 2 ); + + r = t * t * t * t2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), t(i)*t(i)*t(i)*t2(i) ); + + r = (t2/t2) * (t2/t2); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 1 ); + }; + + for(auto const& e : extents) + check(e); + + + BOOST_CHECK_NO_THROW ( tensor_type t = tensor_type(extents.at(0)) + tensor_type(extents.at(0)) ); + BOOST_CHECK_THROW ( tensor_type t = tensor_type(extents.at(0)) + tensor_type(extents.at(2)), std::runtime_error ); + BOOST_CHECK_THROW ( tensor_type t = tensor_type(extents.at(1)) + tensor_type(extents.at(2)), std::runtime_error ); + + +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_unary_arithmetic_operations, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + auto check = [](auto const& e) + { + auto t = tensor_type (e); + auto t2 = tensor_type (e); + auto v = value_type {}; + + std::iota(t.begin(), t.end(), v); + std::iota(t2.begin(), t2.end(), v+2); + + tensor_type r1 = t + 2 + t + 2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r1(i), 2*t(i) + 4 ); + + tensor_type r2 = 2 + t + 2 + t; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r2(i), 2*t(i) + 4 ); + + tensor_type r3 = (t-2) + (t-2); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r3(i), 2*t(i) - 4 ); + + tensor_type r4 = (t*2) * (3*t); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r4(i), 2*3*t(i)*t(i) ); + + tensor_type r5 = (t2*2) / (2*t2) * t2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r5(i), (t2(i)*2) / (2*t2(i)) * t2(i) ); + + tensor_type r6 = (t2/2+1) / (2/t2+1) / t2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r6(i), (t2(i)/2+1) / (2/t2(i)+1) / t2(i) ); + + }; + + for(auto const& e : extents) + check(e); + + BOOST_CHECK_NO_THROW ( tensor_type t = tensor_type(extents.at(0)) + 2 + tensor_type(extents.at(0)) ); + BOOST_CHECK_THROW ( tensor_type t = tensor_type(extents.at(0)) + 2 + tensor_type(extents.at(2)), std::runtime_error ); + BOOST_CHECK_THROW ( tensor_type t = tensor_type(extents.at(1)) + 2 + tensor_type(extents.at(2)), std::runtime_error ); + BOOST_CHECK_THROW ( tensor_type t = tensor_type(extents.at(2)) + 2 + tensor_type(extents.at(2)) + tensor_type(extents.at(1)), std::runtime_error ); + BOOST_CHECK_THROW ( tensor_type t = tensor_type(extents.at(2)) + 2 + tensor_type(extents.at(2)) + 2 + tensor_type(extents.at(1)), std::runtime_error ); +} + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_assign_arithmetic_operations, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + auto check = [](auto const& e) + { + auto t = tensor_type (e); + auto t2 = tensor_type (e); + auto r = tensor_type (e); + auto v = value_type {}; + + std::iota(t.begin(), t.end(), v); + std::iota(t2.begin(), t2.end(), v+2); + + r = t + 2; + r += t; + r += 2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 2*t(i) + 4 ); + + r = 2 + t; + r += t; + r += 2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 2*t(i) + 4 ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 2*t(i) + 4 ); + + r = (t-2); + r += t; + r -= 2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 2*t(i) - 4 ); + + r = (t*2); + r *= 3; + r *= t; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), 2*3*t(i)*t(i) ); + + r = (t2*2); + r /= 2; + r /= t2; + r *= t2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), (t2(i)*2) / (2*t2(i)) * t2(i) ); + + r = (t2/2+1); + r /= (2/t2+1); + r /= t2; + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( r(i), (t2(i)/2+1) / (2/t2(i)+1) / t2(i) ); + + tensor_type q = -r; + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( q(i), -r(i) ); + + tensor_type p = +r; + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL ( p(i), r(i) ); + }; + + for(auto const& e : extents) + check(e); + + auto r = tensor_type (extents.at(0)); + + BOOST_CHECK_NO_THROW ( r += tensor_type(extents.at(0)) + 2 + tensor_type(extents.at(0)) ); + BOOST_CHECK_THROW ( r += tensor_type(extents.at(0)) + 2 + tensor_type(extents.at(2)), std::runtime_error ); + BOOST_CHECK_THROW ( r += tensor_type(extents.at(1)) + 2 + tensor_type(extents.at(2)), std::runtime_error ); + BOOST_CHECK_THROW ( r += tensor_type(extents.at(2)) + 2 + tensor_type(extents.at(2)) + tensor_type(extents.at(1)), std::runtime_error ); + BOOST_CHECK_THROW ( r += tensor_type(extents.at(2)) + 2 + tensor_type(extents.at(2)) + 2 + tensor_type(extents.at(1)), std::runtime_error ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_operators_comparison.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_operators_comparison.cpp new file mode 100644 index 000000000..f076e9c1e --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_operators_comparison.cpp @@ -0,0 +1,246 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + + +#include <boost/numeric/ublas/tensor/operators_comparison.hpp> +#include <boost/numeric/ublas/tensor/operators_arithmetic.hpp> +#include <boost/numeric/ublas/tensor/tensor.hpp> +#include <boost/test/unit_test.hpp> +#include <boost/multiprecision/cpp_bin_float.hpp> +#include "utility.hpp" + + +using double_extended = boost::multiprecision::cpp_bin_float_double_extended; + +using test_types = zip<int,long,float,double,double_extended>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + +struct fixture { + using extents_type = boost::numeric::ublas::basic_extents<std::size_t>; + fixture() + : extents{ + extents_type{}, // 0 + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{4,1,3}, // 6 + extents_type{1,2,3}, // 7 + extents_type{4,2,3}, // 8 + extents_type{4,2,3,5}} // 9 + { + } + std::vector<extents_type> extents; +}; + +BOOST_AUTO_TEST_SUITE(test_tensor_comparison, * boost::unit_test::depends_on("test_tensor")) + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_comparison, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + auto check = [](auto const& e) + { + auto t = tensor_type (e); + auto t2 = tensor_type (e); + auto v = value_type {}; + + std::iota(t.begin(), t.end(), v); + std::iota(t2.begin(), t2.end(), v+2); + + BOOST_CHECK( t == t ); + BOOST_CHECK( t != t2 ); + + if(t.empty()) + return; + + BOOST_CHECK(!(t < t)); + BOOST_CHECK(!(t > t)); + BOOST_CHECK( t < t2 ); + BOOST_CHECK( t2 > t ); + BOOST_CHECK( t <= t ); + BOOST_CHECK( t >= t ); + BOOST_CHECK( t <= t2 ); + BOOST_CHECK( t2 >= t ); + BOOST_CHECK( t2 >= t2 ); + BOOST_CHECK( t2 >= t ); + }; + + for(auto const& e : extents) + check(e); + + auto e0 = extents.at(0); + auto e1 = extents.at(1); + auto e2 = extents.at(2); + + + auto b = false; + BOOST_CHECK_NO_THROW ( b = (tensor_type(e0) == tensor_type(e0))); + BOOST_CHECK_NO_THROW ( b = (tensor_type(e1) == tensor_type(e2))); + BOOST_CHECK_NO_THROW ( b = (tensor_type(e0) == tensor_type(e2))); + BOOST_CHECK_NO_THROW ( b = (tensor_type(e1) != tensor_type(e2))); + + BOOST_CHECK_THROW ( b = (tensor_type(e1) >= tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW ( b = (tensor_type(e1) <= tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW ( b = (tensor_type(e1) < tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW ( b = (tensor_type(e1) > tensor_type(e2)), std::runtime_error ); + +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_comparison_with_tensor_expressions, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + auto check = [](auto const& e) + { + auto t = tensor_type (e); + auto t2 = tensor_type (e); + auto v = value_type {}; + + std::iota(t.begin(), t.end(), v); + std::iota(t2.begin(), t2.end(), v+2); + + BOOST_CHECK( t == t ); + BOOST_CHECK( t != t2 ); + + if(t.empty()) + return; + + BOOST_CHECK( !(t < t) ); + BOOST_CHECK( !(t > t) ); + BOOST_CHECK( t < (t2+t) ); + BOOST_CHECK( (t2+t) > t ); + BOOST_CHECK( t <= (t+t) ); + BOOST_CHECK( (t+t2) >= t ); + BOOST_CHECK( (t2+t2+2) >= t); + BOOST_CHECK( 2*t2 > t ); + BOOST_CHECK( t < 2*t2 ); + BOOST_CHECK( 2*t2 > t); + BOOST_CHECK( 2*t2 >= t2 ); + BOOST_CHECK( t2 <= 2*t2); + BOOST_CHECK( 3*t2 >= t ); + + }; + + for(auto const& e : extents) + check(e); + + auto e0 = extents.at(0); + auto e1 = extents.at(1); + auto e2 = extents.at(2); + + auto b = false; + BOOST_CHECK_NO_THROW (b = tensor_type(e0) == (tensor_type(e0) + tensor_type(e0)) ); + BOOST_CHECK_NO_THROW (b = tensor_type(e1) == (tensor_type(e2) + tensor_type(e2)) ); + BOOST_CHECK_NO_THROW (b = tensor_type(e0) == (tensor_type(e2) + 2) ); + BOOST_CHECK_NO_THROW (b = tensor_type(e1) != (2 + tensor_type(e2)) ); + + BOOST_CHECK_NO_THROW (b = (tensor_type(e0) + tensor_type(e0)) == tensor_type(e0) ); + BOOST_CHECK_NO_THROW (b = (tensor_type(e2) + tensor_type(e2)) == tensor_type(e1) ); + BOOST_CHECK_NO_THROW (b = (tensor_type(e2) + 2) == tensor_type(e0) ); + BOOST_CHECK_NO_THROW (b = (2 + tensor_type(e2)) != tensor_type(e1) ); + + BOOST_CHECK_THROW (b = tensor_type(e1) >= (tensor_type(e2) + tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW (b = tensor_type(e1) <= (tensor_type(e2) + tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW (b = tensor_type(e1) < (tensor_type(e2) + tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW (b = tensor_type(e1) > (tensor_type(e2) + tensor_type(e2)), std::runtime_error ); + + BOOST_CHECK_THROW (b = tensor_type(e1) >= (tensor_type(e2) + 2), std::runtime_error ); + BOOST_CHECK_THROW (b = tensor_type(e1) <= (2 + tensor_type(e2)), std::runtime_error ); + BOOST_CHECK_THROW (b = tensor_type(e1) < (tensor_type(e2) + 3), std::runtime_error ); + BOOST_CHECK_THROW (b = tensor_type(e1) > (4 + tensor_type(e2)), std::runtime_error ); + +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_comparison_with_scalar, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + auto check = [](auto const& e) + { + + BOOST_CHECK( tensor_type(e,value_type{2}) == tensor_type(e,value_type{2}) ); + BOOST_CHECK( tensor_type(e,value_type{2}) != tensor_type(e,value_type{1}) ); + + if(e.empty()) + return; + + BOOST_CHECK( !(tensor_type(e,2) < 2) ); + BOOST_CHECK( !(tensor_type(e,2) > 2) ); + BOOST_CHECK( (tensor_type(e,2) >= 2) ); + BOOST_CHECK( (tensor_type(e,2) <= 2) ); + BOOST_CHECK( (tensor_type(e,2) == 2) ); + BOOST_CHECK( (tensor_type(e,2) != 3) ); + + BOOST_CHECK( !(2 > tensor_type(e,2)) ); + BOOST_CHECK( !(2 < tensor_type(e,2)) ); + BOOST_CHECK( (2 <= tensor_type(e,2)) ); + BOOST_CHECK( (2 >= tensor_type(e,2)) ); + BOOST_CHECK( (2 == tensor_type(e,2)) ); + BOOST_CHECK( (3 != tensor_type(e,2)) ); + + BOOST_CHECK( !( tensor_type(e,2)+3 < 5) ); + BOOST_CHECK( !( tensor_type(e,2)+3 > 5) ); + BOOST_CHECK( ( tensor_type(e,2)+3 >= 5) ); + BOOST_CHECK( ( tensor_type(e,2)+3 <= 5) ); + BOOST_CHECK( ( tensor_type(e,2)+3 == 5) ); + BOOST_CHECK( ( tensor_type(e,2)+3 != 6) ); + + + BOOST_CHECK( !( 5 > tensor_type(e,2)+3) ); + BOOST_CHECK( !( 5 < tensor_type(e,2)+3) ); + BOOST_CHECK( ( 5 >= tensor_type(e,2)+3) ); + BOOST_CHECK( ( 5 <= tensor_type(e,2)+3) ); + BOOST_CHECK( ( 5 == tensor_type(e,2)+3) ); + BOOST_CHECK( ( 6 != tensor_type(e,2)+3) ); + + + BOOST_CHECK( !( tensor_type(e,2)+tensor_type(e,3) < 5) ); + BOOST_CHECK( !( tensor_type(e,2)+tensor_type(e,3) > 5) ); + BOOST_CHECK( ( tensor_type(e,2)+tensor_type(e,3) >= 5) ); + BOOST_CHECK( ( tensor_type(e,2)+tensor_type(e,3) <= 5) ); + BOOST_CHECK( ( tensor_type(e,2)+tensor_type(e,3) == 5) ); + BOOST_CHECK( ( tensor_type(e,2)+tensor_type(e,3) != 6) ); + + + BOOST_CHECK( !( 5 > tensor_type(e,2)+tensor_type(e,3)) ); + BOOST_CHECK( !( 5 < tensor_type(e,2)+tensor_type(e,3)) ); + BOOST_CHECK( ( 5 >= tensor_type(e,2)+tensor_type(e,3)) ); + BOOST_CHECK( ( 5 <= tensor_type(e,2)+tensor_type(e,3)) ); + BOOST_CHECK( ( 5 == tensor_type(e,2)+tensor_type(e,3)) ); + BOOST_CHECK( ( 6 != tensor_type(e,2)+tensor_type(e,3)) ); + + }; + + for(auto const& e : extents) + check(e); + +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_strides.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_strides.cpp new file mode 100644 index 000000000..3a29e660a --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_strides.cpp @@ -0,0 +1,172 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + + + +#include <boost/test/unit_test.hpp> +#include <boost/numeric/ublas/tensor/strides.hpp> +#include <boost/numeric/ublas/tensor/extents.hpp> + +//BOOST_AUTO_TEST_SUITE(test_strides, * boost::unit_test::depends_on("test_extents")); + +BOOST_AUTO_TEST_SUITE(test_strides) + +using test_types = std::tuple<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_strides_ctor, value, test_types) +{ + using namespace boost::numeric; + + using extents_type = ublas::basic_extents<unsigned>; + using strides_type = ublas::strides<value>; + + strides_type s0{}; + BOOST_CHECK ( s0.empty()); + BOOST_CHECK_EQUAL ( s0.size(), 0); + + strides_type s1{extents_type{1,1}}; + BOOST_CHECK (!s1.empty()); + BOOST_CHECK_EQUAL ( s1.size(), 2); + + strides_type s2{extents_type{1,2}}; + BOOST_CHECK (!s2.empty()); + BOOST_CHECK_EQUAL ( s2.size(), 2); + + strides_type s3{extents_type{2,1}}; + BOOST_CHECK (!s3.empty()); + BOOST_CHECK_EQUAL ( s3.size(), 2); + + strides_type s4{extents_type{2,3}}; + BOOST_CHECK (!s4.empty()); + BOOST_CHECK_EQUAL ( s4.size(), 2); + + strides_type s5{extents_type{2,3,1}}; + BOOST_CHECK (!s5.empty()); + BOOST_CHECK_EQUAL ( s5.size(), 3); + + strides_type s6{extents_type{1,2,3}}; + BOOST_CHECK (!s6.empty()); + BOOST_CHECK_EQUAL ( s6.size(), 3); + + strides_type s7{extents_type{4,2,3}}; + BOOST_CHECK (!s7.empty()); + BOOST_CHECK_EQUAL ( s7.size(), 3); +} + + + +BOOST_AUTO_TEST_CASE( test_strides_ctor_access_first_order) +{ + using namespace boost::numeric; + + using extents_type = ublas::basic_extents<unsigned>; + using strides_type = ublas::strides<ublas::first_order>; + + strides_type s1{extents_type{1,1}}; + BOOST_REQUIRE_EQUAL( s1.size(),2); + BOOST_CHECK_EQUAL ( s1[0], 1); + BOOST_CHECK_EQUAL ( s1[1], 1); + + strides_type s2{extents_type{1,2}}; + BOOST_REQUIRE_EQUAL ( s2.size(),2); + BOOST_CHECK_EQUAL ( s2[0], 1); + BOOST_CHECK_EQUAL ( s2[1], 1); + + strides_type s3{extents_type{2,1}}; + BOOST_REQUIRE_EQUAL ( s3.size(),2); + BOOST_CHECK_EQUAL ( s3[0], 1); + BOOST_CHECK_EQUAL ( s3[1], 1); + + strides_type s4{extents_type{2,3}}; + BOOST_REQUIRE_EQUAL ( s4.size(),2); + BOOST_CHECK_EQUAL ( s4[0], 1); + BOOST_CHECK_EQUAL ( s4[1], 2); + + strides_type s5{extents_type{2,3,1}}; + BOOST_REQUIRE_EQUAL ( s5.size(),3); + BOOST_CHECK_EQUAL ( s5[0], 1); + BOOST_CHECK_EQUAL ( s5[1], 2); + BOOST_CHECK_EQUAL ( s5[2], 6); + + strides_type s6{extents_type{1,2,3}}; + BOOST_REQUIRE_EQUAL ( s6.size(),3); + BOOST_CHECK_EQUAL ( s6[0], 1); + BOOST_CHECK_EQUAL ( s6[1], 1); + BOOST_CHECK_EQUAL ( s6[2], 2); + + strides_type s7{extents_type{2,1,3}}; + BOOST_REQUIRE_EQUAL ( s7.size(),3); + BOOST_CHECK_EQUAL ( s7[0], 1); + BOOST_CHECK_EQUAL ( s7[1], 2); + BOOST_CHECK_EQUAL ( s7[2], 2); + + strides_type s8{extents_type{4,2,3}}; + BOOST_REQUIRE_EQUAL ( s8.size(),3); + BOOST_CHECK_EQUAL ( s8[0], 1); + BOOST_CHECK_EQUAL ( s8[1], 4); + BOOST_CHECK_EQUAL ( s8[2], 8); +} + +BOOST_AUTO_TEST_CASE( test_strides_ctor_access_last_order) +{ + using namespace boost::numeric; + + using extents_type = ublas::basic_extents<unsigned>; + using strides_type = ublas::strides<ublas::last_order>; + + strides_type s1{extents_type{1,1}}; + BOOST_REQUIRE_EQUAL( s1.size(),2); + BOOST_CHECK_EQUAL ( s1[0], 1); + BOOST_CHECK_EQUAL ( s1[1], 1); + + strides_type s2{extents_type{1,2}}; + BOOST_REQUIRE_EQUAL ( s2.size(),2); + BOOST_CHECK_EQUAL ( s2[0], 1); + BOOST_CHECK_EQUAL ( s2[1], 1); + + strides_type s3{extents_type{2,1}}; + BOOST_REQUIRE_EQUAL ( s3.size(),2); + BOOST_CHECK_EQUAL ( s3[0], 1); + BOOST_CHECK_EQUAL ( s3[1], 1); + + strides_type s4{extents_type{2,3}}; + BOOST_REQUIRE_EQUAL ( s4.size(),2); + BOOST_CHECK_EQUAL ( s4[0], 3); + BOOST_CHECK_EQUAL ( s4[1], 1); + + strides_type s5{extents_type{2,3,1}}; + BOOST_REQUIRE_EQUAL ( s5.size(),3); + BOOST_CHECK_EQUAL ( s5[0], 3); + BOOST_CHECK_EQUAL ( s5[1], 1); + BOOST_CHECK_EQUAL ( s5[2], 1); + + strides_type s6{extents_type{1,2,3}}; + BOOST_REQUIRE_EQUAL ( s6.size(),3); + BOOST_CHECK_EQUAL ( s6[0], 6); + BOOST_CHECK_EQUAL ( s6[1], 3); + BOOST_CHECK_EQUAL ( s6[2], 1); + + strides_type s7{extents_type{2,1,3}}; + BOOST_REQUIRE_EQUAL ( s7.size(),3); + BOOST_CHECK_EQUAL ( s7[0], 3); + BOOST_CHECK_EQUAL ( s7[1], 3); + BOOST_CHECK_EQUAL ( s7[2], 1); + + strides_type s8{extents_type{4,2,3}}; + BOOST_REQUIRE_EQUAL ( s8.size(),3); + BOOST_CHECK_EQUAL ( s8[0], 6); + BOOST_CHECK_EQUAL ( s8[1], 3); + BOOST_CHECK_EQUAL ( s8[2], 1); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_tensor.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_tensor.cpp new file mode 100644 index 000000000..400e86245 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_tensor.cpp @@ -0,0 +1,473 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + + +#include <random> +#include <boost/numeric/ublas/tensor/tensor.hpp> + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE TestTensor + +#include <boost/test/unit_test.hpp> +#include "utility.hpp" + +//BOOST_AUTO_TEST_SUITE ( test_tensor, * boost::unit_test::depends_on("test_extents") ) ; +BOOST_AUTO_TEST_SUITE ( test_tensor ) + +using test_types = zip<int,long,float,double,std::complex<float>>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_tensor_ctor, value, test_types) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto a1 = tensor_type{}; + BOOST_CHECK_EQUAL( a1.size() , 0ul ); + BOOST_CHECK( a1.empty() ); + BOOST_CHECK_EQUAL( a1.data() , nullptr); + + auto a2 = tensor_type{1,1}; + BOOST_CHECK_EQUAL( a2.size() , 1 ); + BOOST_CHECK( !a2.empty() ); + BOOST_CHECK_NE( a2.data() , nullptr); + + auto a3 = tensor_type{2,1}; + BOOST_CHECK_EQUAL( a3.size() , 2 ); + BOOST_CHECK( !a3.empty() ); + BOOST_CHECK_NE( a3.data() , nullptr); + + auto a4 = tensor_type{1,2}; + BOOST_CHECK_EQUAL( a4.size() , 2 ); + BOOST_CHECK( !a4.empty() ); + BOOST_CHECK_NE( a4.data() , nullptr); + + auto a5 = tensor_type{2,1}; + BOOST_CHECK_EQUAL( a5.size() , 2 ); + BOOST_CHECK( !a5.empty() ); + BOOST_CHECK_NE( a5.data() , nullptr); + + auto a6 = tensor_type{4,3,2}; + BOOST_CHECK_EQUAL( a6.size() , 4*3*2 ); + BOOST_CHECK( !a6.empty() ); + BOOST_CHECK_NE( a6.data() , nullptr); + + auto a7 = tensor_type{4,1,2}; + BOOST_CHECK_EQUAL( a7.size() , 4*1*2 ); + BOOST_CHECK( !a7.empty() ); + BOOST_CHECK_NE( a7.data() , nullptr); +} + + +struct fixture +{ + using extents_type = boost::numeric::ublas::basic_extents<std::size_t>; + fixture() + : extents { + extents_type{}, // 0 + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{2,3,1}, // 5 + extents_type{4,1,3}, // 6 + extents_type{1,2,3}, // 7 + extents_type{4,2,3}, // 8 + extents_type{4,2,3,5}} // 9 + { + } + std::vector<extents_type> extents; +}; + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ctor_extents, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto check = [](auto const& e) { + auto t = tensor_type{e}; + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + if(e.empty()) { + BOOST_CHECK ( t.empty() ); + BOOST_CHECK_EQUAL ( t.data() , nullptr); + } + else{ + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + } + }; + + for(auto const& e : extents) + check(e); +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_copy_ctor, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto check = [](auto const& e) + { + auto r = tensor_type{e}; + auto t = r; + BOOST_CHECK_EQUAL ( t.size() , r.size() ); + BOOST_CHECK_EQUAL ( t.rank() , r.rank() ); + BOOST_CHECK ( t.strides() == r.strides() ); + BOOST_CHECK ( t.extents() == r.extents() ); + + if(e.empty()) { + BOOST_CHECK ( t.empty() ); + BOOST_CHECK_EQUAL ( t.data() , nullptr); + } + else{ + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + } + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( t[i], r[i] ); + }; + + for(auto const& e : extents) + check(e); +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_copy_ctor_layout, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using other_layout_type = std::conditional_t<std::is_same<ublas::first_order,layout_type>::value, ublas::last_order, ublas::first_order>; + using other_tensor_type = ublas::tensor<value_type, other_layout_type>; + + + for(auto const& e : extents) + { + auto r = tensor_type{e}; + other_tensor_type t = r; + tensor_type q = t; + + BOOST_CHECK_EQUAL ( t.size() , r.size() ); + BOOST_CHECK_EQUAL ( t.rank() , r.rank() ); + BOOST_CHECK ( t.extents() == r.extents() ); + + BOOST_CHECK_EQUAL ( q.size() , r.size() ); + BOOST_CHECK_EQUAL ( q.rank() , r.rank() ); + BOOST_CHECK ( q.strides() == r.strides() ); + BOOST_CHECK ( q.extents() == r.extents() ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( q[i], r[i] ); + } +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_copy_move_ctor, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto check = [](auto const& e) + { + auto r = tensor_type{e}; + auto t = std::move(r); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + + if(e.empty()) { + BOOST_CHECK ( t.empty() ); + BOOST_CHECK_EQUAL ( t.data() , nullptr); + } + else{ + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + } + + }; + + for(auto const& e : extents) + check(e); +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ctor_extents_init, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + std::random_device device{}; + std::minstd_rand0 generator(device()); + + using distribution_type = std::conditional_t<std::is_integral_v<value_type>, std::uniform_int_distribution<>, std::uniform_real_distribution<> >; + auto distribution = distribution_type(1,6); + + for(auto const& e : extents){ + auto r = static_cast<value_type>(distribution(generator)); + auto t = tensor_type{e,r}; + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( t[i], r ); + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_ctor_extents_array, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using array_type = typename tensor_type::array_type; + + for(auto const& e : extents) { + auto a = array_type(e.product()); + auto v = value_type {}; + + for(auto& aa : a){ + aa = v; + v += value_type{1}; + } + auto t = tensor_type{e, a}; + v = value_type{}; + + for(auto i = 0ul; i < t.size(); ++i, v+=value_type{1}) + BOOST_CHECK_EQUAL( t[i], v); + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_read_write_single_index_access, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + for(auto const& e : extents) { + auto t = tensor_type{e}; + auto v = value_type {}; + for(auto i = 0ul; i < t.size(); ++i, v+=value_type{1}){ + t[i] = v; + BOOST_CHECK_EQUAL( t[i], v ); + + t(i) = v; + BOOST_CHECK_EQUAL( t(i), v ); + } + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_read_write_multi_index_access_at, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + auto check1 = [](const tensor_type& t) + { + auto v = value_type{}; + for(auto k = 0ul; k < t.size(); ++k){ + BOOST_CHECK_EQUAL(t[k], v); + v+=value_type{1}; + } + }; + + auto check2 = [](const tensor_type& t) + { + std::array<unsigned,2> k; + auto r = std::is_same_v<layout_type,ublas::first_order> ? 1 : 0; + auto q = std::is_same_v<layout_type,ublas::last_order > ? 1 : 0; + auto v = value_type{}; + for(k[r] = 0ul; k[r] < t.size(r); ++k[r]){ + for(k[q] = 0ul; k[q] < t.size(q); ++k[q]){ + BOOST_CHECK_EQUAL(t.at(k[0],k[1]), v); + v+=value_type{1}; + } + } + }; + + auto check3 = [](const tensor_type& t) + { + std::array<unsigned,3> k; + using op_type = std::conditional_t<std::is_same_v<layout_type,ublas::first_order>, std::minus<>, std::plus<>>; + auto r = std::is_same_v<layout_type,ublas::first_order> ? 2 : 0; + auto o = op_type{}; + auto v = value_type{}; + for(k[r] = 0ul; k[r] < t.size(r); ++k[r]){ + for(k[o(r,1)] = 0ul; k[o(r,1)] < t.size(o(r,1)); ++k[o(r,1)]){ + for(k[o(r,2)] = 0ul; k[o(r,2)] < t.size(o(r,2)); ++k[o(r,2)]){ + BOOST_CHECK_EQUAL(t.at(k[0],k[1],k[2]), v); + v+=value_type{1}; + } + } + } + }; + + auto check4 = [](const tensor_type& t) + { + std::array<unsigned,4> k; + using op_type = std::conditional_t<std::is_same_v<layout_type,ublas::first_order>, std::minus<>, std::plus<>>; + auto r = std::is_same_v<layout_type,ublas::first_order> ? 3 : 0; + auto o = op_type{}; + auto v = value_type{}; + for(k[r] = 0ul; k[r] < t.size(r); ++k[r]){ + for(k[o(r,1)] = 0ul; k[o(r,1)] < t.size(o(r,1)); ++k[o(r,1)]){ + for(k[o(r,2)] = 0ul; k[o(r,2)] < t.size(o(r,2)); ++k[o(r,2)]){ + for(k[o(r,3)] = 0ul; k[o(r,3)] < t.size(o(r,3)); ++k[o(r,3)]){ + BOOST_CHECK_EQUAL(t.at(k[0],k[1],k[2],k[3]), v); + v+=value_type{1}; + } + } + } + } + }; + + auto check = [check1,check2,check3,check4](auto const& e) { + auto t = tensor_type{e}; + auto v = value_type {}; + for(auto i = 0ul; i < t.size(); ++i){ + t[i] = v; + v+=value_type{1}; + } + + if(t.rank() == 1) check1(t); + else if(t.rank() == 2) check2(t); + else if(t.rank() == 3) check3(t); + else if(t.rank() == 4) check4(t); + + }; + + for(auto const& e : extents) + check(e); +} + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_reshape, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + + for(auto const& efrom : extents){ + for(auto const& eto : extents){ + + auto v = value_type {}; + v+=value_type{1}; + auto t = tensor_type{efrom, v}; + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( t[i], v ); + + t.reshape(eto); + for(auto i = 0ul; i < std::min(efrom.product(),eto.product()); ++i) + BOOST_CHECK_EQUAL( t[i], v ); + + BOOST_CHECK_EQUAL ( t.size() , eto.product() ); + BOOST_CHECK_EQUAL ( t.rank() , eto.size() ); + BOOST_CHECK ( t.extents() == eto ); + + if(efrom != eto){ + for(auto i = efrom.product(); i < t.size(); ++i) + BOOST_CHECK_EQUAL( t[i], value_type{} ); + } + } + } +} + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_swap, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + for(auto const& e_t : extents){ + for(auto const& e_r : extents) { + + auto v = value_type {} + value_type{1}; + auto w = value_type {} + value_type{2}; + auto t = tensor_type{e_t, v}; + auto r = tensor_type{e_r, w}; + + std::swap( r, t ); + + for(auto i = 0ul; i < t.size(); ++i) + BOOST_CHECK_EQUAL( t[i], w ); + + BOOST_CHECK_EQUAL ( t.size() , e_r.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e_r.size() ); + BOOST_CHECK ( t.extents() == e_r ); + + for(auto i = 0ul; i < r.size(); ++i) + BOOST_CHECK_EQUAL( r[i], v ); + + BOOST_CHECK_EQUAL ( r.size() , e_t.product() ); + BOOST_CHECK_EQUAL ( r.rank() , e_t.size() ); + BOOST_CHECK ( r.extents() == e_t ); + + + } + } +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_standard_iterator, value, test_types, fixture) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + + for(auto const& e : extents) + { + auto v = value_type {} + value_type{1}; + auto t = tensor_type{e, v}; + + BOOST_CHECK_EQUAL( std::distance(t.begin(), t.end ()), t.size() ); + BOOST_CHECK_EQUAL( std::distance(t.rbegin(), t.rend()), t.size() ); + + BOOST_CHECK_EQUAL( std::distance(t.cbegin(), t.cend ()), t.size() ); + BOOST_CHECK_EQUAL( std::distance(t.crbegin(), t.crend()), t.size() ); + + if(t.size() > 0) { + BOOST_CHECK( t.data() == std::addressof( *t.begin () ) ) ; + BOOST_CHECK( t.data() == std::addressof( *t.cbegin() ) ) ; + } + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/ublas/test/tensor/test_tensor_matrix_vector.cpp b/src/boost/libs/numeric/ublas/test/tensor/test_tensor_matrix_vector.cpp new file mode 100644 index 000000000..3e34047dd --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/test_tensor_matrix_vector.cpp @@ -0,0 +1,472 @@ +// Copyright (c) 2018-2019 Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + + +#include <iostream> +#include <random> +#include <boost/numeric/ublas/tensor.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/test/unit_test.hpp> + +#include "utility.hpp" + +// BOOST_AUTO_TEST_SUITE ( test_tensor_matrix_interoperability, * boost::unit_test::depends_on("test_tensor") ) ; + +BOOST_AUTO_TEST_SUITE ( test_tensor_matrix_interoperability ) + +using test_types = zip<int,long,float,double>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_tensor_matrix_copy_ctor, value, test_types) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using matrix_type = typename tensor_type::matrix_type; + + tensor_type a1 = matrix_type(); + BOOST_CHECK_EQUAL( a1.size() , 0ul ); + BOOST_CHECK( a1.empty() ); + BOOST_CHECK_EQUAL( a1.data() , nullptr); + + tensor_type a2 = matrix_type(1,1); + BOOST_CHECK_EQUAL( a2.size() , 1 ); + BOOST_CHECK( !a2.empty() ); + BOOST_CHECK_NE( a2.data() , nullptr); + + tensor_type a3 = matrix_type(2,1); + BOOST_CHECK_EQUAL( a3.size() , 2 ); + BOOST_CHECK( !a3.empty() ); + BOOST_CHECK_NE( a3.data() , nullptr); + + tensor_type a4 = matrix_type(1,2); + BOOST_CHECK_EQUAL( a4.size() , 2 ); + BOOST_CHECK( !a4.empty() ); + BOOST_CHECK_NE( a4.data() , nullptr); + + tensor_type a5 = matrix_type(2,3); + BOOST_CHECK_EQUAL( a5.size() , 6 ); + BOOST_CHECK( !a5.empty() ); + BOOST_CHECK_NE( a5.data() , nullptr); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_tensor_vector_copy_ctor, value, test_types) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using vector_type = typename tensor_type::vector_type; + + tensor_type a1 = vector_type(); + BOOST_CHECK_EQUAL( a1.size() , 0ul ); + BOOST_CHECK( a1.empty() ); + BOOST_CHECK_EQUAL( a1.data() , nullptr); + + tensor_type a2 = vector_type(1); + BOOST_CHECK_EQUAL( a2.size() , 1 ); + BOOST_CHECK( !a2.empty() ); + BOOST_CHECK_NE( a2.data() , nullptr); + + tensor_type a3 = vector_type(2); + BOOST_CHECK_EQUAL( a3.size() , 2 ); + BOOST_CHECK( !a3.empty() ); + BOOST_CHECK_NE( a3.data() , nullptr); + + tensor_type a4 = vector_type(2); + BOOST_CHECK_EQUAL( a4.size() , 2 ); + BOOST_CHECK( !a4.empty() ); + BOOST_CHECK_NE( a4.data() , nullptr); + + tensor_type a5 = vector_type(3); + BOOST_CHECK_EQUAL( a5.size() , 3 ); + BOOST_CHECK( !a5.empty() ); + BOOST_CHECK_NE( a5.data() , nullptr); +} + + +struct fixture +{ + using extents_type = boost::numeric::ublas::basic_extents<std::size_t>; + fixture() + : extents{ + extents_type{1,1}, // 1 + extents_type{1,2}, // 2 + extents_type{2,1}, // 3 + extents_type{2,3}, // 4 + extents_type{9,7}, // 5 + extents_type{9,11}, // 6 + extents_type{12,12}, // 7 + extents_type{15,17}} // 8 + { + } + std::vector<extents_type> extents; +}; + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_matrix_copy_ctor_extents, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using matrix_type = typename tensor_type::matrix_type; + + auto check = [](auto const& e) { + assert(e.size()==2); + tensor_type t = matrix_type{e[0],e[1]}; + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + }; + + for(auto const& e : extents) + check(e); +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_vector_copy_ctor_extents, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using vector_type = typename tensor_type::vector_type; + + auto check = [](auto const& e) { + assert(e.size()==2); + if(e.empty()) + return; + + tensor_type t = vector_type(e.product()); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + }; + + for(auto const& e : extents) + check(e); +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_matrix_copy_assignment, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using matrix_type = typename tensor_type::matrix_type; + + auto check = [](auto const& e) + { + assert(e.size() == 2); + auto t = tensor_type{}; + auto r = matrix_type(e[0],e[1]); + std::iota(r.data().begin(),r.data().end(), 1); + t = r; + + BOOST_CHECK_EQUAL ( t.extents().at(0) , e.at(0) ); + BOOST_CHECK_EQUAL ( t.extents().at(1) , e.at(1) ); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + + for(auto j = 0ul; j < t.size(1); ++j){ + for(auto i = 0ul; i < t.size(0); ++i){ + BOOST_CHECK_EQUAL( t.at(i,j), r(i,j) ); + } + } + }; + + for(auto const& e : extents) + check(e); +} + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_vector_copy_assignment, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using vector_type = typename tensor_type::vector_type; + + auto check = [](auto const& e) + { + assert(e.size() == 2); + auto t = tensor_type{}; + auto r = vector_type(e[0]*e[1]); + std::iota(r.data().begin(),r.data().end(), 1); + t = r; + + BOOST_CHECK_EQUAL ( t.extents().at(0) , e.at(0)*e.at(1) ); + BOOST_CHECK_EQUAL ( t.extents().at(1) , 1); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + + for(auto i = 0ul; i < t.size(); ++i){ + BOOST_CHECK_EQUAL( t[i], r(i) ); + } + }; + + for(auto const& e : extents) + check(e); +} + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_matrix_move_assignment, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using matrix_type = typename tensor_type::matrix_type; + + auto check = [](auto const& e) + { + assert(e.size() == 2); + auto t = tensor_type{}; + auto r = matrix_type(e[0],e[1]); + std::iota(r.data().begin(),r.data().end(), 1); + auto q = r; + t = std::move(r); + + BOOST_CHECK_EQUAL ( t.extents().at(0) , e.at(0) ); + BOOST_CHECK_EQUAL ( t.extents().at(1) , e.at(1) ); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + + for(auto j = 0ul; j < t.size(1); ++j){ + for(auto i = 0ul; i < t.size(0); ++i){ + BOOST_CHECK_EQUAL( t.at(i,j), q(i,j) ); + } + } + }; + + for(auto const& e : extents) + check(e); +} + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_vector_move_assignment, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using vector_type = typename tensor_type::vector_type; + + auto check = [](auto const& e) + { + assert(e.size() == 2); + auto t = tensor_type{}; + auto r = vector_type(e[0]*e[1]); + std::iota(r.data().begin(),r.data().end(), 1); + auto q = r; + t = std::move(r); + + BOOST_CHECK_EQUAL ( t.extents().at(0) , e.at(0) * e.at(1)); + BOOST_CHECK_EQUAL ( t.extents().at(1) , 1); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + + for(auto i = 0ul; i < t.size(); ++i){ + BOOST_CHECK_EQUAL( t[i], q(i) ); + } + }; + + for(auto const& e : extents) + check(e); +} + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_matrix_expressions, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using matrix_type = typename tensor_type::matrix_type; + + auto check = [](auto const& e) + { + assert(e.size() == 2); + auto t = tensor_type{}; + auto r = matrix_type(e[0],e[1]); + std::iota(r.data().begin(),r.data().end(), 1); + t = r + 3*r; + tensor_type s = r + 3*r; + tensor_type q = s + r + 3*r + s; // + 3*r + + + BOOST_CHECK_EQUAL ( t.extents().at(0) , e.at(0) ); + BOOST_CHECK_EQUAL ( t.extents().at(1) , e.at(1) ); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + + BOOST_CHECK_EQUAL ( s.extents().at(0) , e.at(0) ); + BOOST_CHECK_EQUAL ( s.extents().at(1) , e.at(1) ); + BOOST_CHECK_EQUAL ( s.size() , e.product() ); + BOOST_CHECK_EQUAL ( s.rank() , e.size() ); + BOOST_CHECK ( !s.empty() ); + BOOST_CHECK_NE ( s.data() , nullptr); + + BOOST_CHECK_EQUAL ( q.extents().at(0) , e.at(0) ); + BOOST_CHECK_EQUAL ( q.extents().at(1) , e.at(1) ); + BOOST_CHECK_EQUAL ( q.size() , e.product() ); + BOOST_CHECK_EQUAL ( q.rank() , e.size() ); + BOOST_CHECK ( !q.empty() ); + BOOST_CHECK_NE ( q.data() , nullptr); + + + for(auto j = 0ul; j < t.size(1); ++j){ + for(auto i = 0ul; i < t.size(0); ++i){ + BOOST_CHECK_EQUAL( t.at(i,j), 4*r(i,j) ); + BOOST_CHECK_EQUAL( s.at(i,j), t.at(i,j) ); + BOOST_CHECK_EQUAL( q.at(i,j), 3*s.at(i,j) ); + } + } + }; + + for(auto const& e : extents) + check(e); +} + + + + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_vector_expressions, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using vector_type = typename tensor_type::vector_type; + + auto check = [](auto const& e) + { + assert(e.size() == 2); + auto t = tensor_type{}; + auto r = vector_type(e[0]*e[1]); + std::iota(r.data().begin(),r.data().end(), 1); + t = r + 3*r; + tensor_type s = r + 3*r; + tensor_type q = s + r + 3*r + s; // + 3*r + + + BOOST_CHECK_EQUAL ( t.extents().at(0) , e.at(0)*e.at(1) ); + BOOST_CHECK_EQUAL ( t.extents().at(1) , 1); + BOOST_CHECK_EQUAL ( t.size() , e.product() ); + BOOST_CHECK_EQUAL ( t.rank() , e.size() ); + BOOST_CHECK ( !t.empty() ); + BOOST_CHECK_NE ( t.data() , nullptr); + + BOOST_CHECK_EQUAL ( s.extents().at(0) , e.at(0)*e.at(1) ); + BOOST_CHECK_EQUAL ( s.extents().at(1) , 1); + BOOST_CHECK_EQUAL ( s.size() , e.product() ); + BOOST_CHECK_EQUAL ( s.rank() , e.size() ); + BOOST_CHECK ( !s.empty() ); + BOOST_CHECK_NE ( s.data() , nullptr); + + BOOST_CHECK_EQUAL ( q.extents().at(0) , e.at(0)*e.at(1) ); + BOOST_CHECK_EQUAL ( q.extents().at(1) , 1); + BOOST_CHECK_EQUAL ( q.size() , e.product() ); + BOOST_CHECK_EQUAL ( q.rank() , e.size() ); + BOOST_CHECK ( !q.empty() ); + BOOST_CHECK_NE ( q.data() , nullptr); + + + + for(auto i = 0ul; i < t.size(); ++i){ + BOOST_CHECK_EQUAL( t.at(i), 4*r(i) ); + BOOST_CHECK_EQUAL( s.at(i), t.at(i) ); + BOOST_CHECK_EQUAL( q.at(i), 3*s.at(i) ); + } + }; + + for(auto const& e : extents) + check(e); +} + + + +BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_matrix_vector_expressions, value, test_types, fixture ) +{ + using namespace boost::numeric; + using value_type = typename value::first_type; + using layout_type = typename value::second_type; + using tensor_type = ublas::tensor<value_type, layout_type>; + using matrix_type = typename tensor_type::matrix_type; + using vector_type = typename tensor_type::vector_type; + + auto check = [](auto const& e) + { + if(e.product() <= 2) + return; + assert(e.size() == 2); + auto Q = tensor_type{e[0],1}; + auto A = matrix_type(e[0],e[1]); + auto b = vector_type(e[1]); + auto c = vector_type(e[0]); + std::iota(b.data().begin(),b.data().end(), 1); + std::fill(A.data().begin(),A.data().end(), 1); + std::fill(c.data().begin(),c.data().end(), 2); + std::fill(Q.begin(),Q.end(), 2); + + tensor_type T = Q + (ublas::prod(A , b) + 2*c) + 3*Q; + + BOOST_CHECK_EQUAL ( T.extents().at(0) , Q.extents().at(0) ); + BOOST_CHECK_EQUAL ( T.extents().at(1) , Q.extents().at(1)); + BOOST_CHECK_EQUAL ( T.size() , Q.size() ); + BOOST_CHECK_EQUAL ( T.size() , c.size() ); + BOOST_CHECK_EQUAL ( T.rank() , Q.rank() ); + BOOST_CHECK ( !T.empty() ); + BOOST_CHECK_NE ( T.data() , nullptr); + + for(auto i = 0ul; i < T.size(); ++i){ + auto n = e[1]; + auto ab = n * (n+1) / 2; + BOOST_CHECK_EQUAL( T(i), ab+4*Q(0)+2*c(0) ); + } + + }; + + + + for(auto const& e : extents) + check(e); +} + + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/ublas/test/tensor/utility.hpp b/src/boost/libs/numeric/ublas/test/tensor/utility.hpp new file mode 100644 index 000000000..b2ef266e6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/tensor/utility.hpp @@ -0,0 +1,56 @@ +// Copyright (c) 2018-2019 +// Cem Bassoy +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// Fraunhofer and Google in producing this work +// which started as a Google Summer of Code project. +// + +#ifndef _BOOST_UBLAS_TEST_TENSOR_UTILITY_ +#define _BOOST_UBLAS_TEST_TENSOR_UTILITY_ + +template<class ... types> +struct zip_helper; + +template<class type1, class ... types3> +struct zip_helper<std::tuple<types3...>, type1> +{ + template<class ... types2> + struct with + { + using type = std::tuple<types3...,std::pair<type1,types2>...>; + }; + template<class ... types2> + using with_t = typename with<types2...>::type; +}; + + +template<class type1, class ... types3, class ... types1> +struct zip_helper<std::tuple<types3...>, type1, types1...> +{ + template<class ... types2> + struct with + { + using next_tuple = std::tuple<types3...,std::pair<type1,types2>...>; + using type = typename zip_helper<next_tuple, types1...>::template with<types2...>::type; + }; + + template<class ... types2> + using with_t = typename with<types2...>::type; +}; + +template<class ... types> +using zip = zip_helper<std::tuple<>,types...>; + +// creates e.g. +// using test_types = zip<long,float>::with_t<first_order,last_order>; // equals +// using test_types = std::tuple< std::pair<float, first_order>, std::pair<float, last_order >, std::pair<double,first_order>, std::pair<double,last_order > +//>; +//static_assert(std::is_same< std::tuple_element_t<0,std::tuple_element_t<0,test_types2>>, float>::value,"should be float "); +//static_assert(std::is_same< std::tuple_element_t<1,std::tuple_element_t<0,test_types2>>, boost::numeric::ublas::first_order>::value,"should be boost::numeric::ublas::first_order "); + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test1.cpp b/src/boost/libs/numeric/ublas/test/test1.cpp new file mode 100644 index 000000000..53de79019 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test1.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test1.hpp" + +int main () { + test_vector (); + test_matrix_vector (); + test_matrix (); + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test1.hpp b/src/boost/libs/numeric/ublas/test/test1.hpp new file mode 100644 index 000000000..fcf3d67a5 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test1.hpp @@ -0,0 +1,33 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST1_H +#define TEST1_H + +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_proxy.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/io.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +void test_vector (); +void test_matrix_vector (); +void test_matrix (); + + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test11.cpp b/src/boost/libs/numeric/ublas/test/test11.cpp new file mode 100644 index 000000000..2d3d27527 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test11.cpp @@ -0,0 +1,265 @@ +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. + +#include "test1.hpp" + +// Test vector expression templates +template<class V, int N> +struct test_my_vector { + typedef typename V::value_type value_type; + typedef typename V::size_type size_type; + typedef typename ublas::type_traits<value_type>::real_type real_type; + + template<class VP> + void test_container_with (VP &v1) const { + // Container type tests in addition to expression types + // Insert and erase + v1.insert_element (0, 55); + v1.erase_element (1); + v1.clear (); + } + + template<class VP> + void test_expression_with (VP &v1, VP &v2, VP &v3) const { + // Expression type tests + value_type t; + size_type i; + real_type n; + + // Default Construct + default_construct<VP>::test (); + + // Copy and swap + initialize_vector (v1); + initialize_vector (v2); + v1 = v2; + std::cout << "v1 = v2 = " << v1 << std::endl; + v1.assign_temporary (v2); + std::cout << "v1.assign_temporary (v2) = " << v1 << std::endl; + v1.swap (v2); + std::cout << "v1.swap (v2) = " << v1 << " " << v2 << std::endl; + + // Zero assignment + v1 = ublas::zero_vector<> (v1.size ()); + std::cout << "v1.zero_vector = " << v1 << std::endl; + v1 = v2; + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + // Project range and slice + initialize_vector (v1); + initialize_vector (v2); + project (v1, ublas::range(0,1)) = project (v2, ublas::range(0,1)); + project (v1, ublas::range(0,1)) = project (v2, ublas::slice(0,1,1)); + project (v1, ublas::slice(2,-1,2)) = project (v2, ublas::slice(0,1,2)); + project (v1, ublas::slice(2,-1,2)) = project (v2, ublas::range(0,2)); + std::cout << "v1 = range/slice " << v1 << std::endl; +#endif + + // Unary vector operations resulting in a vector + initialize_vector (v1); + v2 = - v1; + std::cout << "- v1 = " << v2 << std::endl; + v2 = ublas::conj (v1); + std::cout << "conj (v1) = " << v2 << std::endl; + + // Binary vector operations resulting in a vector + initialize_vector (v1); + initialize_vector (v2); + v3 = v1 + v2; + std::cout << "v1 + v2 = " << v3 << std::endl; + v3 = v1 - v2; + std::cout << "v1 - v2 = " << v3 << std::endl; + v3 = ublas::element_prod (v1, v2); + std::cout << "element_prod (v1, v2) = " << v3 << std::endl; + + // Scaling a vector + t = N; + initialize_vector (v1); + v2 = value_type (1.) * v1; + std::cout << "1. * v1 = " << v2 << std::endl; + v2 = t * v1; + std::cout << "N * v1 = " << v2 << std::endl; + initialize_vector (v1); + v2 = v1 * value_type (1.); + std::cout << "v1 * 1. = " << v2 << std::endl; + v2 = v1 * t; + std::cout << "v1 * value_type(N) = " << v2 << std::endl; + // test interop with integer + v2 = v1 * N; + + std::cout << "v1 * N = " << v2 << std::endl; + + // Some assignments + initialize_vector (v1); + initialize_vector (v2); + v2 += v1; + std::cout << "v2 += v1 = " << v2 << std::endl; + v2 -= v1; + std::cout << "v2 -= v1 = " << v2 << std::endl; + v2 = v2 + v1; + std::cout << "v2 = v2 + v1 = " << v2 << std::endl; + v2 = v2 - v1; + std::cout << "v2 = v2 - v1 = " << v2 << std::endl; + v1 *= value_type (1.); + std::cout << "v1 *= 1. = " << v1 << std::endl; + v1 *= t; + std::cout << "v1 *= value_type(N) = " << v1 << std::endl; + // test interop with integer + v1 *= N; + std::cout << "v1 *= N = " << v1 << std::endl; + + // Unary vector operations resulting in a scalar + initialize_vector (v1); + t = ublas::sum (v1); + std::cout << "sum (v1) = " << t << std::endl; + n = ublas::norm_1 (v1); + std::cout << "norm_1 (v1) = " << n << std::endl; + n = ublas::norm_2 (v1); + std::cout << "norm_2 (v1) = " << n << std::endl; + n = ublas::norm_inf (v1); + std::cout << "norm_inf (v1) = " << n << std::endl; + + i = ublas::index_norm_inf (v1); + std::cout << "index_norm_inf (v1) = " << i << std::endl; + + // Binary vector operations resulting in a scalar + initialize_vector (v1); + initialize_vector (v2); + t = ublas::inner_prod (v1, v2); + std::cout << "inner_prod (v1, v2) = " << t << std::endl; + + // Scalar and Binary vector expression resulting in a vector + initialize_vector (v1); + initialize_vector (v2); + v1 = v1 * ublas::inner_prod (v1, v2); + std::cout << "v1 * inner_prod (v1, v2) = " << v1 << std::endl; + } + + void operator () () const { + V v1 (N), v2 (N), v3 (N); + test_expression_with (v1, v2, v3); + test_container_with (v1); + +#ifdef USE_RANGE + ublas::vector_range<V> vr1 (v1, ublas::range (0, N)), + vr2 (v2, ublas::range (0, N)), + vr3 (v3, ublas::range (0, N)); + test_expression_with (vr1, vr2, vr3); +#endif + +#ifdef USE_SLICE + ublas::vector_slice<V> vs1 (v1, ublas::slice (0, 1, N)), + vs2 (v2, ublas::slice (0, 1, N)), + vs3 (v3, ublas::slice (0, 1, N)); + test_expression_with (vs1, vs2, vs3); +#endif + } +}; + +// Test vector +void test_vector () { + std::cout << "test_vector" << std::endl; + +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_vector<ublas::vector<float, ublas::unbounded_array<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_vector<ublas::vector<double, ublas::unbounded_array<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_vector<ublas::vector<float, std::vector<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_vector<ublas::vector<double, std::vector<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_BOUNDED_VECTOR +#ifdef USE_FLOAT + std::cout << "float, bounded" << std::endl; + test_my_vector<ublas::bounded_vector<float, 3>, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded" << std::endl; + test_my_vector<ublas::bounded_vector<double, 3>, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded" << std::endl; + test_my_vector<ublas::bounded_vector<std::complex<float>, 3>, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded" << std::endl; + test_my_vector<ublas::bounded_vector<std::complex<double>, 3>, 3> () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test12.cpp b/src/boost/libs/numeric/ublas/test/test12.cpp new file mode 100644 index 000000000..8c9e61da0 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test12.cpp @@ -0,0 +1,277 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test1.hpp" + +// Test matrix & vector expression templates +template<class V, class M, int N> +struct test_my_matrix_vector { + typedef typename V::value_type value_type; + + template<class VP, class MP> + void test_with (VP &v1, VP &v2, MP &m1) const { + { + // Rows and columns + initialize_matrix (m1); + for (int i = 0; i < N; ++ i) { + v1 = ublas::row (m1, i); + std::cout << "row (m, " << i << ") = " << v1 << std::endl; + v1 = ublas::column (m1, i); + std::cout << "column (m, " << i << ") = " << v1 << std::endl; + } + + // Outer product + initialize_vector (v1); + initialize_vector (v2); + m1 = ublas::outer_prod (v1, v2); + std::cout << "outer_prod (v1, v2) = " << m1 << std::endl; + + // Matrix vector product + initialize_matrix (m1); + initialize_vector (v1); + v2 = ublas::prod (m1, v1); + std::cout << "prod (m1, v1) = " << v2 << std::endl; + v2 = ublas::prod (v1, m1); + std::cout << "prod (v1, m1) = " << v2 << std::endl; + } + } + void operator () () const { + { + V v1 (N), v2 (N); + M m1 (N, N); + test_with (v1, v2, m1); + + ublas::matrix_row<M> mr1 (m1, 0), mr2 (m1, 1); + test_with (mr1, mr2, m1); + + ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, 1); + test_with (mc1, mc2, m1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (m1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, m1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, m1); +#endif + } + } +}; + +// Test matrix & vector +void test_matrix_vector () { + std::cout << "test_matrix_vector" << std::endl; + +#ifdef USE_MATRIX +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::matrix<float, ublas::row_major, std::vector<float> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::matrix<double, ublas::row_major, std::vector<double> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (); +#endif +#endif +#endif +#endif + +#ifdef USE_BOUNDED_MATRIX +#ifdef USE_FLOAT + std::cout << "float, bounded" << std::endl; + test_my_matrix_vector<ublas::bounded_vector<float, 3>, + ublas::bounded_matrix<float, 3, 3>, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded" << std::endl; + test_my_matrix_vector<ublas::bounded_vector<double, 3>, + ublas::bounded_matrix<double, 3, 3>, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded" << std::endl; + test_my_matrix_vector<ublas::bounded_vector<std::complex<float>, 3>, + ublas::bounded_matrix<std::complex<float>, 3, 3>, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded" << std::endl; + test_my_matrix_vector<ublas::bounded_vector<std::complex<double>, 3>, + ublas::bounded_matrix<std::complex<double>, 3, 3>, 3> () (); +#endif +#endif +#endif + +#ifdef USE_VECTOR_OF_VECTOR +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::vector_of_vector<float, ublas::row_major, ublas::bounded_array<ublas::bounded_array<float, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::vector_of_vector<double, ublas::row_major, ublas::bounded_array<ublas::bounded_array<double, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::vector_of_vector<std::complex<float>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<std::complex<float>, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::vector_of_vector<std::complex<double>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<std::complex<double>, 3>, 3 + 1> >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::vector_of_vector<float, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::vector_of_vector<double, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<double> > >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::vector_of_vector<std::complex<float>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<std::complex<float> > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::vector_of_vector<std::complex<double>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<std::complex<double> > > >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::vector_of_vector<float, ublas::row_major, std::vector<std::vector<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::vector_of_vector<double, ublas::row_major, std::vector<std::vector<double> > >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::vector_of_vector<std::complex<float>, ublas::row_major, std::vector<std::vector<std::complex<float> > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::vector_of_vector<std::complex<double>, ublas::row_major, std::vector<std::vector<std::complex<double> > > >, 3> () (); +#endif +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test13.cpp b/src/boost/libs/numeric/ublas/test/test13.cpp new file mode 100644 index 000000000..d84f321fe --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test13.cpp @@ -0,0 +1,325 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test1.hpp" + +// Test matrix expression templates +template<class M, int N> +struct test_my_matrix { + typedef typename M::value_type value_type; + + template<class VP> + void test_container_with (VP &v1) const { + // Container type tests in addition to expression types + // Insert and erase + v1.insert_element (0,0, 55); + v1.erase_element (1,1); + v1.clear (); + } + + template<class MP> + void test_expression_with (MP &m1, MP &m2, MP &m3) const { + value_type t; + + // Default Construct + default_construct<MP>::test (); + + // Copy and swap + initialize_matrix (m1); + initialize_matrix (m2); + m1 = m2; + std::cout << "m1 = m2 = " << m1 << std::endl; + m1.assign_temporary (m2); + std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl; + m1.swap (m2); + std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl; + + // Zero assignment + m1 = ublas::zero_matrix<> (m1.size1 (), m1.size2 ()); + std::cout << "m1.zero_matrix = " << m1 << std::endl; + m1 = m2; + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + // Project range and slice + initialize_matrix (m1); + initialize_matrix (m2); + project (m1, ublas::range(0,1),ublas::range(0,1)) = project (m2, ublas::range(0,1),ublas::range(0,1)); + project (m1, ublas::range(0,1),ublas::range(0,1)) = project (m2, ublas::slice(0,1,1),ublas::slice(0,1,1)); + project (m1, ublas::slice(2,-1,2),ublas::slice(2,-1,2)) = project (m2, ublas::slice(0,1,2),ublas::slice(0,1,2)); + project (m1, ublas::slice(2,-1,2),ublas::slice(2,-1,2)) = project (m2, ublas::range(0,2),ublas::range(0,2)); + std::cout << "m1 = range/slice " << m1 << std::endl; +#endif + + // Unary matrix operations resulting in a matrix + initialize_matrix (m1); + m2 = - m1; + std::cout << "- m1 = " << m2 << std::endl; + m2 = ublas::conj (m1); + std::cout << "conj (m1) = " << m2 << std::endl; + + // Binary matrix operations resulting in a matrix + initialize_matrix (m1); + initialize_matrix (m2); + m3 = m1 + m2; + std::cout << "m1 + m2 = " << m3 << std::endl; + m3 = m1 - m2; + std::cout << "m1 - m2 = " << m3 << std::endl; + m3 = ublas::element_prod (m1, m2); + std::cout << "element_prod (m1, m2) = " << m3 << std::endl; + + // Scaling a matrix + t = N; + initialize_matrix (m1); + m2 = value_type (1.) * m1; + std::cout << "1. * m1 = " << m2 << std::endl; + m2 = t * m1; + std::cout << "N * m1 = " << m2 << std::endl; + initialize_matrix (m1); + m2 = m1 * value_type (1.); + std::cout << "m1 * 1. = " << m2 << std::endl; + m2 = m1 * t; + std::cout << "m1 * N = " << m2 << std::endl; + m2 = m1 / value_type (2.); + std::cout << "m1 / 2. = " << m2 << std::endl; + m2 = m1 / t; + std::cout << "m1 / N = " << m2 << std::endl; + + // Some assignments + initialize_matrix (m1); + initialize_matrix (m2); + m2 += m1; + std::cout << "m2 += m1 = " << m2 << std::endl; + m2 -= m1; + std::cout << "m2 -= m1 = " << m2 << std::endl; + m2 = m2 + m1; + std::cout << "m2 = m2 + m1 = " << m2 << std::endl; + m2 = m2 - m1; + std::cout << "m2 = m2 - m1 = " << m2 << std::endl; + m1 *= value_type (1.); + std::cout << "m1 *= 1. = " << m1 << std::endl; + m1 *= t; + std::cout << "m1 *= N = " << m1 << std::endl; + + // Transpose + initialize_matrix (m1); + m2 = ublas::trans (m1); + std::cout << "trans (m1) = " << m2 << std::endl; + + // Hermitean + initialize_matrix (m1); + m2 = ublas::herm (m1); + std::cout << "herm (m1) = " << m2 << std::endl; + + // Matrix multiplication + initialize_matrix (m1); + initialize_matrix (m2); + m3 = ublas::prod (m1, m2); + std::cout << "prod (m1, m2) = " << m3 << std::endl; + } + + void operator () () const { + M m1 (N, N), m2 (N, N), m3 (N, N); + test_expression_with (m1, m2, m3); + test_container_with (m1); + +#ifdef USE_RANGE + ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mr2 (m2, ublas::range (0, N), ublas::range (0, N)), + mr3 (m3, ublas::range (0, N), ublas::range (0, N)); + test_expression_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_expression_with (ms1, ms2, ms3); +#endif + } +}; + +// Test matrix +void test_matrix () { + std::cout << "test_matrix" << std::endl; + +#ifdef USE_MATRIX +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix<ublas::matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix<ublas::matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix<ublas::matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix<ublas::matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix<ublas::matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix<ublas::matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix<ublas::matrix<float, ublas::row_major, std::vector<float> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix<ublas::matrix<double, ublas::row_major, std::vector<double> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix<ublas::matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix<ublas::matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (); +#endif +#endif +#endif +#endif + +#ifdef USE_BOUNDED_MATRIX +#ifdef USE_FLOAT + std::cout << "float, bounded" << std::endl; + test_my_matrix<ublas::bounded_matrix<float, 3, 3>, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded" << std::endl; + test_my_matrix<ublas::bounded_matrix<double, 3, 3>, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded" << std::endl; + test_my_matrix<ublas::bounded_matrix<std::complex<float>, 3, 3>, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded" << std::endl; + test_my_matrix<ublas::bounded_matrix<std::complex<double>, 3, 3>, 3> () (); +#endif +#endif +#endif + +#ifdef USE_VECTOR_OF_VECTOR +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<float, ublas::row_major, ublas::bounded_array<ublas::bounded_array<float, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<double, ublas::row_major, ublas::bounded_array<ublas::bounded_array<double, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<std::complex<float>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<std::complex<float>, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<std::complex<double>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<std::complex<double>, 3>, 3 + 1> >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<float, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<double, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<double> > >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<std::complex<float>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<std::complex<float> > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<std::complex<double>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<std::complex<double> > > >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix<ublas::vector_of_vector<float, ublas::row_major, std::vector<std::vector<float > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix<ublas::vector_of_vector<double, ublas::row_major, std::vector<std::vector<double> > >, 3> () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix<ublas::vector_of_vector<std::complex<float>, ublas::row_major, std::vector<std::vector<std::complex<float> > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix<ublas::vector_of_vector<std::complex<double>, ublas::row_major, std::vector<std::vector<std::complex<double> > > >, 3> () (); +#endif +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test2.cpp b/src/boost/libs/numeric/ublas/test/test2.cpp new file mode 100644 index 000000000..07a4c7558 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test2.cpp @@ -0,0 +1,87 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test2.hpp" + +int main () { +#ifdef USE_FLOAT + std::cout << "float" << std::endl; + test_blas_1<ublas::vector<float>, 3> ().test (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double" << std::endl; + test_blas_1<ublas::vector<double>, 3> ().test (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>" << std::endl; + test_blas_1<ublas::vector<std::complex<float> >, 3> ().test (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>" << std::endl; + test_blas_1<ublas::vector<std::complex<double> >, 3> ().test (); +#endif +#endif + + std::cout << "test_blas_2" << std::endl; + +#ifdef USE_FLOAT + std::cout << "float" << std::endl; + test_blas_2<ublas::vector<float>, ublas::matrix<float>, 3> ().test (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double" << std::endl; + test_blas_2<ublas::vector<double>, ublas::matrix<double>, 3> ().test (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>" << std::endl; + test_blas_2<ublas::vector<std::complex<float> >, ublas::matrix<std::complex<float> >, 3> ().test (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>" << std::endl; + test_blas_2<ublas::vector<std::complex<double> >, ublas::matrix<std::complex<double> >, 3> ().test (); +#endif +#endif + + std::cout << "test_blas_3" << std::endl; + +#ifdef USE_FLOAT + std::cout << "float" << std::endl; + test_blas_3<ublas::matrix<float>, 3> ().test (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double" << std::endl; + test_blas_3<ublas::matrix<double>, 3> ().test (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>" << std::endl; + test_blas_3<ublas::matrix<std::complex<float> >, 3> ().test (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>" << std::endl; + test_blas_3<ublas::matrix<std::complex<double> >, 3> ().test (); +#endif +#endif + + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test2.hpp b/src/boost/libs/numeric/ublas/test/test2.hpp new file mode 100644 index 000000000..d4d4baa57 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test2.hpp @@ -0,0 +1,51 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST2_H +#define TEST2_H + +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/numeric/ublas/io.hpp> +#include <boost/numeric/ublas/blas.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +template<class V, std::size_t N> +struct test_blas_1 { + typedef typename V::value_type value_type; + typedef typename ublas::type_traits<value_type>::real_type real_type; + + void test (); +}; + +template<class V, class M, std::size_t N> +struct test_blas_2 { + typedef typename V::value_type value_type; + + void test (); +}; + +template<class M, std::size_t N> +struct test_blas_3 { + typedef typename M::value_type value_type; + + void test (); +}; + + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test21.cpp b/src/boost/libs/numeric/ublas/test/test21.cpp new file mode 100644 index 000000000..408b17dc0 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test21.cpp @@ -0,0 +1,95 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test2.hpp" + +template<class V, std::size_t N> +void test_blas_1<V, N>::test () { + { + value_type t; + real_type n; + V v1 (N), v2 (N); + + // _asum + initialize_vector (v1); + n = ublas::blas_1::asum (v1); + std::cout << "asum (v1) = " << n << std::endl; + + // _amax + initialize_vector (v1); + n = ublas::blas_1::amax (v1); + std::cout << "amax (v1) = " << n << std::endl; + + // _nrm2 + initialize_vector (v1); + n = ublas::blas_1::nrm2 (v1); + std::cout << "nrm2 (v1) = " << n << std::endl; + + // _dot + // _dotu + // _dotc + initialize_vector (v1); + initialize_vector (v2); + t = ublas::blas_1::dot (v1, v2); + std::cout << "dot (v1, v2) = " << t << std::endl; + t = ublas::blas_1::dot (ublas::conj (v1), v2); + std::cout << "dot (conj (v1), v2) = " << t << std::endl; + + // _copy + initialize_vector (v2); + ublas::blas_1::copy (v1, v2); + std::cout << "copy (v1, v2) = " << v1 << std::endl; + + // _swap + initialize_vector (v1); + initialize_vector (v2); + ublas::blas_1::swap (v1, v2); + std::cout << "swap (v1, v2) = " << v1 << " " << v2 << std::endl; + + // _scal + // csscal + // zdscal + initialize_vector (v1); + ublas::blas_1::scal (v1, value_type (1)); + std::cout << "scal (v1, 1) = " << v1 << std::endl; + + // _axpy + initialize_vector (v1); + initialize_vector (v2); + ublas::blas_1::axpy (v1, value_type (1), v2); + std::cout << "axpy (v1, 1, v2) = " << v1 << std::endl; + + // _rot + initialize_vector (v1); + initialize_vector (v2); + ublas::blas_1::rot (value_type (1), v1, value_type (1), v2); + std::cout << "rot (1, v1, 1, v2) = " << v1 << " " << v2 << std::endl; + } +} + +#ifdef USE_FLOAT +template struct test_blas_1<ublas::vector<float>, 3>; +#endif + +#ifdef USE_DOUBLE +template struct test_blas_1<ublas::vector<double>, 3>; +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT +template struct test_blas_1<ublas::vector<std::complex<float> >, 3>; +#endif + +#ifdef USE_DOUBLE +template struct test_blas_1<ublas::vector<std::complex<double> >, 3>; +#endif +#endif diff --git a/src/boost/libs/numeric/ublas/test/test22.cpp b/src/boost/libs/numeric/ublas/test/test22.cpp new file mode 100644 index 000000000..13b313ea4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test22.cpp @@ -0,0 +1,147 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test2.hpp" + +template<class V, class M, std::size_t N> +void test_blas_2<V, M, N>::test () { + { + V v1 (N), v2 (N); + M m (N, N); + + // _t_mv + initialize_vector (v1); + initialize_matrix (m); + ublas::blas_2::tmv (v1, m); + std::cout << "tmv (v1, m) = " << v1 << std::endl; + initialize_vector (v1); + initialize_matrix (m); + ublas::blas_2::tmv (v1, ublas::trans (m)); + std::cout << "tmv (v1, trans (m)) = " << v1 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_vector (v1); + initialize_matrix (m); + ublas::blas_2::tmv (v1, ublas::herm (m)); + std::cout << "tmv (v1, herm (m)) = " << v1 << std::endl; +#endif + + // _t_sv + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m, ublas::lower_tag ()); + ublas::blas_2::tsv (v1, m, ublas::lower_tag ()); + std::cout << "tsv (v1, m) = " << v1 << " " << ublas::prod (m, v1) - v2 << std::endl; + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m, ublas::upper_tag ()); + ublas::blas_2::tsv (v1, ublas::trans (m), ublas::lower_tag ()); + std::cout << "tsv (v1, trans (m)) = " << v1 << " " << ublas::prod (ublas::trans (m), v1) - v2 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m, ublas::upper_tag ()); + ublas::blas_2::tsv (v1, ublas::herm (m), ublas::lower_tag ()); + std::cout << "tsv (v1, herm (m)) = " << v1 << " " << ublas::prod (ublas::herm (m), v1) - v2 << std::endl; +#endif + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m, ublas::upper_tag ()); + ublas::blas_2::tsv (v1, m, ublas::upper_tag ()); + std::cout << "tsv (v1, m) = " << v1 << " " << ublas::prod (m, v1) - v2 << std::endl; + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m, ublas::lower_tag ()); + ublas::blas_2::tsv (v1, ublas::trans (m), ublas::upper_tag ()); + std::cout << "tsv (v1, trans (m)) = " << v1 << " " << ublas::prod (ublas::trans (m), v1) - v2 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m, ublas::lower_tag ()); + ublas::blas_2::tsv (v1, ublas::herm (m), ublas::upper_tag ()); + std::cout << "tsv (v1, herm (m)) = " << v1 << " " << ublas::prod (ublas::herm (m), v1) - v2 << std::endl; +#endif + + // _g_mv + // _s_mv + // _h_mv + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m); + ublas::blas_2::gmv (v1, value_type (1), value_type (1), m, v2); + std::cout << "gmv (v1, 1, 1, m, v2) = " << v1 << std::endl; + ublas::blas_2::gmv (v1, value_type (1), value_type (1), ublas::trans (m), v2); + std::cout << "gmv (v1, 1, 1, trans (m), v2) = " << v1 << std::endl; +#ifdef USE_STD_COMPLEX + ublas::blas_2::gmv (v1, value_type (1), value_type (1), ublas::herm (m), v2); + std::cout << "gmv (v1, 1, 1, herm (m), v2) = " << v1 << std::endl; +#endif + + // _g_r + // _g_ru + // _g_rc + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m); + ublas::blas_2::gr (m, value_type (1), v1, v2); + std::cout << "gr (m, 1, v1, v2) = " << m << std::endl; + ublas::blas_2::gr (m, value_type (1), v1, ublas::conj (v2)); + std::cout << "gr (m, 1, v1, conj (v2)) = " << m << std::endl; + + // _s_r + initialize_vector (v1); + initialize_matrix (m); + ublas::blas_2::sr (m, value_type (1), v1); + std::cout << "sr (m, 1, v1) = " << m << std::endl; + +#ifdef USE_STD_COMPLEX + // _h_r + initialize_vector (v1); + initialize_matrix (m); + ublas::blas_2::hr (m, value_type (1), v1); + std::cout << "hr (m, 1, v1) = " << m << std::endl; +#endif + + // _s_r2 + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m); + ublas::blas_2::sr2 (m, value_type (1), v1, v2); + std::cout << "sr2 (m, 1, v1, v2) = " << m << std::endl; + +#ifdef USE_STD_COMPLEX + // _h_r2 + initialize_vector (v1); + initialize_vector (v2); + initialize_matrix (m); + ublas::blas_2::hr2 (m, value_type (1), v1, v2); + std::cout << "hr2 (m, 1, v1, v2) = " << m << std::endl; +#endif + } +} + +#ifdef USE_FLOAT +template struct test_blas_2<ublas::vector<float>, ublas::matrix<float>, 3>; +#endif + +#ifdef USE_DOUBLE +template struct test_blas_2<ublas::vector<double>, ublas::matrix<double>, 3>; +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT +template struct test_blas_2<ublas::vector<std::complex<float> >, ublas::matrix<std::complex<float> >, 3>; +#endif + +#ifdef USE_DOUBLE +template struct test_blas_2<ublas::vector<std::complex<double> >, ublas::matrix<std::complex<double> >, 3>; +#endif +#endif diff --git a/src/boost/libs/numeric/ublas/test/test23.cpp b/src/boost/libs/numeric/ublas/test/test23.cpp new file mode 100644 index 000000000..2817710cf --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test23.cpp @@ -0,0 +1,208 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test2.hpp" + +template<class M, std::size_t N> +void test_blas_3<M, N>::test () { + { + M m1 (N, N), m2 (N, N), m3 (N, N); + + // _t_mm + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), m2, m1); + std::cout << "tmm (m1, 1, m2, m1) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), m2, ublas::trans (m1)); + std::cout << "tmm (m1, 1, m2, trans (m1)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), ublas::trans (m2), m1); + std::cout << "tmm (m1, 1, trans (m2), m1) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), ublas::trans (m2), ublas::trans (m1)); + std::cout << "tmm (m1, 1, trans (m2), trans (m1)) = " << m1 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), m2, ublas::herm (m1)); + std::cout << "tmm (m1, 1, m2, herm (m1)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), ublas::herm (m2), m1); + std::cout << "tmm (m1, 1, herm (m2), m1) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), ublas::trans (m2), ublas::herm (m1)); + std::cout << "tmm (m1, 1, trans (m2), herm (m1)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), ublas::herm (m2), ublas::trans (m1)); + std::cout << "tmm (m1, 1, herm (m2), trans (m1)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::tmm (m1, value_type (1), ublas::herm (m2), ublas::herm (m1)); + std::cout << "tmm (m1, 1, herm (m2), herm (m1)) = " << m1 << std::endl; +#endif + + // _t_sm + initialize_matrix (m1); + initialize_matrix (m2, ublas::lower_tag ()); + initialize_matrix (m3); + ublas::blas_3::tsm (m1, value_type (1), m2, ublas::lower_tag ()); + std::cout << "tsm (m1, 1, m2) = " << m1 << " " << ublas::prod (m2, m1) - value_type (1) * m3 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2, ublas::upper_tag ()); + ublas::blas_3::tsm (m1, value_type (1), ublas::trans (m2), ublas::lower_tag ()); + std::cout << "tsm (m1, 1, trans (m2)) = " << m1 << " " << ublas::prod (ublas::trans (m2), m1) - value_type (1) * m3 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_matrix (m1); + initialize_matrix (m2, ublas::upper_tag ()); + ublas::blas_3::tsm (m1, value_type (1), ublas::herm (m2), ublas::lower_tag ()); + std::cout << "tsm (m1, 1, herm (m2)) = " << m1 << " " << ublas::prod (ublas::herm (m2), m1) - value_type (1) * m3 << std::endl; +#endif + initialize_matrix (m1); + initialize_matrix (m2, ublas::upper_tag ()); + ublas::blas_3::tsm (m1, value_type (1), m2, ublas::upper_tag ()); + std::cout << "tsm (m1, 1, m2) = " << m1 << " " << ublas::prod (m2, m1) - value_type (1) * m3 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2, ublas::lower_tag ()); + ublas::blas_3::tsm (m1, value_type (1), ublas::trans (m2), ublas::upper_tag ()); + std::cout << "tsm (m1, 1, trans (m2)) = " << m1 << " " << ublas::prod (ublas::trans (m2), m1) - value_type (1) * m3 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_matrix (m1); + initialize_matrix (m2, ublas::lower_tag ()); + ublas::blas_3::tsm (m1, value_type (1), ublas::herm (m2), ublas::upper_tag ()); + std::cout << "tsm (m1, 1, herm (m2)) = " << m1 << " " << ublas::prod (ublas::herm (m2), m1) - value_type (1) * m3 << std::endl; +#endif + + // _g_mm + // _s_mm + // _h_mm + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), m2, m3); + std::cout << "gmm (m1, 1, 1, m2, m3) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::trans (m2), m3); + std::cout << "gmm (m1, 1, 1, trans (m2), m3) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), m2, ublas::trans (m3)); + std::cout << "gmm (m1, 1, 1, m2, trans (m3)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::trans (m2), ublas::trans (m3)); + std::cout << "gmm (m1, 1, 1, trans (m2), trans (m3)) = " << m1 << std::endl; +#ifdef USE_STD_COMPLEX + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::herm (m2), m3); + std::cout << "gmm (m1, 1, 1, herm (m2), m3) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), m2, ublas::herm (m3)); + std::cout << "gmm (m1, 1, 1, m2, herm (m3)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::herm (m2), ublas::trans (m3)); + std::cout << "gmm (m1, 1, 1, herm (m2), trans (m3)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::trans (m2), ublas::herm (m3)); + std::cout << "gmm (m1, 1, 1, trans (m2), herm (m3)) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::herm (m2), ublas::herm (m3)); + std::cout << "gmm (m1, 1, 1, herm (m2), herm (m3)) = " << m1 << std::endl; +#endif + + // s_rk + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::srk (m1, value_type (1), value_type (1), m2); + std::cout << "srk (m1, 1, 1, m2) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::srk (m1, value_type (1), value_type (1), ublas::trans (m2)); + std::cout << "srk (m1, 1, 1, trans (m2)) = " << m1 << std::endl; + +#ifdef USE_STD_COMPLEX + // h_rk + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::hrk (m1, value_type (1), value_type (1), m2); + std::cout << "hrk (m1, 1, 1, m2) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + ublas::blas_3::hrk (m1, value_type (1), value_type (1), ublas::herm (m2)); + std::cout << "hrk (m1, 1, 1, herm (m2)) = " << m1 << std::endl; +#endif + + // s_r2k + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::sr2k (m1, value_type (1), value_type (1), m2, m3); + std::cout << "sr2k (m1, 1, 1, m2, m3) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::sr2k (m1, value_type (1), value_type (1), ublas::trans (m2), ublas::trans (m3)); + std::cout << "sr2k (m1, 1, 1, trans (m2), trans (m3)) = " << m1 << std::endl; + +#ifdef USE_STD_COMPLEX + // h_r2k + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::hr2k (m1, value_type (1), value_type (1), m2, m3); + std::cout << "hr2k (m1, 1, 1, m2, m3) = " << m1 << std::endl; + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + ublas::blas_3::hr2k (m1, value_type (1), value_type (1), ublas::herm (m2), ublas::herm (m3)); + std::cout << "hr2k (m1, 1, 1, herm (m2), herm (m3)) = " << m1 << std::endl; +#endif + } +} + +#ifdef USE_FLOAT +template struct test_blas_3<ublas::matrix<float>, 3>; +#endif + +#ifdef USE_DOUBLE +template struct test_blas_3<ublas::matrix<double>, 3>; +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT +template struct test_blas_3<ublas::matrix<std::complex<float> >, 3>; +#endif + +#ifdef USE_DOUBLE +template struct test_blas_3<ublas::matrix<std::complex<double> >, 3>; +#endif +#endif diff --git a/src/boost/libs/numeric/ublas/test/test3.cpp b/src/boost/libs/numeric/ublas/test/test3.cpp new file mode 100644 index 000000000..fb2b94dad --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test3.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test3.hpp" + +int main () { + test_vector (); + test_matrix_vector (); + test_matrix (); + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test3.hpp b/src/boost/libs/numeric/ublas/test/test3.hpp new file mode 100644 index 000000000..a9d4fc957 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test3.hpp @@ -0,0 +1,38 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST3_H +#define TEST3_H + +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_proxy.hpp> +#include <boost/numeric/ublas/vector_sparse.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/vector_sparse.hpp> +#ifdef USE_GENERALIZED_VECTOR_OF_VECTOR +#include <boost/numeric/ublas/vector_of_vector.hpp> +#endif +#include <boost/numeric/ublas/io.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +void test_vector (); +void test_matrix_vector (); +void test_matrix (); + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test31.cpp b/src/boost/libs/numeric/ublas/test/test31.cpp new file mode 100644 index 000000000..776228720 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test31.cpp @@ -0,0 +1,248 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test3.hpp" + +// Test vector expression templates +template<class V, int N> +struct test_my_vector { + typedef typename V::value_type value_type; + typedef typename V::size_type size_type; + typedef typename ublas::type_traits<value_type>::real_type real_type; + + template<class VP> + void test_with (VP &v1, VP &v2, VP &v3) const { + { + value_type t; + size_type i; + real_type n; + + // Default Construct + default_construct<VP>::test (); + + // Copy and swap + initialize_vector (v1); + initialize_vector (v2); + v1 = v2; + std::cout << "v1 = v2 = " << v1 << std::endl; + v1.assign_temporary (v2); + std::cout << "v1.assign_temporary (v2) = " << v1 << std::endl; + v1.swap (v2); + std::cout << "v1.swap (v2) = " << v1 << " " << v2 << std::endl; + + // Zero assignment + v1 = ublas::zero_vector<> (v1.size ()); + std::cout << "v1.zero_vector = " << v1 << std::endl; + v1 = v2; + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + // Project range and slice + initialize_vector (v1); + initialize_vector (v2); + project (v1, ublas::range(0,1)) = project (v2, ublas::range(0,1)); + project (v1, ublas::range(0,1)) = project (v2, ublas::slice(0,1,1)); + project (v1, ublas::slice(2,-1,2)) = project (v2, ublas::slice(0,1,2)); + project (v1, ublas::slice(2,-1,2)) = project (v2, ublas::range(0,2)); + std::cout << "v1 = range/slice " << v1 << std::endl; +#endif + + // Unary vector operations resulting in a vector + initialize_vector (v1); + v2 = - v1; + std::cout << "- v1 = " << v2 << std::endl; + v2 = ublas::conj (v1); + std::cout << "conj (v1) = " << v2 << std::endl; + + // Binary vector operations resulting in a vector + initialize_vector (v1); + initialize_vector (v2); + initialize_vector (v3); + v3 = v1 + v2; + std::cout << "v1 + v2 = " << v3 << std::endl; + + v3 = v1 - v2; + std::cout << "v1 - v2 = " << v3 << std::endl; + + // Scaling a vector + t = N; + initialize_vector (v1); + v2 = value_type (1.) * v1; + std::cout << "1. * v1 = " << v2 << std::endl; + v2 = t * v1; + std::cout << "N * v1 = " << v2 << std::endl; + initialize_vector (v1); + v2 = v1 * value_type (1.); + std::cout << "v1 * 1. = " << v2 << std::endl; + v2 = v1 * t; + std::cout << "v1 * N = " << v2 << std::endl; + + // Some assignments + initialize_vector (v1); + initialize_vector (v2); + v2 += v1; + std::cout << "v2 += v1 = " << v2 << std::endl; + v2 -= v1; + std::cout << "v2 -= v1 = " << v2 << std::endl; + v2 = v2 + v1; + std::cout << "v2 = v2 + v1 = " << v2 << std::endl; + v2 = v2 - v1; + std::cout << "v2 = v2 - v1 = " << v2 << std::endl; + v1 *= value_type (1.); + std::cout << "v1 *= 1. = " << v1 << std::endl; + v1 *= t; + std::cout << "v1 *= N = " << v1 << std::endl; + + // Unary vector operations resulting in a scalar + initialize_vector (v1); + t = ublas::sum (v1); + std::cout << "sum (v1) = " << t << std::endl; + n = ublas::norm_1 (v1); + std::cout << "norm_1 (v1) = " << n << std::endl; + n = ublas::norm_2 (v1); + std::cout << "norm_2 (v1) = " << n << std::endl; + n = ublas::norm_inf (v1); + std::cout << "norm_inf (v1) = " << n << std::endl; + + i = ublas::index_norm_inf (v1); + std::cout << "index_norm_inf (v1) = " << i << std::endl; + + // Binary vector operations resulting in a scalar + initialize_vector (v1); + initialize_vector (v2); + t = ublas::inner_prod (v1, v2); + std::cout << "inner_prod (v1, v2) = " << t << std::endl; + } + } + void operator () () const { + { + V v1 (N, N), v2 (N, N), v3 (N, N); + test_with (v1, v2, v3); + +#ifdef USE_RANGE + ublas::vector_range<V> vr1 (v1, ublas::range (0, N)), + vr2 (v2, ublas::range (0, N)), + vr3 (v3, ublas::range (0, N)); + test_with (vr1, vr2, vr3); +#endif + +#ifdef USE_SLICE + ublas::vector_slice<V> vs1 (v1, ublas::slice (0, 1, N)), + vs2 (v2, ublas::slice (0, 1, N)), + vs3 (v3, ublas::slice (0, 1, N)); + test_with (vs1, vs2, vs3); +#endif + } + } +}; + +// Test vector +void test_vector () { + std::cout << "test_vector" << std::endl; + +#ifdef USE_SPARSE_VECTOR +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float, map_array" << std::endl; + test_my_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, map_array" << std::endl; + test_my_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, map_array" << std::endl; + test_my_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, map_array" << std::endl; + test_my_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, std::map" << std::endl; + test_my_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::map" << std::endl; + test_my_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::map" << std::endl; + test_my_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::map" << std::endl; + test_my_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > , 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_COMPRESSED_VECTOR +#ifdef USE_FLOAT + std::cout << "float compressed" << std::endl; + test_my_vector<ublas::compressed_vector<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double compressed" << std::endl; + test_my_vector<ublas::compressed_vector<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> compressed" << std::endl; + test_my_vector<ublas::compressed_vector<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> compressed" << std::endl; + test_my_vector<ublas::compressed_vector<std::complex<double> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_COORDINATE_VECTOR +#ifdef USE_FLOAT + std::cout << "float coordinate" << std::endl; + test_my_vector<ublas::coordinate_vector<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double coordinate" << std::endl; + test_my_vector<ublas::coordinate_vector<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> coordinate" << std::endl; + test_my_vector<ublas::coordinate_vector<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> coordinate" << std::endl; + test_my_vector<ublas::coordinate_vector<std::complex<double> >, 3 > () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test32.cpp b/src/boost/libs/numeric/ublas/test/test32.cpp new file mode 100644 index 000000000..eaf492976 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test32.cpp @@ -0,0 +1,354 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test3.hpp" + +// Test matrix & vector expression templates +template<class V, class M, int N> +struct test_my_matrix_vector { + typedef typename V::value_type value_type; + + template<class VP, class MP> + void test_with (VP &v1, VP &v2, MP &m1) const { + { + // Rows and columns + initialize_matrix (m1); + for (int i = 0; i < N; ++ i) { + v1 = ublas::row (m1, i); + std::cout << "row (m, " << i << ") = " << v1 << std::endl; + v1 = ublas::column (m1, i); + std::cout << "column (m, " << i << ") = " << v1 << std::endl; + } + + // Outer product + initialize_vector (v1); + initialize_vector (v2); + m1 = ublas::outer_prod (v1, v2); + std::cout << "outer_prod (v1, v2) = " << m1 << std::endl; + + // Matrix vector product + initialize_matrix (m1); + initialize_vector (v1); + v2 = ublas::prod (m1, v1); + std::cout << "prod (m1, v1) = " << v2 << std::endl; + v2 = ublas::prod (v1, m1); + std::cout << "prod (v1, m1) = " << v2 << std::endl; + } + } + void operator () () const { + { + V v1 (N, N), v2 (N, N); + M m1 (N, N, N * N); + + test_with (v1, v2, m1); + + ublas::matrix_row<M> mr1 (m1, 0), mr2 (m1, N - 1); + test_with (mr1, mr2, m1); + + ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, N - 1); + test_with (mc1, mc2, m1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (m1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, m1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, m1); +#endif + } + } +}; + +// Test matrix & vector +void test_matrix_vector () { + std::cout << "test_matrix_vector" << std::endl; + +#ifdef USE_SPARSE_MATRIX +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float, map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, + ublas::mapped_matrix<float, ublas::row_major, ublas::map_array<std::size_t, float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, + ublas::mapped_matrix<double, ublas::row_major, ublas::map_array<std::size_t, double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, + ublas::mapped_matrix<std::complex<float>, ublas::row_major, ublas::map_array<std::size_t, std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, + ublas::mapped_matrix<std::complex<double>, ublas::row_major, ublas::map_array<std::size_t, std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, + ublas::mapped_matrix<float, ublas::row_major, std::map<std::size_t, float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, + ublas::mapped_matrix<double, ublas::row_major, std::map<std::size_t, double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, + ublas::mapped_matrix<std::complex<float>, ublas::row_major, std::map<std::size_t, std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, + ublas::mapped_matrix<std::complex<double>, ublas::row_major, std::map<std::size_t, std::complex<double> > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_SPARSE_VECTOR_OF_SPARSE_VECTOR +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float, mapped_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, + ublas::mapped_vector<float, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, mapped_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, + ublas::mapped_vector<double, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, double> > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, mapped_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, + ublas::mapped_vector<std::complex<float>, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, std::complex<float> > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>,mapped_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, + ublas::mapped_vector<std::complex<double>, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, std::complex<double> > > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, mapped_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, + ublas::mapped_vector<float, ublas::row_major, std::map<std::size_t, std::map<std::size_t, float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, mapped_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, + ublas::mapped_vector<double, ublas::row_major, std::map<std::size_t, std::map<std::size_t, double> > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, mapped_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, + ublas::mapped_vector<std::complex<float>, ublas::row_major, std::map<std::size_t, std::map<std::size_t, std::complex<float> > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, mapped_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, + ublas::mapped_vector<std::complex<double>, ublas::row_major, std::map<std::size_t, std::map<std::size_t, std::complex<double> > > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_GENERALIZED_VECTOR_OF_VECTOR +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, + ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, + ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, ublas::map_array<std::size_t, ublas::mapped_vector<float, ublas::map_array<std::size_t, float> > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, + ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, + ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, ublas::map_array<std::size_t, ublas::mapped_vector<double, ublas::map_array<std::size_t, double> > > > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, + ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, + ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, ublas::map_array<std::size_t, ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, + ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, + ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, ublas::map_array<std::size_t, ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > > > > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, + ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::vector<ublas::mapped_vector<float, std::map<std::size_t, float> > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, + ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, std::map<std::size_t, ublas::mapped_vector<float, std::map<std::size_t, float> > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, + ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::vector<ublas::mapped_vector<double, std::map<std::size_t, double> > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, + ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, std::map<std::size_t, ublas::mapped_vector<double, std::map<std::size_t, double> > > > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, + ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, + ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, std::map<std::size_t, ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, + ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > > >, 3 > () (); + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, + ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, std::map<std::size_t, ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > > > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_COMPRESSED_MATRIX +#ifdef USE_FLOAT + std::cout << "float compressed" << std::endl; + test_my_matrix_vector<ublas::compressed_vector<float>, + ublas::compressed_matrix<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double compressed" << std::endl; + test_my_matrix_vector<ublas::compressed_vector<double>, + ublas::compressed_matrix<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> compressed" << std::endl; + test_my_matrix_vector<ublas::compressed_vector<std::complex<float> >, + ublas::compressed_matrix<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> compressed" << std::endl; + test_my_matrix_vector<ublas::compressed_vector<std::complex<double> >, + ublas::compressed_matrix<std::complex<double> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_COORDINATE_MATRIX +#ifdef USE_FLOAT + std::cout << "float coordinate" << std::endl; + test_my_matrix_vector<ublas::coordinate_vector<float>, + ublas::coordinate_matrix<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double coordinate" << std::endl; + test_my_matrix_vector<ublas::coordinate_vector<double>, + ublas::coordinate_matrix<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> coordinate" << std::endl; + test_my_matrix_vector<ublas::coordinate_vector<std::complex<float> >, + ublas::coordinate_matrix<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> coordinate" << std::endl; + test_my_matrix_vector<ublas::coordinate_vector<std::complex<double> >, + ublas::coordinate_matrix<std::complex<double> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_MAPPED_VECTOR_OF_MAPPED_VECTOR +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, + ublas::mapped_vector_of_mapped_vector<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, + ublas::mapped_vector_of_mapped_vector<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, + ublas::mapped_vector_of_mapped_vector<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, + ublas::mapped_vector_of_mapped_vector<std::complex<double> >, 3 > () (); +#endif +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test33.cpp b/src/boost/libs/numeric/ublas/test/test33.cpp new file mode 100644 index 000000000..48e1424f4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test33.cpp @@ -0,0 +1,371 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test3.hpp" + +// Test matrix expression templates +template<class M, std::size_t N> +struct test_my_matrix { + typedef typename M::value_type value_type; + + template<class MP> + void test_with (MP &m1, MP &m2, MP &m3) const { + { + value_type t; + + // Default Construct + default_construct<MP>::test (); + + // Copy and swap + initialize_matrix (m1); + initialize_matrix (m2); + m1 = m2; + std::cout << "m1 = m2 = " << m1 << std::endl; + m1.assign_temporary (m2); + std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl; + m1.swap (m2); + std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl; + + // Zero assignment + m1 = ublas::zero_matrix<short> (m1.size1 (), m1.size2 ()); + std::cout << "m1.zero_matrix = " << m1 << std::endl; + m1 = m2; + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + // Project range and slice + initialize_matrix (m1); + initialize_matrix (m2); + project (m1, ublas::range(0,1),ublas::range(0,1)) = project (m2, ublas::range(0,1),ublas::range(0,1)); + project (m1, ublas::range(0,1),ublas::range(0,1)) = project (m2, ublas::slice(0,1,1),ublas::slice(0,1,1)); + project (m1, ublas::slice(2,-1,2),ublas::slice(2,-1,2)) = project (m2, ublas::slice(0,1,2),ublas::slice(0,1,2)); + project (m1, ublas::slice(2,-1,2),ublas::slice(2,-1,2)) = project (m2, ublas::range(0,2),ublas::range(0,2)); + std::cout << "m1 = range/slice " << m1 << std::endl; +#endif + + // Unary matrix operations resulting in a matrix + initialize_matrix (m1); + m2 = - m1; + std::cout << "- m1 = " << m2 << std::endl; + m2 = ublas::conj (m1); + std::cout << "conj (m1) = " << m2 << std::endl; + + // Binary matrix operations resulting in a matrix + initialize_matrix (m1); + initialize_matrix (m2); + initialize_matrix (m3); + m3 = m1 + m2; + std::cout << "m1 + m2 = " << m3 << std::endl; + m3 = m1 - m2; + std::cout << "m1 - m2 = " << m3 << std::endl; + + // Scaling a matrix + t = N; + initialize_matrix (m1); + m2 = value_type (1.) * m1; + std::cout << "1. * m1 = " << m2 << std::endl; + m2 = t * m1; + std::cout << "N * m1 = " << m2 << std::endl; + initialize_matrix (m1); + m2 = m1 * value_type (1.); + std::cout << "m1 * 1. = " << m2 << std::endl; + m2 = m1 * t; + std::cout << "m1 * N = " << m2 << std::endl; + + // Some assignments + initialize_matrix (m1); + initialize_matrix (m2); + m2 += m1; + std::cout << "m2 += m1 = " << m2 << std::endl; + m2 -= m1; + std::cout << "m2 -= m1 = " << m2 << std::endl; + m2 = m2 + m1; + std::cout << "m2 = m2 + m1 = " << m2 << std::endl; + m2 = m2 - m1; + std::cout << "m2 = m2 - m1 = " << m2 << std::endl; + m1 *= value_type (1.); + std::cout << "m1 *= 1. = " << m1 << std::endl; + m1 *= t; + std::cout << "m1 *= N = " << m1 << std::endl; + + // Transpose + initialize_matrix (m1); + m2 = ublas::trans (m1); + std::cout << "trans (m1) = " << m2 << std::endl; + + // Hermitean + initialize_matrix (m1); + m2 = ublas::herm (m1); + std::cout << "herm (m1) = " << m2 << std::endl; + + // Matrix multiplication + initialize_matrix (m1); + initialize_matrix (m2); + m3 = ublas::prod (m1, m2); + std::cout << "prod (m1, m2) = " << m3 << std::endl; + } + } + void operator () () const { + { + M m1 (N, N, N * N), m2 (N, N, N * N), m3 (N, N, N * N); + test_with (m1, m2, m3); + +#ifdef USE_RANGE + ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mr2 (m2, ublas::range (0, N), ublas::range (0, N)), + mr3 (m3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } + } +}; + +// Test matrix +void test_matrix () { + std::cout << "test_matrix" << std::endl; + +#ifdef USE_SPARSE_MATRIX +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float, mapped_matrix map_array" << std::endl; + test_my_matrix<ublas::mapped_matrix<float, ublas::row_major, ublas::map_array<std::size_t, float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, mapped_matrix map_array" << std::endl; + test_my_matrix<ublas::mapped_matrix<double, ublas::row_major, ublas::map_array<std::size_t, double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, mapped_matrix map_array" << std::endl; + test_my_matrix<ublas::mapped_matrix<std::complex<float>, ublas::row_major, ublas::map_array<std::size_t, std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, mapped_matrix map_array" << std::endl; + test_my_matrix<ublas::mapped_matrix<std::complex<double>, ublas::row_major, ublas::map_array<std::size_t, std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, mapped_matrix std::map" << std::endl; + test_my_matrix<ublas::mapped_matrix<float, ublas::row_major, std::map<std::size_t, float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, mapped_matrix std::map" << std::endl; + test_my_matrix<ublas::mapped_matrix<double, ublas::row_major, std::map<std::size_t, double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, mapped_matrix std::map" << std::endl; + test_my_matrix<ublas::mapped_matrix<std::complex<float>, ublas::row_major, std::map<std::size_t, std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, mapped_matrix std::map" << std::endl; + test_my_matrix<ublas::mapped_matrix<std::complex<double>, ublas::row_major, std::map<std::size_t, std::complex<double> > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_SPARSE_VECTOR_OF_SPARSE_VECTOR +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float, mapped_vector_of_mapped_vector map_array" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<float, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, mapped_vector_of_mapped_vector map_array" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<double, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, double> > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, mapped_vector_of_mapped_vector map_array" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<float>, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, std::complex<float> > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, mapped_vector_of_mapped_vectormap_array" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<double>, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, std::complex<double> > > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, mapped_vector_of_mapped_vector std::map" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<float, ublas::row_major, std::map<std::size_t, std::map<std::size_t, float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, mapped_vector_of_mapped_vector std::map" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<double, ublas::row_major, std::map<std::size_t, std::map<std::size_t, double> > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, mapped_vector_of_mapped_vector std::map" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<float>, ublas::row_major, std::map<std::size_t, std::map<std::size_t, std::complex<float> > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, mapped_vector_of_mapped_vector std::map" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<double>, ublas::row_major, std::map<std::size_t, std::map<std::size_t, std::complex<double> > > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_GENERALIZED_VECTOR_OF_VECTOR +#ifdef USE_MAP_ARRAY +#ifdef USE_FLOAT + std::cout << "float,generalized_vector_of_vector map_array" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, ublas::map_array<std::size_t, ublas::mapped_vector<float, ublas::map_array<std::size_t, float> > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, ublas::map_array<std::size_t, ublas::mapped_vector<double, ublas::map_array<std::size_t, double> > > > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, ublas::map_array<std::size_t, ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, generalized_vector_of_vector map_array" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, ublas::map_array<std::size_t, ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > > > > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_MAP +#ifdef USE_FLOAT + std::cout << "float, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::vector<ublas::mapped_vector<float, std::map<std::size_t, float> > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, std::map<std::size_t, ublas::mapped_vector<float, std::map<std::size_t, float> > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::vector<ublas::mapped_vector<double, std::map<std::size_t, double> > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, std::map<std::size_t, ublas::mapped_vector<double, std::map<std::size_t, double> > > > >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, std::map<std::size_t, ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > > > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, generalized_vector_of_vector std::map" << std::endl; + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > > >, 3 > () (); + test_my_matrix<ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, std::map<std::size_t, ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > > > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_COMPRESSED_MATRIX +#ifdef USE_FLOAT + std::cout << "float compressed_matrix" << std::endl; + test_my_matrix<ublas::compressed_matrix<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double compressed_matrix" << std::endl; + test_my_matrix<ublas::compressed_matrix<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> compressed_matrix" << std::endl; + test_my_matrix<ublas::compressed_matrix<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> compressed_matrix" << std::endl; + test_my_matrix<ublas::compressed_matrix<std::complex<double> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_COORDINATE_MATRIX +#ifdef USE_FLOAT + std::cout << "float coordinate_matrix" << std::endl; + test_my_matrix<ublas::coordinate_matrix<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double coordinate_matrix" << std::endl; + test_my_matrix<ublas::coordinate_matrix<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> coordinate_matrix" << std::endl; + test_my_matrix<ublas::coordinate_matrix<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> coordinate_matrix" << std::endl; + test_my_matrix<ublas::coordinate_matrix<std::complex<double> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_MAPPED_VECTOR_OF_MAPPED_VECTOR +#ifdef USE_FLOAT + std::cout << "float mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<float>, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<double>, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float> mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double> mapped_vector_of_mapped_vector" << std::endl; + test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<double> >, 3 > () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test4.cpp b/src/boost/libs/numeric/ublas/test/test4.cpp new file mode 100644 index 000000000..bf5816f5e --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test4.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test4.hpp" + +int main () { + test_matrix_vector (); + test_matrix (); + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test4.hpp b/src/boost/libs/numeric/ublas/test/test4.hpp new file mode 100644 index 000000000..fc5b48cbe --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test4.hpp @@ -0,0 +1,39 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST4_H +#define TEST4_H + +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/banded.hpp> +#include <boost/numeric/ublas/io.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +//#define USE_BANDED +#define USE_DIAGONAL + + +void test_matrix_vector (); +void test_matrix (); + + +// FIXME slice are failing in assignment to zero elements +#undef USE_SLICE + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test42.cpp b/src/boost/libs/numeric/ublas/test/test42.cpp new file mode 100644 index 000000000..d284e6854 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test42.cpp @@ -0,0 +1,366 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test4.hpp" +#include "utils.hpp" + +// Test matrix & vector expression templates +template<class V, class M, int N> +struct test_my_matrix_vector { + typedef typename V::value_type value_type; + + template<class VP, class MP> + void test_with (VP &v1, VP &v2, MP &m1) const { + { +#ifndef USE_DIAGONAL + // Rows and columns + initialize_matrix (m1); + for (int i = 0; i < N; ++ i) { + v2 = ublas::row (m1, i); + std::cout << "row (m, " << i << ") = " << v2 << std::endl; + v2 = ublas::column (m1, i); + std::cout << "column (m, " << i << ") = " << v2 << std::endl; + } + + // Outer product + initialize_vector (v1); + initialize_vector (v2); + v1 (0) = 0; + v1 (N - 1) = 0; + m1 = ublas::outer_prod (v1, v2); + std::cout << "outer_prod (v1, v2) = " << m1 << std::endl; + + // Matrix vector product + initialize_matrix (m1); + initialize_vector (v1); + v2 = ublas::prod (m1, v1); + std::cout << "prod (m1, v1) = " << v2 << std::endl; + v2 = ublas::prod (v1, m1); + std::cout << "prod (v1, m1) = " << v2 << std::endl; +#else + BOOST_UBLAS_NOT_USED(v1); + BOOST_UBLAS_NOT_USED(v2); + BOOST_UBLAS_NOT_USED(m1); +#endif + } + } + void operator () () const { + { + V v1 (N), v2 (N); +#ifdef USE_BANDED + M m1 (N, N, 1, 1); +#endif +#ifdef USE_DIAGONAL + M m1 (N, N); +#endif + test_with (v1, v2, m1); + + ublas::matrix_row<M> mr1 (m1, 1), mr2 (m1, 1); + test_with (mr1, mr2, m1); + + ublas::matrix_column<M> mc1 (m1, 1), mc2 (m1, 1); + test_with (mc1, mc2, m1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (m1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, m1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, m1); +#endif + } + } + + void operator () (int) const { +#ifdef USE_ADAPTOR + { +#ifdef USE_BANDED + V v1 (N), v2 (N); + M m1 (N, N, 1, 1); + ublas::banded_adaptor<M> bam1 (m1, 1, 1); + test_with (v1, v2, bam1); + + ublas::matrix_row<ublas::banded_adaptor<M> > mr1 (bam1, 1), mr2 (bam1, 1); + test_with (mr1, mr2, bam1); + + ublas::matrix_column<ublas::banded_adaptor<M> > mc1 (bam1, 1), mc2 (bam1, 1); + test_with (mc1, mc2, bam1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<ublas::banded_adaptor<M> > mvr1 (bam1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (bam1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, bam1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<ublas::banded_adaptor<M> > mvs1 (bam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (bam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, bam1); +#endif +#endif +#ifdef USE_DIAGONAL + V v1 (N), v2 (N); + M m1 (N, N); + ublas::diagonal_adaptor<M> dam1 (m1); + test_with (v1, v2, dam1); + + ublas::matrix_row<ublas::diagonal_adaptor<M> > mr1 (dam1, 1), mr2 (dam1, 1); + test_with (mr1, mr2, dam1); + + ublas::matrix_column<ublas::diagonal_adaptor<M> > mc1 (dam1, 1), mc2 (dam1, 1); + test_with (mc1, mc2, dam1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<ublas::diagonal_adaptor<M> > mvr1 (dam1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (dam1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, dam1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<ublas::diagonal_adaptor<M> > mvs1 (dam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (dam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, dam1); +#endif +#endif + } +#endif + } +}; + +// Test matrix & vector +void test_matrix_vector () { + std::cout << "test_matrix_vector" << std::endl; + +#ifdef USE_BANDED +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::banded_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::banded_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::banded_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::banded_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::banded_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::banded_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::banded_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::banded_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::banded_matrix<float, ublas::row_major, std::vector<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::banded_matrix<float, ublas::row_major, std::vector<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::banded_matrix<double, ublas::row_major, std::vector<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::banded_matrix<double, ublas::row_major, std::vector<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::banded_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::banded_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::banded_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::banded_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif +#endif + +#ifdef USE_DIAGONAL +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::diagonal_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::diagonal_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::diagonal_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::diagonal_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::diagonal_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::diagonal_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::diagonal_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::diagonal_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::diagonal_matrix<float, ublas::row_major, std::vector<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::diagonal_matrix<float, ublas::row_major, std::vector<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::diagonal_matrix<double, ublas::row_major, std::vector<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::diagonal_matrix<double, ublas::row_major, std::vector<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::diagonal_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::diagonal_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::diagonal_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::diagonal_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test43.cpp b/src/boost/libs/numeric/ublas/test/test43.cpp new file mode 100644 index 000000000..9db3c9b2c --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test43.cpp @@ -0,0 +1,326 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test4.hpp" + +// Test matrix expression templates +template<class M, int N> +struct test_my_matrix { + typedef typename M::value_type value_type; + + template<class MP> + void test_with (MP &m1, MP &m2, MP &m3) const { + { + value_type t; + + // Default Construct + default_construct<MP>::test (); + + // Copy and swap + initialize_matrix (m1); + initialize_matrix (m2); + m1 = m2; + std::cout << "m1 = m2 = " << m1 << std::endl; + m1.assign_temporary (m2); + std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl; + m1.swap (m2); + std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl; + + // Zero assignment + m1 = ublas::zero_matrix<> (m1.size1 (), m1.size2 ()); + std::cout << "m1.zero_matrix = " << m1 << std::endl; + m1 = m2; + + // Unary matrix operations resulting in a matrix + initialize_matrix (m1); + m2 = - m1; + std::cout << "- m1 = " << m2 << std::endl; + m2 = ublas::conj (m1); + std::cout << "conj (m1) = " << m2 << std::endl; + + // Binary matrix operations resulting in a matrix + initialize_matrix (m1); + initialize_matrix (m2); + m3 = m1 + m2; + std::cout << "m1 + m2 = " << m3 << std::endl; + m3 = m1 - m2; + std::cout << "m1 - m2 = " << m3 << std::endl; + + // Scaling a matrix + t = N; + initialize_matrix (m1); + m2 = value_type (1.) * m1; + std::cout << "1. * m1 = " << m2 << std::endl; + m2 = t * m1; + std::cout << "N * m1 = " << m2 << std::endl; + initialize_matrix (m1); + m2 = m1 * value_type (1.); + std::cout << "m1 * 1. = " << m2 << std::endl; + m2 = m1 * t; + std::cout << "m1 * N = " << m2 << std::endl; + + // Some assignments + initialize_matrix (m1); + initialize_matrix (m2); + m2 += m1; + std::cout << "m2 += m1 = " << m2 << std::endl; + m2 -= m1; + std::cout << "m2 -= m1 = " << m2 << std::endl; + m2 = m2 + m1; + std::cout << "m2 = m2 + m1 = " << m2 << std::endl; + m2 = m2 - m1; + std::cout << "m2 = m2 - m1 = " << m2 << std::endl; + m1 *= value_type (1.); + std::cout << "m1 *= 1. = " << m1 << std::endl; + m1 *= t; + std::cout << "m1 *= N = " << m1 << std::endl; + + // Transpose + initialize_matrix (m1); + m2 = ublas::trans (m1); + std::cout << "trans (m1) = " << m2 << std::endl; + + // Hermitean + initialize_matrix (m1); + m2 = ublas::herm (m1); + std::cout << "herm (m1) = " << m2 << std::endl; + + // Matrix multiplication + initialize_matrix (m1); + initialize_matrix (m2); + // Banded times banded isn't banded + std::cout << "prod (m1, m2) = " << ublas::prod (m1, m2) << std::endl; + } + } + void operator () () const { + { +#ifdef USE_BANDED + M m1 (N, N, 1, 1), m2 (N, N, 1, 1), m3 (N, N, 1, 1); +#endif +#ifdef USE_DIAGONAL + M m1 (N, N), m2 (N, N), m3 (N, N); +#endif + test_with (m1, m2, m3); + +#ifdef USE_RANGE + ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mr2 (m2, ublas::range (0, N), ublas::range (0, N)), + mr3 (m3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } + +#ifdef USE_ADAPTOR + { +#ifdef USE_BANDED + M m1 (N, N, 1, 1), m2 (N, N, 1, 1), m3 (N, N, 1, 1); + ublas::banded_adaptor<M> bam1 (m1, 1, 1), bam2 (m2, 1, 1), bam3 (m3, 1, 1); + test_with (bam1, bam2, bam3); + +#ifdef USE_RANGE + ublas::matrix_range<ublas::banded_adaptor<M> > mr1 (bam1, ublas::range (0, N), ublas::range (0, N)), + mr2 (bam2, ublas::range (0, N), ublas::range (0, N)), + mr3 (bam3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<ublas::banded_adaptor<M> > ms1 (bam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (bam2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (bam3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif +#endif +#ifdef USE_DIAGONAL + M m1 (N, N), m2 (N, N), m3 (N, N); + ublas::diagonal_adaptor<M> dam1 (m1), dam2 (m2), dam3 (m3); + test_with (dam1, dam2, dam3); + +#ifdef USE_RANGE + ublas::matrix_range<ublas::diagonal_adaptor<M> > mr1 (dam1, ublas::range (0, N), ublas::range (0, N)), + mr2 (dam2, ublas::range (0, N), ublas::range (0, N)), + mr3 (dam3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<ublas::diagonal_adaptor<M> > ms1 (dam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (dam2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (dam3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif +#endif + } +#endif + + } +}; + +// Test matrix +void test_matrix () { + std::cout << "test_matrix" << std::endl; + +#ifdef USE_BANDED +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix<ublas::banded_matrix<float, ublas::row_major, std::vector<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix<ublas::banded_matrix<double, ublas::row_major, std::vector<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix<ublas::banded_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix<ublas::banded_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif +#endif + +#ifdef USE_DIAGONAL +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix<ublas::diagonal_matrix<float, ublas::row_major, std::vector<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix<ublas::diagonal_matrix<double, ublas::row_major, std::vector<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix<ublas::diagonal_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix<ublas::diagonal_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test5.cpp b/src/boost/libs/numeric/ublas/test/test5.cpp new file mode 100644 index 000000000..548cd6033 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test5.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test5.hpp" + +int main () { + test_matrix_vector (); + test_matrix (); + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test5.hpp b/src/boost/libs/numeric/ublas/test/test5.hpp new file mode 100644 index 000000000..a13dfa2ef --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test5.hpp @@ -0,0 +1,35 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST5_H +#define TEST5_H + +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/numeric/ublas/io.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +void test_matrix_vector (); +void test_matrix (); + + +// FIXME slice are failing in assignment to zero elements +#undef USE_SLICE + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test52.cpp b/src/boost/libs/numeric/ublas/test/test52.cpp new file mode 100644 index 000000000..4803ce260 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test52.cpp @@ -0,0 +1,214 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test5.hpp" + +// Test matrix & vector expression templates +template<class V, class M, int N> +struct test_my_matrix_vector { + typedef typename V::value_type value_type; + + template<class VP, class MP> + void test_with (VP &v1, VP &v2, MP &m1) const { + { + // Rows and columns + initialize_matrix (m1); + for (int i = 0; i < N; ++ i) { + v2 = ublas::row (m1, i); + std::cout << "row (m, " << i << ") = " << v2 << std::endl; + v2 = ublas::column (m1, i); + std::cout << "column (m, " << i << ") = " << v2 << std::endl; + } + + // Outer product + initialize_vector (v1); + initialize_vector (v2); + v1 (0) = 0; + v2 (N - 1) = 0; + m1 = ublas::outer_prod (v1, v2); + std::cout << "outer_prod (v1, v2) = " << m1 << std::endl; + + // Matrix vector product + initialize_matrix (m1); + initialize_vector (v1); + v2 = ublas::prod (m1, v1); + std::cout << "prod (m1, v1) = " << v2 << std::endl; + v2 = ublas::prod (v1, m1); + std::cout << "prod (v1, m1) = " << v2 << std::endl; + } + } + void operator () () const { + { + V v1 (N), v2 (N); + M m1 (N, N); + test_with (v1, v2, m1); + + ublas::matrix_row<M> mr1 (m1, N - 1), mr2 (m1, N - 1); + test_with (mr1, mr2, m1); + + ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, 0); + test_with (mc1, mc2, m1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (m1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, m1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, m1); +#endif + } + } + + void operator () (int) const { +#ifdef USE_ADAPTOR + { + V v1 (N), v2 (N); + M m1 (N, N); + ublas::triangular_adaptor<M> tam1 (m1); + test_with (v1, v2, tam1); + + ublas::matrix_row<ublas::triangular_adaptor<M> > mr1 (tam1, N - 1), mr2 (tam1, N - 1); + test_with (mr1, mr2, tam1); + + ublas::matrix_column<ublas::triangular_adaptor<M> > mc1 (tam1, 0), mc2 (tam1, 0); + test_with (mc1, mc2, tam1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<ublas::triangular_adaptor<M> > mvr1 (tam1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (tam1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, tam1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<ublas::triangular_adaptor<M> > mvs1 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, tam1); +#endif + } +#endif + } +}; + +// Test matrix & vector +void test_matrix_vector () { + std::cout << "test_matrix_vector" << std::endl; + +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::triangular_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::triangular_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::triangular_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::triangular_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3> () (0); + + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test53.cpp b/src/boost/libs/numeric/ublas/test/test53.cpp new file mode 100644 index 000000000..250d462d4 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test53.cpp @@ -0,0 +1,223 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test5.hpp" + +// Test matrix expression templates +template<class M, int N> +struct test_my_matrix { + typedef typename M::value_type value_type; + + template<class MP> + void test_with (MP &m1, MP &m2, MP &m3) const { + { + value_type t; + + // Default Construct + default_construct<MP>::test (); + + // Copy and swap + initialize_matrix (m1); + initialize_matrix (m2); + m1 = m2; + std::cout << "m1 = m2 = " << m1 << std::endl; + m1.assign_temporary (m2); + std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl; + m1.swap (m2); + std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl; + + // Zero assignment + m1 = ublas::zero_matrix<> (m1.size1 (), m1.size2 ()); + std::cout << "m1.zero_matrix = " << m1 << std::endl; + m1 = m2; + + // Unary matrix operations resulting in a matrix + initialize_matrix (m1); + m2 = - m1; + std::cout << "- m1 = " << m2 << std::endl; + m2 = ublas::conj (m1); + std::cout << "conj (m1) = " << m2 << std::endl; + + // Binary matrix operations resulting in a matrix + initialize_matrix (m1); + initialize_matrix (m2); + m3 = m1 + m2; + std::cout << "m1 + m2 = " << m3 << std::endl; + m3 = m1 - m2; + std::cout << "m1 - m2 = " << m3 << std::endl; + + // Scaling a matrix + t = N; + initialize_matrix (m1); + m2 = value_type (1.) * m1; + std::cout << "1. * m1 = " << m2 << std::endl; + m2 = t * m1; + std::cout << "N * m1 = " << m2 << std::endl; + initialize_matrix (m1); + m2 = m1 * value_type (1.); + std::cout << "m1 * 1. = " << m2 << std::endl; + m2 = m1 * t; + std::cout << "m1 * N = " << m2 << std::endl; + + // Some assignments + initialize_matrix (m1); + initialize_matrix (m2); + m2 += m1; + std::cout << "m2 += m1 = " << m2 << std::endl; + m2 -= m1; + std::cout << "m2 -= m1 = " << m2 << std::endl; + m2 = m2 + m1; + std::cout << "m2 = m2 + m1 = " << m2 << std::endl; + m2 = m2 - m1; + std::cout << "m2 = m2 - m1 = " << m2 << std::endl; + m1 *= value_type (1.); + std::cout << "m1 *= 1. = " << m1 << std::endl; + m1 *= t; + std::cout << "m1 *= N = " << m1 << std::endl; + + // Transpose + initialize_matrix (m1); + // Transpose of a triangular isn't triangular of the same kind + std::cout << "trans (m1) = " << ublas::trans (m1) << std::endl; + + // Hermitian + initialize_matrix (m1); + // Hermitian of a triangular isn't hermitian of the same kind + std::cout << "herm (m1) = " << ublas::herm (m1) << std::endl; + + // Matrix multiplication + initialize_matrix (m1); + initialize_matrix (m2); + m3 = ublas::prod (m1, m2); + std::cout << "prod (m1, m2) = " << m3 << std::endl; + } + } + void operator () () const { + { + M m1 (N, N), m2 (N, N), m3 (N, N); + test_with (m1, m2, m3); + +#ifdef USE_RANGE + ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mr2 (m2, ublas::range (0, N), ublas::range (0, N)), + mr3 (m3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } + +#ifdef USE_ADAPTOR + { + M m1 (N, N), m2 (N, N), m3 (N, N); + ublas::triangular_adaptor<M> tam1 (m1), tam2 (m2), tam3 (m3); + test_with (tam1, tam2, tam3); + +#ifdef USE_RANGE + ublas::matrix_range<ublas::triangular_adaptor<M> > mr1 (tam1, ublas::range (0, N), ublas::range (0, N)), + mr2 (tam2, ublas::range (0, N), ublas::range (0, N)), + mr3 (tam3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<ublas::triangular_adaptor<M> > ms1 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (tam2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (tam3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } +#endif + } +}; + +// Test matrix +void test_matrix () { + std::cout << "test_matrix" << std::endl; + +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix<ublas::triangular_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix<ublas::triangular_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix<ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE +std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix<ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test6.cpp b/src/boost/libs/numeric/ublas/test/test6.cpp new file mode 100644 index 000000000..61a5c3105 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test6.cpp @@ -0,0 +1,19 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test6.hpp" + +int main () { + test_matrix_vector (); + test_matrix (); + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test6.hpp b/src/boost/libs/numeric/ublas/test/test6.hpp new file mode 100644 index 000000000..766d6b929 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test6.hpp @@ -0,0 +1,32 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST6_H +#define TEST6_H + +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/symmetric.hpp> +#include <boost/numeric/ublas/io.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +void test_matrix_vector (); +void test_matrix (); + + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test62.cpp b/src/boost/libs/numeric/ublas/test/test62.cpp new file mode 100644 index 000000000..5d7feb9a3 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test62.cpp @@ -0,0 +1,218 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test6.hpp" + +// Test matrix & vector expression templates +template<class V, class M, int N> +struct test_my_matrix_vector { + typedef typename V::value_type value_type; + + template<class VP, class MP> + void test_with (VP &v1, VP &v2, MP &m1) const { + { + // Rows and columns + initialize_matrix (m1); + for (int i = 0; i < N; ++ i) { + v2 = ublas::row (m1, i); + std::cout << "row (m, " << i << ") = " << v2 << std::endl; + v2 = ublas::column (m1, i); + std::cout << "column (m, " << i << ") = " << v2 << std::endl; + } + + // Outer product + initialize_vector (v1); + initialize_vector (v2); + v1 (0) = 0; + v1 (N - 1) = 0; + v2 (0) = 0; + v2 (N - 1) = 0; + m1 = ublas::outer_prod (v1, v2); + std::cout << "outer_prod (v1, v2) = " << m1 << std::endl; + + // Matrix vector product + initialize_matrix (m1); + initialize_vector (v1); + v2 = ublas::prod (m1, v1); + std::cout << "prod (m1, v1) = " << v2 << std::endl; + v2 = ublas::prod (v1, m1); + std::cout << "prod (v1, m1) = " << v2 << std::endl; + } + } + void operator () () const { + { + V v1 (N), v2 (N); + M m1 (N, N); + test_with (v1, v2, m1); + + ublas::matrix_row<M> mr1 (m1, N - 1), mr2 (m1, N - 1); + test_with (mr1, mr2, m1); + + ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, 0); + test_with (mc1, mc2, m1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (m1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, m1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, m1); +#endif + } + } + + void operator () (int) const { +#ifdef USE_ADAPTOR + { + V v1 (N), v2 (N); + M m1 (N, N); + ublas::symmetric_adaptor<M> tam1 (m1); + test_with (v1, v2, tam1); + + ublas::matrix_row<ublas::symmetric_adaptor<M> > mr1 (tam1, N - 1), mr2 (tam1, N - 1); + test_with (mr1, mr2, tam1); + + ublas::matrix_column<ublas::symmetric_adaptor<M> > mc1 (tam1, 0), mc2 (tam1, 0); + test_with (mc1, mc2, tam1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<ublas::symmetric_adaptor<M> > mvr1 (tam1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (tam1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, tam1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<ublas::symmetric_adaptor<M> > mvs1 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, tam1); +#endif + } +#endif + } +}; + +// Test matrix & vector +void test_matrix_vector () { + std::cout << "test_matrix_vector" << std::endl; + +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, + ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, + ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, + ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, + ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >, + ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >, + ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, + ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, + ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3> () (); + test_my_matrix_vector<ublas::vector<float, std::vector<float> >, + ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3> () (); + test_my_matrix_vector<ublas::vector<double, std::vector<double> >, + ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3> () (0); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, + ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3> () (0); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3> () (); + test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, + ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3> () (0); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test63.cpp b/src/boost/libs/numeric/ublas/test/test63.cpp new file mode 100644 index 000000000..4a0013d2c --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test63.cpp @@ -0,0 +1,223 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test6.hpp" + +// Test matrix expression templates +template<class M, int N> +struct test_my_matrix { + typedef typename M::value_type value_type; + + template<class MP> + void test_with (MP &m1, MP &m2, MP &m3) const { + { + value_type t; + + // Default Construct + default_construct<MP>::test (); + + // Copy and swap + initialize_matrix (m1); + initialize_matrix (m2); + m1 = m2; + std::cout << "m1 = m2 = " << m1 << std::endl; + m1.assign_temporary (m2); + std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl; + m1.swap (m2); + std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl; + + // Zero assignment + m1 = ublas::zero_matrix<> (m1.size1 (), m1.size2 ()); + std::cout << "m1.zero_matrix = " << m1 << std::endl; + m1 = m2; + + // Unary matrix operations resulting in a matrix + initialize_matrix (m1); + m2 = - m1; + std::cout << "- m1 = " << m2 << std::endl; + m2 = ublas::conj (m1); + std::cout << "conj (m1) = " << m2 << std::endl; + + // Binary matrix operations resulting in a matrix + initialize_matrix (m1); + initialize_matrix (m2); + m3 = m1 + m2; + std::cout << "m1 + m2 = " << m3 << std::endl; + m3 = m1 - m2; + std::cout << "m1 - m2 = " << m3 << std::endl; + + // Scaling a matrix + t = N; + initialize_matrix (m1); + m2 = value_type (1.) * m1; + std::cout << "1. * m1 = " << m2 << std::endl; + m2 = t * m1; + std::cout << "N * m1 = " << m2 << std::endl; + initialize_matrix (m1); + m2 = m1 * value_type (1.); + std::cout << "m1 * 1. = " << m2 << std::endl; + m2 = m1 * t; + std::cout << "m1 * N = " << m2 << std::endl; + + // Some assignments + initialize_matrix (m1); + initialize_matrix (m2); + m2 += m1; + std::cout << "m2 += m1 = " << m2 << std::endl; + m2 -= m1; + std::cout << "m2 -= m1 = " << m2 << std::endl; + m2 = m2 + m1; + std::cout << "m2 = m2 + m1 = " << m2 << std::endl; + m2 = m2 - m1; + std::cout << "m2 = m1 - m1 = " << m2 << std::endl; + m1 *= value_type (1.); + std::cout << "m1 *= 1. = " << m1 << std::endl; + m1 *= t; + std::cout << "m1 *= N = " << m1 << std::endl; + + // Transpose + initialize_matrix (m1); + m2 = ublas::trans (m1); + std::cout << "trans (m1) = " << m2 << std::endl; + + // Hermitean + initialize_matrix (m1); + m2 = ublas::herm (m1); + std::cout << "herm (m1) = " << m2 << std::endl; + + // Matrix multiplication + initialize_matrix (m1); + initialize_matrix (m2); + m3 = ublas::prod (m1, m2); + std::cout << "prod (m1, m2) = " << m3 << std::endl; + } + } + void operator () () const { + { + M m1 (N, N), m2 (N, N), m3 (N, N); + test_with (m1, m2, m3); + +#ifdef USE_RANGE + ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mr2 (m2, ublas::range (0, N), ublas::range (0, N)), + mr3 (m3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } + +#ifdef USE_ADAPTOR + { + M m1 (N, N), m2 (N, N), m3 (N, N); + ublas::symmetric_adaptor<M> sam1 (m1), sam2 (m2), sam3 (m3); + test_with (sam1, sam2, sam3); + +#ifdef USE_RANGE + ublas::matrix_range<ublas::symmetric_adaptor<M> > mr1 (sam1, ublas::range (0, N), ublas::range (0, N)), + mr2 (sam2, ublas::range (0, N), ublas::range (0, N)), + mr3 (sam3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<ublas::symmetric_adaptor<M> > ms1 (sam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (sam2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (sam3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } +#endif + } +}; + +// Test matrix +void test_matrix () { + std::cout << "test_matrix" << std::endl; + +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, bounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, bounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, bounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, bounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "float, unbounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, unbounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "float, std::vector" << std::endl; + test_my_matrix<ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "double, std::vector" << std::endl; + test_my_matrix<ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3 > () (); +#endif + +#ifdef USE_STD_COMPLEX +#ifdef USE_FLOAT + std::cout << "std::complex<float>, std::vector" << std::endl; + test_my_matrix<ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "std::complex<double>, std::vector" << std::endl; + test_my_matrix<ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3 > () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test7.cpp b/src/boost/libs/numeric/ublas/test/test7.cpp new file mode 100644 index 000000000..f564031ce --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test7.cpp @@ -0,0 +1,31 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include <iostream> + +#include <boost/numeric/interval.hpp> +#include <boost/numeric/interval/io.hpp> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/io.hpp> + +#include "test7.hpp" + +// this testcase requires fix of task #2473 + +int main () { + test_vector (); + test_matrix_vector (); + test_matrix (); + return 0; +} diff --git a/src/boost/libs/numeric/ublas/test/test7.hpp b/src/boost/libs/numeric/ublas/test/test7.hpp new file mode 100644 index 000000000..5dbae1fca --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test7.hpp @@ -0,0 +1,36 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#ifndef TEST7_H +#define TEST7_H + +#include <iostream> + +#include <boost/numeric/interval.hpp> +#include <boost/numeric/interval/io.hpp> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_proxy.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_proxy.hpp> +#include <boost/numeric/ublas/io.hpp> + +namespace ublas = boost::numeric::ublas; + +#include "common/init.hpp" + +void test_vector (); +void test_matrix_vector (); +void test_matrix (); + + +#endif diff --git a/src/boost/libs/numeric/ublas/test/test71.cpp b/src/boost/libs/numeric/ublas/test/test71.cpp new file mode 100644 index 000000000..89e9ccf78 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test71.cpp @@ -0,0 +1,170 @@ +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test7.hpp" + +// Test vector expression templates +template<class V, int N> +struct test_my_vector { + typedef typename V::value_type value_type; + typedef typename V::size_type size_type; + typedef typename ublas::type_traits<value_type>::real_type real_type; + + template<class VP> + void test_with (VP &v1, VP &v2, VP &v3) const { + { + value_type t; + size_type i; + real_type n; + + // Copy and swap + initialize_vector (v1); + initialize_vector (v2); + v1 = v2; + std::cout << "v1 = v2 = " << v1 << std::endl; + v1.assign_temporary (v2); + std::cout << "v1.assign_temporary (v2) = " << v1 << std::endl; + v1.swap (v2); + std::cout << "v1.swap (v2) = " << v1 << " " << v2 << std::endl; + + // Zero assignment + v1 = ublas::zero_vector<value_type> (v1.size ()); + std::cout << "v1.zero_vector = " << v1 << std::endl; + v1 = v2; + + // Unary vector operations resulting in a vector + initialize_vector (v1); + v2 = - v1; + std::cout << "- v1 = " << v2 << std::endl; + v2 = ublas::conj (v1); + std::cout << "conj (v1) = " << v2 << std::endl; + + // Binary vector operations resulting in a vector + initialize_vector (v1); + initialize_vector (v2); + v3 = v1 + v2; + std::cout << "v1 + v2 = " << v3 << std::endl; + + v3 = v1 - v2; + std::cout << "v1 - v2 = " << v3 << std::endl; + + // Scaling a vector + t = value_type (N); + initialize_vector (v1); + v2 = value_type (1.) * v1; + std::cout << "1. * v1 = " << v2 << std::endl; +// v2 = t * v1; + std::cout << "N * v1 = " << v2 << std::endl; + initialize_vector (v1); +// v2 = v1 * value_type (1.); + std::cout << "v1 * 1. = " << v2 << std::endl; +// v2 = v1 * t; + std::cout << "v1 * N = " << v2 << std::endl; + + // Some assignments + initialize_vector (v1); + initialize_vector (v2); + v2 += v1; + std::cout << "v2 += v1 = " << v2 << std::endl; + v2 -= v1; + std::cout << "v2 -= v1 = " << v2 << std::endl; + v2 = v2 + v1; + std::cout << "v2 = v2 + v1 = " << v2 << std::endl; + v2 = v2 - v1; + std::cout << "v2 = v2 - v1 = " << v2 << std::endl; + v1 *= value_type (1.); + std::cout << "v1 *= 1. = " << v1 << std::endl; + v1 *= t; + std::cout << "v1 *= N = " << v1 << std::endl; + + // Unary vector operations resulting in a scalar + initialize_vector (v1); + t = ublas::sum (v1); + std::cout << "sum (v1) = " << t << std::endl; + n = ublas::norm_1 (v1); + std::cout << "norm_1 (v1) = " << n << std::endl; + n = ublas::norm_2 (v1); + std::cout << "norm_2 (v1) = " << n << std::endl; + n = ublas::norm_inf (v1); + std::cout << "norm_inf (v1) = " << n << std::endl; + + i = ublas::index_norm_inf (v1); + std::cout << "index_norm_inf (v1) = " << i << std::endl; + + // Binary vector operations resulting in a scalar + initialize_vector (v1); + initialize_vector (v2); + t = ublas::inner_prod (v1, v2); + std::cout << "inner_prod (v1, v2) = " << t << std::endl; + } + } + void operator () () const { + { + V v1 (N), v2 (N), v3 (N); + test_with (v1, v2, v3); + +#ifdef USE_RANGE + ublas::vector_range<V> vr1 (v1, ublas::range (0, N)), + vr2 (v2, ublas::range (0, N)), + vr3 (v3, ublas::range (0, N)); + test_with (vr1, vr2, vr3); +#endif + +#ifdef USE_SLICE + ublas::vector_slice<V> vs1 (v1, ublas::slice (0, 1, N)), + vs2 (v2, ublas::slice (0, 1, N)), + vs3 (v3, ublas::slice (0, 1, N)); + test_with (vs1, vs2, vs3); +#endif + } + } +}; + +// Test vector +void test_vector () { + std::cout << "test_vector" << std::endl; + +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl; + test_my_vector<ublas::vector<boost::numeric::interval<float>, ublas::bounded_array<boost::numeric::interval<float>, 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl; + test_my_vector<ublas::vector<boost::numeric::interval<double>, ublas::bounded_array<boost::numeric::interval<double>, 3> >, 3 > () (); +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl; + test_my_vector<ublas::vector<boost::numeric::interval<float>, ublas::unbounded_array<boost::numeric::interval<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl; + test_my_vector<ublas::vector<boost::numeric::interval<double>, ublas::unbounded_array<boost::numeric::interval<double> > >, 3 > () (); +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, std::vector" << std::endl; + test_my_vector<ublas::vector<boost::numeric::interval<float>, std::vector<boost::numeric::interval<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, std::vector" << std::endl; + test_my_vector<ublas::vector<boost::numeric::interval<double>, std::vector<boost::numeric::interval<double> > >, 3 > () (); +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test72.cpp b/src/boost/libs/numeric/ublas/test/test72.cpp new file mode 100644 index 000000000..bdc3f3e8b --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test72.cpp @@ -0,0 +1,165 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test7.hpp" + +// Test matrix & vector expression templates +template<class V, class M, int N> +struct test_my_matrix_vector { + typedef typename V::value_type value_type; + + template<class VP, class MP> + void test_with (VP &v1, VP &v2, MP &m1) const { + { + // Rows and columns + initialize_matrix (m1); + for (int i = 0; i < N; ++ i) { + v1 = ublas::row (m1, i); + std::cout << "row (m, " << i << ") = " << v1 << std::endl; + v1 = ublas::column (m1, i); + std::cout << "column (m, " << i << ") = " << v1 << std::endl; + } + + // Outer product + initialize_vector (v1); + initialize_vector (v2); + m1 = ublas::outer_prod (v1, v2); + std::cout << "outer_prod (v1, v2) = " << m1 << std::endl; + + // Matrix vector product + initialize_matrix (m1); + initialize_vector (v1); + v2 = ublas::prod (m1, v1); + std::cout << "prod (m1, v1) = " << v2 << std::endl; + v2 = ublas::prod (v1, m1); + std::cout << "prod (v1, m1) = " << v2 << std::endl; + } + } + void operator () () const { + { + V v1 (N), v2 (N); + M m1 (N, N); + test_with (v1, v2, m1); + + ublas::matrix_row<M> mr1 (m1, 0), mr2 (m1, 1); + test_with (mr1, mr2, m1); + + ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, 1); + test_with (mc1, mc2, m1); + +#ifdef USE_RANGE + ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mvr2 (m1, ublas::range (0, N), ublas::range (0, N)); + test_with (mvr1, mvr2, m1); +#endif + +#ifdef USE_SLICE + ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (mvs1, mvs2, m1); +#endif + } + } +}; + +// Test matrix & vector +void test_matrix_vector () { + std::cout << "test_matrix_vector" << std::endl; + +#ifdef USE_MATRIX +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, ublas::bounded_array<boost::numeric::interval<float>, 3> >, + ublas::matrix<boost::numeric::interval<float>, ublas::row_major, ublas::bounded_array<boost::numeric::interval<float>, 3 * 3> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, ublas::bounded_array<boost::numeric::interval<double>, 3> >, + ublas::matrix<boost::numeric::interval<double>, ublas::row_major, ublas::bounded_array<boost::numeric::interval<double>, 3 * 3> >, 3> () (); +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, ublas::unbounded_array<boost::numeric::interval<float> > >, + ublas::matrix<boost::numeric::interval<float>, ublas::row_major, ublas::unbounded_array<boost::numeric::interval<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, ublas::unbounded_array<boost::numeric::interval<double> > >, + ublas::matrix<boost::numeric::interval<double>, ublas::row_major, ublas::unbounded_array<boost::numeric::interval<double> > >, 3> () (); +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, std::vector<boost::numeric::interval<float> > >, + ublas::matrix<boost::numeric::interval<float>, ublas::row_major, std::vector<boost::numeric::interval<float> > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, std::vector<boost::numeric::interval<double> > >, + ublas::matrix<boost::numeric::interval<double>, ublas::row_major, std::vector<boost::numeric::interval<double> > >, 3> () (); +#endif +#endif +#endif + +#ifdef USE_VECTOR_OF_VECTOR +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, ublas::bounded_array<boost::numeric::interval<float>, 3> >, + ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<boost::numeric::interval<float>, 3>, 3 + 1> >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, ublas::bounded_array<boost::numeric::interval<double>, 3> >, + ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<boost::numeric::interval<double>, 3>, 3 + 1> >, 3> () (); +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, ublas::unbounded_array<boost::numeric::interval<float> > >, + ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<boost::numeric::interval<float> > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, ublas::unbounded_array<boost::numeric::interval<double> > >, + ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<boost::numeric::interval<double> > > >, 3> () (); +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, std::vector<boost::numeric::interval<float> > >, + ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, std::vector<std::vector<boost::numeric::interval<float> > > >, 3> () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, std::vector" << std::endl; + test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, std::vector<boost::numeric::interval<double> > >, + ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, std::vector<std::vector<boost::numeric::interval<double> > > >, 3> () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test73.cpp b/src/boost/libs/numeric/ublas/test/test73.cpp new file mode 100644 index 000000000..e2d68ceed --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test73.cpp @@ -0,0 +1,202 @@ +// +// Copyright (c) 2000-2002 +// Joerg Walter, Mathias Koch +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// The authors gratefully acknowledge the support of +// GeNeSys mbH & Co. KG in producing this work. +// + +#include "test7.hpp" + +// Test matrix expression templates +template<class M, int N> +struct test_my_matrix { + typedef typename M::value_type value_type; + + template<class MP> + void test_with (MP &m1, MP &m2, MP &m3) const { + { + value_type t; + + // Copy and swap + initialize_matrix (m1); + initialize_matrix (m2); + m1 = m2; + std::cout << "m1 = m2 = " << m1 << std::endl; + m1.assign_temporary (m2); + std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl; + m1.swap (m2); + std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl; + + // Zero assignment + m1 = ublas::zero_matrix<value_type> (m1.size1 (), m1.size2 ()); + std::cout << "m1.zero_matrix = " << m1 << std::endl; + m1 = m2; + + // Unary matrix operations resulting in a matrix + initialize_matrix (m1); + m2 = - m1; + std::cout << "- m1 = " << m2 << std::endl; + m2 = ublas::conj (m1); + std::cout << "conj (m1) = " << m2 << std::endl; + + // Binary matrix operations resulting in a matrix + initialize_matrix (m1); + initialize_matrix (m2); + m3 = m1 + m2; + std::cout << "m1 + m2 = " << m3 << std::endl; + m3 = m1 - m2; + std::cout << "m1 - m2 = " << m3 << std::endl; + + // Scaling a matrix + t = N; + initialize_matrix (m1); + m2 = value_type (1.) * m1; + std::cout << "1. * m1 = " << m2 << std::endl; + m2 = t * m1; + std::cout << "N * m1 = " << m2 << std::endl; + initialize_matrix (m1); + m2 = m1 * value_type (1.); + std::cout << "m1 * 1. = " << m2 << std::endl; + m2 = m1 * t; + std::cout << "m1 * N = " << m2 << std::endl; + + // Some assignments + initialize_matrix (m1); + initialize_matrix (m2); + m2 += m1; + std::cout << "m2 += m1 = " << m2 << std::endl; + m2 -= m1; + std::cout << "m2 -= m1 = " << m2 << std::endl; + m2 = m2 + m1; + std::cout << "m2 = m2 + m1 = " << m2 << std::endl; + m2 = m2 - m1; + std::cout << "m2 = m1 - m1 = " << m2 << std::endl; + m1 *= value_type (1.); + std::cout << "m1 *= 1. = " << m1 << std::endl; + m1 *= t; + std::cout << "m1 *= N = " << m1 << std::endl; + + // Transpose + initialize_matrix (m1); + m2 = ublas::trans (m1); + std::cout << "trans (m1) = " << m2 << std::endl; + + // Hermitean + initialize_matrix (m1); + m2 = ublas::herm (m1); + std::cout << "herm (m1) = " << m2 << std::endl; + + // Matrix multiplication + initialize_matrix (m1); + initialize_matrix (m2); + m3 = ublas::prod (m1, m2); + std::cout << "prod (m1, m2) = " << m3 << std::endl; + } + } + void operator () () const { + { + M m1 (N, N), m2 (N, N), m3 (N, N); + test_with (m1, m2, m3); + +#ifdef USE_RANGE + ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)), + mr2 (m2, ublas::range (0, N), ublas::range (0, N)), + mr3 (m3, ublas::range (0, N), ublas::range (0, N)); + test_with (mr1, mr2, mr3); +#endif + +#ifdef USE_SLICE + ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)), + ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N)); + test_with (ms1, ms2, ms3); +#endif + } + } +}; + +// Test matrix +void test_matrix () { + std::cout << "test_matrix" << std::endl; + +#ifdef USE_MATRIX +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl; + test_my_matrix<ublas::matrix<boost::numeric::interval<float>, ublas::row_major, ublas::bounded_array<boost::numeric::interval<float>, 3 * 3> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl; + test_my_matrix<ublas::matrix<boost::numeric::interval<double>, ublas::row_major, ublas::bounded_array<boost::numeric::interval<double>, 3 * 3> >, 3 > () (); +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::matrix<boost::numeric::interval<float>, ublas::row_major, ublas::unbounded_array<boost::numeric::interval<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::matrix<boost::numeric::interval<double>, ublas::row_major, ublas::unbounded_array<boost::numeric::interval<double> > >, 3 > () (); +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, std::vector" << std::endl; + test_my_matrix<ublas::matrix<boost::numeric::interval<float>, ublas::row_major, std::vector<boost::numeric::interval<float> > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, std::vector" << std::endl; + test_my_matrix<ublas::matrix<boost::numeric::interval<double>, ublas::row_major, std::vector<boost::numeric::interval<double> > >, 3 > () (); +#endif +#endif +#endif + +#ifdef USE_VECTOR_OF_VECTOR +#ifdef USE_BOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<boost::numeric::interval<float>, 3>, 3 + 1> >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<boost::numeric::interval<double>, 3>, 3 + 1> >, 3 > () (); +#endif +#endif + +#ifdef USE_UNBOUNDED_ARRAY +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<boost::numeric::interval<float> > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl; + test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<boost::numeric::interval<double> > > >, 3 > () (); +#endif +#endif + +#ifdef USE_STD_VECTOR +#ifdef USE_FLOAT + std::cout << "boost::numeric::interval<float>, std::vector" << std::endl; + test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, std::vector<std::vector<boost::numeric::interval<float> > > >, 3 > () (); +#endif + +#ifdef USE_DOUBLE + std::cout << "boost::numeric::interval<double>, std::vector" << std::endl; + test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, std::vector<std::vector<boost::numeric::interval<double> > > >, 3 > () (); +#endif +#endif +#endif +} diff --git a/src/boost/libs/numeric/ublas/test/test_assignment.cpp b/src/boost/libs/numeric/ublas/test/test_assignment.cpp new file mode 100644 index 000000000..ab8be58c6 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_assignment.cpp @@ -0,0 +1,790 @@ +// +// Copyright (c) 2010 Athanasios Iliopoulos +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include <boost/numeric/ublas/assignment.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_proxy.hpp> +#include <boost/numeric/ublas/vector_sparse.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/io.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/timer.hpp> +#include <ctime> +#include "common/testhelper.hpp" +#include "utils.hpp" + +using namespace boost::numeric::ublas; + +template <class V> +bool test_vector() { + bool pass = true; + + V a(3), ra(3); + a <<= 1, 2, 3; + ra(0) = typename V::value_type(1); ra(1) = typename V::value_type(2); ra(2) = typename V::value_type(3); + pass &= compare_distance(a, ra); + + V b(7), rb(7); + b<<= a, 10, a; + rb(0) = typename V::value_type(1); rb(1) = typename V::value_type(2); rb(2) = typename V::value_type(3); + rb(3) = typename V::value_type(10); rb(4) = typename V::value_type(1); rb(5) = typename V::value_type(2); rb(6) = typename V::value_type(3); + pass &= compare_distance(b, rb); + + { + V c(6), rc(6); + c <<= 1, move(2), 3 ,4, 5, move(-5), 10, 10; + rc(0) = typename V::value_type(1); rc(1) = typename V::value_type(10); rc(2) = typename V::value_type(10); + rc(3) = typename V::value_type(3); rc(4) = typename V::value_type(4); rc(5) = typename V::value_type(5); + pass &= compare_distance(c, rc); + + V d(6), rd(6); + d <<= 1, move_to(3), 3 ,4, 5, move_to(1), 10, 10; + rd(0) = typename V::value_type(1); rd(1) = typename V::value_type(10); rd(2) = typename V::value_type(10); + rd(3) = typename V::value_type(3); rd(4) = typename V::value_type(4); rd(5) = typename V::value_type(5); + pass &= compare_distance(d, rd); + } + + { + V c(6), rc(6); + c <<= 1, move<2>(), 3 ,4, 5, move<-5>(), 10, 10; + rc(0) = typename V::value_type(1); rc(1) = typename V::value_type(10); rc(2) = typename V::value_type(10); + rc(3) = typename V::value_type(3); rc(4) = typename V::value_type(4); rc(5) = typename V::value_type(5); + pass &= compare_distance(c, rc); + + V d(6), rd(6); + d <<= 1, move_to<3>(), 3 ,4, 5, move_to<1>(), 10, 10; + rd(0) = typename V::value_type(1); rd(1) = typename V::value_type(10); rd(2) = typename V::value_type(10); + rd(3) = typename V::value_type(3); rd(4) = typename V::value_type(4); rd(5) = typename V::value_type(5); + pass &= compare_distance(d, rd); + } + + + { + V f(6), rf(6); + f <<= 5, 5, 5, 5, 5, 5; + V fa(3); fa<<= 1, 2, 3; + f <<= fill_policy::index_plus_assign(), fa; + rf <<= 6,7,8, 5, 5, 5; + pass &= compare_distance(f, rf); + } + + { + V f(6), rf(6); + f <<= 5, 5, 5, 5, 5, 5; + V fa(3); fa<<= 1, 2, 3; + f <<= fill_policy::index_minus_assign(), fa; + rf <<= 4,3,2, 5, 5, 5; + pass &= compare_distance(f, rf); + } + + return pass; +} + +template <class V> +bool test_vector_sparse_push_back() { + bool pass = true; + + V a(3), ra(3); + a <<= fill_policy::sparse_push_back(), 1, 2, 3; + ra(0) = typename V::value_type(1); ra(1) = typename V::value_type(2); ra(2) = typename V::value_type(3); + pass &= compare_distance(a, ra); + + V b(7), rb(7); + b<<= fill_policy::sparse_push_back(), a, 10, a; + rb(0) = typename V::value_type(1); rb(1) = typename V::value_type(2); rb(2) = typename V::value_type(3); + rb(3) = typename V::value_type(10), rb(4)= typename V::value_type(1); rb(5) = typename V::value_type(2); rb(6) = typename V::value_type(3); + pass &= compare_distance(b, rb); + + V c(6), rc(6); + c <<= fill_policy::sparse_push_back(), 1, move(2), 3 ,4, 5; // Move back (i.e. negative is dangerous for push_back) + rc(0) = typename V::value_type(1); rc(1) = typename V::value_type(0); rc(2) = typename V::value_type(0); + rc(3) = typename V::value_type(3); rc(4) = typename V::value_type(4); rc(5) = typename V::value_type(5); + pass &= compare_distance(c, rc); + + V d(6), rd(6); + d <<= fill_policy::sparse_push_back(), 1, move_to(3), 3 ,4, 5; // Move back (i.e. before current index is dangerous for push_back) + rd(0) = typename V::value_type(1); rd(1) = typename V::value_type(0); rd(2) = typename V::value_type(0); + rd(3) = typename V::value_type(3); rd(4) = typename V::value_type(4); rd(5) = typename V::value_type(5); + pass &= compare_distance(d, rd); + + V e(6), re(6); + e <<= fill_policy::sparse_push_back(), 1, move_to(3), 3 ,4, 5, fill_policy::sparse_insert(), move_to(1), 10, 10; // If you want to move back, use this + re(0) = typename V::value_type(1); re(1) = typename V::value_type(10); re(2) = typename V::value_type(10); + re(3) = typename V::value_type(3); re(4) = typename V::value_type(4); re(5) = typename V::value_type(5); + pass &= compare_distance(e, re); + + return pass; +} + + +template <class V> +bool test_vector_sparse_insert() { + bool pass = true; + + V a(3), ra(3); + a <<= fill_policy::sparse_insert(), 1, 2, 3; + ra(0) = typename V::value_type(1); ra(1) = typename V::value_type(2); ra(2) = typename V::value_type(3); + pass &= compare_distance(a, ra); + + V b(7), rb(7); + b<<= fill_policy::sparse_insert(), a, 10, a; + rb(0) = typename V::value_type(1); rb(1) = typename V::value_type(2); rb(2) = typename V::value_type(3); + rb(3) = typename V::value_type(10), rb(4) = typename V::value_type(1); rb(5)= typename V::value_type(2); rb(6) = typename V::value_type(3); + pass &= compare_distance(b, rb); + + V c(6), rc(6); + c <<= fill_policy::sparse_insert(), 1, move(2), 3 ,4, 5, move(-5), 10, 10; // Move back (i.e. negative is dangerous for sparse) + rc(0) = typename V::value_type(1); rc(1) = typename V::value_type(10); rc(2) = typename V::value_type(10); + rc(3) = typename V::value_type(3); rc(4) = typename V::value_type(4); rc(5) = typename V::value_type(5); + pass &= compare_distance(c, rc); + + + V d(6), rd(6); + d <<= fill_policy::sparse_insert(), 1, move_to(3), 3 ,4, 5, move_to(1), 10, 10; // Move back (i.e.before is dangerous for sparse) + rd(0) = typename V::value_type(1); rd(1) = typename V::value_type(10); rd(2) = typename V::value_type(10); + rd(3) = typename V::value_type(3); rd(4) = typename V::value_type(4); rd(5) = typename V::value_type(5); + pass &= compare_distance(d, rd); + + + return pass; +} + + +template <class V> +bool test_matrix() { + bool pass = true; + + V A(3,3), RA(3,3); + A <<= 1, 2, 3, 4, 5, 6, 7, 8, 9; + RA(0,0)= typename V::value_type(1); RA(0,1)=typename V::value_type(2); RA(0,2)=typename V::value_type(3); + RA(1,0)= typename V::value_type(4); RA(1,1)=typename V::value_type(5); RA(1,2)=typename V::value_type(6); + RA(2,0)= typename V::value_type(7); RA(2,1)=typename V::value_type(8); RA(2,2)=typename V::value_type(9); + pass &= compare_distance(A, RA); + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(3); + b<<= 4,5,6; + B<<= 1, 2, 3, b, 7, project(b, range(1,3)); + RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6; // If the first worked we can now probably use it. + pass &= compare_distance(B, RB); + } + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(3); + b<<= 4,5,6; + B<<= move(1,0), b, move_to(0,0), 1, 2, 3, move(1,0), 7, project(b, range(1,3)); + RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6; + pass &= compare_distance(B, RB); + } + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(9); + b<<= 1, 2, 3, 4, 5, 6, 7, 8, 9; + B<<=b; + RB<<=1, 2, 3, 4, 5, 6, 7, 8, 9; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, + 4, 5; + B<<= C,C, + C,C; + RB <<= 2,3,2,3, + 4,5,4,5, + 2,3,2,3, + 4,5,4,5; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, 4, 5; + B<<= C, zero_matrix<typename V::value_type>(2,2), + zero_matrix<typename V::value_type>(2,2), C; + RB<<= 2,3,0,0, + 4,5,0,0, + 0,0,2,3, + 0,0,4,5; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, 4, 5; + B<<= C, zero_matrix<typename V::value_type>(2,2), + zero_matrix<typename V::value_type>(2,2), C; + RB<<= 2,3,0,0, + 4,5,0,0, + 0,0,2,3, + 0,0,4,5; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); // We need that because of the non-zero instatiation of dense types. + V C(2,2); + C <<= 2, 3, 4, 5; + B<<= move(1,1), C; + RB<<= 0,0,0,0, + 0,2,3,0, + 0,4,5,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<= move_to(0,1), 2, 3, next_row(), 1, 2, next_row(), 4, 5; + RB<<= 0,2,3,0, + 1,2,0,0, + 4,5,0,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=traverse_policy::by_column(), move_to(0,1), 2, 3, 6, next_column(), 4, 5; + RB<<= 0,2,4,0, + 0,3,5,0, + 0,6,0,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=traverse_policy::by_column(), move_to(0,1), 2, 3, next_row(), traverse_policy::by_row(), 4, 5; + RB<<= 0,2,0,0, + 0,3,0,0, + 0,0,0,0, + 4,5,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8; + RB<<= 0,2,0,0, + 0,3,0,0, + 4,5,6,7, + 8,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8,9, begin1(), 1, 2; + RB<<= 0,2,1,2, + 0,3,0,0, + 4,5,6,7, + 8,9,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = scalar_matrix<typename V::value_type>(4,4,1); + V C(2,2); + C <<= 1, 2, 3, 4; + B<<= fill_policy::index_plus_assign(), move(1,1), C; + RB<<= 1,1,1,1, + 1,2,3,1, + 1,4,5,1, + 1,1,1,1; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = scalar_matrix<typename V::value_type>(4,4,5); + V C(2,2); + C <<= 1, 2, 3, 4; + B<<= fill_policy::index_minus_assign(), move(1,1), C; + RB<<= 5,5,5,5, + 5,4,3,5, + 5,2,1,5, + 5,5,5,5; + pass &= compare_distance(B, RB); + } + + + return pass; +} + +template <class V> +bool test_matrix_sparse_push_back() { + bool pass = true; + + V A(3,3), RA(3,3); + A <<= fill_policy::sparse_push_back(), 1, 2, 3, 4, 5, 6, 7, 8, 9; + RA(0,0)= typename V::value_type(1); RA(0,1)= typename V::value_type(2); RA(0,2)= typename V::value_type(3); + RA(1,0)= typename V::value_type(4); RA(1,1)= typename V::value_type(5); RA(1,2)= typename V::value_type(6); + RA(2,0)= typename V::value_type(7); RA(2,1)= typename V::value_type(8); RA(2,2)= typename V::value_type(9); + pass &= compare_distance(A, RA); + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(3); + b<<= 4,5,6; + B<<=fill_policy::sparse_push_back(), 1, 2, 3, b, 7, project(b, range(1,3)); + RB<<= 1, 2, 3, 4, 5, 6, 7, 5, 6; // If the first worked we can now probably use it. + pass &= compare_distance(B, RB); + } + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(3); + b<<= 4,5,6; + B<<=fill_policy::sparse_push_back(), move(1,0), b, fill_policy::sparse_insert(), move_to(0,0), 1, 2, 3, move(1,0), 7, project(b, range(1,3)); + RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6; + pass &= compare_distance(B, RB); + } + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(9); + b<<= 1, 2, 3, 4, 5, 6, 7, 8, 9; + B<<=b; + RB<<=1, 2, 3, 4, 5, 6, 7, 8, 9; + pass &= compare_distance(B, RB); + } + + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, + 4, 5; + // It might get complicated for sparse push_back, this must go into the tutorial. (This way is not convient nor fast) + B<<=fill_policy::sparse_push_back(), C, move_to(2,2), C, fill_policy::sparse_insert(), move_to(0,2), C, C; + RB <<= 2,3,2,3, + 4,5,4,5, + 2,3,2,3, + 4,5,4,5; + pass &= compare_distance(B, RB); + } + + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, 4, 5; + B<<=fill_policy::sparse_push_back(), C, move_to(2,2), C; + RB<<= 2,3,0,0, + 4,5,0,0, + 0,0,2,3, + 0,0,4,5; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, 4, 5; + B<<=fill_policy::sparse_push_back(), move(1,1), C; + RB<<= 0,0,0,0, + 0,2,3,0, + 0,4,5,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_push_back(), move_to(0,1), 2, 3, next_row(), 1, 2, next_row(), 4, 5; + RB<<= 0,2,3,0, + 1,2,0,0, + 4,5,0,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + // The next will not work with sparse push_back because elements that are prior to the ones already in are attempted to be added +/* + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_push_back(),traverse_policy::by_column(), move_to(0,1), 2, 3, 6, next_column(), 4, 5; + RB<<= 0,2,4,0, + 0,3,5,0, + 0,6,0,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } +*/ + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_push_back(),traverse_policy::by_column(), move_to(0,1), 2, 3, next_row(), traverse_policy::by_row(), 4, 5; + RB<<= 0,2,0,0, + 0,3,0,0, + 0,0,0,0, + 4,5,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_push_back(),traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8; + RB<<= 0,2,0,0, + 0,3,0,0, + 4,5,6,7, + 8,0,0,0; + pass &= compare_distance(B, RB); + } + + // The next will not work with sparse push_back because elements that are prior to the ones already in are attempted to be added +/* + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_push_back(),traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8,9, begin1(), 1, 2; + RB<<= 0,2,1,2, + 0,3,0,0, + 4,5,6,7, + 8,9,0,0; + pass &= compare_distance(B, RB); + } +*/ + return pass; +} + +template <class V> +bool test_matrix_sparse_insert() { + bool pass = true; + + V A(3,3), RA(3,3); + A <<= fill_policy::sparse_insert(), 1, 2, 3, 4, 5, 6, 7, 8, 9; + RA(0,0)= typename V::value_type(1); RA(0,1)= typename V::value_type(2); RA(0,2)= typename V::value_type(3); + RA(1,0)= typename V::value_type(4); RA(1,1)= typename V::value_type(5); RA(1,2)= typename V::value_type(6); + RA(2,0)= typename V::value_type(7); RA(2,1)= typename V::value_type(8); RA(2,2)= typename V::value_type(9); + pass &= compare_distance(A, RA); + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(3); + b<<= 4,5,6; + B<<=fill_policy::sparse_insert(), 1, 2, 3, b, 7, project(b, range(1,3)); + RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6; // If the first worked we can now probably use it. + pass &= compare_distance(B, RB); + } + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(3); + b<<= 4,5,6; + B<<=fill_policy::sparse_insert(), move(1,0), b, fill_policy::sparse_insert(), move_to(0,0), 1, 2, 3, move(1,0), 7, project(b, range(1,3)); + RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6; + pass &= compare_distance(B, RB); + } + + { + V B(3,3), RB(3,3); + vector<typename V::value_type> b(9); + b<<= 1, 2, 3, 4, 5, 6, 7, 8, 9; + B<<=b; + RB<<=1, 2, 3, 4, 5, 6, 7, 8, 9; + pass &= compare_distance(B, RB); + } + + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, + 4, 5; + B<<=fill_policy::sparse_insert(), C, C, C, C; + RB <<= 2,3,2,3, + 4,5,4,5, + 2,3,2,3, + 4,5,4,5; + pass &= compare_distance(B, RB); + } + + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, 4, 5; + B<<=fill_policy::sparse_insert(), C, move_to(2,2), C; + RB<<= 2,3,0,0, + 4,5,0,0, + 0,0,2,3, + 0,0,4,5; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + V C(2,2); + C <<= 2, 3, 4, 5; + B<<=fill_policy::sparse_insert(), move(1,1), C; + RB<<= 0,0,0,0, + 0,2,3,0, + 0,4,5,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_insert(), move_to(0,1), 2, 3, next_row(), 1, 2, next_row(), 4, 5; + RB<<= 0,2,3,0, + 1,2,0,0, + 4,5,0,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_insert(),traverse_policy::by_column(), move_to(0,1), 2, 3, 6, next_column(), 4, 5; + RB<<= 0,2,4,0, + 0,3,5,0, + 0,6,0,0, + 0,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_insert(),traverse_policy::by_column(), move_to(0,1), 2, 3, next_row(), traverse_policy::by_row(), 4, 5; + RB<<= 0,2,0,0, + 0,3,0,0, + 0,0,0,0, + 4,5,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_insert(),traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8; + RB<<= 0,2,0,0, + 0,3,0,0, + 4,5,6,7, + 8,0,0,0; + pass &= compare_distance(B, RB); + } + + { + V B(4,4), RB(4,4); + B = zero_matrix<typename V::value_type>(4,4); + B<<=fill_policy::sparse_insert(),traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8,9, begin1(), 1, 2; + RB<<= 0,2,1,2, + 0,3,0,0, + 4,5,6,7, + 8,9,0,0; + pass &= compare_distance(B, RB); + } + + return pass; +} + + +BOOST_UBLAS_TEST_DEF (test_vector) { + + BOOST_UBLAS_DEBUG_TRACE( "Starting operator \"<<= \" vector assignment tests" ); + + BOOST_UBLAS_TEST_CHECK(test_vector<vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<vector<char> >()); + + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<double,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<float,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<long,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<unsigned long,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<int,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<unsigned int,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<std::size_t,7> >())); + BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<char,7> >())); + + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<unsigned int> >()) + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<std::size_t> >()) + BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<long> >()) + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<unsigned long> >()) + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<double> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<float> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<char> >()); +} + +BOOST_UBLAS_TEST_DEF (test_matrix) { + + BOOST_UBLAS_DEBUG_TRACE( "Starting operator \"<<= \" matrix assignment tests" ); + + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<double,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<float,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<long,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<unsigned long,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<int,7,7 > >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<unsigned int,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<char,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<std::size_t,7, 7> >())); + + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<unsigned int> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<std::size_t> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<long> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<unsigned long> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<char> >()); + + + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<char> >()); +} + + +int main () { + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_vector ); + BOOST_UBLAS_TEST_DO( test_matrix ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_banded_storage_layout.cpp b/src/boost/libs/numeric/ublas/test/test_banded_storage_layout.cpp new file mode 100644 index 000000000..d5c640b93 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_banded_storage_layout.cpp @@ -0,0 +1,287 @@ + +#include <iostream> +#include <boost/numeric/ublas/banded.hpp> +#include <boost/numeric/ublas/io.hpp> +#include <boost/numeric/ublas/operation.hpp> +#include <iomanip> + +#include "utils.hpp" + +using namespace boost::numeric::ublas; + +int expected_index( size_t index, column_major ) { + // this is the data shown on http://www.netlib.org/lapack/lug/node124.html + // read column-by-column, aka column_major + int mapping[] = { 0, 11, 21, 31, 12, 22, 32, 42, 23, 33, 43, 53, 34, 44, 54, 0, 45, 55, 0, 0 }; + return mapping[ index ]; +} + + +int expected_index( size_t index, row_major ) { + // this is the data shown on http://www.netlib.org/lapack/lug/node124.html + // read row-by-row, aka row_major + int mapping[] = { 0, 0, 11, 12, 0, 21, 22, 23, 31, 32, 33, 34, 42, 43, 44, 45, 53, 54, 55, 0 }; + return mapping[ index ]; +} + +int expected_index_6_by_5( size_t index, column_major ) { + // read column-by-column, aka column_major + int mapping[] = { 0, 11, 21, 31, 12, 22, 32, 42, 23, 33, 43, 53, 34, 44, 54, 64, 45, 55, 65, 0 }; + return mapping[ index ]; +} + +int expected_index_6_by_5( size_t index, row_major ) { + // read row-by-row, aka row_major + int mapping[] = { 0, 0, 11, 12, 0, 21, 22, 23, 31, 32, 33, 34, 42, 43, 44, 45, 53, 54, 55, 0, 64, 65, 0, 0 }; + return mapping[ index ]; +} + +int expected_index_5_by_6( size_t index, column_major ) { + // read column-by-column, aka column_major + int mapping[] = { 0, 11, 21, 31, 12, 22, 32, 42, 23, 33, 43, 53, 34, 44, 54, 0, 45, 55, 0, 0, 56, 0, 0, 0 }; + return mapping[ index ]; +} + +int expected_index_5_by_6( size_t index, row_major ) { + // read row-by-row, aka row_major + int mapping[] = { 0, 0, 11, 12, 0, 21, 22, 23, 31, 32, 33, 34, 42, 43, 44, 45, 53, 54, 55, 56}; + return mapping[ index ]; +} + +template< typename Orientation > +bool test_band_storage() { + + int m = 5; + int n = 5; + int kl = 2; + int ku = 1; + + banded_matrix< int, Orientation > test_matrix( m, n, kl, ku ); + test_matrix.clear(); + size_t band_storage_size = test_matrix.data().size(); + + test_matrix( 0, 0 ) = 11; + test_matrix( 0, 1 ) = 12; + test_matrix( 1, 0 ) = 21; + test_matrix( 1, 1 ) = 22; + test_matrix( 1, 2 ) = 23; + test_matrix( 2, 0 ) = 31; + test_matrix( 2, 1 ) = 32; + test_matrix( 2, 2 ) = 33; + test_matrix( 2, 3 ) = 34; + test_matrix( 3, 1 ) = 42; + test_matrix( 3, 2 ) = 43; + test_matrix( 3, 3 ) = 44; + test_matrix( 3, 4 ) = 45; + test_matrix( 4, 2 ) = 53; + test_matrix( 4, 3 ) = 54; + test_matrix( 4, 4 ) = 55; + + BOOST_UBLAS_TEST_TRACE( "Full matrix" ); + BOOST_UBLAS_TEST_TRACE( std::setw( 3 ) << test_matrix ); + + BOOST_UBLAS_TEST_TRACE( "data() of matrix" ); + for ( size_t i = 0; i < band_storage_size; ++i ) { + std::cerr << test_matrix.data()[ i ] << " "; + } + std::cerr << std::endl; + + BOOST_UBLAS_TEST_TRACE( "Expected data() of matrix" ); + for ( size_t i = 0; i < band_storage_size; ++i ) { + std::cerr << expected_index( i, Orientation() ) << " "; + } + std::cerr << std::endl; + + size_t mismatch = 0; + + for ( size_t i = 0; i < band_storage_size; ++i ) { + if ( test_matrix.data()[ i ] != expected_index( i, Orientation() ) ) { + ++mismatch; + } + } + + return 0 == mismatch; +} + +template< typename Orientation > +bool test_band_storage_6_by_5() { + + int m = 6; + int n = 5; + int kl = 2; + int ku = 1; + + + banded_matrix< int, Orientation > test_matrix( m, n, kl, ku ); + test_matrix.clear(); + size_t band_storage_size = test_matrix.data().size(); + + test_matrix( 0, 0 ) = 11; + test_matrix( 0, 1 ) = 12; + test_matrix( 1, 0 ) = 21; + test_matrix( 1, 1 ) = 22; + test_matrix( 1, 2 ) = 23; + test_matrix( 2, 0 ) = 31; + test_matrix( 2, 1 ) = 32; + test_matrix( 2, 2 ) = 33; + test_matrix( 2, 3 ) = 34; + test_matrix( 3, 1 ) = 42; + test_matrix( 3, 2 ) = 43; + test_matrix( 3, 3 ) = 44; + test_matrix( 3, 4 ) = 45; + test_matrix( 4, 2 ) = 53; + test_matrix( 4, 3 ) = 54; + test_matrix( 4, 4 ) = 55; + test_matrix( 5, 3 ) = 64; + test_matrix( 5, 4 ) = 65; + + BOOST_UBLAS_TEST_TRACE( "Full matrix" ); + BOOST_UBLAS_TEST_TRACE( std::setw( 3 ) << test_matrix ); + + BOOST_UBLAS_TEST_TRACE( "data() of matrix" ); + for ( size_t i = 0; i < band_storage_size; ++i ) { + std::cerr << test_matrix.data()[ i ] << " "; + } + std::cerr << std::endl; + + BOOST_UBLAS_TEST_TRACE( "Expected data() of matrix" ); + for ( size_t i = 0; i < band_storage_size; ++i ) { + std::cerr << expected_index_6_by_5( i, Orientation() ) << " "; + } + std::cerr << std::endl; + + size_t mismatch = 0; + + for ( size_t i = 0; i < band_storage_size; ++i ) { + if ( test_matrix.data()[ i ] != expected_index_6_by_5( i, Orientation() ) ) { + ++mismatch; + } + } + + return 0 == mismatch; +} + +template< typename Orientation > +bool test_band_storage_5_by_6() { + + int m = 5; + int n = 6; + int kl = 2; + int ku = 1; + + banded_matrix< int, Orientation > test_matrix( m, n, kl, ku ); + test_matrix.clear(); + size_t band_storage_size = test_matrix.data().size(); + + test_matrix( 0, 0 ) = 11; + test_matrix( 0, 1 ) = 12; + test_matrix( 1, 0 ) = 21; + test_matrix( 1, 1 ) = 22; + test_matrix( 1, 2 ) = 23; + test_matrix( 2, 0 ) = 31; + test_matrix( 2, 1 ) = 32; + test_matrix( 2, 2 ) = 33; + test_matrix( 2, 3 ) = 34; + test_matrix( 3, 1 ) = 42; + test_matrix( 3, 2 ) = 43; + test_matrix( 3, 3 ) = 44; + test_matrix( 3, 4 ) = 45; + test_matrix( 4, 2 ) = 53; + test_matrix( 4, 3 ) = 54; + test_matrix( 4, 4 ) = 55; + test_matrix( 4, 5 ) = 56; + + BOOST_UBLAS_TEST_TRACE( "Full matrix" ); + BOOST_UBLAS_TEST_TRACE( std::setw( 3 ) << test_matrix ); + + BOOST_UBLAS_TEST_TRACE( "data() of matrix" ); + for ( size_t i = 0; i < band_storage_size; ++i ) { + std::cerr << test_matrix.data()[ i ] << " "; + } + std::cerr << std::endl; + + BOOST_UBLAS_TEST_TRACE( "Expected data() of matrix" ); + for ( size_t i = 0; i < band_storage_size; ++i ) { + std::cerr << expected_index_5_by_6( i, Orientation() ) << " "; + } + std::cerr << std::endl; + + size_t mismatch = 0; + + for ( size_t i = 0; i < band_storage_size; ++i ) { + if ( test_matrix.data()[ i ] != expected_index_5_by_6( i, Orientation() ) ) { + ++mismatch; + } + } + + return 0 == mismatch; +} + + + + +BOOST_UBLAS_TEST_DEF( banded_matrix_column_major ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < column_major >" ); + + BOOST_UBLAS_TEST_CHECK( test_band_storage< column_major >() ); +} + +BOOST_UBLAS_TEST_DEF( banded_matrix_row_major ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < row_major >" ); + + BOOST_UBLAS_TEST_CHECK( test_band_storage< row_major >() ); +} + +BOOST_UBLAS_TEST_DEF( banded_matrix_column_major_6_by_5 ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < column_major > 6x5" ); + + BOOST_UBLAS_TEST_CHECK( test_band_storage_6_by_5< column_major >() ); +} + +BOOST_UBLAS_TEST_DEF( banded_matrix_row_major_6_by_5 ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < row_major > 6x5" ); + + BOOST_UBLAS_TEST_CHECK( test_band_storage_6_by_5< row_major >() ); +} + +BOOST_UBLAS_TEST_DEF( banded_matrix_column_major_5_by_6 ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < column_major > 5x6" ); + + BOOST_UBLAS_TEST_CHECK( test_band_storage_5_by_6< column_major >() ); +} + +BOOST_UBLAS_TEST_DEF( banded_matrix_row_major_5_by_6 ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < row_major > 5x6" ); + + BOOST_UBLAS_TEST_CHECK( test_band_storage_5_by_6< row_major >() ); +} + +int main() +{ + + BOOST_UBLAS_TEST_SUITE( "Test storage layout of banded matrix type" ); + + BOOST_UBLAS_TEST_TRACE( "Example data taken from http://www.netlib.org/lapack/lug/node124.html" ); + + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( banded_matrix_column_major ); + + BOOST_UBLAS_TEST_DO( banded_matrix_row_major ); + + BOOST_UBLAS_TEST_DO( banded_matrix_column_major_6_by_5 ); + + BOOST_UBLAS_TEST_DO( banded_matrix_row_major_6_by_5 ); + + BOOST_UBLAS_TEST_DO( banded_matrix_column_major_5_by_6 ); + + BOOST_UBLAS_TEST_DO( banded_matrix_row_major_5_by_6 ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_complex_norms.cpp b/src/boost/libs/numeric/ublas/test/test_complex_norms.cpp new file mode 100644 index 000000000..0c37ed45b --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_complex_norms.cpp @@ -0,0 +1,119 @@ +// Copyright 2010 Gunter Winkler <guwi17@gmx.de> +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/io.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <complex> + +#include "utils.hpp" + +using namespace boost::numeric::ublas; + +static const double TOL(1.0e-5); ///< Used for comparing two real numbers. + +BOOST_UBLAS_TEST_DEF ( test_double_complex_norm_inf ) { + typedef std::complex<double> dComplex; + vector<dComplex> v(4); + for (unsigned int i = 0; i < v.size(); ++i) + v[i] = dComplex(i, i + 1); + + const double expected = abs(v[3]); + + BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_inf(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_inf(v) - expected) < TOL); + v *= 3.; + BOOST_UBLAS_TEST_CHECK(std::abs(norm_inf(v) - (3.0*expected)) < TOL); +} + +BOOST_UBLAS_TEST_DEF ( test_double_complex_norm_2 ) { + typedef std::complex<double> dComplex; + vector<dComplex> v(4); + for (unsigned int i = 0; i < v.size(); ++i) + v[i] = dComplex(i, i + 1); + + const double expected = sqrt(44.0); + + BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_2(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - expected) < TOL); + v *= 3.; + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - (3.0*expected)) < TOL); +} + +BOOST_UBLAS_TEST_DEF ( test_double_complex_norm_2_square ) { + typedef std::complex<double> dComplex; + vector<dComplex> v(4); + for (unsigned int i = 0; i < v.size(); ++i) + v[i] = dComplex(i, i + 1); + + const double expected = 44; + + BOOST_UBLAS_DEBUG_TRACE( "square norm is " << norm_2_square(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2_square(v) - expected) < TOL); + v *= 3.; + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2_square(v) - (9.0*expected)) < TOL); +} + + +BOOST_UBLAS_TEST_DEF ( test_float_complex_norm_inf ) { + typedef std::complex<float> dComplex; + vector<dComplex> v(4); + for (unsigned short i = 0; i < v.size(); ++i) { + unsigned short imag(i + 1); + v[i] = dComplex(i, imag); + } + + const float expected = abs(v[3]); + + BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_inf(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_inf(v) - expected) < TOL); + v *= 3.f; + BOOST_UBLAS_TEST_CHECK(std::abs(norm_inf(v) - (3.0*expected)) < TOL); +} + +BOOST_UBLAS_TEST_DEF ( test_float_complex_norm_2 ) { + typedef std::complex<float> dComplex; + vector<dComplex> v(4); + for (unsigned short i = 0; i < v.size(); ++i) { + unsigned short imag(i + 1); + v[i] = dComplex(i, imag); + } + + const double expected = sqrt(44.0); + + BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_2(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - expected) < TOL); + v *= 3.f; + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - (3.0*expected)) < TOL); +} + +BOOST_UBLAS_TEST_DEF ( test_float_complex_norm_2_square ) { + typedef std::complex<float> dComplex; + vector<dComplex> v(4); + for (unsigned short i = 0; i < v.size(); ++i) { + unsigned short imag(i + 1); + v[i] = dComplex(i, imag); + } + + const double expected = 44; + + BOOST_UBLAS_DEBUG_TRACE( "square norm is " << norm_2_square(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2_square(v) - expected) < TOL); + v *= 3.f; + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2_square(v) - (9.0*expected)) < TOL); +} + +int main() { + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_double_complex_norm_inf ); + BOOST_UBLAS_TEST_DO( test_float_complex_norm_inf ); + BOOST_UBLAS_TEST_DO( test_double_complex_norm_2 ); + BOOST_UBLAS_TEST_DO( test_float_complex_norm_2 ); + BOOST_UBLAS_TEST_DO( test_double_complex_norm_2_square ); + BOOST_UBLAS_TEST_DO( test_float_complex_norm_2_square ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_coordinate_matrix_inplace_merge.cpp b/src/boost/libs/numeric/ublas/test/test_coordinate_matrix_inplace_merge.cpp new file mode 100644 index 000000000..aac3504eb --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_coordinate_matrix_inplace_merge.cpp @@ -0,0 +1,118 @@ +// Copyright (c) 2011 David Bellot +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES +# define BOOST_UBLAS_NO_ELEMENT_PROXIES +#endif + +#include <boost/numeric/ublas/assignment.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/matrix_expression.hpp> +#include <boost/numeric/ublas/io.hpp> +#include "common/testhelper.hpp" +#include "utils.hpp" + +using std::cout; +using std::endl; + +const double TOL = 1e-15; + +template<typename T> +bool check_sortedness(const boost::numeric::ublas::coordinate_matrix<T>& matrix) { + bool result = true; + typedef boost::numeric::ublas::coordinate_matrix<T> matrix_type; + typename matrix_type::index_array_type i1 = matrix.index1_data(); + typename matrix_type::index_array_type i2 = matrix.index2_data(); + typename matrix_type::array_size_type size = matrix.filled(); + + for (typename matrix_type::array_size_type i = 0; i + 1 < size && result; ++ i) { + result &= ( (i1[i] < i1[i + 1]) || + ((i1[i] == i1[i]) && + (i2[i] < i2[i + 1])) ); + + } + return result; +} + +void print_entries(size_t size_x, size_t size_y, + const std::vector<std::pair<size_t, size_t> >& entries) +{ + std::cerr << "Error - Size:" << size_x << " x " << size_y << ". Entries: "; + for (size_t i = 0; i < entries.size(); ++ i) { + std::cerr << entries[i].first << ", " << entries[i].second << "; "; + } + std::cerr << "\n"; +} + + +BOOST_UBLAS_TEST_DEF( test_coordinate_matrix_inplace_merge_random ) +{ + const size_t max_repeats = 100; + const size_t max_size = 100; + const size_t dim_var = 10; + const size_t nr_entries = 10; + + for (size_t repeats = 1; repeats < max_repeats; ++repeats ) { + for (size_t size = 1; size < max_size; size += 5) { + size_t size_x = size + rand() % dim_var; + size_t size_y = size + rand() % dim_var; + + boost::numeric::ublas::coordinate_matrix<double> matrix_coord(size_x, size_y); + boost::numeric::ublas::matrix<double> matrix_dense(size_x, size_y, 0); + + matrix_coord.sort(); + + std::vector<std::pair<size_t, size_t> > entries; + for (size_t entry = 0; entry < nr_entries; ++ entry) { + int x = rand() % size_x; + int y = rand() % size_y; + entries.push_back(std::make_pair(x, y)); + matrix_coord.append_element(x, y, 1); + matrix_dense(x, y) += 1; + } + matrix_coord.sort(); + + { + bool sorted = check_sortedness(matrix_coord); + bool identical = compare_distance(matrix_coord, matrix_dense, TOL); + if (!(sorted && identical)) { + print_entries(size_x, size_y, entries); + } + BOOST_UBLAS_TEST_CHECK( check_sortedness(matrix_coord) ); + BOOST_UBLAS_TEST_CHECK( compare_distance(matrix_coord, matrix_dense, TOL) ); + } + + for (size_t entry = 0; entry < nr_entries; ++ entry) { + int x = rand() % size_x; + int y = rand() % size_y; + entries.push_back(std::make_pair(x, y)); + matrix_coord(x, y) += 1; + matrix_dense(x, y) += 1; + matrix_coord.sort(); + } + + { + bool sorted = check_sortedness(matrix_coord); + bool identical = compare_distance(matrix_coord, matrix_dense, TOL); + if (!(sorted && identical)) { + print_entries(size_x, size_y, entries); + } + BOOST_UBLAS_TEST_CHECK( sorted ); + BOOST_UBLAS_TEST_CHECK( identical ); + } + } + } +} + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_coordinate_matrix_inplace_merge_random ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_coordinate_matrix_sort.cpp b/src/boost/libs/numeric/ublas/test/test_coordinate_matrix_sort.cpp new file mode 100644 index 000000000..d07abb3b1 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_coordinate_matrix_sort.cpp @@ -0,0 +1,73 @@ +// Copyright (c) 2011 David Bellot +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES +# define BOOST_UBLAS_NO_ELEMENT_PROXIES +#endif + +#include<boost/numeric/ublas/matrix_sparse.hpp> +#include<boost/numeric/ublas/io.hpp> + +#include "utils.hpp" + +using std::cout; +using std::endl; + +BOOST_UBLAS_TEST_DEF( test_coordinate_matrix_sort ) +{ + + boost::numeric::ublas::coordinate_matrix<double> matrix_mask(3, 3, 2); + cout << "Setting matrix(1,1) = 2.1" << endl; + matrix_mask(1,1) = 2.1; + + cout << "Displaying matrix(1,1)" << endl; + std::cout << matrix_mask(1,1) << std::endl; + + BOOST_UBLAS_DEBUG_TRACE( "Displaying matrix(1,1)" << matrix_mask(1,1) ); + BOOST_UBLAS_TEST_CHECK( matrix_mask(1,1) == 2.1 ); + + BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[0] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[0] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[0] == 2.1 ); + + BOOST_UBLAS_DEBUG_TRACE( "Setting matrix(0,1) = 1.1" ); + matrix_mask(0, 1) = 1.1; + + BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[0] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[0] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[0] == 2.1 ); + + BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[1] == 0 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[1] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[1] == 1.1 ); + + BOOST_UBLAS_DEBUG_TRACE( "Sort the matrix - this would be triggered by any element lookup." ); + matrix_mask.sort(); + + BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[1] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[1] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[1] == 2.1 ); + + BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[0] == 0 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[0] == 1 ); + BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[0] == 1.1 ); + + BOOST_UBLAS_DEBUG_TRACE( "Displaying matrix(1,1)" << matrix_mask(1,1) ); + BOOST_UBLAS_TEST_CHECK( matrix_mask(1,1) == 2.1 ); + + BOOST_UBLAS_DEBUG_TRACE( "Displaying matrix(0,1)" << matrix_mask(0,1) ); + BOOST_UBLAS_TEST_CHECK( matrix_mask(0,1) == 1.1 ); + +} + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_coordinate_matrix_sort ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_coordinate_vector_inplace_merge.cpp b/src/boost/libs/numeric/ublas/test/test_coordinate_vector_inplace_merge.cpp new file mode 100644 index 000000000..73a4247ce --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_coordinate_vector_inplace_merge.cpp @@ -0,0 +1,107 @@ +// Copyright (c) 2011 David Bellot +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES +# define BOOST_UBLAS_NO_ELEMENT_PROXIES +#endif + +#include <boost/numeric/ublas/assignment.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/vector_sparse.hpp> +#include <boost/numeric/ublas/vector_expression.hpp> +#include <boost/numeric/ublas/io.hpp> +#include "common/testhelper.hpp" +#include "utils.hpp" + +const double TOL = 1e-15; + +template<typename T> +bool check_sortedness(const boost::numeric::ublas::coordinate_vector<T>& vector) { + bool result = true; + typedef boost::numeric::ublas::coordinate_vector<T> vector_type; + typename vector_type::index_array_type idx = vector.index_data(); + typename vector_type::size_type size = vector.filled(); + + for (typename vector_type::size_type i = 0; i + 1 < size && result; ++ i) { + result &= (idx[i] < idx[i + 1]); + } + return result; +} + +void print_entries(size_t size, + const std::vector<size_t>& entries) +{ + std::cerr << "Error entries - Size:" << size << ". Entries: "; + for (size_t i = 0; i < entries.size(); ++ i) { + std::cerr << entries[i] << "; "; + } + std::cerr << "\n"; +} + +BOOST_UBLAS_TEST_DEF( test_coordinate_vector_inplace_merge_random ) +{ + const size_t max_repeats = 100; + const size_t max_size = 100; + const size_t dim_var = 10; + const size_t nr_entries = 10; + + for (size_t repeats = 1; repeats < max_repeats; ++repeats ) { + for (size_t size = 1; size < max_size; size += 5) { + size_t size_vec = size + rand() % dim_var; + + boost::numeric::ublas::coordinate_vector<double> vector_coord(size_vec); + boost::numeric::ublas::vector<double> vector_dense(size_vec, 0); + + vector_coord.sort(); + + std::vector<size_t> entries; + for (size_t entry = 0; entry < nr_entries; ++ entry) { + int x = rand() % size_vec; + entries.push_back(x); + vector_coord.append_element(x, 1); + vector_dense(x) += 1; + } + vector_coord.sort(); + + { + bool sorted = check_sortedness(vector_coord); + bool identical = compare_distance(vector_coord, vector_dense, TOL); + if (!(sorted && identical)) { + print_entries(size_vec, entries); + } + BOOST_UBLAS_TEST_CHECK( check_sortedness(vector_coord) ); + BOOST_UBLAS_TEST_CHECK( compare_distance(vector_coord, vector_dense, TOL) ); + } + + for (size_t entry = 0; entry < nr_entries; ++ entry) { + int x = rand() % size_vec; + entries.push_back(x); + vector_coord(x) += 1; + vector_dense(x) += 1; + vector_coord.sort(); + } + + { + bool sorted = check_sortedness(vector_coord); + bool identical = compare_distance(vector_coord, vector_dense, TOL); + if (!(sorted && identical)) { + print_entries(size_vec, entries); + } + BOOST_UBLAS_TEST_CHECK( sorted ); + BOOST_UBLAS_TEST_CHECK( identical ); + } + } + } +} + +int main() +{ + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_coordinate_vector_inplace_merge_random ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_fixed_containers.cpp b/src/boost/libs/numeric/ublas/test/test_fixed_containers.cpp new file mode 100644 index 000000000..76f5a2886 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_fixed_containers.cpp @@ -0,0 +1,325 @@ +#undef BOOST_UBLAS_NO_EXCEPTIONS +#include "common/testhelper.hpp" +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/assignment.hpp> +#include <boost/numeric/ublas/io.hpp> +#include <string> +#include <complex> +#include <iomanip> +#include "utils.hpp" + +#ifdef BOOST_UBLAS_CPP_GE_2011 + +using namespace boost::numeric::ublas; + +using std::cout; +using std::endl; + + +template <typename T> +struct data_type { + typedef T value_type; +}; + +template <typename T> +struct data_type< std::complex<T> > { + typedef typename std::complex<T>::value_type value_type; +}; + + +template < class T > +bool test_vector( std::string type_name) +{ + typedef typename data_type<T>::value_type component_type; + + BOOST_UBLAS_DEBUG_TRACE( std::string("Testing for: ") + type_name ); + + bool pass = true; + + { + typedef fixed_vector<T, 1> vec1; + + vec1 v1( static_cast<component_type>(122.0) ); + + pass &= ( v1(0) == static_cast<component_type>(122.0) ); + + } + + { + typedef fixed_vector<T, 3> vec3; + + vec3 v1(static_cast<component_type>(0.0), + static_cast<component_type>(0.0), + static_cast<component_type>(0.0)); + + pass &=(sizeof( vec3 ) == v1.size() * sizeof( T ) ) ; + + vector<T> v( 3, 0 ) ; + + pass &= compare( v1, v ); + + v1 <<= static_cast<component_type>(10.0), 10, 33; + v <<= static_cast<component_type>(10.0), 10, 33; + + pass &= compare( v1, v ); + + + vec3 v2; + + v2( 0 ) = static_cast<component_type>(10.0); + v2( 1 ) = 10; + v2( 2 ) = 33; + pass &= compare( v, v2 ); + + v2 += v; + + pass &= compare( v2, 2*v ); + + + v1 = 2*v1 + v - 6*v2; + pass &= compare( v1, (3-2*6)*v ); + + + vec3 v3{ static_cast<component_type>(-90.0), + static_cast<component_type>(-90.0), + static_cast<component_type>(-297.0) }; + pass &= compare( v3, v1 ); + + vec3 v4 = { static_cast<component_type>(-90.0), + static_cast<component_type>(-90.0), + static_cast<component_type>(-297.0) }; + pass &= compare( v4, v1 ); + + vec3 v5( static_cast<component_type>(-90.0), + static_cast<component_type>(-90.0), + static_cast<component_type>(-297.0) ); + pass &= compare( v5, v1 ); + + vec3 v6( static_cast<component_type>(5.0), + static_cast<component_type>(8.0), + static_cast<component_type>(9.0) ); + + matrix<T> M = outer_prod( v6, v6), L( 3, 3); + + L <<= 25, 40, 45, 40, 64, 72, 45, 72, 81; + + pass &= compare( M, L ); + + L <<= 1, 2, 3, 4, 5, 6, 7, 8, 9; + v6 <<= 4, 5, 6; + vec3 v7 ( static_cast<component_type>(32.0), + static_cast<component_type>(77.0), + static_cast<component_type>(122.0) ); + + pass &= compare( v7, prod(L, v6) ); + + vec3 v8(prod(L, v6)); + + pass &= compare( v7, v8 ); + } + + + { + const std::size_t N = 33; + typedef fixed_vector<T, N> vec33; + + vec33 v1; + vector<T> v( N ); + + for ( std::size_t i = 0; i != v1.size(); i++) + { + v1( i ) = static_cast<component_type>(3.14159*i); + v ( i ) = static_cast<component_type>(3.14159*i); + } + + pass &= compare( v1, v ); + + + auto ip = inner_prod( v, v); + auto ip1 = inner_prod( v1, v1); + + pass &= ( ip == ip1 ) ; + + T c = 0; + for (auto i = v1.begin(); i != v1.end(); i++) + { + *i = c; + c = c + 1; + } + + c = 0; + for (auto i = v.begin(); i != v.end(); i++) + { + *i = c; + c = c + 1; + } + + pass &= compare( v1, v ); + + // Check if bad index indeed works + try { + T a; + a=v1( 100 ); + BOOST_UBLAS_NOT_USED( a ); + + } catch ( bad_index &e) { + std::cout << " Caught (GOOD): " << e.what() << endl; + pass &= true; + } + + + } + return pass; +} + +template < class T > +bool test_matrix( std::string type_name) +{ + typedef typename data_type<T>::value_type component_type; + + BOOST_UBLAS_DEBUG_TRACE( std::string("Testing for: ") + type_name ); + + bool pass = true; + + typedef fixed_matrix<T, 3, 4> mat34; + typedef fixed_matrix<T, 4, 3> mat43; + typedef fixed_matrix<T, 3, 3> mat33; + + + { + typedef fixed_matrix<T, 1, 1> mat1; + + mat1 m1( static_cast<component_type>(122.0) ); + + pass &= ( m1(0, 0) == static_cast<component_type>(122.0) ); + } + + + { + mat34 m1( T(static_cast<component_type>(3.0)) ); + + pass &=(sizeof( mat34 ) == m1.size1()*m1.size2()*sizeof( T ) ) ; + + matrix<T> m( 3, 4, static_cast<component_type>(3.0) ) ; + + pass &= compare( m1, m ); + + cout << m1 << endl; + cout << m << endl; + + + m1 <<= 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; + m <<= 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; + + pass &= compare( m1, m ); + + cout << m1 << endl; + cout << m << endl; + + mat34 m2( static_cast<component_type>(0.0) ); + + T count = 1 ; + for ( std::size_t i = 0; i != m2.size1(); i++) + { + for (std::size_t j = 0; j!= m2.size2(); j++) + { + m2( i, j ) = count; + count = count + 1; + } + + } + pass &= compare( m2, m ); + cout << m2 << endl; + + } + { + mat34 m1((T)1, (T)2, (T)3, (T)3, (T)3, (T)2, (T)5, (T)4, (T)2, (T)6, (T)5, (T)2); + mat43 m2((T)4, (T)5, (T)6, (T)3, (T)2, (T)2, (T)1, (T)4, (T)2, (T)6, (T)5, (T)2); + + mat33 m3(prod(m1, m2)); + + matrix<T> m(3, 3); + m <<= 31,36,22,47,59,40,43,52,38; + + pass &= compare(m ,m3); + + mat33 m4; + m4 <<= (T)1, (T)2, (T)1, (T)2, (T)1, (T)3, (T)1, (T)2, (T) 5; + m3 = prod(m4, trans(m4)); + + m<<=6,7,10,7,14,19,10,19,30; + + cout << m3 << endl; + pass &= compare(m ,m3); + + m3 = 2 * m4 - 1 * m3; + + cout << m3 << endl; + + m <<= -4,-3,-8,-3,-12,-13,-8,-15,-20; + + pass &= compare(m, m3); + + m = m3; + + m3 = trans(m); + + pass &= compare(m3, trans(m)); + + // Check if bad index indeed works + try { + T a; + a=m1( 100, 100 ); + BOOST_UBLAS_NOT_USED( a ); + + } catch ( bad_index &e) { + std::cout << " Caught (GOOD): " << e.what() << endl; + pass &= true; + } + + } + + return pass; + +} + +BOOST_UBLAS_TEST_DEF (test_fixed) { + + BOOST_UBLAS_DEBUG_TRACE( "Starting fixed container tests" ); + + BOOST_UBLAS_TEST_CHECK( test_vector< double >( "double") ); + BOOST_UBLAS_TEST_CHECK( test_vector< float >( "float") ); + BOOST_UBLAS_TEST_CHECK( test_vector< int >( "int") ); + + BOOST_UBLAS_TEST_CHECK( test_vector< std::complex<double> >( "std::complex<double>") ); + BOOST_UBLAS_TEST_CHECK( test_vector< std::complex<float> >( "std::complex<float>") ); + BOOST_UBLAS_TEST_CHECK( test_vector< std::complex<int> >( "std::complex<int>") ); + + BOOST_UBLAS_TEST_CHECK( test_matrix< double >( "double") ); + BOOST_UBLAS_TEST_CHECK( test_matrix< float >( "float") ); + BOOST_UBLAS_TEST_CHECK( test_matrix< int >( "int") ); + + BOOST_UBLAS_TEST_CHECK( test_matrix< std::complex<double> >( "std::complex<double>") ); + BOOST_UBLAS_TEST_CHECK( test_matrix< std::complex<float> >( "std::complex<float>") ); + BOOST_UBLAS_TEST_CHECK( test_matrix< std::complex<int> >( "std::complex<int>") ); +} + + +int main () { + + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_fixed ); + + BOOST_UBLAS_TEST_END(); +} + +#else + +int main () { + + BOOST_UBLAS_TEST_BEGIN(); + BOOST_UBLAS_TEST_END(); +} +#endif // BOOST_UBLAS_CPP_GE_2011 diff --git a/src/boost/libs/numeric/ublas/test/test_inplace_solve.cpp b/src/boost/libs/numeric/ublas/test/test_inplace_solve.cpp new file mode 100644 index 000000000..b2bf58d45 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_inplace_solve.cpp @@ -0,0 +1,123 @@ +#include <iostream> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/numeric/ublas/io.hpp> + +#include "utils.hpp" + +namespace ublas = boost::numeric::ublas; + +static const double TOL(1.0e-5); ///< Used for comparing two real numbers. +static const int n(10); ///< defines the test matrix size + +template<class mat, class vec> +double diff(const mat& A, const vec& x, const vec& b) { + return ublas::norm_2(prod(A, x) - b); +} + +// efficiently fill matrix depending on majority +template<class mat> +void fill_matrix(mat& A, ublas::column_major_tag) { + for (int i=0; i<n; ++i) { + if (i-1>=0) { + A(i-1, i) = -1; + } + A(i, i) = 1; + if (i+1<n) { + A(i+1, i) = -2; + } + } +} +template<class mat> +void fill_matrix(mat& A, ublas::row_major_tag) { + for (int i=0; i<n; ++i) { + if (i-1>=0) { + A(i, i-1) = -1; + } + A(i, i) = 1; + if (i+1<n) { + A(i, i+1) = -2; + } + } +} + +template<class mat> +BOOST_UBLAS_TEST_DEF ( test_inplace_solve ) +{ + mat A(n, n); + A.clear(); + fill_matrix(A, typename mat::orientation_category()); + + ublas::vector<double> b(n, 1.0); + + // The test matrix is not triangular, but is interpreted that way by + // inplace_solve using the lower_tag/upper_tags. For checking, the + // triangular_adaptor makes A triangular for comparison. + { + ublas::vector<double> x(b); + ublas::inplace_solve(A, x, ublas::lower_tag()); + BOOST_UBLAS_TEST_CHECK(diff(ublas::triangular_adaptor<mat, ublas::lower>(A), x, b) < TOL); + } + { + ublas::vector<double> x(b); + ublas::inplace_solve(A, x, ublas::upper_tag()); + BOOST_UBLAS_TEST_CHECK(diff (ublas::triangular_adaptor<mat, ublas::upper>(A), x, b) < TOL); + } + { + ublas::vector<double> x(b); + ublas::inplace_solve(x, A, ublas::lower_tag()); + BOOST_UBLAS_TEST_CHECK(diff (trans(ublas::triangular_adaptor<mat, ublas::lower>(A)), x, b) < TOL); + } + { + ublas::vector<double> x(b); + ublas::inplace_solve(x, A, ublas::upper_tag()); + BOOST_UBLAS_TEST_CHECK(diff (trans(ublas::triangular_adaptor<mat, ublas::upper>(A)), x , b) < TOL); + } +} + +int main() { + + // typedefs are needed as macros do not work with "," in template arguments + + BOOST_UBLAS_TEST_BEGIN(); + +#ifdef USE_MATRIX + typedef ublas::matrix<double, ublas::row_major> mat_doub_rowmaj; + typedef ublas::matrix<double, ublas::column_major> mat_doub_colmaj; + BOOST_UBLAS_TEST_DO( test_inplace_solve<mat_doub_rowmaj> ); + BOOST_UBLAS_TEST_DO( test_inplace_solve<mat_doub_colmaj> ); +#endif + +#ifdef USE_COMPRESSED_MATRIX + typedef ublas::compressed_matrix<double, ublas::row_major> commat_doub_rowmaj; + typedef ublas::compressed_matrix<double, ublas::column_major> commat_doub_colmaj; + BOOST_UBLAS_TEST_DO( test_inplace_solve<commat_doub_rowmaj> ); + BOOST_UBLAS_TEST_DO( test_inplace_solve<commat_doub_colmaj> ); +#endif + +#ifdef USE_MAPPED_MATRIX + typedef ublas::mapped_matrix<double, ublas::row_major> mapmat_doub_rowmaj; + typedef ublas::mapped_matrix<double, ublas::column_major> mapmat_doub_colmaj; + BOOST_UBLAS_TEST_DO( test_inplace_solve<mapmat_doub_rowmaj> ); + BOOST_UBLAS_TEST_DO( test_inplace_solve<mapmat_doub_colmaj> ); +#endif + +#ifdef USE_COORDINATE_MATRIX + typedef ublas::coordinate_matrix<double, ublas::row_major> cormat_doub_rowmaj; + typedef ublas::coordinate_matrix<double, ublas::column_major> cormat_doub_colmaj; + BOOST_UBLAS_TEST_DO( test_inplace_solve<cormat_doub_rowmaj> ); + BOOST_UBLAS_TEST_DO( test_inplace_solve<cormat_doub_colmaj> ); +#endif + +#ifdef USE_MAPPED_VECTOR_OF_MAPPED_VECTOR + typedef ublas::mapped_vector_of_mapped_vector<double, ublas::row_major> mvmv_doub_rowmaj; + typedef ublas::mapped_vector_of_mapped_vector<double, ublas::column_major> mvmv_doub_colmaj; + BOOST_UBLAS_TEST_DO( test_inplace_solve<mvmv_doub_rowmaj> ); + BOOST_UBLAS_TEST_DO( test_inplace_solve<mvmv_doub_colmaj> ); +#endif + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_lu.cpp b/src/boost/libs/numeric/ublas/test/test_lu.cpp new file mode 100644 index 000000000..866ecf2f2 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_lu.cpp @@ -0,0 +1,70 @@ +// Copyright 2008 Gunter Winkler <guwi17@gmx.de> +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// switch automatic singular check off +#define BOOST_UBLAS_TYPE_CHECK 0 + +#include <boost/numeric/ublas/io.hpp> +#include <boost/numeric/ublas/lu.hpp> +#include <boost/cstdlib.hpp> + +#include "common/testhelper.hpp" + +#include <iostream> +#include <sstream> + +using namespace boost::numeric::ublas; +using std::string; + +static const string matrix_IN = "[3,3]((1,2,2),(2,3,3),(3,4,6))\0"; +static const string matrix_LU = "[3,3]((3,4,6),(3.33333343e-01,6.66666627e-01,0),(6.66666687e-01,4.99999911e-01,-1))\0"; +static const string matrix_INV= "[3,3]((-3,2,-7.94728621e-08),(1.50000012,0,-5.00000060e-01),(4.99999911e-01,-1,5.00000060e-01))\0"; +static const string matrix_PM = "[3](2,2,2)"; + +int main () { + + typedef float TYPE; + + typedef matrix<TYPE> MATRIX; + + MATRIX A; + MATRIX LU; + MATRIX INV; + + { + std::istringstream is(matrix_IN); + is >> A; + } + { + std::istringstream is(matrix_LU); + is >> LU; + } + { + std::istringstream is(matrix_INV); + is >> INV; + } + permutation_matrix<>::vector_type temp; + { + std::istringstream is(matrix_PM); + is >> temp; + } + permutation_matrix<> PM(temp); + + permutation_matrix<> pm(3); + + std::size_t result = lu_factorize<MATRIX, permutation_matrix<> >(A, pm); + + assertTrue("factorization completed: ", 0 == result); + assertTrue("LU factors are correct: ", compare(A, LU)); + assertTrue("permutation is correct: ", compare(pm, PM)); + + MATRIX B = identity_matrix<TYPE>(A.size2()); + + lu_substitute(A, pm, B); + + assertTrue("inverse is correct: ", compare(B, INV)); + + return (getResults().second > 0) ? boost::exit_failure : boost::exit_success; +} diff --git a/src/boost/libs/numeric/ublas/test/test_matrix_vector.cpp b/src/boost/libs/numeric/ublas/test/test_matrix_vector.cpp new file mode 100644 index 000000000..586028737 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_matrix_vector.cpp @@ -0,0 +1,456 @@ +// +// Copyright (c) 2013 Joaquim Duran +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include <boost/numeric/ublas/assignment.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_vector.hpp> +#include "common/testhelper.hpp" +#include "utils.hpp" + +using namespace boost::numeric::ublas; + + +template <class Vector, class StorageCategory> +void guardSparsePreserveResize( Vector &vec, typename Vector::size_type new_size, StorageCategory) // Because sparse matrices don't have preserve data implemented +{ + vec.resize( new_size ); +} + + +template <class Vector> +void guardSparsePreserveResize( Vector &vec, typename Vector::size_type new_size, sparse_tag) // Because sparse matrices don't have preserve data implemented +{ + vec.resize( new_size, false ); +} + +template <class Matrix> +bool test_matrix_row_facade() { + bool pass = true; + + typedef matrix_row_vector<Matrix> RowVector; + + { // Testing resize + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: resize" ); + + typename Matrix::size_type num_rows = 3; + typename Matrix::size_type num_cols = 5; + + Matrix matrix(num_rows, num_cols); + RowVector rows(matrix); + pass &= (matrix.size1() == num_rows); + pass &= (rows.size() == num_rows); + pass &= (matrix.size2() == num_cols); + + typename Matrix::size_type new_num_rows = 6; + guardSparsePreserveResize( rows, new_num_rows, typename Matrix::storage_category()); + //rows.resize(new_num_rows); + + pass &= (matrix.size1() == new_num_rows); + pass &= (rows.size() == new_num_rows); + pass &= (matrix.size2() == num_cols); + } + + { // Testing operator() + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: operator()" ); + + Matrix A(3,3), RA(3,3); + RowVector rows(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + for(typename Matrix::size_type i = 0; i < A.size1(); i++) { + rows(i) = matrix_row<Matrix>(RA, i); + } + + pass &= compare_distance(A, RA); + } + + { // Testing operator[] + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: operator[]" ); + + Matrix A(3,3), RA(3,3); + RowVector rows(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + for(typename Matrix::size_type i = 0; i < A.size1(); i++) { + rows[i] = matrix_row<Matrix>(RA, i); + } + + pass &= compare_distance(A, RA); + } + + { // Testing operator[] const + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: operator[] const" ); + + Matrix RA(3,3); + RowVector rows(RA); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + for(typename Matrix::size_type i = 0; i < RA.size1(); i++) { + pass &= compare_distance(rows[i], matrix_row<Matrix>(RA, i)); + } + } + + { // Testing const iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: const iterator" ); + + Matrix RA(3,3); + RowVector rows(RA); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename RowVector::size_type i = 0; + for(typename RowVector::const_iterator iter = rows.begin(); + iter != rows.end(); + iter++) { + pass &= compare_distance(*iter, matrix_row<Matrix>(RA, i++)); + } + } + + { // Testing iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: iterator" ); + + Matrix A(3,3), RA(3,3); + RowVector rows(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename RowVector::size_type i = 0; + for(typename RowVector::iterator iter = rows.begin(); + iter != rows.end(); + iter++) { + *iter = matrix_row<Matrix>(RA, i++); + } + + pass &= compare_distance(A, RA); + } + + { // Testing reserse iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: reverse iterator" ); + + Matrix A(3,3), RA(3,3); + RowVector rows(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename RowVector::size_type i = rows.size(); + for(typename RowVector::reverse_iterator iter = rows.rbegin(); + iter != rows.rend(); + iter++) { + *iter = matrix_row<Matrix>(RA, --i); + } + + pass &= compare_distance(A, RA); + } + + { // Testing const reverse iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: const reverse iterator" ); + + Matrix RA(3,3); + RowVector rows(RA); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename RowVector::size_type i = rows.size(); + for(typename RowVector::const_reverse_iterator iter = rows.rbegin(); + iter != rows.rend(); + iter++) { + pass &= compare_distance(*iter, matrix_row<Matrix>(RA, --i)); + } + } + + return pass; +} + + +template <class Matrix> +bool test_matrix_column_facade() { + bool pass = true; + + typedef matrix_column_vector<Matrix> ColumnVector; + + { // Testing resize + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: resize" ); + typename Matrix::size_type num_rows = 5; + typename Matrix::size_type num_cols = 3; + + Matrix matrix(num_rows, num_cols); + ColumnVector columns(matrix); + pass &= (matrix.size2() == num_cols); + pass &= (columns.size() == num_cols); + pass &= (matrix.size1() == num_rows); + + typename Matrix::size_type new_num_cols = 6; + guardSparsePreserveResize( columns, new_num_cols, typename Matrix::storage_category()); + //columns.resize(new_num_cols); + pass &= (matrix.size2() == new_num_cols); + pass &= (columns.size() == new_num_cols); + pass &= (matrix.size1() == num_rows); + } + + { // Testing operator () + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: operator()" ); + + Matrix A(3,3), RA(3,3); + ColumnVector columns(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + for(typename Matrix::size_type i = 0; i < A.size2(); i++) { + columns(i) = matrix_column<Matrix>(RA, i); + } + + pass &= compare_distance(A, RA); + } + + { // Testing operator[] + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: operator[]" ); + + Matrix A(3,3), RA(3,3); + ColumnVector columns(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + for(typename Matrix::size_type i = 0; i < A.size2(); i++) { + columns[i] = matrix_column<Matrix>(RA, i); + } + + pass &= compare_distance(A, RA); + } + + { // Testing operator[] const + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: operator[] const" ); + + Matrix RA(3,3); + ColumnVector columns(RA); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + for(typename Matrix::size_type i = 0; i < RA.size2(); i++) { + pass &= compare_distance(columns[i], matrix_column<Matrix>(RA, i)); + } + } + + { // Testing iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: iterator" ); + + Matrix A(3,3), RA(3,3); + ColumnVector columns(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename ColumnVector::size_type i = 0; + for(typename ColumnVector::iterator iter = columns.begin(); + iter != columns.end(); + iter++) { + *iter = matrix_column<Matrix>(RA, i++); + } + + pass &= compare_distance(A, RA); + } + + { // Testing const iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: const iterator" ); + + Matrix RA(3,3); + ColumnVector columns(RA); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename ColumnVector::size_type i = 0; + for(typename ColumnVector::const_iterator iter = columns.begin(); + iter != columns.end(); + iter++) { + pass &= compare_distance(*iter, matrix_column<Matrix>(RA, i++)); + } + } + + { // Testing reserse iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: reverese iterator" ); + + Matrix A(3,3), RA(3,3); + ColumnVector columns(A); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename ColumnVector::size_type i = columns.size(); + for(typename ColumnVector::reverse_iterator iter = columns.rbegin(); + iter != columns.rend(); + iter++) { + *iter = matrix_column<Matrix>(RA, --i); + } + + pass &= compare_distance(A, RA); + } + + { // Testing const reverse iterator + BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: const reverese iterator" ); + + Matrix RA(3,3); + ColumnVector columns(RA); + + RA <<= 1, 2, 3, + 4, 5, 6, + 7, 8, 9; + + typename ColumnVector::size_type i = columns.size(); + for(typename ColumnVector::const_reverse_iterator iter = columns.rbegin(); + iter != columns.rend(); + iter++) { + pass &= compare_distance(*iter, matrix_column<Matrix>(RA, --i)); + } + } + + return pass; +} + + +BOOST_UBLAS_TEST_DEF (test_matrix_row_facade) { + + BOOST_UBLAS_DEBUG_TRACE( "Starting matrix row vector facade" ); + + BOOST_UBLAS_DEBUG_TRACE( "Testing matrix..." ); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<char> >()); + + BOOST_UBLAS_DEBUG_TRACE( "Testing bounded_matrix..." ); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<double,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<float,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<long,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<unsigned long,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<int,7,7 > >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<unsigned int,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<char,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<std::size_t,7, 7> >())); + + BOOST_UBLAS_DEBUG_TRACE( "Testing mapped_matrix..." ); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<unsigned int> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<std::size_t> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<char> >()); + + BOOST_UBLAS_DEBUG_TRACE( "Testing compressed_matrix..." ); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<char> >()); + + BOOST_UBLAS_DEBUG_TRACE( "Testing coordinate_matrix..." ); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<long> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<unsigned long> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<char> >()); +} + + +BOOST_UBLAS_TEST_DEF (test_matrix_column_facade) { + + BOOST_UBLAS_DEBUG_TRACE( "Starting matrix row column facade" ); + + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<double,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<float,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<long,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<unsigned long,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<int,7,7 > >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<unsigned int,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<char,7, 7> >())); + BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<std::size_t,7, 7> >())); + + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<unsigned int> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<std::size_t> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<unsigned long> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<char> >()); + + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<double> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<float> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<long> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<unsigned long> >()) + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<unsigned int> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<std::size_t> >()); + BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<char> >()); +} + + +int main () { + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_matrix_row_facade ); + BOOST_UBLAS_TEST_DO( test_matrix_column_facade ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_scaled_norm.cpp b/src/boost/libs/numeric/ublas/test/test_scaled_norm.cpp new file mode 100644 index 000000000..74065048f --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_scaled_norm.cpp @@ -0,0 +1,41 @@ +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/io.hpp> + +#include "utils.hpp" + +using namespace boost::numeric::ublas; + +static const double TOL(1.0e-5); ///< Used for comparing two real numbers. + +BOOST_UBLAS_TEST_DEF ( test_double_scaled_norm_2 ) { + vector<double> v(2); + v[0] = 0; v[1] = 1.0e155; + + const double expected = 1.0e155; + + BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_2(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - expected) < TOL); +} + +BOOST_UBLAS_TEST_DEF ( test_float_scaled_norm_2 ) { + vector<float> v(2); + v[0] = 0; v[1] = 1.0e20; + + const float expected = 1.0e20; + + BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_2(v) ); + BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - expected) < TOL); +} + +int main() { + BOOST_UBLAS_TEST_BEGIN(); + + BOOST_UBLAS_TEST_DO( test_double_scaled_norm_2 ); + BOOST_UBLAS_TEST_DO( test_float_scaled_norm_2 ); + + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_ticket7296.cpp b/src/boost/libs/numeric/ublas/test/test_ticket7296.cpp new file mode 100644 index 000000000..bf4d2d861 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_ticket7296.cpp @@ -0,0 +1,292 @@ +/** + * \file libs/numeric/ublas/test/test_utils.hpp + * + * \brief Test suite for utils.hpp. + * + * Copyright (c) 2012, Marco Guazzone + * + * Distributed under the Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * \author Marco Guazzone (marco.guazzone@gmail.com) + */ + +#include <boost/numeric/ublas/io.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <complex> +#include <cstddef> +#include "utils.hpp" + + +namespace ublas = boost::numeric::ublas; + + +static const float tol(1e-6f); +static const float mul(tol*10); + + +BOOST_UBLAS_TEST_DEF( check ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check'" ); + + BOOST_UBLAS_TEST_CHECK( true ); +} + +BOOST_UBLAS_TEST_DEF( check_eq ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_eq'" ); + + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_EQ( short(1), short(1) ); + BOOST_UBLAS_TEST_CHECK_EQ( int(1), int(1) ); + BOOST_UBLAS_TEST_CHECK_EQ( long(1), long(1) ); + BOOST_UBLAS_TEST_CHECK_EQ( unsigned(1), unsigned(1) ); + + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_EQ( short(1), int(1) ); + BOOST_UBLAS_TEST_CHECK_EQ( short(1), int(1) ); + BOOST_UBLAS_TEST_CHECK_EQ( int(1), long(1) ); + BOOST_UBLAS_TEST_CHECK_EQ( long(1), int(1) ); + + BOOST_UBLAS_DEBUG_TRACE( "-- Test aliases." ); + BOOST_UBLAS_TEST_CHECK_EQUAL( int(1), int(1) ); +} + +BOOST_UBLAS_TEST_DEF( check_close ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_close'" ); + + const float c1(1*mul); + const float c2(2*mul); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_CLOSE( float(c1), float(c1), tol ); + BOOST_UBLAS_TEST_CHECK_CLOSE( double(c1), double(c1), tol ); + BOOST_UBLAS_TEST_CHECK_CLOSE( std::complex<float>(c1,c2), std::complex<float>(c1,c2), tol ); + BOOST_UBLAS_TEST_CHECK_CLOSE( std::complex<double>(c1,c2), std::complex<double>(c1,c2), tol ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_CLOSE( float(c1), double(c1), tol ); + BOOST_UBLAS_TEST_CHECK_CLOSE( double(c1), float(c1), tol ); + BOOST_UBLAS_TEST_CHECK_CLOSE( std::complex<float>(c1,c2), std::complex<double>(c1,c2), tol ); + BOOST_UBLAS_TEST_CHECK_CLOSE( std::complex<double>(c1,c2), std::complex<float>(c1,c2), tol ); + + // Check alias + BOOST_UBLAS_DEBUG_TRACE( "-- Test aliases." ); + BOOST_UBLAS_TEST_CHECK_PRECISION( float(c1), float(c1), tol ); +} + +BOOST_UBLAS_TEST_DEF( check_rel_close ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_rel_close'" ); + + const float c1(1*mul); + const float c2(2*mul); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( float(c1), float(c1), tol ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( double(c1), double(c1), tol ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( std::complex<float>(c1,c2), std::complex<float>(c1,c2), tol ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( std::complex<double>(c1,c2), std::complex<double>(c1,c2), tol ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( float(c1), double(c1), tol ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( double(c1), float(c1), tol ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( std::complex<float>(c1,c2), std::complex<double>(c1,c2), tol ); + BOOST_UBLAS_TEST_CHECK_REL_CLOSE( std::complex<double>(c1,c2), std::complex<float>(c1,c2), tol ); + + // Check alias + BOOST_UBLAS_DEBUG_TRACE( "-- Test aliases." ); + BOOST_UBLAS_TEST_CHECK_REL_PRECISION( float(c1), float(c1), tol ); +} + +BOOST_UBLAS_TEST_DEF( check_vector_eq ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_vector_eq'" ); + + const std::size_t n(5); + + ublas::vector<short> sv = ublas::scalar_vector<short>(n, 1); + ublas::vector<int> iv = ublas::scalar_vector<int>(n, 1); + ublas::vector<long> lv = ublas::scalar_vector<long>(n, 1L); + ublas::vector<unsigned> uv = ublas::scalar_vector<unsigned>(n, 1u); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( sv, sv, n ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( iv, iv, n ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( lv, lv, n ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( uv, uv, n ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( sv, iv, n ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( iv, sv, n ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( iv, lv, n ); + BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( lv, iv, n ); +} + +BOOST_UBLAS_TEST_DEF( check_vector_close ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_vector_close'" ); + + const std::size_t n(5); + + ublas::vector<float> fv = ublas::scalar_vector<float>(n, 1); + ublas::vector<float> dv = ublas::scalar_vector<float>(n, 1); + ublas::vector< std::complex<float> > cfv = ublas::scalar_vector< std::complex<float> >(n, std::complex<float>(1,2)); + ublas::vector< std::complex<double> > cdv = ublas::scalar_vector< std::complex<double> >(n, std::complex<double>(1,2)); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( fv, fv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( dv, dv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( cfv, cfv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( cdv, cdv, n, tol ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( fv, dv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( dv, fv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( cfv, cdv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( cdv, cfv, n, tol ); +} + +BOOST_UBLAS_TEST_DEF( check_vector_rel_close ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_vector_rel_close'" ); + + const std::size_t n(5); + const float c1(1*mul); + const float c2(2*mul); + + ublas::vector<float> fv = ublas::scalar_vector<float>(n, c1); + ublas::vector<double> dv = ublas::scalar_vector<double>(n, c1); + ublas::vector< std::complex<float> > cfv = ublas::scalar_vector< std::complex<float> >(n, std::complex<float>(c1,c2)); + ublas::vector< std::complex<double> > cdv = ublas::scalar_vector< std::complex<double> >(n, std::complex<double>(c1,c2)); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( fv, fv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( dv, dv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( cfv, cfv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( cdv, cdv, n, tol ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( fv, dv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( dv, fv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( cfv, cdv, n, tol ); + BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( cdv, cfv, n, tol ); +} + +BOOST_UBLAS_TEST_DEF( check_matrix_eq ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_matrix_eq'" ); + + const std::size_t nr(3); + const std::size_t nc(4); + + ublas::matrix<short> sv = ublas::scalar_matrix<short>(nr, nc, 1); + ublas::matrix<int> iv = ublas::scalar_matrix<int>(nr, nc, 1); + ublas::matrix<long> lv = ublas::scalar_matrix<long>(nr, nc, 1L); + ublas::matrix<unsigned> uv = ublas::scalar_matrix<unsigned>(nr, nc, 1u); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( sv, sv, nr, nc ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( iv, iv, nr, nc ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( lv, lv, nr, nc ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( uv, uv, nr, nc ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( sv, iv, nr, nc ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( iv, sv, nr, nc ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( iv, lv, nr, nc ); + BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( lv, iv, nr, nc ); +} + +BOOST_UBLAS_TEST_DEF( check_matrix_close ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_matrix_close'" ); + + const std::size_t nr(3); + const std::size_t nc(4); + const float c1(1*mul); + const float c2(2*mul); + + ublas::matrix<float> fA = ublas::scalar_matrix<float>(nr, nc, c1); + ublas::matrix<double> dA = ublas::scalar_matrix<double>(nr, nc, c1); + ublas::matrix< std::complex<float> > cfA = ublas::scalar_matrix< std::complex<float> >(nr, nc, std::complex<float>(c1,c2)); + ublas::matrix< std::complex<double> > cdA = ublas::scalar_matrix< std::complex<double> >(nr, nc, std::complex<double>(c1,c2)); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( fA, fA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( dA, dA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( cfA, cfA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( cdA, cdA, nr, nc, tol ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( fA, dA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( dA, fA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( cfA, cdA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( cdA, cfA, nr, nc, tol ); +} + + +BOOST_UBLAS_TEST_DEF( check_matrix_rel_close ) +{ + BOOST_UBLAS_TEST_TRACE( "Test case: 'check_matrix_rel_close'" ); + + const std::size_t nr(3); + const std::size_t nc(4); + const float c1(1*mul); + const float c2(2*mul); + + ublas::matrix<float> fA = ublas::scalar_matrix<float>(nr, nc, c1); + ublas::matrix<double> dA = ublas::scalar_matrix<double>(nr, nc, c1); + ublas::matrix< std::complex<float> > cfA = ublas::scalar_matrix< std::complex<float> >(nr, nc, std::complex<float>(c1,c2)); + ublas::matrix< std::complex<double> > cdA = ublas::scalar_matrix< std::complex<double> >(nr, nc, std::complex<double>(c1,c2)); + + // Check T vs. T + BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( fA, fA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( dA, dA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( cfA, cfA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( cdA, cdA, nr, nc, tol ); + + // Check T1 vs. T2 + BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( fA, dA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( dA, fA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( cfA, cdA, nr, nc, tol ); + BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( cdA, cfA, nr, nc, tol ); +} + + +int main() +{ + BOOST_UBLAS_TEST_SUITE( "Test 'utils.hpp' functionalities" ); + + BOOST_UBLAS_TEST_BEGIN(); + BOOST_UBLAS_TEST_DO( check ); + BOOST_UBLAS_TEST_DO( check_eq ); + BOOST_UBLAS_TEST_DO( check_close ); + BOOST_UBLAS_TEST_DO( check_rel_close ); + BOOST_UBLAS_TEST_DO( check_vector_eq ); + BOOST_UBLAS_TEST_DO( check_vector_close ); + BOOST_UBLAS_TEST_DO( check_vector_rel_close ); + BOOST_UBLAS_TEST_DO( check_matrix_eq ); + BOOST_UBLAS_TEST_DO( check_matrix_close ); + BOOST_UBLAS_TEST_DO( check_matrix_rel_close ); + BOOST_UBLAS_TEST_END(); +} diff --git a/src/boost/libs/numeric/ublas/test/test_triangular.cpp b/src/boost/libs/numeric/ublas/test/test_triangular.cpp new file mode 100644 index 000000000..c6cba9134 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/test_triangular.cpp @@ -0,0 +1,129 @@ +#include <iostream> +#include <stdlib.h> +#include <cmath> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> +#include <boost/numeric/ublas/matrix_sparse.hpp> +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/numeric/ublas/io.hpp> + +#include <boost/timer/timer.hpp> + +namespace ublas = boost::numeric::ublas; + +template<class mat, class vec> +double diff(const mat& A, const vec& x, const vec& b) { + vec temp(prod(A, x) - b); + double result = 0; + for (typename vec::size_type i=0; i<temp.size(); ++i) { + result += temp(i)*temp(i); + } + return std::sqrt(result); +} + +template<class mat, class vec> +double diff(const vec& x, const mat& A, const vec& b) { + return diff(trans(A), x, b); +} + +namespace ublas = boost::numeric::ublas; + + +int main() { + const int n=7000; +#if 1 + ublas::compressed_matrix<double, ublas::row_major> mat_row_upp(n, n); + ublas::compressed_matrix<double, ublas::column_major> mat_col_upp(n, n); + ublas::compressed_matrix<double, ublas::row_major> mat_row_low(n, n); + ublas::compressed_matrix<double, ublas::column_major> mat_col_low(n, n); +#else + ublas::matrix<double, ublas::row_major> mat_row_upp(n, n, 0); + ublas::matrix<double, ublas::column_major> mat_col_upp(n, n, 0); + ublas::matrix<double, ublas::row_major> mat_row_low(n, n, 0); + ublas::matrix<double, ublas::column_major> mat_col_low(n, n, 0); +#endif + ublas::vector<double> b(n, 1); + + std::cerr << "Constructing..." << std::endl; + for (int i=0; i<n; ++i) { + b(i) = std::rand() % 10; + double main = -10 + std::rand() % 20 ; + if (main == 0) main+=1; + double side = -10 + std::rand() % 20 ; + if (i-1>=0) { + mat_row_low(i, i-1) = side; + } + mat_row_low(i, i) = main; + + mat_col_low(i, i) = main; + if (i+1<n) { + mat_col_low(i+1, i) = side; + } + + mat_row_upp(i, i) = main; + if (i+1<n) { + mat_row_upp(i, i+1) = side; + } + + if (i-1>=0) { + mat_col_upp(i-1, i) = side; + } + mat_col_upp(i, i) = main; + } + + std::cerr << "Starting..." << std::endl; + { + boost::timer::auto_cpu_timer t(std::cerr, "col_low x: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(mat_col_low, x, ublas::lower_tag()); + std::cerr << "delta: " << diff(mat_col_low, x, b) << "\n"; + } + { + boost::timer::auto_cpu_timer t(std::cerr, "row_low x: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(mat_row_low, x, ublas::lower_tag()); + std::cerr << "delta: " << diff(mat_row_low, x, b) << "\n"; + } + + { + boost::timer::auto_cpu_timer t(std::cerr, "col_upp x: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(mat_col_upp, x, ublas::upper_tag()); + std::cerr << "delta: " << diff(mat_col_upp, x, b) << "\n"; + } + { + boost::timer::auto_cpu_timer t(std::cerr, "row_upp x: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(mat_row_upp, x, ublas::upper_tag()); + std::cerr << "delta: " << diff(mat_row_upp, x, b) << "\n"; + } + + { + boost::timer::auto_cpu_timer t(std::cerr, "x col_low: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(x, mat_col_low, ublas::lower_tag()); + std::cerr << "delta: " << diff(x, mat_col_low, b) << "\n"; + } + { + boost::timer::auto_cpu_timer t(std::cerr, "x row_low: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(x, mat_row_low, ublas::lower_tag()); + std::cerr << "delta: " << diff(x, mat_row_low, b) << "\n"; + } + + { + boost::timer::auto_cpu_timer t(std::cerr, "x col_upp: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(x, mat_col_upp, ublas::upper_tag()); + std::cerr << "delta: " << diff(x, mat_col_upp, b) << "\n"; + } + { + boost::timer::auto_cpu_timer t(std::cerr, "x row_upp: %t sec CPU, %w sec real\n"); + ublas::vector<double> x(b); + ublas::inplace_solve(x, mat_row_upp, ublas::upper_tag()); + std::cerr << "delta: " << diff(x, mat_row_upp, b) << "\n"; + } + + +} diff --git a/src/boost/libs/numeric/ublas/test/triangular_access.cpp b/src/boost/libs/numeric/ublas/test/triangular_access.cpp new file mode 100644 index 000000000..c2c9b7733 --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/triangular_access.cpp @@ -0,0 +1,220 @@ +/* Test program to test find functions of triagular matrices + * + * author: Gunter Winkler ( guwi17 at gmx dot de ) + */ +// Copyright 2008 Gunter Winkler <guwi17@gmx.de> +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/numeric/ublas/io.hpp> +#include <boost/cstdlib.hpp> + +#include "common/testhelper.hpp" + +#ifdef BOOST_UBLAS_NO_NESTED_CLASS_RELATION +using boost::numeric::ublas::iterator1_tag; +using boost::numeric::ublas::iterator2_tag; +#endif + +template < class MAT > +void test_iterator( MAT & A ) { + +#ifndef NOMESSAGES + std::cout << "=>"; +#endif + // check mutable iterators + typename MAT::iterator1 it1 = A.begin1(); + typename MAT::iterator1 it1_end = A.end1(); + + for ( ; it1 != it1_end; ++it1 ) { +#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION + typename MAT::iterator2 it2 = it1.begin(); + typename MAT::iterator2 it2_end = it1.end(); +#else + typename MAT::iterator2 it2 = begin(it1, iterator1_tag()); + typename MAT::iterator2 it2_end = end(it1, iterator1_tag()); +#endif + for ( ; it2 != it2_end ; ++ it2 ) { +#ifndef NOMESSAGES + std::cout << "( " << it2.index1() << ", " << it2.index2() << ") " << std::flush; +#endif + * it2 = ( 10 * it2.index1() + it2.index2() ); + } +#ifndef NOMESSAGES + std::cout << std::endl; +#endif + } + +} + +template < class MAT > +void test_iterator2( MAT & A ) { + +#ifndef NOMESSAGES + std::cout << "=>"; +#endif + // check mutable iterators + typename MAT::iterator2 it2 = A.begin2(); + typename MAT::iterator2 it2_end = A.end2(); + + for ( ; it2 != it2_end; ++it2 ) { +#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION + typename MAT::iterator1 it1 = it2.begin(); + typename MAT::iterator1 it1_end = it2.end(); +#else + typename MAT::iterator1 it1 = begin(it2, iterator2_tag()); + typename MAT::iterator1 it1_end = end(it2, iterator2_tag()); +#endif + for ( ; it1 != it1_end ; ++ it1 ) { +#ifndef NOMESSAGES + std::cout << "( " << it1.index1() << ", " << it1.index2() << ") " << std::flush; +#endif + * it1 = ( 10 * it1.index1() + it1.index2() ); + } +#ifndef NOMESSAGES + std::cout << std::endl; +#endif + } + +} + +template < class MAT > +typename MAT::value_type +test_iterator3( const MAT & A ) { + +#ifndef NOMESSAGES + std::cout << "=>"; +#endif + typename MAT::value_type result = 0; + + // check mutable iterators + typename MAT::const_iterator1 it1 = A.begin1(); + typename MAT::const_iterator1 it1_end = A.end1(); + + for ( ; it1 != it1_end; ++it1 ) { +#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION + typename MAT::const_iterator2 it2 = it1.begin(); + typename MAT::const_iterator2 it2_end = it1.end(); +#else + typename MAT::const_iterator2 it2 = begin(it1, iterator1_tag()); + typename MAT::const_iterator2 it2_end = end(it1, iterator1_tag()); +#endif + for ( ; it2 != it2_end ; ++ it2 ) { +#ifndef NOMESSAGES + std::cout << "( " << it2.index1() << ", " << it2.index2() << ") " << std::flush; +#endif + result += * it2; + } +#ifndef NOMESSAGES + std::cout << std::endl; +#endif + } + return result; + +} + + +int main () { + using namespace boost::numeric::ublas; + + typedef double VALUE_TYPE; + typedef triangular_matrix<VALUE_TYPE, lower> LT; + typedef triangular_matrix<VALUE_TYPE, unit_lower> ULT; + typedef triangular_matrix<VALUE_TYPE, strict_lower> SLT; + typedef triangular_matrix<VALUE_TYPE, upper> UT; + typedef triangular_matrix<VALUE_TYPE, unit_upper> UUT; + typedef triangular_matrix<VALUE_TYPE, strict_upper> SUT; + + LT A(5,5); + + test_iterator(A); + test_iterator2(A); + + ULT B(5,5); + + test_iterator(B); + test_iterator2(B); + + SLT C(5,5); + + test_iterator(C); + test_iterator2(C); + + UT D(5,5); + + test_iterator(D); + test_iterator2(D); + + UUT E(5,5); + + test_iterator(E); + test_iterator2(E); + + SUT F(5,5); + + test_iterator(F); + test_iterator2(F); + + assertTrue("Write access using iterators: ", true); + + assertEquals(" LT: ",420.0,test_iterator3(A)); + assertEquals("ULT: ",315.0,test_iterator3(B)); + assertEquals("SLT: ",310.0,test_iterator3(C)); + assertEquals(" UT: ",240.0,test_iterator3(D)); + assertEquals("UUT: ",135.0,test_iterator3(E)); + assertEquals("SUT: ",130.0,test_iterator3(F)); + + assertTrue("Read access using iterators: ", true); + +#ifndef NOMESSAGES + std::cout << A << B << C << D << E << F << std::endl; +#endif + + typedef matrix<VALUE_TYPE> MATRIX; + MATRIX mat(5,5); + triangular_adaptor<MATRIX, lower> lta((mat)); + triangular_adaptor<MATRIX, unit_lower> ulta((mat)); + triangular_adaptor<MATRIX, strict_lower> slta((mat)); + triangular_adaptor<MATRIX, upper> uta((mat)); + triangular_adaptor<MATRIX, unit_upper> uuta((mat)); + triangular_adaptor<MATRIX, strict_upper> suta((mat)); + + test_iterator ( lta ); + test_iterator2( lta ); + + test_iterator ( ulta ); + test_iterator2( ulta ); + + test_iterator ( slta ); + test_iterator2( slta ); + + test_iterator ( uta ); + test_iterator2( uta ); + + test_iterator ( uuta ); + test_iterator2( uuta ); + + test_iterator ( suta ); + test_iterator2( suta ); + + assertTrue("Write access using adaptors: ", true); + + assertEquals(" LTA: ",420.0,test_iterator3( lta )); + assertEquals("ULTA: ",315.0,test_iterator3( ulta )); + assertEquals("SLTA: ",310.0,test_iterator3( slta )); + + assertEquals(" UTA: ",240.0,test_iterator3( uta )); + assertEquals("UUTA: ",135.0,test_iterator3( uuta )); + assertEquals("SUTA: ",130.0,test_iterator3( suta )); + + assertTrue("Read access using adaptors: ", true); + +#ifndef NOMESSAGES + std::cout << mat << std::endl; +#endif + + return (getResults().second > 0) ? boost::exit_failure : boost::exit_success; +} diff --git a/src/boost/libs/numeric/ublas/test/triangular_layout.cpp b/src/boost/libs/numeric/ublas/test/triangular_layout.cpp new file mode 100644 index 000000000..f4da9752b --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/triangular_layout.cpp @@ -0,0 +1,139 @@ +// Copyright 2008 Gunter Winkler <guwi17@gmx.de> +// Thanks to Tiago Requeijo for providing this test +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <iostream> +#include <boost/numeric/ublas/symmetric.hpp> +#include <boost/numeric/ublas/triangular.hpp> +#include <boost/cstdlib.hpp> + +using namespace std; +namespace ublas = boost::numeric::ublas; + +int main() +{ + int sz = 4; + ublas::symmetric_matrix<int, ublas::upper, ublas::column_major> UpCol (sz, sz); + ublas::symmetric_matrix<int, ublas::upper, ublas::row_major> UpRow (sz, sz); + ublas::symmetric_matrix<int, ublas::lower, ublas::column_major> LoCol (sz, sz); + ublas::symmetric_matrix<int, ublas::lower, ublas::row_major> LoRow (sz, sz); + + ublas::triangular_matrix<int, ublas::upper, ublas::column_major> TrUpCol (sz, sz); + ublas::triangular_matrix<int, ublas::upper, ublas::row_major> TrUpRow (sz, sz); + ublas::triangular_matrix<int, ublas::lower, ublas::column_major> TrLoCol (sz, sz); + ublas::triangular_matrix<int, ublas::lower, ublas::row_major> TrLoRow (sz, sz); + + for(int i=0; i<sz; ++i) + for(int j=i; j<sz; ++j) + { + // Symmetric + UpCol(i,j) = 10*i + j; + UpRow(i,j) = 10*i + j; + LoCol(i,j) = 10*i + j; + LoRow(i,j) = 10*i + j; + // Triangular + TrUpCol(i,j) = 10*i + j; + TrUpRow(i,j) = 10*i + j; + TrLoCol(j,i) = 10*i + j; + TrLoRow(j,i) = 10*i + j; + } + + //get pointers to data + int* uc = &(UpCol.data()[0]); + int* ur = &(UpRow.data()[0]); + int* lc = &(LoCol.data()[0]); + int* lr = &(LoRow.data()[0]); + int* tuc = &(TrUpCol.data()[0]); + int* tur = &(TrUpRow.data()[0]); + int* tlc = &(TrLoCol.data()[0]); + int* tlr = &(TrLoRow.data()[0]); + + // upper, column_major + // storage should be: 0 1 11 2 12 22 3 13 23 33 + int uc_correct[] = {0, 1, 11, 2, 12, 22, 3, 13, 23, 33}; + + // upper, row_major + // storage should be: 0 1 2 3 11 12 13 22 23 33 + int ur_correct[] = {0, 1, 2, 3, 11, 12, 13, 22, 23, 33}; + + // lower, column_major + // storage should be: 0 1 2 3 11 12 13 22 23 33 + int lc_correct[] = {0, 1, 2, 3, 11, 12, 13, 22, 23, 33}; + + // lower, row_major + // storage should be: 0 1 11 2 12 22 3 13 23 33 + int lr_correct[] = {0, 1, 11, 2, 12, 22, 3, 13, 23, 33}; + + bool success = true; + + // Test Symmetric + for(int i=0; i<sz*(sz+1)/2; ++i) + if(uc[i] != uc_correct[i]) + { + cout << "Storage error (Symmetric, Upper, Column major)" << endl; + success = false; + break; + } + + for(int i=0; i<sz*(sz+1)/2; ++i) + if(ur[i] != ur_correct[i]) + { + cout << "Storage error (Symmetric, Upper, Row major)" << endl; + success = false; + break; + } + + for(int i=0; i<sz*(sz+1)/2; ++i) + if(lc[i] != lc_correct[i]) + { + cout << "Storage error (Symmetric, Lower, Column major)" << endl; + success = false; + break; + } + + for(int i=0; i<sz*(sz+1)/2; ++i) + if(lr[i] != lr_correct[i]) + { + cout << "Storage error (Symmetric, Lower, Row major)" << endl; + success = false; + break; + } + + // Test Triangular + for(int i=0; i<sz*(sz+1)/2; ++i) + if(tuc[i] != uc_correct[i]) + { + cout << "Storage error (Triangular, Upper, Column major)" << endl; + success = false; + break; + } + + for(int i=0; i<sz*(sz+1)/2; ++i) + if(tur[i] != ur_correct[i]) + { + cout << "Storage error (Triangular, Upper, Row major)" << endl; + success = false; + break; + } + + for(int i=0; i<sz*(sz+1)/2; ++i) + if(tlc[i] != lc_correct[i]) + { + cout << "Storage error (Triangular, Lower, Column major)" << endl; + success = false; + break; + } + + for(int i=0; i<sz*(sz+1)/2; ++i) + if(tlr[i] != lr_correct[i]) + { + cout << "Storage error (Triangular, Lower, Row major)" << endl; + success = false; + break; + } + + + return (success)?boost::exit_success:boost::exit_failure; +} diff --git a/src/boost/libs/numeric/ublas/test/utils.hpp b/src/boost/libs/numeric/ublas/test/utils.hpp new file mode 100644 index 000000000..65708e17e --- /dev/null +++ b/src/boost/libs/numeric/ublas/test/utils.hpp @@ -0,0 +1,396 @@ +/** + * \file util.hpp + * + * \brief Utility macros/functions for testing and debugging purpose. + * + * Basic usage: + * <pre> + * BOOST_UBLAS_TEST_DEF( test_case_1 ) + * { + * // do your test stuff + * } + * + * BOOST_UBLAS_TEST_DEF( test_case_2 ) + * { + * // do your test stuff + * } + * + * // ... + * + * BOOST_UBLAS_TEST_DEF( test_case_n ) + * { + * // do your test stuff + * } + * + * int main() + * { + * BOOST_UBLAS_TEST_SUITE( "My Test Suite" ); // optional + * + * BOOST_UBLAS_TEST_BEGIN(); + * BOOST_UBLAS_TEST_DO( test_case_1 ); + * BOOST_UBLAS_TEST_DO( test_case_2 ); + * // ... + * BOOST_UBLAS_TEST_DO( test_case_n ); + * BOOST_UBLAS_TEST_END(); + * } + * </pre> + * Inside each <em>test_case_<code>k</code></em> you can use the various + * \c BOOST_UBLAS_TEST_CHECK* macros. + * + * <hr/> + * + * Copyright (c) 2009-2012, Marco Guazzone + * + * Distributed under the Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * \author Marco Guazzone, marco.guazzone@gmail.com + */ + +#ifndef BOOST_NUMERIC_UBLAS_TEST_UTILS_HPP +#define BOOST_NUMERIC_UBLAS_TEST_UTILS_HPP + + +#include <boost/numeric/ublas/detail/config.hpp> +#include <boost/numeric/ublas/traits.hpp> + +#include <boost/math/special_functions/fpclassify.hpp> // isnan, isinf + +#include <cmath> +#include <complex> +#include <cstddef> +#include <iostream> +#include <limits> +#include <stdexcept> + +#define BOOST_UBLAS_NOT_USED(x) (void)(x) + +namespace boost { namespace numeric { namespace ublas { namespace test { namespace detail { namespace /*<unnamed>*/ { + + using ::std::abs; + using ::std::max; + +/// Check if the given complex number is a NaN. +// read the comments in fpclassify as well +template <typename T> +BOOST_UBLAS_INLINE +bool (isnan)(::std::complex<T> const& z) +{ + // According to IEEE, NaN is different even by itself + return (z != z) || (boost::math::isnan)(z.real()) || (boost::math::isnan)(z.imag()); +} + +/// Check if two (real) numbers are close each other (wrt a given tolerance). +template <typename T1, typename T2, typename T3> +BOOST_UBLAS_INLINE +bool close_to(T1 x, T2 y, T3 tol) +{ + typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type, + T3>::promote_type real_type; + + if ((boost::math::isnan)(x) || (boost::math::isnan)(y)) + { + // According to IEEE, NaN is different even by itself + return false; + } + return abs(x-y) <= (max(static_cast<real_type>(abs(x)), static_cast<real_type>(abs(y)))*tol); +} + +/// Check if two complex numbers are close each other (wrt a given tolerance). +template <typename T1, typename T2, typename T3> +BOOST_UBLAS_INLINE +bool close_to(::std::complex<T1> const& x, ::std::complex<T2> const& y, T3 tol) +{ + typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type, + T3>::promote_type real_type; + + if ((isnan)(x) || (isnan)(y)) + { + // According to IEEE, NaN is different even by itself + return false; + } + ::std::complex<real_type> xx(x); + ::std::complex<real_type> yy(y); + + return abs(xx-yy) <= (max(abs(xx), abs(yy))*tol); +} + +/// Check if two (real) numbers are close each other (wrt a given tolerance). +template <typename T1, typename T2, typename T3> +BOOST_UBLAS_INLINE +bool rel_close_to(T1 x, T2 y, T3 tol) +{ + //typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type, + // T3>::promote_type real_type; + + if ((boost::math::isnan)(x) || (boost::math::isnan)(y)) + { + // According to IEEE, NaN is different even by itself + return false; + } + return abs(x-y)/abs(y) <= tol; +} + +/// Check if two complex numbers are close each other (wrt a given tolerance). +template <typename T1, typename T2, typename T3> +BOOST_UBLAS_INLINE +bool rel_close_to(::std::complex<T1> const& x, ::std::complex<T2> const& y, T3 tol) +{ + typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type, + T3>::promote_type real_type; + + if ((isnan)(x) || (isnan)(y)) + { + // According to IEEE, NaN is different even by itself + return false; + } + ::std::complex<real_type> xx(x); + ::std::complex<real_type> yy(y); + + return abs(xx-yy)/abs(yy) <= tol; +} + +}}}}}} // Namespace boost::numeric::ublas::test::detail::<unnamed> + + +/// Expand its argument \a x. +#define BOOST_UBLAS_TEST_EXPAND_(x) x + + +/// Expand its argument \a x inside parenthesis. +#define BOOST_UBLAS_TEST_EXPANDP_(x) (x) + + +/// Transform its argument \a x into a string. +#define BOOST_UBLAS_TEST_STRINGIFY_(x) #x + + +/// Concatenate its two \e string arguments \a x and \a y. +#define BOOST_UBLAS_TEST_JOIN_(x,y) x ## y + + +/// Output the message \a x if in debug-mode; otherwise output nothing. +/// Note: we don't use macro expansion inside parenthesis to let \a m be an +/// expression of the form <code>a << b</code>. +#ifndef NDEBUG +# define BOOST_UBLAS_DEBUG_TRACE(x) ::std::cerr << "[Debug>> " << BOOST_UBLAS_TEST_EXPAND_(x) << ::std::endl +#else +# define BOOST_UBLAS_DEBUG_TRACE(x) /**/ +#endif // NDEBUG + + +/// Define the name \a m of the entire test suite. +#define BOOST_UBLAS_TEST_SUITE(m) ::std::cerr << "--- Test Suite: " << BOOST_UBLAS_TEST_EXPAND_(m) << " ---" << ::std::endl; + + +/// Define the beginning of a test suite. +#define BOOST_UBLAS_TEST_BEGIN() /* [BOOST_UBLAS_TEST_BEGIN] */ \ + { \ + /* Begin of Test Suite */ \ + ::std::size_t test_fails__(0) \ + /* [/BOOST_UBLAS_TEST_BEGIN] */ + + +/// Define a test case \a x inside the current test suite. +#define BOOST_UBLAS_TEST_DEF(x) static void BOOST_UBLAS_TEST_EXPAND_(x)(::std::size_t& test_fails__) + + +/// Call the test case \a x. +#define BOOST_UBLAS_TEST_DO(x) /* [BOOST_UBLAS_TEST_DO] */ \ + try \ + { \ + BOOST_UBLAS_TEST_EXPAND_(x)(test_fails__); \ + } \ + catch (::std::exception& e) \ + { \ + ++test_fails__; \ + BOOST_UBLAS_TEST_ERROR( e.what() ); \ + } \ + catch (...) \ + { \ + ++test_fails__; \ + } \ + /* [/BOOST_UBLAS_TEST_DO] */ + + +/// Define the end of a test suite and return non-zero value if any test failed. +#define BOOST_UBLAS_TEST_END() /* [BOOST_UBLAS_TEST_END] */ \ + if (test_fails__ > 0) \ + { \ + ::std::cerr << "Number of failed tests: " << test_fails__ << ::std::endl; \ + return EXIT_FAILURE; \ + } \ + else \ + { \ + ::std::cerr << "No failed test" << ::std::endl; \ + return EXIT_SUCCESS; \ + } \ + } /* End of test suite */ \ + /* [/BOOST_UBLAS_TEST_END] */ + + +/// Output the message \a m. +/// Note: we don't use macro expansion inside parenthesis to let \a m be an +/// expression of the form <code>a << b</code>. +#define BOOST_UBLAS_TEST_TRACE(m) ::std::cerr << "[Info>> " << BOOST_UBLAS_TEST_EXPAND_(m) << ::std::endl + + +/// Check the truth of assertion \a x. +#define BOOST_UBLAS_TEST_CHECK(x) /* [BOOST_UBLAS_TEST_CHECK] */ \ + if (!BOOST_UBLAS_TEST_EXPANDP_(x)) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: " << BOOST_UBLAS_TEST_STRINGIFY_(x) ); \ + ++test_fails__; \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK] */ + + +/// Check for the equality of \a x against \a y. +#define BOOST_UBLAS_TEST_CHECK_EQ(x,y) /* [BOOST_UBLAS_TEST_CHECK_EQUAL] */ \ + if (!(BOOST_UBLAS_TEST_EXPANDP_(x) == BOOST_UBLAS_TEST_EXPANDP_(y))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: (" << BOOST_UBLAS_TEST_STRINGIFY_(x) << " == " << BOOST_UBLAS_TEST_STRINGIFY_(y) << ")" ); \ + ++test_fails__; \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_EQUAL] */ + + +/// Alias for macro \c BOOST_UBLAS_TEST_CHECK_EQ (for backward compatibility). +#define BOOST_UBLAS_TEST_CHECK_EQUAL(x,y) BOOST_UBLAS_TEST_CHECK_EQ(x,y) + + +/// Check that \a x and \a y are close with respect to a given precision \a e. +#define BOOST_UBLAS_TEST_CHECK_CLOSE(x,y,e) /* [BOOST_UBLAS_TEST_CHECK_CLOSE] */ \ + if (!::boost::numeric::ublas::test::detail::close_to(BOOST_UBLAS_TEST_EXPAND_(x), BOOST_UBLAS_TEST_EXPAND_(y), BOOST_UBLAS_TEST_EXPAND_(e))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs(" << BOOST_UBLAS_TEST_STRINGIFY_(x) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " == " << BOOST_UBLAS_TEST_EXPANDP_(e) << "]" ); \ + ++test_fails__; \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_CLOSE] */ + + +/// Alias for macro \c BOOST_UBLAS_TEST_CHECK_CLOSE (for backward compatibility), +#define BOOST_UBLAS_TEST_CHECK_PRECISION(x,y,e) BOOST_UBLAS_TEST_CHECK_CLOSE(x,y,e) + + +/// Check that \a x is close to \a y with respect to a given relative precision \a e. +#define BOOST_UBLAS_TEST_CHECK_REL_CLOSE(x,y,e) /* [BOOST_UBLAS_TEST_CHECK_REL_CLOSE] */ \ + if (!::boost::numeric::ublas::test::detail::rel_close_to(BOOST_UBLAS_TEST_EXPAND_(x), BOOST_UBLAS_TEST_EXPAND_(y), BOOST_UBLAS_TEST_EXPAND_(e))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y) << ")/" << BOOST_UBLAS_TEST_STRINGIFY_(y) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " == " << BOOST_UBLAS_TEST_EXPANDP_(e) << "]" ); \ + ++test_fails__; \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_REL_CLOSE] */ + + +/// Alias for macro \c BOOST_UBLAS_TEST_CHECK_REL_CLOSE (for backward compatibility), +#define BOOST_UBLAS_TEST_CHECK_REL_PRECISION(x,y,e) BOOST_UBLAS_TEST_CHECK_REL_CLOSE(x,y,e) + + +/// Check that elements of \a x and \a y are equal. +#define BOOST_UBLAS_TEST_CHECK_VECTOR_EQ(x,y,n) /* [BOOST_UBLAS_TEST_CHECK_VECTOR_EQ] */ \ + if (BOOST_UBLAS_TEST_EXPANDP_(n) > 0) \ + { \ + ::std::size_t n__ = BOOST_UBLAS_TEST_EXPAND_(n); \ + for (::std::size_t i__ = n__; i__ > 0; --i__) \ + { \ + if (!(BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__]==BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__])) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: (" << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << "==" << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << ")" << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << " and " << BOOST_UBLAS_TEST_STRINGIFY_(n) << " == " << n__ << "]" ); \ + ++test_fails__; \ + } \ + } \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_VECTOR_EQ] */ + + +/// Check that elements of \a x and \a y are close with respect to a given precision \a e. +#define BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE(x,y,n,e) /* [BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE] */ \ + if (BOOST_UBLAS_TEST_EXPANDP_(n) > 0) \ + { \ + ::std::size_t n__ = BOOST_UBLAS_TEST_EXPAND_(n); \ + for (::std::size_t i__ = n__; i__ > 0; --i__) \ + { \ + if (!::boost::numeric::ublas::test::detail::close_to(BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__], BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__], BOOST_UBLAS_TEST_EXPANDP_(e))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << " and " << BOOST_UBLAS_TEST_STRINGIFY_(n) << " == " << n__ << "]" ); \ + ++test_fails__; \ + } \ + } \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE] */ + + +/// Check that elements of \a x and \a y are close with respect to a given relative precision \a e. +#define BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE(x,y,n,e) /* [BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE] */ \ + if (BOOST_UBLAS_TEST_EXPANDP_(n) > 0) \ + { \ + ::std::size_t n__ = BOOST_UBLAS_TEST_EXPAND_(n); \ + for (::std::size_t i__ = n__; i__ > 0; --i__) \ + { \ + if (!::boost::numeric::ublas::test::detail::rel_close_to(BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__], BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__], BOOST_UBLAS_TEST_EXPANDP_(e))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << " and " << BOOST_UBLAS_TEST_STRINGIFY_(n) << " == " << n__ << "]" ); \ + ++test_fails__; \ + } \ + } \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE] */ + + +/// Check that elements of matrices \a x and \a y are equal. +#define BOOST_UBLAS_TEST_CHECK_MATRIX_EQ(x,y,nr,nc) /* [BOOST_UBLAS_TEST_CHECK_MATRIX_EQ] */ \ + for (::std::size_t i__ = 0; i__ < BOOST_UBLAS_TEST_EXPANDP_(nr); ++i__) \ + { \ + for (::std::size_t j__ = 0; j__ < BOOST_UBLAS_TEST_EXPANDP_(nc); ++j__) \ + { \ + if (!(BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__)==BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: (" << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << " == " << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << ") [with " << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << ", " << BOOST_UBLAS_TEST_STRINGIFY_(j__) << " == " << BOOST_UBLAS_TEST_EXPANDP_(j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(nr) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nr) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(nc) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nc) << "]" ); \ + ++test_fails__; \ + } \ + } \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_MATRIX_EQ] */ + + +/// Check that elements of matrices \a x and \a y are close with respect to a given precision \a e. +#define BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE(x,y,nr,nc,e) /* [BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE] */ \ + for (::std::size_t i__ = 0; i__ < BOOST_UBLAS_TEST_EXPANDP_(nr); ++i__) \ + { \ + for (::std::size_t j__ = 0; j__ < BOOST_UBLAS_TEST_EXPANDP_(nc); ++j__) \ + { \ + if (!::boost::numeric::ublas::test::detail::close_to(BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__), BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__), BOOST_UBLAS_TEST_EXPANDP_(e))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << ", " << BOOST_UBLAS_TEST_STRINGIFY_(j__) << " == " << BOOST_UBLAS_TEST_EXPANDP_(j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(nr) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nr) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(nc) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nc) << "]" ); \ + ++test_fails__; \ + } \ + } \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE] */ + + +/// Check that elements of matrices \a x and \a y are close with respect to a given relative precision \a e. +#define BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE(x,y,nr,nc,e) /* [BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE] */ \ + for (::std::size_t i__ = 0; i__ < BOOST_UBLAS_TEST_EXPANDP_(nr); ++i__) \ + { \ + for (::std::size_t j__ = 0; j__ < BOOST_UBLAS_TEST_EXPANDP_(nc); ++j__) \ + { \ + if (!::boost::numeric::ublas::test::detail::rel_close_to(BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__), BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__), BOOST_UBLAS_TEST_EXPANDP_(e))) \ + { \ + BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << ", " << BOOST_UBLAS_TEST_STRINGIFY_(j__) << " == " << BOOST_UBLAS_TEST_EXPANDP_(j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(nr) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nr) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(nc) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nc) << "]" ); \ + ++test_fails__; \ + } \ + } \ + } \ + /* [/BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE] */ + +///< Output the error message \a x. +#ifdef _MSC_VER +# define BOOST_UBLAS_TEST_ERROR(x) ::std::cerr << "[Error (" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ")>> " << BOOST_UBLAS_TEST_EXPAND_(x) << ::std::endl +#else +# define BOOST_UBLAS_TEST_ERROR(x) ::std::cerr << "[Error (" << __FILE__ << ":" << __func__ << ":" << __LINE__ << ")>> " << BOOST_UBLAS_TEST_EXPAND_(x) << ::std::endl +#endif + +#endif // BOOST_NUMERIC_UBLAS_TEST_UTILS_HPP |