diff --git a/doc/container_concept.htm b/doc/container_concept.htm index 2613b6fe..141f4e1a 100644 --- a/doc/container_concept.htm +++ b/doc/container_concept.htm @@ -110,7 +110,7 @@ Dense Vector ONLY. The type of underlying storage array used to store the elemen Storage v.data() v is mutable and Dense. -array_type& if a is mutable, const array_type& otherwise +array_type& if v is mutable, const array_type& otherwise @@ -307,7 +307,7 @@ following expressions must be valid.

Storage m.data() m is mutable and Dense. -array_type& if a is mutable, const array_type& otherwise +array_type& if m is mutable, const array_type& otherwise diff --git a/doc/samples/Jamfile.v2 b/doc/samples/Jamfile.v2 index d32c8742..55a8e6a6 100644 --- a/doc/samples/Jamfile.v2 +++ b/doc/samples/Jamfile.v2 @@ -222,3 +222,7 @@ exe triangular_matrix exe triangular_adaptor : triangular_adaptor.cpp ; + +exe ex_triangular + : ex_triangular.cpp + ; diff --git a/doc/samples/ex_triangular.cpp b/doc/samples/ex_triangular.cpp new file mode 100644 index 00000000..a2a34d96 --- /dev/null +++ b/doc/samples/ex_triangular.cpp @@ -0,0 +1,58 @@ +// Copyright Gunter Winkler 2004 - 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) + + +#include + +#include +#include + +#include + +using std::cout; +using std::endl; + + + +namespace ublas = boost::numeric::ublas; + + +int main(int argc, char * argv[] ) { + + ublas::matrix M (3, 3); + for (std::size_t i=0; i < M.data().size(); ++i) { M.data()[i] = 1+i ; } + + std::cout << "full M = " << M << "\n" ; + + ublas::triangular_matrix L; + ublas::triangular_matrix UL; + ublas::triangular_matrix SL; + + L = ublas::triangular_adaptor, ublas::lower> (M); + SL = ublas::triangular_adaptor, ublas::strict_lower> (M); + UL = ublas::triangular_adaptor, ublas::unit_lower> (M); + + std::cout << "lower L = " << L << "\n" + << "strict lower SL = " << SL << "\n" + << "unit lower UL = " << UL << "\n" ; + + ublas::triangular_matrix U; + ublas::triangular_matrix UU; + ublas::triangular_matrix SU; + + U = ublas::triangular_adaptor, ublas::upper> (M); + SU = ublas::triangular_adaptor, ublas::strict_upper> (M); + UU = ublas::triangular_adaptor, ublas::unit_upper> (M); + + std::cout << "upper U = " << U << "\n" + << "strict upper SU = " << SU << "\n" + << "unit upper UU = " << UU << "\n" ; + + std::cout << "M = L + SU ? " << ((norm_inf( M - (L + SU) ) == 0.0)?"ok":"failed") << "\n"; + std::cout << "M = U + SL ? " << ((norm_inf( M - (U + SL) ) == 0.0)?"ok":"failed") << "\n"; + +} + + diff --git a/doc/triangular.htm b/doc/triangular.htm index eea59333..f2ff474c 100644 --- a/doc/triangular.htm +++ b/doc/triangular.htm @@ -21,7 +21,7 @@ For a (n x n )-dimensional lower triangular matrix and ti, j = 0 , if i > j. If furthermore holds ti, i= 1 the matrix is called unit lower triangular. For a (n x n -)-dimensional upper triangular matrix and 0 <= i < +)-dimensional lower triangular matrix and 0 <= i < n,0 <= j < n holds ti, j = 0 , if i < j. If furthermore holds ti, i= 1 the matrix is called @@ -46,6 +46,8 @@ int main () { std::cout << mu << std::endl; } +

Please read the full triangular example for more details.

+

Definition

Defined in the header triangular.hpp.

Template parameters

@@ -348,6 +350,8 @@ int main () { std::cout << tau << std::endl; } +

Please read the full triangular example for more details.

+

Definition

Defined in the header triangular.hpp.

