using namespace std; #include #include "Mmn.h" /**************************************************************** * die Klasse "Mmn" * ****************************************************************/ //------ Kontruktoren ------------------------------------------- template Mmn::Mmn(K* a, unsigned m, unsigned n) : m(m), n(n), Rg(0), Det_F(false) { _a=new (K*)[m]; for(unsigned i=0; i Mmn::Mmn(unsigned m) : m(m), n(m), Rg(0), Det_F(false) { _a=new (K*)[m]; for(unsigned i=0; i Mmn::Mmn(unsigned m, unsigned n) : m(m), n(n), Rg(0), Det_F(false) { _a=new (K*)[m]; for(unsigned i=0; i Mmn::Mmn(const Mmn& A) : m(A.m), n(A.n), Rg(A.Rg), Det(A.Det), Det_F(A.Det_F) { _a=new (K*)[m]; for(unsigned i=0; i Mmn::~Mmn() { freeall(); } //--------------------------------------------------------------- //------ Operatoren --------------------------------------------- template const Mmn& Mmn::operator=(const Mmn& A) { if(this==&A) return *this; if(!_a || m != A.m || n != A.n) { freeall(); _a=new (K*)[A.m]; for(unsigned i=0; i Mmn Mmn::operator*(const K& a) const { Mmn A(m,n); for(unsigned i=0; i Mmn Mmn::operator%(const Mmn& A) const { if(n != A.m) return null(); Mmn B(m,A.n); for(unsigned i=0; i Mmn Mmn::operator+(const Mmn& A) const { if(n != A.n || m != A.m) return null(); Mmn B(m,n); for(unsigned i=0; i Mmn Mmn::operator-(const Mmn& A) const { Mmn B(m,n); for(unsigned i=0; i void Mmn::freeall(void) { if(_a) { for(unsigned i=0; i K Mmn::sarrus(void) const { return _a[0][0]*_a[1][1]*_a[2][2]\ +_a[0][1]*_a[1][2]*_a[2][0]\ +_a[0][2]*_a[1][0]*_a[2][1]\ -_a[0][1]*_a[1][0]*_a[2][2]\ -_a[0][0]*_a[1][2]*_a[2][1]\ -_a[0][2]*_a[1][1]*_a[2][0]; } template K Mmn::laplace(void) const { K detA=0; Mmn A; // analytisches optimieren des Laplace-Algorithmus, durch finden der // Zeile/Spalte mit den meisten Nullen. //------------------------------------------------------------------- unsigned nulls_in_line[m]; for(unsigned i=0; imax_nulls) max_nulls=nulls_in_line[i]; if(nulls_in_col[i]>max_nulls) max_nulls=nulls_in_col[i]; // ist eine komplette Zeile oder Spalte 0, so koennen wir // direkt abbrechen und 0 zurueckgeben. if(max_nulls==m) return (K)0; max_nulls_line=(max_nulls==nulls_in_line[i])?i:max_nulls_line; max_nulls_col=(max_nulls==nulls_in_col[j])?j:max_nulls_col; } if(nulls_in_line[max_nulls_line] > nulls_in_col[max_nulls_col]) { A=T(); max_nulls_col=max_nulls_line; } else A=*this; //------------------------------------------------------------------- for(unsigned i=0; i K Mmn::det(void) const { K Det=(K)0; if(m!=n) { return Det; } else { switch(m) { case 1: Det=_a[0][0]; break; case 2: Det=_a[0][0]*_a[1][1]-_a[0][1]*_a[1][0]; break; case 3: Det=sarrus(); break; default: Det=laplace(); } return Det; } } template K Mmn::det(void) { if(m!=n) { Det=(K)0; Det_F=false; return Det; } else { switch(m) { case 1: Det=_a[0][0]; break; case 2: Det=_a[0][0]*_a[1][1]-_a[0][1]*_a[1][0]; break; case 3: Det=sarrus(); break; default: Det=laplace(); } Det_F=true; return Det; } } //--------------------------------------------------------------- //------ Matrizenmanipulationen --------------------------------- template Mmn Mmn::Aij(unsigned i, unsigned j) const { Mmn A(m-1,n-1); unsigned _i, _l, _j, _k; for(_i=0, _l=0; _i=m) break; for(_j=0, _k=0; _j=n) break; A._a[_l][_k]=_a[_i][_j]; } } return A; } template Mmn Mmn::Ai(unsigned i) const { Mmn A(m-1,n); unsigned _i, l; for(_i=0, l=0; i=m) break; for(unsigned j=0; j Mmn Mmn::Aj(unsigned j) const { Mmn A(m,n-1); unsigned _j, k; for(unsigned i=0; i=n) break; A._a[i][k]=_a[i][_j]; } return A; } template Mmn Mmn::T(void) const { Mmn A(n,m); for(unsigned i=0; i Mmn Mmn::Ad_det(void) const { Mmn A(n,m); for(unsigned i=0; i Mmn Mmn::Ad_inv(void) const { // Das geht nur wenn die Determinante nicht 0 ist, da sonst die ganze // Ergebnismatrix automatisch 0 wird, was aber nicht unbedingt sein muß. // Dies gilt insbesondere Wenn die Matrize eine Null-Zeile oder Spalte // enthaelt. K d=Det_F?Det:det(); if(d != (K)0) return d*gauss(INVERSE); else return Ad_det(); } template Mmn Mmn::inv_Ad(void) const { K Adet; if((Adet=Det_F?Det:det())==(K)0) { return null(); } else { return Ad_det()*((K)1/Adet); } } template Mmn Mmn::gauss(gauss_typ T) const { Mmn A=*this; Mmn B(m); for(unsigned i=0; i Mmn Mmn::solve(void) const { Mmn A=gauss(TREPPENNORMALE); Mmn B=Aj(n-1).gauss(TREPPENNORMALE); // Gibt es eine Loesung??? if(B.Rg != A.Rg) return null(); else { K l[B.n][B.n-B.Rg+1]; K a[B.n][A.n]; for(unsigned i=0, j=0; j=A.m || A._a[i][j] != (K)1) { for(unsigned k=0; k((K*)l, B.n, B.n-B.Rg+1); } } template Mmn Mmn::special_solve(void) const { Mmn S=solve(); Mmn A(S.m,1); for(unsigned i=0; i