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{
28private:
29 bool dirty;
30 int precision, width;
31
32 void Init();
33 void Copy(ColumnExtras & c);
34
35public:
36 String label;
37
39 {
40 Init();
41 }
42 ColumnExtras(ColumnExtras & original)
43 {
44 Init();
45 Copy(original);
46 }
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
76class Matrix
77{
78public:
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
252private:
253 static int alloc;
254 static int CompareRows(Vector ** row1, Vector ** row2);
255
256 void Init();
257};
258
259#endif
260
261
262