Simbody  3.4 (development)
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-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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines