Go to the documentation of this file.00001
00002 #include "mbl_matxvec.h"
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <vnl/vnl_vector.h>
00021 #include <vnl/vnl_matrix.h>
00022 #include <vcl_cassert.h>
00023 #include <vcl_cstdlib.h>
00024 #include <vcl_iostream.h>
00025
00026
00027
00028
00029
00030
00031
00032
00033 #if 0 // long part commented out
00034
00035 static bool HasNaN(const char* s,
00036 const vnl_matrix<double>& M)
00037 {
00038 for (int i=1;i<=M.nrows();++i)
00039 for (int j=1;j<=M.ncols();++j)
00040 {
00041 if (isnan(M(i,j)))
00042 {
00043 vcl_cout<<s<<" has NaN at element "<<i<<','<<j
00044 <<" in a "<<M.nrows()<<" x "<<M.ncols()<<" matrix.\n";
00045 return true;
00046 }
00047 }
00048 return false;
00049 }
00050
00051
00052
00053
00054 void NC_VecXMat(const vnl_vector<double>& V,
00055 const vnl_matrix<double>& M,
00056 vnl_matrix<double>& R)
00057 {
00058 int nrows = V.size();
00059 int ncols = M.ncols();
00060 if (M.nrows()>1)
00061 {
00062 vcl_cerr << "NC_VecXMat : M is a "<<M.nrows()<<"-row matrix.\n"
00063 << "it may only be 1-row.\n";
00064 vcl_abort();
00065 }
00066
00067 R.set_size(nrows,ncols);
00068
00069 const double* v_data = V.dataPtr();
00070 const double** M_data = M.dataPtr();
00071 double** R_data = R.dataPtr();
00072
00073 for (int i=1;i<=nrows;i++)
00074 {
00075 const double *m_data = M_data[i];
00076 double *r_data = R_data[i];
00077 double vval = v_data[i];
00078 for (int j=1;j<=ncols;j++)
00079 {
00080 r_data[j] = vval * m_data[j];
00081 }
00082 }
00083
00084 for (int i=1;i<=nrows;i++)
00085 for (int j=1;j<=ncols;j++)
00086 R(i,j) = V(i) * M(1,j);
00087 }
00088 #endif //0 - long part commented out
00089
00090
00091
00092
00093
00094
00095 void mbl_matxvec_prod_mv(const vnl_matrix<double>& M,
00096 const vnl_vector<double>& V,
00097 vnl_vector<double>& R)
00098 {
00099 int nr = M.rows();
00100
00101 R.set_size(nr);
00102
00103 mbl_matxvec_prod_mv_2(M,V,R);
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113 void mbl_matxvec_prod_mv_2(const vnl_matrix<double>& M,
00114 const vnl_vector<double>& V,
00115 vnl_vector<double>& R)
00116 {
00117 if (R.size()==0) return;
00118
00119
00120 int nR = R.size();
00121 #ifndef NDEBUG
00122 int nc = M.cols();
00123 int nr = M.rows();
00124 if (nR>nr)
00125 {
00126 vcl_cerr<<"ERROR: mbl_matxvec_prod_mv_2() R too long.\n";
00127 vcl_abort();
00128 }
00129 #endif
00130
00131 double *Rdata = R.data_block();
00132
00133 int t = V.size();
00134 #ifndef NDEBUG
00135 if (t>nc)
00136 {
00137 vcl_cerr<<"ERROR: mbl_matxvec_prod_mv_2() V too long. V has "<<t<<" elements. M has "<<nc<<" columns.\n";
00138 vcl_abort();
00139 }
00140 #endif
00141
00142 if (t==0)
00143 {
00144 int r = nR;
00145 while (r--) Rdata[r]=0.0;
00146 return;
00147 }
00148
00149 #ifndef NDEBUG
00150 if ((nr<1) || (nc<1))
00151 {
00152 vcl_cerr<<"ERROR: mbl_matxvec_prod_mv_2() - vnl_matrix<double> is 0 x 0\n"
00153 <<"V has dimension "<<V.size()<<vcl_endl;
00154 vcl_abort();
00155 }
00156 #endif
00157
00158 const double * const* Mdata = M.data_array();
00159 const double *Mdata2;
00160 const double *Vdata = V.data_block();
00161
00162 int r = nR;
00163 while (r--)
00164 {
00165 double T=0.0;
00166 Mdata2 = Mdata[r];
00167 int c=t;
00168 while (c--)
00169 T+=Mdata2[c] * Vdata[c];
00170
00171 Rdata[r] = T;
00172 }
00173 }
00174
00175
00176
00177
00178
00179 #if 0 // long part commented out
00180
00181 void TC_MatXVec(const vnl_matrix<double>& M,
00182 const vnl_vector<double>& V,
00183 vnl_vector<double>& R,
00184 const vcl_vector<int>& index)
00185
00186 {
00187 int nc = M.ncols();
00188 int nr = M.nrows();
00189 if (index.lo()!=1)
00190 {
00191 vcl_cerr<<"TC_MatXVec(M,V,R,index) : index array must begin at 1\n";
00192 vcl_abort();
00193 }
00194 int n = index.size();
00195
00196
00197 if (R.size()!=n) R.set_size(n);
00198 double *Rdata = R.dataPtr();
00199
00200 int t = V.size();
00201 if (t>nc)
00202 {
00203 vcl_cerr<<"TC_MatXVec() R too long.\n";
00204 vcl_abort();
00205 }
00206
00207 if (t==0)
00208 {
00209 int r = n+1;
00210 while (--r) Rdata[r]=0.0;
00211 return;
00212 }
00213
00214 if ((nr<1) || (nc<1))
00215 {
00216 vcl_cerr<<"TC_MatXVec - vnl_matrix<double> is 0 x 0\n"
00217 <<"V has dimension "<<V.size()<<vcl_endl;
00218 vcl_abort();
00219 }
00220
00221 const double ** Mdata = M.dataPtr();
00222 const double *Mdata2;
00223 const double *Vdata = V.dataPtr();
00224 const int * i_data = index.dataPtr();
00225
00226 int i = n+1;
00227 while (--i)
00228 {
00229 int r = i_data[i];
00230 double T=0.0;
00231 Mdata2 = Mdata[r];
00232 int c=t+1;
00233 while (--c)
00234 T+=Mdata2[c] * Vdata[c];
00235
00236 Rdata[i] = T;
00237 }
00238 }
00239 #endif //0 - long part commented out
00240
00241
00242
00243
00244 void mbl_matxvec_prod_vm(const vnl_vector<double>& V,
00245 const vnl_matrix<double>& M,
00246 vnl_vector<double>& R)
00247 {
00248 R.fill(0.0);
00249 mbl_matxvec_add_prod_vm(V,M,R);
00250 }
00251
00252
00253
00254
00255 void mbl_matxvec_add_prod_vm(const vnl_vector<double>& V,
00256 const vnl_matrix<double>& M,
00257 vnl_vector<double>& R)
00258 {
00259 unsigned int nr = M.rows();
00260
00261 #ifndef NDEBUG
00262 unsigned int nc = M.cols();
00263 if (nr!=V.size())
00264 {
00265 vcl_cerr<<"ERROR: mbl_matxvec_add_prod_vm - V wrong length\n"
00266 <<"Expected "<<nr<<" got "<<V.size()<<vcl_endl;
00267 vcl_abort();
00268 }
00269 #endif //!NDEBUG
00270
00271 unsigned int t = R.size();
00272 if (t==0) return;
00273
00274 #ifndef NDEBUG
00275 assert(t<=nc);
00276 if ((nr<1) || (nc<1))
00277 {
00278 vcl_cerr<<"ERROR: mbl_matxvec_add_prod_vm - vnl_matrix<double> is 0 x 0\n"
00279 <<"V has dimension "<<V.size()<<vcl_endl;
00280 vcl_abort();
00281 }
00282 #endif //!NDEBUG
00283
00284 const double *const * Mdata = M.data_array();
00285 const double * Vdata = V.data_block();
00286 double * Rdata = R.data_block();
00287
00288 int r = nr;
00289 while (r--)
00290 {
00291 double v = Vdata[r];
00292 const double *Mdata2 = Mdata[r];
00293 int c=t;
00294 while (c--)
00295 Rdata[c]+=Mdata2[c] * v;
00296 }
00297 }
00298
00299
00300
00301
00302
00303 #if 0 // long part commented out
00304 void TC_ProductABt(vnl_matrix<double>& ABt,
00305 const vnl_matrix<double>& A,
00306 const vnl_matrix<double>& B)
00307
00308 {
00309 int nr1 = A.nrows();
00310 int nc1 = A.ncols();
00311 int nr2 = B.nrows();
00312 int nc2 = B.ncols();
00313
00314 #ifndef NDEBUG
00315 if ( nc2 != nc1 )
00316 {
00317 vcl_cerr<<"TC_ProductABt : B.ncols != A.ncols\n";
00318 vcl_abort() ;
00319 }
00320 #endif //!NDEBUG
00321
00322 if ( (ABt.nrows()!=nr1) || (ABt.ncols()!= nr2) )
00323 ABt.set_size( nr1, nr2 ) ;
00324
00325 const double ** A_data = A.dataPtr();
00326 const double ** B_data = B.dataPtr();
00327 double ** R_data = ABt.dataPtr();
00328
00329 int r = nr1 + 1;
00330 while (--r)
00331 {
00332 const double* A_row = A_data[r];
00333 double* R_row = R_data[r];
00334 int c = nr2 + 1;
00335 while (--c)
00336 {
00337 const double* B_row = B_data[c];
00338 double sum = 0.0 ;
00339 int i = nc1 + 1;
00340 while (--i) { sum += A_row[i] * B_row[i]; }
00341
00342 R_row[c] = sum ;
00343 }
00344 }
00345 }
00346
00347
00348
00349
00350
00351 void TC_ProductAtB(vnl_matrix<double>& AtB,
00352 const vnl_matrix<double>& A,
00353 const vnl_matrix<double>& B)
00354
00355 {
00356 int nr1 = A.nrows();
00357 int nc1 = A.ncols();
00358 int nr2 = B.nrows();
00359 int nc2 = B.ncols();
00360
00361 if ( nr2 != nr1 )
00362 {
00363 vcl_cerr<<"TC_ProductAtB : B.nrows != A.nrows\n";
00364 vcl_abort() ;
00365 }
00366
00367 if ( (AtB.nrows()!=nc1) || (AtB.ncols()!= nc2) )
00368 AtB.set_size( nc1, nc2 ) ;
00369
00370 const double ** A_data = A.dataPtr();
00371 const double ** B_data = B.dataPtr();
00372 double ** R_data = AtB.dataPtr();
00373
00374
00375 for (int r=1;r<=nc1;r++)
00376 {
00377 double *R_row = R_data[r];
00378 int c=nc2;
00379 while (c) { R_row[c] = 0.0; --c; }
00380 }
00381
00382 for (int r1 = 1; r1<=nr1; r1++)
00383 {
00384 const double* A_row = A_data[r1];
00385 const double* B_row = B_data[r1];
00386 double a;
00387 int c1 = nc1;
00388 while (c1)
00389 {
00390 double *R_row = R_data[c1];
00391 a = A_row[c1];
00392 int c2 = nc2;
00393 while (c2)
00394 {
00395 R_row[c2] +=a*B_row[c2];
00396 c2--;
00397 }
00398 c1--;
00399 }
00400 }
00401 }
00402
00403
00404
00405
00406
00407
00408 void TC_ProductMD(vnl_matrix<double>& MD,
00409 const vnl_matrix<double>& M,
00410 const vnl_vector<double>& d)
00411 {
00412 int nr = M.nrows();
00413 int nc = M.ncols();
00414 if (d.size()!=nc)
00415 {
00416 vcl_cerr<<"TC_ProductMD() d doesnt match M\n"
00417 <<"d is "<<d.size()<<" element vector.\n"
00418 <<"M is "<<nr<<" x "<<nc<<vcl_endl;
00419 vcl_abort();
00420 }
00421
00422 if ((MD.nrows()!=nr) || (MD.ncols()!=nc)) MD.set_size(nr,nc);
00423
00424 double **MD_data = MD.dataPtr();
00425 const double **M_data = M.dataPtr();
00426 const double *d_data = d.dataPtr();
00427
00428 for (int r=1;r<=nr;++r)
00429 {
00430 const double* M_row = M_data[r];
00431 double *MR_row = MD_data[r];
00432 int c=nc;
00433 while (c) { MR_row[c] = M_row[c]*d_data[c]; --c; }
00434 }
00435 }
00436
00437
00438
00439
00440 void TC_ProductDM(vnl_matrix<double>& DM,
00441 const vnl_matrix<double>& M,
00442 const vnl_vector<double>& d)
00443 {
00444 int nr = M.nrows();
00445 int nc = M.ncols();
00446 if (d.size()!=nr)
00447 {
00448 vcl_cerr<<"TC_ProductDM() d doesnt match M\n"
00449 <<"d is "<<d.size()<<" element vector.\n"
00450 <<"M is "<<nr<<" x "<<nc<<vcl_endl;
00451 vcl_abort();
00452 }
00453
00454 if ((DM.nrows()!=nr) || (DM.ncols()!=nc)) DM.set_size(nr,nc);
00455
00456 double **DM_data = DM.dataPtr();
00457 const double **M_data = M.dataPtr();
00458 const double *d_data = d.dataPtr();
00459
00460 for (int r=1;r<=nr;++r)
00461 {
00462 const double* M_row = M_data[r];
00463 double *DM_row = DM_data[r];
00464 double di = d_data[r];
00465 int c=nc;
00466 while (c) { DM_row[c] = di * M_row[c]; --c; }
00467 }
00468 }
00469 #endif //0 - long part commented out