00001 #ifndef SimTK_SIMMATRIX_MATRIX_CHARACTERISTICS_H_
00002 #define SimTK_SIMMATRIX_MATRIX_CHARACTERISTICS_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00041 #include "SimTKcommon/Scalar.h"
00042
00043 #include <iostream>
00044 #include <cassert>
00045 #include <complex>
00046 #include <cstddef>
00047 #include <utility>
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
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;
00140 static const StructureMask AnyStructure = 0x0007ffffU;
00141 static const StructureMask UncommittedStructure = 0xffffffffU;
00142 static StructureMask calcStructureMask(Structure);
00143
00148 enum Position {
00149 NoPosition = 0x0000,
00150 Lower = 0x0001,
00151 Upper = 0x0002
00152 };
00153 static const char* name(Position);
00154
00155 typedef unsigned short PositionMask;
00156 static const PositionMask AnyPosition = 0x0003U;
00157 static const PositionMask UncommittedPosition = 0xffffU;
00158 static PositionMask calcPositionMask(Structure);
00159
00165 enum DiagValue {
00166 NoDiagValue = 0x0000,
00167 StoredDiag = 0x0001,
00168 ZeroDiag = 0x0002,
00169 UnitDiag = 0x0004
00170 };
00171 static const char* name(DiagValue);
00172
00173 typedef unsigned short DiagValueMask;
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
00257
00258 class SimTK_SimTKCOMMON_EXPORT MatrixStorage {
00259 public:
00260 enum Packing {
00261 NoPacking = 0x0000,
00262 Full = 0x0001,
00263 TriInFull = 0x0002,
00264 TriPacked = 0x0004,
00265 Banded = 0x0008,
00266 Vector = 0x0010,
00267 Scalar = 0x0020,
00268 Permutation = 0x0040
00269 };
00270 static const char* name(Packing);
00271 typedef unsigned short PackingMask;
00272 static const PackingMask AllPacking = 0x007fU;
00273 static const PackingMask UncommittedPacking = 0xffffU;
00274
00275 enum Placement {
00276 NoPlacement = 0x0000,
00277 Lower = 0x0001,
00278 Upper = 0x0002,
00279 };
00280 static const char* name(Placement);
00281 typedef unsigned short PlacementMask;
00282 static const PlacementMask AllPlacement = 0x0003U;
00283 static const PlacementMask UncommittedPlacement = 0xffffU;
00284
00285 enum Order {
00286 NoOrder = 0x0000,
00287 ColumnOrder = 0x0001,
00288 RowOrder = 0x0002,
00289 };
00290 static const char* name(Order);
00291 typedef unsigned short OrderMask;
00292 static const OrderMask AllOrder = 0x03U;
00293 static const OrderMask UncommittedOrder = 0xffU;
00294
00295 enum Diagonal {
00296 NoDiag = 0x0000,
00297 StoredDiag = 0x0001,
00298 AssumedDiag = 0x0002
00299 };
00300 static const char* name(Diagonal);
00301 typedef unsigned short DiagonalMask;
00302 static const DiagonalMask AllDiagonal = 0x0003U;
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;
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
00430
00431 class SimTK_SimTKCOMMON_EXPORT MatrixOutline {
00432 public:
00433 enum Outline {
00434 NoOutline = 0x0000,
00435 Scalar = 0x0001,
00436 Column = 0x0002,
00437 Row = 0x0004,
00438 Square = 0x0008,
00439 Wide = 0x0010,
00440 Tall = 0x0020,
00441 Rectangular = 0x0040
00442 };
00443 static const char* name(Outline);
00444
00445 typedef unsigned short OutlineMask;
00446 static const OutlineMask AnyOutline = 0x007fU;
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
00508
00509 class SimTK_SimTKCOMMON_EXPORT MatrixCondition {
00510 public:
00511 enum Condition {
00512 UnknownCondition = 0x0000,
00513 Orthogonal = 0x0001,
00514 PositiveDefinite = 0x0002,
00515 WellConditioned = 0x0004,
00516 FullRank = 0x0008,
00517 Singular = 0x0010
00518 };
00519 static const char* name(Condition);
00520
00521 typedef unsigned short ConditionMask;
00522 static const ConditionMask AnyCondition = 0x001fU;
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;
00535 static const DiagonalMask AnyDiagonal = 0x000fU;
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
00601
00609
00610
00611 class SimTK_SimTKCOMMON_EXPORT MatrixCharacter {
00612 public:
00615 MatrixCharacter() : nr(0), nc(0), lband(0), uband(0) {}
00616
00617
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
00631
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;
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
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
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
00838
00843
00844
00845 class SimTK_SimTKCOMMON_EXPORT MatrixCommitment {
00846 public:
00847 MatrixCommitment() {}
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()
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
01113
01114 }
01115
01116 #endif // SimTK_SIMMATRIX_MATRIX_CHARACTERISTICS_H_