00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "sparse.h"
00014 #include <Eigen/SparseExtra>
00015 #include <Eigen/KroneckerProduct>
00016
00017
00018 template<typename MatrixType>
00019 void check_dimension(const MatrixType& ab, const int rows, const int cols)
00020 {
00021 VERIFY_IS_EQUAL(ab.rows(), rows);
00022 VERIFY_IS_EQUAL(ab.cols(), cols);
00023 }
00024
00025
00026 template<typename MatrixType>
00027 void check_kronecker_product(const MatrixType& ab)
00028 {
00029 VERIFY_IS_EQUAL(ab.rows(), 6);
00030 VERIFY_IS_EQUAL(ab.cols(), 6);
00031 VERIFY_IS_EQUAL(ab.nonZeros(), 36);
00032 VERIFY_IS_APPROX(ab.coeff(0,0), -0.4017367630386106);
00033 VERIFY_IS_APPROX(ab.coeff(0,1), 0.1056863433932735);
00034 VERIFY_IS_APPROX(ab.coeff(0,2), -0.7255206194554212);
00035 VERIFY_IS_APPROX(ab.coeff(0,3), 0.1908653336744706);
00036 VERIFY_IS_APPROX(ab.coeff(0,4), 0.350864567234111);
00037 VERIFY_IS_APPROX(ab.coeff(0,5), -0.0923032108308013);
00038 VERIFY_IS_APPROX(ab.coeff(1,0), 0.415417514804677);
00039 VERIFY_IS_APPROX(ab.coeff(1,1), -0.2369227701722048);
00040 VERIFY_IS_APPROX(ab.coeff(1,2), 0.7502275131458511);
00041 VERIFY_IS_APPROX(ab.coeff(1,3), -0.4278731019742696);
00042 VERIFY_IS_APPROX(ab.coeff(1,4), -0.3628129162264507);
00043 VERIFY_IS_APPROX(ab.coeff(1,5), 0.2069210808481275);
00044 VERIFY_IS_APPROX(ab.coeff(2,0), 0.05465890160863986);
00045 VERIFY_IS_APPROX(ab.coeff(2,1), -0.2634092511419858);
00046 VERIFY_IS_APPROX(ab.coeff(2,2), 0.09871180285793758);
00047 VERIFY_IS_APPROX(ab.coeff(2,3), -0.4757066334017702);
00048 VERIFY_IS_APPROX(ab.coeff(2,4), -0.04773740823058334);
00049 VERIFY_IS_APPROX(ab.coeff(2,5), 0.2300535609645254);
00050 VERIFY_IS_APPROX(ab.coeff(3,0), -0.8172945853260133);
00051 VERIFY_IS_APPROX(ab.coeff(3,1), 0.2150086428359221);
00052 VERIFY_IS_APPROX(ab.coeff(3,2), 0.5825113847292743);
00053 VERIFY_IS_APPROX(ab.coeff(3,3), -0.1532433770097174);
00054 VERIFY_IS_APPROX(ab.coeff(3,4), -0.329383387282399);
00055 VERIFY_IS_APPROX(ab.coeff(3,5), 0.08665207912033064);
00056 VERIFY_IS_APPROX(ab.coeff(4,0), 0.8451267514863225);
00057 VERIFY_IS_APPROX(ab.coeff(4,1), -0.481996458918977);
00058 VERIFY_IS_APPROX(ab.coeff(4,2), -0.6023482390791535);
00059 VERIFY_IS_APPROX(ab.coeff(4,3), 0.3435339347164565);
00060 VERIFY_IS_APPROX(ab.coeff(4,4), 0.3406002157428891);
00061 VERIFY_IS_APPROX(ab.coeff(4,5), -0.1942526344200915);
00062 VERIFY_IS_APPROX(ab.coeff(5,0), 0.1111982482925399);
00063 VERIFY_IS_APPROX(ab.coeff(5,1), -0.5358806424754169);
00064 VERIFY_IS_APPROX(ab.coeff(5,2), -0.07925446559335647);
00065 VERIFY_IS_APPROX(ab.coeff(5,3), 0.3819388757769038);
00066 VERIFY_IS_APPROX(ab.coeff(5,4), 0.04481475387219876);
00067 VERIFY_IS_APPROX(ab.coeff(5,5), -0.2159688616158057);
00068 }
00069
00070
00071 template<typename MatrixType>
00072 void check_sparse_kronecker_product(const MatrixType& ab)
00073 {
00074 VERIFY_IS_EQUAL(ab.rows(), 12);
00075 VERIFY_IS_EQUAL(ab.cols(), 10);
00076 VERIFY_IS_EQUAL(ab.nonZeros(), 3*2);
00077 VERIFY_IS_APPROX(ab.coeff(3,0), -0.04);
00078 VERIFY_IS_APPROX(ab.coeff(5,1), 0.05);
00079 VERIFY_IS_APPROX(ab.coeff(0,6), -0.08);
00080 VERIFY_IS_APPROX(ab.coeff(2,7), 0.10);
00081 VERIFY_IS_APPROX(ab.coeff(6,8), 0.12);
00082 VERIFY_IS_APPROX(ab.coeff(8,9), -0.15);
00083 }
00084
00085
00086 void test_kronecker_product()
00087 {
00088
00089
00090 Matrix<double, 2, 3> DM_a;
00091 SparseMatrix<double> SM_a(2,3);
00092 SM_a.insert(0,0) = DM_a.coeffRef(0,0) = -0.4461540300782201;
00093 SM_a.insert(0,1) = DM_a.coeffRef(0,1) = -0.8057364375283049;
00094 SM_a.insert(0,2) = DM_a.coeffRef(0,2) = 0.3896572459516341;
00095 SM_a.insert(1,0) = DM_a.coeffRef(1,0) = -0.9076572187376921;
00096 SM_a.insert(1,1) = DM_a.coeffRef(1,1) = 0.6469156566545853;
00097 SM_a.insert(1,2) = DM_a.coeffRef(1,2) = -0.3658010398782789;
00098
00099 MatrixXd DM_b(3,2);
00100 SparseMatrix<double> SM_b(3,2);
00101 SM_b.insert(0,0) = DM_b.coeffRef(0,0) = 0.9004440976767099;
00102 SM_b.insert(0,1) = DM_b.coeffRef(0,1) = -0.2368830858139832;
00103 SM_b.insert(1,0) = DM_b.coeffRef(1,0) = -0.9311078389941825;
00104 SM_b.insert(1,1) = DM_b.coeffRef(1,1) = 0.5310335762980047;
00105 SM_b.insert(2,0) = DM_b.coeffRef(2,0) = -0.1225112806872035;
00106 SM_b.insert(2,1) = DM_b.coeffRef(2,1) = 0.5903998022741264;
00107
00108 SparseMatrix<double,RowMajor> SM_row_a(SM_a), SM_row_b(SM_b);
00109
00110
00111 Matrix<double, 6, 6> DM_fix_ab = kroneckerProduct(DM_a.topLeftCorner<2,3>(),DM_b);
00112
00113 CALL_SUBTEST(check_kronecker_product(DM_fix_ab));
00114
00115 for(int i=0;i<DM_fix_ab.rows();++i)
00116 for(int j=0;j<DM_fix_ab.cols();++j)
00117 VERIFY_IS_APPROX(kroneckerProduct(DM_a,DM_b).coeff(i,j), DM_fix_ab(i,j));
00118
00119
00120 MatrixXd DM_block_ab(10,15);
00121 DM_block_ab.block<6,6>(2,5) = kroneckerProduct(DM_a,DM_b);
00122 CALL_SUBTEST(check_kronecker_product(DM_block_ab.block<6,6>(2,5)));
00123
00124
00125 MatrixXd DM_ab = kroneckerProduct(DM_a,DM_b);
00126 CALL_SUBTEST(check_kronecker_product(DM_ab));
00127
00128
00129 SparseMatrix<double> SM_ab = kroneckerProduct(SM_a,DM_b);
00130 CALL_SUBTEST(check_kronecker_product(SM_ab));
00131 SparseMatrix<double,RowMajor> SM_ab2 = kroneckerProduct(SM_a,DM_b);
00132 CALL_SUBTEST(check_kronecker_product(SM_ab2));
00133
00134
00135 SM_ab.setZero();
00136 SM_ab.insert(0,0)=37.0;
00137 SM_ab = kroneckerProduct(DM_a,SM_b);
00138 CALL_SUBTEST(check_kronecker_product(SM_ab));
00139 SM_ab2.setZero();
00140 SM_ab2.insert(0,0)=37.0;
00141 SM_ab2 = kroneckerProduct(DM_a,SM_b);
00142 CALL_SUBTEST(check_kronecker_product(SM_ab2));
00143
00144
00145 SM_ab.resize(2,33);
00146 SM_ab.insert(0,0)=37.0;
00147 SM_ab = kroneckerProduct(SM_a,SM_b);
00148 CALL_SUBTEST(check_kronecker_product(SM_ab));
00149 SM_ab2.resize(5,11);
00150 SM_ab2.insert(0,0)=37.0;
00151 SM_ab2 = kroneckerProduct(SM_a,SM_b);
00152 CALL_SUBTEST(check_kronecker_product(SM_ab2));
00153
00154
00155 SM_a.resize(4,5);
00156 SM_b.resize(3,2);
00157 SM_a.resizeNonZeros(0);
00158 SM_b.resizeNonZeros(0);
00159 SM_a.insert(1,0) = -0.1;
00160 SM_a.insert(0,3) = -0.2;
00161 SM_a.insert(2,4) = 0.3;
00162 SM_a.finalize();
00163
00164 SM_b.insert(0,0) = 0.4;
00165 SM_b.insert(2,1) = -0.5;
00166 SM_b.finalize();
00167 SM_ab.resize(1,1);
00168 SM_ab.insert(0,0)=37.0;
00169 SM_ab = kroneckerProduct(SM_a,SM_b);
00170 CALL_SUBTEST(check_sparse_kronecker_product(SM_ab));
00171
00172
00173 MatrixXd DM_a2(2,1);
00174 MatrixXd DM_b2(5,4);
00175 MatrixXd DM_ab2 = kroneckerProduct(DM_a2,DM_b2);
00176 CALL_SUBTEST(check_dimension(DM_ab2,2*5,1*4));
00177 DM_a2.resize(10,9);
00178 DM_b2.resize(4,8);
00179 DM_ab2 = kroneckerProduct(DM_a2,DM_b2);
00180 CALL_SUBTEST(check_dimension(DM_ab2,10*4,9*8));
00181 }