Template parameters

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fdb8beee..8b2a0b8f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -50,13 +50,22 @@ boost_test_run(ublas_test6 test6.cpp test62.cpp test63.cpp COMPILE_FLAGS "${UBLAS_TESTSET_DEFINES}") -# Test commented out, just like in V1 and V2 Jamfiles +# Test commented out because boost::interval does not behave like a scalar # boost_test_run(test7 # test7.cpp test71.cpp test72.cpp test73.cpp # COMPILE_FLAGS "-DBOOST_UBLAS_USE_INTERVAL ${UBLAS_TESTSET_DEFINES}") boost_test_run(placement_new) +boost_test_run(test_lu) + +boost_test_run(triangular_access + triangular_access.cpp + COMPILE_FLAGS "-DNOMESSAGES") + +boost_test_run(triangular_layout + triangular_layout.cpp) + SET(test_compile_flags "-DEXTERNAL") #-- Intel Compiler flags diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index a1b401ed..0bd12e83 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -88,7 +88,7 @@ test-suite numeric/uBLAS : : : $(UBLAS_TESTSET) ] -# Test commented out, just like in V1 Jamfile +# Test commented out because boost::interval does not behave like a scalar type # [ run test7.cpp # test71.cpp # test72.cpp @@ -106,4 +106,12 @@ test-suite numeric/uBLAS intel-linux:"-Xc" darwin:"-fabi-version=0" ] + [ run test_lu.cpp + ] + [ run triangular_access.cpp + : : : + NOMESSAGES + ] + [ run triangular_layout.cpp + ] ; diff --git a/test/common/init.hpp b/test/common/init.hpp index e3a23ed5..a9691b4e 100644 --- a/test/common/init.hpp +++ b/test/common/init.hpp @@ -43,7 +43,7 @@ template 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); + v [i] = typename V::value_type ( i + 1.f ); } template @@ -52,11 +52,11 @@ void initialize_matrix_impl (M &m, ublas::packed_proxy_tag) { #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); + *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); + *j = typename M::value_type ( i.index1() * size1 + j.index2() + 1.f ); #endif } diff --git a/test/common/testhelper.hpp b/test/common/testhelper.hpp new file mode 100644 index 00000000..4fbf9c4d --- /dev/null +++ b/test/common/testhelper.hpp @@ -0,0 +1,74 @@ +// Copyright 2008 Gunter Winkler +// 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 + +static unsigned _success_counter = 0; +static unsigned _fail_counter = 0; + +static inline +void assertTrue(const char* message, bool condition) { +#ifndef NOMESSAGES + std::cout << 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; +#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 + } +} + +static +std::pair getResults() { + return std::make_pair(_success_counter, _fail_counter); +} + +template < class M1, class M2 > +bool compare( const boost::numeric::ublas::matrix_expression & m1, + const boost::numeric::ublas::matrix_expression & m2 ) { + size_t size1 = (std::min)(m1().size1(), m2().size1()); + size_t size2 = (std::min)(m1().size2(), m2().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, + const boost::numeric::ublas::vector_expression & m2 ) { + size_t size = (std::min)(m1().size(), m2().size()); + for (size_t i=0; i < size; ++i) { + if ( m1()(i) != m2()(i) ) return false; + } + return true; +} + +#endif diff --git a/test/test7.cpp b/test/test7.cpp index 4782975f..f564031c 100644 --- a/test/test7.cpp +++ b/test/test7.cpp @@ -21,6 +21,8 @@ #include "test7.hpp" +// this testcase requires fix of task #2473 + int main () { test_vector (); test_matrix_vector (); diff --git a/test/test71.cpp b/test/test71.cpp index 3d397bd3..89e9ccf7 100644 --- a/test/test71.cpp +++ b/test/test71.cpp @@ -36,7 +36,7 @@ struct test_my_vector { std::cout << "v1.swap (v2) = " << v1 << " " << v2 << std::endl; // Zero assignment - v1 = ublas::zero_vector<> (v1.size ()); + v1 = ublas::zero_vector (v1.size ()); std::cout << "v1.zero_vector = " << v1 << std::endl; v1 = v2; diff --git a/test/test73.cpp b/test/test73.cpp index cb0a55b5..e2d68cee 100644 --- a/test/test73.cpp +++ b/test/test73.cpp @@ -33,7 +33,7 @@ struct test_my_matrix { std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl; // Zero assignment - m1 = ublas::zero_matrix<> (m1.size (), m1.size2 ()); + m1 = ublas::zero_matrix (m1.size1 (), m1.size2 ()); std::cout << "m1.zero_matrix = " << m1 << std::endl; m1 = m2; diff --git a/test/test_lu.cpp b/test/test_lu.cpp new file mode 100644 index 00000000..e2b203f8 --- /dev/null +++ b/test/test_lu.cpp @@ -0,0 +1,70 @@ +// Copyright 2008 Gunter Winkler +// 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 +#include +#include + +#include "common/testhelper.hpp" + +#include +#include + +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 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); + + int result = lu_factorize >(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(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/test/triangular_access.cpp b/test/triangular_access.cpp new file mode 100644 index 00000000..cccf80d0 --- /dev/null +++ b/test/triangular_access.cpp @@ -0,0 +1,201 @@ +/* Test program to test find functions of triagular matrices + * + * author: Gunter Winkler ( guwi17 at gmx dot de ) + */ +// Copyright 2008 Gunter Winkler +// 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 +#include +#include + +#include "common/testhelper.hpp" + + +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 ) { + typename MAT::iterator2 it2 = it1.begin(); + typename MAT::iterator2 it2_end = it1.end(); + 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 ) { + typename MAT::iterator1 it1 = it2.begin(); + typename MAT::iterator1 it1_end = it2.end(); + 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 ) { + typename MAT::const_iterator2 it2 = it1.begin(); + typename MAT::const_iterator2 it2_end = it1.end(); + 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 (int argc, char * argv[]) { + using namespace boost::numeric::ublas; + + typedef double VALUE_TYPE; + typedef triangular_matrix LT; + typedef triangular_matrix ULT; + typedef triangular_matrix SLT; + typedef triangular_matrix UT; + typedef triangular_matrix UUT; + typedef triangular_matrix 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 MATRIX; + MATRIX mat(5,5); + triangular_adaptor lta((mat)); + triangular_adaptor ulta((mat)); + triangular_adaptor slta((mat)); + triangular_adaptor uta((mat)); + triangular_adaptor uuta((mat)); + triangular_adaptor 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/test/triangular_layout.cpp b/test/triangular_layout.cpp new file mode 100644 index 00000000..8906bc86 --- /dev/null +++ b/test/triangular_layout.cpp @@ -0,0 +1,139 @@ +// Copyright 2008 Gunter Winkler +// 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 +#include +#include +#include + +using namespace std; +namespace ublas = boost::numeric::ublas; + +int main(int argc, char* argv[]) +{ + int sz = 4; + ublas::symmetric_matrix UpCol (sz, sz); + ublas::symmetric_matrix UpRow (sz, sz); + ublas::symmetric_matrix LoCol (sz, sz); + ublas::symmetric_matrix LoRow (sz, sz); + + ublas::triangular_matrix TrUpCol (sz, sz); + ublas::triangular_matrix TrUpRow (sz, sz); + ublas::triangular_matrix TrLoCol (sz, sz); + ublas::triangular_matrix TrLoRow (sz, sz); + + for(int i=0; i