|
GiNaC
1.6.2
|
00001 00005 /* 00006 * GiNaC Copyright (C) 1999-2011 Johannes Gutenberg University Mainz, Germany 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 #ifndef GINAC_MATRIX_H 00024 #define GINAC_MATRIX_H 00025 00026 #include "basic.h" 00027 #include "ex.h" 00028 #include "archive.h" 00029 00030 #include <string> 00031 #include <vector> 00032 00033 namespace GiNaC { 00034 00037 template <typename T, typename It> 00038 class matrix_init { 00039 public: 00040 matrix_init(It i) : iter(i) {} 00041 00042 matrix_init<T, It> operator,(const T & x) 00043 { 00044 *iter = x; 00045 return matrix_init<T, It>(++iter); 00046 } 00047 00048 // The following specializations produce much tighter code than the 00049 // general case above 00050 00051 matrix_init<T, It> operator,(int x) 00052 { 00053 *iter = T(x); 00054 return matrix_init<T, It>(++iter); 00055 } 00056 00057 matrix_init<T, It> operator,(unsigned int x) 00058 { 00059 *iter = T(x); 00060 return matrix_init<T, It>(++iter); 00061 } 00062 00063 matrix_init<T, It> operator,(long x) 00064 { 00065 *iter = T(x); 00066 return matrix_init<T, It>(++iter); 00067 } 00068 00069 matrix_init<T, It> operator,(unsigned long x) 00070 { 00071 *iter = T(x); 00072 return matrix_init<T, It>(++iter); 00073 } 00074 00075 matrix_init<T, It> operator,(double x) 00076 { 00077 *iter = T(x); 00078 return matrix_init<T, It>(++iter); 00079 } 00080 00081 matrix_init<T, It> operator,(const symbol & x) 00082 { 00083 *iter = T(x); 00084 return matrix_init<T, It>(++iter); 00085 } 00086 00087 private: 00088 matrix_init(); 00089 It iter; 00090 }; 00091 00092 00094 class matrix : public basic 00095 { 00096 GINAC_DECLARE_REGISTERED_CLASS(matrix, basic) 00097 00098 // other constructors 00099 public: 00100 matrix(unsigned r, unsigned c); 00101 matrix(unsigned r, unsigned c, const exvector & m2); 00102 matrix(unsigned r, unsigned c, const lst & l); 00103 00104 // First step of initialization of matrix with a comma-separated seqeuence 00105 // of expressions. Subsequent steps are handled by matrix_init<>::operator,(). 00106 matrix_init<ex, exvector::iterator> operator=(const ex & x) 00107 { 00108 m[0] = x; 00109 return matrix_init<ex, exvector::iterator>(++m.begin()); 00110 } 00111 00112 // functions overriding virtual functions from base classes 00113 public: 00114 size_t nops() const; 00115 ex op(size_t i) const; 00116 ex & let_op(size_t i); 00117 ex eval(int level=0) const; 00118 ex evalm() const {return *this;} 00119 ex subs(const exmap & m, unsigned options = 0) const; 00120 ex eval_indexed(const basic & i) const; 00121 ex add_indexed(const ex & self, const ex & other) const; 00122 ex scalar_mul_indexed(const ex & self, const numeric & other) const; 00123 bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const; 00124 ex conjugate() const; 00125 ex real_part() const; 00126 ex imag_part() const; 00127 00129 void archive(archive_node& n) const; 00131 void read_archive(const archive_node& n, lst& syms); 00132 protected: 00133 bool match_same_type(const basic & other) const; 00134 unsigned return_type() const { return return_types::noncommutative; }; 00135 00136 // non-virtual functions in this class 00137 public: 00138 unsigned rows() const 00139 { return row; } 00140 unsigned cols() const 00141 { return col; } 00142 matrix add(const matrix & other) const; 00143 matrix sub(const matrix & other) const; 00144 matrix mul(const matrix & other) const; 00145 matrix mul(const numeric & other) const; 00146 matrix mul_scalar(const ex & other) const; 00147 matrix pow(const ex & expn) const; 00148 const ex & operator() (unsigned ro, unsigned co) const; 00149 ex & operator() (unsigned ro, unsigned co); 00150 matrix & set(unsigned ro, unsigned co, const ex & value) { (*this)(ro, co) = value; return *this; } 00151 matrix transpose() const; 00152 ex determinant(unsigned algo = determinant_algo::automatic) const; 00153 ex trace() const; 00154 ex charpoly(const ex & lambda) const; 00155 matrix inverse() const; 00156 matrix solve(const matrix & vars, const matrix & rhs, 00157 unsigned algo = solve_algo::automatic) const; 00158 unsigned rank() const; 00159 bool is_zero_matrix() const; 00160 protected: 00161 ex determinant_minor() const; 00162 int gauss_elimination(const bool det = false); 00163 int division_free_elimination(const bool det = false); 00164 int fraction_free_elimination(const bool det = false); 00165 int pivot(unsigned ro, unsigned co, bool symbolic = true); 00166 00167 void print_elements(const print_context & c, const char *row_start, const char *row_end, const char *row_sep, const char *col_sep) const; 00168 void do_print(const print_context & c, unsigned level) const; 00169 void do_print_latex(const print_latex & c, unsigned level) const; 00170 void do_print_python_repr(const print_python_repr & c, unsigned level) const; 00171 00172 // member variables 00173 protected: 00174 unsigned row; 00175 unsigned col; 00176 exvector m; 00177 }; 00178 GINAC_DECLARE_UNARCHIVER(matrix); 00179 00180 00181 // wrapper functions around member functions 00182 00183 inline size_t nops(const matrix & m) 00184 { return m.nops(); } 00185 00186 inline ex expand(const matrix & m, unsigned options = 0) 00187 { return m.expand(options); } 00188 00189 inline ex eval(const matrix & m, int level = 0) 00190 { return m.eval(level); } 00191 00192 inline ex evalf(const matrix & m, int level = 0) 00193 { return m.evalf(level); } 00194 00195 inline unsigned rows(const matrix & m) 00196 { return m.rows(); } 00197 00198 inline unsigned cols(const matrix & m) 00199 { return m.cols(); } 00200 00201 inline matrix transpose(const matrix & m) 00202 { return m.transpose(); } 00203 00204 inline ex determinant(const matrix & m, unsigned options = determinant_algo::automatic) 00205 { return m.determinant(options); } 00206 00207 inline ex trace(const matrix & m) 00208 { return m.trace(); } 00209 00210 inline ex charpoly(const matrix & m, const ex & lambda) 00211 { return m.charpoly(lambda); } 00212 00213 inline matrix inverse(const matrix & m) 00214 { return m.inverse(); } 00215 00216 inline unsigned rank(const matrix & m) 00217 { return m.rank(); } 00218 00219 // utility functions 00220 00222 extern ex lst_to_matrix(const lst & l); 00223 00225 extern ex diag_matrix(const lst & l); 00226 00228 extern ex unit_matrix(unsigned r, unsigned c); 00229 00231 inline ex unit_matrix(unsigned x) 00232 { return unit_matrix(x, x); } 00233 00237 extern ex symbolic_matrix(unsigned r, unsigned c, const std::string & base_name, const std::string & tex_base_name); 00238 00241 extern ex reduced_matrix(const matrix& m, unsigned r, unsigned c); 00242 00244 extern ex sub_matrix(const matrix&m, unsigned r, unsigned nr, unsigned c, unsigned nc); 00245 00248 inline ex symbolic_matrix(unsigned r, unsigned c, const std::string & base_name) 00249 { return symbolic_matrix(r, c, base_name, base_name); } 00250 00251 } // namespace GiNaC 00252 00253 #endif // ndef GINAC_MATRIX_H