00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "matrix.h"
00024
00025 #include <iostream>
00026
00027 using namespace sheep;
00028
00029 using std::endl;
00030
00031 Matrix Matrix::operator*(const Matrix &m) const {
00032 assert(m_c == m.m_r);
00033
00034
00035
00036 Matrix res(m_r, m.m_c);
00037
00038 Real *v = res.m_v;
00039
00040 for(int i = 0; i < m_r; i++)
00041 for(int j = 0; j < m.m_c; j++) {
00042 Real sum = 0;
00043
00044 for(int k = 0; k < m_c; k++)
00045 sum += operator()(i, k) * m(k, j);
00046
00047 *(v++) = sum;
00048 }
00049
00050 return res;
00051 }
00052
00053 Vector Matrix::operator*(const Vector &v) const {
00054 assert(m_c == v.GetDimension());
00055
00056 Vector res(m_r);
00057
00058 for(int i = 0; i < m_r; i++) {
00059 Real sum = 0;
00060
00061 for(int j = 0; j < m_c; j++)
00062 sum += operator()(i, j) * v[j];
00063
00064 res[i] = sum;
00065 }
00066
00067 return res;
00068 }
00069
00070 Matrix Matrix::Transpose() const {
00071 Matrix res(m_c, m_r);
00072
00073 Real *u = m_v;
00074
00075 for(int i = 0; i < m_r; i++) {
00076 Real *v = res.m_v + i;
00077
00078 for(int j = 0; j < m_c; j++, v += m_r)
00079 *v = *(u++);
00080 }
00081
00082 return res;
00083 }
00084
00085 Matrix Matrix::Inverse() const {
00086 assert(m_r == m_c);
00087
00088 Matrix res = *this;
00089
00090 int i,j,k;
00091
00092 int *pvt_i, *pvt_j;
00093 double pvt_val;
00094 double hold;
00095
00096 pvt_i = new int[m_r];
00097 pvt_j = new int[m_r];
00098
00099 for (k = 0; k < m_r; k++)
00100 {
00101
00102 pvt_val = res(k,k);
00103 pvt_i[k] = k;
00104 pvt_j[k] = k;
00105 for(i = k; i < m_r; i++)
00106 for(j = k; j < m_r; j++)
00107 if(fabs(res(i,j)) > fabs(pvt_val)) {
00108 pvt_i[k] = i;
00109 pvt_j[k] = j;
00110 pvt_val = res(i,j);
00111 }
00112
00113 if(pvt_val==0) {
00114
00115 delete [] pvt_i;
00116 delete [] pvt_j;
00117 assert(!"Matrix is singular.");
00118 }
00119
00120
00121 i = pvt_i[k];
00122 if (i != k)
00123 for (j = 0; j < m_r; j++)
00124 {
00125 hold = -res(k,j);
00126 res(k,j) = res(i,j);
00127 res(i,j) = hold;
00128 }
00129
00130
00131 j = pvt_j[k];
00132 if (j != k)
00133 for (i = 0; i < m_r; i++)
00134 {
00135 hold = -res(i,k);
00136 res(i,k) = res(i,j);
00137 res(i,j) = hold;
00138 }
00139
00140
00141 for (i = 0; i < m_r; i++)
00142 if (i != k)
00143 res(i,k) /= ( -pvt_val) ;
00144
00145
00146 for (i = 0; i < m_r; i++)
00147 {
00148 hold = res(i,k);
00149 for (j = 0; j < m_r; j++)
00150 if ( i != k && j != k )
00151 res(i,j) += hold * res(k,j);
00152 }
00153
00154
00155 for (j = 0; j < m_r; j++)
00156 if (j != k)
00157 res(k,j) /= pvt_val;
00158
00159
00160 res(k,k) = 1.0/pvt_val;
00161 }
00162
00163
00164
00165 for (k = m_r-2; k >= 0; k--)
00166 {
00167 i = pvt_j[k];
00168 if (i != k)
00169 for(j = 0; j < m_r; j++)
00170 {
00171 hold = res(k,j);
00172 res(k,j) = -res(i,j);
00173 res(i,j) = hold;
00174 }
00175
00176 j = pvt_i[k];
00177 if (j != k)
00178 for (i = 0; i < m_r; i++)
00179 {
00180 hold = res(i,k);
00181 res(i,k) = -res(i,j);
00182 res(i,j) = hold;
00183 }
00184 }
00185
00186 delete [] pvt_i;
00187 delete [] pvt_j;
00188
00189 return res;
00190 }
00191
00192 Real Matrix::Determinant() const {
00193 assert(m_r == m_c);
00194
00195
00196
00197 return 0;
00198 }
00199
00200 htmlstream &operator<<(htmlstream &s, const Matrix &m) {
00201 s << "<table border=\"1\">" << endl;
00202
00203 for(int i = 0; i < m.GetRows(); ++i) {
00204 s << "<tr>" << endl;
00205
00206 for(int j = 0; j < m.GetColumns(); ++j) {
00207 s << "<td>" << m(i, j) << "</td>" << endl;
00208 }
00209
00210 s << "</tr>" << endl;
00211 }
00212
00213 s << "</table>" << endl;
00214
00215 return s;
00216 }