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

Generated on Thu Aug 12 16:37:11 2010 for SimTKcore by  doxygen 1.6.1