libStatGen Software  1
MathMatrix.h
00001 /*
00002  *  Copyright (C) 2010  Regents of the University of Michigan
00003  *
00004  *   This program is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #ifndef __MATHMATRIX_H__
00019 #define __MATHMATRIX_H__
00020 
00021 #include "MathVector.h"
00022 #include "Error.h"
00023 
00024 #include <stdio.h>
00025 
00026 class ColumnExtras
00027 {
00028 private:
00029     bool dirty;
00030     int  precision, width;
00031 
00032     void Init();
00033     void Copy(ColumnExtras & c);
00034 
00035 public:
00036     String label;
00037 
00038     ColumnExtras()
00039     {
00040         Init();
00041     }
00042     ColumnExtras(ColumnExtras & original)
00043     {
00044         Init();
00045         Copy(original);
00046     }
00047     ~ColumnExtras();
00048 
00049     void SetLabel(const char * name);
00050     void SetPrecision(int p)
00051     {
00052         precision = p;
00053         dirty = true;
00054     }
00055     void SetWidth(int w)
00056     {
00057         width = w;
00058         dirty = true;
00059     }
00060 
00061     int    GetWidth();
00062     int    GetPrecision()
00063     {
00064         return precision;
00065     }
00066 
00067     ColumnExtras & operator = (ColumnExtras & rhs)
00068     {
00069         Copy(rhs);
00070         return (*this);
00071     }
00072 
00073     void Swap(ColumnExtras & rhs);
00074 };
00075 
00076 class Matrix
00077 {
00078 public:
00079     String    label;
00080     ColumnExtras * extras;
00081     int       rows, cols, size, extraSize;
00082     Vector ** data;
00083 
00084     Matrix()
00085     {
00086         Init();
00087     }
00088     Matrix(Matrix & m)
00089     {
00090         Init();
00091         Copy(m);
00092     }
00093     Matrix(Matrix & m, const char * name)
00094     {
00095         Init();
00096         Copy(m);
00097         SetLabel(name);
00098     }
00099     Matrix(int n, int m)
00100     {
00101         Init();
00102         Dimension(n, m);
00103     }
00104     Matrix(const char * name)
00105     {
00106         Init();
00107         SetLabel(name);
00108     }
00109     Matrix(const char * name, int n, int m)
00110     {
00111         Init();
00112         Dimension(n, m);
00113         SetLabel(name);
00114     }
00115     ~Matrix();
00116 
00117     void Dimension(int m, int n);
00118     void Dimension(int m, int n, double value);
00119     void GrowTo(int m, int n)
00120     {
00121         Dimension(m > rows ? m : rows, n > cols ? n : cols);
00122     }
00123     void GrowTo(int m, int n, double value)
00124     {
00125         Dimension(m > rows ? m : rows, n > cols ? n : cols, value);
00126     }
00127 
00128     void SetLabel(const char * name);
00129     void SetColumnLabel(int n, const char * name)
00130     {
00131         extras[n].SetLabel(name);
00132     }
00133     const char * GetColumnLabel(int n)
00134     {
00135         return extras[n].label;
00136     }
00137     void SetColWidth(int n, int w)
00138     {
00139         extras[n].SetWidth(w);
00140     }
00141     void SetColPrecision(int n, int p)
00142     {
00143         extras[n].SetPrecision(p);
00144     }
00145     void CopyLabels(Matrix & m);
00146 
00147     void Negate();
00148     void Identity();
00149     void Zero();
00150     void Set(double k);
00151 
00152     void Copy(const Matrix & m);
00153     void Transpose(const Matrix & m);
00154     void Add(const Matrix & m);
00155     void AddMultiple(double k, const Matrix & m);
00156     void Product(const Matrix & left, const Matrix & right);
00157 
00158     void Add(double k);
00159     void Multiply(double k);
00160 
00161     // Reduces a matrix to row echelon form, assuming
00162     // values smaller than tol are zero
00163     void Reduce(double tol = 0.0);
00164 
00165     Vector & operator [](int i)
00166     {
00167         assert(i < rows);
00168         return *(data[i]);
00169     }
00170 
00171     const Vector & operator [](int i) const
00172     {
00173         assert(i < rows);
00174         return *(data[i]);
00175     }
00176 
00177     void DeleteRow(int r);
00178     void DeleteColumn(int c);
00179 
00180     void SwapRows(int r1, int r2)
00181     {
00182         Vector * temp = data[r1];
00183         data[r1] = data[r2];
00184         data[r2] = temp;
00185     };
00186 
00187     void SwapColumns(int c1, int c2);
00188 
00189     void MultiplyRow(int r1, double k);
00190     void AddRows(int r1, int r2);
00191     void AddRows(double k, int r1, int r2);
00192 
00193     // Sort according to numeric values in the first column
00194     void Sort();
00195 
00196     void Print(FILE * f, int maxRows = -1, int maxCols = -1);
00197     void PrintUpper(FILE * f, int maxRows = -1, int maxCols = -1, bool print_diag = false);
00198     void PrintLower(FILE * f, int maxRows = -1, int maxCols = -1, bool print_diag = false);
00199     void SetupPrint(FILE *f, int r, int c, int & column_zero, int * precision, int * width);
00200 
00201     void Read(FILE * f);
00202 
00203     Matrix & operator = (const Matrix & rhs)
00204     {
00205         Copy(rhs);
00206         return *this;
00207     }
00208 
00209     bool operator == (const Matrix & rhs) const;
00210     bool operator != (const Matrix & rhs) const
00211     {
00212         return !(*this == rhs);
00213     }
00214 
00215     Matrix & operator *= (double rhs)
00216     {
00217         Multiply(rhs);
00218         return *this;
00219     }
00220     Matrix & operator /= (double rhs)
00221     {
00222         Multiply(1.0/rhs);
00223         return *this;
00224     }
00225 
00226     // Stack a matrix to the bottom of the current matrix
00227     void StackBottom(const Matrix & m);
00228 
00229     // Stack a matrix to the left of the current matrix
00230     void StackLeft(const Matrix & m);
00231 
00232     // Swap dynamic allocation for two matrices
00233     void Swap(Matrix & m);
00234 
00235     // Functions that calculate basic summary statistics
00236     double Min() const;
00237     double Max() const;
00238     double Mean() const;
00239 
00240     // Functions that calculate summary statistics in the presence of missing data
00241     double SafeMin() const;
00242     double SafeMax() const;
00243     double SafeMean() const;
00244     int SafeCount() const;
00245 
00246     // Return the last row in matrix
00247     Vector & Last()
00248     {
00249         return *(data[rows - 1]);
00250     }
00251 
00252 private:
00253     static int alloc;
00254     static int CompareRows(Vector ** row1, Vector ** row2);
00255 
00256     void Init();
00257 };
00258 
00259 #endif
00260 
00261 
00262 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends