00001
00002 #ifndef vnl_matrix_fixed_h_
00003 #define vnl_matrix_fixed_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <vcl_cstring.h>
00028 #include <vcl_cassert.h>
00029 #include <vcl_iosfwd.h>
00030
00031 #include "vnl_matrix.h"
00032 #include "vnl_matrix_ref.h"
00033 #include <vnl/vnl_vector.h>
00034 #include <vnl/vnl_c_vector.h>
00035 #include <vnl/vnl_config.h>
00036
00037 export template <class T, unsigned int n> class vnl_vector_fixed;
00038 export template <class T, unsigned int num_rows, unsigned int num_cols> class vnl_matrix_fixed;
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
00082 template <class T, unsigned int num_rows, unsigned int num_cols>
00083 class vnl_matrix_fixed;
00084 template <class T, unsigned M, unsigned N>
00085 inline
00086 vnl_vector_fixed<T, M> vnl_matrix_fixed_mat_vec_mult(const vnl_matrix_fixed<T, M, N>& a, const vnl_vector_fixed<T, N>& b);
00087 template <class T, unsigned M, unsigned N, unsigned O>
00088 inline
00089 vnl_matrix_fixed<T, M, O> vnl_matrix_fixed_mat_mat_mult(const vnl_matrix_fixed<T, M, N>& a, const vnl_matrix_fixed<T, N, O>& b);
00090 #ifdef VCL_VC_6
00091 template <unsigned num_cols, unsigned num_rows, class T>
00092 class vnl_matrix_fixed_fake_base
00093 {
00094 };
00095
00096 #define VNL_MATRIX_FIXED_VCL60_WORKAROUND : public vnl_matrix_fixed_fake_base<num_cols,num_rows,T>
00097 #else
00098 #define VNL_MATRIX_FIXED_VCL60_WORKAROUND
00099 #endif
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 template <class T, unsigned int num_rows, unsigned int num_cols>
00110 class vnl_matrix_fixed VNL_MATRIX_FIXED_VCL60_WORKAROUND
00111 {
00112 public:
00113 typedef vnl_matrix_fixed<T,num_rows,num_cols> self;
00114 typedef unsigned int size_type;
00115
00116 private:
00117 T data_[num_rows][num_cols];
00118
00119 public:
00120
00121
00122 vnl_matrix_fixed() {}
00123
00124
00125
00126
00127
00128
00129
00130 vnl_matrix_fixed( unsigned n, unsigned m )
00131 {
00132 assert( n == num_rows && m == num_cols );
00133 }
00134
00135
00136 explicit vnl_matrix_fixed(T value)
00137 {
00138 T* p = data_[0];
00139 unsigned int n = num_rows * num_cols;
00140 while (n--)
00141 *p++ = value;
00142 }
00143
00144
00145 explicit vnl_matrix_fixed(const T* datablck)
00146 {
00147 vcl_memcpy(data_[0], datablck, num_rows*num_cols*sizeof(T));
00148 }
00149
00150
00151
00152 vnl_matrix_fixed(const vnl_matrix_fixed& rhs)
00153 {
00154 vcl_memcpy(data_[0], rhs.data_block(), num_rows*num_cols*sizeof(T));
00155 }
00156
00157
00158
00159 vnl_matrix_fixed(const vnl_matrix<T>& rhs)
00160 {
00161 assert(rhs.rows() == num_rows && rhs.columns() == num_cols);
00162 vcl_memcpy(data_[0], rhs.data_block(), num_rows*num_cols*sizeof(T));
00163 }
00164
00165
00166
00167
00168
00169 ~vnl_matrix_fixed() {}
00170
00171
00172
00173 vnl_matrix_fixed& operator= (T const&v) { fill(v); return *this; }
00174
00175
00176
00177 vnl_matrix_fixed& operator=(const vnl_matrix<T>& rhs)
00178 {
00179 assert(rhs.rows() == num_rows && rhs.columns() == num_cols);
00180 vcl_memcpy(data_[0], rhs.data_block(), num_rows*num_cols*sizeof(T));
00181 return *this;
00182 }
00183
00184
00185 vnl_matrix_fixed& operator=(const vnl_matrix_fixed& rhs)
00186 {
00187 vcl_memcpy(data_[0], rhs.data_block(), num_rows*num_cols*sizeof(T));
00188 return *this;
00189 }
00190
00191
00192
00193
00194 unsigned rows() const { return num_rows; }
00195
00196
00197
00198 unsigned columns() const { return num_cols; }
00199
00200
00201
00202 unsigned cols() const { return num_cols; }
00203
00204
00205
00206 unsigned size() const { return num_rows*num_cols; }
00207
00208
00209 void put (unsigned r, unsigned c, T const& v) { (*this)(r,c) = v; }
00210
00211
00212 T get (unsigned r, unsigned c) const { return (*this)(r,c); }
00213
00214
00215
00216 T * operator[] (unsigned r) { return data_[r]; }
00217
00218
00219
00220 T const * operator[] (unsigned r) const { return data_[r]; }
00221
00222
00223
00224 T & operator() (unsigned r, unsigned c)
00225 {
00226 #if VNL_CONFIG_CHECK_BOUNDS && (!defined NDEBUG)
00227 assert(r<rows());
00228 assert(c<cols());
00229 #endif
00230 return this->data_[r][c];
00231 }
00232
00233
00234
00235 T const & operator() (unsigned r, unsigned c) const
00236 {
00237 #if VNL_CONFIG_CHECK_BOUNDS && (!defined NDEBUG)
00238 assert(r<rows());
00239 assert(c<cols());
00240 #endif
00241 return this->data_[r][c];
00242 }
00243
00244
00245
00246
00247
00248 void fill (T);
00249
00250
00251
00252 void fill_diagonal (T);
00253
00254
00255
00256 void copy_in(T const *);
00257
00258
00259
00260 void set(T const *d) { copy_in(d); }
00261
00262
00263
00264
00265
00266 void copy_out(T *) const;
00267
00268
00269 void inplace_transpose();
00270
00271
00272
00273
00274
00275
00276
00277 vnl_matrix_fixed& operator+= (T s)
00278 {
00279 self::add( data_block(), s, data_block() ); return *this;
00280 }
00281
00282
00283 vnl_matrix_fixed& operator-= (T s)
00284 {
00285 self::sub( data_block(), s, data_block() ); return *this;
00286 }
00287
00288
00289 vnl_matrix_fixed& operator*= (T s)
00290 {
00291 self::mul( data_block(), s, data_block() ); return *this;
00292 }
00293
00294
00295 vnl_matrix_fixed& operator/= (T s)
00296 {
00297 self::div( data_block(), s, data_block() ); return *this;
00298 }
00299
00300
00301 vnl_matrix_fixed& operator+= (vnl_matrix_fixed const& m)
00302 {
00303 self::add( data_block(), m.data_block(), data_block() ); return *this;
00304 }
00305
00306
00307 vnl_matrix_fixed& operator+= (vnl_matrix<T> const& m)
00308 {
00309 assert( m.rows() == rows() && m.cols() == cols() );
00310 self::add( data_block(), m.data_block(), data_block() ); return *this;
00311 }
00312
00313
00314 vnl_matrix_fixed& operator-= (vnl_matrix_fixed const& m)
00315 {
00316 self::sub( data_block(), m.data_block(), data_block() ); return *this;
00317 }
00318
00319
00320 vnl_matrix_fixed& operator-= (vnl_matrix<T> const& m)
00321 {
00322 assert( m.rows() == rows() && m.cols() == cols() );
00323 self::sub( data_block(), m.data_block(), data_block() );
00324 return *this;
00325 }
00326
00327
00328 vnl_matrix_fixed operator- () const
00329 {
00330 vnl_matrix_fixed r;
00331 self::sub( T(0), data_block(), r.data_block() );
00332 return r;
00333 }
00334
00335
00336 vnl_matrix_fixed& operator*= (vnl_matrix_fixed<T,num_cols,num_cols> const& s)
00337 {
00338 vnl_matrix_fixed<T, num_rows, num_cols> out;
00339 for (unsigned i = 0; i < num_rows; ++i)
00340 for (unsigned j = 0; j < num_cols; ++j)
00341 {
00342 T accum = this->data_[i][0] * s(0,j);
00343 for (unsigned k = 1; k < num_cols; ++k)
00344 accum += this->data_[i][k] * s(k,j);
00345 out(i,j) = accum;
00346 }
00347 return *this = out;
00348 }
00349
00350 #ifdef VCL_VC_6
00351 template <unsigned o>
00352 vnl_matrix_fixed<T,num_rows,o> operator*( vnl_matrix_fixed_fake_base<o,num_cols,T> const& mat ) const
00353 {
00354 vnl_matrix_fixed<T,num_cols,o> const& b = static_cast<vnl_matrix_fixed<T,num_cols,o> const&>(mat);
00355 return vnl_matrix_fixed_mat_mat_mult<T,num_rows,num_cols,o>( *this, b );
00356 }
00357 vnl_vector_fixed<T, num_rows> operator*( vnl_vector_fixed<T, num_cols> const& b) const
00358 {
00359 return vnl_matrix_fixed_mat_vec_mult<T,num_rows,num_cols>(*this,b);
00360 }
00361 #endif
00362
00363
00364
00365
00366 vnl_matrix_fixed apply(T (*f)(T)) const;
00367
00368
00369 vnl_matrix_fixed apply(T (*f)(T const&)) const;
00370
00371
00372 vnl_matrix_fixed<T,num_cols,num_rows> transpose () const;
00373
00374
00375 vnl_matrix_fixed<T,num_cols,num_rows> conjugate_transpose () const;
00376
00377
00378 vnl_matrix_fixed& update (vnl_matrix<T> const&, unsigned top=0, unsigned left=0);
00379
00380
00381 void set_column(unsigned i, T const * v);
00382
00383
00384 void set_column(unsigned i, T value );
00385
00386
00387 void set_column(unsigned j, vnl_vector<T> const& v);
00388
00389
00390 void set_column(unsigned j, vnl_vector_fixed<T,num_rows> const& v);
00391
00392
00393 void set_columns(unsigned starting_column, vnl_matrix<T> const& M);
00394
00395
00396 void set_row (unsigned i, T const * v);
00397
00398
00399 void set_row (unsigned i, T value );
00400
00401
00402 void set_row (unsigned i, vnl_vector<T> const&);
00403
00404
00405 void set_row (unsigned i, vnl_vector_fixed<T,num_cols> const&);
00406
00407
00408
00409 vnl_matrix<T> extract (unsigned r, unsigned c,
00410 unsigned top=0, unsigned left=0) const;
00411
00412
00413
00414
00415
00416
00417 void extract ( vnl_matrix<T>& sub_matrix,
00418 unsigned top=0, unsigned left=0) const;
00419
00420
00421 vnl_vector_fixed<T,num_cols> get_row (unsigned row) const;
00422
00423
00424 vnl_vector_fixed<T,num_rows> get_column(unsigned col) const;
00425
00426
00427 vnl_matrix<T> get_n_rows (unsigned rowstart, unsigned n) const;
00428
00429
00430 vnl_matrix<T> get_n_columns(unsigned colstart, unsigned n) const;
00431
00432
00433
00434
00435
00436
00437 void set_identity();
00438
00439
00440 void flipud();
00441
00442
00443 void fliplr();
00444
00445
00446
00447 void normalize_rows();
00448
00449
00450
00451 void normalize_columns();
00452
00453
00454 void scale_row (unsigned row, T value);
00455
00456
00457 void scale_column(unsigned col, T value);
00458
00459
00460 typedef typename vnl_c_vector<T>::abs_t abs_t;
00461
00462
00463 abs_t array_one_norm() const { return vnl_c_vector<T>::one_norm(begin(), size()); }
00464
00465
00466 abs_t array_two_norm() const { return vnl_c_vector<T>::two_norm(begin(), size()); }
00467
00468
00469 abs_t array_inf_norm() const { return vnl_c_vector<T>::inf_norm(begin(), size()); }
00470
00471
00472 abs_t absolute_value_sum() const { return array_one_norm(); }
00473
00474
00475 abs_t absolute_value_max() const { return array_inf_norm(); }
00476
00477
00478 abs_t operator_one_norm() const;
00479
00480
00481 abs_t operator_inf_norm() const;
00482
00483
00484 abs_t frobenius_norm() const { return vnl_c_vector<T>::two_norm(begin(), size()); }
00485
00486
00487 abs_t fro_norm() const { return frobenius_norm(); }
00488
00489
00490 abs_t rms() const { return vnl_c_vector<T>::rms_norm(begin(), size()); }
00491
00492
00493 T min_value() const { return vnl_c_vector<T>::min_value(begin(), size()); }
00494
00495
00496 T max_value() const { return vnl_c_vector<T>::max_value(begin(), size()); }
00497
00498
00499 unsigned arg_min() const { return vnl_c_vector<T>::arg_min(begin(), size()); }
00500
00501
00502 unsigned arg_max() const { return vnl_c_vector<T>::arg_max(begin(), size()); }
00503
00504
00505 T mean() const { return vnl_c_vector<T>::mean(begin(), size()); }
00506
00507
00508
00509
00510 bool empty() const { return num_rows==0 && num_cols==0; }
00511
00512
00513 bool is_identity() const;
00514
00515
00516 bool is_identity(double tol) const;
00517
00518
00519 bool is_zero() const;
00520
00521
00522 bool is_zero(double tol) const;
00523
00524
00525 bool is_finite() const;
00526
00527
00528 bool has_nans() const;
00529
00530
00531
00532 void assert_size(unsigned nr_rows, unsigned nr_cols) const
00533 {
00534 #ifndef NDEBUG
00535 assert_size_internal(nr_rows, nr_cols);
00536 #endif
00537 }
00538
00539
00540
00541 void assert_finite() const
00542 {
00543 #ifndef NDEBUG
00544 assert_finite_internal();
00545 #endif
00546 }
00547
00548
00549
00550
00551 bool read_ascii(vcl_istream& s);
00552
00553
00554
00555
00556
00557 T const* data_block () const { return data_[0]; }
00558
00559
00560
00561 T * data_block () { return data_[0]; }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577 vnl_matrix_ref<T> as_ref() { return vnl_matrix_ref<T>( num_rows, num_cols, data_block() ); }
00578
00579
00580
00581
00582
00583
00584 const vnl_matrix_ref<T> as_ref() const { return vnl_matrix_ref<T>( num_rows, num_cols, const_cast<T*>(data_block()) ); }
00585
00586
00587
00588
00589
00590 operator const vnl_matrix_ref<T>() const { return vnl_matrix_ref<T>( num_rows, num_cols, const_cast<T*>(data_block()) ); }
00591
00592
00593 const vnl_matrix<T> as_matrix() const { return vnl_matrix<T>(const_cast<T*>(data_block()),num_rows,num_cols); }
00594
00595
00596
00597 typedef T element_type;
00598
00599
00600 typedef T *iterator;
00601
00602 iterator begin() { return data_[0]; }
00603
00604 iterator end() { return begin() + size(); }
00605
00606
00607 typedef T const *const_iterator;
00608
00609 const_iterator begin() const { return data_[0]; }
00610
00611 const_iterator end() const { return begin() + size(); }
00612
00613
00614
00615
00616 bool operator_eq (vnl_matrix_fixed const & rhs) const
00617 {
00618 return equal( this->data_block(), rhs.data_block() );
00619 }
00620
00621
00622 bool operator==(vnl_matrix<T> const &that) const { return this->operator_eq(that); }
00623
00624
00625 bool operator!=(vnl_matrix<T> const &that) const { return !this->operator_eq(that); }
00626
00627
00628 void print(vcl_ostream& os) const;
00629
00630
00631
00632
00633
00634
00635
00636
00637 static void add( const T* a, const T* b, T* r );
00638 static void add( const T* a, T b, T* r );
00639 static void sub( const T* a, const T* b, T* r );
00640 static void sub( const T* a, T b, T* r );
00641 static void sub( T a, const T* b, T* r );
00642 static void mul( const T* a, const T* b, T* r );
00643 static void mul( const T* a, T b, T* r );
00644 static void div( const T* a, const T* b, T* r );
00645 static void div( const T* a, T b, T* r );
00646
00647 static bool equal( const T* a, const T* b );
00648
00649 private:
00650 void assert_finite_internal() const;
00651
00652 void assert_size_internal(unsigned, unsigned) const;
00653 };
00654
00655 #undef VNL_MATRIX_FIXED_VCL60_WORKAROUND
00656
00657
00658
00659
00660
00661
00662
00663
00664 template <class T, unsigned m, unsigned n>
00665 inline
00666 vnl_matrix_fixed<T,m,n> operator+( const vnl_matrix_fixed<T,m,n>& mat1, const vnl_matrix_fixed<T,m,n>& mat2 )
00667 {
00668 vnl_matrix_fixed<T,m,n> r;
00669 vnl_matrix_fixed<T,m,n>::add( mat1.data_block(), mat2.data_block(), r.data_block() );
00670 return r;
00671 }
00672
00673 template <class T, unsigned m, unsigned n>
00674 inline
00675 vnl_matrix_fixed<T,m,n> operator+( const vnl_matrix_fixed<T,m,n>& mat, T s )
00676 {
00677 vnl_matrix_fixed<T,m,n> r;
00678 vnl_matrix_fixed<T,m,n>::add( mat.data_block(), s, r.data_block() );
00679 return r;
00680 }
00681
00682 template <class T, unsigned m, unsigned n>
00683 inline
00684 vnl_matrix_fixed<T,m,n> operator+( const T& s,
00685 const vnl_matrix_fixed<T,m,n>& mat )
00686 {
00687 vnl_matrix_fixed<T,m,n> r;
00688 vnl_matrix_fixed<T,m,n>::add( mat.data_block(), s, r.data_block() );
00689 return r;
00690 }
00691
00692 template <class T, unsigned m, unsigned n>
00693 inline
00694 vnl_matrix_fixed<T,m,n> operator-( const vnl_matrix_fixed<T,m,n>& mat1, const vnl_matrix_fixed<T,m,n>& mat2 )
00695 {
00696 vnl_matrix_fixed<T,m,n> r;
00697 vnl_matrix_fixed<T,m,n>::sub( mat1.data_block(), mat2.data_block(), r.data_block() );
00698 return r;
00699 }
00700
00701 template <class T, unsigned m, unsigned n>
00702 inline
00703 vnl_matrix_fixed<T,m,n> operator-( const vnl_matrix_fixed<T,m,n>& mat, T s )
00704 {
00705 vnl_matrix_fixed<T,m,n> r;
00706 vnl_matrix_fixed<T,m,n>::sub( mat.data_block(), s, r.data_block() );
00707 return r;
00708 }
00709
00710 template <class T, unsigned m, unsigned n>
00711 inline
00712 vnl_matrix_fixed<T,m,n> operator-( const T& s,
00713 const vnl_matrix_fixed<T,m,n>& mat )
00714 {
00715 vnl_matrix_fixed<T,m,n> r;
00716 vnl_matrix_fixed<T,m,n>::sub( s, mat.data_block(), r.data_block() );
00717 return r;
00718 }
00719
00720 template <class T, unsigned m, unsigned n>
00721 inline
00722 vnl_matrix_fixed<T,m,n> operator*( const vnl_matrix_fixed<T,m,n>& mat, T s )
00723 {
00724 vnl_matrix_fixed<T,m,n> r;
00725 vnl_matrix_fixed<T,m,n>::mul( mat.data_block(), s, r.data_block() );
00726 return r;
00727 }
00728
00729 template <class T, unsigned m, unsigned n>
00730 inline
00731 vnl_matrix_fixed<T,m,n> operator*( const T& s,
00732 const vnl_matrix_fixed<T,m,n>& mat )
00733 {
00734 vnl_matrix_fixed<T,m,n> r;
00735 vnl_matrix_fixed<T,m,n>::mul( mat.data_block(), s, r.data_block() );
00736 return r;
00737 }
00738
00739 template <class T, unsigned m, unsigned n>
00740 inline
00741 vnl_matrix_fixed<T,m,n> operator/( const vnl_matrix_fixed<T,m,n>& mat, T s )
00742 {
00743 vnl_matrix_fixed<T,m,n> r;
00744 vnl_matrix_fixed<T,m,n>::div( mat.data_block(), s, r.data_block() );
00745 return r;
00746 }
00747
00748
00749 template <class T, unsigned m, unsigned n>
00750 inline
00751 vnl_matrix_fixed<T,m,n> element_product( const vnl_matrix_fixed<T,m,n>& mat1,
00752 const vnl_matrix_fixed<T,m,n>& mat2 )
00753 {
00754 vnl_matrix_fixed<T,m,n> r;
00755 vnl_matrix_fixed<T,m,n>::mul( mat1.data_block(), mat2.data_block(), r.data_block() );
00756 return r;
00757 }
00758
00759
00760 template <class T, unsigned m, unsigned n>
00761 inline
00762 vnl_matrix_fixed<T,m,n> element_quotient( const vnl_matrix_fixed<T,m,n>& mat1,
00763 const vnl_matrix_fixed<T,m,n>& mat2)
00764 {
00765 vnl_matrix_fixed<T,m,n> r;
00766 vnl_matrix_fixed<T,m,n>::div( mat1.data_block(), mat2.data_block(), r.data_block() );
00767 return r;
00768 }
00769
00770
00771
00772
00773
00774 template <class T, unsigned M, unsigned N>
00775 inline
00776 vnl_vector_fixed<T, M>
00777 vnl_matrix_fixed_mat_vec_mult(const vnl_matrix_fixed<T, M, N>& a,
00778 const vnl_vector_fixed<T, N>& b)
00779 {
00780 vnl_vector_fixed<T, M> out;
00781 for (unsigned i = 0; i < M; ++i)
00782 {
00783 T accum = a(i,0) * b(0);
00784 for (unsigned k = 1; k < N; ++k)
00785 accum += a(i,k) * b(k);
00786 out(i) = accum;
00787 }
00788 return out;
00789 }
00790
00791 template <class T, unsigned M, unsigned N>
00792 inline
00793 vnl_vector_fixed<T, N>
00794 vnl_matrix_fixed_vec_mat_mult(const vnl_vector_fixed<T, M>& a,
00795 const vnl_matrix_fixed<T, M, N>& b)
00796 {
00797 vnl_vector_fixed<T, N> out;
00798 for (unsigned i = 0; i < N; ++i)
00799 {
00800 T accum = a(0) * b(0,i);
00801 for (unsigned k = 1; k < M; ++k)
00802 accum += a(k) * b(k,i);
00803 out(i) = accum;
00804 }
00805 return out;
00806 }
00807
00808
00809 template <class T, unsigned M, unsigned N, unsigned O>
00810 inline
00811 vnl_matrix_fixed<T, M, O>
00812 vnl_matrix_fixed_mat_mat_mult(const vnl_matrix_fixed<T, M, N>& a,
00813 const vnl_matrix_fixed<T, N, O>& b)
00814 {
00815 vnl_matrix_fixed<T, M, O> out;
00816 for (unsigned i = 0; i < M; ++i)
00817 for (unsigned j = 0; j < O; ++j)
00818 {
00819 T accum = a(i,0) * b(0,j);
00820 for (unsigned k = 1; k < N; ++k)
00821 accum += a(i,k) * b(k,j);
00822 out(i,j) = accum;
00823 }
00824 return out;
00825 }
00826
00827 #ifndef VCL_VC_6
00828
00829
00830
00831
00832
00833 template <class T, unsigned M, unsigned N>
00834 inline
00835 vnl_vector_fixed<T, M> operator*(const vnl_matrix_fixed<T, M, N>& a, const vnl_vector_fixed<T, N>& b)
00836 {
00837 return vnl_matrix_fixed_mat_vec_mult(a, b);
00838 }
00839
00840
00841
00842
00843 template <class T, unsigned M, unsigned N>
00844 inline
00845 vnl_vector_fixed<T, N> operator*(const vnl_vector_fixed<T, M>& a, const vnl_matrix_fixed<T, M, N>& b)
00846 {
00847 return vnl_matrix_fixed_vec_mat_mult(a, b);
00848 }
00849
00850
00851
00852 template <class T, unsigned M, unsigned N, unsigned O>
00853 inline
00854 vnl_matrix_fixed<T, M, O> operator*(const vnl_matrix_fixed<T, M, N>& a, const vnl_matrix_fixed<T, N, O>& b)
00855 {
00856 return vnl_matrix_fixed_mat_mat_mult(a, b);
00857 }
00858 #endif // VCL_VC_6
00859
00860
00861
00862
00863
00864
00865 template <class T, unsigned m, unsigned n>
00866 inline vnl_matrix<T> operator+( const vnl_matrix_fixed<T,m,n>& a, const vnl_matrix<T>& b )
00867 {
00868 return a.as_ref() + b;
00869 }
00870
00871 template <class T, unsigned m, unsigned n>
00872 inline vnl_matrix<T> operator+( const vnl_matrix<T>& a, const vnl_matrix_fixed<T,m,n>& b )
00873 {
00874 return a + b.as_ref();
00875 }
00876
00877 template <class T, unsigned m, unsigned n>
00878 inline vnl_matrix<T> operator-( const vnl_matrix_fixed<T,m,n>& a, const vnl_matrix<T>& b )
00879 {
00880 return a.as_ref() - b;
00881 }
00882
00883 template <class T, unsigned m, unsigned n>
00884 inline vnl_matrix<T> operator-( const vnl_matrix<T>& a, const vnl_matrix_fixed<T,m,n>& b )
00885 {
00886 return a - b.as_ref();
00887 }
00888
00889 template <class T, unsigned m, unsigned n>
00890 inline vnl_matrix<T> operator*( const vnl_matrix_fixed<T,m,n>& a, const vnl_matrix<T>& b )
00891 {
00892 return a.as_ref() * b;
00893 }
00894
00895 template <class T, unsigned m, unsigned n>
00896 inline vnl_matrix<T> operator*( const vnl_matrix<T>& a, const vnl_matrix_fixed<T,m,n>& b )
00897 {
00898 return a * b.as_ref();
00899 }
00900
00901 template <class T, unsigned m, unsigned n>
00902 inline vnl_vector<T> operator*( const vnl_matrix_fixed<T,m,n>& a, const vnl_vector<T>& b )
00903 {
00904 return a.as_ref() * b;
00905 }
00906
00907 template <class T, unsigned n>
00908 inline vnl_vector<T> operator*( const vnl_matrix<T>& a, const vnl_vector_fixed<T,n>& b )
00909 {
00910 return a * b.as_ref();
00911 }
00912
00913
00914
00915
00916 template <class T, unsigned m, unsigned n>
00917 inline
00918 vcl_ostream& operator<< (vcl_ostream& os, vnl_matrix_fixed<T,m,n> const& mat)
00919 {
00920 mat.print(os);
00921 return os;
00922 }
00923
00924 template <class T, unsigned m, unsigned n>
00925 inline
00926 vcl_istream& operator>> (vcl_istream& is, vnl_matrix_fixed<T,m,n>& mat)
00927 {
00928 mat.read_ascii(is);
00929 return is;
00930 }
00931
00932
00933
00934
00935
00936
00937
00938 #if defined(VCL_VC_6) && !defined(__GCCXML__)
00939
00940 template<class T, unsigned m, class FixedVector>
00941 struct outer_product_fixed_type_helper
00942 {
00943 typedef vnl_matrix_fixed<T,m,FixedVector::SIZE> result_matrix;
00944 };
00945
00946 template<class V1, class V2, class RM>
00947 struct outer_product_fixed_calc_helper
00948 {
00949 static RM calc( V1 const& a, V2 const& b );
00950 };
00951
00952 template <class T, unsigned m, class SecondFixedVector>
00953 outer_product_fixed_type_helper<T,m,SecondFixedVector>::result_matrix
00954 outer_product(vnl_vector_fixed<T,m> const& a, SecondFixedVector const& b)
00955 {
00956 typedef vnl_vector_fixed<T,m> VecA;
00957 typedef vnl_vector_fixed<T,SecondFixedVector::SIZE> VecB;
00958 typedef outer_product_fixed_type_helper<T,m,SecondFixedVector>::result_matrix ResultMat;
00959 return outer_product_fixed_calc_helper<VecA,VecB,ResultMat>::calc(a,b);
00960 }
00961
00962 #else // no need for VC6 workaround for outer_product
00963
00964
00965
00966 template <class T, unsigned m, unsigned n>
00967 vnl_matrix_fixed<T,m,n> outer_product(vnl_vector_fixed<T,m> const& a, vnl_vector_fixed<T,n> const& b);
00968
00969 #endif // VC6 workaround for outer_product
00970
00971 #define VNL_MATRIX_FIXED_INSTANTIATE(T, M, N) \
00972 extern "please include vnl/vnl_matrix_fixed.txx instead"
00973
00974 #endif // vnl_matrix_fixed_h_