libStatGen Software  1
MathMatrix.h
1 /*
2  * Copyright (C) 2010 Regents of the University of Michigan
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef __MATHMATRIX_H__
19 #define __MATHMATRIX_H__
20 
21 #include "MathVector.h"
22 #include "Error.h"
23 
24 #include <stdio.h>
25 
27 {
28 private:
29  bool dirty;
30  int precision, width;
31 
32  void Init();
33  void Copy(ColumnExtras & c);
34 
35 public:
36  String label;
37 
38  ColumnExtras()
39  {
40  Init();
41  }
42  ColumnExtras(ColumnExtras & original)
43  {
44  Init();
45  Copy(original);
46  }
47  ~ColumnExtras();
48 
49  void SetLabel(const char * name);
50  void SetPrecision(int p)
51  {
52  precision = p;
53  dirty = true;
54  }
55  void SetWidth(int w)
56  {
57  width = w;
58  dirty = true;
59  }
60 
61  int GetWidth();
62  int GetPrecision()
63  {
64  return precision;
65  }
66 
67  ColumnExtras & operator = (ColumnExtras & rhs)
68  {
69  Copy(rhs);
70  return (*this);
71  }
72 
73  void Swap(ColumnExtras & rhs);
74 };
75 
76 class Matrix
77 {
78 public:
79  String label;
80  ColumnExtras * extras;
81  int rows, cols, size, extraSize;
82  Vector ** data;
83 
84  Matrix()
85  {
86  Init();
87  }
88  Matrix(Matrix & m)
89  {
90  Init();
91  Copy(m);
92  }
93  Matrix(Matrix & m, const char * name)
94  {
95  Init();
96  Copy(m);
97  SetLabel(name);
98  }
99  Matrix(int n, int m)
100  {
101  Init();
102  Dimension(n, m);
103  }
104  Matrix(const char * name)
105  {
106  Init();
107  SetLabel(name);
108  }
109  Matrix(const char * name, int n, int m)
110  {
111  Init();
112  Dimension(n, m);
113  SetLabel(name);
114  }
115  ~Matrix();
116 
117  void Dimension(int m, int n);
118  void Dimension(int m, int n, double value);
119  void GrowTo(int m, int n)
120  {
121  Dimension(m > rows ? m : rows, n > cols ? n : cols);
122  }
123  void GrowTo(int m, int n, double value)
124  {
125  Dimension(m > rows ? m : rows, n > cols ? n : cols, value);
126  }
127 
128  void SetLabel(const char * name);
129  void SetColumnLabel(int n, const char * name)
130  {
131  extras[n].SetLabel(name);
132  }
133  const char * GetColumnLabel(int n)
134  {
135  return extras[n].label;
136  }
137  void SetColWidth(int n, int w)
138  {
139  extras[n].SetWidth(w);
140  }
141  void SetColPrecision(int n, int p)
142  {
143  extras[n].SetPrecision(p);
144  }
145  void CopyLabels(Matrix & m);
146 
147  void Negate();
148  void Identity();
149  void Zero();
150  void Set(double k);
151 
152  void Copy(const Matrix & m);
153  void Transpose(const Matrix & m);
154  void Add(const Matrix & m);
155  void AddMultiple(double k, const Matrix & m);
156  void Product(const Matrix & left, const Matrix & right);
157 
158  void Add(double k);
159  void Multiply(double k);
160 
161  // Reduces a matrix to row echelon form, assuming
162  // values smaller than tol are zero
163  void Reduce(double tol = 0.0);
164 
165  Vector & operator [](int i)
166  {
167  assert(i < rows);
168  return *(data[i]);
169  }
170 
171  const Vector & operator [](int i) const
172  {
173  assert(i < rows);
174  return *(data[i]);
175  }
176 
177  void DeleteRow(int r);
178  void DeleteColumn(int c);
179 
180  void SwapRows(int r1, int r2)
181  {
182  Vector * temp = data[r1];
183  data[r1] = data[r2];
184  data[r2] = temp;
185  };
186 
187  void SwapColumns(int c1, int c2);
188 
189  void MultiplyRow(int r1, double k);
190  void AddRows(int r1, int r2);
191  void AddRows(double k, int r1, int r2);
192 
193  // Sort according to numeric values in the first column
194  void Sort();
195 
196  void Print(FILE * f, int maxRows = -1, int maxCols = -1);
197  void PrintUpper(FILE * f, int maxRows = -1, int maxCols = -1, bool print_diag = false);
198  void PrintLower(FILE * f, int maxRows = -1, int maxCols = -1, bool print_diag = false);
199  void SetupPrint(FILE *f, int r, int c, int & column_zero, int * precision, int * width);
200 
201  void Read(FILE * f);
202 
203  Matrix & operator = (const Matrix & rhs)
204  {
205  Copy(rhs);
206  return *this;
207  }
208 
209  bool operator == (const Matrix & rhs) const;
210  bool operator != (const Matrix & rhs) const
211  {
212  return !(*this == rhs);
213  }
214 
215  Matrix & operator *= (double rhs)
216  {
217  Multiply(rhs);
218  return *this;
219  }
220  Matrix & operator /= (double rhs)
221  {
222  Multiply(1.0/rhs);
223  return *this;
224  }
225 
226  // Stack a matrix to the bottom of the current matrix
227  void StackBottom(const Matrix & m);
228 
229  // Stack a matrix to the left of the current matrix
230  void StackLeft(const Matrix & m);
231 
232  // Swap dynamic allocation for two matrices
233  void Swap(Matrix & m);
234 
235  // Functions that calculate basic summary statistics
236  double Min() const;
237  double Max() const;
238  double Mean() const;
239 
240  // Functions that calculate summary statistics in the presence of missing data
241  double SafeMin() const;
242  double SafeMax() const;
243  double SafeMean() const;
244  int SafeCount() const;
245 
246  // Return the last row in matrix
247  Vector & Last()
248  {
249  return *(data[rows - 1]);
250  }
251 
252 private:
253  static int alloc;
254  static int CompareRows(Vector ** row1, Vector ** row2);
255 
256  void Init();
257 };
258 
259 #endif
260 
261 
262