00001 #include "GMatrix.h"
00002 #include "../io_src/GError_Output.h"
00003 #include "../io_src/GStd_Output.h"
00004
00005 #include <iostream>
00006 #include <iomanip>
00007 #include <string>
00008 #include <vector>
00009 #include <omp.h>
00010
00011 using namespace GMathLib;
00012 using namespace GMathLib::IO;
00013
00014 GMatrix::GMatrix()
00015 : GObject(), p_data(0), row(0), column(0), internal_new_flag(false)
00016 {
00017 Class_Name("GMatrix");
00018
00019 }
00020
00021 GMatrix::~GMatrix()
00022 {
00023 if(internal_new_flag){
00024 delete[] p_data;
00025
00026 }
00027 }
00028
00029 GMatrix::GMatrix(const GMatrix& obj)
00030 {
00031
00032 row = obj.row;
00033 column = obj.column;
00034
00035 if(obj.p_data != 0){
00036 double* original_d = obj.p_data;
00037 int data_size = row * column;
00038 this->p_data = new double[data_size];
00039 internal_new_flag = true;
00040
00041 for(int i=0; i < data_size; i++){
00042 this->p_data[i] = original_d[i];
00043 }
00044
00045 }
00046 }
00047
00048 void GMatrix::allocate_initialize(int mrow, int mcolumn, double* mdata)
00049 {
00050 Class_Name("GMatrix");
00051 row = mrow; column = mcolumn;
00052
00053
00054
00055
00056 if(mdata != 0){
00057 p_data = mdata;
00058 internal_new_flag = false;
00059
00060
00061
00062 }else{
00063 p_data = new double[row * column];
00064 internal_new_flag = true;
00065
00066
00067 }
00068 }
00069
00070 int GMatrix::Copy(const GMatrix& obj)
00071 {
00072
00073
00074
00075 if(row != obj.row || column != obj.column){
00076
00077
00078
00079 if(obj.p_data != 0 && internal_new_flag){
00080 delete[] p_data;
00081
00082 }
00083
00084 row = obj.row;
00085 column = obj.column;
00086
00087 p_data = new double[row * column];
00088 internal_new_flag = true;
00089
00090
00091 }
00092
00093 double *original_d = obj.p_data;
00094 int d_size = row * column;
00095
00096
00097 int i;
00098 #pragma omp parallel for private(i) if(d_size > 200)
00099 for(i=0; i < d_size; i++){
00100 this->p_data[i] = original_d[i];
00101 }
00102
00103 return 0;
00104 }
00105
00106 int GMatrix::Reshape(int new_row, int new_column)
00107 {
00108
00109 if(row * column != new_row * new_column){
00110
00111 const std::string errinfo = "The size of matrix must not be changed.";
00112 GError_Output::Puts(Class_Name() +"::Reshape", errinfo);
00113 return 1;
00114 }
00115
00116
00117 row = new_row;
00118 column = new_column;
00119
00120 return 0;
00121 }
00122
00123 int GMatrix::Add(const GMatrix &a, const GMatrix &b)
00124 {
00125 int b_col = b.Column(); int b_row = b.Row();
00126
00127 if(a.Row() != b_row || b_row != row ||
00128 a.Column() != b_col || b_col != column){
00129
00130 const std::string errinfo = "The sizes of two matrixes are not consistent.";
00131 GError_Output::Puts(Class_Name() + "::Add", errinfo);
00132 return 1;
00133
00134 }else{
00135 double tmp;
00136
00137 for(int i= 0; i < b_row; i++){
00138 for(int j=0; j < b_col; j++){
00139 tmp = a.Get(i, j) + b.Get(i, j);
00140 Set(i, j, tmp);
00141 }
00142 }
00143
00144 return 0;
00145 }
00146 }
00147
00148
00149
00150 int GMatrix::Sub(const GMatrix &a, const GMatrix &b)
00151 {
00152 int b_col = b.Column(); int b_row = b.Row();
00153
00154 if(a.Row() != b_row || b_row != row ||
00155 a.Column() != b_col || b_col != column){
00156
00157 const std::string errinfo = "The sizes of two matrixes are not consistent.";
00158 GError_Output::Puts(Class_Name() + "::Sub", errinfo);
00159 return 1;
00160
00161 }else{
00162 double tmp;
00163
00164 for(int i= 0; i < b_row; i++){
00165 for(int j=0; j < b_col; j++){
00166 tmp = a.Get(i, j) - b.Get(i, j);
00167 Set(i, j, tmp);
00168 }
00169 }
00170
00171 return 0;
00172 }
00173 }
00174
00175 int GMatrix::Multi(const GMatrix& a, const GMatrix& b)
00176 {
00177 int this_row = Row();
00178 int this_col = Column();
00179 int a_col = a.Column();
00180 int b_col = b.Column();
00181
00182 if(this_row != a.Row() || this_col != b_col || a_col != b.Row()){
00183 const std::string errinfo = "Error of matrix size in calculating Multi!";
00184 GError_Output::Puts(Class_Name() + "::Multi", errinfo);
00185 return 1;
00186
00187 }else{
00188 double tmp_d = 0.0;
00189
00190 for(int i= 0; i < this_row; i++){
00191 for(int j=0; j < this_col; j++){
00192 for(int k = 0; k < a_col; k++){
00193 tmp_d += a.Get(i, k) * b.Get(k, j);
00194 }
00195
00196 Set(i, j, tmp_d);
00197 tmp_d = 0.0;
00198 }
00199 }
00200
00201 return 0;
00202 }
00203 }
00204
00205
00206
00207
00208 GMatrix GMatrix::operator=(const GMatrix &a)
00209 {
00210 int a_row = a.Row();
00211 int a_col = a.Column();
00212
00213 if( Row() != a_row || Column() != a_col ){
00214 const std::string errinfo = "The sizes of two matrixes are not consistent.";
00215 GError_Output::Puts(Class_Name() + "::operator=", errinfo);
00216
00217 }else{
00218 this->Copy(a);
00219 }
00220
00221 return (*this);
00222 }
00223
00227 GMatrix GMatrix::operator+(const GMatrix &a)
00228 {
00229 int a_row = a.Row();
00230 int a_col = a.Column();
00231
00232 GMatrix r(a_row, a_col);
00233
00234 if( Row() != a_row || Column() != a_col ){
00235 const std::string errinfo = "The sizes of two matrixes are not consistent.";
00236 GError_Output::Puts(Class_Name() + "::operator+", errinfo);
00237 return r;
00238
00239 }else{
00240 r.Add(*this, a);
00241
00242 return (r);
00243 }
00244 }
00245
00249 GMatrix GMatrix::operator-(const GMatrix &a)
00250 {
00251 int a_row = a.Row();
00252 int a_col = a.Column();
00253
00254 GMatrix r(a_row, a_col);
00255
00256 if( Row() != a_row || Column() != a_col ){
00257 const std::string errinfo = "The sizes of two matrixes are not consistent.";
00258 GError_Output::Puts(Class_Name() + "::operator-", errinfo);
00259 return r;
00260
00261 }else{
00262 r.Sub(*this, a);
00263
00264 return r;
00265 }
00266
00267 }
00268
00272 GMatrix GMatrix::operator*(const GMatrix &a)
00273 {
00274 int a_row = a.Row();
00275 int a_col = a.Column();
00276
00277 GMatrix r(Row(), a_col);
00278
00279 if( Column() != a_row ){
00280 const std::string errinfo = "The sizes of two matrixes are not consistent.";
00281 GError_Output::Puts(Class_Name() + "::operator-", errinfo);
00282 return r;
00283
00284 }else{
00285 r.Multi(*this, a);
00286
00287 return r;
00288 }
00289 }
00290
00294 void GMatrix::Print(int turn_down, bool scientific_format)
00295 {
00296
00297 GStd_Output::Write(Class_Name() + "::Print()", ToString());
00298
00299
00300
00301 if(scientific_format)
00302 std::cout.setf(std::ios::scientific);
00303
00304
00305
00306 for(int i = 0; i < row; i++){
00307 std::cout << "| ";
00308
00309 for(int j = 0; j < column-1; j++){
00310 std::cout << Get(i, j) << " ";
00311
00312
00313 if( turn_down != -1 && !( (j+1) % turn_down ))
00314 std::cout << std::endl;
00315 }
00316
00317
00318 std::cout << Get(i, column - 1) << " |\n";
00319
00320 }
00321
00322 std::cout << std::endl;
00323 }
00324