diff --git a/cpp/Matrix.cpp b/cpp/Matrix.cpp index 114ddd3e2..fa6d6dbe7 100644 --- a/cpp/Matrix.cpp +++ b/cpp/Matrix.cpp @@ -494,24 +494,26 @@ Matrix stack(size_t nrMatrices, ...) } /* ************************************************************************* */ -Matrix collect(vector matrices) +Matrix collect(const std::vector& matrices, size_t m, size_t n) { - int dimA1 = 0; - int dimA2 = 0; - BOOST_FOREACH(const Matrix* M, matrices) { - dimA1 = M->size1(); // TODO: should check if all the same ! - dimA2 += M->size2(); - } - Matrix A(dimA1, dimA2); - int hindex = 0; - BOOST_FOREACH(const Matrix* M, matrices) { - for(size_t d1 = 0; d1 < M->size1(); d1++) - for(size_t d2 = 0; d2 < M->size2(); d2++) - A(d1, d2+hindex) = (*M)(d1, d2); - hindex += M->size2(); - } + // if we have known and constant dimensions, use them + size_t dimA1 = m; + size_t dimA2 = n*matrices.size(); + if (!m && !n) + BOOST_FOREACH(const Matrix* M, matrices) { + dimA1 = M->size1(); // TODO: should check if all the same ! + dimA2 += M->size2(); + } + Matrix A(dimA1, dimA2); + size_t hindex = 0; + BOOST_FOREACH(const Matrix* M, matrices) { + for(size_t d1 = 0; d1 < M->size1(); d1++) + for(size_t d2 = 0; d2 < M->size2(); d2++) + A(d1, d2+hindex) = (*M)(d1, d2); + hindex += M->size2(); + } - return A; + return A; } /* ************************************************************************* */ diff --git a/cpp/Matrix.h b/cpp/Matrix.h index dcded7637..723523013 100644 --- a/cpp/Matrix.h +++ b/cpp/Matrix.h @@ -252,9 +252,14 @@ Matrix stack(size_t nrMatrices, ...); /** * create a matrix by concatenating * Given a set of matrices: A1, A2, A3... + * If all matrices have the same size, specifying single matrix dimensions + * will avoid the lookup of dimensions + * @param matrices is a vector of matrices in the order to be collected + * @param m is the number of rows of a single matrix + * @param n is the number of columns of a single matrix * @return combined matrix [A1 A2 A3] */ -Matrix collect(std::vector matrices); +Matrix collect(const std::vector& matrices, size_t m = 0, size_t n = 0); Matrix collect(size_t nrMatrices, ...); /** diff --git a/cpp/testMatrix.cpp b/cpp/testMatrix.cpp index f75bf80c7..0b26f75d4 100644 --- a/cpp/testMatrix.cpp +++ b/cpp/testMatrix.cpp @@ -72,23 +72,61 @@ TEST( matrix, row_major ) } /* ************************************************************************* */ -TEST( matrix, collect ) +TEST( matrix, collect1 ) { - Matrix A = Matrix_(2,2, - -5.0 , 3.0, - 00.0, -5.0 ); - Matrix B = Matrix_(2,3, - -0.5 , 2.1, 1.1, - 3.4 , 2.6 , 7.1); - Matrix AB = collect(2, &A, &B); - Matrix C(2,5); - for(int i = 0; i < 2; i++) for(int j = 0; j < 2; j++) C(i,j) = A(i,j); - for(int i = 0; i < 2; i++) for(int j = 0; j < 3; j++) C(i,j+2) = B(i,j); + Matrix A = Matrix_(2,2, + -5.0 , 3.0, + 00.0, -5.0 ); + Matrix B = Matrix_(2,3, + -0.5 , 2.1, 1.1, + 3.4 , 2.6 , 7.1); + Matrix AB = collect(2, &A, &B); + Matrix C(2,5); + for(int i = 0; i < 2; i++) for(int j = 0; j < 2; j++) C(i,j) = A(i,j); + for(int i = 0; i < 2; i++) for(int j = 0; j < 3; j++) C(i,j+2) = B(i,j); - EQUALITY(C,AB); + EQUALITY(C,AB); } +/* ************************************************************************* */ +TEST( matrix, collect2 ) +{ + Matrix A = Matrix_(2,2, + -5.0 , 3.0, + 00.0, -5.0 ); + Matrix B = Matrix_(2,3, + -0.5 , 2.1, 1.1, + 3.4 , 2.6 , 7.1); + vector matrices; + matrices.push_back(&A); + matrices.push_back(&B); + Matrix AB = collect(matrices); + Matrix C(2,5); + for(int i = 0; i < 2; i++) for(int j = 0; j < 2; j++) C(i,j) = A(i,j); + for(int i = 0; i < 2; i++) for(int j = 0; j < 3; j++) C(i,j+2) = B(i,j); + + EQUALITY(C,AB); + +} + +/* ************************************************************************* */ +TEST( matrix, collect3 ) +{ + Matrix A, B; + A = eye(2,3); + B = eye(2,3); + vector matrices; + matrices.push_back(&A); + matrices.push_back(&B); + Matrix AB = collect(matrices, 2, 3); + Matrix exp = Matrix_(2, 6, + 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, 1.0, 0.0); + + EQUALITY(exp,AB); +} + /* ************************************************************************* */ TEST( matrix, stack ) { diff --git a/cpp/timeMatrix.cpp b/cpp/timeMatrix.cpp index 201d465a8..3ba3281d2 100644 --- a/cpp/timeMatrix.cpp +++ b/cpp/timeMatrix.cpp @@ -5,20 +5,24 @@ */ #include -#include +#include #include "Matrix.h" using namespace std; using namespace gtsam; -int main(int argc, char ** argv) { - cout << "Starting Matrix::collect() Timing" << endl; - +/* + * Results: + * Alex's Machine: + * - no pass: 0.1818 sec + * - pass : 0.1802 sec + */ +double timeCollect(size_t p, size_t m, size_t n, bool passDims, size_t reps) { // create a large number of matrices - size_t n, m, p; - p = 100000; // number of matrices - n = 10; // rows per matrix - m = 12; // columns per matrix + // p = number of matrices + // m = rows per matrix + // n = columns per matrix + // reps = number of repetitions // fill the matrices with identities vector matrices; @@ -30,15 +34,37 @@ int main(int argc, char ** argv) { // start timing Matrix result; + double elapsed; { - boost::progress_timer t; - result = collect(matrices); - } + boost::timer t; + if (passDims) + for (int i=0; i