Simbody
|
00001 #ifndef SimTK_SIMMATRIX_MATRIX_CHARACTERISTICS_H_ 00002 #define SimTK_SIMMATRIX_MATRIX_CHARACTERISTICS_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * SimTK Core: SimTK Simmatrix(tm) * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK Core biosimulation toolkit originating from * 00008 * Simbios, the NIH National Center for Physics-Based Simulation of * 00009 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00010 * Medical Research, grant U54 GM072970. See https://simtk.org. * 00011 * * 00012 * Portions copyright (c) 2005-9 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: * 00015 * * 00016 * Permission is hereby granted, free of charge, to any person obtaining a * 00017 * copy of this software and associated documentation files (the "Software"), * 00018 * to deal in the Software without restriction, including without limitation * 00019 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00020 * and/or sell copies of the Software, and to permit persons to whom the * 00021 * Software is furnished to do so, subject to the following conditions: * 00022 * * 00023 * The above copyright notice and this permission notice shall be included in * 00024 * all copies or substantial portions of the Software. * 00025 * * 00026 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00027 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00028 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00029 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00030 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00031 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00032 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 00033 * -------------------------------------------------------------------------- */ 00034 00041 #include "SimTKcommon/Scalar.h" 00042 00043 #include <iostream> 00044 #include <cassert> 00045 #include <complex> 00046 #include <cstddef> 00047 #include <utility> // for std::pair 00048 00049 namespace SimTK { 00050 00099 class MatrixStructure; 00100 class MatrixStorage; 00101 class MatrixOutline; 00102 class MatrixCondition; 00103 class MatrixCharacter; 00104 class MatrixCommitment; 00105 00106 00107 // ------------------------------ MatrixStructure ----------------------------- 00112 // ---------------------------------------------------------------------------- 00113 class SimTK_SimTKCOMMON_EXPORT MatrixStructure { 00114 public: 00115 enum Structure { 00116 NoStructure = 0x00000000, 00117 Matrix1d = 0x00000001, 00118 Zero = 0x00000002, 00119 Identity = 0x00000004, 00120 Permutation = 0x00000008, 00121 RepeatedDiagonal = 0x00000010, 00122 Diagonal = 0x00000020, 00123 BiDiagonal = 0x00000040, 00124 TriDiagonal = 0x00000080, 00125 BandedSymmetric = 0x00000100, 00126 BandedHermitian = 0x00000200, 00127 Banded = 0x00000400, 00128 Triangular = 0x00000800, 00129 QuasiTriangular = 0x00001000, 00130 Hessenberg = 0x00002000, 00131 Symmetric = 0x00004000, 00132 Hermitian = 0x00008000, 00133 SkewSymmetric = 0x00010000, 00134 SkewHermitian = 0x00020000, 00135 Full = 0x00040000 00136 }; 00137 static const char* name(Structure); 00138 00139 typedef unsigned int StructureMask; // 32 bits 00140 static const StructureMask AnyStructure = 0x0007ffffU; // see above 00141 static const StructureMask UncommittedStructure = 0xffffffffU; 00142 static StructureMask calcStructureMask(Structure); 00143 00148 enum Position { 00149 NoPosition = 0x0000, 00150 Lower = 0x0001, // matrix is lower triangular (default) 00151 Upper = 0x0002 // matrix is upper triangular 00152 }; 00153 static const char* name(Position); 00154 00155 typedef unsigned short PositionMask; // 16 bits 00156 static const PositionMask AnyPosition = 0x0003U; // see above 00157 static const PositionMask UncommittedPosition = 0xffffU; 00158 static PositionMask calcPositionMask(Structure); 00159 00165 enum DiagValue { 00166 NoDiagValue = 0x0000, 00167 StoredDiag = 0x0001, // could be anything (default) 00168 ZeroDiag = 0x0002, // zero (e.g. for skew matrices) 00169 UnitDiag = 0x0004 // unit (one) diagonal is used frequently by Lapack 00170 }; 00171 static const char* name(DiagValue); 00172 00173 typedef unsigned short DiagValueMask; // 16 bits 00174 static const DiagValueMask AnyDiagValue = 0x0003U; 00175 static const DiagValueMask UncommittedDiagValue = 0xffffU; 00176 static DiagValueMask calcDiagValueMask(Structure); 00177 00178 MatrixStructure& setMissingAttributes() { 00179 if (structure == NoStructure) 00180 structure = Full; 00181 if (position == NoPosition) 00182 position = Lower; 00183 if (diagValue == NoDiagValue) 00184 diagValue = StoredDiag; 00185 return *this; 00186 } 00187 00188 std::string name() const { 00189 return std::string(name(getStructure())) 00190 + "|" + std::string(name(getPosition())) 00191 + "|" + std::string(name(getDiagValue())); 00192 } 00193 00194 struct Mask { 00195 Mask() {setToUncommitted();} 00196 Mask(StructureMask sm, PositionMask pm, DiagValueMask dm) 00197 : structure(sm), position(pm), diagValue(dm) {} 00198 Mask& setToUncommitted() 00199 { structure=UncommittedStructure; position=UncommittedPosition; 00200 diagValue=UncommittedDiagValue; return *this; } 00201 bool isUncommitted() const 00202 { return structure==UncommittedStructure && position==UncommittedPosition 00203 && diagValue==UncommittedDiagValue; } 00204 bool isSatisfiedBy(Structure str, Position pos, DiagValue diag) const 00205 { return ((StructureMask)str&structure)==(StructureMask)str 00206 && ((PositionMask)pos&position)==(PositionMask)pos 00207 && ((DiagValueMask)diag&diagValue)==(DiagValueMask)diag; } 00208 bool isSatisfiedBy(const MatrixStructure& actual) const 00209 { return isSatisfiedBy(actual.getStructure(), actual.getPosition(), 00210 actual.getDiagValue()); } 00211 00212 StructureMask structure; 00213 PositionMask position; 00214 DiagValueMask diagValue; 00215 }; 00216 00217 MatrixStructure() {setToNone();} 00218 00221 MatrixStructure(Structure s, Position p=NoPosition, DiagValue d=NoDiagValue) 00222 : structure(s), position(p), diagValue(d) {} 00223 00228 Mask mask() const; 00229 00230 Structure getStructure() const {return structure;} 00231 Position getPosition() const {return position;} 00232 DiagValue getDiagValue() const {return diagValue;} 00233 00234 MatrixStructure& setStructure(Structure s) {structure=s; return *this;} 00235 MatrixStructure& setPosition (Position p) {position=p; return *this;} 00236 MatrixStructure& setDiagValue(DiagValue d) {diagValue=d; return *this;} 00237 00238 MatrixStructure& set(Structure s, Position p, DiagValue d) 00239 { structure=s; position=p; diagValue=d; return *this; } 00240 00241 MatrixStructure& setToNone() 00242 { structure=NoStructure; position=NoPosition; 00243 diagValue=NoDiagValue; return *this; } 00244 00245 private: 00246 Structure structure:32; 00247 Position position:16; 00248 DiagValue diagValue:16; 00249 }; 00250 00251 00252 // ------------------------------ MatrixStorage ------------------------------- 00257 // ---------------------------------------------------------------------------- 00258 class SimTK_SimTKCOMMON_EXPORT MatrixStorage { 00259 public: 00260 enum Packing { 00261 NoPacking = 0x0000, 00262 Full = 0x0001, // full storage layout 00263 TriInFull = 0x0002, // a triangular piece of a full storage layout 00264 TriPacked = 0x0004, // triangle packed into minimal storage, at performance cost 00265 Banded = 0x0008, // a packed, banded storage format 00266 Vector = 0x0010, // a possibly-strided or scattered vector 00267 Scalar = 0x0020, // a single scalar is stored 00268 Permutation = 0x0040 // a permuted identity matrix 00269 }; 00270 static const char* name(Packing); 00271 typedef unsigned short PackingMask; 00272 static const PackingMask AllPacking = 0x007fU; // see above 00273 static const PackingMask UncommittedPacking = 0xffffU; 00274 00275 enum Placement { 00276 NoPlacement = 0x0000, 00277 Lower = 0x0001, // stored in lower triangle of full matrix 00278 Upper = 0x0002, // stored in upper triangle of full matrix 00279 }; 00280 static const char* name(Placement); 00281 typedef unsigned short PlacementMask; 00282 static const PlacementMask AllPlacement = 0x0003U; // see above 00283 static const PlacementMask UncommittedPlacement = 0xffffU; 00284 00285 enum Order { 00286 NoOrder = 0x0000, 00287 ColumnOrder = 0x0001, // matrix is stored by columns 00288 RowOrder = 0x0002, // matrix is stored by rows 00289 }; 00290 static const char* name(Order); 00291 typedef unsigned short OrderMask; 00292 static const OrderMask AllOrder = 0x03U; // see above 00293 static const OrderMask UncommittedOrder = 0xffU; 00294 00295 enum Diagonal { 00296 NoDiag = 0x0000, 00297 StoredDiag = 0x0001, // matrix diagonal is stored 00298 AssumedDiag = 0x0002 // matrix diagonal is not stored but has known value 00299 }; 00300 static const char* name(Diagonal); 00301 typedef unsigned short DiagonalMask; 00302 static const DiagonalMask AllDiagonal = 0x0003U; // see above 00303 static const DiagonalMask UncommittedDiagonal = 0xffffU; 00304 00307 struct Mask { 00308 Mask() 00309 : packing(UncommittedPacking), placement(UncommittedPlacement), 00310 order(UncommittedOrder), diagonal(UncommittedDiagonal) {} 00311 Mask(PackingMask pkm, PlacementMask plm, OrderMask om, DiagonalMask dm) 00312 : packing(pkm), placement(plm), order(om), diagonal(dm) {} 00313 Mask& setToUncommitted() 00314 { packing=UncommittedPacking; placement=UncommittedPlacement; 00315 order=UncommittedOrder; diagonal=UncommittedDiagonal; return *this; } 00316 bool isUncommitted() const 00317 { return packing==UncommittedPacking && placement==UncommittedPlacement 00318 && order==UncommittedOrder && diagonal==UncommittedDiagonal; } 00319 bool isSatisfiedBy(Packing pack, Placement place, Order ord, Diagonal diag) const 00320 { return ((PackingMask)pack & packing) == (PackingMask) pack 00321 && ((PlacementMask)place & placement) == (PlacementMask)place 00322 && ((OrderMask)ord & order) == (OrderMask) ord 00323 && ((DiagonalMask)diag & diagonal) == (DiagonalMask) diag; } 00324 bool isSatisfiedBy(const MatrixStorage& actual) const 00325 { return isSatisfiedBy(actual.getPacking(), actual.getPlacement(), 00326 actual.getOrder(), actual.getDiagonal());} 00327 00328 PackingMask packing; 00329 PlacementMask placement; 00330 OrderMask order; 00331 DiagonalMask diagonal; 00332 }; 00333 00334 static MatrixStorage calcDefaultStorage(const MatrixStructure&, 00335 const MatrixOutline&); 00336 00337 std::string name() const { 00338 return std::string(name(getPacking())) 00339 + "|" + std::string(name(getPlacement())) 00340 + "|" + std::string(name(getOrder())) 00341 + "|" + std::string(name(getDiagonal())); 00342 } 00343 00348 Mask mask() const { 00349 Mask ms; // initially uncommitted 00350 if (packing) ms.packing = (PackingMask)packing; 00351 if (placement) ms.placement = (PlacementMask)placement; 00352 if (order) ms.order = (OrderMask)order; 00353 if (diagonal) ms.diagonal = (DiagonalMask)diagonal; 00354 return ms; 00355 } 00356 00358 MatrixStorage() 00359 : packing(NoPacking), placement(NoPlacement), order(NoOrder), diagonal(NoDiag) {} 00360 00364 MatrixStorage(Packing pk, Placement pl=NoPlacement, Order o=NoOrder, Diagonal d=NoDiag) 00365 : packing(pk), placement(pl), order(o), diagonal(d) {} 00366 00369 MatrixStorage(Packing pk, Order o) 00370 : packing(pk), placement(NoPlacement), order(o), diagonal(StoredDiag) {} 00371 00374 MatrixStorage& setMissingAttributes() { 00375 if (packing==NoPacking) 00376 packing = Full; 00377 if (placement==NoPlacement) 00378 placement = Lower; 00379 if (order==NoOrder) 00380 order = ColumnOrder; 00381 if (diagonal==NoDiag) 00382 diagonal = StoredDiag; 00383 return *this; 00384 } 00385 00387 MatrixStorage& setToNone() 00388 { packing=NoPacking; placement=NoPlacement; 00389 order=NoOrder; diagonal=NoDiag; return *this; } 00390 00391 MatrixStorage& setPacking(Packing p) {packing = p; return *this;} 00392 MatrixStorage& setPlacement(Placement p) {placement = p; return *this;} 00393 MatrixStorage& setOrder(Order o) {order = o; return *this;} 00394 MatrixStorage& setDiagonal(Diagonal d) {diagonal = d; return *this;} 00395 00396 Packing getPacking() const {return packing;} 00397 Placement getPlacement() const {return placement;} 00398 Order getOrder() const {return order;} 00399 Diagonal getDiagonal() const {return diagonal;} 00400 00401 private: 00402 Packing packing:16; 00403 Placement placement:16; 00404 Order order:16; 00405 Diagonal diagonal:16; 00406 }; 00407 00408 00409 // ------------------------------- MatrixOutline ------------------------------ 00430 // ---------------------------------------------------------------------------- 00431 class SimTK_SimTKCOMMON_EXPORT MatrixOutline { 00432 public: 00433 enum Outline { 00434 NoOutline = 0x0000, 00435 Scalar = 0x0001, // 1x1 00436 Column = 0x0002, // mx1, m != 1 00437 Row = 0x0004, // 1xn, n != 1 00438 Square = 0x0008, // mxn, m == n 00439 Wide = 0x0010, // mxn, m < n 00440 Tall = 0x0020, // mxn, m > n 00441 Rectangular = 0x0040 // mxn 00442 }; 00443 static const char* name(Outline); 00444 00445 typedef unsigned short OutlineMask; 00446 static const OutlineMask AnyOutline = 0x007fU; // see above 00447 static const OutlineMask UncommittedOutline = 0xffffU; 00448 00449 struct Mask { 00450 Mask() : outline(UncommittedOutline) {} 00451 explicit Mask(OutlineMask mask) : outline(mask) {} 00452 Mask& setToUncommitted() {outline=UncommittedOutline; return *this;} 00453 bool isUncommitted() const {return outline==UncommittedOutline;} 00454 bool isSatisfiedBy(const MatrixOutline& actual) const 00455 { return ((OutlineMask)actual.outline & outline) == (OutlineMask)actual.outline; } 00456 00457 OutlineMask outline; 00458 }; 00459 00460 std::string name() const {return std::string(name(getOutline()));} 00461 00464 MatrixOutline() : outline(NoOutline) {} 00465 00467 MatrixOutline(Outline outline) : outline(outline) {} 00468 00470 MatrixOutline& setToNone() {outline=NoOutline; return *this;} 00471 00475 static OutlineMask calcMask(Outline); 00476 00479 Mask mask() const {return Mask(calcMask(getOutline()));} 00480 00482 bool isSizeOK(int m, int n) const; 00483 00485 void getMinimumSize(int& m, int& n) const; 00486 00488 static MatrixOutline calcFromSize(int m, int n); 00489 00491 Outline getOutline() const {return outline;} 00492 00493 private: 00494 Outline outline:16; 00495 }; 00496 00497 00498 00499 // ---------------------------- MatrixCondition ------------------------------- 00508 // ---------------------------------------------------------------------------- 00509 class SimTK_SimTKCOMMON_EXPORT MatrixCondition { 00510 public: 00511 enum Condition { 00512 UnknownCondition = 0x0000, 00513 Orthogonal = 0x0001, // implies well conditioned 00514 PositiveDefinite = 0x0002, // implies well conditioned 00515 WellConditioned = 0x0004, // implies full rank 00516 FullRank = 0x0008, // but might have bad conditioning 00517 Singular = 0x0010 // implies possible bad conditioning 00518 }; 00519 static const char* name(Condition); 00520 00521 typedef unsigned short ConditionMask; // 16 bits in mask 00522 static const ConditionMask AnyCondition = 0x001fU; // see above 00523 static const ConditionMask UncommittedCondition = 0xffffU; 00524 00525 enum Diagonal { 00526 UnknownDiagonal = 0x0000, 00527 ZeroDiagonal = 0x0001, 00528 OneDiagonal = 0x0002, 00529 RealDiagonal = 0x0004, 00530 ImaginaryDiagonal = 0x0008 00531 }; 00532 static const char* name(Diagonal); 00533 00534 typedef unsigned short DiagonalMask; // 16 bits in mask 00535 static const DiagonalMask AnyDiagonal = 0x000fU; // see above 00536 static const DiagonalMask UncommittedDiagonal = 0xffffU; 00537 00539 struct Mask { 00540 Mask() : condition(UncommittedCondition), diagonal(UncommittedDiagonal) {} 00541 Mask(ConditionMask cmask, DiagonalMask dmask) : condition(cmask), diagonal(dmask) {} 00542 Mask& setToUncommitted() 00543 { condition=UncommittedCondition; diagonal=UncommittedDiagonal; return *this;} 00544 bool isUncommitted() const 00545 { return condition==UncommittedCondition && diagonal==UncommittedDiagonal;} 00546 bool isSatisfiedBy(const MatrixCondition& actual) const 00547 { return ((ConditionMask)actual.condition & condition) == (ConditionMask)actual.condition 00548 && ((DiagonalMask) actual.diagonal & diagonal) == (DiagonalMask)actual.diagonal; } 00549 00550 ConditionMask condition; 00551 DiagonalMask diagonal; 00552 }; 00553 00554 std::string name() const 00555 { return std::string(name(getCondition())) + "|" + std::string(name(getDiagonal()));} 00556 00559 MatrixCondition() : condition(UnknownCondition), diagonal(UnknownDiagonal) {} 00560 00563 MatrixCondition(Condition cond, Diagonal diag=UnknownDiagonal) : condition(cond) {} 00564 00566 MatrixCondition& setToNone() {condition=UnknownCondition; diagonal=UnknownDiagonal; return *this;} 00567 00573 static ConditionMask calcMask(Condition); 00574 00580 static DiagonalMask calcMask(Diagonal); 00581 00584 Mask mask() const 00585 { return Mask(calcMask(getCondition()), calcMask(getDiagonal())); } 00586 00587 Condition getCondition() const {return condition;} 00588 Diagonal getDiagonal() const {return diagonal;} 00589 00590 MatrixCondition& setCondition(Condition c) {condition=c; return *this;} 00591 MatrixCondition& setDiagonal (Diagonal d) {diagonal=d; return *this;} 00592 00593 private: 00594 Condition condition:16; 00595 Diagonal diagonal:16; 00596 }; 00597 00598 00599 00600 // ------------------------------ MatrixCharacter ----------------------------- 00601 00609 00610 // ---------------------------------------------------------------------------- 00611 class SimTK_SimTKCOMMON_EXPORT MatrixCharacter { 00612 public: 00615 MatrixCharacter() : nr(0), nc(0), lband(0), uband(0) {} 00616 00617 // Some handy predefined MatrixCharacters. 00618 class LapackFull; 00619 class Vector; 00620 class RowVector; 00621 00623 MatrixCharacter& setToNone() { 00624 nr=nc=lband=uband=0; 00625 structure.setToNone(); outline.setToNone(); 00626 storage.setToNone(); condition.setToNone(); 00627 return *this; 00628 } 00629 00630 // These are dimensions of the logical matrix and have nothing to do with how 00631 // much storage may be used to hold the elements. 00632 int nrow() const {return nr;} 00633 int ncol() const {return nc;} 00634 std::pair<int,int> getSize() const {return std::pair<int,int>(nrow(),ncol());} 00635 ptrdiff_t nelt() const {return (ptrdiff_t)nrow() * (ptrdiff_t)ncol();} 00636 00637 int getLowerBandwidth() const {return lband;} 00638 int getUpperBandwidth() const {return uband;} 00639 std::pair<int,int> getBandwidth() const 00640 { return std::pair<int,int>(getLowerBandwidth(), getUpperBandwidth()); } 00641 00642 const MatrixStructure& getStructure() const {return structure;} 00643 const MatrixStorage& getStorage() const {return storage;} 00644 const MatrixOutline& getOutline() const {return outline;} 00645 const MatrixCondition& getCondition() const {return condition;} 00646 00647 MatrixStructure& updStructure() {return structure;} 00648 MatrixStorage& updStorage() {return storage;} 00649 MatrixOutline& updOutline() {return outline;} 00650 MatrixCondition& updCondition() {return condition;} 00651 00652 MatrixCharacter& setStructure(const MatrixStructure& sa) {structure = sa; return *this;} 00653 MatrixCharacter& setStorage (const MatrixStorage& sa) {storage = sa; return *this;} 00654 MatrixCharacter& setOutline (const MatrixOutline& oa) {outline = oa; return *this;} 00655 MatrixCharacter& setCondition(const MatrixCondition& ca) {condition = ca; return *this;} 00656 00657 00659 MatrixCharacter& setActualSize(int m, int n) 00660 { setSize(m,n); outline = MatrixOutline::calcFromSize(m,n); return *this; } 00661 MatrixCharacter& setActualNumRows(int m) 00662 { setNumRows(m); outline = MatrixOutline::calcFromSize(m,ncol()); return *this; } 00663 MatrixCharacter& setActualNumCols(int n) 00664 { setNumCols(n); outline = MatrixOutline::calcFromSize(nrow(),n); return *this; } 00665 00666 MatrixCharacter& setBandwidth(int lb, int ub) { 00667 assert(lb>=0 && lb>=0); 00668 lband = lb; uband = ub; 00669 return *this; 00670 } 00671 MatrixCharacter& setLowerBandwidth(int lb) { 00672 assert(lb>=0); 00673 lband = lb; 00674 return *this; 00675 } 00676 MatrixCharacter& setUpperBandwidth(int ub) { 00677 assert(ub>=0); 00678 uband = ub; 00679 return *this; 00680 } 00681 00682 class Mask; // defined below 00683 00684 protected: 00685 MatrixCharacter(int m, int n, 00686 int lb, int ub, 00687 MatrixStructure structure, 00688 MatrixStorage storage, 00689 MatrixCondition condition) 00690 : nr(m), nc(n), lband(lb), uband(ub), 00691 structure(structure), storage(storage), 00692 outline(MatrixOutline::calcFromSize(m,n)), 00693 condition(condition) {} 00694 00695 00696 int nr, 00697 nc; 00698 int lband, 00699 uband; 00700 MatrixStructure structure; 00701 MatrixStorage storage; 00702 MatrixOutline outline; 00703 MatrixCondition condition; 00704 00705 private: 00706 // These are private because they don't set the outline as well. 00707 MatrixCharacter& setSize(int m, int n) 00708 { assert(m>=0 && n>=0); nr = m; nc = n; return *this; } 00709 MatrixCharacter& setNumRows(int m) 00710 { assert(m>=0); nr = m; return *this; } 00711 MatrixCharacter& setNumCols(int n) 00712 { assert(n>=0); nc = n; return *this; } 00713 }; 00714 00716 SimTK_SimTKCOMMON_EXPORT std::ostream& 00717 operator<<(std::ostream& o, const MatrixCharacter&); 00718 00724 class MatrixCharacter::LapackFull : public MatrixCharacter { 00725 public: 00726 LapackFull(int m, int n) 00727 : MatrixCharacter(m,n,0,0, 00728 MatrixStructure(MatrixStructure::Full), 00729 MatrixStorage(MatrixStorage::Full,MatrixStorage::ColumnOrder), 00730 MatrixCondition()) {} 00731 }; 00732 00737 class MatrixCharacter::Vector : public MatrixCharacter { 00738 public: 00739 Vector(int m) 00740 : MatrixCharacter(m,1,0,0, 00741 MatrixStructure(MatrixStructure::Matrix1d), 00742 MatrixStorage(MatrixStorage::Vector,MatrixStorage::ColumnOrder), 00743 MatrixCondition()) {} 00744 }; 00745 00750 class MatrixCharacter::RowVector : public MatrixCharacter { 00751 public: 00752 RowVector(int n) 00753 : MatrixCharacter(1,n,0,0, 00754 MatrixStructure(MatrixStructure::Matrix1d), 00755 MatrixStorage(MatrixStorage::Vector,MatrixStorage::RowOrder), 00756 MatrixCondition()) {} 00757 }; 00758 00759 // -------------------------- MatrixCharacter::Mask --------------------------- 00762 // ---------------------------------------------------------------------------- 00763 class MatrixCharacter::Mask { 00764 public: 00765 Mask() {setToUncommitted();} 00766 00767 typedef unsigned int SizeMask; 00768 static const SizeMask SizeUncommitted = 0xffffffffU; 00769 00770 bool isResizeable() const {return nr==SizeUncommitted || nc==SizeUncommitted;} 00771 bool isFullyResizeable() const {return nr==SizeUncommitted && nc==SizeUncommitted;} 00772 bool isNumRowsLocked() const {return nr!=SizeUncommitted;} 00773 bool isNumColsLocked() const {return nc!=SizeUncommitted;} 00774 00775 unsigned int getNumRowsMask() const {return nr;} 00776 unsigned int getNumColsMask() const {return nc;} 00777 unsigned int getLowerBandwidthMask() const {return lband;} 00778 unsigned int getUpperBandwidthMask() const {return uband;} 00779 00780 int getDefaultNumRows() const {return isNumRowsLocked() ? nr : 0;} 00781 int getDefaultNumCols() const {return isNumColsLocked() ? nc : 0;} 00782 00783 bool isLowerBandwidthLocked() const {return lband!=SizeUncommitted;} 00784 bool isUpperBandwidthLocked() const {return uband!=SizeUncommitted;} 00785 int getDefaultLowerBandwidth() const {return isLowerBandwidthLocked() ? lband : 0;} 00786 int getDefaultUpperBandwidth() const {return isUpperBandwidthLocked() ? uband : 0;} 00787 00789 Mask& setToUncommitted() { 00790 nr=nc=lband=uband=SizeUncommitted; 00791 structure.setToUncommitted(); storage.setToUncommitted(); 00792 outline.setToUncommitted(); condition.setToUncommitted(); 00793 return *this; 00794 } 00795 00797 bool isUncommitted() const { 00798 return nr==SizeUncommitted && nc==SizeUncommitted 00799 && lband==SizeUncommitted && uband==SizeUncommitted 00800 && structure.isUncommitted() && storage.isUncommitted() 00801 && outline.isUncommitted() && condition.isUncommitted(); 00802 } 00803 00805 bool isSatisfiedBy(const MatrixCharacter& actual) const { 00806 return isSizeOK(actual.nr, actual.nc) 00807 && isBandwidthOK(actual.lband, actual.uband) 00808 && structure.isSatisfiedBy(actual.getStructure()) 00809 && storage.isSatisfiedBy(actual.getStorage()) 00810 && outline.isSatisfiedBy(actual.getOutline()) 00811 && condition.isSatisfiedBy(actual.getCondition()); 00812 } 00813 00815 bool isSizeOK(int m, int n) const 00816 { return ((SizeMask)m & nr) == (SizeMask)m 00817 && ((SizeMask)n & nc) == (SizeMask)n; } 00818 00821 bool isBandwidthOK(int lower, int upper) const 00822 { return ((SizeMask)lower & lband) == (SizeMask)lower 00823 && ((SizeMask)upper & uband) == (SizeMask)upper; } 00824 00825 SizeMask nr, 00826 nc; 00827 SizeMask lband, 00828 uband; 00829 MatrixStructure::Mask structure; 00830 MatrixStorage::Mask storage; 00831 MatrixOutline::Mask outline; 00832 MatrixCondition::Mask condition; 00833 00834 friend class MatrixCommitment; 00835 }; 00836 00837 // ----------------------------- MatrixCommitment ----------------------------- 00838 00843 00844 // ---------------------------------------------------------------------------- 00845 class SimTK_SimTKCOMMON_EXPORT MatrixCommitment { 00846 public: 00847 MatrixCommitment() {} // set commitments to "none" and masks to "uncommitted" 00848 00851 MatrixCommitment(const MatrixStructure& str) 00852 { new (this) MatrixCommitment(str, MatrixStorage(), MatrixOutline(), MatrixCondition());} 00853 00854 class Vector; 00855 class RowVector; 00856 class Triangular; 00857 class Symmetric; 00858 class Hermitian; 00859 class SkewSymmetric; 00860 class SkewHermitian; 00861 00862 MatrixCommitment& commitSize(int m, int n) 00863 { commitNumRows(m); commitNumCols(n); return *this; } 00864 MatrixCommitment& commitNumRows(int m) 00865 { SimTK_SIZECHECK_NONNEG(m, "MatrixCommitment::commitNumRows()"); 00866 masks.nr = m; return *this; } 00867 MatrixCommitment& commitNumCols(int n) 00868 { SimTK_SIZECHECK_NONNEG(n, "MatrixCommitment::commitNumCols()"); 00869 masks.nc = n; return *this; } 00870 00871 MatrixCommitment& commitBandwidth(int lb, int ub) 00872 { commitLowerBandwidth(lb); commitUpperBandwidth(ub); return *this;} 00873 MatrixCommitment& commitLowerBandwidth(int lb) 00874 { SimTK_SIZECHECK_NONNEG(lb, "MatrixCommitment::commitLowerBandwidth()"); 00875 masks.lband = lb; return *this; } 00876 MatrixCommitment& commitUpperBandwidth(int ub) 00877 { SimTK_SIZECHECK_NONNEG(ub, "MatrixCommitment::commitUpperBandwidth()"); 00878 masks.uband = ub; return *this; } 00879 00880 MatrixCommitment& commitStructure(const MatrixStructure& s) 00881 { structure=s; masks.structure=s.mask(); return *this; } 00882 MatrixCommitment& commitStorage (const MatrixStorage& s) 00883 { storage=s; masks.storage =s.mask(); return *this; } 00884 MatrixCommitment& commitOutline (const MatrixOutline& o) 00885 { outline=o; masks.outline =o.mask(); return *this; } 00886 MatrixCommitment& commitCondition(const MatrixCondition& c) 00887 { condition=c; masks.condition=c.mask(); return *this; } 00888 00899 MatrixCharacter calcDefaultCharacter(int minNumRows, int minNumCols) const; 00900 00902 const MatrixStructure& getStructureCommitment() const {return structure;} 00903 const MatrixStorage& getStorageCommitment() const {return storage;} 00904 const MatrixOutline& getOutlineCommitment() const {return outline;} 00905 const MatrixCondition& getConditionCommitment() const {return condition;} 00906 00908 const MatrixStructure::Mask& getStructureMask() const {return masks.structure;} 00909 const MatrixStorage::Mask& getStorageMask() const {return masks.storage;} 00910 const MatrixOutline::Mask& getOutlineMask() const {return masks.outline;} 00911 const MatrixCondition::Mask& getConditionMask() const {return masks.condition;} 00912 00913 MatrixCharacter::Mask::SizeMask getNumRowsMask() const {return masks.nr;} 00914 MatrixCharacter::Mask::SizeMask getNumColsMask() const {return masks.nc;} 00915 MatrixCharacter::Mask::SizeMask getLowerBandwidthMask() const {return masks.lband;} 00916 MatrixCharacter::Mask::SizeMask getUpperBandwidthMask() const {return masks.uband;} 00917 00918 int getDefaultNumRows() const {return masks.getDefaultNumRows();} 00919 int getDefaultNumCols() const {return masks.getDefaultNumRows();} 00920 00921 bool isSizeOK(int m, int n) const {return masks.isSizeOK(m,n);} 00922 bool isSizeOK(const std::pair<int,int>& mn) const 00923 { return isSizeOK(mn.first, mn.second); } 00924 00925 bool isBandwidthOK(int lower, int upper) const {return masks.isBandwidthOK(lower,upper);} 00926 00927 bool isSatisfiedBy(const MatrixCharacter& actual) const 00928 { return masks.isSatisfiedBy(actual); } 00929 bool isStructureOK(const MatrixStructure& s) const 00930 { return getStructureMask().isSatisfiedBy(s); } 00931 bool isStorageOK(const MatrixStorage& s) const 00932 { return getStorageMask().isSatisfiedBy(s); } 00933 bool isOutlineOK(const MatrixOutline& o) const 00934 { return getOutlineMask().isSatisfiedBy(o); } 00935 bool isConditionOK(const MatrixCondition& c) const 00936 { return getConditionMask().isSatisfiedBy(c); } 00937 00938 bool isResizeable() const {return masks.isResizeable();} 00939 bool isFullyResizeable() const {return masks.isFullyResizeable();;} 00940 bool isNumRowsLocked() const {return masks.isNumRowsLocked();} 00941 bool isNumColsLocked() const {return masks.isNumColsLocked();} 00942 00943 bool isStructureCommitted() const 00944 { return !getStructureMask().isUncommitted(); } 00945 bool isStorageCommitted() const 00946 { return !getStorageMask().isUncommitted();} 00947 bool isOutlineCommitted() const 00948 { return !getOutlineMask().isUncommitted(); } 00949 bool isConditionCommitted() const 00950 { return !getConditionMask().isUncommitted();} 00951 00953 void clear() { 00954 structure.setToNone(); 00955 storage.setToNone(); 00956 outline.setToNone(); 00957 condition.setToNone(); 00958 masks.setToUncommitted(); 00959 } 00960 00961 protected: 00962 MatrixCommitment(const MatrixStructure& structure, 00963 const MatrixStorage& storage, 00964 const MatrixOutline& outline, 00965 const MatrixCondition& condition) 00966 : structure(structure), storage(storage), 00967 outline(outline), condition(condition), 00968 masks() // set to all 1's 00969 { 00970 if (outline.getOutline()==MatrixOutline::Scalar) commitSize(1,1); 00971 else if (outline.getOutline()==MatrixOutline::Column) commitNumCols(1); 00972 else if (outline.getOutline()==MatrixOutline::Row) commitNumRows(1); 00973 00974 masks.structure = structure.mask(); 00975 masks.storage = storage.mask(); 00976 masks.outline = outline.mask(); 00977 masks.condition = condition.mask(); 00978 } 00979 00982 MatrixStructure structure; 00983 MatrixStorage storage; 00984 MatrixOutline outline; 00985 MatrixCondition condition; 00986 00989 MatrixCharacter::Mask masks; 00990 }; 00991 00992 00994 class MatrixCommitment::Vector : public MatrixCommitment { 00995 public: 00997 Vector() 00998 : MatrixCommitment 00999 ( MatrixStructure(MatrixStructure::Matrix1d), 01000 MatrixStorage(), 01001 MatrixOutline(MatrixOutline::Column), 01002 MatrixCondition()) 01003 { 01004 } 01006 explicit Vector(int m) 01007 : MatrixCommitment 01008 ( MatrixStructure(MatrixStructure::Matrix1d), 01009 MatrixStorage(), 01010 MatrixOutline(MatrixOutline::Column), 01011 MatrixCondition()) 01012 { 01013 commitNumRows(m); 01014 } 01015 }; 01016 01018 class MatrixCommitment::RowVector : public MatrixCommitment { 01019 public: 01021 RowVector() 01022 : MatrixCommitment 01023 ( MatrixStructure(MatrixStructure::Matrix1d), 01024 MatrixStorage(), 01025 MatrixOutline(MatrixOutline::Row), 01026 MatrixCondition()) 01027 { 01028 } 01030 explicit RowVector(int n) 01031 : MatrixCommitment 01032 ( MatrixStructure(MatrixStructure::Matrix1d), 01033 MatrixStorage(), 01034 MatrixOutline(MatrixOutline::Row), 01035 MatrixCondition()) 01036 { 01037 commitNumCols(n); 01038 } 01039 }; 01040 01042 class MatrixCommitment::Triangular : public MatrixCommitment { 01043 public: 01044 Triangular() 01045 : MatrixCommitment(MatrixStructure::Triangular, MatrixStorage(), 01046 MatrixOutline(), MatrixCondition()) 01047 { 01048 } 01049 }; 01050 01053 class MatrixCommitment::Symmetric : public MatrixCommitment { 01054 public: 01055 Symmetric() 01056 : MatrixCommitment(MatrixStructure::Symmetric, MatrixStorage(), 01057 MatrixOutline(), MatrixCondition()) 01058 { 01059 } 01060 }; 01061 01065 class MatrixCommitment::Hermitian : public MatrixCommitment { 01066 public: 01067 Hermitian() 01068 : MatrixCommitment 01069 ( MatrixStructure::Hermitian, 01070 MatrixStorage(), 01071 MatrixOutline(), 01072 MatrixCondition().setDiagonal(MatrixCondition::RealDiagonal)) 01073 { 01074 } 01075 }; 01076 01080 class MatrixCommitment::SkewSymmetric : public MatrixCommitment { 01081 public: 01082 SkewSymmetric() 01083 : MatrixCommitment 01084 ( MatrixStructure::SkewSymmetric, 01085 MatrixStorage(), 01086 MatrixOutline(), 01087 MatrixCondition().setDiagonal(MatrixCondition::ZeroDiagonal)) 01088 { 01089 } 01090 }; 01091 01095 class MatrixCommitment::SkewHermitian : public MatrixCommitment { 01096 public: 01097 SkewHermitian() 01098 : MatrixCommitment 01099 ( MatrixStructure::SkewHermitian, 01100 MatrixStorage(), 01101 MatrixOutline(), 01102 MatrixCondition().setDiagonal(MatrixCondition::ImaginaryDiagonal)) 01103 { 01104 } 01105 }; 01106 01108 SimTK_SimTKCOMMON_EXPORT std::ostream& 01109 operator<<(std::ostream& o, const MatrixCommitment&); 01110 01111 // End of MatrixCharacteristics group. 01113 01114 } //namespace SimTK 01115 01116 #endif // SimTK_SIMMATRIX_MATRIX_CHARACTERISTICS_H_