Simbody
3.4 (development)
|
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-12 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 00091 class MatrixStructure; 00092 class MatrixStorage; 00093 class MatrixOutline; 00094 class MatrixCondition; 00095 class MatrixCharacter; 00096 class MatrixCommitment; 00097 00098 00099 // ------------------------------ MatrixStructure ----------------------------- 00104 // ---------------------------------------------------------------------------- 00105 class SimTK_SimTKCOMMON_EXPORT MatrixStructure { 00106 public: 00107 enum Structure { 00108 NoStructure = 0x00000000, 00109 Matrix1d = 0x00000001, 00110 Zero = 0x00000002, 00111 Identity = 0x00000004, 00112 Permutation = 0x00000008, 00113 RepeatedDiagonal = 0x00000010, 00114 Diagonal = 0x00000020, 00115 BiDiagonal = 0x00000040, 00116 TriDiagonal = 0x00000080, 00117 BandedSymmetric = 0x00000100, 00118 BandedHermitian = 0x00000200, 00119 Banded = 0x00000400, 00120 Triangular = 0x00000800, 00121 QuasiTriangular = 0x00001000, 00122 Hessenberg = 0x00002000, 00123 Symmetric = 0x00004000, 00124 Hermitian = 0x00008000, 00125 SkewSymmetric = 0x00010000, 00126 SkewHermitian = 0x00020000, 00127 Full = 0x00040000 00128 }; 00129 static const char* name(Structure); 00130 00131 typedef unsigned int StructureMask; // 32 bits 00132 static const StructureMask AnyStructure = 0x0007ffffU; // see above 00133 static const StructureMask UncommittedStructure = 0xffffffffU; 00134 static StructureMask calcStructureMask(Structure); 00135 00140 enum Position { 00141 NoPosition = 0x0000, 00142 Lower = 0x0001, // matrix is lower triangular (default) 00143 Upper = 0x0002 // matrix is upper triangular 00144 }; 00145 static const char* name(Position); 00146 00147 typedef unsigned short PositionMask; // 16 bits 00148 static const PositionMask AnyPosition = 0x0003U; // see above 00149 static const PositionMask UncommittedPosition = 0xffffU; 00150 static PositionMask calcPositionMask(Structure); 00151 00157 enum DiagValue { 00158 NoDiagValue = 0x0000, 00159 StoredDiag = 0x0001, // could be anything (default) 00160 ZeroDiag = 0x0002, // zero (e.g. for skew matrices) 00161 UnitDiag = 0x0004 // unit (one) diagonal is used frequently by Lapack 00162 }; 00163 static const char* name(DiagValue); 00164 00165 typedef unsigned short DiagValueMask; // 16 bits 00166 static const DiagValueMask AnyDiagValue = 0x0003U; 00167 static const DiagValueMask UncommittedDiagValue = 0xffffU; 00168 static DiagValueMask calcDiagValueMask(Structure); 00169 00170 MatrixStructure& setMissingAttributes() { 00171 if (structure == NoStructure) 00172 structure = Full; 00173 if (position == NoPosition) 00174 position = Lower; 00175 if (diagValue == NoDiagValue) 00176 diagValue = StoredDiag; 00177 return *this; 00178 } 00179 00180 std::string name() const { 00181 return std::string(name(getStructure())) 00182 + "|" + std::string(name(getPosition())) 00183 + "|" + std::string(name(getDiagValue())); 00184 } 00185 00186 struct Mask { 00187 Mask() {setToUncommitted();} 00188 Mask(StructureMask sm, PositionMask pm, DiagValueMask dm) 00189 : structure(sm), position(pm), diagValue(dm) {} 00190 Mask& setToUncommitted() 00191 { structure=UncommittedStructure; position=UncommittedPosition; 00192 diagValue=UncommittedDiagValue; return *this; } 00193 bool isUncommitted() const 00194 { return structure==UncommittedStructure && position==UncommittedPosition 00195 && diagValue==UncommittedDiagValue; } 00196 bool isSatisfiedBy(Structure str, Position pos, DiagValue diag) const 00197 { return ((StructureMask)str&structure)==(StructureMask)str 00198 && ((PositionMask)pos&position)==(PositionMask)pos 00199 && ((DiagValueMask)diag&diagValue)==(DiagValueMask)diag; } 00200 bool isSatisfiedBy(const MatrixStructure& actual) const 00201 { return isSatisfiedBy(actual.getStructure(), actual.getPosition(), 00202 actual.getDiagValue()); } 00203 00204 StructureMask structure; 00205 PositionMask position; 00206 DiagValueMask diagValue; 00207 }; 00208 00209 MatrixStructure() {setToNone();} 00210 00213 MatrixStructure(Structure s, Position p=NoPosition, DiagValue d=NoDiagValue) 00214 : structure(s), position(p), diagValue(d) {} 00215 00220 Mask mask() const; 00221 00222 Structure getStructure() const {return structure;} 00223 Position getPosition() const {return position;} 00224 DiagValue getDiagValue() const {return diagValue;} 00225 00226 MatrixStructure& setStructure(Structure s) {structure=s; return *this;} 00227 MatrixStructure& setPosition (Position p) {position=p; return *this;} 00228 MatrixStructure& setDiagValue(DiagValue d) {diagValue=d; return *this;} 00229 00230 MatrixStructure& set(Structure s, Position p, DiagValue d) 00231 { structure=s; position=p; diagValue=d; return *this; } 00232 00233 MatrixStructure& setToNone() 00234 { structure=NoStructure; position=NoPosition; 00235 diagValue=NoDiagValue; return *this; } 00236 00237 private: 00238 Structure structure:32; 00239 Position position:16; 00240 DiagValue diagValue:16; 00241 }; 00242 00243 00244 // ------------------------------ MatrixStorage ------------------------------- 00249 // ---------------------------------------------------------------------------- 00250 class SimTK_SimTKCOMMON_EXPORT MatrixStorage { 00251 public: 00252 enum Packing { 00253 NoPacking = 0x0000, 00254 Full = 0x0001, // full storage layout 00255 TriInFull = 0x0002, // a triangular piece of a full storage layout 00256 TriPacked = 0x0004, // triangle packed into minimal storage, at performance cost 00257 Banded = 0x0008, // a packed, banded storage format 00258 Vector = 0x0010, // a possibly-strided or scattered vector 00259 Scalar = 0x0020, // a single scalar is stored 00260 Permutation = 0x0040 // a permuted identity matrix 00261 }; 00262 static const char* name(Packing); 00263 typedef unsigned short PackingMask; 00264 static const PackingMask AllPacking = 0x007fU; // see above 00265 static const PackingMask UncommittedPacking = 0xffffU; 00266 00267 enum Placement { 00268 NoPlacement = 0x0000, 00269 Lower = 0x0001, // stored in lower triangle of full matrix 00270 Upper = 0x0002, // stored in upper triangle of full matrix 00271 }; 00272 static const char* name(Placement); 00273 typedef unsigned short PlacementMask; 00274 static const PlacementMask AllPlacement = 0x0003U; // see above 00275 static const PlacementMask UncommittedPlacement = 0xffffU; 00276 00277 enum Order { 00278 NoOrder = 0x0000, 00279 ColumnOrder = 0x0001, // matrix is stored by columns 00280 RowOrder = 0x0002, // matrix is stored by rows 00281 }; 00282 static const char* name(Order); 00283 typedef unsigned short OrderMask; 00284 static const OrderMask AllOrder = 0x03U; // see above 00285 static const OrderMask UncommittedOrder = 0xffU; 00286 00287 enum Diagonal { 00288 NoDiag = 0x0000, 00289 StoredDiag = 0x0001, // matrix diagonal is stored 00290 AssumedDiag = 0x0002 // matrix diagonal is not stored but has known value 00291 }; 00292 static const char* name(Diagonal); 00293 typedef unsigned short DiagonalMask; 00294 static const DiagonalMask AllDiagonal = 0x0003U; // see above 00295 static const DiagonalMask UncommittedDiagonal = 0xffffU; 00296 00299 struct Mask { 00300 Mask() 00301 : packing(UncommittedPacking), placement(UncommittedPlacement), 00302 order(UncommittedOrder), diagonal(UncommittedDiagonal) {} 00303 Mask(PackingMask pkm, PlacementMask plm, OrderMask om, DiagonalMask dm) 00304 : packing(pkm), placement(plm), order(om), diagonal(dm) {} 00305 Mask& setToUncommitted() 00306 { packing=UncommittedPacking; placement=UncommittedPlacement; 00307 order=UncommittedOrder; diagonal=UncommittedDiagonal; return *this; } 00308 bool isUncommitted() const 00309 { return packing==UncommittedPacking && placement==UncommittedPlacement 00310 && order==UncommittedOrder && diagonal==UncommittedDiagonal; } 00311 bool isSatisfiedBy(Packing pack, Placement place, Order ord, Diagonal diag) const 00312 { return ((PackingMask)pack & packing) == (PackingMask) pack 00313 && ((PlacementMask)place & placement) == (PlacementMask)place 00314 && ((OrderMask)ord & order) == (OrderMask) ord 00315 && ((DiagonalMask)diag & diagonal) == (DiagonalMask) diag; } 00316 bool isSatisfiedBy(const MatrixStorage& actual) const 00317 { return isSatisfiedBy(actual.getPacking(), actual.getPlacement(), 00318 actual.getOrder(), actual.getDiagonal());} 00319 00320 PackingMask packing; 00321 PlacementMask placement; 00322 OrderMask order; 00323 DiagonalMask diagonal; 00324 }; 00325 00326 static MatrixStorage calcDefaultStorage(const MatrixStructure&, 00327 const MatrixOutline&); 00328 00329 std::string name() const { 00330 return std::string(name(getPacking())) 00331 + "|" + std::string(name(getPlacement())) 00332 + "|" + std::string(name(getOrder())) 00333 + "|" + std::string(name(getDiagonal())); 00334 } 00335 00340 Mask mask() const { 00341 Mask ms; // initially uncommitted 00342 if (packing) ms.packing = (PackingMask)packing; 00343 if (placement) ms.placement = (PlacementMask)placement; 00344 if (order) ms.order = (OrderMask)order; 00345 if (diagonal) ms.diagonal = (DiagonalMask)diagonal; 00346 return ms; 00347 } 00348 00350 MatrixStorage() 00351 : packing(NoPacking), placement(NoPlacement), order(NoOrder), diagonal(NoDiag) {} 00352 00356 MatrixStorage(Packing pk, Placement pl=NoPlacement, Order o=NoOrder, Diagonal d=NoDiag) 00357 : packing(pk), placement(pl), order(o), diagonal(d) {} 00358 00361 MatrixStorage(Packing pk, Order o) 00362 : packing(pk), placement(NoPlacement), order(o), diagonal(StoredDiag) {} 00363 00366 MatrixStorage& setMissingAttributes() { 00367 if (packing==NoPacking) 00368 packing = Full; 00369 if (placement==NoPlacement) 00370 placement = Lower; 00371 if (order==NoOrder) 00372 order = ColumnOrder; 00373 if (diagonal==NoDiag) 00374 diagonal = StoredDiag; 00375 return *this; 00376 } 00377 00379 MatrixStorage& setToNone() 00380 { packing=NoPacking; placement=NoPlacement; 00381 order=NoOrder; diagonal=NoDiag; return *this; } 00382 00383 MatrixStorage& setPacking(Packing p) {packing = p; return *this;} 00384 MatrixStorage& setPlacement(Placement p) {placement = p; return *this;} 00385 MatrixStorage& setOrder(Order o) {order = o; return *this;} 00386 MatrixStorage& setDiagonal(Diagonal d) {diagonal = d; return *this;} 00387 00388 Packing getPacking() const {return packing;} 00389 Placement getPlacement() const {return placement;} 00390 Order getOrder() const {return order;} 00391 Diagonal getDiagonal() const {return diagonal;} 00392 00393 private: 00394 Packing packing:16; 00395 Placement placement:16; 00396 Order order:16; 00397 Diagonal diagonal:16; 00398 }; 00399 00400 00401 // ------------------------------- MatrixOutline ------------------------------ 00422 // ---------------------------------------------------------------------------- 00423 class SimTK_SimTKCOMMON_EXPORT MatrixOutline { 00424 public: 00425 enum Outline { 00426 NoOutline = 0x0000, 00427 Scalar = 0x0001, // 1x1 00428 Column = 0x0002, // mx1, m != 1 00429 Row = 0x0004, // 1xn, n != 1 00430 Square = 0x0008, // mxn, m == n 00431 Wide = 0x0010, // mxn, m < n 00432 Tall = 0x0020, // mxn, m > n 00433 Rectangular = 0x0040 // mxn 00434 }; 00435 static const char* name(Outline); 00436 00437 typedef unsigned short OutlineMask; 00438 static const OutlineMask AnyOutline = 0x007fU; // see above 00439 static const OutlineMask UncommittedOutline = 0xffffU; 00440 00441 struct Mask { 00442 Mask() : outline(UncommittedOutline) {} 00443 explicit Mask(OutlineMask mask) : outline(mask) {} 00444 Mask& setToUncommitted() {outline=UncommittedOutline; return *this;} 00445 bool isUncommitted() const {return outline==UncommittedOutline;} 00446 bool isSatisfiedBy(const MatrixOutline& actual) const 00447 { return ((OutlineMask)actual.outline & outline) == (OutlineMask)actual.outline; } 00448 00449 OutlineMask outline; 00450 }; 00451 00452 std::string name() const {return std::string(name(getOutline()));} 00453 00456 MatrixOutline() : outline(NoOutline) {} 00457 00459 MatrixOutline(Outline outline) : outline(outline) {} 00460 00462 MatrixOutline& setToNone() {outline=NoOutline; return *this;} 00463 00467 static OutlineMask calcMask(Outline); 00468 00471 Mask mask() const {return Mask(calcMask(getOutline()));} 00472 00474 bool isSizeOK(int m, int n) const; 00475 00477 void getMinimumSize(int& m, int& n) const; 00478 00480 static MatrixOutline calcFromSize(int m, int n); 00481 00483 Outline getOutline() const {return outline;} 00484 00485 private: 00486 Outline outline:16; 00487 }; 00488 00489 00490 00491 // ---------------------------- MatrixCondition ------------------------------- 00500 // ---------------------------------------------------------------------------- 00501 class SimTK_SimTKCOMMON_EXPORT MatrixCondition { 00502 public: 00503 enum Condition { 00504 UnknownCondition = 0x0000, 00505 Orthogonal = 0x0001, // implies well conditioned 00506 PositiveDefinite = 0x0002, // implies well conditioned 00507 WellConditioned = 0x0004, // implies full rank 00508 FullRank = 0x0008, // but might have bad conditioning 00509 Singular = 0x0010 // implies possible bad conditioning 00510 }; 00511 static const char* name(Condition); 00512 00513 typedef unsigned short ConditionMask; // 16 bits in mask 00514 static const ConditionMask AnyCondition = 0x001fU; // see above 00515 static const ConditionMask UncommittedCondition = 0xffffU; 00516 00517 enum Diagonal { 00518 UnknownDiagonal = 0x0000, 00519 ZeroDiagonal = 0x0001, 00520 OneDiagonal = 0x0002, 00521 RealDiagonal = 0x0004, 00522 ImaginaryDiagonal = 0x0008 00523 }; 00524 static const char* name(Diagonal); 00525 00526 typedef unsigned short DiagonalMask; // 16 bits in mask 00527 static const DiagonalMask AnyDiagonal = 0x000fU; // see above 00528 static const DiagonalMask UncommittedDiagonal = 0xffffU; 00529 00531 struct Mask { 00532 Mask() : condition(UncommittedCondition), diagonal(UncommittedDiagonal) {} 00533 Mask(ConditionMask cmask, DiagonalMask dmask) : condition(cmask), diagonal(dmask) {} 00534 Mask& setToUncommitted() 00535 { condition=UncommittedCondition; diagonal=UncommittedDiagonal; return *this;} 00536 bool isUncommitted() const 00537 { return condition==UncommittedCondition && diagonal==UncommittedDiagonal;} 00538 bool isSatisfiedBy(const MatrixCondition& actual) const 00539 { return ((ConditionMask)actual.condition & condition) == (ConditionMask)actual.condition 00540 && ((DiagonalMask) actual.diagonal & diagonal) == (DiagonalMask)actual.diagonal; } 00541 00542 ConditionMask condition; 00543 DiagonalMask diagonal; 00544 }; 00545 00546 std::string name() const 00547 { return std::string(name(getCondition())) + "|" + std::string(name(getDiagonal()));} 00548 00551 MatrixCondition() : condition(UnknownCondition), diagonal(UnknownDiagonal) {} 00552 00555 MatrixCondition(Condition cond, Diagonal diag=UnknownDiagonal) : condition(cond) {} 00556 00558 MatrixCondition& setToNone() {condition=UnknownCondition; diagonal=UnknownDiagonal; return *this;} 00559 00565 static ConditionMask calcMask(Condition); 00566 00572 static DiagonalMask calcMask(Diagonal); 00573 00576 Mask mask() const 00577 { return Mask(calcMask(getCondition()), calcMask(getDiagonal())); } 00578 00579 Condition getCondition() const {return condition;} 00580 Diagonal getDiagonal() const {return diagonal;} 00581 00582 MatrixCondition& setCondition(Condition c) {condition=c; return *this;} 00583 MatrixCondition& setDiagonal (Diagonal d) {diagonal=d; return *this;} 00584 00585 private: 00586 Condition condition:16; 00587 Diagonal diagonal:16; 00588 }; 00589 00590 00591 00592 // ------------------------------ MatrixCharacter ----------------------------- 00593 00601 00602 // ---------------------------------------------------------------------------- 00603 class SimTK_SimTKCOMMON_EXPORT MatrixCharacter { 00604 public: 00607 MatrixCharacter() : nr(0), nc(0), lband(0), uband(0) {} 00608 00609 // Some handy predefined MatrixCharacters. 00610 class LapackFull; 00611 class Vector; 00612 class RowVector; 00613 00615 MatrixCharacter& setToNone() { 00616 nr=nc=lband=uband=0; 00617 structure.setToNone(); outline.setToNone(); 00618 storage.setToNone(); condition.setToNone(); 00619 return *this; 00620 } 00621 00622 // These are dimensions of the logical matrix and have nothing to do with how 00623 // much storage may be used to hold the elements. 00624 int nrow() const {return nr;} 00625 int ncol() const {return nc;} 00626 std::pair<int,int> getSize() const {return std::pair<int,int>(nrow(),ncol());} 00627 ptrdiff_t nelt() const {return (ptrdiff_t)nrow() * (ptrdiff_t)ncol();} 00628 00629 int getLowerBandwidth() const {return lband;} 00630 int getUpperBandwidth() const {return uband;} 00631 std::pair<int,int> getBandwidth() const 00632 { return std::pair<int,int>(getLowerBandwidth(), getUpperBandwidth()); } 00633 00634 const MatrixStructure& getStructure() const {return structure;} 00635 const MatrixStorage& getStorage() const {return storage;} 00636 const MatrixOutline& getOutline() const {return outline;} 00637 const MatrixCondition& getCondition() const {return condition;} 00638 00639 MatrixStructure& updStructure() {return structure;} 00640 MatrixStorage& updStorage() {return storage;} 00641 MatrixOutline& updOutline() {return outline;} 00642 MatrixCondition& updCondition() {return condition;} 00643 00644 MatrixCharacter& setStructure(const MatrixStructure& sa) {structure = sa; return *this;} 00645 MatrixCharacter& setStorage (const MatrixStorage& sa) {storage = sa; return *this;} 00646 MatrixCharacter& setOutline (const MatrixOutline& oa) {outline = oa; return *this;} 00647 MatrixCharacter& setCondition(const MatrixCondition& ca) {condition = ca; return *this;} 00648 00649 00651 MatrixCharacter& setActualSize(int m, int n) 00652 { setSize(m,n); outline = MatrixOutline::calcFromSize(m,n); return *this; } 00653 MatrixCharacter& setActualNumRows(int m) 00654 { setNumRows(m); outline = MatrixOutline::calcFromSize(m,ncol()); return *this; } 00655 MatrixCharacter& setActualNumCols(int n) 00656 { setNumCols(n); outline = MatrixOutline::calcFromSize(nrow(),n); return *this; } 00657 00658 MatrixCharacter& setBandwidth(int lb, int ub) { 00659 assert(lb>=0 && lb>=0); 00660 lband = lb; uband = ub; 00661 return *this; 00662 } 00663 MatrixCharacter& setLowerBandwidth(int lb) { 00664 assert(lb>=0); 00665 lband = lb; 00666 return *this; 00667 } 00668 MatrixCharacter& setUpperBandwidth(int ub) { 00669 assert(ub>=0); 00670 uband = ub; 00671 return *this; 00672 } 00673 00674 class Mask; // defined below 00675 00676 protected: 00677 MatrixCharacter(int m, int n, 00678 int lb, int ub, 00679 MatrixStructure structure, 00680 MatrixStorage storage, 00681 MatrixCondition condition) 00682 : nr(m), nc(n), lband(lb), uband(ub), 00683 structure(structure), storage(storage), 00684 outline(MatrixOutline::calcFromSize(m,n)), 00685 condition(condition) {} 00686 00687 00688 int nr, 00689 nc; 00690 int lband, 00691 uband; 00692 MatrixStructure structure; 00693 MatrixStorage storage; 00694 MatrixOutline outline; 00695 MatrixCondition condition; 00696 00697 private: 00698 // These are private because they don't set the outline as well. 00699 MatrixCharacter& setSize(int m, int n) 00700 { assert(m>=0 && n>=0); nr = m; nc = n; return *this; } 00701 MatrixCharacter& setNumRows(int m) 00702 { assert(m>=0); nr = m; return *this; } 00703 MatrixCharacter& setNumCols(int n) 00704 { assert(n>=0); nc = n; return *this; } 00705 }; 00706 00708 SimTK_SimTKCOMMON_EXPORT std::ostream& 00709 operator<<(std::ostream& o, const MatrixCharacter&); 00710 00716 class MatrixCharacter::LapackFull : public MatrixCharacter { 00717 public: 00718 LapackFull(int m, int n) 00719 : MatrixCharacter(m,n,0,0, 00720 MatrixStructure(MatrixStructure::Full), 00721 MatrixStorage(MatrixStorage::Full,MatrixStorage::ColumnOrder), 00722 MatrixCondition()) {} 00723 }; 00724 00729 class MatrixCharacter::Vector : public MatrixCharacter { 00730 public: 00731 Vector(int m) 00732 : MatrixCharacter(m,1,0,0, 00733 MatrixStructure(MatrixStructure::Matrix1d), 00734 MatrixStorage(MatrixStorage::Vector,MatrixStorage::ColumnOrder), 00735 MatrixCondition()) {} 00736 }; 00737 00742 class MatrixCharacter::RowVector : public MatrixCharacter { 00743 public: 00744 RowVector(int n) 00745 : MatrixCharacter(1,n,0,0, 00746 MatrixStructure(MatrixStructure::Matrix1d), 00747 MatrixStorage(MatrixStorage::Vector,MatrixStorage::RowOrder), 00748 MatrixCondition()) {} 00749 }; 00750 00751 // -------------------------- MatrixCharacter::Mask --------------------------- 00754 // ---------------------------------------------------------------------------- 00755 class MatrixCharacter::Mask { 00756 public: 00757 Mask() {setToUncommitted();} 00758 00759 typedef unsigned int SizeMask; 00760 static const SizeMask SizeUncommitted = 0xffffffffU; 00761 00762 bool isResizeable() const {return nr==SizeUncommitted || nc==SizeUncommitted;} 00763 bool isFullyResizeable() const {return nr==SizeUncommitted && nc==SizeUncommitted;} 00764 bool isNumRowsLocked() const {return nr!=SizeUncommitted;} 00765 bool isNumColsLocked() const {return nc!=SizeUncommitted;} 00766 00767 unsigned int getNumRowsMask() const {return nr;} 00768 unsigned int getNumColsMask() const {return nc;} 00769 unsigned int getLowerBandwidthMask() const {return lband;} 00770 unsigned int getUpperBandwidthMask() const {return uband;} 00771 00772 int getDefaultNumRows() const {return isNumRowsLocked() ? nr : 0;} 00773 int getDefaultNumCols() const {return isNumColsLocked() ? nc : 0;} 00774 00775 bool isLowerBandwidthLocked() const {return lband!=SizeUncommitted;} 00776 bool isUpperBandwidthLocked() const {return uband!=SizeUncommitted;} 00777 int getDefaultLowerBandwidth() const {return isLowerBandwidthLocked() ? lband : 0;} 00778 int getDefaultUpperBandwidth() const {return isUpperBandwidthLocked() ? uband : 0;} 00779 00781 Mask& setToUncommitted() { 00782 nr=nc=lband=uband=SizeUncommitted; 00783 structure.setToUncommitted(); storage.setToUncommitted(); 00784 outline.setToUncommitted(); condition.setToUncommitted(); 00785 return *this; 00786 } 00787 00789 bool isUncommitted() const { 00790 return nr==SizeUncommitted && nc==SizeUncommitted 00791 && lband==SizeUncommitted && uband==SizeUncommitted 00792 && structure.isUncommitted() && storage.isUncommitted() 00793 && outline.isUncommitted() && condition.isUncommitted(); 00794 } 00795 00797 bool isSatisfiedBy(const MatrixCharacter& actual) const { 00798 return isSizeOK(actual.nr, actual.nc) 00799 && isBandwidthOK(actual.lband, actual.uband) 00800 && structure.isSatisfiedBy(actual.getStructure()) 00801 && storage.isSatisfiedBy(actual.getStorage()) 00802 && outline.isSatisfiedBy(actual.getOutline()) 00803 && condition.isSatisfiedBy(actual.getCondition()); 00804 } 00805 00807 bool isSizeOK(int m, int n) const 00808 { return ((SizeMask)m & nr) == (SizeMask)m 00809 && ((SizeMask)n & nc) == (SizeMask)n; } 00810 00813 bool isBandwidthOK(int lower, int upper) const 00814 { return ((SizeMask)lower & lband) == (SizeMask)lower 00815 && ((SizeMask)upper & uband) == (SizeMask)upper; } 00816 00817 SizeMask nr, 00818 nc; 00819 SizeMask lband, 00820 uband; 00821 MatrixStructure::Mask structure; 00822 MatrixStorage::Mask storage; 00823 MatrixOutline::Mask outline; 00824 MatrixCondition::Mask condition; 00825 00826 friend class MatrixCommitment; 00827 }; 00828 00829 // ----------------------------- MatrixCommitment ----------------------------- 00830 00835 00836 // ---------------------------------------------------------------------------- 00837 class SimTK_SimTKCOMMON_EXPORT MatrixCommitment { 00838 public: 00839 MatrixCommitment() {} // set commitments to "none" and masks to "uncommitted" 00840 00843 MatrixCommitment(const MatrixStructure& str) 00844 { new (this) MatrixCommitment(str, MatrixStorage(), MatrixOutline(), MatrixCondition());} 00845 00846 class Vector; 00847 class RowVector; 00848 class Triangular; 00849 class Symmetric; 00850 class Hermitian; 00851 class SkewSymmetric; 00852 class SkewHermitian; 00853 00854 MatrixCommitment& commitSize(int m, int n) 00855 { commitNumRows(m); commitNumCols(n); return *this; } 00856 MatrixCommitment& commitNumRows(int m) 00857 { SimTK_SIZECHECK_NONNEG(m, "MatrixCommitment::commitNumRows()"); 00858 masks.nr = m; return *this; } 00859 MatrixCommitment& commitNumCols(int n) 00860 { SimTK_SIZECHECK_NONNEG(n, "MatrixCommitment::commitNumCols()"); 00861 masks.nc = n; return *this; } 00862 00863 MatrixCommitment& commitBandwidth(int lb, int ub) 00864 { commitLowerBandwidth(lb); commitUpperBandwidth(ub); return *this;} 00865 MatrixCommitment& commitLowerBandwidth(int lb) 00866 { SimTK_SIZECHECK_NONNEG(lb, "MatrixCommitment::commitLowerBandwidth()"); 00867 masks.lband = lb; return *this; } 00868 MatrixCommitment& commitUpperBandwidth(int ub) 00869 { SimTK_SIZECHECK_NONNEG(ub, "MatrixCommitment::commitUpperBandwidth()"); 00870 masks.uband = ub; return *this; } 00871 00872 MatrixCommitment& commitStructure(const MatrixStructure& s) 00873 { structure=s; masks.structure=s.mask(); return *this; } 00874 MatrixCommitment& commitStorage (const MatrixStorage& s) 00875 { storage=s; masks.storage =s.mask(); return *this; } 00876 MatrixCommitment& commitOutline (const MatrixOutline& o) 00877 { outline=o; masks.outline =o.mask(); return *this; } 00878 MatrixCommitment& commitCondition(const MatrixCondition& c) 00879 { condition=c; masks.condition=c.mask(); return *this; } 00880 00891 MatrixCharacter calcDefaultCharacter(int minNumRows, int minNumCols) const; 00892 00894 const MatrixStructure& getStructureCommitment() const {return structure;} 00895 const MatrixStorage& getStorageCommitment() const {return storage;} 00896 const MatrixOutline& getOutlineCommitment() const {return outline;} 00897 const MatrixCondition& getConditionCommitment() const {return condition;} 00898 00900 const MatrixStructure::Mask& getStructureMask() const {return masks.structure;} 00901 const MatrixStorage::Mask& getStorageMask() const {return masks.storage;} 00902 const MatrixOutline::Mask& getOutlineMask() const {return masks.outline;} 00903 const MatrixCondition::Mask& getConditionMask() const {return masks.condition;} 00904 00905 MatrixCharacter::Mask::SizeMask getNumRowsMask() const {return masks.nr;} 00906 MatrixCharacter::Mask::SizeMask getNumColsMask() const {return masks.nc;} 00907 MatrixCharacter::Mask::SizeMask getLowerBandwidthMask() const {return masks.lband;} 00908 MatrixCharacter::Mask::SizeMask getUpperBandwidthMask() const {return masks.uband;} 00909 00910 int getDefaultNumRows() const {return masks.getDefaultNumRows();} 00911 int getDefaultNumCols() const {return masks.getDefaultNumRows();} 00912 00913 bool isSizeOK(int m, int n) const {return masks.isSizeOK(m,n);} 00914 bool isSizeOK(const std::pair<int,int>& mn) const 00915 { return isSizeOK(mn.first, mn.second); } 00916 00917 bool isBandwidthOK(int lower, int upper) const {return masks.isBandwidthOK(lower,upper);} 00918 00919 bool isSatisfiedBy(const MatrixCharacter& actual) const 00920 { return masks.isSatisfiedBy(actual); } 00921 bool isStructureOK(const MatrixStructure& s) const 00922 { return getStructureMask().isSatisfiedBy(s); } 00923 bool isStorageOK(const MatrixStorage& s) const 00924 { return getStorageMask().isSatisfiedBy(s); } 00925 bool isOutlineOK(const MatrixOutline& o) const 00926 { return getOutlineMask().isSatisfiedBy(o); } 00927 bool isConditionOK(const MatrixCondition& c) const 00928 { return getConditionMask().isSatisfiedBy(c); } 00929 00930 bool isResizeable() const {return masks.isResizeable();} 00931 bool isFullyResizeable() const {return masks.isFullyResizeable();;} 00932 bool isNumRowsLocked() const {return masks.isNumRowsLocked();} 00933 bool isNumColsLocked() const {return masks.isNumColsLocked();} 00934 00935 bool isStructureCommitted() const 00936 { return !getStructureMask().isUncommitted(); } 00937 bool isStorageCommitted() const 00938 { return !getStorageMask().isUncommitted();} 00939 bool isOutlineCommitted() const 00940 { return !getOutlineMask().isUncommitted(); } 00941 bool isConditionCommitted() const 00942 { return !getConditionMask().isUncommitted();} 00943 00945 void clear() { 00946 structure.setToNone(); 00947 storage.setToNone(); 00948 outline.setToNone(); 00949 condition.setToNone(); 00950 masks.setToUncommitted(); 00951 } 00952 00953 protected: 00954 MatrixCommitment(const MatrixStructure& structure, 00955 const MatrixStorage& storage, 00956 const MatrixOutline& outline, 00957 const MatrixCondition& condition) 00958 : structure(structure), storage(storage), 00959 outline(outline), condition(condition), 00960 masks() // set to all 1's 00961 { 00962 if (outline.getOutline()==MatrixOutline::Scalar) commitSize(1,1); 00963 else if (outline.getOutline()==MatrixOutline::Column) commitNumCols(1); 00964 else if (outline.getOutline()==MatrixOutline::Row) commitNumRows(1); 00965 00966 masks.structure = structure.mask(); 00967 masks.storage = storage.mask(); 00968 masks.outline = outline.mask(); 00969 masks.condition = condition.mask(); 00970 } 00971 00974 MatrixStructure structure; 00975 MatrixStorage storage; 00976 MatrixOutline outline; 00977 MatrixCondition condition; 00978 00981 MatrixCharacter::Mask masks; 00982 }; 00983 00984 00986 class MatrixCommitment::Vector : public MatrixCommitment { 00987 public: 00989 Vector() 00990 : MatrixCommitment 00991 ( MatrixStructure(MatrixStructure::Matrix1d), 00992 MatrixStorage(), 00993 MatrixOutline(MatrixOutline::Column), 00994 MatrixCondition()) 00995 { 00996 } 00998 explicit Vector(int m) 00999 : MatrixCommitment 01000 ( MatrixStructure(MatrixStructure::Matrix1d), 01001 MatrixStorage(), 01002 MatrixOutline(MatrixOutline::Column), 01003 MatrixCondition()) 01004 { 01005 commitNumRows(m); 01006 } 01007 }; 01008 01010 class MatrixCommitment::RowVector : public MatrixCommitment { 01011 public: 01013 RowVector() 01014 : MatrixCommitment 01015 ( MatrixStructure(MatrixStructure::Matrix1d), 01016 MatrixStorage(), 01017 MatrixOutline(MatrixOutline::Row), 01018 MatrixCondition()) 01019 { 01020 } 01022 explicit RowVector(int n) 01023 : MatrixCommitment 01024 ( MatrixStructure(MatrixStructure::Matrix1d), 01025 MatrixStorage(), 01026 MatrixOutline(MatrixOutline::Row), 01027 MatrixCondition()) 01028 { 01029 commitNumCols(n); 01030 } 01031 }; 01032 01034 class MatrixCommitment::Triangular : public MatrixCommitment { 01035 public: 01036 Triangular() 01037 : MatrixCommitment(MatrixStructure::Triangular, MatrixStorage(), 01038 MatrixOutline(), MatrixCondition()) 01039 { 01040 } 01041 }; 01042 01045 class MatrixCommitment::Symmetric : public MatrixCommitment { 01046 public: 01047 Symmetric() 01048 : MatrixCommitment(MatrixStructure::Symmetric, MatrixStorage(), 01049 MatrixOutline(), MatrixCondition()) 01050 { 01051 } 01052 }; 01053 01057 class MatrixCommitment::Hermitian : public MatrixCommitment { 01058 public: 01059 Hermitian() 01060 : MatrixCommitment 01061 ( MatrixStructure::Hermitian, 01062 MatrixStorage(), 01063 MatrixOutline(), 01064 MatrixCondition().setDiagonal(MatrixCondition::RealDiagonal)) 01065 { 01066 } 01067 }; 01068 01072 class MatrixCommitment::SkewSymmetric : public MatrixCommitment { 01073 public: 01074 SkewSymmetric() 01075 : MatrixCommitment 01076 ( MatrixStructure::SkewSymmetric, 01077 MatrixStorage(), 01078 MatrixOutline(), 01079 MatrixCondition().setDiagonal(MatrixCondition::ZeroDiagonal)) 01080 { 01081 } 01082 }; 01083 01087 class MatrixCommitment::SkewHermitian : public MatrixCommitment { 01088 public: 01089 SkewHermitian() 01090 : MatrixCommitment 01091 ( MatrixStructure::SkewHermitian, 01092 MatrixStorage(), 01093 MatrixOutline(), 01094 MatrixCondition().setDiagonal(MatrixCondition::ImaginaryDiagonal)) 01095 { 01096 } 01097 }; 01098 01100 SimTK_SimTKCOMMON_EXPORT std::ostream& 01101 operator<<(std::ostream& o, const MatrixCommitment&); 01102 01103 // End of MatrixCharacteristics group. 01105 01106 } //namespace SimTK 01107 01108 #endif // SimTK_SIMMATRIX_MATRIX_CHARACTERISTICS_H_