Simbody  3.5
MatrixCharacteristics.h
Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines