Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

matrix.cc

Go to the documentation of this file.
00001 // matrix.cc
00002 
00003 // Brief introduction to the SuperMix numeric matrix and vector
00004 // classes.
00005 
00006 #include "supermix.h"
00007 
00008 // SuperMix analyzes a circuit by calculating its complex-valued
00009 // scattering and noise correlation matrices from those of its
00010 // individual components. Consequently SuperMix requires a fairly
00011 // sophisticated linear algebra capability. The SuperMix matrix
00012 // and vector classes provide a linear algebra package for
00013 // real-valued and complex-valued vector and matrix data. The
00014 // classes are defined and described in detail in the header files
00015 // "vector.h" and "table.h" found in the/ SuperMix include/
00016 // directory. A complete list of many more aritmetic operations
00017 // is available in the header file "matmath.h".
00018 
00019 // Including "matmath.h" alone makes just the complex number and
00020 // linear algebra capabilities of the SuperMix library available to
00021 // your program. This is convenient for programs which do not
00022 // require the full circuit simulation package.
00023 
00024 int main()
00025 {
00026   // -----------------------------------------------------------------
00027   // BASIC MATRIX CREATION AND ELEMENT ASSIGNMENT
00028 
00029   // We can declare a complex-valued matrix as follows (note that the
00030   // type Matrix starts with an uppercase M):
00031 
00032   Matrix A;      // a 0x0, complex-valued matrix (no available elements)
00033 
00034   // This default matrix is of size zero. To get a matrix with a
00035   // definite size, we can give dimensions as parameters:
00036 
00037   Matrix B(3);   // a square matrix (3x3)
00038   Matrix C(2,4); // a 2x4 matrix (2 rows, 4 columns)
00039 
00040   // All elements in a freshly-created matrix are initialized to 0,
00041   // unless the matrix is created as a copy of some other. Let's look at
00042   // our finite-sized matrices:
00043 
00044   cout << "B:" << endl << B << endl << endl;
00045   cout << "C:" << endl << C << endl << endl;
00046 
00047   // Assigning values to elements:
00048   // The element indexing for matrices A, B, and C above starts
00049   // with element 1 (not 0, as for C-style arrays). This is the
00050   // default indexing mode, but is not the only indexing mode. Look
00051   // in vector.h and table.h for a complete description of the
00052   // available indexing modes.
00053 
00054   B = 3 + 4*I;         // all elements of B set to 3+i4
00055   C[1][3] = 2 - 5*I;   // only the (1,3) element of C affected.
00056   C[2][2] = B[2][2];
00057   cout << "B:" << endl << B << endl << endl;
00058   cout << "C:" << endl << C << endl << endl;
00059 
00060 
00061   // -----------------------------------------------------------------
00062   // BASIC MATRIX ARITHMETIC
00063 
00064   // All the standard matrix operations are available: multiplication by
00065   // a scalar, matrix addition and subtraction, matrix multiplication.
00066   // When the result of an operation is assigned to a matrix, its size
00067   // and memory allocation are adjusted as required to hold the result.
00068 
00069   Matrix B2(B);        // B2 is a copy of B
00070   A = B + B2;          // A is dynamically resized to hold the result
00071   cout << "B, B2:"      << endl << B << endl << endl;
00072   cout << "A = B + B2:" << endl << A << endl << endl;
00073 
00074   // Two matrices can be operated upon by a binary operation even though
00075   // they don't have dimensions compatible with the operation (e.g.,
00076   // their dimensions aren't the same in the case of matrix addition).
00077   // An operation involving any two matrices is interpreted as follows:
00078   //
00079   //    (1) Copy the two matrices into temporary, working matrices. Pad
00080   //        each temoprary matrix with the minimum number of rows and/or
00081   //        columns filled with zeroes which make the dimensions of
00082   //        the two temporary matrices compatible for the operation to
00083   //        be performed.
00084   //
00085   //    (2) Perform the operation on these two new, expanded matrices.
00086   //
00087   //    (3) The result of the operation is the result of step (2).
00088   //
00089   // This process is applied for the binary matrix operations of
00090   // addition, subtraction, and multiplication. The actual algoithms
00091   // are actually quite efficient and don't require unnecesary copying.
00092 
00093   A = B + C;  // Note how the result follows from the above description
00094   cout << "A = B + C:" << endl << A << endl << endl;
00095 
00096   A = B * C;  // Ditto for matrix multiplication
00097   cout << "A = B * C:" << endl << A << endl << endl;
00098   A = C * B;
00099   cout << "A = C * B:" << endl << A << endl << endl;
00100 
00101 
00102   // -----------------------------------------------------------------
00103   // MATRIX SOLVER AND MATRIX INVERSION
00104 
00105   // We can solve nonsingular matrix equations:
00106 
00107   B += 2*identity_matrix(B);  // now B is nonsingular
00108   C.resize(3,2).diagonal(1);  // C is now 3x2, diagonal elements == 1
00109   cout << "B:" << endl << B << endl << endl;
00110   cout << "C:" << endl << C << endl << endl;
00111 
00112   A = solve(B,C);    // solve "B*A = C" for A
00113   cout << "A = solve(B,C):" << endl << A << endl << endl;
00114 
00115   // Let's verify the solution:
00116   cout << fixed << setprecision(15);  // so we don't see tiny numbers
00117   cout << "C - B*A (should be all 0's):" << endl
00118        << C - B*A << endl << endl;
00119   cout << general << setprecision(0); // back to default format
00120   // And the result is zero to within the precision of a double.
00121 
00122   // If there is not a unique solution for solve(), then it returns a
00123   // matrix with no elements; if this had been the case in the above
00124   // example, then the member function A.is_empty() would return a
00125   // nonzero value, indicating that it contained no valid elements. 
00126 
00127   // Matrix inversion is also available:
00128 
00129   A = inverse(B);
00130   cout << general << setprecision(0);
00131   cout << "A = inverse(B):" << endl << A << endl << endl;
00132 
00133   // Let's again verify the solution:
00134   cout << fixed << setprecision(8);  // so we don't see tiny numbers
00135   cout << "A*B (should be the identity matrix):" << endl
00136        << A*B << endl << endl;
00137   cout << general << setprecision(0); // back to default format
00138 
00139 
00140   // ----------------------------------------------------------------
00141   // MORE ABOUT MATRICES AND VECTORS
00142 
00143   // Read the comments at the beginning of the header files:
00144   //    matmath.h
00145   //    vector.h
00146   //    table.h
00147   //
00148   // Play around with the various features of the classes and
00149   // operations by adding code to a copy of this program and seeing
00150   // what happens.
00151 
00152 }

Please direct comments and corrections to supermix@submm.caltech.edu
Go to the supermix home page
Generated by doxygen1.2.7