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