00001
00002 #ifndef vnl_sym_matrix_h_
00003 #define vnl_sym_matrix_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007
00008
00009
00010
00011
00012
00013 #include <vcl_cassert.h>
00014 #include <vcl_iosfwd.h>
00015 #include <vnl/vnl_vector.h>
00016 #include <vnl/vnl_matrix.h>
00017 #include <vnl/vnl_c_vector.h>
00018
00019
00020
00021
00022
00023 export
00024 template <class T>
00025 class vnl_sym_matrix
00026 {
00027 public:
00028
00029 vnl_sym_matrix(): data_(0), index_(0), nn_(0) {}
00030
00031
00032 explicit vnl_sym_matrix(unsigned nn):
00033 data_(vnl_c_vector<T>::allocate_T(nn * (nn + 1) / 2)),
00034 index_(vnl_c_vector<T>::allocate_Tptr(nn)),
00035 nn_(nn) { setup_index(); }
00036
00037
00038
00039
00040 inline vnl_sym_matrix(T const * data, unsigned nn);
00041
00042
00043 inline vnl_sym_matrix(unsigned nn, const T & value);
00044
00045
00046
00047 inline explicit vnl_sym_matrix(vnl_matrix<T> const& that);
00048
00049
00050 inline vnl_sym_matrix(vnl_sym_matrix<T> const& that);
00051
00052 ~vnl_sym_matrix()
00053 { vnl_c_vector<T>::deallocate(data_, size());
00054 vnl_c_vector<T>::deallocate(index_, nn_);}
00055
00056 vnl_sym_matrix<T>& operator=(vnl_sym_matrix<T> const& that);
00057
00058
00059
00060
00061 vnl_sym_matrix<T>& operator*=(T v) { vnl_c_vector<T>::scale(data_, data_, size(), v); return *this; }
00062
00063 vnl_sym_matrix<T>& operator/=(T v) { vnl_c_vector<T>::scale(data_, data_, size(), ((T)1)/v); return *this; }
00064
00065
00066
00067
00068 T operator () (unsigned i, unsigned j) const {
00069 return (i > j) ? index_[i][j] : index_[j][i];
00070 }
00071
00072 T& operator () (unsigned i, unsigned j) {
00073 return (i > j) ? index_[i][j] : index_[j][i];
00074 }
00075
00076
00077
00078 const T* operator [] (unsigned i) const {
00079 assert (i < nn_);
00080 return index_[i];
00081 }
00082
00083
00084 T fast (unsigned i, unsigned j) const {
00085 assert (i >= j);
00086 return index_[i][j];
00087 }
00088
00089
00090 T& fast (unsigned i, unsigned j) {
00091 assert (i >= j);
00092 return index_[i][j];
00093 }
00094
00095
00096
00097 typedef T* iterator;
00098 inline iterator begin() { return data_; }
00099 inline iterator end() { return data_ + size(); }
00100 typedef const T* const_iterator;
00101 inline const_iterator begin() const { return data_; }
00102 inline const_iterator end() const { return data_ + size(); }
00103
00104 unsigned long size() const { return nn_ * (nn_ + 1) / 2; }
00105 unsigned rows() const { return nn_; }
00106 unsigned cols() const { return nn_; }
00107 unsigned columns() const { return nn_; }
00108
00109
00110 inline vnl_matrix<T> as_matrix() const;
00111
00112
00113
00114 inline void set_size(int n);
00115
00116
00117
00118 T* data_block() { return data_; }
00119
00120 T const* data_block() const { return data_; }
00121
00122
00123
00124 void set_half_row (const vnl_vector<T> &half_row, unsigned i);
00125
00126
00127
00128 vnl_sym_matrix<T>& update (vnl_sym_matrix<T> const& m, unsigned diag_start=0);
00129
00130
00131 void swap(vnl_sym_matrix &m);
00132
00133 protected:
00134
00135 inline void setup_index() {
00136 T * data = data_;
00137 for (unsigned i=0; i< nn_; ++i) { index_[i] = data; data += i+1; }
00138 }
00139
00140 T* data_;
00141 T** index_;
00142 unsigned nn_;
00143 };
00144
00145
00146
00147 template <class T> vcl_ostream& operator<< (vcl_ostream&, vnl_sym_matrix<T> const&);
00148
00149
00150 template <class T>
00151 inline vnl_sym_matrix<T>::vnl_sym_matrix(T const * data, unsigned nn):
00152 data_(vnl_c_vector<T>::allocate_T(nn * (nn + 1) / 2)),
00153 index_(vnl_c_vector<T>::allocate_Tptr(nn)),
00154 nn_(nn)
00155 {
00156 setup_index();
00157 for (unsigned i = 0; i < nn_; ++i)
00158 for (unsigned j = 0; j <= i; ++j)
00159 fast(i,j) = *(data++);
00160 }
00161
00162 template <class T>
00163 inline vnl_sym_matrix<T>::vnl_sym_matrix(unsigned nn, const T & value):
00164 data_(vnl_c_vector<T>::allocate_T(nn * (nn + 1) / 2)),
00165 index_(vnl_c_vector<T>::allocate_Tptr(nn)),
00166 nn_(nn)
00167 {
00168 setup_index();
00169 vnl_c_vector<T>::fill(data_, size(), value);
00170 }
00171
00172
00173 template <class T>
00174 inline vnl_sym_matrix<T>::vnl_sym_matrix(vnl_matrix<T> const& that):
00175 data_(vnl_c_vector<T>::allocate_T(that.rows() * (that.rows() + 1) / 2)),
00176 index_(vnl_c_vector<T>::allocate_Tptr(that.rows())),
00177 nn_(that.rows())
00178 {
00179 setup_index();
00180 assert (nn_ == that.cols());
00181 for (unsigned i = 0; i < nn_; ++i)
00182 for (unsigned j = 0; j <= i; ++j)
00183 {
00184 assert( that(i,j) == that(j,i) );
00185 fast(i,j) = that(i,j);
00186 }
00187 }
00188
00189 template <class T>
00190 inline vnl_sym_matrix<T>::vnl_sym_matrix(vnl_sym_matrix<T> const& that):
00191 data_(0), index_(0), nn_(0)
00192 {
00193 set_size(that.rows());
00194 update(that);
00195 }
00196
00197
00198 template <class T>
00199 inline vnl_matrix<T> vnl_sym_matrix<T>::as_matrix() const
00200 {
00201 vnl_matrix<T> ret(nn_, nn_);
00202 for (unsigned i = 0; i < nn_; ++i)
00203 for (unsigned j = 0; j <= i; ++j)
00204 ret(i,j) = ret(j,i) = fast(i,j);
00205 return ret;
00206 }
00207
00208
00209 template <class T>
00210 inline void vnl_sym_matrix<T>::set_size(int n)
00211 {
00212 if (n == (int)nn_) return;
00213
00214 vnl_c_vector<T>::deallocate(data_, size());
00215 vnl_c_vector<T>::deallocate(index_, nn_);
00216
00217 nn_ = n;
00218 data_ = vnl_c_vector<T>::allocate_T(size());
00219 index_ = vnl_c_vector<T>::allocate_Tptr(n);
00220
00221 setup_index();
00222 }
00223
00224 template <class T>
00225 bool operator==(const vnl_sym_matrix<T> &a, const vnl_sym_matrix<T> &b);
00226
00227 template <class T>
00228 bool operator==(const vnl_sym_matrix<T> &a, const vnl_matrix<T> &b);
00229
00230 template <class T>
00231 bool operator==(const vnl_matrix<T> &a, const vnl_sym_matrix<T> &b);
00232
00233
00234
00235 template <class T>
00236 void swap(vnl_sym_matrix<T> &a, vnl_sym_matrix<T> &b)
00237 { a.swap(b); }
00238
00239
00240 #endif // vnl_sym_matrix_h_