00001
00002 #ifndef vnl_matrix_txx_
00003 #define vnl_matrix_txx_
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 #include "vnl_matrix.h"
00082
00083 #include <vcl_cassert.h>
00084 #include <vcl_cstdio.h>
00085 #include <vcl_cstdlib.h>
00086 #include <vcl_cctype.h>
00087 #include <vcl_iostream.h>
00088 #include <vcl_vector.h>
00089 #include <vcl_algorithm.h>
00090
00091 #include <vnl/vnl_math.h>
00092 #include <vnl/vnl_vector.h>
00093 #include <vnl/vnl_c_vector.h>
00094 #include <vnl/vnl_numeric_traits.h>
00095
00096
00097 #if VCL_HAS_SLICED_DESTRUCTOR_BUG
00098
00099 # define vnl_matrix_construct_hack() vnl_matrix_own_data = 1
00100 #else
00101 # define vnl_matrix_construct_hack()
00102 #endif
00103
00104
00105 #define vnl_matrix_alloc_blah(rowz_, colz_) \
00106 do { \
00107 this->num_rows = (rowz_); \
00108 this->num_cols = (colz_); \
00109 if (this->num_rows && this->num_cols) { \
00110 \
00111 this->data = vnl_c_vector<T>::allocate_Tptr(this->num_rows); \
00112 \
00113 T* elmns = vnl_c_vector<T>::allocate_T(this->num_rows * this->num_cols); \
00114 \
00115 for (unsigned int i = 0; i < this->num_rows; ++ i) \
00116 this->data[i] = elmns + i*this->num_cols; \
00117 } \
00118 else { \
00119 \
00120 (this->data = vnl_c_vector<T>::allocate_Tptr(1))[0] = 0; \
00121 } \
00122 } while (false)
00123
00124
00125 #define vnl_matrix_free_blah \
00126 do { \
00127 if (this->data) { \
00128 if (this->num_cols && this->num_rows) { \
00129 vnl_c_vector<T>::deallocate(this->data[0], this->num_cols * this->num_rows); \
00130 vnl_c_vector<T>::deallocate(this->data, this->num_rows); \
00131 } else { \
00132 vnl_c_vector<T>::deallocate(this->data, 1); \
00133 } \
00134 } \
00135 } while (false)
00136
00137
00138
00139
00140 template<class T>
00141 vnl_matrix<T>::vnl_matrix (unsigned rowz, unsigned colz)
00142 {
00143 vnl_matrix_construct_hack();
00144 vnl_matrix_alloc_blah(rowz, colz);
00145 }
00146
00147
00148
00149 template<class T>
00150 vnl_matrix<T>::vnl_matrix (unsigned rowz, unsigned colz, T const& value)
00151 {
00152 vnl_matrix_construct_hack();
00153 vnl_matrix_alloc_blah(rowz, colz);
00154 for (unsigned int i = 0; i < rowz; ++ i)
00155 for (unsigned int j = 0; j < colz; ++ j)
00156 this->data[i][j] = value;
00157 }
00158
00159
00160 template <class T>
00161 vnl_matrix<T>::vnl_matrix(unsigned r, unsigned c, vnl_matrix_type t)
00162 {
00163 vnl_matrix_construct_hack();
00164 vnl_matrix_alloc_blah(r, c);
00165 switch (t) {
00166 case vnl_matrix_identity:
00167 assert(r == c);
00168 for (unsigned int i = 0; i < r; ++ i)
00169 for (unsigned int j = 0; j < c; ++ j)
00170 this->data[i][j] = (i==j) ? T(1) : T(0);
00171 break;
00172 case vnl_matrix_null:
00173 for (unsigned int i = 0; i < r; ++ i)
00174 for (unsigned int j = 0; j < c; ++ j)
00175 this->data[i][j] = T(0);
00176 break;
00177 default:
00178 assert(false);
00179 break;
00180 }
00181 }
00182
00183 #if 1 // fsm: who uses this?
00184
00185
00186 template<class T>
00187 vnl_matrix<T>::vnl_matrix (unsigned rowz, unsigned colz, unsigned n, T const values[])
00188 {
00189 vnl_matrix_construct_hack();
00190 vnl_matrix_alloc_blah(rowz, colz);
00191 if (n > rowz*colz)
00192 n = rowz*colz;
00193 T *dst = this->data[0];
00194 for (unsigned k=0; k<n; ++k)
00195 dst[k] = values[k];
00196 }
00197 #endif
00198
00199
00200
00201
00202 template<class T>
00203 vnl_matrix<T>::vnl_matrix (T const* datablck, unsigned rowz, unsigned colz)
00204 {
00205 vnl_matrix_construct_hack();
00206 vnl_matrix_alloc_blah(rowz, colz);
00207 unsigned int n = rowz*colz;
00208 T *dst = this->data[0];
00209 for (unsigned int k=0; k<n; ++k)
00210 dst[k] = datablck[k];
00211 }
00212
00213
00214
00215
00216
00217 template<class T>
00218 vnl_matrix<T>::vnl_matrix (vnl_matrix<T> const& from)
00219 {
00220 vnl_matrix_construct_hack();
00221 if (from.data) {
00222 vnl_matrix_alloc_blah(from.num_rows, from.num_cols);
00223 unsigned int n = this->num_rows * this->num_cols;
00224 T *dst = this->data[0];
00225 T const *src = from.data[0];
00226 for (unsigned int k=0; k<n; ++k)
00227 dst[k] = src[k];
00228 }
00229 else {
00230 num_rows = 0;
00231 num_cols = 0;
00232 data = 0;
00233 }
00234 }
00235
00236
00237
00238 template<class T>
00239 vnl_matrix<T>::vnl_matrix (vnl_matrix<T> const &A, vnl_matrix<T> const &B, vnl_tag_add)
00240 {
00241 #ifndef NDEBUG
00242 if (A.num_rows != B.num_rows || A.num_cols != B.num_cols)
00243 vnl_error_matrix_dimension ("vnl_tag_add", A.num_rows, A.num_cols, B.num_rows, B.num_cols);
00244 #endif
00245
00246 vnl_matrix_construct_hack();
00247 vnl_matrix_alloc_blah(A.num_rows, A.num_cols);
00248
00249 unsigned int n = A.num_rows * A.num_cols;
00250 T const *a = A.data[0];
00251 T const *b = B.data[0];
00252 T *dst = this->data[0];
00253
00254 for (unsigned int i=0; i<n; ++i)
00255 dst[i] = T(a[i] + b[i]);
00256 }
00257
00258 template<class T>
00259 vnl_matrix<T>::vnl_matrix (vnl_matrix<T> const &A, vnl_matrix<T> const &B, vnl_tag_sub)
00260 {
00261 #ifndef NDEBUG
00262 if (A.num_rows != B.num_rows || A.num_cols != B.num_cols)
00263 vnl_error_matrix_dimension ("vnl_tag_sub", A.num_rows, A.num_cols, B.num_rows, B.num_cols);
00264 #endif
00265
00266 vnl_matrix_construct_hack();
00267 vnl_matrix_alloc_blah(A.num_rows, A.num_cols);
00268
00269 unsigned int n = A.num_rows * A.num_cols;
00270 T const *a = A.data[0];
00271 T const *b = B.data[0];
00272 T *dst = this->data[0];
00273
00274 for (unsigned int i=0; i<n; ++i)
00275 dst[i] = T(a[i] - b[i]);
00276 }
00277
00278 template<class T>
00279 vnl_matrix<T>::vnl_matrix (vnl_matrix<T> const &M, T s, vnl_tag_mul)
00280 {
00281 vnl_matrix_construct_hack();
00282 vnl_matrix_alloc_blah(M.num_rows, M.num_cols);
00283
00284 unsigned int n = M.num_rows * M.num_cols;
00285 T const *m = M.data[0];
00286 T *dst = this->data[0];
00287
00288 for (unsigned int i=0; i<n; ++i)
00289 dst[i] = T(m[i] * s);
00290 }
00291
00292 template<class T>
00293 vnl_matrix<T>::vnl_matrix (vnl_matrix<T> const &M, T s, vnl_tag_div)
00294 {
00295 vnl_matrix_construct_hack();
00296 vnl_matrix_alloc_blah(M.num_rows, M.num_cols);
00297
00298 unsigned int n = M.num_rows * M.num_cols;
00299 T const *m = M.data[0];
00300 T *dst = this->data[0];
00301
00302 for (unsigned int i=0; i<n; ++i)
00303 dst[i] = T(m[i] / s);
00304 }
00305
00306 template<class T>
00307 vnl_matrix<T>::vnl_matrix (vnl_matrix<T> const &M, T s, vnl_tag_add)
00308 {
00309 vnl_matrix_construct_hack();
00310 vnl_matrix_alloc_blah(M.num_rows, M.num_cols);
00311
00312 unsigned int n = M.num_rows * M.num_cols;
00313 T const *m = M.data[0];
00314 T *dst = this->data[0];
00315
00316 for (unsigned int i=0; i<n; ++i)
00317 dst[i] = T(m[i] + s);
00318 }
00319
00320 template<class T>
00321 vnl_matrix<T>::vnl_matrix (vnl_matrix<T> const &M, T s, vnl_tag_sub)
00322 {
00323 vnl_matrix_construct_hack();
00324 vnl_matrix_alloc_blah(M.num_rows, M.num_cols);
00325
00326 unsigned int n = M.num_rows * M.num_cols;
00327 T const *m = M.data[0];
00328 T *dst = this->data[0];
00329
00330 for (unsigned int i=0; i<n; ++i)
00331 dst[i] = T(m[i] - s);
00332 }
00333
00334 template<class T>
00335 vnl_matrix<T>::vnl_matrix (vnl_matrix<T> const &A, vnl_matrix<T> const &B, vnl_tag_mul)
00336 {
00337 #ifndef NDEBUG
00338 if (A.num_cols != B.num_rows)
00339 vnl_error_matrix_dimension("vnl_tag_mul", A.num_rows, A.num_cols, B.num_rows, B.num_cols);
00340 #endif
00341
00342 unsigned int l = A.num_rows;
00343 unsigned int m = A.num_cols;
00344 unsigned int n = B.num_cols;
00345
00346 vnl_matrix_construct_hack();
00347 vnl_matrix_alloc_blah(l, n);
00348
00349 for (unsigned int i=0; i<l; ++i) {
00350 for (unsigned int k=0; k<n; ++k) {
00351 T sum(0);
00352 for (unsigned int j=0; j<m; ++j)
00353 sum += T(A.data[i][j] * B.data[j][k]);
00354 this->data[i][k] = sum;
00355 }
00356 }
00357 }
00358
00359
00360
00361 template<class T>
00362 vnl_matrix<T>::~vnl_matrix()
00363 {
00364
00365 #if VCL_HAS_SLICED_DESTRUCTOR_BUG
00366 if (data && vnl_matrix_own_data) destroy();
00367 #else
00368 if (data) destroy();
00369 #endif
00370 }
00371
00372
00373
00374
00375 template<class T>
00376 void vnl_matrix<T>::destroy()
00377 {
00378 vnl_matrix_free_blah;
00379 }
00380
00381 template<class T>
00382 void vnl_matrix<T>::clear()
00383 {
00384 if (data) {
00385 destroy();
00386 num_rows = 0;
00387 num_cols = 0;
00388 data = 0;
00389 }
00390 }
00391
00392
00393
00394
00395
00396 template<class T>
00397 bool vnl_matrix<T>::set_size (unsigned rowz, unsigned colz)
00398 {
00399 if (this->data) {
00400
00401 if (this->num_rows == rowz && this->num_cols == colz)
00402 return false;
00403
00404
00405 vnl_matrix_free_blah;
00406 vnl_matrix_alloc_blah(rowz, colz);
00407 }
00408 else {
00409
00410 vnl_matrix_alloc_blah(rowz, colz);
00411 }
00412
00413 return true;
00414 }
00415
00416 #undef vnl_matrix_alloc_blah
00417 #undef vnl_matrix_free_blah
00418
00419
00420
00421
00422
00423 template<class T>
00424 void vnl_matrix<T>::fill (T const& value)
00425 {
00426 for (unsigned int i = 0; i < this->num_rows; i++)
00427 for (unsigned int j = 0; j < this->num_cols; j++)
00428 this->data[i][j] = value;
00429 }
00430
00431
00432
00433 template<class T>
00434 void vnl_matrix<T>::fill_diagonal (T const& value)
00435 {
00436 for (unsigned int i = 0; i < this->num_rows && i < this->num_cols; i++)
00437 this->data[i][i] = value;
00438 }
00439
00440 #if 0
00441
00442
00443 template<class T>
00444 vnl_matrix<T>& vnl_matrix<T>::operator= (T const& value)
00445 {
00446 for (unsigned i = 0; i < this->num_rows; i++)
00447 for (unsigned j = 0; j < this->num_cols; j++)
00448 this->data[i][j] = value;
00449 return *this;
00450 }
00451 #endif // 0
00452
00453
00454
00455
00456
00457 template<class T>
00458 vnl_matrix<T>& vnl_matrix<T>::operator= (vnl_matrix<T> const& rhs)
00459 {
00460 if (this != &rhs) {
00461 if (rhs.data) {
00462 this->set_size(rhs.num_rows, rhs.num_cols);
00463 for (unsigned int i = 0; i < this->num_rows; i++)
00464 for (unsigned int j = 0; j < this->num_cols; j++)
00465 this->data[i][j] = rhs.data[i][j];
00466 }
00467 else {
00468
00469 clear();
00470 }
00471 }
00472 return *this;
00473 }
00474
00475 template<class T>
00476 void vnl_matrix<T>::print(vcl_ostream& os) const
00477 {
00478 for (unsigned int i = 0; i < this->rows(); i++) {
00479 for (unsigned int j = 0; j < this->columns(); j++)
00480 os << this->data[i][j] << ' ';
00481 os << '\n';
00482 }
00483 }
00484
00485
00486
00487
00488 template<class T>
00489 vcl_ostream& operator<< (vcl_ostream& os, vnl_matrix<T> const& m)
00490 {
00491 for (unsigned int i = 0; i < m.rows(); ++i) {
00492 for (unsigned int j = 0; j < m.columns(); ++j)
00493 os << m(i, j) << ' ';
00494 os << '\n';
00495 }
00496 return os;
00497 }
00498
00499
00500
00501 template<class T>
00502 vcl_istream& operator>>(vcl_istream& s, vnl_matrix<T>& M)
00503 {
00504 M.read_ascii(s);
00505 return s;
00506 }
00507
00508 template<class T>
00509 void vnl_matrix<T>::inline_function_tickler()
00510 {
00511 vnl_matrix<T> M;
00512
00513 M = T(1) + T(3) * M;
00514 }
00515
00516 template<class T>
00517 vnl_matrix<T>& vnl_matrix<T>::operator+= (T value)
00518 {
00519 for (unsigned int i = 0; i < this->num_rows; i++)
00520 for (unsigned int j = 0; j < this->num_cols; j++)
00521 this->data[i][j] += value;
00522 return *this;
00523 }
00524
00525 template<class T>
00526 vnl_matrix<T>& vnl_matrix<T>::operator-= (T value)
00527 {
00528 for (unsigned int i = 0; i < this->num_rows; i++)
00529 for (unsigned int j = 0; j < this->num_cols; j++)
00530 this->data[i][j] -= value;
00531 return *this;
00532 }
00533
00534 template<class T>
00535 vnl_matrix<T>& vnl_matrix<T>::operator*= (T value)
00536 {
00537 for (unsigned int i = 0; i < this->num_rows; i++)
00538 for (unsigned int j = 0; j < this->num_cols; j++)
00539 this->data[i][j] *= value;
00540 return *this;
00541 }
00542
00543 template<class T>
00544 vnl_matrix<T>& vnl_matrix<T>::operator/= (T value)
00545 {
00546 for (unsigned int i = 0; i < this->num_rows; i++)
00547 for (unsigned int j = 0; j < this->num_cols; j++)
00548 this->data[i][j] /= value;
00549 return *this;
00550 }
00551
00552
00553
00554
00555
00556 template<class T>
00557 vnl_matrix<T>& vnl_matrix<T>::operator+= (vnl_matrix<T> const& rhs)
00558 {
00559 #ifndef NDEBUG
00560 if (this->num_rows != rhs.num_rows ||
00561 this->num_cols != rhs.num_cols)
00562 vnl_error_matrix_dimension ("operator+=",
00563 this->num_rows, this->num_cols,
00564 rhs.num_rows, rhs.num_cols);
00565 #endif
00566 for (unsigned int i = 0; i < this->num_rows; i++)
00567 for (unsigned int j = 0; j < this->num_cols; j++)
00568 this->data[i][j] += rhs.data[i][j];
00569 return *this;
00570 }
00571
00572
00573
00574
00575
00576
00577 template<class T>
00578 vnl_matrix<T>& vnl_matrix<T>::operator-= (vnl_matrix<T> const& rhs)
00579 {
00580 #ifndef NDEBUG
00581 if (this->num_rows != rhs.num_rows ||
00582 this->num_cols != rhs.num_cols)
00583 vnl_error_matrix_dimension ("operator-=",
00584 this->num_rows, this->num_cols,
00585 rhs.num_rows, rhs.num_cols);
00586 #endif
00587 for (unsigned int i = 0; i < this->num_rows; i++)
00588 for (unsigned int j = 0; j < this->num_cols; j++)
00589 this->data[i][j] -= rhs.data[i][j];
00590 return *this;
00591 }
00592
00593
00594 template<class T>
00595 vnl_matrix<T> operator- (T const& value, vnl_matrix<T> const& m)
00596 {
00597 vnl_matrix<T> result(m.rows(),m.columns());
00598 for (unsigned int i = 0; i < m.rows(); i++)
00599 for (unsigned int j = 0; j < m.columns(); j++)
00600 result.put(i,j, T(value - m.get(i,j)) );
00601 return result;
00602 }
00603
00604
00605 #if 0 // commented out
00606
00607
00608
00609
00610 template<class T>
00611 vnl_matrix<T> vnl_matrix<T>::operator* (vnl_matrix<T> const& rhs) const
00612 {
00613 #ifndef NDEBUG
00614 if (this->num_cols != rhs.num_rows)
00615 vnl_error_matrix_dimension("operator*",
00616 this->num_rows, this->num_cols,
00617 rhs.num_rows, rhs.num_cols);
00618 #endif
00619 vnl_matrix<T> result(this->num_rows, rhs.num_cols);
00620 for (unsigned i = 0; i < this->num_rows; i++) {
00621 for (unsigned j = 0; j < rhs.num_cols; j++) {
00622 T sum = 0;
00623 for (unsigned k = 0; k < this->num_cols; k++)
00624 sum += (this->data[i][k] * rhs.data[k][j]);
00625 result(i,j) = sum;
00626 }
00627 }
00628 return result;
00629 }
00630 #endif
00631
00632
00633
00634
00635 template<class T>
00636 vnl_matrix<T> vnl_matrix<T>::operator- () const
00637 {
00638 vnl_matrix<T> result(this->num_rows, this->num_cols);
00639 for (unsigned int i = 0; i < this->num_rows; i++)
00640 for (unsigned int j = 0; j < this->num_cols; j++)
00641 result.data[i][j] = - this->data[i][j];
00642 return result;
00643 }
00644
00645 #if 0 // commented out
00646
00647
00648
00649 template<class T>
00650 vnl_matrix<T> vnl_matrix<T>::operator+ (T const& value) const
00651 {
00652 vnl_matrix<T> result(this->num_rows, this->num_cols);
00653 for (unsigned i = 0; i < this->num_rows; i++)
00654 for (unsigned j = 0; j < this->num_cols; j++)
00655 result.data[i][j] = (this->data[i][j] + value);
00656 return result;
00657 }
00658
00659
00660
00661
00662
00663 template<class T>
00664 vnl_matrix<T> vnl_matrix<T>::operator* (T const& value) const
00665 {
00666 vnl_matrix<T> result(this->num_rows, this->num_cols);
00667 for (unsigned i = 0; i < this->num_rows; i++)
00668 for (unsigned j = 0; j < this->num_cols; j++)
00669 result.data[i][j] = (this->data[i][j] * value);
00670 return result;
00671 }
00672
00673
00674
00675 template<class T>
00676 vnl_matrix<T> vnl_matrix<T>::operator/ (T const& value) const
00677 {
00678 vnl_matrix<T> result(this->num_rows, this->num_cols);
00679 for (unsigned i = 0; i < this->num_rows; i++)
00680 for (unsigned j = 0; j < this->num_cols; j++)
00681 result.data[i][j] = (this->data[i][j] / value);
00682 return result;
00683 }
00684 #endif
00685
00686
00687 template <class T>
00688 vnl_matrix<T> vnl_matrix<T>::apply(T (*f)(T const&)) const
00689 {
00690 vnl_matrix<T> ret(num_rows, num_cols);
00691 vnl_c_vector<T>::apply(this->data[0], num_rows * num_cols, f, ret.data_block());
00692 return ret;
00693 }
00694
00695
00696 template <class T>
00697 vnl_matrix<T> vnl_matrix<T>::apply(T (*f)(T)) const
00698 {
00699 vnl_matrix<T> ret(num_rows, num_cols);
00700 vnl_c_vector<T>::apply(this->data[0], num_rows * num_cols, f, ret.data_block());
00701 return ret;
00702 }
00703
00704
00705
00706
00707
00708
00709 template<class T>
00710 vnl_matrix<T> vnl_matrix<T>::transpose() const
00711 {
00712 vnl_matrix<T> result(this->num_cols, this->num_rows);
00713 for (unsigned int i = 0; i < this->num_cols; i++)
00714 for (unsigned int j = 0; j < this->num_rows; j++)
00715 result.data[i][j] = this->data[j][i];
00716 return result;
00717 }
00718
00719
00720
00721 template<class T>
00722 vnl_matrix<T> vnl_matrix<T>::conjugate_transpose() const
00723 {
00724 vnl_matrix<T> result(transpose());
00725 vnl_c_vector<T>::conjugate(result.begin(),
00726 result.begin(),
00727 result.size());
00728 return result;
00729 }
00730
00731
00732
00733
00734 template<class T>
00735 vnl_matrix<T>& vnl_matrix<T>::update (vnl_matrix<T> const& m,
00736 unsigned top, unsigned left)
00737 {
00738 unsigned int bottom = top + m.num_rows;
00739 unsigned int right = left + m.num_cols;
00740 #ifndef NDEBUG
00741 if (this->num_rows < bottom || this->num_cols < right)
00742 vnl_error_matrix_dimension ("update",
00743 bottom, right, m.num_rows, m.num_cols);
00744 #endif
00745 for (unsigned int i = top; i < bottom; i++)
00746 for (unsigned int j = left; j < right; j++)
00747 this->data[i][j] = m.data[i-top][j-left];
00748 return *this;
00749 }
00750
00751
00752
00753
00754
00755 template<class T>
00756 vnl_matrix<T> vnl_matrix<T>::extract (unsigned rowz, unsigned colz,
00757 unsigned top, unsigned left) const {
00758 vnl_matrix<T> result(rowz, colz);
00759 this->extract( result, top, left );
00760 return result;
00761 }
00762
00763 template<class T>
00764 void vnl_matrix<T>::extract( vnl_matrix<T>& submatrix,
00765 unsigned top, unsigned left) const {
00766 unsigned const rowz = submatrix.rows();
00767 unsigned const colz = submatrix.cols();
00768 #ifndef NDEBUG
00769 unsigned int bottom = top + rowz;
00770 unsigned int right = left + colz;
00771 if ((this->num_rows < bottom) || (this->num_cols < right))
00772 vnl_error_matrix_dimension ("extract",
00773 this->num_rows, this->num_cols, bottom, right);
00774 #endif
00775 for (unsigned int i = 0; i < rowz; i++)
00776 for (unsigned int j = 0; j < colz; j++)
00777 submatrix.data[i][j] = data[top+i][left+j];
00778 }
00779
00780
00781
00782
00783 template<class T>
00784 T dot_product (vnl_matrix<T> const& m1, vnl_matrix<T> const& m2)
00785 {
00786 #ifndef NDEBUG
00787 if (m1.rows() != m2.rows() || m1.columns() != m2.columns())
00788 vnl_error_matrix_dimension ("dot_product",
00789 m1.rows(), m1.columns(),
00790 m2.rows(), m2.columns());
00791 #endif
00792 return vnl_c_vector<T>::dot_product(m1.begin(), m2.begin(), m1.rows()*m1.cols());
00793 }
00794
00795
00796
00797
00798 template<class T>
00799 T inner_product (vnl_matrix<T> const& m1, vnl_matrix<T> const& m2)
00800 {
00801 #ifndef NDEBUG
00802 if (m1.rows() != m2.rows() || m1.columns() != m2.columns())
00803 vnl_error_matrix_dimension ("inner_product",
00804 m1.rows(), m1.columns(),
00805 m2.rows(), m2.columns());
00806 #endif
00807 return vnl_c_vector<T>::inner_product(m1.begin(), m2.begin(), m1.rows()*m1.cols());
00808 }
00809
00810
00811
00812 template<class T>
00813 T cos_angle (vnl_matrix<T> const& a, vnl_matrix<T> const& b)
00814 {
00815 typedef typename vnl_numeric_traits<T>::abs_t Abs_t;
00816 typedef typename vnl_numeric_traits<Abs_t>::real_t abs_r;
00817
00818 T ab = inner_product(a,b);
00819 Abs_t a_b = (Abs_t)vcl_sqrt( (abs_r)vnl_math_abs(inner_product(a,a) * inner_product(b,b)) );
00820
00821 return T( ab / a_b);
00822 }
00823
00824
00825
00826
00827 template<class T>
00828 vnl_matrix<T> element_product (vnl_matrix<T> const& m1,
00829 vnl_matrix<T> const& m2)
00830 {
00831 #ifndef NDEBUG
00832 if (m1.rows() != m2.rows() || m1.columns() != m2.columns())
00833 vnl_error_matrix_dimension ("element_product",
00834 m1.rows(), m1.columns(), m2.rows(), m2.columns());
00835 #endif
00836 vnl_matrix<T> result(m1.rows(), m1.columns());
00837 for (unsigned int i = 0; i < m1.rows(); i++)
00838 for (unsigned int j = 0; j < m1.columns(); j++)
00839 result.put(i,j, T(m1.get(i,j) * m2.get(i,j)) );
00840 return result;
00841 }
00842
00843
00844
00845
00846 template<class T>
00847 vnl_matrix<T> element_quotient (vnl_matrix<T> const& m1,
00848 vnl_matrix<T> const& m2)
00849 {
00850 #ifndef NDEBUG
00851 if (m1.rows() != m2.rows() || m1.columns() != m2.columns())
00852 vnl_error_matrix_dimension("element_quotient",
00853 m1.rows(), m1.columns(), m2.rows(), m2.columns());
00854 #endif
00855 vnl_matrix<T> result(m1.rows(), m1.columns());
00856 for (unsigned int i = 0; i < m1.rows(); i++)
00857 for (unsigned int j = 0; j < m1.columns(); j++)
00858 result.put(i,j, T(m1.get(i,j) / m2.get(i,j)) );
00859 return result;
00860 }
00861
00862
00863
00864 template<class T>
00865 void vnl_matrix<T>::copy_in(T const *p)
00866 {
00867 T* dp = this->data[0];
00868 unsigned int n = this->num_rows * this->num_cols;
00869 while (n--)
00870 *dp++ = *p++;
00871 }
00872
00873
00874
00875 template<class T>
00876 void vnl_matrix<T>::copy_out(T *p) const
00877 {
00878 T* dp = this->data[0];
00879 unsigned int n = this->num_rows * this->num_cols;
00880 while (n--)
00881 *p++ = *dp++;
00882 }
00883
00884
00885 template<class T>
00886 void vnl_matrix<T>::set_identity()
00887 {
00888 #ifndef NDEBUG
00889 if (this->num_rows != this->num_cols)
00890 vnl_error_matrix_nonsquare ("set_identity");
00891 #endif
00892 for (unsigned int i = 0; i < this->num_rows; i++)
00893 for (unsigned int j = 0; j < this->num_cols; j++)
00894 if (i == j)
00895 this->data[i][j] = T(1);
00896 else
00897 this->data[i][j] = T(0);
00898 }
00899
00900
00901
00902 template<class T>
00903 void vnl_matrix<T>::normalize_rows()
00904 {
00905 typedef typename vnl_numeric_traits<T>::abs_t Abs_t;
00906 typedef typename vnl_numeric_traits<T>::real_t Real_t;
00907 typedef typename vnl_numeric_traits<Real_t>::abs_t abs_real_t;
00908 for (unsigned int i = 0; i < this->num_rows; i++) {
00909 Abs_t norm(0);
00910 for (unsigned int j = 0; j < this->num_cols; j++)
00911 norm += vnl_math_squared_magnitude(this->data[i][j]);
00912
00913 if (norm != 0) {
00914 abs_real_t scale = abs_real_t(1)/(vcl_sqrt((abs_real_t)norm));
00915 for (unsigned int j = 0; j < this->num_cols; j++)
00916 this->data[i][j] = T(Real_t(this->data[i][j]) * scale);
00917 }
00918 }
00919 }
00920
00921
00922
00923 template<class T>
00924 void vnl_matrix<T>::normalize_columns()
00925 {
00926 typedef typename vnl_numeric_traits<T>::abs_t Abs_t;
00927 typedef typename vnl_numeric_traits<T>::real_t Real_t;
00928 typedef typename vnl_numeric_traits<Real_t>::abs_t abs_real_t;
00929 for (unsigned int j = 0; j < this->num_cols; j++) {
00930 Abs_t norm(0);
00931 for (unsigned int i = 0; i < this->num_rows; i++)
00932 norm += vnl_math_squared_magnitude(this->data[i][j]);
00933
00934 if (norm != 0) {
00935 abs_real_t scale = abs_real_t(1)/(vcl_sqrt((abs_real_t)norm));
00936 for (unsigned int i = 0; i < this->num_rows; i++)
00937 this->data[i][j] = T(Real_t(this->data[i][j]) * scale);
00938 }
00939 }
00940 }
00941
00942
00943 template<class T>
00944 void vnl_matrix<T>::scale_row(unsigned row_index, T value)
00945 {
00946 #ifndef NDEBUG
00947 if (row_index >= this->num_rows)
00948 vnl_error_matrix_row_index("scale_row", row_index);
00949 #endif
00950 for (unsigned int j = 0; j < this->num_cols; j++)
00951 this->data[row_index][j] *= value;
00952 }
00953
00954
00955 template<class T>
00956 void vnl_matrix<T>::scale_column(unsigned column_index, T value)
00957 {
00958 #ifndef NDEBUG
00959 if (column_index >= this->num_cols)
00960 vnl_error_matrix_col_index("scale_column", column_index);
00961 #endif
00962 for (unsigned int j = 0; j < this->num_rows; j++)
00963 this->data[j][column_index] *= value;
00964 }
00965
00966
00967 template<class T>
00968 vnl_matrix<T> vnl_matrix<T>::get_n_rows (unsigned row, unsigned n) const
00969 {
00970 #ifndef NDEBUG
00971 if (row + n > this->num_rows)
00972 vnl_error_matrix_row_index ("get_n_rows", row);
00973 #endif
00974
00975
00976 return vnl_matrix<T>(data[row], n, this->num_cols);
00977 }
00978
00979
00980 template<class T>
00981 vnl_matrix<T> vnl_matrix<T>::get_n_columns (unsigned column, unsigned n) const
00982 {
00983 #ifndef NDEBUG
00984 if (column + n > this->num_cols)
00985 vnl_error_matrix_col_index ("get_n_columns", column);
00986 #endif
00987
00988 vnl_matrix<T> result(this->num_rows, n);
00989 for (unsigned int c = 0; c < n; ++c)
00990 for (unsigned int r = 0; r < this->num_rows; ++r)
00991 result(r, c) = data[r][column + c];
00992 return result;
00993 }
00994
00995
00996 template<class T>
00997 vnl_vector<T> vnl_matrix<T>::get_row(unsigned row_index) const
00998 {
00999 #ifdef ERROR_CHECKING
01000 if (row_index >= this->num_rows)
01001 vnl_error_matrix_row_index ("get_row", row_index);
01002 #endif
01003
01004 vnl_vector<T> v(this->num_cols);
01005 for (unsigned int j = 0; j < this->num_cols; j++)
01006 v[j] = this->data[row_index][j];
01007 return v;
01008 }
01009
01010
01011 template<class T>
01012 vnl_vector<T> vnl_matrix<T>::get_column(unsigned column_index) const
01013 {
01014 #ifdef ERROR_CHECKING
01015 if (column_index >= this->num_cols)
01016 vnl_error_matrix_col_index ("get_column", column_index);
01017 #endif
01018
01019 vnl_vector<T> v(this->num_rows);
01020 for (unsigned int j = 0; j < this->num_rows; j++)
01021 v[j] = this->data[j][column_index];
01022 return v;
01023 }
01024
01025
01026
01027
01028 template<class T>
01029 void vnl_matrix<T>::set_row(unsigned row_index, T const *v)
01030 {
01031 for (unsigned int j = 0; j < this->num_cols; j++)
01032 this->data[row_index][j] = v[j];
01033 }
01034
01035
01036 template<class T>
01037 void vnl_matrix<T>::set_row(unsigned row_index, vnl_vector<T> const &v)
01038 {
01039 #ifndef NDEBUG
01040 if (v.size() != this->num_cols)
01041 vnl_error_vector_dimension ("vnl_matrix::set_row", v.size(), this->num_cols);
01042 #endif
01043 set_row(row_index,v.data_block());
01044 }
01045
01046
01047 template<class T>
01048 void vnl_matrix<T>::set_row(unsigned row_index, T v)
01049 {
01050 for (unsigned int j = 0; j < this->num_cols; j++)
01051 this->data[row_index][j] = v;
01052 }
01053
01054
01055
01056
01057 template<class T>
01058 void vnl_matrix<T>::set_column(unsigned column_index, T const *v)
01059 {
01060 for (unsigned int i = 0; i < this->num_rows; i++)
01061 this->data[i][column_index] = v[i];
01062 }
01063
01064
01065 template<class T>
01066 void vnl_matrix<T>::set_column(unsigned column_index, vnl_vector<T> const &v)
01067 {
01068 #ifndef NDEBUG
01069 if (v.size() != this->num_rows)
01070 vnl_error_vector_dimension ("vnl_matrix::set_column", v.size(), this->num_rows);
01071 #endif
01072 set_column(column_index,v.data_block());
01073 }
01074
01075
01076 template<class T>
01077 void vnl_matrix<T>::set_column(unsigned column_index, T v)
01078 {
01079 for (unsigned int j = 0; j < this->num_rows; j++)
01080 this->data[j][column_index] = v;
01081 }
01082
01083
01084
01085 template<class T>
01086 void vnl_matrix<T>::set_columns(unsigned starting_column, vnl_matrix<T> const& m)
01087 {
01088 #ifndef NDEBUG
01089 if (this->num_rows != m.num_rows ||
01090 this->num_cols < m.num_cols + starting_column)
01091 vnl_error_matrix_dimension ("set_columns",
01092 this->num_rows, this->num_cols,
01093 m.num_rows, m.num_cols);
01094 #endif
01095
01096 for (unsigned int j = 0; j < m.num_cols; ++j)
01097 for (unsigned int i = 0; i < this->num_rows; i++)
01098 this->data[i][starting_column + j] = m.data[i][j];
01099 }
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109 template<class T>
01110 bool vnl_matrix<T>::operator_eq(vnl_matrix<T> const& rhs) const
01111 {
01112 if (this == &rhs)
01113 return true;
01114
01115 if (this->num_rows != rhs.num_rows || this->num_cols != rhs.num_cols)
01116 return false;
01117
01118 for (unsigned int i = 0; i < this->num_rows; i++)
01119 for (unsigned int j = 0; j < this->num_cols; j++)
01120 if (!(this->data[i][j] == rhs.data[i][j]))
01121 return false;
01122
01123 return true;
01124 }
01125
01126 template <class T>
01127 bool vnl_matrix<T>::is_identity() const
01128 {
01129 T const zero(0);
01130 T const one(1);
01131 for (unsigned int i = 0; i < this->rows(); ++i)
01132 for (unsigned int j = 0; j < this->columns(); ++j) {
01133 T xm = (*this)(i,j);
01134 if ( !((i == j) ? (xm == one) : (xm == zero)) )
01135 return false;
01136 }
01137 return true;
01138 }
01139
01140
01141 template <class T>
01142 bool vnl_matrix<T>::is_identity(double tol) const
01143 {
01144 T one(1);
01145 for (unsigned int i = 0; i < this->rows(); ++i)
01146 for (unsigned int j = 0; j < this->columns(); ++j) {
01147 T xm = (*this)(i,j);
01148 abs_t absdev = (i == j) ? vnl_math_abs(xm - one) : vnl_math_abs(xm);
01149 if (absdev > tol)
01150 return false;
01151 }
01152 return true;
01153 }
01154
01155 template <class T>
01156 bool vnl_matrix<T>::is_zero() const
01157 {
01158 T const zero(0);
01159 for (unsigned int i = 0; i < this->rows(); ++i)
01160 for (unsigned int j = 0; j < this->columns(); ++j)
01161 if ( !( (*this)(i, j) == zero) )
01162 return false;
01163
01164 return true;
01165 }
01166
01167
01168 template <class T>
01169 bool vnl_matrix<T>::is_zero(double tol) const
01170 {
01171 for (unsigned int i = 0; i < this->rows(); ++i)
01172 for (unsigned int j = 0; j < this->columns(); ++j)
01173 if (vnl_math_abs((*this)(i,j)) > tol)
01174 return false;
01175
01176 return true;
01177 }
01178
01179
01180 template <class T>
01181 bool vnl_matrix<T>::has_nans() const
01182 {
01183 for (unsigned int i = 0; i < this->rows(); ++i)
01184 for (unsigned int j = 0; j < this->columns(); ++j)
01185 if (vnl_math_isnan((*this)(i,j)))
01186 return true;
01187
01188 return false;
01189 }
01190
01191
01192 template <class T>
01193 bool vnl_matrix<T>::is_finite() const
01194 {
01195 for (unsigned int i = 0; i < this->rows(); ++i)
01196 for (unsigned int j = 0; j < this->columns(); ++j)
01197 if (!vnl_math_isfinite((*this)(i,j)))
01198 return false;
01199
01200 return true;
01201 }
01202
01203
01204 template <class T>
01205 void vnl_matrix<T>::assert_finite_internal() const
01206 {
01207 if (is_finite())
01208 return;
01209
01210 vcl_cerr << "\n\n" __FILE__ ": " << __LINE__ << ": matrix has non-finite elements\n";
01211
01212 if (rows() <= 20 && cols() <= 20) {
01213 vcl_cerr << __FILE__ ": here it is:\n" << *this;
01214 }
01215 else {
01216 vcl_cerr << __FILE__ ": it is quite big (" << rows() << 'x' << cols() << ")\n"
01217 << __FILE__ ": in the following picture '-' means finite and '*' means non-finite:\n";
01218
01219 for (unsigned int i=0; i<rows(); ++i) {
01220 for (unsigned int j=0; j<cols(); ++j)
01221 vcl_cerr << char(vnl_math_isfinite((*this)(i, j)) ? '-' : '*');
01222 vcl_cerr << '\n';
01223 }
01224 }
01225 vcl_cerr << __FILE__ ": calling abort()\n";
01226 vcl_abort();
01227 }
01228
01229
01230 template <class T>
01231 void vnl_matrix<T>::assert_size_internal(unsigned rs,unsigned cs) const
01232 {
01233 if (this->rows()!=rs || this->cols()!=cs) {
01234 vcl_cerr << __FILE__ ": size is " << this->rows() << 'x' << this->cols()
01235 << ". should be " << rs << 'x' << cs << vcl_endl;
01236 vcl_abort();
01237 }
01238 }
01239
01240
01241
01242 template <class T>
01243 bool vnl_matrix<T>::read_ascii(vcl_istream& s)
01244 {
01245 if (!s.good()) {
01246 vcl_cerr << __FILE__ ": vnl_matrix<T>::read_ascii: Called with bad stream\n";
01247 return false;
01248 }
01249
01250 bool size_known = (this->rows() != 0);
01251
01252 if (size_known) {
01253 for (unsigned int i = 0; i < this->rows(); ++i)
01254 for (unsigned int j = 0; j < this->columns(); ++j)
01255 s >> this->data[i][j];
01256
01257 return s.good() || s.eof();
01258 }
01259
01260 bool debug = false;
01261
01262 vcl_vector<T> first_row_vals;
01263 if (debug)
01264 vcl_cerr << __FILE__ ": vnl_matrix<T>::read_ascii: Determining file dimensions: ";
01265
01266 for (;;) {
01267
01268 while (true)
01269 {
01270 int c = s.get();
01271 if (c == EOF)
01272 goto loademup;
01273 if (!vcl_isspace(c)) {
01274 if (!s.putback(char(c)).good())
01275 vcl_cerr << "vnl_matrix<T>::read_ascii: Could not push back '" << c << "'\n";
01276
01277 goto readfloat;
01278 }
01279
01280 if (c == '\n' && first_row_vals.size() > 0) {
01281 goto loademup;
01282 }
01283 }
01284 readfloat:
01285 T val;
01286 s >> val;
01287 if (!s.fail())
01288 first_row_vals.push_back(val);
01289 if (s.eof())
01290 goto loademup;
01291 }
01292 loademup:
01293 vcl_size_t colz = first_row_vals.size();
01294
01295 if (debug) vcl_cerr << colz << " cols, ";
01296
01297 if (colz == 0)
01298 return false;
01299
01300
01301
01302 vcl_vector<T*> row_vals;
01303 row_vals.reserve(1000);
01304 {
01305
01306 T* row = vnl_c_vector<T>::allocate_T(colz);
01307 for (unsigned int k = 0; k < colz; ++k)
01308 row[k] = first_row_vals[k];
01309 row_vals.push_back(row);
01310 }
01311
01312 while (true)
01313 {
01314 T* row = vnl_c_vector<T>::allocate_T(colz);
01315 if (row == 0) {
01316 vcl_cerr << "vnl_matrix<T>::read_ascii: Error, Out of memory on row "
01317 << row_vals.size() << vcl_endl;
01318 return false;
01319 }
01320 s >> row[0];
01321 if (!s.good())
01322 {
01323 vnl_c_vector<T>::deallocate(row, colz);
01324 break;
01325 }
01326 for (unsigned int k = 1; k < colz; ++k) {
01327 if (s.eof()) {
01328 vcl_cerr << "vnl_matrix<T>::read_ascii: Error, EOF on row "
01329 << row_vals.size() << ", column " << k << vcl_endl;
01330
01331 return false;
01332 }
01333 s >> row[k];
01334 if (s.fail()) {
01335 vcl_cerr << "vnl_matrix<T>::read_ascii: Error, row "
01336 << row_vals.size() << " failed on column " << k << vcl_endl;
01337 return false;
01338 }
01339 }
01340 row_vals.push_back(row);
01341 }
01342
01343 vcl_size_t rowz = row_vals.size();
01344
01345 if (debug)
01346 vcl_cerr << rowz << " rows.\n";
01347
01348 set_size(rowz, colz);
01349
01350 T* p = this->data[0];
01351 for (unsigned int i = 0; i < rowz; ++i) {
01352 for (unsigned int j = 0; j < colz; ++j)
01353 *p++ = row_vals[i][j];
01354 vnl_c_vector<T>::deallocate(row_vals[i], colz);
01355 }
01356
01357 return true;
01358 }
01359
01360
01361
01362
01363
01364
01365
01366
01367 template <class T>
01368 vnl_matrix<T> vnl_matrix<T>::read(vcl_istream& s)
01369 {
01370 vnl_matrix<T> M;
01371 s >> M;
01372 return M;
01373 }
01374
01375 template <class T>
01376 void vnl_matrix<T>::swap(vnl_matrix<T> &that)
01377 {
01378 vcl_swap(this->num_rows, that.num_rows);
01379 vcl_swap(this->num_cols, that.num_cols);
01380 vcl_swap(this->data, that.data);
01381 }
01382
01383
01384 template <class T>
01385 void vnl_matrix<T>::flipud()
01386 {
01387 unsigned int n = this->rows();
01388 unsigned int colz = this->columns();
01389
01390 unsigned int m = n / 2;
01391 for (unsigned int r = 0; r < m; ++r) {
01392 unsigned int r1 = r;
01393 unsigned int r2 = n - 1 - r;
01394 for (unsigned int c = 0; c < colz; ++c) {
01395 T tmp = (*this)(r1, c);
01396 (*this)(r1, c) = (*this)(r2, c);
01397 (*this)(r2, c) = tmp;
01398 }
01399 }
01400 }
01401
01402
01403 template <class T>
01404 void vnl_matrix<T>::fliplr()
01405 {
01406 unsigned int n = this->cols();
01407 unsigned int rowz = this->rows();
01408
01409 unsigned int m = n / 2;
01410 for (unsigned int c = 0; c < m; ++c) {
01411 unsigned int c1 = c;
01412 unsigned int c2 = n - 1 - c;
01413 for (unsigned int r = 0; r < rowz; ++r) {
01414 T tmp = (*this)(r, c1);
01415 (*this)(r, c1) = (*this)(r, c2);
01416 (*this)(r, c2) = tmp;
01417 }
01418 }
01419 }
01420
01421
01422
01423 template <class T>
01424 typename vnl_matrix<T>::abs_t vnl_matrix<T>::operator_one_norm() const
01425 {
01426 abs_t max = 0;
01427 for (unsigned int j=0; j<this->num_cols; ++j) {
01428 abs_t tmp = 0;
01429 for (unsigned int i=0; i<this->num_rows; ++i)
01430 tmp += vnl_math_abs(this->data[i][j]);
01431 if (tmp > max)
01432 max = tmp;
01433 }
01434 return max;
01435 }
01436
01437
01438
01439 template <class T>
01440 typename vnl_matrix<T>::abs_t vnl_matrix<T>::operator_inf_norm() const
01441 {
01442 abs_t max = 0;
01443 for (unsigned int i=0; i<this->num_rows; ++i) {
01444 abs_t tmp = 0;
01445 for (unsigned int j=0; j<this->num_cols; ++j)
01446 tmp += vnl_math_abs(this->data[i][j]);
01447 if (tmp > max)
01448 max = tmp;
01449 }
01450 return max;
01451 }
01452
01453 template <class doublereal>
01454 int vnl_inplace_transpose(doublereal *a, unsigned m, unsigned n, char* move, unsigned iwrk)
01455 {
01456 doublereal b, c;
01457 int k = m * n - 1;
01458 int iter, i1, i2, im, i1c, i2c, ncount, max_;
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476 if (m < 2 || n < 2)
01477 return 0;
01478 if (iwrk < 1)
01479 return -2;
01480 if (m == n) {
01481
01482 for (unsigned i = 0; i < n; ++i)
01483 for (unsigned j = i+1; j < n; ++j) {
01484 i1 = i + j * n;
01485 i2 = j + i * m;
01486 b = a[i1];
01487 a[i1] = a[i2];
01488 a[i2] = b;
01489 }
01490 return 0;
01491 }
01492 ncount = 2;
01493 for (unsigned i = 0; i < iwrk; ++i)
01494 move[i] = char(0);
01495 if (m > 2 && n > 2) {
01496
01497 int ir2 = m - 1;
01498 int ir1 = n - 1;
01499 int ir0 = ir2 % ir1;
01500 while (ir0 != 0) {
01501 ir2 = ir1;
01502 ir1 = ir0;
01503 ir0 = ir2 % ir1;
01504 }
01505 ncount += ir1 - 1;
01506 }
01507
01508 iter = 1;
01509 im = m;
01510
01511 goto L80;
01512
01513 L40:
01514 max_ = k - iter;
01515 ++iter;
01516 if (iter > max_)
01517 return iter;
01518 im += m;
01519 if (im > k)
01520 im -= k;
01521 i2 = im;
01522 if (iter == i2)
01523 goto L40;
01524 if (iter <= (int)iwrk) {
01525 if (move[iter-1])
01526 goto L40;
01527 else
01528 goto L80;
01529 }
01530 while (i2 > iter && i2 < max_) {
01531 i1 = i2;
01532 i2 = m * i1 - k * (i1 / n);
01533 }
01534 if (i2 != iter)
01535 goto L40;
01536
01537 L80:
01538 i1 = iter;
01539 b = a[i1];
01540 i1c = k - iter;
01541 c = a[i1c];
01542 while (true) {
01543 i2 = m * i1 - k * (i1 / n);
01544 i2c = k - i2;
01545 if (i1 <= (int)iwrk)
01546 move[i1-1] = '1';
01547 if (i1c <= (int)iwrk)
01548 move[i1c-1] = '1';
01549 ncount += 2;
01550 if (i2 == iter)
01551 break;
01552 if (i2+iter == k) {
01553 doublereal d = b; b = c; c = d;
01554 break;
01555 }
01556 a[i1] = a[i2];
01557 a[i1c] = a[i2c];
01558 i1 = i2;
01559 i1c = i2c;
01560 }
01561
01562 a[i1] = b;
01563 a[i1c] = c;
01564 if (ncount > k)
01565 return 0;
01566 goto L40;
01567 }
01568
01569
01570
01571
01572 template <class T>
01573 void vnl_matrix<T>::inplace_transpose()
01574 {
01575 unsigned m = rows();
01576 unsigned n = columns();
01577 unsigned iwrk = (m+n)/2;
01578 vcl_vector<char> move(iwrk);
01579
01580 int iok = ::vnl_inplace_transpose(data_block(), n, m, &move[0], iwrk);
01581 if (iok != 0)
01582 vcl_cerr << __FILE__ " : inplace_transpose() -- iok = " << iok << vcl_endl;
01583
01584 this->num_rows = n;
01585 this->num_cols = m;
01586
01587
01588
01589 {
01590 T *tmp = data[0];
01591 vnl_c_vector<T>::deallocate(data, m);
01592 data = vnl_c_vector<T>::allocate_Tptr(n);
01593 for (unsigned i=0; i<n; ++i)
01594 data[i] = tmp + i * m;
01595 }
01596 }
01597
01598
01599
01600 #define VNL_MATRIX_INSTANTIATE(T) \
01601 template class vnl_matrix<T >; \
01602 template vnl_matrix<T > operator-(T const &, vnl_matrix<T > const &); \
01603 VCL_INSTANTIATE_INLINE(vnl_matrix<T > operator+(T const &, vnl_matrix<T > const &)); \
01604 VCL_INSTANTIATE_INLINE(vnl_matrix<T > operator*(T const &, vnl_matrix<T > const &)); \
01605 template T dot_product(vnl_matrix<T > const &, vnl_matrix<T > const &); \
01606 template T inner_product(vnl_matrix<T > const &, vnl_matrix<T > const &); \
01607 template T cos_angle(vnl_matrix<T > const &, vnl_matrix<T > const &); \
01608 template vnl_matrix<T > element_product(vnl_matrix<T > const &, vnl_matrix<T > const &); \
01609 template vnl_matrix<T > element_quotient(vnl_matrix<T > const &, vnl_matrix<T > const &); \
01610 template int vnl_inplace_transpose(T*, unsigned, unsigned, char*, unsigned); \
01611 template vcl_ostream & operator<<(vcl_ostream &, vnl_matrix<T > const &); \
01612 template vcl_istream & operator>>(vcl_istream &, vnl_matrix<T > &)
01613
01614 #endif // vnl_matrix_txx_