Simbody
3.5
|
00001 #ifndef SimTK_SIMMATRIX_MATRIX_CHARACTERISTICS_H_ 00002 #define SimTK_SIMMATRIX_MATRIX_CHARACTERISTICS_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * Simbody(tm): SimTKcommon * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK 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/home/simbody. * 00011 * * 00012 * Portions copyright (c) 2005-13 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: * 00015 * * 00016 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 00017 * not use this file except in compliance with the License. You may obtain a * 00018 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 00019 * * 00020 * Unless required by applicable law or agreed to in writing, software * 00021 * distributed under the License is distributed on an "AS IS" BASIS, * 00022 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00023 * See the License for the specific language governing permissions and * 00024 * limitations under the License. * 00025 * -------------------------------------------------------------------------- */ 00026 00033 #include "SimTKcommon/Scalar.h" 00034 00035 #include <iostream> 00036 #include <cassert> 00037 #include <complex> 00038 #include <cstddef> 00039 #include <utility> // for std::pair 00040 00041 namespace SimTK { 00042 00043 00044 class MatrixStructure; 00045 class MatrixStorage; 00046 class MatrixOutline; 00047 class MatrixCondition; 00048 class MatrixCharacter; 00049 class MatrixCommitment; 00050 00051 00052 // ------------------------------ MatrixStructure ----------------------------- 00057 // ---------------------------------------------------------------------------- 00058 class SimTK_SimTKCOMMON_EXPORT MatrixStructure { 00059 public: 00060 enum Structure { 00061 NoStructure = 0x00000000, 00062 Matrix1d = 0x00000001, 00063 Zero = 0x00000002, 00064 Identity = 0x00000004, 00065 Permutation = 0x00000008, 00066 RepeatedDiagonal = 0x00000010, 00067 Diagonal = 0x00000020, 00068 BiDiagonal = 0x00000040, 00069 TriDiagonal = 0x00000080, 00070 BandedSymmetric = 0x00000100, 00071 BandedHermitian = 0x00000200, 00072 Banded = 0x00000400, 00073 Triangular = 0x00000800, 00074 QuasiTriangular = 0x00001000, 00075 Hessenberg = 0x00002000, 00076 Symmetric = 0x00004000, 00077 Hermitian = 0x00008000, 00078 SkewSymmetric = 0x00010000, 00079 SkewHermitian = 0x00020000, 00080 Full = 0x00040000 00081 }; 00082 static const char* name(Structure); 00083 00084 typedef unsigned int StructureMask; // 32 bits 00085 static const StructureMask AnyStructure = 0x0007ffffU; // see above 00086 static const StructureMask UncommittedStructure = 0xffffffffU; 00087 static StructureMask calcStructureMask(Structure); 00088 00093 enum Position { 00094 NoPosition = 0x0000, 00095 Lower = 0x0001, // matrix is lower triangular (default) 00096 Upper = 0x0002 // matrix is upper triangular 00097 }; 00098 static const char* name(Position); 00099 00100 typedef unsigned short PositionMask; // 16 bits 00101 static const PositionMask AnyPosition = 0x0003U; // see above 00102 static const PositionMask UncommittedPosition = 0xffffU; 00103 static PositionMask calcPositionMask(Structure); 00104 00110 enum DiagValue { 00111 NoDiagValue = 0x0000, 00112 StoredDiag = 0x0001, // could be anything (default) 00113 ZeroDiag = 0x0002, // zero (e.g. for skew matrices) 00114 UnitDiag = 0x0004 // unit (one) diagonal is used frequently by Lapack 00115 }; 00116 static const char* name(DiagValue); 00117 00118 typedef unsigned short DiagValueMask; // 16 bits 00119 static const DiagValueMask AnyDiagValue = 0x0003U; 00120 static const DiagValueMask UncommittedDiagValue = 0xffffU; 00121 static DiagValueMask calcDiagValueMask(Structure); 00122 00123 MatrixStructure& setMissingAttributes() { 00124 if (structure == NoStructure) 00125 structure = Full; 00126 if (position == NoPosition) 00127 position = Lower; 00128 if (diagValue == NoDiagValue) 00129 diagValue = StoredDiag; 00130 return *this; 00131 } 00132 00133 std::string name() const { 00134 return std::string(name(getStructure())) 00135 + "|" + std::string(name(getPosition())) 00136 + "|" + std::string(name(getDiagValue())); 00137 } 00138 00139 struct Mask { 00140 Mask() {setToUncommitted();} 00141 Mask(StructureMask sm, PositionMask pm, DiagValueMask dm) 00142 : structure(sm), position(pm), diagValue(dm) {} 00143 Mask& setToUncommitted() 00144 { structure=UncommittedStructure; position=UncommittedPosition; 00145 diagValue=UncommittedDiagValue; return *this; } 00146 bool isUncommitted() const 00147 { return structure==UncommittedStructure && position==UncommittedPosition 00148 && diagValue==UncommittedDiagValue; } 00149 bool isSatisfiedBy(Structure str, Position pos, DiagValue diag) const 00150 { return ((StructureMask)str&structure)==(StructureMask)str 00151 && ((PositionMask)pos&position)==(PositionMask)pos 00152 && ((DiagValueMask)diag&diagValue)==(DiagValueMask)diag; } 00153 bool isSatisfiedBy(const MatrixStructure& actual) const 00154 { return isSatisfiedBy(actual.getStructure(), actual.getPosition(), 00155 actual.getDiagValue()); } 00156 00157 StructureMask structure; 00158 PositionMask position; 00159 DiagValueMask diagValue; 00160 }; 00161 00162 MatrixStructure() {setToNone();} 00163 00166 MatrixStructure(Structure s, Position p=NoPosition, DiagValue d=NoDiagValue) 00167 : structure(s), position(p), diagValue(d) {} 00168 00173 Mask mask() const; 00174 00175 Structure getStructure() const {return structure;} 00176 Position getPosition() const {return position;} 00177 DiagValue getDiagValue() const {return diagValue;} 00178 00179 MatrixStructure& setStructure(Structure s) {structure=s; return *this;} 00180 MatrixStructure& setPosition (Position p) {position=p; return *this;} 00181 MatrixStructure& setDiagValue(DiagValue d) {diagValue=d; return *this;} 00182 00183 MatrixStructure& set(Structure s, Position p, DiagValue d) 00184 { structure=s; position=p; diagValue=d; return *this; } 00185 00186 MatrixStructure& setToNone() 00187 { structure=NoStructure; position=NoPosition; 00188 diagValue=NoDiagValue; return *this; } 00189 00190 private: 00191 Structure structure:32; 00192 Position position:16; 00193 DiagValue diagValue:16; 00194 }; 00195 00196 00197 // ------------------------------ MatrixStorage ------------------------------- 00202 // ---------------------------------------------------------------------------- 00203 class SimTK_SimTKCOMMON_EXPORT MatrixStorage { 00204 public: 00205 enum Packing { 00206 NoPacking = 0x0000, 00207 Full = 0x0001, // full storage layout 00208 TriInFull = 0x0002, // a triangular piece of a full storage layout 00209 TriPacked = 0x0004, // triangle packed into minimal storage, at performance cost 00210 Banded = 0x0008, // a packed, banded storage format 00211 Vector = 0x0010, // a possibly-strided or scattered vector 00212 Scalar = 0x0020, // a single scalar is stored 00213 Permutation = 0x0040 // a permuted identity matrix 00214 }; 00215 static const char* name(Packing); 00216 typedef unsigned short PackingMask; 00217 static const PackingMask AllPacking = 0x007fU; // see above 00218 static const PackingMask UncommittedPacking = 0xffffU; 00219 00220 enum Placement { 00221 NoPlacement = 0x0000, 00222 Lower = 0x0001, // stored in lower triangle of full matrix 00223 Upper = 0x0002, // stored in upper triangle of full matrix 00224 }; 00225 static const char* name(Placement); 00226 typedef unsigned short PlacementMask; 00227 static const PlacementMask AllPlacement = 0x0003U; // see above 00228 static const PlacementMask UncommittedPlacement = 0xffffU; 00229 00230 enum Order { 00231 NoOrder = 0x0000, 00232 ColumnOrder = 0x0001, // matrix is stored by columns 00233 RowOrder = 0x0002, // matrix is stored by rows 00234 }; 00235 static const char* name(Order); 00236 typedef unsigned short OrderMask; 00237 static const OrderMask AllOrder = 0x03U; // see above 00238 static const OrderMask UncommittedOrder = 0xffU; 00239 00240 enum Diagonal { 00241 NoDiag = 0x0000, 00242 StoredDiag = 0x0001, // matrix diagonal is stored 00243 AssumedDiag = 0x0002 // matrix diagonal is not stored but has known value 00244 }; 00245 static const char* name(Diagonal); 00246 typedef unsigned short DiagonalMask; 00247 static const DiagonalMask AllDiagonal = 0x0003U; // see above 00248 static const DiagonalMask UncommittedDiagonal = 0xffffU; 00249 00252 struct Mask { 00253 Mask() 00254 : packing(UncommittedPacking), placement(UncommittedPlacement), 00255 order(UncommittedOrder), diagonal(UncommittedDiagonal) {} 00256 Mask(PackingMask pkm, PlacementMask plm, OrderMask om, DiagonalMask dm) 00257 : packing(pkm), placement(plm), order(om), diagonal(dm) {} 00258 Mask& setToUncommitted() 00259 { packing=UncommittedPacking; placement=UncommittedPlacement; 00260 order=UncommittedOrder; diagonal=UncommittedDiagonal; return *this; } 00261 bool isUncommitted() const 00262 { return packing==UncommittedPacking && placement==UncommittedPlacement 00263 && order==UncommittedOrder && diagonal==UncommittedDiagonal; } 00264 bool isSatisfiedBy(Packing pack, Placement place, Order ord, Diagonal diag) const 00265 { return ((PackingMask)pack & packing) == (PackingMask) pack 00266 && ((PlacementMask)place & placement) == (PlacementMask)place 00267 && ((OrderMask)ord & order) == (OrderMask) ord 00268 && ((DiagonalMask)diag & diagonal) == (DiagonalMask) diag; } 00269 bool isSatisfiedBy(const MatrixStorage& actual) const 00270 { return isSatisfiedBy(actual.getPacking(), actual.getPlacement(), 00271 actual.getOrder(), actual.getDiagonal());} 00272 00273 PackingMask packing; 00274 PlacementMask placement; 00275 OrderMask order; 00276 DiagonalMask diagonal; 00277 }; 00278 00279 static MatrixStorage calcDefaultStorage(const MatrixStructure&, 00280 const MatrixOutline&); 00281 00282 std::string name() const { 00283 return std::string(name(getPacking())) 00284 + "|" + std::string(name(getPlacement())) 00285 + "|" + std::string(name(getOrder())) 00286 + "|" + std::string(name(getDiagonal())); 00287 } 00288 00293 Mask mask() const { 00294 Mask ms; // initially uncommitted 00295 if (packing) ms.packing = (PackingMask)packing; 00296 if (placement) ms.placement = (PlacementMask)placement; 00297 if (order) ms.order = (OrderMask)order; 00298 if (diagonal) ms.diagonal = (DiagonalMask)diagonal; 00299 return ms; 00300 } 00301 00303 MatrixStorage() 00304 : packing(NoPacking), placement(NoPlacement), order(NoOrder), diagonal(NoDiag) {} 00305 00309 MatrixStorage(Packing pk, Placement pl=NoPlacement, Order o=NoOrder, Diagonal d=NoDiag) 00310 : packing(pk), placement(pl), order(o), diagonal(d) {} 00311 00314 MatrixStorage(Packing pk, Order o) 00315 : packing(pk), placement(NoPlacement), order(o), diagonal(StoredDiag) {} 00316 00319 MatrixStorage& setMissingAttributes() { 00320 if (packing==NoPacking) 00321 packing = Full; 00322 if (placement==NoPlacement) 00323 placement = Lower; 00324 if (order==NoOrder) 00325 order = ColumnOrder; 00326 if (diagonal==NoDiag) 00327 diagonal = StoredDiag; 00328 return *this; 00329 } 00330 00332 MatrixStorage& setToNone() 00333 { packing=NoPacking; placement=NoPlacement; 00334 order=NoOrder; diagonal=NoDiag; return *this; } 00335 00336 MatrixStorage& setPacking(Packing p) {packing = p; return *this;} 00337 MatrixStorage& setPlacement(Placement p) {placement = p; return *this;} 00338 MatrixStorage& setOrder(Order o) {order = o; return *this;} 00339 MatrixStorage& setDiagonal(Diagonal d) {diagonal = d; return *this;} 00340 00341 Packing getPacking() const {return packing;} 00342 Placement getPlacement() const {return placement;} 00343 Order getOrder() const {return order;} 00344 Diagonal getDiagonal() const {return diagonal;} 00345 00346 private: 00347 Packing packing:16; 00348 Placement placement:16; 00349 Order order:16; 00350 Diagonal diagonal:16; 00351 }; 00352 00353 00354 // ------------------------------- MatrixOutline ------------------------------ 00375 // ---------------------------------------------------------------------------- 00376 class SimTK_SimTKCOMMON_EXPORT MatrixOutline { 00377 public: 00378 enum Outline { 00379 NoOutline = 0x0000, 00380 Scalar = 0x0001, // 1x1 00381 Column = 0x0002, // mx1, m != 1 00382 Row = 0x0004, // 1xn, n != 1 00383 Square = 0x0008, // mxn, m == n 00384 Wide = 0x0010, // mxn, m < n 00385 Tall = 0x0020, // mxn, m > n 00386 Rectangular = 0x0040 // mxn 00387 }; 00388 static const char* name(Outline); 00389 00390 typedef unsigned short OutlineMask; 00391 static const OutlineMask AnyOutline = 0x007fU; // see above 00392 static const OutlineMask UncommittedOutline = 0xffffU; 00393 00394 struct Mask { 00395 Mask() : outline(UncommittedOutline) {} 00396 explicit Mask(OutlineMask mask) : outline(mask) {} 00397 Mask& setToUncommitted() {outline=UncommittedOutline; return *this;} 00398 bool isUncommitted() const {return outline==UncommittedOutline;} 00399 bool isSatisfiedBy(const MatrixOutline& actual) const 00400 { return ((OutlineMask)actual.outline & outline) == (OutlineMask)actual.outline; } 00401 00402 OutlineMask outline; 00403 }; 00404 00405 std::string name() const {return std::string(name(getOutline()));} 00406 00409 MatrixOutline() : outline(NoOutline) {} 00410 00412 MatrixOutline(Outline outline) : outline(outline) {} 00413 00415 MatrixOutline& setToNone() {outline=NoOutline; return *this;} 00416 00420 static OutlineMask calcMask(Outline); 00421 00424 Mask mask() const {return Mask(calcMask(getOutline()));} 00425 00427 bool isSizeOK(int m, int n) const; 00428 00430 void getMinimumSize(int& m, int& n) const; 00431 00433 static MatrixOutline calcFromSize(int m, int n); 00434 00436 Outline getOutline() const {return outline;} 00437 00438 private: 00439 Outline outline:16; 00440 }; 00441 00442 00443 00444 // ---------------------------- MatrixCondition ------------------------------- 00453 // ---------------------------------------------------------------------------- 00454 class SimTK_SimTKCOMMON_EXPORT MatrixCondition { 00455 public: 00456 enum Condition { 00457 UnknownCondition = 0x0000, 00458 Orthogonal = 0x0001, // implies well conditioned 00459 PositiveDefinite = 0x0002, // implies well conditioned 00460 WellConditioned = 0x0004, // implies full rank 00461 FullRank = 0x0008, // but might have bad conditioning 00462 Singular = 0x0010 // implies possible bad conditioning 00463 }; 00464 static const char* name(Condition); 00465 00466 typedef unsigned short ConditionMask; // 16 bits in mask 00467 static const ConditionMask AnyCondition = 0x001fU; // see above 00468 static const ConditionMask UncommittedCondition = 0xffffU; 00469 00470 enum Diagonal { 00471 UnknownDiagonal = 0x0000, 00472 ZeroDiagonal = 0x0001, 00473 OneDiagonal = 0x0002, 00474 RealDiagonal = 0x0004, 00475 ImaginaryDiagonal = 0x0008 00476 }; 00477 static const char* name(Diagonal); 00478 00479 typedef unsigned short DiagonalMask; // 16 bits in mask 00480 static const DiagonalMask AnyDiagonal = 0x000fU; // see above 00481 static const DiagonalMask UncommittedDiagonal = 0xffffU; 00482 00484 struct Mask { 00485 Mask() : condition(UncommittedCondition), diagonal(UncommittedDiagonal) {} 00486 Mask(ConditionMask cmask, DiagonalMask dmask) : condition(cmask), diagonal(dmask) {} 00487 Mask& setToUncommitted() 00488 { condition=UncommittedCondition; diagonal=UncommittedDiagonal; return *this;} 00489 bool isUncommitted() const 00490 { return condition==UncommittedCondition && diagonal==UncommittedDiagonal;} 00491 bool isSatisfiedBy(const MatrixCondition& actual) const 00492 { return ((ConditionMask)actual.condition & condition) == (ConditionMask)actual.condition 00493 && ((DiagonalMask) actual.diagonal & diagonal) == (DiagonalMask)actual.diagonal; } 00494 00495 ConditionMask condition; 00496 DiagonalMask diagonal; 00497 }; 00498 00499 std::string name() const 00500 { return std::string(name(getCondition())) + "|" + std::string(name(getDiagonal()));} 00501 00504 MatrixCondition() : condition(UnknownCondition), diagonal(UnknownDiagonal) {} 00505 00508 MatrixCondition(Condition cond, Diagonal diag=UnknownDiagonal) : condition(cond) {} 00509 00511 MatrixCondition& setToNone() {condition=UnknownCondition; diagonal=UnknownDiagonal; return *this;} 00512 00518 static ConditionMask calcMask(Condition); 00519 00525 static DiagonalMask calcMask(Diagonal); 00526 00529 Mask mask() const 00530 { return Mask(calcMask(getCondition()), calcMask(getDiagonal())); } 00531 00532 Condition getCondition() const {return condition;} 00533 Diagonal getDiagonal() const {return diagonal;} 00534 00535 MatrixCondition& setCondition(Condition c) {condition=c; return *this;} 00536 MatrixCondition& setDiagonal (Diagonal d) {diagonal=d; return *this;} 00537 00538 private: 00539 Condition condition:16; 00540 Diagonal diagonal:16; 00541 }; 00542 00543 00544 00545 // ------------------------------ MatrixCharacter ----------------------------- 00596 class SimTK_SimTKCOMMON_EXPORT MatrixCharacter { 00597 public: 00600 MatrixCharacter() : nr(0), nc(0), lband(0), uband(0) {} 00601 00602 // Some handy predefined MatrixCharacters. 00603 class LapackFull; 00604 class Vector; 00605 class RowVector; 00606 00608 MatrixCharacter& setToNone() { 00609 nr=nc=lband=uband=0; 00610 structure.setToNone(); outline.setToNone(); 00611 storage.setToNone(); condition.setToNone(); 00612 return *this; 00613 } 00614 00617 int nrow() const {return nr;} 00618 int ncol() const {return nc;} 00619 std::pair<int,int> getSize() const {return std::pair<int,int>(nrow(),ncol());} 00620 ptrdiff_t nelt() const {return (ptrdiff_t)nrow() * (ptrdiff_t)ncol();} 00621 00622 int getLowerBandwidth() const {return lband;} 00623 int getUpperBandwidth() const {return uband;} 00624 std::pair<int,int> getBandwidth() const 00625 { return std::pair<int,int>(getLowerBandwidth(), getUpperBandwidth()); } 00626 00627 const MatrixStructure& getStructure() const {return structure;} 00628 const MatrixStorage& getStorage() const {return storage;} 00629 const MatrixOutline& getOutline() const {return outline;} 00630 const MatrixCondition& getCondition() const {return condition;} 00631 00632 MatrixStructure& updStructure() {return structure;} 00633 MatrixStorage& updStorage() {return storage;} 00634 MatrixOutline& updOutline() {return outline;} 00635 MatrixCondition& updCondition() {return condition;} 00636 00637 MatrixCharacter& setStructure(const MatrixStructure& sa) {structure = sa; return *this;} 00638 MatrixCharacter& setStorage (const MatrixStorage& sa) {storage = sa; return *this;} 00639 MatrixCharacter& setOutline (const MatrixOutline& oa) {outline = oa; return *this;} 00640 MatrixCharacter& setCondition(const MatrixCondition& ca) {condition = ca; return *this;} 00641 00642 00644 MatrixCharacter& setActualSize(int m, int n) 00645 { setSize(m,n); outline = MatrixOutline::calcFromSize(m,n); return *this; } 00646 MatrixCharacter& setActualNumRows(int m) 00647 { setNumRows(m); outline = MatrixOutline::calcFromSize(m,ncol()); return *this; } 00648 MatrixCharacter& setActualNumCols(int n) 00649 { setNumCols(n); outline = MatrixOutline::calcFromSize(nrow(),n); return *this; } 00650 00651 MatrixCharacter& setBandwidth(int lb, int ub) { 00652 assert(lb>=0 && lb>=0); 00653 lband = lb; uband = ub; 00654 return *this; 00655 } 00656 MatrixCharacter& setLowerBandwidth(int lb) { 00657 assert(lb>=0); 00658 lband = lb; 00659 return *this; 00660 } 00661 MatrixCharacter& setUpperBandwidth(int ub) { 00662 assert(ub>=0); 00663 uband = ub; 00664 return *this; 00665 } 00666 00667 class Mask; // defined below 00668 00669 protected: 00670 MatrixCharacter(int m, int n, 00671 int lb, int ub, 00672 MatrixStructure structure, 00673 MatrixStorage storage, 00674 MatrixCondition condition) 00675 : nr(m), nc(n), lband(lb), uband(ub), 00676 structure(structure), storage(storage), 00677 outline(MatrixOutline::calcFromSize(m,n)), 00678 condition(condition) {} 00679 00680 00681 int nr, 00682 nc; 00683 int lband, 00684 uband; 00685 MatrixStructure structure; 00686 MatrixStorage storage; 00687 MatrixOutline outline; 00688 MatrixCondition condition; 00689 00690 private: 00691 // These are private because they don't set the outline as well. 00692 MatrixCharacter& setSize(int m, int n) 00693 { assert(m>=0 && n>=0); nr = m; nc = n; return *this; } 00694 MatrixCharacter& setNumRows(int m) 00695 { assert(m>=0); nr = m; return *this; } 00696 MatrixCharacter& setNumCols(int n) 00697 { assert(n>=0); nc = n; return *this; } 00698 }; 00699 00702 SimTK_SimTKCOMMON_EXPORT std::ostream& 00703 operator<<(std::ostream& o, const MatrixCharacter&); 00704 00710 class MatrixCharacter::LapackFull : public MatrixCharacter { 00711 public: 00712 LapackFull(int m, int n) 00713 : MatrixCharacter(m,n,0,0, 00714 MatrixStructure(MatrixStructure::Full), 00715 MatrixStorage(MatrixStorage::Full,MatrixStorage::ColumnOrder), 00716 MatrixCondition()) {} 00717 }; 00718 00723 class MatrixCharacter::Vector : public MatrixCharacter { 00724 public: 00725 Vector(int m) 00726 : MatrixCharacter(m,1,0,0, 00727 MatrixStructure(MatrixStructure::Matrix1d), 00728 MatrixStorage(MatrixStorage::Vector,MatrixStorage::ColumnOrder), 00729 MatrixCondition()) {} 00730 }; 00731 00736 class MatrixCharacter::RowVector : public MatrixCharacter { 00737 public: 00738 RowVector(int n) 00739 : MatrixCharacter(1,n,0,0, 00740 MatrixStructure(MatrixStructure::Matrix1d), 00741 MatrixStorage(MatrixStorage::Vector,MatrixStorage::RowOrder), 00742 MatrixCondition()) {} 00743 }; 00744 00745 // -------------------------- MatrixCharacter::Mask --------------------------- 00748 // ---------------------------------------------------------------------------- 00749 class MatrixCharacter::Mask { 00750 public: 00751 Mask() {setToUncommitted();} 00752 00753 typedef unsigned int SizeMask; 00754 static const SizeMask SizeUncommitted = 0xffffffffU; 00755 00756 bool isResizeable() const {return nr==SizeUncommitted || nc==SizeUncommitted;} 00757 bool isFullyResizeable() const {return nr==SizeUncommitted && nc==SizeUncommitted;} 00758 bool isNumRowsLocked() const {return nr!=SizeUncommitted;} 00759 bool isNumColsLocked() const {return nc!=SizeUncommitted;} 00760 00761 unsigned int getNumRowsMask() const {return nr;} 00762 unsigned int getNumColsMask() const {return nc;} 00763 unsigned int getLowerBandwidthMask() const {return lband;} 00764 unsigned int getUpperBandwidthMask() const {return uband;} 00765 00766 int getDefaultNumRows() const {return isNumRowsLocked() ? nr : 0;} 00767 int getDefaultNumCols() const {return isNumColsLocked() ? nc : 0;} 00768 00769 bool isLowerBandwidthLocked() const {return lband!=SizeUncommitted;} 00770 bool isUpperBandwidthLocked() const {return uband!=SizeUncommitted;} 00771 int getDefaultLowerBandwidth() const {return isLowerBandwidthLocked() ? lband : 0;} 00772 int getDefaultUpperBandwidth() const {return isUpperBandwidthLocked() ? uband : 0;} 00773 00775 Mask& setToUncommitted() { 00776 nr=nc=lband=uband=SizeUncommitted; 00777 structure.setToUncommitted(); storage.setToUncommitted(); 00778 outline.setToUncommitted(); condition.setToUncommitted(); 00779 return *this; 00780 } 00781 00783 bool isUncommitted() const { 00784 return nr==SizeUncommitted && nc==SizeUncommitted 00785 && lband==SizeUncommitted && uband==SizeUncommitted 00786 && structure.isUncommitted() && storage.isUncommitted() 00787 && outline.isUncommitted() && condition.isUncommitted(); 00788 } 00789 00791 bool isSatisfiedBy(const MatrixCharacter& actual) const { 00792 return isSizeOK(actual.nr, actual.nc) 00793 && isBandwidthOK(actual.lband, actual.uband) 00794 && structure.isSatisfiedBy(actual.getStructure()) 00795 && storage.isSatisfiedBy(actual.getStorage()) 00796 && outline.isSatisfiedBy(actual.getOutline()) 00797 && condition.isSatisfiedBy(actual.getCondition()); 00798 } 00799 00801 bool isSizeOK(int m, int n) const 00802 { return ((SizeMask)m & nr) == (SizeMask)m 00803 && ((SizeMask)n & nc) == (SizeMask)n; } 00804 00807 bool isBandwidthOK(int lower, int upper) const 00808 { return ((SizeMask)lower & lband) == (SizeMask)lower 00809 && ((SizeMask)upper & uband) == (SizeMask)upper; } 00810 00811 SizeMask nr, 00812 nc; 00813 SizeMask lband, 00814 uband; 00815 MatrixStructure::Mask structure; 00816 MatrixStorage::Mask storage; 00817 MatrixOutline::Mask outline; 00818 MatrixCondition::Mask condition; 00819 00820 friend class MatrixCommitment; 00821 }; 00822 00823 // ----------------------------- MatrixCommitment ----------------------------- 00824 00829 00830 // ---------------------------------------------------------------------------- 00831 class SimTK_SimTKCOMMON_EXPORT MatrixCommitment { 00832 public: 00833 MatrixCommitment() {} // set commitments to "none" and masks to "uncommitted" 00834 00837 MatrixCommitment(const MatrixStructure& str) 00838 { new (this) MatrixCommitment(str, MatrixStorage(), MatrixOutline(), MatrixCondition());} 00839 00840 class Vector; 00841 class RowVector; 00842 class Triangular; 00843 class Symmetric; 00844 class Hermitian; 00845 class SkewSymmetric; 00846 class SkewHermitian; 00847 00848 MatrixCommitment& commitSize(int m, int n) 00849 { commitNumRows(m); commitNumCols(n); return *this; } 00850 MatrixCommitment& commitNumRows(int m) 00851 { SimTK_SIZECHECK_NONNEG(m, "MatrixCommitment::commitNumRows()"); 00852 masks.nr = m; return *this; } 00853 MatrixCommitment& commitNumCols(int n) 00854 { SimTK_SIZECHECK_NONNEG(n, "MatrixCommitment::commitNumCols()"); 00855 masks.nc = n; return *this; } 00856 00857 MatrixCommitment& commitBandwidth(int lb, int ub) 00858 { commitLowerBandwidth(lb); commitUpperBandwidth(ub); return *this;} 00859 MatrixCommitment& commitLowerBandwidth(int lb) 00860 { SimTK_SIZECHECK_NONNEG(lb, "MatrixCommitment::commitLowerBandwidth()"); 00861 masks.lband = lb; return *this; } 00862 MatrixCommitment& commitUpperBandwidth(int ub) 00863 { SimTK_SIZECHECK_NONNEG(ub, "MatrixCommitment::commitUpperBandwidth()"); 00864 masks.uband = ub; return *this; } 00865 00866 MatrixCommitment& commitStructure(const MatrixStructure& s) 00867 { structure=s; masks.structure=s.mask(); return *this; } 00868 MatrixCommitment& commitStorage (const MatrixStorage& s) 00869 { storage=s; masks.storage =s.mask(); return *this; } 00870 MatrixCommitment& commitOutline (const MatrixOutline& o) 00871 { outline=o; masks.outline =o.mask(); return *this; } 00872 MatrixCommitment& commitCondition(const MatrixCondition& c) 00873 { condition=c; masks.condition=c.mask(); return *this; } 00874 00885 MatrixCharacter calcDefaultCharacter(int minNumRows, int minNumCols) const; 00886 00888 const MatrixStructure& getStructureCommitment() const {return structure;} 00889 const MatrixStorage& getStorageCommitment() const {return storage;} 00890 const MatrixOutline& getOutlineCommitment() const {return outline;} 00891 const MatrixCondition& getConditionCommitment() const {return condition;} 00892 00894 const MatrixStructure::Mask& getStructureMask() const {return masks.structure;} 00895 const MatrixStorage::Mask& getStorageMask() const {return masks.storage;} 00896 const MatrixOutline::Mask& getOutlineMask() const {return masks.outline;} 00897 const MatrixCondition::Mask& getConditionMask() const {return masks.condition;} 00898 00899 MatrixCharacter::Mask::SizeMask getNumRowsMask() const {return masks.nr;} 00900 MatrixCharacter::Mask::SizeMask getNumColsMask() const {return masks.nc;} 00901 MatrixCharacter::Mask::SizeMask getLowerBandwidthMask() const {return masks.lband;} 00902 MatrixCharacter::Mask::SizeMask getUpperBandwidthMask() const {return masks.uband;} 00903 00904 int getDefaultNumRows() const {return masks.getDefaultNumRows();} 00905 int getDefaultNumCols() const {return masks.getDefaultNumRows();} 00906 00907 bool isSizeOK(int m, int n) const {return masks.isSizeOK(m,n);} 00908 bool isSizeOK(const std::pair<int,int>& mn) const 00909 { return isSizeOK(mn.first, mn.second); } 00910 00911 bool isBandwidthOK(int lower, int upper) const {return masks.isBandwidthOK(lower,upper);} 00912 00913 bool isSatisfiedBy(const MatrixCharacter& actual) const 00914 { return masks.isSatisfiedBy(actual); } 00915 bool isStructureOK(const MatrixStructure& s) const 00916 { return getStructureMask().isSatisfiedBy(s); } 00917 bool isStorageOK(const MatrixStorage& s) const 00918 { return getStorageMask().isSatisfiedBy(s); } 00919 bool isOutlineOK(const MatrixOutline& o) const 00920 { return getOutlineMask().isSatisfiedBy(o); } 00921 bool isConditionOK(const MatrixCondition& c) const 00922 { return getConditionMask().isSatisfiedBy(c); } 00923 00924 bool isResizeable() const {return masks.isResizeable();} 00925 bool isFullyResizeable() const {return masks.isFullyResizeable();;} 00926 bool isNumRowsLocked() const {return masks.isNumRowsLocked();} 00927 bool isNumColsLocked() const {return masks.isNumColsLocked();} 00928 00929 bool isStructureCommitted() const 00930 { return !getStructureMask().isUncommitted(); } 00931 bool isStorageCommitted() const 00932 { return !getStorageMask().isUncommitted();} 00933 bool isOutlineCommitted() const 00934 { return !getOutlineMask().isUncommitted(); } 00935 bool isConditionCommitted() const 00936 { return !getConditionMask().isUncommitted();} 00937 00939 void clear() { 00940 structure.setToNone(); 00941 storage.setToNone(); 00942 outline.setToNone(); 00943 condition.setToNone(); 00944 masks.setToUncommitted(); 00945 } 00946 00947 protected: 00948 MatrixCommitment(const MatrixStructure& structure, 00949 const MatrixStorage& storage, 00950 const MatrixOutline& outline, 00951 const MatrixCondition& condition) 00952 : structure(structure), storage(storage), 00953 outline(outline), condition(condition), 00954 masks() // set to all 1's 00955 { 00956 if (outline.getOutline()==MatrixOutline::Scalar) commitSize(1,1); 00957 else if (outline.getOutline()==MatrixOutline::Column) commitNumCols(1); 00958 else if (outline.getOutline()==MatrixOutline::Row) commitNumRows(1); 00959 00960 masks.structure = structure.mask(); 00961 masks.storage = storage.mask(); 00962 masks.outline = outline.mask(); 00963 masks.condition = condition.mask(); 00964 } 00965 00968 MatrixStructure structure; 00969 MatrixStorage storage; 00970 MatrixOutline outline; 00971 MatrixCondition condition; 00972 00975 MatrixCharacter::Mask masks; 00976 }; 00977 00978 00980 class MatrixCommitment::Vector : public MatrixCommitment { 00981 public: 00983 Vector() 00984 : MatrixCommitment 00985 ( MatrixStructure(MatrixStructure::Matrix1d), 00986 MatrixStorage(), 00987 MatrixOutline(MatrixOutline::Column), 00988 MatrixCondition()) 00989 { 00990 } 00992 explicit Vector(int m) 00993 : MatrixCommitment 00994 ( MatrixStructure(MatrixStructure::Matrix1d), 00995 MatrixStorage(), 00996 MatrixOutline(MatrixOutline::Column), 00997 MatrixCondition()) 00998 { 00999 commitNumRows(m); 01000 } 01001 }; 01002 01004 class MatrixCommitment::RowVector : public MatrixCommitment { 01005 public: 01007 RowVector() 01008 : MatrixCommitment 01009 ( MatrixStructure(MatrixStructure::Matrix1d), 01010 MatrixStorage(), 01011 MatrixOutline(MatrixOutline::Row), 01012 MatrixCondition()) 01013 { 01014 } 01016 explicit RowVector(int n) 01017 : MatrixCommitment 01018 ( MatrixStructure(MatrixStructure::Matrix1d), 01019 MatrixStorage(), 01020 MatrixOutline(MatrixOutline::Row), 01021 MatrixCondition()) 01022 { 01023 commitNumCols(n); 01024 } 01025 }; 01026 01028 class MatrixCommitment::Triangular : public MatrixCommitment { 01029 public: 01030 Triangular() 01031 : MatrixCommitment(MatrixStructure::Triangular, MatrixStorage(), 01032 MatrixOutline(), MatrixCondition()) 01033 { 01034 } 01035 }; 01036 01039 class MatrixCommitment::Symmetric : public MatrixCommitment { 01040 public: 01041 Symmetric() 01042 : MatrixCommitment(MatrixStructure::Symmetric, MatrixStorage(), 01043 MatrixOutline(), MatrixCondition()) 01044 { 01045 } 01046 }; 01047 01051 class MatrixCommitment::Hermitian : public MatrixCommitment { 01052 public: 01053 Hermitian() 01054 : MatrixCommitment 01055 ( MatrixStructure::Hermitian, 01056 MatrixStorage(), 01057 MatrixOutline(), 01058 MatrixCondition().setDiagonal(MatrixCondition::RealDiagonal)) 01059 { 01060 } 01061 }; 01062 01066 class MatrixCommitment::SkewSymmetric : public MatrixCommitment { 01067 public: 01068 SkewSymmetric() 01069 : MatrixCommitment 01070 ( MatrixStructure::SkewSymmetric, 01071 MatrixStorage(), 01072 MatrixOutline(), 01073 MatrixCondition().setDiagonal(MatrixCondition::ZeroDiagonal)) 01074 { 01075 } 01076 }; 01077 01081 class MatrixCommitment::SkewHermitian : public MatrixCommitment { 01082 public: 01083 SkewHermitian() 01084 : MatrixCommitment 01085 ( MatrixStructure::SkewHermitian, 01086 MatrixStorage(), 01087 MatrixOutline(), 01088 MatrixCondition().setDiagonal(MatrixCondition::ImaginaryDiagonal)) 01089 { 01090 } 01091 }; 01092 01095 SimTK_SimTKCOMMON_EXPORT std::ostream& 01096 operator<<(std::ostream& o, const MatrixCommitment&); 01097 01098 } //namespace SimTK 01099 01100 #endif // SimTK_SIMMATRIX_MATRIX_CHARACTERISTICS_H_