libStatGen Software
1
|
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