[4565] | 1 | //$$ newmat4.cpp Constructors, ReSize, basic utilities |
---|
| 2 | |
---|
| 3 | // Copyright (C) 1991,2,3,4,8,9: R B Davies |
---|
| 4 | |
---|
| 5 | #include "include.h" |
---|
| 6 | |
---|
| 7 | #include "newmat.h" |
---|
| 8 | #include "newmatrc.h" |
---|
| 9 | |
---|
| 10 | #ifdef use_namespace |
---|
| 11 | namespace NEWMAT { |
---|
| 12 | #endif |
---|
| 13 | |
---|
| 14 | |
---|
| 15 | |
---|
| 16 | #ifdef DO_REPORT |
---|
| 17 | #define REPORT { static ExeCounter ExeCount(__LINE__,4); ++ExeCount; } |
---|
| 18 | #else |
---|
| 19 | #define REPORT {} |
---|
| 20 | #endif |
---|
| 21 | |
---|
| 22 | |
---|
| 23 | #define DO_SEARCH // search for LHS of = in RHS |
---|
| 24 | |
---|
| 25 | // ************************* general utilities *************************/ |
---|
| 26 | |
---|
| 27 | static int tristore(int n) // elements in triangular matrix |
---|
| 28 | { return (n*(n+1))/2; } |
---|
| 29 | |
---|
| 30 | |
---|
| 31 | // **************************** constructors ***************************/ |
---|
| 32 | |
---|
| 33 | GeneralMatrix::GeneralMatrix() |
---|
| 34 | { store=0; storage=0; nrows=0; ncols=0; tag=-1; } |
---|
| 35 | |
---|
| 36 | GeneralMatrix::GeneralMatrix(ArrayLengthSpecifier s) |
---|
| 37 | { |
---|
| 38 | REPORT |
---|
| 39 | storage=s.Value(); tag=-1; |
---|
| 40 | if (storage) |
---|
| 41 | { |
---|
| 42 | store = new Real [storage]; MatrixErrorNoSpace(store); |
---|
| 43 | MONITOR_REAL_NEW("Make (GenMatrix)",storage,store) |
---|
| 44 | } |
---|
| 45 | else store = 0; |
---|
| 46 | } |
---|
| 47 | |
---|
| 48 | Matrix::Matrix(int m, int n) : GeneralMatrix(m*n) |
---|
| 49 | { REPORT nrows=m; ncols=n; } |
---|
| 50 | |
---|
| 51 | SymmetricMatrix::SymmetricMatrix(ArrayLengthSpecifier n) |
---|
| 52 | : GeneralMatrix(tristore(n.Value())) |
---|
| 53 | { REPORT nrows=n.Value(); ncols=n.Value(); } |
---|
| 54 | |
---|
| 55 | UpperTriangularMatrix::UpperTriangularMatrix(ArrayLengthSpecifier n) |
---|
| 56 | : GeneralMatrix(tristore(n.Value())) |
---|
| 57 | { REPORT nrows=n.Value(); ncols=n.Value(); } |
---|
| 58 | |
---|
| 59 | LowerTriangularMatrix::LowerTriangularMatrix(ArrayLengthSpecifier n) |
---|
| 60 | : GeneralMatrix(tristore(n.Value())) |
---|
| 61 | { REPORT nrows=n.Value(); ncols=n.Value(); } |
---|
| 62 | |
---|
| 63 | DiagonalMatrix::DiagonalMatrix(ArrayLengthSpecifier m) : GeneralMatrix(m) |
---|
| 64 | { REPORT nrows=m.Value(); ncols=m.Value(); } |
---|
| 65 | |
---|
| 66 | Matrix::Matrix(const BaseMatrix& M) |
---|
| 67 | { |
---|
| 68 | REPORT // CheckConversion(M); |
---|
| 69 | // MatrixConversionCheck mcc; |
---|
| 70 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Rt); |
---|
| 71 | GetMatrix(gmx); |
---|
| 72 | } |
---|
| 73 | |
---|
| 74 | RowVector::RowVector(const BaseMatrix& M) : Matrix(M) |
---|
| 75 | { |
---|
| 76 | if (nrows!=1) |
---|
| 77 | { |
---|
| 78 | Tracer tr("RowVector"); |
---|
| 79 | Throw(VectorException(*this)); |
---|
| 80 | } |
---|
| 81 | } |
---|
| 82 | |
---|
| 83 | ColumnVector::ColumnVector(const BaseMatrix& M) : Matrix(M) |
---|
| 84 | { |
---|
| 85 | if (ncols!=1) |
---|
| 86 | { |
---|
| 87 | Tracer tr("ColumnVector"); |
---|
| 88 | Throw(VectorException(*this)); |
---|
| 89 | } |
---|
| 90 | } |
---|
| 91 | |
---|
| 92 | SymmetricMatrix::SymmetricMatrix(const BaseMatrix& M) |
---|
| 93 | { |
---|
| 94 | REPORT // CheckConversion(M); |
---|
| 95 | // MatrixConversionCheck mcc; |
---|
| 96 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Sm); |
---|
| 97 | GetMatrix(gmx); |
---|
| 98 | } |
---|
| 99 | |
---|
| 100 | UpperTriangularMatrix::UpperTriangularMatrix(const BaseMatrix& M) |
---|
| 101 | { |
---|
| 102 | REPORT // CheckConversion(M); |
---|
| 103 | // MatrixConversionCheck mcc; |
---|
| 104 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::UT); |
---|
| 105 | GetMatrix(gmx); |
---|
| 106 | } |
---|
| 107 | |
---|
| 108 | LowerTriangularMatrix::LowerTriangularMatrix(const BaseMatrix& M) |
---|
| 109 | { |
---|
| 110 | REPORT // CheckConversion(M); |
---|
| 111 | // MatrixConversionCheck mcc; |
---|
| 112 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::LT); |
---|
| 113 | GetMatrix(gmx); |
---|
| 114 | } |
---|
| 115 | |
---|
| 116 | DiagonalMatrix::DiagonalMatrix(const BaseMatrix& M) |
---|
| 117 | { |
---|
| 118 | REPORT //CheckConversion(M); |
---|
| 119 | // MatrixConversionCheck mcc; |
---|
| 120 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Dg); |
---|
| 121 | GetMatrix(gmx); |
---|
| 122 | } |
---|
| 123 | |
---|
| 124 | IdentityMatrix::IdentityMatrix(const BaseMatrix& M) |
---|
| 125 | { |
---|
| 126 | REPORT //CheckConversion(M); |
---|
| 127 | // MatrixConversionCheck mcc; |
---|
| 128 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Id); |
---|
| 129 | GetMatrix(gmx); |
---|
| 130 | } |
---|
| 131 | |
---|
| 132 | GeneralMatrix::~GeneralMatrix() |
---|
| 133 | { |
---|
| 134 | if (store) |
---|
| 135 | { |
---|
| 136 | MONITOR_REAL_DELETE("Free (GenMatrix)",storage,store) |
---|
| 137 | delete [] store; |
---|
| 138 | } |
---|
| 139 | } |
---|
| 140 | |
---|
| 141 | CroutMatrix::CroutMatrix(const BaseMatrix& m) |
---|
| 142 | { |
---|
| 143 | REPORT |
---|
| 144 | Tracer tr("CroutMatrix"); |
---|
| 145 | indx = 0; // in case of exception at next line |
---|
| 146 | GeneralMatrix* gm = ((BaseMatrix&)m).Evaluate(MatrixType::Rt); |
---|
| 147 | GetMatrix(gm); |
---|
| 148 | if (nrows!=ncols) { CleanUp(); Throw(NotSquareException(*gm)); } |
---|
| 149 | d=true; sing=false; |
---|
| 150 | indx=new int [nrows]; MatrixErrorNoSpace(indx); |
---|
| 151 | MONITOR_INT_NEW("Index (CroutMat)",nrows,indx) |
---|
| 152 | ludcmp(); |
---|
| 153 | } |
---|
| 154 | |
---|
| 155 | CroutMatrix::~CroutMatrix() |
---|
| 156 | { |
---|
| 157 | MONITOR_INT_DELETE("Index (CroutMat)",nrows,indx) |
---|
| 158 | delete [] indx; |
---|
| 159 | } |
---|
| 160 | |
---|
| 161 | //ReturnMatrixX::ReturnMatrixX(GeneralMatrix& gmx) |
---|
| 162 | //{ |
---|
| 163 | // REPORT |
---|
| 164 | // gm = gmx.Image(); gm->ReleaseAndDelete(); |
---|
| 165 | //} |
---|
| 166 | |
---|
| 167 | #ifndef TEMPS_DESTROYED_QUICKLY_R |
---|
| 168 | |
---|
| 169 | GeneralMatrix::operator ReturnMatrixX() const |
---|
| 170 | { |
---|
| 171 | REPORT |
---|
| 172 | GeneralMatrix* gm = Image(); gm->ReleaseAndDelete(); |
---|
| 173 | return ReturnMatrixX(gm); |
---|
| 174 | } |
---|
| 175 | |
---|
| 176 | #else |
---|
| 177 | |
---|
| 178 | GeneralMatrix::operator ReturnMatrixX&() const |
---|
| 179 | { |
---|
| 180 | REPORT |
---|
| 181 | GeneralMatrix* gm = Image(); gm->ReleaseAndDelete(); |
---|
| 182 | ReturnMatrixX* x = new ReturnMatrixX(gm); |
---|
| 183 | MatrixErrorNoSpace(x); return *x; |
---|
| 184 | } |
---|
| 185 | |
---|
| 186 | #endif |
---|
| 187 | |
---|
| 188 | #ifndef TEMPS_DESTROYED_QUICKLY_R |
---|
| 189 | |
---|
| 190 | ReturnMatrixX GeneralMatrix::ForReturn() const |
---|
| 191 | { |
---|
| 192 | REPORT |
---|
| 193 | GeneralMatrix* gm = Image(); gm->ReleaseAndDelete(); |
---|
| 194 | return ReturnMatrixX(gm); |
---|
| 195 | } |
---|
| 196 | |
---|
| 197 | #else |
---|
| 198 | |
---|
| 199 | ReturnMatrixX& GeneralMatrix::ForReturn() const |
---|
| 200 | { |
---|
| 201 | REPORT |
---|
| 202 | GeneralMatrix* gm = Image(); gm->ReleaseAndDelete(); |
---|
| 203 | ReturnMatrixX* x = new ReturnMatrixX(gm); |
---|
| 204 | MatrixErrorNoSpace(x); return *x; |
---|
| 205 | } |
---|
| 206 | |
---|
| 207 | #endif |
---|
| 208 | |
---|
| 209 | // ************************** ReSize matrices ***************************/ |
---|
| 210 | |
---|
| 211 | void GeneralMatrix::ReSize(int nr, int nc, int s) |
---|
| 212 | { |
---|
| 213 | REPORT |
---|
| 214 | if (store) |
---|
| 215 | { |
---|
| 216 | MONITOR_REAL_DELETE("Free (ReDimensi)",storage,store) |
---|
| 217 | delete [] store; |
---|
| 218 | } |
---|
| 219 | storage=s; nrows=nr; ncols=nc; tag=-1; |
---|
| 220 | if (s) |
---|
| 221 | { |
---|
| 222 | store = new Real [storage]; MatrixErrorNoSpace(store); |
---|
| 223 | MONITOR_REAL_NEW("Make (ReDimensi)",storage,store) |
---|
| 224 | } |
---|
| 225 | else store = 0; |
---|
| 226 | } |
---|
| 227 | |
---|
| 228 | void Matrix::ReSize(int nr, int nc) |
---|
| 229 | { REPORT GeneralMatrix::ReSize(nr,nc,nr*nc); } |
---|
| 230 | |
---|
| 231 | void SymmetricMatrix::ReSize(int nr) |
---|
| 232 | { REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); } |
---|
| 233 | |
---|
| 234 | void UpperTriangularMatrix::ReSize(int nr) |
---|
| 235 | { REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); } |
---|
| 236 | |
---|
| 237 | void LowerTriangularMatrix::ReSize(int nr) |
---|
| 238 | { REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); } |
---|
| 239 | |
---|
| 240 | void DiagonalMatrix::ReSize(int nr) |
---|
| 241 | { REPORT GeneralMatrix::ReSize(nr,nr,nr); } |
---|
| 242 | |
---|
| 243 | void RowVector::ReSize(int nc) |
---|
| 244 | { REPORT GeneralMatrix::ReSize(1,nc,nc); } |
---|
| 245 | |
---|
| 246 | void ColumnVector::ReSize(int nr) |
---|
| 247 | { REPORT GeneralMatrix::ReSize(nr,1,nr); } |
---|
| 248 | |
---|
| 249 | void RowVector::ReSize(int nr, int nc) |
---|
| 250 | { |
---|
| 251 | Tracer tr("RowVector::ReSize"); |
---|
| 252 | if (nr != 1) Throw(VectorException(*this)); |
---|
| 253 | REPORT GeneralMatrix::ReSize(1,nc,nc); |
---|
| 254 | } |
---|
| 255 | |
---|
| 256 | void ColumnVector::ReSize(int nr, int nc) |
---|
| 257 | { |
---|
| 258 | Tracer tr("ColumnVector::ReSize"); |
---|
| 259 | if (nc != 1) Throw(VectorException(*this)); |
---|
| 260 | REPORT GeneralMatrix::ReSize(nr,1,nr); |
---|
| 261 | } |
---|
| 262 | |
---|
| 263 | void IdentityMatrix::ReSize(int nr) |
---|
| 264 | { REPORT GeneralMatrix::ReSize(nr,nr,1); *store = 1; } |
---|
| 265 | |
---|
| 266 | |
---|
| 267 | void Matrix::ReSize(const GeneralMatrix& A) |
---|
| 268 | { REPORT ReSize(A.Nrows(), A.Ncols()); } |
---|
| 269 | |
---|
| 270 | void nricMatrix::ReSize(const GeneralMatrix& A) |
---|
| 271 | { REPORT ReSize(A.Nrows(), A.Ncols()); } |
---|
| 272 | |
---|
| 273 | void ColumnVector::ReSize(const GeneralMatrix& A) |
---|
| 274 | { REPORT ReSize(A.Nrows(), A.Ncols()); } |
---|
| 275 | |
---|
| 276 | void RowVector::ReSize(const GeneralMatrix& A) |
---|
| 277 | { REPORT ReSize(A.Nrows(), A.Ncols()); } |
---|
| 278 | |
---|
| 279 | void SymmetricMatrix::ReSize(const GeneralMatrix& A) |
---|
| 280 | { |
---|
| 281 | REPORT |
---|
| 282 | int n = A.Nrows(); |
---|
| 283 | if (n != A.Ncols()) |
---|
| 284 | { |
---|
| 285 | Tracer tr("SymmetricMatrix::ReSize(GM)"); |
---|
| 286 | Throw(NotSquareException(*this)); |
---|
| 287 | } |
---|
| 288 | ReSize(n); |
---|
| 289 | } |
---|
| 290 | |
---|
| 291 | void DiagonalMatrix::ReSize(const GeneralMatrix& A) |
---|
| 292 | { |
---|
| 293 | REPORT |
---|
| 294 | int n = A.Nrows(); |
---|
| 295 | if (n != A.Ncols()) |
---|
| 296 | { |
---|
| 297 | Tracer tr("DiagonalMatrix::ReSize(GM)"); |
---|
| 298 | Throw(NotSquareException(*this)); |
---|
| 299 | } |
---|
| 300 | ReSize(n); |
---|
| 301 | } |
---|
| 302 | |
---|
| 303 | void UpperTriangularMatrix::ReSize(const GeneralMatrix& A) |
---|
| 304 | { |
---|
| 305 | REPORT |
---|
| 306 | int n = A.Nrows(); |
---|
| 307 | if (n != A.Ncols()) |
---|
| 308 | { |
---|
| 309 | Tracer tr("UpperTriangularMatrix::ReSize(GM)"); |
---|
| 310 | Throw(NotSquareException(*this)); |
---|
| 311 | } |
---|
| 312 | ReSize(n); |
---|
| 313 | } |
---|
| 314 | |
---|
| 315 | void LowerTriangularMatrix::ReSize(const GeneralMatrix& A) |
---|
| 316 | { |
---|
| 317 | REPORT |
---|
| 318 | int n = A.Nrows(); |
---|
| 319 | if (n != A.Ncols()) |
---|
| 320 | { |
---|
| 321 | Tracer tr("LowerTriangularMatrix::ReSize(GM)"); |
---|
| 322 | Throw(NotSquareException(*this)); |
---|
| 323 | } |
---|
| 324 | ReSize(n); |
---|
| 325 | } |
---|
| 326 | |
---|
| 327 | void IdentityMatrix::ReSize(const GeneralMatrix& A) |
---|
| 328 | { |
---|
| 329 | REPORT |
---|
| 330 | int n = A.Nrows(); |
---|
| 331 | if (n != A.Ncols()) |
---|
| 332 | { |
---|
| 333 | Tracer tr("IdentityMatrix::ReSize(GM)"); |
---|
| 334 | Throw(NotSquareException(*this)); |
---|
| 335 | } |
---|
| 336 | ReSize(n); |
---|
| 337 | } |
---|
| 338 | |
---|
| 339 | void GeneralMatrix::ReSize(const GeneralMatrix&) |
---|
| 340 | { |
---|
| 341 | REPORT |
---|
| 342 | Tracer tr("GeneralMatrix::ReSize(GM)"); |
---|
| 343 | Throw(NotDefinedException("ReSize", "this type of matrix")); |
---|
| 344 | } |
---|
| 345 | |
---|
| 346 | void GeneralMatrix::ReSizeForAdd(const GeneralMatrix& A, const GeneralMatrix&) |
---|
| 347 | { REPORT ReSize(A); } |
---|
| 348 | |
---|
| 349 | void GeneralMatrix::ReSizeForSP(const GeneralMatrix& A, const GeneralMatrix&) |
---|
| 350 | { REPORT ReSize(A); } |
---|
| 351 | |
---|
| 352 | |
---|
| 353 | // ************************* SameStorageType ******************************/ |
---|
| 354 | |
---|
| 355 | // SameStorageType checks A and B have same storage type including bandwidth |
---|
| 356 | // It does not check same dimensions since we assume this is already done |
---|
| 357 | |
---|
| 358 | bool GeneralMatrix::SameStorageType(const GeneralMatrix& A) const |
---|
| 359 | { |
---|
| 360 | REPORT |
---|
| 361 | return Type() == A.Type(); |
---|
| 362 | } |
---|
| 363 | |
---|
| 364 | |
---|
| 365 | // ******************* manipulate types, storage **************************/ |
---|
| 366 | |
---|
| 367 | int GeneralMatrix::search(const BaseMatrix* s) const |
---|
| 368 | { REPORT return (s==this) ? 1 : 0; } |
---|
| 369 | |
---|
| 370 | int GenericMatrix::search(const BaseMatrix* s) const |
---|
| 371 | { REPORT return gm->search(s); } |
---|
| 372 | |
---|
| 373 | int MultipliedMatrix::search(const BaseMatrix* s) const |
---|
| 374 | { REPORT return bm1->search(s) + bm2->search(s); } |
---|
| 375 | |
---|
| 376 | int ShiftedMatrix::search(const BaseMatrix* s) const |
---|
| 377 | { REPORT return bm->search(s); } |
---|
| 378 | |
---|
| 379 | int NegatedMatrix::search(const BaseMatrix* s) const |
---|
| 380 | { REPORT return bm->search(s); } |
---|
| 381 | |
---|
| 382 | int ReturnMatrixX::search(const BaseMatrix* s) const |
---|
| 383 | { REPORT return (s==gm) ? 1 : 0; } |
---|
| 384 | |
---|
| 385 | MatrixType Matrix::Type() const { return MatrixType::Rt; } |
---|
| 386 | MatrixType SymmetricMatrix::Type() const { return MatrixType::Sm; } |
---|
| 387 | MatrixType UpperTriangularMatrix::Type() const { return MatrixType::UT; } |
---|
| 388 | MatrixType LowerTriangularMatrix::Type() const { return MatrixType::LT; } |
---|
| 389 | MatrixType DiagonalMatrix::Type() const { return MatrixType::Dg; } |
---|
| 390 | MatrixType RowVector::Type() const { return MatrixType::RV; } |
---|
| 391 | MatrixType ColumnVector::Type() const { return MatrixType::CV; } |
---|
| 392 | MatrixType CroutMatrix::Type() const { return MatrixType::Ct; } |
---|
| 393 | MatrixType BandMatrix::Type() const { return MatrixType::BM; } |
---|
| 394 | MatrixType UpperBandMatrix::Type() const { return MatrixType::UB; } |
---|
| 395 | MatrixType LowerBandMatrix::Type() const { return MatrixType::LB; } |
---|
| 396 | MatrixType SymmetricBandMatrix::Type() const { return MatrixType::SB; } |
---|
| 397 | |
---|
| 398 | MatrixType IdentityMatrix::Type() const { return MatrixType::Id; } |
---|
| 399 | |
---|
| 400 | |
---|
| 401 | |
---|
| 402 | MatrixBandWidth BaseMatrix::BandWidth() const { REPORT return -1; } |
---|
| 403 | MatrixBandWidth DiagonalMatrix::BandWidth() const { REPORT return 0; } |
---|
| 404 | MatrixBandWidth IdentityMatrix::BandWidth() const { REPORT return 0; } |
---|
| 405 | |
---|
| 406 | MatrixBandWidth UpperTriangularMatrix::BandWidth() const |
---|
| 407 | { REPORT return MatrixBandWidth(0,-1); } |
---|
| 408 | |
---|
| 409 | MatrixBandWidth LowerTriangularMatrix::BandWidth() const |
---|
| 410 | { REPORT return MatrixBandWidth(-1,0); } |
---|
| 411 | |
---|
| 412 | MatrixBandWidth BandMatrix::BandWidth() const |
---|
| 413 | { REPORT return MatrixBandWidth(lower,upper); } |
---|
| 414 | |
---|
| 415 | MatrixBandWidth GenericMatrix::BandWidth()const |
---|
| 416 | { REPORT return gm->BandWidth(); } |
---|
| 417 | |
---|
| 418 | MatrixBandWidth AddedMatrix::BandWidth() const |
---|
| 419 | { REPORT return gm1->BandWidth() + gm2->BandWidth(); } |
---|
| 420 | |
---|
| 421 | MatrixBandWidth SPMatrix::BandWidth() const |
---|
| 422 | { REPORT return gm1->BandWidth().minimum(gm2->BandWidth()); } |
---|
| 423 | |
---|
| 424 | MatrixBandWidth KPMatrix::BandWidth() const |
---|
| 425 | { |
---|
| 426 | int lower, upper; |
---|
| 427 | MatrixBandWidth bw1 = gm1->BandWidth(), bw2 = gm2->BandWidth(); |
---|
| 428 | if (bw1.Lower() < 0) |
---|
| 429 | { |
---|
| 430 | if (bw2.Lower() < 0) { REPORT lower = -1; } |
---|
| 431 | else { REPORT lower = bw2.Lower() + (gm1->Nrows() - 1) * gm2->Nrows(); } |
---|
| 432 | } |
---|
| 433 | else |
---|
| 434 | { |
---|
| 435 | if (bw2.Lower() < 0) |
---|
| 436 | { REPORT lower = (1 + bw1.Lower()) * gm2->Nrows() - 1; } |
---|
| 437 | else { REPORT lower = bw2.Lower() + bw1.Lower() * gm2->Nrows(); } |
---|
| 438 | } |
---|
| 439 | if (bw1.Upper() < 0) |
---|
| 440 | { |
---|
| 441 | if (bw2.Upper() < 0) { REPORT upper = -1; } |
---|
| 442 | else { REPORT upper = bw2.Upper() + (gm1->Nrows() - 1) * gm2->Nrows(); } |
---|
| 443 | } |
---|
| 444 | else |
---|
| 445 | { |
---|
| 446 | if (bw2.Upper() < 0) |
---|
| 447 | { REPORT upper = (1 + bw1.Upper()) * gm2->Nrows() - 1; } |
---|
| 448 | else { REPORT upper = bw2.Upper() + bw1.Upper() * gm2->Nrows(); } |
---|
| 449 | } |
---|
| 450 | return MatrixBandWidth(lower, upper); |
---|
| 451 | } |
---|
| 452 | |
---|
| 453 | MatrixBandWidth MultipliedMatrix::BandWidth() const |
---|
| 454 | { REPORT return gm1->BandWidth() * gm2->BandWidth(); } |
---|
| 455 | |
---|
| 456 | MatrixBandWidth ConcatenatedMatrix::BandWidth() const { REPORT return -1; } |
---|
| 457 | |
---|
| 458 | MatrixBandWidth SolvedMatrix::BandWidth() const |
---|
| 459 | { |
---|
| 460 | if (+gm1->Type() & MatrixType::Diagonal) |
---|
| 461 | { REPORT return gm2->BandWidth(); } |
---|
| 462 | else { REPORT return -1; } |
---|
| 463 | } |
---|
| 464 | |
---|
| 465 | MatrixBandWidth ScaledMatrix::BandWidth() const |
---|
| 466 | { REPORT return gm->BandWidth(); } |
---|
| 467 | |
---|
| 468 | MatrixBandWidth NegatedMatrix::BandWidth() const |
---|
| 469 | { REPORT return gm->BandWidth(); } |
---|
| 470 | |
---|
| 471 | MatrixBandWidth TransposedMatrix::BandWidth() const |
---|
| 472 | { REPORT return gm->BandWidth().t(); } |
---|
| 473 | |
---|
| 474 | MatrixBandWidth InvertedMatrix::BandWidth() const |
---|
| 475 | { |
---|
| 476 | if (+gm->Type() & MatrixType::Diagonal) |
---|
| 477 | { REPORT return MatrixBandWidth(0,0); } |
---|
| 478 | else { REPORT return -1; } |
---|
| 479 | } |
---|
| 480 | |
---|
| 481 | MatrixBandWidth RowedMatrix::BandWidth() const { REPORT return -1; } |
---|
| 482 | MatrixBandWidth ColedMatrix::BandWidth() const { REPORT return -1; } |
---|
| 483 | MatrixBandWidth DiagedMatrix::BandWidth() const { REPORT return 0; } |
---|
| 484 | MatrixBandWidth MatedMatrix::BandWidth() const { REPORT return -1; } |
---|
| 485 | MatrixBandWidth ReturnMatrixX::BandWidth() const |
---|
| 486 | { REPORT return gm->BandWidth(); } |
---|
| 487 | |
---|
| 488 | MatrixBandWidth GetSubMatrix::BandWidth() const |
---|
| 489 | { |
---|
| 490 | |
---|
| 491 | if (row_skip==col_skip && row_number==col_number) |
---|
| 492 | { REPORT return gm->BandWidth(); } |
---|
| 493 | else { REPORT return MatrixBandWidth(-1); } |
---|
| 494 | } |
---|
| 495 | |
---|
| 496 | // ********************** the memory managment tools **********************/ |
---|
| 497 | |
---|
| 498 | // Rules regarding tDelete, reuse, GetStore |
---|
| 499 | // All matrices processed during expression evaluation must be subject |
---|
| 500 | // to exactly one of reuse(), tDelete(), GetStore() or BorrowStore(). |
---|
| 501 | // If reuse returns true the matrix must be reused. |
---|
| 502 | // GetMatrix(gm) always calls gm->GetStore() |
---|
| 503 | // gm->Evaluate obeys rules |
---|
| 504 | // bm->Evaluate obeys rules for matrices in bm structure |
---|
| 505 | |
---|
| 506 | void GeneralMatrix::tDelete() |
---|
| 507 | { |
---|
| 508 | if (tag<0) |
---|
| 509 | { |
---|
| 510 | if (tag<-1) { REPORT store=0; delete this; return; } // borrowed |
---|
| 511 | else { REPORT return; } |
---|
| 512 | } |
---|
| 513 | if (tag==1) |
---|
| 514 | { |
---|
| 515 | if (store) |
---|
| 516 | { |
---|
| 517 | REPORT MONITOR_REAL_DELETE("Free (tDelete)",storage,store) |
---|
| 518 | delete [] store; |
---|
| 519 | } |
---|
| 520 | store=0; CleanUp(); tag=-1; return; |
---|
| 521 | } |
---|
| 522 | if (tag==0) { REPORT delete this; return; } |
---|
| 523 | REPORT tag--; return; |
---|
| 524 | } |
---|
| 525 | |
---|
| 526 | static void BlockCopy(int n, Real* from, Real* to) |
---|
| 527 | { |
---|
| 528 | REPORT |
---|
| 529 | int i = (n >> 3); |
---|
| 530 | while (i--) |
---|
| 531 | { |
---|
| 532 | *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++; |
---|
| 533 | *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++; |
---|
| 534 | } |
---|
| 535 | i = n & 7; while (i--) *to++ = *from++; |
---|
| 536 | } |
---|
| 537 | |
---|
| 538 | bool GeneralMatrix::reuse() |
---|
| 539 | { |
---|
| 540 | if (tag<-1) |
---|
| 541 | { |
---|
| 542 | if (storage) |
---|
| 543 | { |
---|
| 544 | REPORT |
---|
| 545 | Real* s = new Real [storage]; MatrixErrorNoSpace(s); |
---|
| 546 | MONITOR_REAL_NEW("Make (reuse)",storage,s) |
---|
| 547 | BlockCopy(storage, store, s); store=s; |
---|
| 548 | } |
---|
| 549 | else { REPORT store = 0; CleanUp(); } |
---|
| 550 | tag=0; return true; |
---|
| 551 | } |
---|
| 552 | if (tag<0) { REPORT return false; } |
---|
| 553 | if (tag<=1) { REPORT return true; } |
---|
| 554 | REPORT tag--; return false; |
---|
| 555 | } |
---|
| 556 | |
---|
| 557 | Real* GeneralMatrix::GetStore() |
---|
| 558 | { |
---|
| 559 | if (tag<0 || tag>1) |
---|
| 560 | { |
---|
| 561 | Real* s; |
---|
| 562 | if (storage) |
---|
| 563 | { |
---|
| 564 | s = new Real [storage]; MatrixErrorNoSpace(s); |
---|
| 565 | MONITOR_REAL_NEW("Make (GetStore)",storage,s) |
---|
| 566 | BlockCopy(storage, store, s); |
---|
| 567 | } |
---|
| 568 | else s = 0; |
---|
| 569 | if (tag>1) { REPORT tag--; } |
---|
| 570 | else if (tag < -1) { REPORT store=0; delete this; } // borrowed store |
---|
| 571 | else { REPORT } |
---|
| 572 | return s; |
---|
| 573 | } |
---|
| 574 | Real* s=store; store=0; |
---|
| 575 | if (tag==0) { REPORT delete this; } |
---|
| 576 | else { REPORT CleanUp(); tag=-1; } |
---|
| 577 | return s; |
---|
| 578 | } |
---|
| 579 | |
---|
| 580 | void GeneralMatrix::GetMatrix(const GeneralMatrix* gmx) |
---|
| 581 | { |
---|
| 582 | REPORT tag=-1; nrows=gmx->Nrows(); ncols=gmx->Ncols(); |
---|
| 583 | storage=gmx->storage; SetParameters(gmx); |
---|
| 584 | store=((GeneralMatrix*)gmx)->GetStore(); |
---|
| 585 | } |
---|
| 586 | |
---|
| 587 | GeneralMatrix* GeneralMatrix::BorrowStore(GeneralMatrix* gmx, MatrixType mt) |
---|
| 588 | // Copy storage of *this to storage of *gmx. Then convert to type mt. |
---|
| 589 | // If mt == 0 just let *gmx point to storage of *this if tag==-1. |
---|
| 590 | { |
---|
| 591 | if (!mt) |
---|
| 592 | { |
---|
| 593 | if (tag == -1) { REPORT gmx->tag = -2; gmx->store = store; } |
---|
| 594 | else { REPORT gmx->tag = 0; gmx->store = GetStore(); } |
---|
| 595 | } |
---|
| 596 | else if (Compare(gmx->Type(),mt)) |
---|
| 597 | { REPORT gmx->tag = 0; gmx->store = GetStore(); } |
---|
| 598 | else |
---|
| 599 | { |
---|
| 600 | REPORT gmx->tag = -2; gmx->store = store; |
---|
| 601 | gmx = gmx->Evaluate(mt); gmx->tag = 0; tDelete(); |
---|
| 602 | } |
---|
| 603 | |
---|
| 604 | return gmx; |
---|
| 605 | } |
---|
| 606 | |
---|
| 607 | void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt) |
---|
| 608 | // Count number of references to this in X. |
---|
| 609 | // If zero delete storage in this; |
---|
| 610 | // otherwise tag this to show when storage can be deleted |
---|
| 611 | // evaluate X and copy to this |
---|
| 612 | { |
---|
| 613 | #ifdef DO_SEARCH |
---|
| 614 | int counter=X.search(this); |
---|
| 615 | if (counter==0) |
---|
| 616 | { |
---|
| 617 | REPORT |
---|
| 618 | if (store) |
---|
| 619 | { |
---|
| 620 | MONITOR_REAL_DELETE("Free (operator=)",storage,store) |
---|
| 621 | REPORT delete [] store; storage=0; store = 0; |
---|
| 622 | } |
---|
| 623 | } |
---|
| 624 | else { REPORT Release(counter); } |
---|
| 625 | GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt); |
---|
| 626 | if (gmx!=this) { REPORT GetMatrix(gmx); } |
---|
| 627 | else { REPORT } |
---|
| 628 | Protect(); |
---|
| 629 | #else |
---|
| 630 | GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt); |
---|
| 631 | if (gmx!=this) |
---|
| 632 | { |
---|
| 633 | REPORT |
---|
| 634 | if (store) |
---|
| 635 | { |
---|
| 636 | MONITOR_REAL_DELETE("Free (operator=)",storage,store) |
---|
| 637 | REPORT delete [] store; storage=0; store = 0; |
---|
| 638 | } |
---|
| 639 | GetMatrix(gmx); |
---|
| 640 | } |
---|
| 641 | else { REPORT } |
---|
| 642 | Protect(); |
---|
| 643 | #endif |
---|
| 644 | } |
---|
| 645 | |
---|
| 646 | // version to work with operator<< |
---|
| 647 | void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt, bool ldok) |
---|
| 648 | { |
---|
| 649 | REPORT |
---|
| 650 | if (ldok) mt.SetDataLossOK(); |
---|
| 651 | Eq(X, mt); |
---|
| 652 | } |
---|
| 653 | |
---|
| 654 | void GeneralMatrix::Eq2(const BaseMatrix& X, MatrixType mt) |
---|
| 655 | // a cut down version of Eq for use with += etc. |
---|
| 656 | // we know BaseMatrix points to two GeneralMatrix objects, |
---|
| 657 | // the first being this (may be the same). |
---|
| 658 | // we know tag has been set correctly in each. |
---|
| 659 | { |
---|
| 660 | GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt); |
---|
| 661 | if (gmx!=this) { REPORT GetMatrix(gmx); } // simplify GetMatrix ? |
---|
| 662 | else { REPORT } |
---|
| 663 | Protect(); |
---|
| 664 | } |
---|
| 665 | |
---|
| 666 | void GeneralMatrix::Inject(const GeneralMatrix& X) |
---|
| 667 | // copy stored values of X; otherwise leave els of *this unchanged |
---|
| 668 | { |
---|
| 669 | REPORT |
---|
| 670 | Tracer tr("Inject"); |
---|
| 671 | if (nrows != X.nrows || ncols != X.ncols) |
---|
| 672 | Throw(IncompatibleDimensionsException()); |
---|
| 673 | MatrixRow mr((GeneralMatrix*)&X, LoadOnEntry); |
---|
| 674 | MatrixRow mrx(this, LoadOnEntry+StoreOnExit+DirectPart); |
---|
| 675 | int i=nrows; |
---|
| 676 | while (i--) { mrx.Inject(mr); mrx.Next(); mr.Next(); } |
---|
| 677 | } |
---|
| 678 | |
---|
| 679 | // ************* checking for data loss during conversion *******************/ |
---|
| 680 | |
---|
| 681 | bool Compare(const MatrixType& source, MatrixType& destination) |
---|
| 682 | { |
---|
| 683 | if (!destination) { destination=source; return true; } |
---|
| 684 | if (destination==source) return true; |
---|
| 685 | if (!destination.DataLossOK && !(destination>=source)) |
---|
| 686 | Throw(ProgramException("Illegal Conversion", source, destination)); |
---|
| 687 | return false; |
---|
| 688 | } |
---|
| 689 | |
---|
| 690 | // ************* Make a copy of a matrix on the heap *********************/ |
---|
| 691 | |
---|
| 692 | GeneralMatrix* Matrix::Image() const |
---|
| 693 | { |
---|
| 694 | REPORT |
---|
| 695 | GeneralMatrix* gm = new Matrix(*this); MatrixErrorNoSpace(gm); |
---|
| 696 | return gm; |
---|
| 697 | } |
---|
| 698 | |
---|
| 699 | GeneralMatrix* SymmetricMatrix::Image() const |
---|
| 700 | { |
---|
| 701 | REPORT |
---|
| 702 | GeneralMatrix* gm = new SymmetricMatrix(*this); MatrixErrorNoSpace(gm); |
---|
| 703 | return gm; |
---|
| 704 | } |
---|
| 705 | |
---|
| 706 | GeneralMatrix* UpperTriangularMatrix::Image() const |
---|
| 707 | { |
---|
| 708 | REPORT |
---|
| 709 | GeneralMatrix* gm = new UpperTriangularMatrix(*this); |
---|
| 710 | MatrixErrorNoSpace(gm); return gm; |
---|
| 711 | } |
---|
| 712 | |
---|
| 713 | GeneralMatrix* LowerTriangularMatrix::Image() const |
---|
| 714 | { |
---|
| 715 | REPORT |
---|
| 716 | GeneralMatrix* gm = new LowerTriangularMatrix(*this); |
---|
| 717 | MatrixErrorNoSpace(gm); return gm; |
---|
| 718 | } |
---|
| 719 | |
---|
| 720 | GeneralMatrix* DiagonalMatrix::Image() const |
---|
| 721 | { |
---|
| 722 | REPORT |
---|
| 723 | GeneralMatrix* gm = new DiagonalMatrix(*this); MatrixErrorNoSpace(gm); |
---|
| 724 | return gm; |
---|
| 725 | } |
---|
| 726 | |
---|
| 727 | GeneralMatrix* RowVector::Image() const |
---|
| 728 | { |
---|
| 729 | REPORT |
---|
| 730 | GeneralMatrix* gm = new RowVector(*this); MatrixErrorNoSpace(gm); |
---|
| 731 | return gm; |
---|
| 732 | } |
---|
| 733 | |
---|
| 734 | GeneralMatrix* ColumnVector::Image() const |
---|
| 735 | { |
---|
| 736 | REPORT |
---|
| 737 | GeneralMatrix* gm = new ColumnVector(*this); MatrixErrorNoSpace(gm); |
---|
| 738 | return gm; |
---|
| 739 | } |
---|
| 740 | |
---|
| 741 | GeneralMatrix* BandMatrix::Image() const |
---|
| 742 | { |
---|
| 743 | REPORT |
---|
| 744 | GeneralMatrix* gm = new BandMatrix(*this); MatrixErrorNoSpace(gm); |
---|
| 745 | return gm; |
---|
| 746 | } |
---|
| 747 | |
---|
| 748 | GeneralMatrix* UpperBandMatrix::Image() const |
---|
| 749 | { |
---|
| 750 | REPORT |
---|
| 751 | GeneralMatrix* gm = new UpperBandMatrix(*this); MatrixErrorNoSpace(gm); |
---|
| 752 | return gm; |
---|
| 753 | } |
---|
| 754 | |
---|
| 755 | GeneralMatrix* LowerBandMatrix::Image() const |
---|
| 756 | { |
---|
| 757 | REPORT |
---|
| 758 | GeneralMatrix* gm = new LowerBandMatrix(*this); MatrixErrorNoSpace(gm); |
---|
| 759 | return gm; |
---|
| 760 | } |
---|
| 761 | |
---|
| 762 | GeneralMatrix* SymmetricBandMatrix::Image() const |
---|
| 763 | { |
---|
| 764 | REPORT |
---|
| 765 | GeneralMatrix* gm = new SymmetricBandMatrix(*this); MatrixErrorNoSpace(gm); |
---|
| 766 | return gm; |
---|
| 767 | } |
---|
| 768 | |
---|
| 769 | GeneralMatrix* nricMatrix::Image() const |
---|
| 770 | { |
---|
| 771 | REPORT |
---|
| 772 | GeneralMatrix* gm = new nricMatrix(*this); MatrixErrorNoSpace(gm); |
---|
| 773 | return gm; |
---|
| 774 | } |
---|
| 775 | |
---|
| 776 | GeneralMatrix* IdentityMatrix::Image() const |
---|
| 777 | { |
---|
| 778 | REPORT |
---|
| 779 | GeneralMatrix* gm = new IdentityMatrix(*this); MatrixErrorNoSpace(gm); |
---|
| 780 | return gm; |
---|
| 781 | } |
---|
| 782 | |
---|
| 783 | GeneralMatrix* GeneralMatrix::Image() const |
---|
| 784 | { |
---|
| 785 | bool dummy = true; |
---|
| 786 | if (dummy) // get rid of warning message |
---|
| 787 | Throw(InternalException("Cannot apply Image to this matrix type")); |
---|
| 788 | return 0; |
---|
| 789 | } |
---|
| 790 | |
---|
| 791 | |
---|
| 792 | // *********************** nricMatrix routines *****************************/ |
---|
| 793 | |
---|
| 794 | void nricMatrix::MakeRowPointer() |
---|
| 795 | { |
---|
| 796 | if (nrows > 0) |
---|
| 797 | { |
---|
| 798 | row_pointer = new Real* [nrows]; MatrixErrorNoSpace(row_pointer); |
---|
| 799 | Real* s = Store() - 1; int i = nrows; Real** rp = row_pointer; |
---|
| 800 | if (i) for (;;) { *rp++ = s; if (!(--i)) break; s+=ncols; } |
---|
| 801 | } |
---|
| 802 | else row_pointer = 0; |
---|
| 803 | } |
---|
| 804 | |
---|
| 805 | void nricMatrix::DeleteRowPointer() |
---|
| 806 | { if (nrows) delete [] row_pointer; } |
---|
| 807 | |
---|
| 808 | void GeneralMatrix::CheckStore() const |
---|
| 809 | { |
---|
| 810 | if (!store) |
---|
| 811 | Throw(ProgramException("NRIC accessing matrix with unset dimensions")); |
---|
| 812 | } |
---|
| 813 | |
---|
| 814 | |
---|
| 815 | // *************************** CleanUp routines *****************************/ |
---|
| 816 | |
---|
| 817 | void GeneralMatrix::CleanUp() |
---|
| 818 | { |
---|
| 819 | // set matrix dimensions to zero, delete storage |
---|
| 820 | REPORT |
---|
| 821 | if (store && storage) |
---|
| 822 | { |
---|
| 823 | MONITOR_REAL_DELETE("Free (CleanUp) ",storage,store) |
---|
| 824 | REPORT delete [] store; |
---|
| 825 | } |
---|
| 826 | store=0; storage=0; nrows=0; ncols=0; |
---|
| 827 | } |
---|
| 828 | |
---|
| 829 | void nricMatrix::CleanUp() |
---|
| 830 | { DeleteRowPointer(); GeneralMatrix::CleanUp(); } |
---|
| 831 | |
---|
| 832 | void RowVector::CleanUp() |
---|
| 833 | { GeneralMatrix::CleanUp(); nrows=1; } |
---|
| 834 | |
---|
| 835 | void ColumnVector::CleanUp() |
---|
| 836 | { GeneralMatrix::CleanUp(); ncols=1; } |
---|
| 837 | |
---|
| 838 | void CroutMatrix::CleanUp() |
---|
| 839 | { |
---|
| 840 | if (nrows) delete [] indx; |
---|
| 841 | GeneralMatrix::CleanUp(); |
---|
| 842 | } |
---|
| 843 | |
---|
| 844 | void BandLUMatrix::CleanUp() |
---|
| 845 | { |
---|
| 846 | if (nrows) delete [] indx; |
---|
| 847 | if (storage2) delete [] store2; |
---|
| 848 | GeneralMatrix::CleanUp(); |
---|
| 849 | } |
---|
| 850 | |
---|
| 851 | // ************************ simple integer array class *********************** |
---|
| 852 | |
---|
| 853 | // construct a new array of length xn. Check that xn is non-negative and |
---|
| 854 | // that space is available |
---|
| 855 | |
---|
| 856 | SimpleIntArray::SimpleIntArray(int xn) : n(xn) |
---|
| 857 | { |
---|
| 858 | if (n < 0) Throw(Logic_error("invalid array length")); |
---|
| 859 | else if (n == 0) { REPORT a = 0; } |
---|
| 860 | else { REPORT a = new int [n]; if (!a) Throw(Bad_alloc()); } |
---|
| 861 | } |
---|
| 862 | |
---|
| 863 | // destroy an array - return its space to memory |
---|
| 864 | |
---|
| 865 | SimpleIntArray::~SimpleIntArray() { REPORT if (a) delete [] a; } |
---|
| 866 | |
---|
| 867 | // access an element of an array; return a "reference" so elements |
---|
| 868 | // can be modified. |
---|
| 869 | // check index is within range |
---|
| 870 | // in this array class the index runs from 0 to n-1 |
---|
| 871 | |
---|
| 872 | int& SimpleIntArray::operator[](int i) |
---|
| 873 | { |
---|
| 874 | REPORT |
---|
| 875 | if (i < 0 || i >= n) Throw(Logic_error("array index out of range")); |
---|
| 876 | return a[i]; |
---|
| 877 | } |
---|
| 878 | |
---|
| 879 | // same thing again but for arrays declared constant so we can't |
---|
| 880 | // modify its elements |
---|
| 881 | |
---|
| 882 | int SimpleIntArray::operator[](int i) const |
---|
| 883 | { |
---|
| 884 | REPORT |
---|
| 885 | if (i < 0 || i >= n) Throw(Logic_error("array index out of range")); |
---|
| 886 | return a[i]; |
---|
| 887 | } |
---|
| 888 | |
---|
| 889 | // set all the elements equal to a given value |
---|
| 890 | |
---|
| 891 | void SimpleIntArray::operator=(int ai) |
---|
| 892 | { REPORT for (int i = 0; i < n; i++) a[i] = ai; } |
---|
| 893 | |
---|
| 894 | // set the elements equal to those of another array. |
---|
| 895 | // check the arrays are of the same length |
---|
| 896 | |
---|
| 897 | void SimpleIntArray::operator=(const SimpleIntArray& b) |
---|
| 898 | { |
---|
| 899 | REPORT |
---|
| 900 | if (b.n != n) Throw(Logic_error("array lengths differ in copy")); |
---|
| 901 | for (int i = 0; i < n; i++) a[i] = b.a[i]; |
---|
| 902 | } |
---|
| 903 | |
---|
| 904 | // construct a new array equal to an existing array |
---|
| 905 | // check that space is available |
---|
| 906 | |
---|
| 907 | SimpleIntArray::SimpleIntArray(const SimpleIntArray& b) : n(b.n) |
---|
| 908 | { |
---|
| 909 | if (n == 0) { REPORT a = 0; } |
---|
| 910 | else |
---|
| 911 | { |
---|
| 912 | REPORT |
---|
| 913 | a = new int [n]; if (!a) Throw(Bad_alloc()); |
---|
| 914 | for (int i = 0; i < n; i++) a[i] = b.a[i]; |
---|
| 915 | } |
---|
| 916 | } |
---|
| 917 | |
---|
| 918 | // change the size of an array; optionally copy data from old array to |
---|
| 919 | // new array |
---|
| 920 | |
---|
| 921 | void SimpleIntArray::ReSize(int n1, bool keep) |
---|
| 922 | { |
---|
| 923 | if (n1 == n) { REPORT return; } |
---|
| 924 | else if (n1 == 0) { REPORT n = 0; delete [] a; a = 0; } |
---|
| 925 | else if (n == 0) |
---|
| 926 | { REPORT a = new int [n1]; if (!a) Throw(Bad_alloc()); n = n1; } |
---|
| 927 | else |
---|
| 928 | { |
---|
| 929 | int* a1 = a; |
---|
| 930 | if (keep) |
---|
| 931 | { |
---|
| 932 | REPORT |
---|
| 933 | a = new int [n1]; if (!a) Throw(Bad_alloc()); |
---|
| 934 | if (n > n1) n = n1; |
---|
| 935 | for (int i = 0; i < n; i++) a[i] = a1[i]; |
---|
| 936 | n = n1; delete [] a1; |
---|
| 937 | } |
---|
| 938 | else |
---|
| 939 | { |
---|
| 940 | REPORT n = n1; delete [] a1; |
---|
| 941 | a = new int [n]; if (!a) Throw(Bad_alloc()); |
---|
| 942 | } |
---|
| 943 | } |
---|
| 944 | } |
---|
| 945 | |
---|
| 946 | |
---|
| 947 | #ifdef use_namespace |
---|
| 948 | } |
---|
| 949 | #endif |
---|
| 950 | |
---|