[2013] | 1 | /// \ingroup newmat
|
---|
| 2 | ///@{
|
---|
| 3 |
|
---|
| 4 | /// \file newmat4.cpp
|
---|
| 5 | /// Constructors, resize, basic utilities, SimpleIntArray.
|
---|
| 6 |
|
---|
| 7 |
|
---|
| 8 | // Copyright (C) 1991,2,3,4,8,9: R B Davies
|
---|
| 9 |
|
---|
| 10 | //#define WANT_STREAM
|
---|
| 11 |
|
---|
| 12 | #include "include.h"
|
---|
| 13 |
|
---|
| 14 | #include "newmat.h"
|
---|
| 15 | #include "newmatrc.h"
|
---|
| 16 |
|
---|
| 17 | #ifdef use_namespace
|
---|
| 18 | namespace NEWMAT {
|
---|
| 19 | #endif
|
---|
| 20 |
|
---|
| 21 |
|
---|
| 22 |
|
---|
| 23 | #ifdef DO_REPORT
|
---|
| 24 | #define REPORT { static ExeCounter ExeCount(__LINE__,4); ++ExeCount; }
|
---|
| 25 | #else
|
---|
| 26 | #define REPORT {}
|
---|
| 27 | #endif
|
---|
| 28 |
|
---|
| 29 |
|
---|
| 30 | #define DO_SEARCH // search for LHS of = in RHS
|
---|
| 31 |
|
---|
| 32 | // ************************* general utilities *************************/
|
---|
| 33 |
|
---|
| 34 | static int tristore(int n) // elements in triangular matrix
|
---|
| 35 | { return (n*(n+1))/2; }
|
---|
| 36 |
|
---|
| 37 |
|
---|
| 38 | // **************************** constructors ***************************/
|
---|
| 39 |
|
---|
| 40 | GeneralMatrix::GeneralMatrix()
|
---|
| 41 | { store=0; storage=0; nrows_val=0; ncols_val=0; tag_val=-1; }
|
---|
| 42 |
|
---|
| 43 | GeneralMatrix::GeneralMatrix(ArrayLengthSpecifier s)
|
---|
| 44 | {
|
---|
| 45 | REPORT
|
---|
| 46 | storage=s.Value(); tag_val=-1;
|
---|
| 47 | if (storage)
|
---|
| 48 | {
|
---|
| 49 | store = new Real [storage]; MatrixErrorNoSpace(store);
|
---|
| 50 | MONITOR_REAL_NEW("Make (GenMatrix)",storage,store)
|
---|
| 51 | }
|
---|
| 52 | else store = 0;
|
---|
| 53 | }
|
---|
| 54 |
|
---|
| 55 | Matrix::Matrix(int m, int n) : GeneralMatrix(m*n)
|
---|
| 56 | { REPORT nrows_val=m; ncols_val=n; }
|
---|
| 57 |
|
---|
| 58 | SquareMatrix::SquareMatrix(ArrayLengthSpecifier n)
|
---|
| 59 | : Matrix(n.Value(),n.Value())
|
---|
| 60 | { REPORT }
|
---|
| 61 |
|
---|
| 62 | SymmetricMatrix::SymmetricMatrix(ArrayLengthSpecifier n)
|
---|
| 63 | : GeneralMatrix(tristore(n.Value()))
|
---|
| 64 | { REPORT nrows_val=n.Value(); ncols_val=n.Value(); }
|
---|
| 65 |
|
---|
| 66 | UpperTriangularMatrix::UpperTriangularMatrix(ArrayLengthSpecifier n)
|
---|
| 67 | : GeneralMatrix(tristore(n.Value()))
|
---|
| 68 | { REPORT nrows_val=n.Value(); ncols_val=n.Value(); }
|
---|
| 69 |
|
---|
| 70 | LowerTriangularMatrix::LowerTriangularMatrix(ArrayLengthSpecifier n)
|
---|
| 71 | : GeneralMatrix(tristore(n.Value()))
|
---|
| 72 | { REPORT nrows_val=n.Value(); ncols_val=n.Value(); }
|
---|
| 73 |
|
---|
| 74 | DiagonalMatrix::DiagonalMatrix(ArrayLengthSpecifier m) : GeneralMatrix(m)
|
---|
| 75 | { REPORT nrows_val=m.Value(); ncols_val=m.Value(); }
|
---|
| 76 |
|
---|
| 77 | Matrix::Matrix(const BaseMatrix& M)
|
---|
| 78 | {
|
---|
| 79 | REPORT // CheckConversion(M);
|
---|
| 80 | // MatrixConversionCheck mcc;
|
---|
| 81 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Rt);
|
---|
| 82 | GetMatrix(gmx);
|
---|
| 83 | }
|
---|
| 84 |
|
---|
| 85 | SquareMatrix::SquareMatrix(const BaseMatrix& M) : Matrix(M)
|
---|
| 86 | {
|
---|
| 87 | REPORT
|
---|
| 88 | if (ncols_val != nrows_val)
|
---|
| 89 | {
|
---|
| 90 | Tracer tr("SquareMatrix");
|
---|
| 91 | Throw(NotSquareException(*this));
|
---|
| 92 | }
|
---|
| 93 | }
|
---|
| 94 |
|
---|
| 95 |
|
---|
| 96 | SquareMatrix::SquareMatrix(const Matrix& gm)
|
---|
| 97 | {
|
---|
| 98 | REPORT
|
---|
| 99 | if (gm.ncols_val != gm.nrows_val)
|
---|
| 100 | {
|
---|
| 101 | Tracer tr("SquareMatrix(Matrix)");
|
---|
| 102 | Throw(NotSquareException(gm));
|
---|
| 103 | }
|
---|
| 104 | GetMatrix(&gm);
|
---|
| 105 | }
|
---|
| 106 |
|
---|
| 107 |
|
---|
| 108 | RowVector::RowVector(const BaseMatrix& M) : Matrix(M)
|
---|
| 109 | {
|
---|
| 110 | REPORT
|
---|
| 111 | if (nrows_val!=1)
|
---|
| 112 | {
|
---|
| 113 | Tracer tr("RowVector");
|
---|
| 114 | Throw(VectorException(*this));
|
---|
| 115 | }
|
---|
| 116 | }
|
---|
| 117 |
|
---|
| 118 | ColumnVector::ColumnVector(const BaseMatrix& M) : Matrix(M)
|
---|
| 119 | {
|
---|
| 120 | REPORT
|
---|
| 121 | if (ncols_val!=1)
|
---|
| 122 | {
|
---|
| 123 | Tracer tr("ColumnVector");
|
---|
| 124 | Throw(VectorException(*this));
|
---|
| 125 | }
|
---|
| 126 | }
|
---|
| 127 |
|
---|
| 128 | SymmetricMatrix::SymmetricMatrix(const BaseMatrix& M)
|
---|
| 129 | {
|
---|
| 130 | REPORT // CheckConversion(M);
|
---|
| 131 | // MatrixConversionCheck mcc;
|
---|
| 132 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Sm);
|
---|
| 133 | GetMatrix(gmx);
|
---|
| 134 | }
|
---|
| 135 |
|
---|
| 136 | UpperTriangularMatrix::UpperTriangularMatrix(const BaseMatrix& M)
|
---|
| 137 | {
|
---|
| 138 | REPORT // CheckConversion(M);
|
---|
| 139 | // MatrixConversionCheck mcc;
|
---|
| 140 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::UT);
|
---|
| 141 | GetMatrix(gmx);
|
---|
| 142 | }
|
---|
| 143 |
|
---|
| 144 | LowerTriangularMatrix::LowerTriangularMatrix(const BaseMatrix& M)
|
---|
| 145 | {
|
---|
| 146 | REPORT // CheckConversion(M);
|
---|
| 147 | // MatrixConversionCheck mcc;
|
---|
| 148 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::LT);
|
---|
| 149 | GetMatrix(gmx);
|
---|
| 150 | }
|
---|
| 151 |
|
---|
| 152 | DiagonalMatrix::DiagonalMatrix(const BaseMatrix& M)
|
---|
| 153 | {
|
---|
| 154 | REPORT //CheckConversion(M);
|
---|
| 155 | // MatrixConversionCheck mcc;
|
---|
| 156 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Dg);
|
---|
| 157 | GetMatrix(gmx);
|
---|
| 158 | }
|
---|
| 159 |
|
---|
| 160 | IdentityMatrix::IdentityMatrix(const BaseMatrix& M)
|
---|
| 161 | {
|
---|
| 162 | REPORT //CheckConversion(M);
|
---|
| 163 | // MatrixConversionCheck mcc;
|
---|
| 164 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Id);
|
---|
| 165 | GetMatrix(gmx);
|
---|
| 166 | }
|
---|
| 167 |
|
---|
| 168 | GeneralMatrix::~GeneralMatrix()
|
---|
| 169 | {
|
---|
| 170 | if (store)
|
---|
| 171 | {
|
---|
| 172 | MONITOR_REAL_DELETE("Free (GenMatrix)",storage,store)
|
---|
| 173 | delete [] store;
|
---|
| 174 | }
|
---|
| 175 | }
|
---|
| 176 |
|
---|
| 177 | CroutMatrix::CroutMatrix(const BaseMatrix& m)
|
---|
| 178 | {
|
---|
| 179 | REPORT
|
---|
| 180 | Tracer tr("CroutMatrix");
|
---|
| 181 | indx = 0; // in case of exception at next line
|
---|
| 182 | GeneralMatrix* gm = ((BaseMatrix&)m).Evaluate();
|
---|
| 183 | if (gm->nrows_val!=gm->ncols_val)
|
---|
| 184 | { gm->tDelete(); Throw(NotSquareException(*gm)); }
|
---|
| 185 | if (gm->type() == MatrixType::Ct)
|
---|
| 186 | { REPORT ((CroutMatrix*)gm)->get_aux(*this); GetMatrix(gm); }
|
---|
| 187 | else
|
---|
| 188 | {
|
---|
| 189 | REPORT
|
---|
| 190 | GeneralMatrix* gm1 = gm->Evaluate(MatrixType::Rt);
|
---|
| 191 | GetMatrix(gm1);
|
---|
| 192 | d=true; sing=false;
|
---|
| 193 | indx=new int [nrows_val]; MatrixErrorNoSpace(indx);
|
---|
| 194 | MONITOR_INT_NEW("Index (CroutMat)",nrows_val,indx)
|
---|
| 195 | ludcmp();
|
---|
| 196 | }
|
---|
| 197 | }
|
---|
| 198 |
|
---|
| 199 | // could we use SetParameters instead of this
|
---|
| 200 | void CroutMatrix::get_aux(CroutMatrix& X)
|
---|
| 201 | {
|
---|
| 202 | X.d = d; X.sing = sing;
|
---|
| 203 | if (tag_val == 0 || tag_val == 1) // reuse the array
|
---|
| 204 | { REPORT X.indx = indx; indx = 0; d = true; sing = true; return; }
|
---|
| 205 | else if (nrows_val == 0)
|
---|
| 206 | { REPORT indx = 0; d = true; sing = true; return; }
|
---|
| 207 | else // copy the array
|
---|
| 208 | {
|
---|
| 209 | REPORT
|
---|
| 210 | Tracer tr("CroutMatrix::get_aux");
|
---|
| 211 | int *ix = new int [nrows_val]; MatrixErrorNoSpace(ix);
|
---|
| 212 | MONITOR_INT_NEW("Index (CM::get_aux)", nrows_val, ix)
|
---|
| 213 | int n = nrows_val; int* i = ix; int* j = indx;
|
---|
| 214 | while(n--) *i++ = *j++;
|
---|
| 215 | X.indx = ix;
|
---|
| 216 | }
|
---|
| 217 | }
|
---|
| 218 |
|
---|
| 219 | CroutMatrix::CroutMatrix(const CroutMatrix& gm) : GeneralMatrix()
|
---|
| 220 | {
|
---|
| 221 | REPORT
|
---|
| 222 | Tracer tr("CroutMatrix(const CroutMatrix&)");
|
---|
| 223 | ((CroutMatrix&)gm).get_aux(*this);
|
---|
| 224 | GetMatrix(&gm);
|
---|
| 225 | }
|
---|
| 226 |
|
---|
| 227 | CroutMatrix::~CroutMatrix()
|
---|
| 228 | {
|
---|
| 229 | MONITOR_INT_DELETE("Index (CroutMat)",nrows_val,indx)
|
---|
| 230 | delete [] indx;
|
---|
| 231 | }
|
---|
| 232 |
|
---|
| 233 | //ReturnMatrix::ReturnMatrix(GeneralMatrix& gmx)
|
---|
| 234 | //{
|
---|
| 235 | // REPORT
|
---|
| 236 | // gm = gmx.Image(); gm->ReleaseAndDelete();
|
---|
| 237 | //}
|
---|
| 238 |
|
---|
| 239 |
|
---|
| 240 | GeneralMatrix::operator ReturnMatrix() const
|
---|
| 241 | {
|
---|
| 242 | REPORT
|
---|
| 243 | GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
|
---|
| 244 | return ReturnMatrix(gm);
|
---|
| 245 | }
|
---|
| 246 |
|
---|
| 247 |
|
---|
| 248 |
|
---|
| 249 | ReturnMatrix GeneralMatrix::for_return() const
|
---|
| 250 | {
|
---|
| 251 | REPORT
|
---|
| 252 | GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
|
---|
| 253 | return ReturnMatrix(gm);
|
---|
| 254 | }
|
---|
| 255 |
|
---|
| 256 | // ************ Constructors for use with NR in C++ interface ***********
|
---|
| 257 |
|
---|
| 258 | #ifdef SETUP_C_SUBSCRIPTS
|
---|
| 259 |
|
---|
| 260 | Matrix::Matrix(Real a, int m, int n) : GeneralMatrix(m * n)
|
---|
| 261 | { REPORT nrows_val=m; ncols_val=n; operator=(a); }
|
---|
| 262 |
|
---|
| 263 | Matrix::Matrix(const Real* a, int m, int n) : GeneralMatrix(m * n)
|
---|
| 264 | { REPORT nrows_val=m; ncols_val=n; *this << a; }
|
---|
| 265 |
|
---|
| 266 | #endif
|
---|
| 267 |
|
---|
| 268 |
|
---|
| 269 |
|
---|
| 270 | // ************************** resize matrices ***************************/
|
---|
| 271 |
|
---|
| 272 | void GeneralMatrix::resize(int nr, int nc, int s)
|
---|
| 273 | {
|
---|
| 274 | REPORT
|
---|
| 275 | if (store)
|
---|
| 276 | {
|
---|
| 277 | MONITOR_REAL_DELETE("Free (ReDimensi)",storage,store)
|
---|
| 278 | delete [] store;
|
---|
| 279 | }
|
---|
| 280 | storage=s; nrows_val=nr; ncols_val=nc; tag_val=-1;
|
---|
| 281 | if (s)
|
---|
| 282 | {
|
---|
| 283 | store = new Real [storage]; MatrixErrorNoSpace(store);
|
---|
| 284 | MONITOR_REAL_NEW("Make (ReDimensi)",storage,store)
|
---|
| 285 | }
|
---|
| 286 | else store = 0;
|
---|
| 287 | }
|
---|
| 288 |
|
---|
| 289 | void Matrix::resize(int nr, int nc)
|
---|
| 290 | { REPORT GeneralMatrix::resize(nr,nc,nr*nc); }
|
---|
| 291 |
|
---|
| 292 | void SquareMatrix::resize(int n)
|
---|
| 293 | { REPORT GeneralMatrix::resize(n,n,n*n); }
|
---|
| 294 |
|
---|
| 295 | void SquareMatrix::resize(int nr, int nc)
|
---|
| 296 | {
|
---|
| 297 | REPORT
|
---|
| 298 | Tracer tr("SquareMatrix::resize");
|
---|
| 299 | if (nc != nr) Throw(NotSquareException(*this));
|
---|
| 300 | GeneralMatrix::resize(nr,nc,nr*nc);
|
---|
| 301 | }
|
---|
| 302 |
|
---|
| 303 | void SymmetricMatrix::resize(int nr)
|
---|
| 304 | { REPORT GeneralMatrix::resize(nr,nr,tristore(nr)); }
|
---|
| 305 |
|
---|
| 306 | void UpperTriangularMatrix::resize(int nr)
|
---|
| 307 | { REPORT GeneralMatrix::resize(nr,nr,tristore(nr)); }
|
---|
| 308 |
|
---|
| 309 | void LowerTriangularMatrix::resize(int nr)
|
---|
| 310 | { REPORT GeneralMatrix::resize(nr,nr,tristore(nr)); }
|
---|
| 311 |
|
---|
| 312 | void DiagonalMatrix::resize(int nr)
|
---|
| 313 | { REPORT GeneralMatrix::resize(nr,nr,nr); }
|
---|
| 314 |
|
---|
| 315 | void RowVector::resize(int nc)
|
---|
| 316 | { REPORT GeneralMatrix::resize(1,nc,nc); }
|
---|
| 317 |
|
---|
| 318 | void ColumnVector::resize(int nr)
|
---|
| 319 | { REPORT GeneralMatrix::resize(nr,1,nr); }
|
---|
| 320 |
|
---|
| 321 | void RowVector::resize(int nr, int nc)
|
---|
| 322 | {
|
---|
| 323 | Tracer tr("RowVector::resize");
|
---|
| 324 | if (nr != 1) Throw(VectorException(*this));
|
---|
| 325 | REPORT GeneralMatrix::resize(1,nc,nc);
|
---|
| 326 | }
|
---|
| 327 |
|
---|
| 328 | void ColumnVector::resize(int nr, int nc)
|
---|
| 329 | {
|
---|
| 330 | Tracer tr("ColumnVector::resize");
|
---|
| 331 | if (nc != 1) Throw(VectorException(*this));
|
---|
| 332 | REPORT GeneralMatrix::resize(nr,1,nr);
|
---|
| 333 | }
|
---|
| 334 |
|
---|
| 335 | void IdentityMatrix::resize(int nr)
|
---|
| 336 | { REPORT GeneralMatrix::resize(nr,nr,1); *store = 1; }
|
---|
| 337 |
|
---|
| 338 |
|
---|
| 339 | void Matrix::resize(const GeneralMatrix& A)
|
---|
| 340 | { REPORT resize(A.Nrows(), A.Ncols()); }
|
---|
| 341 |
|
---|
| 342 | void SquareMatrix::resize(const GeneralMatrix& A)
|
---|
| 343 | {
|
---|
| 344 | REPORT
|
---|
| 345 | int n = A.Nrows();
|
---|
| 346 | if (n != A.Ncols())
|
---|
| 347 | {
|
---|
| 348 | Tracer tr("SquareMatrix::resize(GM)");
|
---|
| 349 | Throw(NotSquareException(*this));
|
---|
| 350 | }
|
---|
| 351 | resize(n);
|
---|
| 352 | }
|
---|
| 353 |
|
---|
| 354 | void nricMatrix::resize(const GeneralMatrix& A)
|
---|
| 355 | { REPORT resize(A.Nrows(), A.Ncols()); }
|
---|
| 356 |
|
---|
| 357 | void ColumnVector::resize(const GeneralMatrix& A)
|
---|
| 358 | { REPORT resize(A.Nrows(), A.Ncols()); }
|
---|
| 359 |
|
---|
| 360 | void RowVector::resize(const GeneralMatrix& A)
|
---|
| 361 | { REPORT resize(A.Nrows(), A.Ncols()); }
|
---|
| 362 |
|
---|
| 363 | void SymmetricMatrix::resize(const GeneralMatrix& A)
|
---|
| 364 | {
|
---|
| 365 | REPORT
|
---|
| 366 | int n = A.Nrows();
|
---|
| 367 | if (n != A.Ncols())
|
---|
| 368 | {
|
---|
| 369 | Tracer tr("SymmetricMatrix::resize(GM)");
|
---|
| 370 | Throw(NotSquareException(*this));
|
---|
| 371 | }
|
---|
| 372 | resize(n);
|
---|
| 373 | }
|
---|
| 374 |
|
---|
| 375 | void DiagonalMatrix::resize(const GeneralMatrix& A)
|
---|
| 376 | {
|
---|
| 377 | REPORT
|
---|
| 378 | int n = A.Nrows();
|
---|
| 379 | if (n != A.Ncols())
|
---|
| 380 | {
|
---|
| 381 | Tracer tr("DiagonalMatrix::resize(GM)");
|
---|
| 382 | Throw(NotSquareException(*this));
|
---|
| 383 | }
|
---|
| 384 | resize(n);
|
---|
| 385 | }
|
---|
| 386 |
|
---|
| 387 | void UpperTriangularMatrix::resize(const GeneralMatrix& A)
|
---|
| 388 | {
|
---|
| 389 | REPORT
|
---|
| 390 | int n = A.Nrows();
|
---|
| 391 | if (n != A.Ncols())
|
---|
| 392 | {
|
---|
| 393 | Tracer tr("UpperTriangularMatrix::resize(GM)");
|
---|
| 394 | Throw(NotSquareException(*this));
|
---|
| 395 | }
|
---|
| 396 | resize(n);
|
---|
| 397 | }
|
---|
| 398 |
|
---|
| 399 | void LowerTriangularMatrix::resize(const GeneralMatrix& A)
|
---|
| 400 | {
|
---|
| 401 | REPORT
|
---|
| 402 | int n = A.Nrows();
|
---|
| 403 | if (n != A.Ncols())
|
---|
| 404 | {
|
---|
| 405 | Tracer tr("LowerTriangularMatrix::resize(GM)");
|
---|
| 406 | Throw(NotSquareException(*this));
|
---|
| 407 | }
|
---|
| 408 | resize(n);
|
---|
| 409 | }
|
---|
| 410 |
|
---|
| 411 | void IdentityMatrix::resize(const GeneralMatrix& A)
|
---|
| 412 | {
|
---|
| 413 | REPORT
|
---|
| 414 | int n = A.Nrows();
|
---|
| 415 | if (n != A.Ncols())
|
---|
| 416 | {
|
---|
| 417 | Tracer tr("IdentityMatrix::resize(GM)");
|
---|
| 418 | Throw(NotSquareException(*this));
|
---|
| 419 | }
|
---|
| 420 | resize(n);
|
---|
| 421 | }
|
---|
| 422 |
|
---|
| 423 | void GeneralMatrix::resize(const GeneralMatrix&)
|
---|
| 424 | {
|
---|
| 425 | REPORT
|
---|
| 426 | Tracer tr("GeneralMatrix::resize(GM)");
|
---|
| 427 | Throw(NotDefinedException("resize", "this type of matrix"));
|
---|
| 428 | }
|
---|
| 429 |
|
---|
| 430 | //*********************** resize_keep *******************************
|
---|
| 431 |
|
---|
| 432 | void Matrix::resize_keep(int nr, int nc)
|
---|
| 433 | {
|
---|
| 434 | Tracer tr("Matrix::resize_keep");
|
---|
| 435 | if (nr == nrows_val && nc == ncols_val) { REPORT return; }
|
---|
| 436 |
|
---|
| 437 | if (nr <= nrows_val && nc <= ncols_val)
|
---|
| 438 | {
|
---|
| 439 | REPORT
|
---|
| 440 | Matrix X = submatrix(1,nr,1,nc);
|
---|
| 441 | swap(X);
|
---|
| 442 | }
|
---|
| 443 | else if (nr >= nrows_val && nc >= ncols_val)
|
---|
| 444 | {
|
---|
| 445 | REPORT
|
---|
| 446 | Matrix X(nr, nc); X = 0;
|
---|
| 447 | X.submatrix(1,nrows_val,1,ncols_val) = *this;
|
---|
| 448 | swap(X);
|
---|
| 449 | }
|
---|
| 450 | else
|
---|
| 451 | {
|
---|
| 452 | REPORT
|
---|
| 453 | Matrix X(nr, nc); X = 0;
|
---|
| 454 | if (nr > nrows_val) nr = nrows_val;
|
---|
| 455 | if (nc > ncols_val) nc = ncols_val;
|
---|
| 456 | X.submatrix(1,nr,1,nc) = submatrix(1,nr,1,nc);
|
---|
| 457 | swap(X);
|
---|
| 458 | }
|
---|
| 459 | }
|
---|
| 460 |
|
---|
| 461 | void SquareMatrix::resize_keep(int nr)
|
---|
| 462 | {
|
---|
| 463 | Tracer tr("SquareMatrix::resize_keep");
|
---|
| 464 | if (nr < nrows_val)
|
---|
| 465 | {
|
---|
| 466 | REPORT
|
---|
| 467 | SquareMatrix X = sym_submatrix(1,nr);
|
---|
| 468 | swap(X);
|
---|
| 469 | }
|
---|
| 470 | else if (nr > nrows_val)
|
---|
| 471 | {
|
---|
| 472 | REPORT
|
---|
| 473 | SquareMatrix X(nr); X = 0;
|
---|
| 474 | X.sym_submatrix(1,nrows_val) = *this;
|
---|
| 475 | swap(X);
|
---|
| 476 | }
|
---|
| 477 | }
|
---|
| 478 |
|
---|
| 479 | void SquareMatrix::resize_keep(int nr, int nc)
|
---|
| 480 | {
|
---|
| 481 | Tracer tr("SquareMatrix::resize_keep 2");
|
---|
| 482 | REPORT
|
---|
| 483 | if (nr != nc) Throw(NotSquareException(*this));
|
---|
| 484 | resize_keep(nr);
|
---|
| 485 | }
|
---|
| 486 |
|
---|
| 487 |
|
---|
| 488 | void SymmetricMatrix::resize_keep(int nr)
|
---|
| 489 | {
|
---|
| 490 | Tracer tr("SymmetricMatrix::resize_keep");
|
---|
| 491 | if (nr < nrows_val)
|
---|
| 492 | {
|
---|
| 493 | REPORT
|
---|
| 494 | SymmetricMatrix X = sym_submatrix(1,nr);
|
---|
| 495 | swap(X);
|
---|
| 496 | }
|
---|
| 497 | else if (nr > nrows_val)
|
---|
| 498 | {
|
---|
| 499 | REPORT
|
---|
| 500 | SymmetricMatrix X(nr); X = 0;
|
---|
| 501 | X.sym_submatrix(1,nrows_val) = *this;
|
---|
| 502 | swap(X);
|
---|
| 503 | }
|
---|
| 504 | }
|
---|
| 505 |
|
---|
| 506 | void UpperTriangularMatrix::resize_keep(int nr)
|
---|
| 507 | {
|
---|
| 508 | Tracer tr("UpperTriangularMatrix::resize_keep");
|
---|
| 509 | if (nr < nrows_val)
|
---|
| 510 | {
|
---|
| 511 | REPORT
|
---|
| 512 | UpperTriangularMatrix X = sym_submatrix(1,nr);
|
---|
| 513 | swap(X);
|
---|
| 514 | }
|
---|
| 515 | else if (nr > nrows_val)
|
---|
| 516 | {
|
---|
| 517 | REPORT
|
---|
| 518 | UpperTriangularMatrix X(nr); X = 0;
|
---|
| 519 | X.sym_submatrix(1,nrows_val) = *this;
|
---|
| 520 | swap(X);
|
---|
| 521 | }
|
---|
| 522 | }
|
---|
| 523 |
|
---|
| 524 | void LowerTriangularMatrix::resize_keep(int nr)
|
---|
| 525 | {
|
---|
| 526 | Tracer tr("LowerTriangularMatrix::resize_keep");
|
---|
| 527 | if (nr < nrows_val)
|
---|
| 528 | {
|
---|
| 529 | REPORT
|
---|
| 530 | LowerTriangularMatrix X = sym_submatrix(1,nr);
|
---|
| 531 | swap(X);
|
---|
| 532 | }
|
---|
| 533 | else if (nr > nrows_val)
|
---|
| 534 | {
|
---|
| 535 | REPORT
|
---|
| 536 | LowerTriangularMatrix X(nr); X = 0;
|
---|
| 537 | X.sym_submatrix(1,nrows_val) = *this;
|
---|
| 538 | swap(X);
|
---|
| 539 | }
|
---|
| 540 | }
|
---|
| 541 |
|
---|
| 542 | void DiagonalMatrix::resize_keep(int nr)
|
---|
| 543 | {
|
---|
| 544 | Tracer tr("DiagonalMatrix::resize_keep");
|
---|
| 545 | if (nr < nrows_val)
|
---|
| 546 | {
|
---|
| 547 | REPORT
|
---|
| 548 | DiagonalMatrix X = sym_submatrix(1,nr);
|
---|
| 549 | swap(X);
|
---|
| 550 | }
|
---|
| 551 | else if (nr > nrows_val)
|
---|
| 552 | {
|
---|
| 553 | REPORT
|
---|
| 554 | DiagonalMatrix X(nr); X = 0;
|
---|
| 555 | X.sym_submatrix(1,nrows_val) = *this;
|
---|
| 556 | swap(X);
|
---|
| 557 | }
|
---|
| 558 | }
|
---|
| 559 |
|
---|
| 560 | void RowVector::resize_keep(int nc)
|
---|
| 561 | {
|
---|
| 562 | Tracer tr("RowVector::resize_keep");
|
---|
| 563 | if (nc < ncols_val)
|
---|
| 564 | {
|
---|
| 565 | REPORT
|
---|
| 566 | RowVector X = columns(1,nc);
|
---|
| 567 | swap(X);
|
---|
| 568 | }
|
---|
| 569 | else if (nc > ncols_val)
|
---|
| 570 | {
|
---|
| 571 | REPORT
|
---|
| 572 | RowVector X(nc); X = 0;
|
---|
| 573 | X.columns(1,ncols_val) = *this;
|
---|
| 574 | swap(X);
|
---|
| 575 | }
|
---|
| 576 | }
|
---|
| 577 |
|
---|
| 578 | void RowVector::resize_keep(int nr, int nc)
|
---|
| 579 | {
|
---|
| 580 | Tracer tr("RowVector::resize_keep 2");
|
---|
| 581 | REPORT
|
---|
| 582 | if (nr != 1) Throw(VectorException(*this));
|
---|
| 583 | resize_keep(nc);
|
---|
| 584 | }
|
---|
| 585 |
|
---|
| 586 | void ColumnVector::resize_keep(int nr)
|
---|
| 587 | {
|
---|
| 588 | Tracer tr("ColumnVector::resize_keep");
|
---|
| 589 | if (nr < nrows_val)
|
---|
| 590 | {
|
---|
| 591 | REPORT
|
---|
| 592 | ColumnVector X = rows(1,nr);
|
---|
| 593 | swap(X);
|
---|
| 594 | }
|
---|
| 595 | else if (nr > nrows_val)
|
---|
| 596 | {
|
---|
| 597 | REPORT
|
---|
| 598 | ColumnVector X(nr); X = 0;
|
---|
| 599 | X.rows(1,nrows_val) = *this;
|
---|
| 600 | swap(X);
|
---|
| 601 | }
|
---|
| 602 | }
|
---|
| 603 |
|
---|
| 604 | void ColumnVector::resize_keep(int nr, int nc)
|
---|
| 605 | {
|
---|
| 606 | Tracer tr("ColumnVector::resize_keep 2");
|
---|
| 607 | REPORT
|
---|
| 608 | if (nc != 1) Throw(VectorException(*this));
|
---|
| 609 | resize_keep(nr);
|
---|
| 610 | }
|
---|
| 611 |
|
---|
| 612 |
|
---|
| 613 | /*
|
---|
| 614 | void GeneralMatrix::resizeForAdd(const GeneralMatrix& A, const GeneralMatrix&)
|
---|
| 615 | { REPORT resize(A); }
|
---|
| 616 |
|
---|
| 617 | void GeneralMatrix::resizeForSP(const GeneralMatrix& A, const GeneralMatrix&)
|
---|
| 618 | { REPORT resize(A); }
|
---|
| 619 |
|
---|
| 620 |
|
---|
| 621 | // ************************* SameStorageType ******************************
|
---|
| 622 |
|
---|
| 623 | // SameStorageType checks A and B have same storage type including bandwidth
|
---|
| 624 | // It does not check same dimensions since we assume this is already done
|
---|
| 625 |
|
---|
| 626 | bool GeneralMatrix::SameStorageType(const GeneralMatrix& A) const
|
---|
| 627 | {
|
---|
| 628 | REPORT
|
---|
| 629 | return type() == A.type();
|
---|
| 630 | }
|
---|
| 631 | */
|
---|
| 632 |
|
---|
| 633 | // ******************* manipulate types, storage **************************/
|
---|
| 634 |
|
---|
| 635 | int GeneralMatrix::search(const BaseMatrix* s) const
|
---|
| 636 | { REPORT return (s==this) ? 1 : 0; }
|
---|
| 637 |
|
---|
| 638 | int GenericMatrix::search(const BaseMatrix* s) const
|
---|
| 639 | { REPORT return gm->search(s); }
|
---|
| 640 |
|
---|
| 641 | int MultipliedMatrix::search(const BaseMatrix* s) const
|
---|
| 642 | { REPORT return bm1->search(s) + bm2->search(s); }
|
---|
| 643 |
|
---|
| 644 | int ShiftedMatrix::search(const BaseMatrix* s) const
|
---|
| 645 | { REPORT return bm->search(s); }
|
---|
| 646 |
|
---|
| 647 | int NegatedMatrix::search(const BaseMatrix* s) const
|
---|
| 648 | { REPORT return bm->search(s); }
|
---|
| 649 |
|
---|
| 650 | int ReturnMatrix::search(const BaseMatrix* s) const
|
---|
| 651 | { REPORT return (s==gm) ? 1 : 0; }
|
---|
| 652 |
|
---|
| 653 | MatrixType Matrix::type() const { return MatrixType::Rt; }
|
---|
| 654 | MatrixType SquareMatrix::type() const { return MatrixType::Sq; }
|
---|
| 655 | MatrixType SymmetricMatrix::type() const { return MatrixType::Sm; }
|
---|
| 656 | MatrixType UpperTriangularMatrix::type() const { return MatrixType::UT; }
|
---|
| 657 | MatrixType LowerTriangularMatrix::type() const { return MatrixType::LT; }
|
---|
| 658 | MatrixType DiagonalMatrix::type() const { return MatrixType::Dg; }
|
---|
| 659 | MatrixType RowVector::type() const { return MatrixType::RV; }
|
---|
| 660 | MatrixType ColumnVector::type() const { return MatrixType::CV; }
|
---|
| 661 | MatrixType CroutMatrix::type() const { return MatrixType::Ct; }
|
---|
| 662 | MatrixType BandMatrix::type() const { return MatrixType::BM; }
|
---|
| 663 | MatrixType UpperBandMatrix::type() const { return MatrixType::UB; }
|
---|
| 664 | MatrixType LowerBandMatrix::type() const { return MatrixType::LB; }
|
---|
| 665 | MatrixType SymmetricBandMatrix::type() const { return MatrixType::SB; }
|
---|
| 666 |
|
---|
| 667 | MatrixType IdentityMatrix::type() const { return MatrixType::Id; }
|
---|
| 668 |
|
---|
| 669 |
|
---|
| 670 |
|
---|
| 671 | MatrixBandWidth BaseMatrix::bandwidth() const { REPORT return -1; }
|
---|
| 672 | MatrixBandWidth DiagonalMatrix::bandwidth() const { REPORT return 0; }
|
---|
| 673 | MatrixBandWidth IdentityMatrix::bandwidth() const { REPORT return 0; }
|
---|
| 674 |
|
---|
| 675 | MatrixBandWidth UpperTriangularMatrix::bandwidth() const
|
---|
| 676 | { REPORT return MatrixBandWidth(0,-1); }
|
---|
| 677 |
|
---|
| 678 | MatrixBandWidth LowerTriangularMatrix::bandwidth() const
|
---|
| 679 | { REPORT return MatrixBandWidth(-1,0); }
|
---|
| 680 |
|
---|
| 681 | MatrixBandWidth BandMatrix::bandwidth() const
|
---|
| 682 | { REPORT return MatrixBandWidth(lower_val,upper_val); }
|
---|
| 683 |
|
---|
| 684 | MatrixBandWidth BandLUMatrix::bandwidth() const
|
---|
| 685 | { REPORT return MatrixBandWidth(m1,m2); }
|
---|
| 686 |
|
---|
| 687 | MatrixBandWidth GenericMatrix::bandwidth()const
|
---|
| 688 | { REPORT return gm->bandwidth(); }
|
---|
| 689 |
|
---|
| 690 | MatrixBandWidth AddedMatrix::bandwidth() const
|
---|
| 691 | { REPORT return gm1->bandwidth() + gm2->bandwidth(); }
|
---|
| 692 |
|
---|
| 693 | MatrixBandWidth SPMatrix::bandwidth() const
|
---|
| 694 | { REPORT return gm1->bandwidth().minimum(gm2->bandwidth()); }
|
---|
| 695 |
|
---|
| 696 | MatrixBandWidth KPMatrix::bandwidth() const
|
---|
| 697 | {
|
---|
| 698 | int lower, upper;
|
---|
| 699 | MatrixBandWidth bw1 = gm1->bandwidth(), bw2 = gm2->bandwidth();
|
---|
| 700 | if (bw1.Lower() < 0)
|
---|
| 701 | {
|
---|
| 702 | if (bw2.Lower() < 0) { REPORT lower = -1; }
|
---|
| 703 | else { REPORT lower = bw2.Lower() + (gm1->Nrows() - 1) * gm2->Nrows(); }
|
---|
| 704 | }
|
---|
| 705 | else
|
---|
| 706 | {
|
---|
| 707 | if (bw2.Lower() < 0)
|
---|
| 708 | { REPORT lower = (1 + bw1.Lower()) * gm2->Nrows() - 1; }
|
---|
| 709 | else { REPORT lower = bw2.Lower() + bw1.Lower() * gm2->Nrows(); }
|
---|
| 710 | }
|
---|
| 711 | if (bw1.Upper() < 0)
|
---|
| 712 | {
|
---|
| 713 | if (bw2.Upper() < 0) { REPORT upper = -1; }
|
---|
| 714 | else { REPORT upper = bw2.Upper() + (gm1->Nrows() - 1) * gm2->Nrows(); }
|
---|
| 715 | }
|
---|
| 716 | else
|
---|
| 717 | {
|
---|
| 718 | if (bw2.Upper() < 0)
|
---|
| 719 | { REPORT upper = (1 + bw1.Upper()) * gm2->Nrows() - 1; }
|
---|
| 720 | else { REPORT upper = bw2.Upper() + bw1.Upper() * gm2->Nrows(); }
|
---|
| 721 | }
|
---|
| 722 | return MatrixBandWidth(lower, upper);
|
---|
| 723 | }
|
---|
| 724 |
|
---|
| 725 | MatrixBandWidth MultipliedMatrix::bandwidth() const
|
---|
| 726 | { REPORT return gm1->bandwidth() * gm2->bandwidth(); }
|
---|
| 727 |
|
---|
| 728 | MatrixBandWidth ConcatenatedMatrix::bandwidth() const { REPORT return -1; }
|
---|
| 729 |
|
---|
| 730 | MatrixBandWidth SolvedMatrix::bandwidth() const
|
---|
| 731 | {
|
---|
| 732 | if (+gm1->type() & MatrixType::Diagonal)
|
---|
| 733 | { REPORT return gm2->bandwidth(); }
|
---|
| 734 | else { REPORT return -1; }
|
---|
| 735 | }
|
---|
| 736 |
|
---|
| 737 | MatrixBandWidth ScaledMatrix::bandwidth() const
|
---|
| 738 | { REPORT return gm->bandwidth(); }
|
---|
| 739 |
|
---|
| 740 | MatrixBandWidth NegatedMatrix::bandwidth() const
|
---|
| 741 | { REPORT return gm->bandwidth(); }
|
---|
| 742 |
|
---|
| 743 | MatrixBandWidth TransposedMatrix::bandwidth() const
|
---|
| 744 | { REPORT return gm->bandwidth().t(); }
|
---|
| 745 |
|
---|
| 746 | MatrixBandWidth InvertedMatrix::bandwidth() const
|
---|
| 747 | {
|
---|
| 748 | if (+gm->type() & MatrixType::Diagonal)
|
---|
| 749 | { REPORT return MatrixBandWidth(0,0); }
|
---|
| 750 | else { REPORT return -1; }
|
---|
| 751 | }
|
---|
| 752 |
|
---|
| 753 | MatrixBandWidth RowedMatrix::bandwidth() const { REPORT return -1; }
|
---|
| 754 | MatrixBandWidth ColedMatrix::bandwidth() const { REPORT return -1; }
|
---|
| 755 | MatrixBandWidth DiagedMatrix::bandwidth() const { REPORT return 0; }
|
---|
| 756 | MatrixBandWidth MatedMatrix::bandwidth() const { REPORT return -1; }
|
---|
| 757 | MatrixBandWidth ReturnMatrix::bandwidth() const
|
---|
| 758 | { REPORT return gm->bandwidth(); }
|
---|
| 759 |
|
---|
| 760 | MatrixBandWidth GetSubMatrix::bandwidth() const
|
---|
| 761 | {
|
---|
| 762 |
|
---|
| 763 | if (row_skip==col_skip && row_number==col_number)
|
---|
| 764 | { REPORT return gm->bandwidth(); }
|
---|
| 765 | else { REPORT return MatrixBandWidth(-1); }
|
---|
| 766 | }
|
---|
| 767 |
|
---|
| 768 | // ********************** the memory managment tools **********************/
|
---|
| 769 |
|
---|
| 770 | // Rules regarding tDelete, reuse, GetStore, BorrowStore
|
---|
| 771 | // All matrices processed during expression evaluation must be subject
|
---|
| 772 | // to exactly one of reuse(), tDelete(), GetStore() or BorrowStore().
|
---|
| 773 | // If reuse returns true the matrix must be reused.
|
---|
| 774 | // GetMatrix(gm) always calls gm->GetStore()
|
---|
| 775 | // gm->Evaluate obeys rules
|
---|
| 776 | // bm->Evaluate obeys rules for matrices in bm structure
|
---|
| 777 |
|
---|
| 778 | // Meaning of tag_val
|
---|
| 779 | // tag_val = -1 memory cannot be reused (default situation)
|
---|
| 780 | // tag_val = -2 memory has been borrowed from another matrix
|
---|
| 781 | // (don't change values)
|
---|
| 782 | // tag_val = i > 0 delete or reuse memory after i operations
|
---|
| 783 | // tag_val = 0 like value 1 but matrix was created by new
|
---|
| 784 | // so delete it
|
---|
| 785 |
|
---|
| 786 | void GeneralMatrix::tDelete()
|
---|
| 787 | {
|
---|
| 788 | if (tag_val<0)
|
---|
| 789 | {
|
---|
| 790 | if (tag_val<-1) { REPORT store = 0; delete this; return; } // borrowed
|
---|
| 791 | else { REPORT return; } // not a temporary matrix - leave alone
|
---|
| 792 | }
|
---|
| 793 | if (tag_val==1)
|
---|
| 794 | {
|
---|
| 795 | if (store)
|
---|
| 796 | {
|
---|
| 797 | REPORT MONITOR_REAL_DELETE("Free (tDelete)",storage,store)
|
---|
| 798 | delete [] store;
|
---|
| 799 | }
|
---|
| 800 | MiniCleanUp(); return; // CleanUp
|
---|
| 801 | }
|
---|
| 802 | if (tag_val==0) { REPORT delete this; return; }
|
---|
| 803 |
|
---|
| 804 | REPORT tag_val--; return;
|
---|
| 805 | }
|
---|
| 806 |
|
---|
| 807 | void newmat_block_copy(int n, Real* from, Real* to)
|
---|
| 808 | {
|
---|
| 809 | REPORT
|
---|
| 810 | int i = (n >> 3);
|
---|
| 811 | while (i--)
|
---|
| 812 | {
|
---|
| 813 | *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++;
|
---|
| 814 | *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++;
|
---|
| 815 | }
|
---|
| 816 | i = n & 7; while (i--) *to++ = *from++;
|
---|
| 817 | }
|
---|
| 818 |
|
---|
| 819 | bool GeneralMatrix::reuse()
|
---|
| 820 | {
|
---|
| 821 | if (tag_val < -1) // borrowed storage
|
---|
| 822 | {
|
---|
| 823 | if (storage)
|
---|
| 824 | {
|
---|
| 825 | REPORT
|
---|
| 826 | Real* s = new Real [storage]; MatrixErrorNoSpace(s);
|
---|
| 827 | MONITOR_REAL_NEW("Make (reuse)",storage,s)
|
---|
| 828 | newmat_block_copy(storage, store, s); store = s;
|
---|
| 829 | }
|
---|
| 830 | else { REPORT MiniCleanUp(); } // CleanUp
|
---|
| 831 | tag_val = 0; return true;
|
---|
| 832 | }
|
---|
| 833 | if (tag_val < 0 ) { REPORT return false; }
|
---|
| 834 | if (tag_val <= 1 ) { REPORT return true; }
|
---|
| 835 | REPORT tag_val--; return false;
|
---|
| 836 | }
|
---|
| 837 |
|
---|
| 838 | Real* GeneralMatrix::GetStore()
|
---|
| 839 | {
|
---|
| 840 | if (tag_val<0 || tag_val>1)
|
---|
| 841 | {
|
---|
| 842 | Real* s;
|
---|
| 843 | if (storage)
|
---|
| 844 | {
|
---|
| 845 | s = new Real [storage]; MatrixErrorNoSpace(s);
|
---|
| 846 | MONITOR_REAL_NEW("Make (GetStore)",storage,s)
|
---|
| 847 | newmat_block_copy(storage, store, s);
|
---|
| 848 | }
|
---|
| 849 | else s = 0;
|
---|
| 850 | if (tag_val > 1) { REPORT tag_val--; }
|
---|
| 851 | else if (tag_val < -1) { REPORT store = 0; delete this; } // borrowed store
|
---|
| 852 | else { REPORT }
|
---|
| 853 | return s;
|
---|
| 854 | }
|
---|
| 855 | Real* s = store; // cleanup - done later
|
---|
| 856 | if (tag_val==0) { REPORT store = 0; delete this; }
|
---|
| 857 | else { REPORT MiniCleanUp(); }
|
---|
| 858 | return s;
|
---|
| 859 | }
|
---|
| 860 |
|
---|
| 861 | void GeneralMatrix::GetMatrix(const GeneralMatrix* gmx)
|
---|
| 862 | {
|
---|
| 863 | REPORT tag_val=-1; nrows_val=gmx->Nrows(); ncols_val=gmx->Ncols();
|
---|
| 864 | storage=gmx->storage; SetParameters(gmx);
|
---|
| 865 | store=((GeneralMatrix*)gmx)->GetStore();
|
---|
| 866 | }
|
---|
| 867 |
|
---|
| 868 | GeneralMatrix* GeneralMatrix::BorrowStore(GeneralMatrix* gmx, MatrixType mt)
|
---|
| 869 | // Copy storage of *this to storage of *gmx. Then convert to type mt.
|
---|
| 870 | // If mt == 0 just let *gmx point to storage of *this if tag_val==-1.
|
---|
| 871 | {
|
---|
| 872 | if (!mt)
|
---|
| 873 | {
|
---|
| 874 | if (tag_val == -1) { REPORT gmx->tag_val = -2; gmx->store = store; }
|
---|
| 875 | else { REPORT gmx->tag_val = 0; gmx->store = GetStore(); }
|
---|
| 876 | }
|
---|
| 877 | else if (Compare(gmx->type(),mt))
|
---|
| 878 | { REPORT gmx->tag_val = 0; gmx->store = GetStore(); }
|
---|
| 879 | else
|
---|
| 880 | {
|
---|
| 881 | REPORT gmx->tag_val = -2; gmx->store = store;
|
---|
| 882 | gmx = gmx->Evaluate(mt); gmx->tag_val = 0; tDelete();
|
---|
| 883 | }
|
---|
| 884 |
|
---|
| 885 | return gmx;
|
---|
| 886 | }
|
---|
| 887 |
|
---|
| 888 | void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt)
|
---|
| 889 | // Count number of references to this in X.
|
---|
| 890 | // If zero delete storage in this;
|
---|
| 891 | // otherwise tag this to show when storage can be deleted
|
---|
| 892 | // evaluate X and copy to this
|
---|
| 893 | {
|
---|
| 894 | #ifdef DO_SEARCH
|
---|
| 895 | int counter=X.search(this);
|
---|
| 896 | if (counter==0)
|
---|
| 897 | {
|
---|
| 898 | REPORT
|
---|
| 899 | if (store)
|
---|
| 900 | {
|
---|
| 901 | MONITOR_REAL_DELETE("Free (operator=)",storage,store)
|
---|
| 902 | REPORT delete [] store; storage = 0; store = 0;
|
---|
| 903 | }
|
---|
| 904 | }
|
---|
| 905 | else { REPORT Release(counter); }
|
---|
| 906 | GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
|
---|
| 907 | if (gmx!=this) { REPORT GetMatrix(gmx); }
|
---|
| 908 | else { REPORT }
|
---|
| 909 | Protect();
|
---|
| 910 | #else
|
---|
| 911 | GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
|
---|
| 912 | if (gmx!=this)
|
---|
| 913 | {
|
---|
| 914 | REPORT
|
---|
| 915 | if (store)
|
---|
| 916 | {
|
---|
| 917 | MONITOR_REAL_DELETE("Free (operator=)",storage,store)
|
---|
| 918 | REPORT delete [] store; storage = 0; store = 0;
|
---|
| 919 | }
|
---|
| 920 | GetMatrix(gmx);
|
---|
| 921 | }
|
---|
| 922 | else { REPORT }
|
---|
| 923 | Protect();
|
---|
| 924 | #endif
|
---|
| 925 | }
|
---|
| 926 |
|
---|
| 927 | // version with no conversion
|
---|
| 928 | void GeneralMatrix::Eq(const GeneralMatrix& X)
|
---|
| 929 | {
|
---|
| 930 | GeneralMatrix* gmx = (GeneralMatrix*)&X;
|
---|
| 931 | if (gmx!=this)
|
---|
| 932 | {
|
---|
| 933 | REPORT
|
---|
| 934 | if (store)
|
---|
| 935 | {
|
---|
| 936 | MONITOR_REAL_DELETE("Free (operator=)",storage,store)
|
---|
| 937 | REPORT delete [] store; storage = 0; store = 0;
|
---|
| 938 | }
|
---|
| 939 | GetMatrix(gmx);
|
---|
| 940 | }
|
---|
| 941 | else { REPORT }
|
---|
| 942 | Protect();
|
---|
| 943 | }
|
---|
| 944 |
|
---|
| 945 | // version to work with operator<<
|
---|
| 946 | void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt, bool ldok)
|
---|
| 947 | {
|
---|
| 948 | REPORT
|
---|
| 949 | if (ldok) mt.SetDataLossOK();
|
---|
| 950 | Eq(X, mt);
|
---|
| 951 | }
|
---|
| 952 |
|
---|
| 953 | void GeneralMatrix::Eq2(const BaseMatrix& X, MatrixType mt)
|
---|
| 954 | // a cut down version of Eq for use with += etc.
|
---|
| 955 | // we know BaseMatrix points to two GeneralMatrix objects,
|
---|
| 956 | // the first being this (may be the same).
|
---|
| 957 | // we know tag_val has been set correctly in each.
|
---|
| 958 | {
|
---|
| 959 | GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
|
---|
| 960 | if (gmx!=this) { REPORT GetMatrix(gmx); } // simplify GetMatrix ?
|
---|
| 961 | else { REPORT }
|
---|
| 962 | Protect();
|
---|
| 963 | }
|
---|
| 964 |
|
---|
| 965 | void GeneralMatrix::inject(const GeneralMatrix& X)
|
---|
| 966 | // copy stored values of X; otherwise leave els of *this unchanged
|
---|
| 967 | {
|
---|
| 968 | REPORT
|
---|
| 969 | Tracer tr("inject");
|
---|
| 970 | if (nrows_val != X.nrows_val || ncols_val != X.ncols_val)
|
---|
| 971 | Throw(IncompatibleDimensionsException());
|
---|
| 972 | MatrixRow mr((GeneralMatrix*)&X, LoadOnEntry);
|
---|
| 973 | MatrixRow mrx(this, LoadOnEntry+StoreOnExit+DirectPart);
|
---|
| 974 | int i=nrows_val;
|
---|
| 975 | while (i--) { mrx.Inject(mr); mrx.Next(); mr.Next(); }
|
---|
| 976 | }
|
---|
| 977 |
|
---|
| 978 | // ************* checking for data loss during conversion *******************/
|
---|
| 979 |
|
---|
| 980 | bool Compare(const MatrixType& source, MatrixType& destination)
|
---|
| 981 | {
|
---|
| 982 | if (!destination) { destination=source; return true; }
|
---|
| 983 | if (destination==source) return true;
|
---|
| 984 | if (!destination.DataLossOK && !(destination>=source))
|
---|
| 985 | Throw(ProgramException("Illegal Conversion", source, destination));
|
---|
| 986 | return false;
|
---|
| 987 | }
|
---|
| 988 |
|
---|
| 989 | // ************* Make a copy of a matrix on the heap *********************/
|
---|
| 990 |
|
---|
| 991 | GeneralMatrix* Matrix::Image() const
|
---|
| 992 | {
|
---|
| 993 | REPORT
|
---|
| 994 | GeneralMatrix* gm = new Matrix(*this); MatrixErrorNoSpace(gm);
|
---|
| 995 | return gm;
|
---|
| 996 | }
|
---|
| 997 |
|
---|
| 998 | GeneralMatrix* SquareMatrix::Image() const
|
---|
| 999 | {
|
---|
| 1000 | REPORT
|
---|
| 1001 | GeneralMatrix* gm = new SquareMatrix(*this); MatrixErrorNoSpace(gm);
|
---|
| 1002 | return gm;
|
---|
| 1003 | }
|
---|
| 1004 |
|
---|
| 1005 | GeneralMatrix* SymmetricMatrix::Image() const
|
---|
| 1006 | {
|
---|
| 1007 | REPORT
|
---|
| 1008 | GeneralMatrix* gm = new SymmetricMatrix(*this); MatrixErrorNoSpace(gm);
|
---|
| 1009 | return gm;
|
---|
| 1010 | }
|
---|
| 1011 |
|
---|
| 1012 | GeneralMatrix* UpperTriangularMatrix::Image() const
|
---|
| 1013 | {
|
---|
| 1014 | REPORT
|
---|
| 1015 | GeneralMatrix* gm = new UpperTriangularMatrix(*this);
|
---|
| 1016 | MatrixErrorNoSpace(gm); return gm;
|
---|
| 1017 | }
|
---|
| 1018 |
|
---|
| 1019 | GeneralMatrix* LowerTriangularMatrix::Image() const
|
---|
| 1020 | {
|
---|
| 1021 | REPORT
|
---|
| 1022 | GeneralMatrix* gm = new LowerTriangularMatrix(*this);
|
---|
| 1023 | MatrixErrorNoSpace(gm); return gm;
|
---|
| 1024 | }
|
---|
| 1025 |
|
---|
| 1026 | GeneralMatrix* DiagonalMatrix::Image() const
|
---|
| 1027 | {
|
---|
| 1028 | REPORT
|
---|
| 1029 | GeneralMatrix* gm = new DiagonalMatrix(*this); MatrixErrorNoSpace(gm);
|
---|
| 1030 | return gm;
|
---|
| 1031 | }
|
---|
| 1032 |
|
---|
| 1033 | GeneralMatrix* RowVector::Image() const
|
---|
| 1034 | {
|
---|
| 1035 | REPORT
|
---|
| 1036 | GeneralMatrix* gm = new RowVector(*this); MatrixErrorNoSpace(gm);
|
---|
| 1037 | return gm;
|
---|
| 1038 | }
|
---|
| 1039 |
|
---|
| 1040 | GeneralMatrix* ColumnVector::Image() const
|
---|
| 1041 | {
|
---|
| 1042 | REPORT
|
---|
| 1043 | GeneralMatrix* gm = new ColumnVector(*this); MatrixErrorNoSpace(gm);
|
---|
| 1044 | return gm;
|
---|
| 1045 | }
|
---|
| 1046 |
|
---|
| 1047 | GeneralMatrix* nricMatrix::Image() const
|
---|
| 1048 | {
|
---|
| 1049 | REPORT
|
---|
| 1050 | GeneralMatrix* gm = new nricMatrix(*this); MatrixErrorNoSpace(gm);
|
---|
| 1051 | return gm;
|
---|
| 1052 | }
|
---|
| 1053 |
|
---|
| 1054 | GeneralMatrix* IdentityMatrix::Image() const
|
---|
| 1055 | {
|
---|
| 1056 | REPORT
|
---|
| 1057 | GeneralMatrix* gm = new IdentityMatrix(*this); MatrixErrorNoSpace(gm);
|
---|
| 1058 | return gm;
|
---|
| 1059 | }
|
---|
| 1060 |
|
---|
| 1061 | GeneralMatrix* CroutMatrix::Image() const
|
---|
| 1062 | {
|
---|
| 1063 | REPORT
|
---|
| 1064 | GeneralMatrix* gm = new CroutMatrix(*this); MatrixErrorNoSpace(gm);
|
---|
| 1065 | return gm;
|
---|
| 1066 | }
|
---|
| 1067 |
|
---|
| 1068 | GeneralMatrix* GeneralMatrix::Image() const
|
---|
| 1069 | {
|
---|
| 1070 | bool dummy = true;
|
---|
| 1071 | if (dummy) // get rid of warning message
|
---|
| 1072 | Throw(InternalException("Cannot apply Image to this matrix type"));
|
---|
| 1073 | return 0;
|
---|
| 1074 | }
|
---|
| 1075 |
|
---|
| 1076 |
|
---|
| 1077 | // *********************** nricMatrix routines *****************************/
|
---|
| 1078 |
|
---|
| 1079 | void nricMatrix::MakeRowPointer()
|
---|
| 1080 | {
|
---|
| 1081 | REPORT
|
---|
| 1082 | if (nrows_val > 0)
|
---|
| 1083 | {
|
---|
| 1084 | row_pointer = new Real* [nrows_val]; MatrixErrorNoSpace(row_pointer);
|
---|
| 1085 | Real* s = Store() - 1; int i = nrows_val; Real** rp = row_pointer;
|
---|
| 1086 | if (i) for (;;) { *rp++ = s; if (!(--i)) break; s+=ncols_val; }
|
---|
| 1087 | }
|
---|
| 1088 | else row_pointer = 0;
|
---|
| 1089 | }
|
---|
| 1090 |
|
---|
| 1091 | void nricMatrix::DeleteRowPointer()
|
---|
| 1092 | { REPORT if (nrows_val) delete [] row_pointer; }
|
---|
| 1093 |
|
---|
| 1094 | void GeneralMatrix::CheckStore() const
|
---|
| 1095 | {
|
---|
| 1096 | REPORT
|
---|
| 1097 | if (!store)
|
---|
| 1098 | Throw(ProgramException("NRIC accessing matrix with unset dimensions"));
|
---|
| 1099 | }
|
---|
| 1100 |
|
---|
| 1101 |
|
---|
| 1102 | // *************************** CleanUp routines *****************************/
|
---|
| 1103 |
|
---|
| 1104 | void GeneralMatrix::cleanup()
|
---|
| 1105 | {
|
---|
| 1106 | // set matrix dimensions to zero, delete storage
|
---|
| 1107 | REPORT
|
---|
| 1108 | if (store && storage)
|
---|
| 1109 | {
|
---|
| 1110 | MONITOR_REAL_DELETE("Free (cleanup) ",storage,store)
|
---|
| 1111 | REPORT delete [] store;
|
---|
| 1112 | }
|
---|
| 1113 | store=0; storage=0; nrows_val=0; ncols_val=0; tag_val = -1;
|
---|
| 1114 | }
|
---|
| 1115 |
|
---|
| 1116 | void nricMatrix::cleanup()
|
---|
| 1117 | { REPORT DeleteRowPointer(); GeneralMatrix::cleanup(); }
|
---|
| 1118 |
|
---|
| 1119 | void nricMatrix::MiniCleanUp()
|
---|
| 1120 | { REPORT DeleteRowPointer(); GeneralMatrix::MiniCleanUp(); }
|
---|
| 1121 |
|
---|
| 1122 | void RowVector::cleanup()
|
---|
| 1123 | { REPORT GeneralMatrix::cleanup(); nrows_val=1; }
|
---|
| 1124 |
|
---|
| 1125 | void ColumnVector::cleanup()
|
---|
| 1126 | { REPORT GeneralMatrix::cleanup(); ncols_val=1; }
|
---|
| 1127 |
|
---|
| 1128 | void CroutMatrix::cleanup()
|
---|
| 1129 | {
|
---|
| 1130 | REPORT
|
---|
| 1131 | if (nrows_val) delete [] indx;
|
---|
| 1132 | GeneralMatrix::cleanup();
|
---|
| 1133 | }
|
---|
| 1134 |
|
---|
| 1135 | void CroutMatrix::MiniCleanUp()
|
---|
| 1136 | {
|
---|
| 1137 | REPORT
|
---|
| 1138 | if (nrows_val) delete [] indx;
|
---|
| 1139 | GeneralMatrix::MiniCleanUp();
|
---|
| 1140 | }
|
---|
| 1141 |
|
---|
| 1142 | void BandLUMatrix::cleanup()
|
---|
| 1143 | {
|
---|
| 1144 | REPORT
|
---|
| 1145 | if (nrows_val) delete [] indx;
|
---|
| 1146 | if (storage2) delete [] store2;
|
---|
| 1147 | GeneralMatrix::cleanup();
|
---|
| 1148 | }
|
---|
| 1149 |
|
---|
| 1150 | void BandLUMatrix::MiniCleanUp()
|
---|
| 1151 | {
|
---|
| 1152 | REPORT
|
---|
| 1153 | if (nrows_val) delete [] indx;
|
---|
| 1154 | if (storage2) delete [] store2;
|
---|
| 1155 | GeneralMatrix::MiniCleanUp();
|
---|
| 1156 | }
|
---|
| 1157 |
|
---|
| 1158 | // ************************ simple integer array class ***********************
|
---|
| 1159 |
|
---|
| 1160 | // construct a new array of length xn. Check that xn is non-negative and
|
---|
| 1161 | // that space is available
|
---|
| 1162 |
|
---|
| 1163 | SimpleIntArray::SimpleIntArray(int xn) : n(xn)
|
---|
| 1164 | {
|
---|
| 1165 | if (n < 0) Throw(Logic_error("invalid array length"));
|
---|
| 1166 | else if (n == 0) { REPORT a = 0; }
|
---|
| 1167 | else { REPORT a = new int [n]; if (!a) Throw(Bad_alloc()); }
|
---|
| 1168 | }
|
---|
| 1169 |
|
---|
| 1170 | // destroy an array - return its space to memory
|
---|
| 1171 |
|
---|
| 1172 | SimpleIntArray::~SimpleIntArray() { REPORT if (a) delete [] a; }
|
---|
| 1173 |
|
---|
| 1174 | // access an element of an array; return a "reference" so elements
|
---|
| 1175 | // can be modified.
|
---|
| 1176 | // check index is within range
|
---|
| 1177 | // in this array class the index runs from 0 to n-1
|
---|
| 1178 |
|
---|
| 1179 | int& SimpleIntArray::operator[](int i)
|
---|
| 1180 | {
|
---|
| 1181 | REPORT
|
---|
| 1182 | if (i < 0 || i >= n) Throw(Logic_error("array index out of range"));
|
---|
| 1183 | return a[i];
|
---|
| 1184 | }
|
---|
| 1185 |
|
---|
| 1186 | // same thing again but for arrays declared constant so we can't
|
---|
| 1187 | // modify its elements
|
---|
| 1188 |
|
---|
| 1189 | int SimpleIntArray::operator[](int i) const
|
---|
| 1190 | {
|
---|
| 1191 | REPORT
|
---|
| 1192 | if (i < 0 || i >= n) Throw(Logic_error("array index out of range"));
|
---|
| 1193 | return a[i];
|
---|
| 1194 | }
|
---|
| 1195 |
|
---|
| 1196 | // set all the elements equal to a given value
|
---|
| 1197 |
|
---|
| 1198 | void SimpleIntArray::operator=(int ai)
|
---|
| 1199 | { REPORT for (int i = 0; i < n; i++) a[i] = ai; }
|
---|
| 1200 |
|
---|
| 1201 | // set the elements equal to those of another array.
|
---|
| 1202 | // now allow length to be changed
|
---|
| 1203 |
|
---|
| 1204 | void SimpleIntArray::operator=(const SimpleIntArray& b)
|
---|
| 1205 | {
|
---|
| 1206 | REPORT
|
---|
| 1207 | if (b.n != n) resize(b.n);
|
---|
| 1208 | for (int i = 0; i < n; i++) a[i] = b.a[i];
|
---|
| 1209 | }
|
---|
| 1210 |
|
---|
| 1211 | // construct a new array equal to an existing array
|
---|
| 1212 | // check that space is available
|
---|
| 1213 |
|
---|
| 1214 | SimpleIntArray::SimpleIntArray(const SimpleIntArray& b) : Janitor(), n(b.n)
|
---|
| 1215 | {
|
---|
| 1216 | if (n == 0) { REPORT a = 0; }
|
---|
| 1217 | else
|
---|
| 1218 | {
|
---|
| 1219 | REPORT
|
---|
| 1220 | a = new int [n]; if (!a) Throw(Bad_alloc());
|
---|
| 1221 | for (int i = 0; i < n; i++) a[i] = b.a[i];
|
---|
| 1222 | }
|
---|
| 1223 | }
|
---|
| 1224 |
|
---|
| 1225 | // change the size of an array; optionally copy data from old array to
|
---|
| 1226 | // new array
|
---|
| 1227 |
|
---|
| 1228 | void SimpleIntArray::resize(int n1, bool keep)
|
---|
| 1229 | {
|
---|
| 1230 | if (n1 == n) { REPORT return; }
|
---|
| 1231 | else if (n1 == 0) { REPORT n = 0; delete [] a; a = 0; }
|
---|
| 1232 | else if (n == 0)
|
---|
| 1233 | {
|
---|
| 1234 | REPORT
|
---|
| 1235 | a = new int [n1]; if (!a) Throw(Bad_alloc());
|
---|
| 1236 | n = n1;
|
---|
| 1237 | if (keep) operator=(0);
|
---|
| 1238 | }
|
---|
| 1239 | else
|
---|
| 1240 | {
|
---|
| 1241 | int* a1 = a;
|
---|
| 1242 | if (keep)
|
---|
| 1243 | {
|
---|
| 1244 | REPORT
|
---|
| 1245 | int i;
|
---|
| 1246 | a = new int [n1]; if (!a) Throw(Bad_alloc());
|
---|
| 1247 | if (n > n1) n = n1;
|
---|
| 1248 | else for (i = n; i < n1; i++) a[i] = 0;
|
---|
| 1249 | for (i = 0; i < n; i++) a[i] = a1[i];
|
---|
| 1250 | n = n1; delete [] a1;
|
---|
| 1251 | }
|
---|
| 1252 | else
|
---|
| 1253 | {
|
---|
| 1254 | REPORT n = n1; delete [] a1;
|
---|
| 1255 | a = new int [n]; if (!a) Throw(Bad_alloc());
|
---|
| 1256 | }
|
---|
| 1257 | }
|
---|
| 1258 | }
|
---|
| 1259 |
|
---|
| 1260 | //************************** swap values ********************************
|
---|
| 1261 |
|
---|
| 1262 | // swap values
|
---|
| 1263 |
|
---|
| 1264 | void GeneralMatrix::swap(GeneralMatrix& gm)
|
---|
| 1265 | {
|
---|
| 1266 | REPORT
|
---|
| 1267 | int t;
|
---|
| 1268 | t = tag_val; tag_val = gm.tag_val; gm.tag_val = t;
|
---|
| 1269 | t = nrows_val; nrows_val = gm.nrows_val; gm.nrows_val = t;
|
---|
| 1270 | t = ncols_val; ncols_val = gm.ncols_val; gm.ncols_val = t;
|
---|
| 1271 | t = storage; storage = gm.storage; gm.storage = t;
|
---|
| 1272 | Real* s = store; store = gm.store; gm.store = s;
|
---|
| 1273 | }
|
---|
| 1274 |
|
---|
| 1275 | void nricMatrix::swap(nricMatrix& gm)
|
---|
| 1276 | {
|
---|
| 1277 | REPORT
|
---|
| 1278 | GeneralMatrix::swap((GeneralMatrix&)gm);
|
---|
| 1279 | Real** rp = row_pointer; row_pointer = gm.row_pointer; gm.row_pointer = rp;
|
---|
| 1280 | }
|
---|
| 1281 |
|
---|
| 1282 | void CroutMatrix::swap(CroutMatrix& gm)
|
---|
| 1283 | {
|
---|
| 1284 | REPORT
|
---|
| 1285 | GeneralMatrix::swap((GeneralMatrix&)gm);
|
---|
| 1286 | int* i = indx; indx = gm.indx; gm.indx = i;
|
---|
| 1287 | bool b;
|
---|
| 1288 | b = d; d = gm.d; gm.d = b;
|
---|
| 1289 | b = sing; sing = gm.sing; gm.sing = b;
|
---|
| 1290 | }
|
---|
| 1291 |
|
---|
| 1292 | void BandMatrix::swap(BandMatrix& gm)
|
---|
| 1293 | {
|
---|
| 1294 | REPORT
|
---|
| 1295 | GeneralMatrix::swap((GeneralMatrix&)gm);
|
---|
| 1296 | int i;
|
---|
| 1297 | i = lower_val; lower_val = gm.lower_val; gm.lower_val = i;
|
---|
| 1298 | i = upper_val; upper_val = gm.upper_val; gm.upper_val = i;
|
---|
| 1299 | }
|
---|
| 1300 |
|
---|
| 1301 | void SymmetricBandMatrix::swap(SymmetricBandMatrix& gm)
|
---|
| 1302 | {
|
---|
| 1303 | REPORT
|
---|
| 1304 | GeneralMatrix::swap((GeneralMatrix&)gm);
|
---|
| 1305 | int i;
|
---|
| 1306 | i = lower_val; lower_val = gm.lower_val; gm.lower_val = i;
|
---|
| 1307 | }
|
---|
| 1308 |
|
---|
| 1309 | void BandLUMatrix::swap(BandLUMatrix& gm)
|
---|
| 1310 | {
|
---|
| 1311 | REPORT
|
---|
| 1312 | GeneralMatrix::swap((GeneralMatrix&)gm);
|
---|
| 1313 | int* i = indx; indx = gm.indx; gm.indx = i;
|
---|
| 1314 | bool b;
|
---|
| 1315 | b = d; d = gm.d; gm.d = b;
|
---|
| 1316 | b = sing; sing = gm.sing; gm.sing = b;
|
---|
| 1317 | int m;
|
---|
| 1318 | m = storage2; storage2 = gm.storage2; gm.storage2 = m;
|
---|
| 1319 | m = m1; m1 = gm.m1; gm.m1 = m;
|
---|
| 1320 | m = m2; m2 = gm.m2; gm.m2 = m;
|
---|
| 1321 | Real* s = store2; store2 = gm.store2; gm.store2 = s;
|
---|
| 1322 | }
|
---|
| 1323 |
|
---|
| 1324 | void GenericMatrix::swap(GenericMatrix& x)
|
---|
| 1325 | {
|
---|
| 1326 | REPORT
|
---|
| 1327 | GeneralMatrix* tgm = gm; gm = x.gm; x.gm = tgm;
|
---|
| 1328 | }
|
---|
| 1329 |
|
---|
| 1330 | // ********************** C subscript classes ****************************
|
---|
| 1331 |
|
---|
| 1332 | RealStarStar::RealStarStar(Matrix& A)
|
---|
| 1333 | {
|
---|
| 1334 | REPORT
|
---|
| 1335 | Tracer tr("RealStarStar");
|
---|
| 1336 | int n = A.ncols();
|
---|
| 1337 | int m = A.nrows();
|
---|
| 1338 | a = new Real*[m];
|
---|
| 1339 | MatrixErrorNoSpace(a);
|
---|
| 1340 | Real* d = A.data();
|
---|
| 1341 | for (int i = 0; i < m; ++i) a[i] = d + i * n;
|
---|
| 1342 | }
|
---|
| 1343 |
|
---|
| 1344 | ConstRealStarStar::ConstRealStarStar(const Matrix& A)
|
---|
| 1345 | {
|
---|
| 1346 | REPORT
|
---|
| 1347 | Tracer tr("ConstRealStarStar");
|
---|
| 1348 | int n = A.ncols();
|
---|
| 1349 | int m = A.nrows();
|
---|
| 1350 | a = new const Real*[m];
|
---|
| 1351 | MatrixErrorNoSpace(a);
|
---|
| 1352 | const Real* d = A.data();
|
---|
| 1353 | for (int i = 0; i < m; ++i) a[i] = d + i * n;
|
---|
| 1354 | }
|
---|
| 1355 |
|
---|
| 1356 |
|
---|
| 1357 |
|
---|
| 1358 | #ifdef use_namespace
|
---|
| 1359 | }
|
---|
| 1360 | #endif
|
---|
| 1361 |
|
---|
| 1362 |
|
---|
| 1363 | /// \fn GeneralMatrix::SimpleAddOK(const GeneralMatrix* gm)
|
---|
| 1364 | /// Can we add two matrices with simple vector add.
|
---|
| 1365 | /// SimpleAddOK shows when we can add two matrices by a simple vector add
|
---|
| 1366 | /// and when we can add one matrix into another
|
---|
| 1367 | ///
|
---|
| 1368 | /// *gm must be the same type as *this
|
---|
| 1369 | /// - return 0 if simple add is OK
|
---|
| 1370 | /// - return 1 if we can add into *gm only
|
---|
| 1371 | /// - return 2 if we can add into *this only
|
---|
| 1372 | /// - return 3 if we can't add either way
|
---|
| 1373 | ///
|
---|
| 1374 | /// Also applies to subtract;
|
---|
| 1375 | /// for SP this will still be valid if we swap 1 and 2
|
---|
| 1376 | ///
|
---|
| 1377 | /// For types Matrix, DiagonalMatrix, UpperTriangularMatrix,
|
---|
| 1378 | /// LowerTriangularMatrix, SymmetricMatrix etc return 0.
|
---|
| 1379 | /// For band matrices we will need to check bandwidths.
|
---|
| 1380 |
|
---|
| 1381 |
|
---|
| 1382 |
|
---|
| 1383 |
|
---|
| 1384 |
|
---|
| 1385 |
|
---|
| 1386 |
|
---|
| 1387 | ///@}
|
---|