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
1.2.7