File indexing completed on 2024-04-28 05:43:16
0001 /************************************************************************** 0002 * Copyright (C) 2003-2004 by David Saxton * 0003 * david@bluehaze.org * 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 0011 #ifndef MATRIX_H 0012 #define MATRIX_H 0013 0014 #include <math/qmatrix.h> 0015 0016 /** 0017 This class performs matrix storage, lu decomposition, forward and backward 0018 substitution, and a few other useful operations. Steps in using class: 0019 (1) Create an instance of this class with the correct size 0020 (2) Define the matrix pattern as neccessary: 0021 (1) Call zero (unnecessary after initial ceration) to reset the pattern 0022 & matrix 0023 (2) Call setUse to set the use of each element in the matrix 0024 (3) Call createMap to generate the row-wise permutation mapping for use 0025 in partial pivoting 0026 (3) Add the values to the matrix 0027 (4) Call performLU, and get the results with fbSub 0028 (5) Repeat 2, 3, 4 or 5 as necessary. 0029 @todo We need to allow createMap to work while the matrix has already been initalised 0030 @short Matrix manipulation class tailored for circuit equations 0031 @author David Saxton 0032 */ 0033 class Matrix 0034 { 0035 public: 0036 /** 0037 * Creates a size x size square matrix m, with all values zero, 0038 * and a right side vector x of size m+n 0039 */ 0040 Matrix(CUI n, CUI m); 0041 ~Matrix(); 0042 0043 /** 0044 * Returns true if the matrix is changed since last calling performLU() 0045 * - i.e. if we do need to call performLU again. 0046 */ 0047 inline bool isChanged() const 0048 { 0049 return max_k < m_mat->size_m(); 0050 } 0051 /** 0052 * Performs LU decomposition. Going along the rows, 0053 * the value of the decomposed LU matrix depends only on 0054 * the previous values. 0055 */ 0056 void performLU(); 0057 /** 0058 * Applies the right side vector (x) to the decomposed matrix, 0059 * with the solution returned in x. 0060 */ 0061 void fbSub(QuickVector *x); 0062 /** 0063 * Prints the LU-decomposed matrix to stdout 0064 */ 0065 void displayLU(); 0066 /** 0067 * Sets the element matrix at row i, col j to value x 0068 */ 0069 double &g(CUI i, CUI j) 0070 { 0071 const unsigned int mapped_i = m_inMap[i]; 0072 if (mapped_i < max_k) 0073 max_k = mapped_i; 0074 if (j < max_k) 0075 max_k = j; 0076 0077 // I think I need the next line... 0078 if (max_k > 0) 0079 max_k--; 0080 0081 return (*m_mat)[mapped_i][j]; 0082 } 0083 0084 double g(CUI i, CUI j) const 0085 { 0086 return (*m_mat)[m_inMap[i]][j]; 0087 } 0088 0089 double &b(CUI i, CUI j) 0090 { 0091 return g(i, j + m_n); 0092 } 0093 double &c(CUI i, CUI j) 0094 { 0095 return g(i + m_n, j); 0096 } 0097 double &d(CUI i, CUI j) 0098 { 0099 return g(i + m_n, j + m_n); 0100 } 0101 0102 double b(CUI i, CUI j) const 0103 { 0104 return g(i, j + m_n); 0105 } 0106 double c(CUI i, CUI j) const 0107 { 0108 return g(i + m_n, j); 0109 } 0110 double d(CUI i, CUI j) const 0111 { 0112 return g(i + m_n, j + m_n); 0113 } 0114 /** 0115 * Returns the value of matrix at row i, col j. 0116 */ 0117 double m(CUI i, CUI j) const 0118 { 0119 return (*m_mat)[m_inMap[i]][j]; 0120 } 0121 0122 private: 0123 /** 0124 * Swaps around the rows in the (a) the matrix; and (b) the mappings 0125 */ 0126 void swapRows(CUI a, CUI b); 0127 0128 unsigned int m_n; // number of cnodes. 0129 unsigned int max_k; // optimization variable, allows partial L_U re-do. 0130 0131 int *m_inMap; // Rowwise permutation mapping from external reference to internal storage 0132 0133 QuickMatrix *m_mat; 0134 QuickMatrix *m_lu; 0135 double *m_y; // Avoids recreating it lots of times 0136 }; 0137 0138 #endif