yang.cc
Go to the documentation of this file.00001
00002
00003
00004
00005 #include <iostream>
00006 #include <cmath>
00007 #include <cstdlib>
00008 #include <ctime>
00009 #include "yang.h"
00010
00011 void error(const char* v) {
00012 std::cout << v << "\n";
00013 exit(1);
00014 }
00015
00016
00017
00018 Vtr::Vtr(int n, double* abd) {
00019 ets = new double [lenth =n];
00020 for (int i = 0; i < lenth; i++) ets[i]= *(abd +i);
00021 }
00022
00023 Vtr::Vtr(int n, double a) {
00024 ets = new double [lenth =n];
00025 for (int i = 0; i < lenth; i++) ets[i] = a;
00026 }
00027
00028 Vtr::Vtr(const Vtr & v) {
00029 ets = new double [lenth = v.lenth];
00030 for (int i = 0; i < lenth; i++) ets[i] = v[i];
00031 }
00032
00033
00034
00035
00036
00037 Vtr& Vtr::operator=(const Vtr& v) {
00038 if (this != &v) {
00039 if (lenth != v.lenth ) error("Vtr::op=: Error: Bad vector sizes");
00040 for (int i = 0; i < lenth; i++) ets[i] = v[i];
00041 }
00042 return *this;
00043 }
00044
00045 Vtr & Vtr::operator+=(const Vtr& v) {
00046 if (lenth != v.lenth ) error("bad vector sizes");
00047 for (int i = 0; i < lenth; i++) ets[i] += v[i];
00048 return *this;
00049 }
00050
00051 Vtr & Vtr::operator-=(const Vtr& v) {
00052 if (lenth != v.lenth ) error("bad vtor sizes");
00053 for (int i = 0; i < lenth; i++) ets[i] -= v[i];
00054 return *this;
00055 }
00056
00057 Vtr operator+(const Vtr & v) {
00058 return v;
00059 }
00060
00061 Vtr operator-(const Vtr& v) {
00062 return Vtr(v.lenth) - v;
00063 }
00064
00065 Vtr operator+(const Vtr& v1, const Vtr & v2) {
00066 if (v1.lenth != v2.lenth ) error("Vtr::op+: Error Bad vtor sizes");
00067 Vtr sum = v1;
00068 sum += v2;
00069 return sum;
00070 }
00071
00072 Vtr operator-(const Vtr& v1, const Vtr& v2) {
00073
00074 Vtr sum = v1;
00075 sum -= v2;
00076 return sum;
00077 }
00078
00079 std::ostream& operator<<(std::ostream& s, const Vtr& v ) {
00080 for (int i =0; i < v.lenth; i++ ) {
00081 s << v[i] << " ";
00082 if (i%10 == 9) s << "\n";
00083 }
00084 return s;
00085 }
00086
00087 double Vtr::twonorm() const{
00088 double norm = std::abs(ets[0]);
00089 for (int i = 1; i < lenth; i++) {
00090 double vi = std::abs(ets[i]);
00091 if (norm < 100) norm = std::sqrt(norm*norm + vi*vi);
00092 else {
00093 double tm = vi/norm;
00094 norm *= std::sqrt(1.0 + tm*tm);
00095 }
00096 }
00097 return norm;
00098 }
00099
00100 double Vtr::maxnorm() const {
00101 double norm = std::abs(ets[0]);
00102 for (int i = 1; i < lenth; i++)
00103 if (norm < std::abs(ets[i])) norm = std::abs(ets[i]);
00104 return norm;
00105 }
00106
00107 Vtr operator*(const double scalar, const Vtr & v) {
00108 Vtr tm(v.lenth);
00109 for (int i = 0; i < v.lenth; i++) tm[i] = scalar*v[i];
00110 return tm;
00111 }
00112
00113 Vtr operator*(const Vtr & v1, const Vtr & v2) {
00114 int sz = v1.lenth;
00115 if (sz != v2.lenth ) error("bad vtor sizes");
00116 Vtr tm(sz);
00117 for (int i = 0; i < sz; i++)
00118 tm[i] = v1[i]*v2[i];
00119 return tm;
00120 }
00121
00122 Vtr operator/(const Vtr & v, const double scalar) {
00123 if (scalar == 0) error("division by zero in vector-scalar division");
00124 return (1.0/scalar)*v;
00125 }
00126
00127 double dot(const Vtr & v1, const Vtr & v2) {
00128 int sz = v1.lenth;
00129 if (sz != v2.lenth ) error("bad vtor sizes");
00130 double tm = v1[0]*v2[0];
00131 for (int i = 1; i < sz; i++) tm += v1[i]*v2[i];
00132 return tm;
00133 }
00134
00135
00136
00137 Mtx::Mtx(int n, int m, double** dbp) {
00138 nrows = n;
00139 ncols = m;
00140 ets = new double* [nrows];
00141 for (int i = 0; i < nrows; i++) {
00142 ets[i] = new double [ncols];
00143 for (int j = 0; j < ncols; j++) ets[i][j] = dbp[i][j];
00144 }
00145 }
00146
00147 Mtx::Mtx(int n, int m, double a) {
00148 ets = new double* [nrows = n];
00149 for (int i = 0; i< nrows; i++) {
00150 ets[i] = new double [ncols = m];
00151 for (int j = 0; j < ncols; j++) ets[i][j] = a;
00152 }
00153 }
00154
00155 Mtx::Mtx(const Mtx & mat) {
00156 ets = new double* [nrows = mat.nrows];
00157 for (int i = 0; i< nrows; i++) {
00158 ets[i] = new double [ncols = mat.ncols];
00159 for (int j = 0; j < ncols; j++) ets[i][j] = mat[i][j];
00160 }
00161 }
00162
00163 Mtx::~Mtx(){
00164 for (int i = 0; i< nrows; i++) delete[] ets[i];
00165 delete[] ets;
00166 }
00167
00168 Mtx& Mtx::operator=(const Mtx& mat) {
00169 if (this != &mat) {
00170 if (nrows != mat.nrows || ncols != mat.ncols) error("bad matrix sizes");
00171 for (int i = 0; i < nrows; i++)
00172 for (int j = 0; j < ncols; j++) ets[i][j] = mat[i][j];
00173 }
00174 return *this;
00175 }
00176
00177 Mtx& Mtx::operator+=(const Mtx& mat) {
00178 if (nrows != mat.nrows || ncols != mat.ncols) error("bad matrix sizes");
00179 for (int i = 0; i < nrows; i++)
00180 for (int j = 0; j < ncols; j++) ets[i][j] += mat[i][j];
00181 return *this;
00182 }
00183
00184 Mtx& Mtx::operator-=(const Mtx& mat) {
00185 if (nrows != mat.nrows || ncols != mat.ncols) error("bad matrix sizes");
00186 for (int i = 0; i < nrows; i++)
00187 for (int j = 0; j < ncols; j++) ets[i][j] -= mat[i][j];
00188 return *this;
00189 }
00190
00191 Mtx& Mtx::operator+() {
00192 return *this;
00193 }
00194
00195 Mtx operator-(const Mtx & mat) {
00196 return Mtx(mat.nrows,mat.ncols) - mat;
00197 }
00198
00199 Mtx Mtx::operator+(const Mtx & mat) {
00200 Mtx sum = *this;
00201 sum += mat;
00202 return sum;
00203 }
00204
00205 Vtr Mtx::operator*(const Vtr& v) const {
00206 if (ncols != v.size())
00207 error("Mtx::op*(Vtr): Error: Mat. and vec. sizes do not match.");
00208 Vtr tm(nrows);
00209 for (int i = 0; i < nrows; i++)
00210 for (int j = 0; j < ncols; j++) tm[i] += ets[i][j]*v[j];
00211 return tm;
00212 }
00213
00214 Vtr operator*(const Vtr& v, const Mtx& mat)
00215 {
00216 if (v.lenth != mat.nrows)
00217 error("op*(Vtr, Mtx): Error: Mat. and vec. size do no match.");
00218 Vtr res(mat.ncols, 0.0);
00219 for (int i=0; i<mat.ncols; i++)
00220 for (int j=0; j<v.lenth; j++)
00221 res[i] = v.ets[j] * mat.ets[j][i];
00222 return res;
00223 }
00224
00225
00226 Mtx operator-(const Mtx& m1, const Mtx& m2) {
00227 if(m1.nrows !=m2.nrows || m1.ncols !=m2.ncols)
00228 error("bad matrix sizes");
00229 Mtx sum = m1;
00230 sum -= m2;
00231 return sum;
00232 }
00233
00234
00235 void Mtx::getcol(int n, Vtr& vec) const
00236 {
00237 if (vec.size() != nrows)
00238 error("Mtx::getcol(): Bad vector size.");
00239 for (int i = 0; i < nrows; i++)
00240 vec[i] = ets[i][n];
00241 }
00242
00243 void Mtx::setcol(int n, const Vtr& vec)
00244 {
00245 if (vec.size() != nrows)
00246 error("Mtx::getcol(): Bad vector size.");
00247 for (int i = 0; i < nrows; i++)
00248 ets[i][n] = vec[i];
00249 }
00250
00251 void Mtx::clear()
00252 {
00253 for (int i = 0; i < nrows; i++)
00254 for (int j = 0; j < ncols; j++)
00255 ets[i][j] = 0;
00256 }
00257
00258 int Mtx::transpose(Mat_DP& dest) const
00259 {
00260 if ((nrows != dest.cols()) || (ncols != dest.rows())) {
00261 std::cerr << "Mtx::transpose(): Error: Matrix dim."
00262 << std::endl;
00263 return -1;
00264 }
00265
00266 for (int i=0; i<nrows; i++)
00267 for (int j=0; j<ncols; j++)
00268 dest(j, i) = ets[i][j];
00269 return 0;
00270 }
00271
00272 std::ostream& operator<<(std::ostream& s, const Mtx& mat)
00273 {
00274 for (int i = 0; i < mat.rows(); i++) {
00275 s << "| ";
00276 for(int j = 0; j < mat.cols(); j++) {
00277 s.setf(std::ios_base::fixed, std::ios_base::floatfield);
00278 s.precision(4);
00279 s.width(8);
00280 s << mat.ets[i][j];
00281 }
00282 s << " |" << std::endl;
00283 }
00284 return s;
00285 }
00286
00287 Mtx Mtx::operator*(const Mtx& mat) const
00288 {
00289 Mtx tmp(nrows, mat.ncols);
00290
00291 if (ncols != mat.nrows)
00292 error("Mtx::op*=: Bad matrix sizes.");
00293
00294 for (int i = 0; i < nrows; i++)
00295 for (int j = 0; j < mat.ncols; j++)
00296 for (int k = 0; k < ncols; k++)
00297 tmp(i,j) += ets[i][k] * mat.ets[k][j];
00298
00299 return tmp;
00300 }
00301
00302 int Mtx::QRdecomp(Mtx& Q, Mtx& R)
00303 {
00304 if ((Q.nrows != nrows) || (Q.ncols != ncols) ||
00305 (R.nrows != ncols) || (R.ncols != ncols)) {
00306 std::cerr << "Mtx::QRdecomp(): Error: Bad matrix size.";
00307 return -1;
00308 }
00309
00310 double** tmp;
00311 double norm, dot;
00312
00313
00314 int tmprows = ncols;
00315 int tmpcols = nrows;
00316 tmp = new double* [tmprows];
00317 for (int i=0; i<tmprows; i++) {
00318 tmp[i] = new double [tmpcols];
00319 for (int j=0; j<tmpcols; j++)
00320 tmp[i][j] = ets[j][i];
00321 }
00322 Mat_DP QT(tmprows,tmpcols);
00323
00324 R.clear();
00325
00326 for (int i=0; i<tmprows; i++) {
00327 norm = 0;
00328 for (int k=0; k<tmpcols; k++)
00329 norm += tmp[i][k]*tmp[i][k];
00330 norm = std::sqrt(norm);
00331 R.ets[i][i] = norm;
00332 for (int k=0; k<tmpcols; k++)
00333 QT.ets[i][k] = tmp[i][k] / norm;
00334
00335 for (int j=i+1; j<tmprows; j++) {
00336 dot = 0;
00337 for (int k=0; k<tmpcols; k++)
00338 dot += QT.ets[i][k]*tmp[j][k];
00339 R.ets[i][j] = dot;
00340 for (int k=0; k<tmpcols; k++)
00341 tmp[j][k] = tmp[j][k] - dot*QT.ets[i][k];
00342 }
00343 }
00344
00345 QT.transpose(Q);
00346
00347 for (int i=0; i<tmprows; i++)
00348 delete[] tmp[i];
00349 return 0;
00350 }
00351
00352 int Mtx::QRdecomp_slow(Mtx& Q, Mtx& R)
00353 {
00354 if ((Q.nrows != nrows) || (Q.ncols != ncols) ||
00355 (R.nrows != ncols) || (R.ncols != ncols)) {
00356 std::cerr << "Mtx::QRdecomp(): Error: Bad matrix size.";
00357 return -1;
00358 }
00359
00360 double** tmp;
00361 double norm, dot;
00362
00363 tmp = new double* [nrows];
00364 for (int i=0; i<nrows; i++) {
00365 tmp[i] = new double [ncols];
00366 for (int j=0; j<ncols; j++)
00367 tmp[i][j] = ets[i][j];
00368 }
00369
00370 R.clear();
00371
00372 for (int i=0; i<ncols; i++) {
00373 norm = 0;
00374 for (int k=0; k<nrows; k++)
00375 norm += tmp[k][i]*tmp[k][i];
00376 norm = std::sqrt(norm);
00377 R.ets[i][i] = norm;
00378 for (int k=0; k<nrows; k++)
00379 Q.ets[k][i] = tmp[k][i] / norm;
00380
00381 for (int j=i+1; j<ncols; j++) {
00382 dot = 0;
00383 for (int k=0; k<nrows; k++)
00384 dot += Q.ets[k][i]*tmp[k][j];
00385 R.ets[i][j] = dot;
00386 for (int k=0; k<nrows; k++)
00387 tmp[k][j] = tmp[k][j] - dot*Q.ets[k][i];
00388 }
00389 }
00390
00391 for (int i=0; i<nrows; i++)
00392 delete[] tmp[i];
00393 return 0;
00394 }
00395
00396