123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500 |
- /*
- * NICE-Core - efficient algebra and computer vision methods
- * - libbasicvector - A simple vector library
- * See file License for license information.
- */
- #ifdef NICE_USELIB_CPPUNIT
- #include <string>
- #include <iostream>
- #include <stdexcept>
- #include <cstddef>
- #include <core/basics/cppunitex.h>
- #include "core/vector/RowMatrixT.h"
- #include "core/vector/CheckedVectorT.h"
- #include "core/vector/CheckedRowMatrixT.h"
- #include "core/vector/Eigen.h"
- #include "core/vector/Algorithms.h"
- #include "TestERowMatrix.h"
- #ifdef NICE_USELIB_LINAL
- #include "LinAl/eigen.h"
- #endif
- CPPUNIT_TEST_SUITE_REGISTRATION( TestERowMatrix );
- using namespace NICE;
- using namespace std;
- void TestERowMatrix::setUp() {
- }
- void TestERowMatrix::tearDown() {
- }
- void TestERowMatrix::testAccess() {
- RowMatrixT<double> m(10, 7, 5.4);
- CPPUNIT_ASSERT_EQUAL(5.4, m(0, 3));
- CPPUNIT_ASSERT_EQUAL(5.4, m(9, 6));
- }
- void TestERowMatrix::testConst() {
- const char* data = "abcdef";
- RowMatrixT<char> v(data, 2, 3);
- CPPUNIT_ASSERT_EQUAL(2u, (uint)v.rows());
- CPPUNIT_ASSERT_EQUAL(3u, (uint)v.cols());
- for (unsigned int i = 0; i < v.rows(); i++) {
- for (unsigned int j = 0; j < v.cols(); j++) {
- // row major
- CPPUNIT_ASSERT_EQUAL(data[i*3+j], v(i, j));
- }
- }
- }
- void TestERowMatrix::testCopy() {
- const char data[] = "fkepw.xja8";
- unsigned int size = strlen(data);
- unsigned int rows = size / 2;
- unsigned int cols = 2;
- RowMatrixT<char> v(data, rows, cols);
- RowMatrixT<char> w(v);
- RowMatrixT<char> x(w);
- CPPUNIT_ASSERT_EQUAL(rows, (uint)v.rows());
- CPPUNIT_ASSERT_EQUAL(cols, (uint)v.cols());
- CPPUNIT_ASSERT_EQUAL(rows, (uint)w.rows());
- CPPUNIT_ASSERT_EQUAL(cols, (uint)w.cols());
- CPPUNIT_ASSERT_EQUAL(rows, (uint)x.rows());
- CPPUNIT_ASSERT_EQUAL(cols, (uint)x.cols());
- for (unsigned int i = 0; i < v.rows(); i++) {
- for (unsigned int j = 0; j < v.cols(); j++) {
- // row major
- CPPUNIT_ASSERT_EQUAL(data[i*cols+j], v(i, j));
- CPPUNIT_ASSERT_EQUAL(data[i*cols+j], w(i, j));
- CPPUNIT_ASSERT_EQUAL(data[i*cols+j], x(i, j));
- }
- }
- }
- void TestERowMatrix::testExternal() {
- char data[] = "1234567890";
- unsigned int size = strlen(data);
- unsigned int rows = size / 5;
- unsigned int cols = 5;
- RowMatrixT<char> v(data, rows, cols, MatrixBase::external);
- data[5] = 'A';
- v(0, 3) = 'B';
- CPPUNIT_ASSERT_EQUAL(rows, (uint)v.rows());
- CPPUNIT_ASSERT_EQUAL(cols, (uint)v.cols());
- for (unsigned int i = 0; i < v.rows(); i++) {
- for (unsigned int j = 0; j < v.cols(); j++) {
- // row major
- CPPUNIT_ASSERT_EQUAL(data[i*cols+j], v(i, j));
- }
- }
- // row major
- CPPUNIT_ASSERT_EQUAL('A', v(1, 0));
- CPPUNIT_ASSERT_EQUAL('B', data[3]);
- }
- void TestERowMatrix::testAssignment() {
- const char data[] = "fkepw.xja8";
- int size = strlen(data);
- unsigned int rows = size / 5;
- unsigned int cols = 5;
- RowMatrixT<char> a(data, rows, cols);
- std::auto_ptr<const RowMatrixT<char> >
- b(RowMatrixT<char>::createConst(data, rows, cols));
- RowMatrixT<char> t(a);
- RowMatrixT<char> u;
- u = a;
- RowMatrixT<char> v = a;
- RowMatrixT<char> w(*b);
- RowMatrixT<char> x;
- x = *b;
- RowMatrixT<char> y = *b;
- for (unsigned int i = 0; i < v.rows(); i++) {
- for (unsigned int j = 0; j < v.cols(); j++) {
- // row major
- CPPUNIT_ASSERT_EQUAL(data[i*cols+j], t(i, j));
- CPPUNIT_ASSERT_EQUAL(data[i*cols+j], u(i, j));
- CPPUNIT_ASSERT_EQUAL(data[i*cols+j], v(i, j));
- CPPUNIT_ASSERT_EQUAL(data[i*cols+j], w(i, j));
- CPPUNIT_ASSERT_EQUAL(data[i*cols+j], x(i, j));
- CPPUNIT_ASSERT_EQUAL(data[i*cols+j], y(i, j));
- }
- }
- u = 'o';
- for (unsigned int i = 0; i < v.rows(); i++) {
- for (unsigned int j = 0; j < v.cols(); j++) {
- CPPUNIT_ASSERT_EQUAL('o', u(i, j));
- }
- }
- RowMatrixT<int> ev[3];
- ev[0]=RowMatrixT<int>(2, 2);
- ev[1]=RowMatrixT<int>(3, 3);
- ev[2]=RowMatrixT<int>(4, 4);
- RowMatrixT<RowMatrixT<int> > eev(ev,3,1);
- RowMatrixT<RowMatrixT<int> > copy_eev = eev;
- for (unsigned int i = 0; i < eev.rows(); i++) {
- for (unsigned int j = 0; j < eev.cols(); j++) {
- CPPUNIT_ASSERT_EQUAL(eev(i, j), copy_eev(i, j));
- }
- }
- }
- void TestERowMatrix::testArithmetics() {
- RowMatrixT<float> v(2, 10);
- for (unsigned int i = 0; i < v.rows(); i++) {
- for (unsigned int j = 0; j < v.cols(); j++) {
- v(i, j) = 100.0 - float(i+j);
- }
- }
- RowMatrixT<float> w(v);
- w *= 3.0;
- w -= v;
- for (unsigned int i = 0; i < v.rows(); i++) {
- for (unsigned int j = 0; j < v.cols(); j++) {
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(2.0f * v(i, j), w(i, j), 1E-20);
- }
- }
- RowMatrixT<float> a(3, 1);
- RowMatrixT<float> b(3, 1);
- RowMatrixT<float> c(3, 1);
- for (unsigned int i = 0; i < a.rows(); i++) {
- a(i, 0) = float(i);
- b(i, 0) = float(i + 1);
- c(i, 0) = float(i + 2);
- }
- RowMatrixT<float> m(3, 1);
- m = 0.0f;
- m += a;
- m += b;
- m += c;
- m /= 3.0f;
- for (unsigned int i = 0; i < m.rows(); i++) {
- CPPUNIT_ASSERT_EQUAL(float(i + 1), m(i, 0));
- }
- }
- void TestERowMatrix::testRangeChecks() {
- CheckedRowMatrixT<double> v(10, 10, 4.5);
- CPPUNIT_ASSERT_EQUAL(4.5, v(0, 0));
- CPPUNIT_ASSERT_EQUAL(4.5, v(9, 9));
- CPPUNIT_ASSERT_THROW(v(-1, 0), std::out_of_range);
- CPPUNIT_ASSERT_THROW(v(0, -1), std::out_of_range);
- CPPUNIT_ASSERT_THROW(v(10, 0), std::out_of_range);
- CPPUNIT_ASSERT_THROW(v(0, 10), std::out_of_range);
- v(9, 9) = 5.1;
- CheckedRowMatrixT<double> w(v.getDataPointer(), v.rows(), v.cols());
- CPPUNIT_ASSERT_EQUAL(4.5, w(0, 0));
- CPPUNIT_ASSERT_EQUAL(5.1, w(9, 9));
- CPPUNIT_ASSERT_THROW(w(-1, 0), std::out_of_range);
- CPPUNIT_ASSERT_THROW(w(0, -1), std::out_of_range);
- CPPUNIT_ASSERT_THROW(w(10, 0), std::out_of_range);
- CPPUNIT_ASSERT_THROW(w(0, 10), std::out_of_range);
- }
- void TestERowMatrix::testEqual() {
- RowMatrixT<double> v(10, 10, 4.5);
- RowMatrixT<double> w(10, 10, 4.5);
- RowMatrixT<double> x(10, 10, 4.5);
- RowMatrixT<double> y(9, 10, 4.5);
- RowMatrixT<double> z;
- x(9,9)=4.7;
- CPPUNIT_ASSERT(z==z);
- CPPUNIT_ASSERT(!(z!=z));
- CPPUNIT_ASSERT(v==w);
- CPPUNIT_ASSERT(!(v!=w));
- CPPUNIT_ASSERT(v!=x);
- CPPUNIT_ASSERT(!(v==x));
- CPPUNIT_ASSERT_THROW(x==y, std::invalid_argument);
- CPPUNIT_ASSERT_THROW(x!=y, std::invalid_argument);
- }
- void TestERowMatrix::testTranspose() {
- {
- const float data[] = {13.0f,15.0f,17.0f,18.0f,1.0f,2.0f,3.0f,4.0f,5.0f};
- unsigned int rows = 3;
- unsigned int cols = 3;
- RowMatrixT<float> a(data, rows, cols);
- RowMatrixT<float> b(data, rows, cols);
- a.transposeInplace();
- for (unsigned int i = 0; i < a.rows(); i++) {
- for (unsigned int j = 0; j < a.cols(); j++) {
- CPPUNIT_ASSERT_EQUAL(a(i, j), b(j, i));
- }
- }
- RowMatrixT<float> c = a.transpose();
- CPPUNIT_ASSERT_EQUAL(a.rows(), c.cols());
- CPPUNIT_ASSERT_EQUAL(a.cols(), c.rows());
- for (unsigned int i = 0; i < a.rows(); i++) {
- for (unsigned int j = 0; j < a.cols(); j++) {
- CPPUNIT_ASSERT_EQUAL(a(i, j), c(j, i));
- }
- }
- //std::stringstream inout; inout << c << "!=" << a.transpose();
- //CPPUNIT_COND_STREAM(!(a==c), inout.str());
- RowMatrixT<float> d(data, 2, 3);
- RowMatrixT<float> e = d.transpose();
- CPPUNIT_ASSERT_EQUAL(d.rows(), e.cols());
- CPPUNIT_ASSERT_EQUAL(d.cols(), e.rows());
- for (unsigned int i = 0; i < d.rows(); i++) {
- for (unsigned int j = 0; j < d.cols(); j++) {
- CPPUNIT_ASSERT_EQUAL(d(i, j), e(j, i));
- }
- }
- }
- {
- const char data[] = "fkepw.xja";
- unsigned int rows = 3;
- unsigned int cols = 3;
- RowMatrixT<char> a(data, rows, cols);
- RowMatrixT<char> b(data, rows, cols);
- a.transposeInplace();
- for (unsigned int i = 0; i < a.rows(); i++) {
- for (unsigned int j = 0; j < a.cols(); j++) {
- CPPUNIT_ASSERT_EQUAL(a(i, j), b(j, i));
- }
- }
- RowMatrixT<char> c = a.transpose();
- CPPUNIT_ASSERT_EQUAL(a.rows(), c.cols());
- CPPUNIT_ASSERT_EQUAL(a.cols(), c.rows());
- for (unsigned int i = 0; i < a.rows(); i++) {
- for (unsigned int j = 0; j < a.cols(); j++) {
- CPPUNIT_ASSERT_EQUAL(a(i, j), c(j, i));
- }
- }
- //std::stringstream inout; inout << c << "!=" << a.transpose();
- //CPPUNIT_COND_STREAM(!(a==c), inout.str());
- RowMatrixT<char> d(data, 2, 3);
- RowMatrixT<char> e = d.transpose();
- CPPUNIT_ASSERT_EQUAL(d.rows(), e.cols());
- CPPUNIT_ASSERT_EQUAL(d.cols(), e.rows());
- for (unsigned int i = 0; i < d.rows(); i++) {
- for (unsigned int j = 0; j < d.cols(); j++) {
- CPPUNIT_ASSERT_EQUAL(d(i, j), e(j, i));
- }
- }
- }
- }
- void TestERowMatrix::testMultiply() {
- RowMatrixT<double> a(2,3);
- RowMatrixT<double> b(3,2);
- RowMatrixT<double> d(3,1);
- for (unsigned int i = 0; i < a.rows(); i++) {
- for (unsigned int j = 0; j < a.cols(); j++) {
- a(i, j) = i+j;
- }
- }
- for (unsigned int i = 0; i < b.rows(); i++) {
- for (unsigned int j = 0; j < b.cols(); j++) {
- b(i, j) = (int)i - (int)j;
- }
- }
- {
- RowMatrixT<double> m;
- CPPUNIT_ASSERT_THROW(m.multiply(d, a), Exception);
- }
- {
- RowMatrixT<double> m;
- CPPUNIT_ASSERT_THROW(m.multiply(a, d, true), Exception);
- }
- {
- RowMatrixT<double> m;
- CPPUNIT_ASSERT_THROW(m.multiply(b, d), Exception);
- }
- {
- RowMatrixT<double> m;
- CPPUNIT_ASSERT_THROW(m.multiply(d, b), Exception);
- }
- {
- RowMatrixT<double> m(2,1);
- CPPUNIT_ASSERT_NO_THROW(m.multiply(a, d));
- }
- {
- RowMatrixT<double> m(1,2);
- CPPUNIT_ASSERT_NO_THROW(m.multiply(d, a, true, true));
- }
- {
- RowMatrixT<double> m(1,2);
- CPPUNIT_ASSERT_NO_THROW(m.multiply(d, b, true, false));
- }
- {
- RowMatrixT<double> m(2,2);
- CPPUNIT_ASSERT_NO_THROW(m.multiply(a, a, false, true));
- }
- RowMatrixT<double> m;
- m.multiply(a, b);
- CPPUNIT_ASSERT_EQUAL(2u, (uint)m.cols());
- CPPUNIT_ASSERT_EQUAL(2u, (uint)m.rows());
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(5.0, m(0, 0), 1E-20);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(2.0, m(0, 1), 1E-20);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(8.0, m(1, 0), 1E-20);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(2.0, m(1, 1), 1E-20);
- float array[]= {0.8385,0.6946,0.1730,0.1365,0.2844,0.5155
- ,0.5681,0.6213,0.9797,0.0118,0.4692,0.3340
- ,0.3704,0.7948,0.2714,0.8939,0.0648,0.4329
- ,0.7027,0.9568,0.2523,0.1991,0.9883,0.2259
- ,0.5466,0.5226,0.8757,0.2987,0.5828,0.5798
- ,0.4449,0.8801,0.7373,0.6614,0.4235,0.7604};
- RowMatrixT<float> c(array,6,6);
- c.transposeInplace();
- {
- RowMatrixT<float> m;
- m.multiply(c, c);
- double checksum=0;
- for(int i=0;i<6;i++)
- for(int j=0;j<6;j++) {
- checksum += m(i,j);
- checksum*=3.0;
- }
- std::stringstream inout; inout << checksum << endl << c << "*" << c << "=" << m;
- CPPUNIT_COND_STREAM(abs(checksum-3.72091e+17)/3.72091e+17<1e-6, inout.str());
- }
- {
- RowMatrixT<float> m;
- m.multiply(c, c, false, true);
- double checksum=0;
- for(int i=0;i<6;i++)
- for(int j=0;j<6;j++) {
- checksum += m(i,j);
- checksum*=3.0;
- }
- std::stringstream inout; inout << checksum << endl << c << "*" << c.transpose() << "=" << m;
- CPPUNIT_COND_STREAM(abs(checksum-4.92936e+17)/4.92936e+17<1e-6, inout.str());
- }
- {
- RowMatrixT<float> m;
- m.multiply(c, c, true, true);
- double checksum=0;
- for(int i=0;i<6;i++)
- for(int j=0;j<6;j++) {
- checksum += m(i,j);
- checksum*=3.0;
- }
- std::stringstream inout; inout << checksum << endl << c.transpose() << "*" << c.transpose() << "=" << m;
- CPPUNIT_COND_STREAM(abs(checksum-3.7386e+17)/3.7386e+17<1e-6, inout.str());
- }
- {
- RowMatrixT<float> m;
- m.multiply(c, c, true, false);
- double checksum=0;
- for(int i=0;i<6;i++)
- for(int j=0;j<6;j++) {
- checksum += m(i,j);
- checksum*=3.0;
- }
- std::stringstream inout; inout << checksum << endl << c.transpose() << "*" << c << " =" << m;
- CPPUNIT_COND_STREAM(abs(checksum-3.4161e+17)/3.4161e+17<1e-6, inout.str());
- }
- }
- void TestERowMatrix::testDet() {
- #ifdef NICE_USELIB_IPP
- RowMatrixT<float> a(20,20);
- a.setIdentity();
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(1.0,det(a), 1E-6);
- RowMatrixT<float> b(20,20,0.0);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0,det(b), 1E-6);
- float array[]= {0.8385,0.6946,0.1730,0.1365,0.2844,0.5155
- ,0.5681,0.6213,0.9797,0.0118,0.4692,0.3340
- ,0.3704,0.7948,0.2714,0.8939,0.0648,0.4329
- ,0.7027,0.9568,0.2523,0.1991,0.9883,0.2259
- ,0.5466,0.5226,0.8757,0.2987,0.5828,0.5798
- ,0.4449,0.8801,0.7373,0.6614,0.4235,0.7604};
- RowMatrixT<float> c(array,6,6);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0498667,det(c), 1E-6);
- #endif
- }
- void TestERowMatrix::testEigenValues() {
- VectorT<float> buffer(3);
- RowMatrixT<float> b(3,3,0.0f);
- float data[][3]= {{1.00861, 2.17143, 2.90536},
- {9.01223, 2.17129, 1.90898},
- {8.01585, 2.17114, 9.9126},
- {7.01947, 2.171, 8.91622},
- {6.02309, 2.17086, 7.91984},
- {5.02671, 2.17071, 6.92346},
- {4.03033, 2.17057, 5.92708},
- {3.03396, 2.17042, 4.93071},
- {2.03758, 2.17028, 3.93433},
- {1.0412, 2.17013, 2.93795}};
- for(int i=0;i<10;i++) {
- //buffer = VectorT<float>::UniformRandom(3,1.0,10.0,i);
- buffer = VectorT<float>(data[i], 3, VectorBase::external);
- //std::cerr << buffer << std::endl;
- RowMatrixT<float> x(buffer.getDataPointer(),3,1,MatrixBase::external);
- RowMatrixT<float> a(3,3);
- a.multiply(x,x,false,true);
- b+=a;
- }
- RowMatrixT<double> evecs;
- VectorT<double> evals;
- RowMatrixT<double> I;
- #ifdef NICE_USELIB_IPP
- {
- float array[]= {11,4,14,4,-1,10,14,10,8};
- RowMatrixT<float> c(array,3,3);
- eigenvalues(c,&buffer);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0,27-buffer(0), 2E-6);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0,buffer(1), 2E-6);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0,-9-buffer(2), 1E-6);
- }
- {
- eigenvalues(b,&buffer);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(677.0, buffer(0), 5);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(40.07, buffer(1), 3);
- // CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(674.32794189453, buffer(0), 1E-4);
- // CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(37.728626251220, buffer(1), 1E-4);
- double array[]= {292,101,295,104,48,122,295,122,384};
- RowMatrixT<double> c(array,3,3);
- eigenvectorvalues(c,evecs,evals);
- I.multiply(evecs,evecs.transpose());
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, 1.0-det(I), 2E-15);
- }
- #endif
- #ifdef NICE_USELIB_LINAL
- {
- double array[]= {292,101,295,104,48,122,295,122,384};
- RowMatrixT<double> c(array,3,3);
- evals= VectorT<double>(3,0.0);
- evecs= RowMatrixT<double>(3,3,0.0);
- LinAl::MatrixCF<double> lc = c.linal();
- LinAl::VectorCC<double> levals = evals.linalCol();
- LinAl::MatrixCF<double> levecs = evecs.linal();
- eigensym(lc, levals, levecs, 3);
- // CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(674.32794189453, levals(0,0), 1E-4);
- // CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(37.728626251220, levals(1,0), 1E-4);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(677.0, levals(0,0), 5);
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(40.07, levals(1,0), 1.1);
- I.multiply(evecs,evecs.transpose());
- double d = LinAl::det(I.linal());
- CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, 1.0-d, 1E-15);
- }
- #endif
- }
- #endif
|