File indexing completed on 2025-03-23 11:26:01
0001 /*************************************************************************** 0002 * Copyright (C) 2006 by Alan Grimes * 0003 * agrimes@speakeasy.net * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 0021 //#ifndef QMATRIX_H 0022 #include "qmatrix.h" 0023 //#endif 0024 0025 #include <cassert> 0026 #include <cmath> 0027 #include <cstdlib> // for NULL 0028 #include <cstring> 0029 #include <iostream> 0030 0031 /* 0032 #ifndef BADRNG_H 0033 #include "badrng.h" 0034 #endif 0035 */ 0036 0037 using namespace std; 0038 0039 // #################################### 0040 0041 bool QuickMatrix::isSquare() const 0042 { 0043 return m == n; 0044 } 0045 0046 // #################################### 0047 0048 // Ideally, this should be inlined, however I am reluctant to put code in the header files which may be included in numerous 0049 // object files locations. 0050 0051 unsigned int QuickMatrix::size_m() const 0052 { 0053 return m; 0054 } 0055 0056 // #################################### 0057 0058 unsigned int QuickMatrix::size_n() const 0059 { 0060 return n; 0061 } 0062 0063 // #################################### 0064 0065 void QuickMatrix::allocator() 0066 { 0067 // assert(!values); 0068 assert(m); 0069 assert(n); 0070 0071 values = new double *[m]; 0072 for (unsigned int i = 0; i < m; i++) { 0073 values[i] = new double[n]; 0074 } 0075 } 0076 0077 // #################################### 0078 0079 QuickMatrix::QuickMatrix(CUI m_in, CUI n_in) 0080 : m(m_in) 0081 , n(n_in) 0082 { 0083 allocator(); 0084 fillWithZero(); 0085 } 0086 0087 // #################################### 0088 0089 QuickMatrix::QuickMatrix(CUI m_in) 0090 : m(m_in) 0091 , n(m_in) 0092 { 0093 allocator(); 0094 fillWithZero(); 0095 } 0096 0097 // #################################### 0098 0099 QuickMatrix::QuickMatrix(const QuickMatrix *old) 0100 : m(old->m) 0101 , n(old->n) 0102 { 0103 allocator(); 0104 0105 for (unsigned int j = 0; j < m; j++) { 0106 memcpy(values[j], old->values[j], n * sizeof(double)); // fastest method. =) 0107 } 0108 } 0109 0110 // #################################### 0111 0112 QuickMatrix::~QuickMatrix() 0113 { 0114 for (unsigned int i = 0; i < m; i++) 0115 delete[] values[i]; 0116 delete[] values; 0117 } 0118 0119 // #################################### 0120 0121 double QuickMatrix::at(CUI m_a, CUI n_a) const 0122 { 0123 if (m_a >= m || n_a >= n) 0124 return NAN; 0125 0126 return values[m_a][n_a]; 0127 } 0128 0129 // #################################### 0130 0131 bool QuickMatrix::atPut(CUI m_a, CUI n_a, const double val) 0132 { 0133 if (m_a >= m || n_a >= n) 0134 return false; 0135 0136 values[m_a][n_a] = val; 0137 return true; 0138 } 0139 0140 // #################################### 0141 0142 bool QuickMatrix::atAdd(CUI m_a, CUI n_a, const double val) 0143 { 0144 if (m_a >= m || n_a >= n) 0145 return false; 0146 0147 values[m_a][n_a] += val; 0148 return true; 0149 } 0150 0151 // #################################### 0152 0153 bool QuickMatrix::swapRows(CUI m_a, CUI m_b) 0154 { 0155 if (m_a >= m || m_b >= m) 0156 return false; 0157 0158 double *temp = values[m_a]; 0159 values[m_a] = values[m_b]; 0160 values[m_b] = temp; 0161 0162 return true; 0163 } 0164 0165 // #################################### 0166 0167 bool QuickMatrix::partialSAF(CUI m_a, CUI m_b, CUI from, const double scalor) 0168 { 0169 if (m_a >= m || m_b >= m) 0170 return false; 0171 0172 const double *arow = values[m_a]; 0173 double *brow = values[m_b]; 0174 0175 // iterate over n - m_a columns. 0176 for (unsigned int j = from; j < n; j++) 0177 brow[j] += arow[j] * scalor; 0178 0179 return true; 0180 } 0181 0182 // #################################### 0183 0184 QuickVector *QuickMatrix::operator*(const QuickVector *operandvec) const 0185 { 0186 if (operandvec->size() != n) 0187 return nullptr; 0188 0189 QuickVector *ret = new QuickVector(m); 0190 0191 for (unsigned int i = 0; i < m; i++) { 0192 double sum = 0; 0193 for (unsigned int j = 0; j < n; j++) 0194 sum += values[i][j] * (*operandvec)[j]; 0195 (*ret)[i] = sum; 0196 } 0197 0198 return ret; 0199 } 0200 0201 // #################################### 0202 0203 QuickMatrix *QuickMatrix::operator+=(const QuickMatrix *operandmat) 0204 { 0205 if (operandmat->n != n || operandmat->m != m) 0206 return nullptr; 0207 0208 for (unsigned int i = 0; i < m; i++) { 0209 for (unsigned int j = 0; j < n; j++) 0210 values[i][j] += operandmat->values[i][j]; 0211 } 0212 0213 return this; 0214 } 0215 0216 // #################################### 0217 0218 QuickMatrix *QuickMatrix::operator*(const QuickMatrix *operandmat) const 0219 { 0220 if (operandmat->m != n) 0221 return nullptr; 0222 0223 QuickMatrix *ret = new QuickMatrix(m, operandmat->n); 0224 0225 for (unsigned int i = 0; i < m; i++) { 0226 for (unsigned int j = 0; j < operandmat->n; j++) { 0227 double sum = 0; 0228 for (unsigned int k = 0; k < n; k++) 0229 sum += values[i][k] * operandmat->values[k][j]; 0230 ret->values[i][j] = sum; 0231 } 0232 } 0233 0234 return ret; 0235 } 0236 0237 // ################################### 0238 0239 void QuickMatrix::dumpToAux() const 0240 { 0241 for (unsigned int j = 0; j < m; j++) { 0242 for (unsigned int i = 0; i < n; i++) 0243 cout << values[j][i] << ' '; 0244 cout << endl; 0245 } 0246 } 0247 0248 // ################################### 0249 0250 void QuickMatrix::fillWithZero() 0251 { 0252 for (unsigned int j = 0; j < m; j++) { 0253 memset(values[j], 0, n * sizeof(double)); // fastest method. =) 0254 } 0255 } 0256 0257 // ################################### 0258 // sets the diagonal to a constant. 0259 QuickMatrix *QuickMatrix::operator=(const double y) 0260 { 0261 fillWithZero(); 0262 unsigned int size = n; 0263 if (size > m) 0264 size = m; 0265 0266 for (unsigned int i = 0; i < size; i++) 0267 values[i][i] = y; 0268 return this; 0269 }