| [0b990d] | 1 | // | 
|---|
|  | 2 | // abstract.h | 
|---|
|  | 3 | // | 
|---|
|  | 4 | // Copyright (C) 1996 Limit Point Systems, Inc. | 
|---|
|  | 5 | // | 
|---|
|  | 6 | // Author: Curtis Janssen <cljanss@limitpt.com> | 
|---|
|  | 7 | // Maintainer: LPS | 
|---|
|  | 8 | // | 
|---|
|  | 9 | // This file is part of the SC Toolkit. | 
|---|
|  | 10 | // | 
|---|
|  | 11 | // The SC Toolkit is free software; you can redistribute it and/or modify | 
|---|
|  | 12 | // it under the terms of the GNU Library General Public License as published by | 
|---|
|  | 13 | // the Free Software Foundation; either version 2, or (at your option) | 
|---|
|  | 14 | // any later version. | 
|---|
|  | 15 | // | 
|---|
|  | 16 | // The SC Toolkit is distributed in the hope that it will be useful, | 
|---|
|  | 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
|  | 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
|  | 19 | // GNU Library General Public License for more details. | 
|---|
|  | 20 | // | 
|---|
|  | 21 | // You should have received a copy of the GNU Library General Public License | 
|---|
|  | 22 | // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to | 
|---|
|  | 23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | 
|---|
|  | 24 | // | 
|---|
|  | 25 | // The U.S. Government is granted a limited license as per AL 91-7. | 
|---|
|  | 26 | // | 
|---|
|  | 27 |  | 
|---|
|  | 28 | #ifndef _math_scmat_abstract_h | 
|---|
|  | 29 | #define _math_scmat_abstract_h | 
|---|
|  | 30 |  | 
|---|
|  | 31 | #ifdef __GNUC__ | 
|---|
|  | 32 | #pragma interface | 
|---|
|  | 33 | #endif | 
|---|
|  | 34 |  | 
|---|
|  | 35 | #include <util/group/message.h> | 
|---|
|  | 36 |  | 
|---|
|  | 37 | #include <util/state/state.h> | 
|---|
|  | 38 | #include <math/scmat/dim.h> | 
|---|
|  | 39 | #include <math/scmat/block.h> | 
|---|
|  | 40 | #include <iostream> | 
|---|
|  | 41 |  | 
|---|
|  | 42 | namespace sc { | 
|---|
|  | 43 |  | 
|---|
|  | 44 | class SCMatrix; | 
|---|
|  | 45 | class SymmSCMatrix; | 
|---|
|  | 46 | class DiagSCMatrix; | 
|---|
|  | 47 | class SCVector; | 
|---|
|  | 48 |  | 
|---|
|  | 49 | class SCElementOp; | 
|---|
|  | 50 | class SCElementOp2; | 
|---|
|  | 51 | class SCElementOp3; | 
|---|
|  | 52 |  | 
|---|
|  | 53 | class RefSCDimension; | 
|---|
|  | 54 |  | 
|---|
|  | 55 | /** The SCMatrixKit abstract class acts as a factory for producing | 
|---|
|  | 56 | matrices.  By using one of these, the program makes sure that all of the | 
|---|
|  | 57 | matrices are consistent.  */ | 
|---|
|  | 58 | class SCMatrixKit: public DescribedClass { | 
|---|
|  | 59 | protected: | 
|---|
|  | 60 | Ref<MessageGrp> grp_; | 
|---|
|  | 61 |  | 
|---|
|  | 62 | public: | 
|---|
|  | 63 | SCMatrixKit(); | 
|---|
|  | 64 | SCMatrixKit(const Ref<KeyVal>&); | 
|---|
|  | 65 | ~SCMatrixKit(); | 
|---|
|  | 66 |  | 
|---|
|  | 67 | // these members are default in local.cc | 
|---|
|  | 68 | /** This returns a LocalSCMatrixKit, unless the | 
|---|
|  | 69 | default has been changed with set_default_matrixkit. */ | 
|---|
|  | 70 | static SCMatrixKit* default_matrixkit(); | 
|---|
|  | 71 | static void set_default_matrixkit(const Ref<SCMatrixKit> &); | 
|---|
|  | 72 |  | 
|---|
|  | 73 | Ref<MessageGrp> messagegrp() const; | 
|---|
|  | 74 |  | 
|---|
|  | 75 | /// Given the dimensions, create matrices or vectors. | 
|---|
|  | 76 | virtual SCMatrix* matrix(const RefSCDimension&,const RefSCDimension&) = 0; | 
|---|
|  | 77 | virtual SymmSCMatrix* symmmatrix(const RefSCDimension&) = 0; | 
|---|
|  | 78 | virtual DiagSCMatrix* diagmatrix(const RefSCDimension&) = 0; | 
|---|
|  | 79 | virtual SCVector* vector(const RefSCDimension&) = 0; | 
|---|
|  | 80 |  | 
|---|
|  | 81 | /** Given the dimensions and a StateIn object, | 
|---|
|  | 82 | restore matrices or vectors. */ | 
|---|
|  | 83 | SCMatrix* restore_matrix(StateIn&, | 
|---|
|  | 84 | const RefSCDimension&, | 
|---|
|  | 85 | const RefSCDimension&); | 
|---|
|  | 86 | SymmSCMatrix* restore_symmmatrix(StateIn&, | 
|---|
|  | 87 | const RefSCDimension&); | 
|---|
|  | 88 | DiagSCMatrix* restore_diagmatrix(StateIn&, | 
|---|
|  | 89 | const RefSCDimension&); | 
|---|
|  | 90 | SCVector* restore_vector(StateIn&, | 
|---|
|  | 91 | const RefSCDimension&); | 
|---|
|  | 92 | }; | 
|---|
|  | 93 |  | 
|---|
|  | 94 |  | 
|---|
|  | 95 | /** The SCVector class is the abstract base class for | 
|---|
|  | 96 | double valued vectors. */ | 
|---|
|  | 97 | class SCVector: public DescribedClass { | 
|---|
|  | 98 | protected: | 
|---|
|  | 99 | RefSCDimension d; | 
|---|
|  | 100 | Ref<SCMatrixKit> kit_; | 
|---|
|  | 101 | public: | 
|---|
|  | 102 | SCVector(const RefSCDimension&, SCMatrixKit *); | 
|---|
|  | 103 |  | 
|---|
|  | 104 | /// Save and restore this in an implementation independent way. | 
|---|
|  | 105 | virtual void save(StateOut&); | 
|---|
|  | 106 | virtual void restore(StateIn&); | 
|---|
|  | 107 |  | 
|---|
|  | 108 | /// Return the SCMatrixKit used to create this object. | 
|---|
|  | 109 | Ref<SCMatrixKit> kit() const { return kit_; } | 
|---|
|  | 110 |  | 
|---|
|  | 111 | // concrete functions (some can be overridden) | 
|---|
|  | 112 | /// Return a vector with the same dimension and same elements. | 
|---|
|  | 113 | virtual SCVector* copy(); | 
|---|
|  | 114 | /// Return a vector with the same dimension but uninitialized memory. | 
|---|
|  | 115 | virtual SCVector* clone(); | 
|---|
|  | 116 |  | 
|---|
|  | 117 | virtual ~SCVector(); | 
|---|
|  | 118 | /// Return the length of the vector. | 
|---|
|  | 119 | int n() const { return d->n(); } | 
|---|
|  | 120 | /// Return the maximum absolute value element of this vector. | 
|---|
|  | 121 | virtual double maxabs() const; | 
|---|
|  | 122 | /// Normalize this. | 
|---|
|  | 123 | virtual void normalize(); | 
|---|
|  | 124 | /// Assign each element to a random number between -1 and 1 | 
|---|
|  | 125 | virtual void randomize(); | 
|---|
|  | 126 | /// Assign all elements of this to val. | 
|---|
|  | 127 | void assign(double val) { assign_val(val); } | 
|---|
|  | 128 | /// Assign element i to v[i] for all i. | 
|---|
|  | 129 | void assign(const double* v) { assign_p(v); } | 
|---|
|  | 130 | /** Make this have the same elements as v.  The dimensions must | 
|---|
|  | 131 | match. */ | 
|---|
|  | 132 | void assign(SCVector* v) { assign_v(v); } | 
|---|
|  | 133 | /// Overridden to implement the assign functions. | 
|---|
|  | 134 | virtual void assign_val(double val); | 
|---|
|  | 135 | virtual void assign_p(const double* v); | 
|---|
|  | 136 | virtual void assign_v(SCVector *v); | 
|---|
|  | 137 | /// Assign v[i] to element i for all i. | 
|---|
|  | 138 | virtual void convert(double* v) const; | 
|---|
|  | 139 | /** Convert an SCVector of a different specialization | 
|---|
|  | 140 | to this specialization and possibly accumulate the data. */ | 
|---|
|  | 141 | virtual void convert(SCVector*); | 
|---|
|  | 142 | virtual void convert_accumulate(SCVector*); | 
|---|
|  | 143 | /// Multiply each element by val. | 
|---|
|  | 144 | virtual void scale(double val); | 
|---|
|  | 145 |  | 
|---|
|  | 146 | /// Return the RefSCDimension corresponding to this vector. | 
|---|
|  | 147 | RefSCDimension dim() const { return d; } | 
|---|
|  | 148 | /// Set element i to val. | 
|---|
|  | 149 | virtual void set_element(int i,double val) = 0; | 
|---|
|  | 150 | /// Add val to element i. | 
|---|
|  | 151 | virtual void accumulate_element(int,double) = 0; | 
|---|
|  | 152 | /// Return the value of element i. | 
|---|
|  | 153 | virtual double get_element(int i) const = 0; | 
|---|
|  | 154 | /// Sum the result of m times v into this. | 
|---|
|  | 155 | void accumulate_product(SymmSCMatrix* m, SCVector* v) | 
|---|
|  | 156 | { accumulate_product_sv(m,v); } | 
|---|
|  | 157 | void accumulate_product(SCMatrix* m, SCVector* v) | 
|---|
|  | 158 | {  accumulate_product_rv(m,v); } | 
|---|
|  | 159 | virtual void accumulate_product_sv(SymmSCMatrix* m, SCVector* v); | 
|---|
|  | 160 | virtual void accumulate_product_rv(SCMatrix* m, SCVector* v) = 0; | 
|---|
|  | 161 | /// Sum v into this. | 
|---|
|  | 162 | virtual void accumulate(const SCVector*v) = 0; | 
|---|
|  | 163 | /// Sum m into this.  One of m's dimensions must be 1. | 
|---|
|  | 164 | virtual void accumulate(const SCMatrix*m) = 0; | 
|---|
|  | 165 | /// Return the dot product. | 
|---|
|  | 166 | virtual double scalar_product(SCVector*) = 0; | 
|---|
|  | 167 | /// Perform the element operation op on each element of this. | 
|---|
|  | 168 | virtual void element_op(const Ref<SCElementOp>&) = 0; | 
|---|
|  | 169 | virtual void element_op(const Ref<SCElementOp2>&, | 
|---|
|  | 170 | SCVector*) = 0; | 
|---|
|  | 171 | virtual void element_op(const Ref<SCElementOp3>&, | 
|---|
|  | 172 | SCVector*,SCVector*) = 0; | 
|---|
|  | 173 | /// Print out the vector. | 
|---|
|  | 174 | void print(std::ostream&o=ExEnv::out0()) const; | 
|---|
|  | 175 | void print(const char* title=0,std::ostream&out=ExEnv::out0(),int=10) const; | 
|---|
|  | 176 | virtual void vprint(const char*title=0,std::ostream&out=ExEnv::out0(), | 
|---|
|  | 177 | int=10) const = 0; | 
|---|
|  | 178 |  | 
|---|
|  | 179 | /// Returns the message group used by the matrix kit | 
|---|
|  | 180 | Ref<MessageGrp> messagegrp() const; | 
|---|
|  | 181 |  | 
|---|
|  | 182 | /** Returns iterators for the local (rapidly accessible) blocks used in | 
|---|
|  | 183 | this vector.  Only one iterator is allowed for a matrix is it has | 
|---|
|  | 184 | Accum or Write access is allowed.  Multiple Read iterators are | 
|---|
|  | 185 | permitted. */ | 
|---|
|  | 186 | virtual Ref<SCMatrixSubblockIter> local_blocks( | 
|---|
|  | 187 | SCMatrixSubblockIter::Access) = 0; | 
|---|
|  | 188 | /// Returns iterators for the all blocks used in this vector. | 
|---|
|  | 189 | virtual Ref<SCMatrixSubblockIter> all_blocks(SCMatrixSubblockIter::Access) = 0; | 
|---|
|  | 190 | }; | 
|---|
|  | 191 |  | 
|---|
|  | 192 | /** The SCMatrix class is the abstract base class for general double valued | 
|---|
|  | 193 | n by m matrices.  For symmetric matrices use SymmSCMatrix and for | 
|---|
|  | 194 | diagonal matrices use DiagSCMatrix. */ | 
|---|
|  | 195 | class SCMatrix: public DescribedClass { | 
|---|
|  | 196 | protected: | 
|---|
|  | 197 | RefSCDimension d1,d2; | 
|---|
|  | 198 | Ref<SCMatrixKit> kit_; | 
|---|
|  | 199 | public: | 
|---|
|  | 200 | // used to control transformations | 
|---|
|  | 201 | enum Transform { NormalTransform = 0, TransposeTransform = 1 }; | 
|---|
|  | 202 |  | 
|---|
|  | 203 | // concrete functions (some can be overridden) | 
|---|
|  | 204 | SCMatrix(const RefSCDimension&, const RefSCDimension&, SCMatrixKit *); | 
|---|
|  | 205 | virtual ~SCMatrix(); | 
|---|
|  | 206 |  | 
|---|
|  | 207 | /// Save and restore this in an implementation independent way. | 
|---|
|  | 208 | virtual void save(StateOut&); | 
|---|
|  | 209 | virtual void restore(StateIn&); | 
|---|
|  | 210 |  | 
|---|
|  | 211 | /// Return the SCMatrixKit used to create this object. | 
|---|
|  | 212 | Ref<SCMatrixKit> kit() const { return kit_; } | 
|---|
|  | 213 |  | 
|---|
|  | 214 | /// Return the number of rows. | 
|---|
|  | 215 | int nrow() const { return d1->n(); } | 
|---|
|  | 216 | /// Return the number of columns. | 
|---|
|  | 217 | int ncol() const { return d2->n(); } | 
|---|
|  | 218 | /// Return the maximum absolute value element. | 
|---|
|  | 219 | virtual double maxabs() const; | 
|---|
|  | 220 | /// Assign each element to a random number between -1 and 1 | 
|---|
|  | 221 | virtual void randomize(); | 
|---|
|  | 222 | /// Set all elements to val. | 
|---|
|  | 223 | void assign(double val) { assign_val(val); } | 
|---|
|  | 224 | /// Assign element i, j to m[ir*nrow()+j]. | 
|---|
|  | 225 | void assign(const double* m) { assign_p(m); } | 
|---|
|  | 226 | /// Assign element i, j to m[i][j]. | 
|---|
|  | 227 | void assign(const double** m) { assign_pp(m); } | 
|---|
|  | 228 | /// Make this have the same elements as m. The dimensions must match. | 
|---|
|  | 229 | void assign(SCMatrix* m) { assign_r(m); } | 
|---|
|  | 230 | /// Overridden to implement to assign members. | 
|---|
|  | 231 | virtual void assign_val(double val); | 
|---|
|  | 232 | virtual void assign_p(const double* m); | 
|---|
|  | 233 | virtual void assign_pp(const double** m); | 
|---|
|  | 234 | virtual void assign_r(SCMatrix* m); | 
|---|
|  | 235 | /** Like the assign members, but these write values to the | 
|---|
|  | 236 | arguments. */ | 
|---|
|  | 237 | virtual void convert(double*) const; | 
|---|
|  | 238 | virtual void convert(double**) const; | 
|---|
|  | 239 | /** Convert an SCMatrix of a different specialization to this | 
|---|
|  | 240 | specialization and possibly accumulate the data. */ | 
|---|
|  | 241 | virtual void convert(SCMatrix*); | 
|---|
|  | 242 | virtual void convert_accumulate(SCMatrix*); | 
|---|
|  | 243 | /// Multiply all elements by val. | 
|---|
|  | 244 | virtual void scale(double val); | 
|---|
|  | 245 | /// Scale the diagonal elements by val. | 
|---|
|  | 246 | virtual void scale_diagonal(double val); | 
|---|
|  | 247 | /// Shift the diagonal elements by val. | 
|---|
|  | 248 | virtual void shift_diagonal(double val); | 
|---|
|  | 249 | /// Make this equal to the unit matrix. | 
|---|
|  | 250 | virtual void unit(); | 
|---|
|  | 251 | /// Return a matrix with the same dimension and same elements. | 
|---|
|  | 252 | virtual SCMatrix* copy(); | 
|---|
|  | 253 | /// Return a matrix with the same dimension but uninitialized memory. | 
|---|
|  | 254 | virtual SCMatrix* clone(); | 
|---|
|  | 255 |  | 
|---|
|  | 256 | // pure virtual functions | 
|---|
|  | 257 | /// Return the row or column dimension. | 
|---|
|  | 258 | RefSCDimension rowdim() const { return d1; } | 
|---|
|  | 259 | RefSCDimension coldim() const { return d2; } | 
|---|
|  | 260 | /// Return or modify an element. | 
|---|
|  | 261 | virtual double get_element(int,int) const = 0; | 
|---|
|  | 262 | virtual void set_element(int,int,double) = 0; | 
|---|
|  | 263 | virtual void accumulate_element(int,int,double) = 0; | 
|---|
|  | 264 |  | 
|---|
|  | 265 | /** Return a subblock of this.  The subblock is defined as | 
|---|
|  | 266 | the rows starting at br and ending at er, and the | 
|---|
|  | 267 | columns beginning at bc and ending at ec. */ | 
|---|
|  | 268 | virtual SCMatrix * get_subblock(int br, int er, int bc, int ec) =0; | 
|---|
|  | 269 |  | 
|---|
|  | 270 | /// Assign m to a subblock of this. | 
|---|
|  | 271 | virtual void assign_subblock(SCMatrix *m, int, int, int, int, int=0, int=0) =0; | 
|---|
|  | 272 |  | 
|---|
|  | 273 | /// Sum m into a subblock of this. | 
|---|
|  | 274 | virtual void accumulate_subblock(SCMatrix *m, int, int, int, int, int=0,int=0) =0; | 
|---|
|  | 275 |  | 
|---|
|  | 276 | /// Return a row or column of this. | 
|---|
|  | 277 | virtual SCVector * get_row(int i) =0; | 
|---|
|  | 278 | virtual SCVector * get_column(int i) =0; | 
|---|
|  | 279 |  | 
|---|
|  | 280 | /// Assign v to a row or column of this. | 
|---|
|  | 281 | virtual void assign_row(SCVector *v, int i) =0; | 
|---|
|  | 282 | virtual void assign_column(SCVector *v, int i) =0; | 
|---|
|  | 283 |  | 
|---|
|  | 284 | /// Sum v to a row or column of this. | 
|---|
|  | 285 | virtual void accumulate_row(SCVector *v, int i) =0; | 
|---|
|  | 286 | virtual void accumulate_column(SCVector *v, int i) =0; | 
|---|
|  | 287 |  | 
|---|
|  | 288 | /// Sum m into this. | 
|---|
|  | 289 | virtual void accumulate(const SCMatrix* m) = 0; | 
|---|
|  | 290 | virtual void accumulate(const SymmSCMatrix* m) = 0; | 
|---|
|  | 291 | virtual void accumulate(const DiagSCMatrix* m) = 0; | 
|---|
|  | 292 | virtual void accumulate(const SCVector*) = 0; | 
|---|
|  | 293 | /// Sum into this the products of various vectors or matrices. | 
|---|
|  | 294 | virtual void accumulate_outer_product(SCVector*,SCVector*) = 0; | 
|---|
|  | 295 | void accumulate_product(SCMatrix*m1,SCMatrix*m2) | 
|---|
|  | 296 | { accumulate_product_rr(m1,m2); } | 
|---|
|  | 297 | void accumulate_product(SCMatrix*m1,SymmSCMatrix*m2) | 
|---|
|  | 298 | { accumulate_product_rs(m1,m2); } | 
|---|
|  | 299 | void accumulate_product(SCMatrix*m1,DiagSCMatrix*m2) | 
|---|
|  | 300 | { accumulate_product_rd(m1,m2); } | 
|---|
|  | 301 | void accumulate_product(SymmSCMatrix*m1,SCMatrix*m2) | 
|---|
|  | 302 | { accumulate_product_sr(m1,m2); } | 
|---|
|  | 303 | void accumulate_product(DiagSCMatrix*m1,SCMatrix*m2) | 
|---|
|  | 304 | { accumulate_product_dr(m1,m2); } | 
|---|
|  | 305 | void accumulate_product(SymmSCMatrix*m1,SymmSCMatrix*m2) | 
|---|
|  | 306 | { accumulate_product_ss(m1,m2); } | 
|---|
|  | 307 | virtual void accumulate_product_rr(SCMatrix*,SCMatrix*) = 0; | 
|---|
|  | 308 | virtual void accumulate_product_rs(SCMatrix*,SymmSCMatrix*); | 
|---|
|  | 309 | virtual void accumulate_product_rd(SCMatrix*,DiagSCMatrix*); | 
|---|
|  | 310 | virtual void accumulate_product_sr(SymmSCMatrix*,SCMatrix*); | 
|---|
|  | 311 | virtual void accumulate_product_dr(DiagSCMatrix*,SCMatrix*); | 
|---|
|  | 312 | virtual void accumulate_product_ss(SymmSCMatrix*,SymmSCMatrix*); | 
|---|
|  | 313 | /// Transpose this. | 
|---|
|  | 314 | virtual void transpose_this() = 0; | 
|---|
|  | 315 | /// Return the trace. | 
|---|
|  | 316 | virtual double trace() =0; | 
|---|
|  | 317 | /// Invert this. | 
|---|
|  | 318 | virtual double invert_this() = 0; | 
|---|
|  | 319 | /// Return the determinant of this.  this is overwritten. | 
|---|
|  | 320 | virtual double determ_this() = 0; | 
|---|
|  | 321 |  | 
|---|
|  | 322 | /** Compute the singular value decomposition for this, | 
|---|
|  | 323 | possibly destroying this. */ | 
|---|
|  | 324 | virtual void svd_this(SCMatrix *U, DiagSCMatrix *sigma, SCMatrix *V); | 
|---|
|  | 325 | virtual double solve_this(SCVector*) = 0; | 
|---|
|  | 326 | virtual void gen_invert_this(); | 
|---|
|  | 327 |  | 
|---|
|  | 328 | /** Schmidt orthogonalize this.  S is the overlap matrix. | 
|---|
|  | 329 | n is the number of columns to orthogonalize. */ | 
|---|
|  | 330 | virtual void schmidt_orthog(SymmSCMatrix*, int n) =0; | 
|---|
|  | 331 |  | 
|---|
|  | 332 | /** Schmidt orthogonalize this.  S is the overlap matrix.  tol is the | 
|---|
|  | 333 | tolerance.  The number of linearly independent vectors is | 
|---|
|  | 334 | returned. */ | 
|---|
|  | 335 | virtual int schmidt_orthog_tol(SymmSCMatrix*, double tol, double*res=0)=0; | 
|---|
|  | 336 |  | 
|---|
|  | 337 | /// Perform the element operation op on each element of this. | 
|---|
|  | 338 | virtual void element_op(const Ref<SCElementOp>&) = 0; | 
|---|
|  | 339 | virtual void element_op(const Ref<SCElementOp2>&, | 
|---|
|  | 340 | SCMatrix*) = 0; | 
|---|
|  | 341 | virtual void element_op(const Ref<SCElementOp3>&, | 
|---|
|  | 342 | SCMatrix*,SCMatrix*) = 0; | 
|---|
|  | 343 | /// Print out the matrix. | 
|---|
|  | 344 | void print(std::ostream&o=ExEnv::out0()) const; | 
|---|
|  | 345 | void print(const char* title=0,std::ostream& out=ExEnv::out0(), | 
|---|
|  | 346 | int =10) const; | 
|---|
|  | 347 | virtual void vprint(const char*title=0, | 
|---|
|  | 348 | std::ostream&out=ExEnv::out0(),int =10) const = 0; | 
|---|
|  | 349 |  | 
|---|
|  | 350 | /// Returns the message group used by the matrix kit | 
|---|
|  | 351 | Ref<MessageGrp> messagegrp() const; | 
|---|
|  | 352 |  | 
|---|
|  | 353 | /** Returns iterators for the local (rapidly accessible) | 
|---|
|  | 354 | blocks used in this matrix. */ | 
|---|
|  | 355 | virtual Ref<SCMatrixSubblockIter> local_blocks( | 
|---|
|  | 356 | SCMatrixSubblockIter::Access) = 0; | 
|---|
|  | 357 | /// Returns iterators for the all blocks used in this matrix. | 
|---|
|  | 358 | virtual Ref<SCMatrixSubblockIter> all_blocks( | 
|---|
|  | 359 | SCMatrixSubblockIter::Access) = 0; | 
|---|
|  | 360 | }; | 
|---|
|  | 361 |  | 
|---|
|  | 362 | /** The SymmSCMatrix class is the abstract base class for symmetric | 
|---|
|  | 363 | double valued matrices. */ | 
|---|
|  | 364 | class SymmSCMatrix: public DescribedClass { | 
|---|
|  | 365 | protected: | 
|---|
|  | 366 | RefSCDimension d; | 
|---|
|  | 367 | Ref<SCMatrixKit> kit_; | 
|---|
|  | 368 | public: | 
|---|
|  | 369 | SymmSCMatrix(const RefSCDimension&, SCMatrixKit *); | 
|---|
|  | 370 | ~SymmSCMatrix(); | 
|---|
|  | 371 |  | 
|---|
|  | 372 | /// Return the SCMatrixKit object that created this object. | 
|---|
|  | 373 | Ref<SCMatrixKit> kit() const { return kit_; } | 
|---|
|  | 374 |  | 
|---|
|  | 375 | /// Save and restore this in an implementation independent way. | 
|---|
|  | 376 | virtual void save(StateOut&); | 
|---|
|  | 377 | virtual void restore(StateIn&); | 
|---|
|  | 378 | /// Return the maximum absolute value element of this vector. | 
|---|
|  | 379 | virtual double maxabs() const; | 
|---|
|  | 380 | /// Assign each element to a random number between -1 and 1 | 
|---|
|  | 381 | virtual void randomize(); | 
|---|
|  | 382 | /// Set all elements to val. | 
|---|
|  | 383 | void assign(double val) { assign_val(val); } | 
|---|
|  | 384 | /** Assign element i, j to m[i*(i+1)/2+j]. */ | 
|---|
|  | 385 | void assign(const double* m) { assign_p(m); } | 
|---|
|  | 386 | /// Assign element i, j to m[i][j]. | 
|---|
|  | 387 | void assign(const double** m) { assign_pp(m); } | 
|---|
|  | 388 | /** Make this have the same elements as m.  The dimensions must | 
|---|
|  | 389 | match. */ | 
|---|
|  | 390 | void assign(SymmSCMatrix* m) { assign_s(m); } | 
|---|
|  | 391 | /// Overridden to implement the assign functions | 
|---|
|  | 392 | virtual void assign_val(double val); | 
|---|
|  | 393 | virtual void assign_p(const double* m); | 
|---|
|  | 394 | virtual void assign_pp(const double** m); | 
|---|
|  | 395 | virtual void assign_s(SymmSCMatrix* m); | 
|---|
|  | 396 | /// Like the assign members, but these write values to the arguments. | 
|---|
|  | 397 | virtual void convert(double*) const; | 
|---|
|  | 398 | virtual void convert(double**) const; | 
|---|
|  | 399 | /** Convert an SCSymmSCMatrix of a different specialization | 
|---|
|  | 400 | to this specialization and possibly accumulate the data. */ | 
|---|
|  | 401 | virtual void convert(SymmSCMatrix*); | 
|---|
|  | 402 | virtual void convert_accumulate(SymmSCMatrix*); | 
|---|
|  | 403 | /// Multiply all elements by val. | 
|---|
|  | 404 | virtual void scale(double); | 
|---|
|  | 405 | /// Scale the diagonal elements by val. | 
|---|
|  | 406 | virtual void scale_diagonal(double); | 
|---|
|  | 407 | /// Shift the diagonal elements by val. | 
|---|
|  | 408 | virtual void shift_diagonal(double); | 
|---|
|  | 409 | /// Make this equal to the unit matrix. | 
|---|
|  | 410 | virtual void unit(); | 
|---|
|  | 411 | /// Return the dimension. | 
|---|
|  | 412 | int n() const { return d->n(); } | 
|---|
|  | 413 | /// Return a matrix with the same dimension and same elements. | 
|---|
|  | 414 | virtual SymmSCMatrix* copy(); | 
|---|
|  | 415 | /// Return a matrix with the same dimension but uninitialized memory. | 
|---|
|  | 416 | virtual SymmSCMatrix* clone(); | 
|---|
|  | 417 |  | 
|---|
|  | 418 | // pure virtual functions | 
|---|
|  | 419 | /// Return the dimension. | 
|---|
|  | 420 | RefSCDimension dim() const { return d; } | 
|---|
|  | 421 | /// Return or modify an element. | 
|---|
|  | 422 | virtual double get_element(int,int) const = 0; | 
|---|
|  | 423 | virtual void set_element(int,int,double) = 0; | 
|---|
|  | 424 | virtual void accumulate_element(int,int,double) = 0; | 
|---|
|  | 425 |  | 
|---|
|  | 426 | /** Return a subblock of this.  The subblock is defined as the rows | 
|---|
|  | 427 | starting at br and ending at er, and the columns beginning at bc | 
|---|
|  | 428 | and ending at ec. */ | 
|---|
|  | 429 | virtual SCMatrix * get_subblock(int br, int er, int bc, int ec) =0; | 
|---|
|  | 430 | virtual SymmSCMatrix * get_subblock(int br, int er) =0; | 
|---|
|  | 431 |  | 
|---|
|  | 432 | /// Assign m to a subblock of this. | 
|---|
|  | 433 | virtual void assign_subblock(SCMatrix *m, int, int, int, int) =0; | 
|---|
|  | 434 | virtual void assign_subblock(SymmSCMatrix *m, int, int) =0; | 
|---|
|  | 435 |  | 
|---|
|  | 436 | /// Sum m into a subblock of this. | 
|---|
|  | 437 | virtual void accumulate_subblock(SCMatrix *m, int, int, int, int) =0; | 
|---|
|  | 438 | virtual void accumulate_subblock(SymmSCMatrix *m, int, int) =0; | 
|---|
|  | 439 |  | 
|---|
|  | 440 | /// Return a row of this. | 
|---|
|  | 441 | virtual SCVector * get_row(int i) =0; | 
|---|
|  | 442 |  | 
|---|
|  | 443 | /// Assign v to a row of this. | 
|---|
|  | 444 | virtual void assign_row(SCVector *v, int i) =0; | 
|---|
|  | 445 |  | 
|---|
|  | 446 | /// Sum v to a row of this. | 
|---|
|  | 447 | virtual void accumulate_row(SCVector *v, int i) =0; | 
|---|
|  | 448 |  | 
|---|
|  | 449 | /** Diagonalize this, placing the eigenvalues in d and the eigenvectors | 
|---|
|  | 450 | in m. */ | 
|---|
|  | 451 | virtual void diagonalize(DiagSCMatrix*d,SCMatrix*m) = 0; | 
|---|
|  | 452 | /// Sum m into this. | 
|---|
|  | 453 | virtual void accumulate(const SymmSCMatrix* m) = 0; | 
|---|
|  | 454 | /// Sum into this the products of various vectors or matrices. | 
|---|
|  | 455 | virtual void accumulate_symmetric_sum(SCMatrix*) = 0; | 
|---|
|  | 456 | virtual void accumulate_symmetric_product(SCMatrix*); | 
|---|
|  | 457 | virtual void accumulate_transform(SCMatrix*,SymmSCMatrix*, | 
|---|
|  | 458 | SCMatrix::Transform = SCMatrix::NormalTransform); | 
|---|
|  | 459 | virtual void accumulate_transform(SCMatrix*,DiagSCMatrix*, | 
|---|
|  | 460 | SCMatrix::Transform = SCMatrix::NormalTransform); | 
|---|
|  | 461 | virtual void accumulate_transform(SymmSCMatrix*,SymmSCMatrix*); | 
|---|
|  | 462 | virtual void accumulate_symmetric_outer_product(SCVector*); | 
|---|
|  | 463 | /** Return the scalar obtained by multiplying this on the | 
|---|
|  | 464 | left and right by v. */ | 
|---|
|  | 465 | virtual double scalar_product(SCVector* v); | 
|---|
|  | 466 | /// Return the trace. | 
|---|
|  | 467 | virtual double trace() = 0; | 
|---|
|  | 468 | /// Invert this. | 
|---|
|  | 469 | virtual double invert_this() = 0; | 
|---|
|  | 470 | /// Return the determinant of this.  this is overwritten. | 
|---|
|  | 471 | virtual double determ_this() = 0; | 
|---|
|  | 472 |  | 
|---|
|  | 473 | virtual double solve_this(SCVector*) = 0; | 
|---|
|  | 474 | virtual void gen_invert_this() = 0; | 
|---|
|  | 475 |  | 
|---|
|  | 476 | /// Perform the element operation op on each element of this. | 
|---|
|  | 477 | virtual void element_op(const Ref<SCElementOp>&) = 0; | 
|---|
|  | 478 | virtual void element_op(const Ref<SCElementOp2>&, | 
|---|
|  | 479 | SymmSCMatrix*) = 0; | 
|---|
|  | 480 | virtual void element_op(const Ref<SCElementOp3>&, | 
|---|
|  | 481 | SymmSCMatrix*,SymmSCMatrix*) = 0; | 
|---|
|  | 482 | /// Print out the matrix. | 
|---|
|  | 483 | void print(std::ostream&o=ExEnv::out0()) const; | 
|---|
|  | 484 | void print(const char* title=0,std::ostream& out=ExEnv::out0(), | 
|---|
|  | 485 | int =10) const; | 
|---|
|  | 486 | virtual void vprint(const char* title=0, | 
|---|
|  | 487 | std::ostream& out=ExEnv::out0(), int =10) const; | 
|---|
|  | 488 |  | 
|---|
|  | 489 | /// Returns the message group used by the matrix kit | 
|---|
|  | 490 | Ref<MessageGrp> messagegrp() const; | 
|---|
|  | 491 |  | 
|---|
|  | 492 | /** Returns iterators for the local (rapidly accessible) | 
|---|
|  | 493 | blocks used in this matrix. */ | 
|---|
|  | 494 | virtual Ref<SCMatrixSubblockIter> local_blocks( | 
|---|
|  | 495 | SCMatrixSubblockIter::Access) = 0; | 
|---|
|  | 496 | /// Returns iterators for the all blocks used in this matrix. | 
|---|
|  | 497 | virtual Ref<SCMatrixSubblockIter> all_blocks( | 
|---|
|  | 498 | SCMatrixSubblockIter::Access) = 0; | 
|---|
|  | 499 | }; | 
|---|
|  | 500 |  | 
|---|
|  | 501 | /** The SymmSCMatrix class is the abstract base class for diagonal double | 
|---|
|  | 502 | valued matrices.  */ | 
|---|
|  | 503 | class DiagSCMatrix: public DescribedClass { | 
|---|
|  | 504 | protected: | 
|---|
|  | 505 | RefSCDimension d; | 
|---|
|  | 506 | Ref<SCMatrixKit> kit_; | 
|---|
|  | 507 | public: | 
|---|
|  | 508 | DiagSCMatrix(const RefSCDimension&, SCMatrixKit *); | 
|---|
|  | 509 | ~DiagSCMatrix(); | 
|---|
|  | 510 |  | 
|---|
|  | 511 | /// Return the SCMatrixKit used to create this object. | 
|---|
|  | 512 | Ref<SCMatrixKit> kit() const { return kit_; } | 
|---|
|  | 513 |  | 
|---|
|  | 514 | /// Save and restore this in an implementation independent way. | 
|---|
|  | 515 | virtual void save(StateOut&); | 
|---|
|  | 516 | virtual void restore(StateIn&); | 
|---|
|  | 517 |  | 
|---|
|  | 518 | /// Return the maximum absolute value element of this vector. | 
|---|
|  | 519 | virtual double maxabs() const; | 
|---|
|  | 520 | /// Assign each element to a random number between -1 and 1 | 
|---|
|  | 521 | virtual void randomize(); | 
|---|
|  | 522 | /// Set all elements to val. | 
|---|
|  | 523 | void assign(double val) { assign_val(val); } | 
|---|
|  | 524 | /// Assign element i, i to m[i]. | 
|---|
|  | 525 | void assign(const double*p) { assign_p(p); } | 
|---|
|  | 526 | /** Make this have the same elements as m.  The dimensions must | 
|---|
|  | 527 | match. */ | 
|---|
|  | 528 | void assign(DiagSCMatrix*d_a) { assign_d(d_a); } | 
|---|
|  | 529 | /// Overridden to implement the assign members. | 
|---|
|  | 530 | virtual void assign_val(double val); | 
|---|
|  | 531 | virtual void assign_p(const double*); | 
|---|
|  | 532 | virtual void assign_d(DiagSCMatrix*); | 
|---|
|  | 533 | /// Like the assign member, but this writes values to the argument. | 
|---|
|  | 534 | virtual void convert(double*) const; | 
|---|
|  | 535 | /** Convert an SCDiagSCMatrix of a different specialization | 
|---|
|  | 536 | to this specialization and possibly accumulate the data. */ | 
|---|
|  | 537 | virtual void convert(DiagSCMatrix*); | 
|---|
|  | 538 | virtual void convert_accumulate(DiagSCMatrix*); | 
|---|
|  | 539 | /// Multiply all elements by val. | 
|---|
|  | 540 | virtual void scale(double); | 
|---|
|  | 541 | /// Return the dimension. | 
|---|
|  | 542 | int n() const { return d->n(); } | 
|---|
|  | 543 | /// Return a matrix with the same dimension and same elements. | 
|---|
|  | 544 | virtual DiagSCMatrix* copy(); | 
|---|
|  | 545 | /// Return a matrix with the same dimension but uninitialized memory. | 
|---|
|  | 546 | virtual DiagSCMatrix* clone(); | 
|---|
|  | 547 |  | 
|---|
|  | 548 | // pure virtual functions | 
|---|
|  | 549 | /// Return the dimension. | 
|---|
|  | 550 | RefSCDimension dim() const { return d; } | 
|---|
|  | 551 | /// Return or modify an element. | 
|---|
|  | 552 | virtual double get_element(int) const = 0; | 
|---|
|  | 553 | virtual void set_element(int,double) = 0; | 
|---|
|  | 554 | virtual void accumulate_element(int,double) = 0; | 
|---|
|  | 555 | /// Sum m into this. | 
|---|
|  | 556 | virtual void accumulate(const DiagSCMatrix* m) = 0; | 
|---|
|  | 557 | /// Return the trace. | 
|---|
|  | 558 | virtual double trace() = 0; | 
|---|
|  | 559 | /// Return the determinant of this.  this is overwritten. | 
|---|
|  | 560 | virtual double determ_this() = 0; | 
|---|
|  | 561 | /// Invert this. | 
|---|
|  | 562 | virtual double invert_this() = 0; | 
|---|
|  | 563 | /// Do a generalized inversion of this. | 
|---|
|  | 564 | virtual void gen_invert_this() = 0; | 
|---|
|  | 565 | /// Perform the element operation op on each element of this. | 
|---|
|  | 566 | virtual void element_op(const Ref<SCElementOp>&) = 0; | 
|---|
|  | 567 | virtual void element_op(const Ref<SCElementOp2>&, | 
|---|
|  | 568 | DiagSCMatrix*) = 0; | 
|---|
|  | 569 | virtual void element_op(const Ref<SCElementOp3>&, | 
|---|
|  | 570 | DiagSCMatrix*,DiagSCMatrix*) = 0; | 
|---|
|  | 571 | /// Print out the matrix. | 
|---|
|  | 572 | void print(std::ostream&o=ExEnv::out0()) const; | 
|---|
|  | 573 | void print(const char* title=0, | 
|---|
|  | 574 | std::ostream& out=ExEnv::out0(), int =10) const; | 
|---|
|  | 575 | virtual void vprint(const char* title=0, | 
|---|
|  | 576 | std::ostream& out=ExEnv::out0(), int =10) const; | 
|---|
|  | 577 |  | 
|---|
|  | 578 | /// Returns the message group used by the matrix kit | 
|---|
|  | 579 | Ref<MessageGrp> messagegrp() const; | 
|---|
|  | 580 |  | 
|---|
|  | 581 | /** Returns iterators for the local (rapidly accessible) | 
|---|
|  | 582 | blocks used in this matrix. */ | 
|---|
|  | 583 | virtual Ref<SCMatrixSubblockIter> local_blocks( | 
|---|
|  | 584 | SCMatrixSubblockIter::Access) = 0; | 
|---|
|  | 585 | /// Returns iterators for the all blocks used in this matrix. | 
|---|
|  | 586 | virtual Ref<SCMatrixSubblockIter> all_blocks( | 
|---|
|  | 587 | SCMatrixSubblockIter::Access) = 0; | 
|---|
|  | 588 | }; | 
|---|
|  | 589 |  | 
|---|
|  | 590 | } | 
|---|
|  | 591 |  | 
|---|
|  | 592 | #endif | 
|---|
|  | 593 |  | 
|---|
|  | 594 | // Local Variables: | 
|---|
|  | 595 | // mode: c++ | 
|---|
|  | 596 | // c-file-style: "CLJ" | 
|---|
|  | 597 | // End: | 
|---|