00001 #ifndef Impala_Core_Matrix_VirtualMatrix_h
00002 #define Impala_Core_Matrix_VirtualMatrix_h
00003
00004 #include "Core/Array/Arrays.h"
00005 #include "Core/Vector/VectorTem.h"
00006 #include "Core/Matrix/Mat.h"
00007
00008 namespace Impala
00009 {
00010 namespace Core
00011 {
00012 namespace Matrix
00013 {
00014
00015
00016 class VirtualMatrix
00017 {
00018 public:
00019
00020 typedef Vector::VectorTem<Real64> Vector64;
00021
00022 VirtualMatrix()
00023 {
00024 }
00025
00026 virtual
00027 ~VirtualMatrix()
00028 {
00029 }
00030
00031 virtual int
00032 NrRow() = 0;
00033
00034 virtual int
00035 NrCol() = 0;
00036
00037 Vector64
00038 GetRow(int rowNr)
00039 {
00040 Vector64 res(NrCol());
00041 GetRow(rowNr, res.GetData(), res.Size());
00042 return res;
00043 }
00044
00045 int
00046 GetRow(int rowNr, Real64* buffer, int bufferSize)
00047 {
00048 if (bufferSize < NrCol())
00049 {
00050 ILOG_ERROR("[GetRow] Buffer too small");
00051 return 0;
00052 }
00053 if (HasGetRowImplReal64())
00054 return GetRowImpl(rowNr, buffer, bufferSize);
00055 if (!HasGetRowImplReal32())
00056 {
00057 ILOG_ERROR("GetRow not implemented");
00058 return 0;
00059 }
00060 Real32* tmpBuf = new Real32[bufferSize];
00061 int nr = GetRowImpl(rowNr, tmpBuf, bufferSize);
00062 for (int i=0 ; i<nr ; i++)
00063 buffer[i] = tmpBuf[i];
00064 delete tmpBuf;
00065 return nr;
00066 }
00067
00068 int
00069 GetRow(int rowNr, Real32* buffer, int bufferSize)
00070 {
00071 if (bufferSize < NrCol())
00072 {
00073 ILOG_ERROR("[GetRow] Buffer too small");
00074 return 0;
00075 }
00076 if (HasGetRowImplReal32())
00077 return GetRowImpl(rowNr, buffer, bufferSize);
00078 if (!HasGetRowImplReal64())
00079 {
00080 ILOG_ERROR("GetRow not implemented");
00081 return 0;
00082 }
00083 Real64* tmpBuf = new Real64[bufferSize];
00084 int nr = GetRowImpl(rowNr, tmpBuf, bufferSize);
00085 for (int i=0 ; i<nr ; i++)
00086 buffer[i] = tmpBuf[i];
00087 delete tmpBuf;
00088 return nr;
00089 }
00090
00091
00092 int
00093 AddRow(int rowNr, Real64* buffer)
00094 {
00095 if (HasAddRowImplReal64())
00096 return AddRowImpl(rowNr, buffer);
00097 if (!HasAddRowImplReal32())
00098 {
00099 ILOG_ERROR("AddRow not implemented");
00100 return 0;
00101 }
00102 int nr = NrCol();
00103 Real32* tmpBuf = new Real32[nr];
00104 for (int i=0 ; i<nr ; i++)
00105 tmpBuf[i] = buffer[i];
00106 int res = AddRowImpl(rowNr, tmpBuf);
00107 delete tmpBuf;
00108 return res;
00109 }
00110
00111
00112 int
00113 AddRow(int rowNr, Real32* buffer)
00114 {
00115 if (HasAddRowImplReal32())
00116 return AddRowImpl(rowNr, buffer);
00117 if (!HasAddRowImplReal64())
00118 {
00119 ILOG_ERROR("AddRow not implemented");
00120 return 0;
00121 }
00122 int nr = NrCol();
00123 Real64* tmpBuf = new Real64[nr];
00124 for (int i=0 ; i<nr ; i++)
00125 tmpBuf[i] = buffer[i];
00126 int res = AddRowImpl(rowNr, tmpBuf);
00127 delete tmpBuf;
00128 return res;
00129 }
00130
00131 int
00132 AddRowPart(int rowNr, int colNr, Real64* buffer, int bufSize)
00133 {
00134 if (HasAddRowImplReal64())
00135 return AddRowPartImpl(rowNr, colNr, buffer, bufSize);
00136 if (!HasAddRowImplReal32())
00137 {
00138 ILOG_ERROR("AddRowPart not implemented");
00139 return 0;
00140 }
00141 Real32* tmpBuf = new Real32[bufSize];
00142 for (int i=0 ; i<bufSize ; i++)
00143 tmpBuf[i] = buffer[i];
00144 int res = AddRowPartImpl(rowNr, colNr, tmpBuf, bufSize);
00145 delete tmpBuf;
00146 return res;
00147 }
00148
00149 int
00150 AddRowPart(int rowNr, int colNr, Real32* buffer, int bufSize)
00151 {
00152 if (HasAddRowImplReal32())
00153 return AddRowPartImpl(rowNr, colNr, buffer, bufSize);
00154 if (!HasAddRowImplReal64())
00155 {
00156 ILOG_ERROR("AddRowPart not implemented");
00157 return 0;
00158 }
00159 Real64* tmpBuf = new Real64[bufSize];
00160 for (int i=0 ; i<bufSize ; i++)
00161 tmpBuf[i] = buffer[i];
00162 int res = AddRowPartImpl(rowNr, colNr, tmpBuf, bufSize);
00163 delete tmpBuf;
00164 return res;
00165 }
00166
00167 Vector64
00168 GetDiagonal()
00169 {
00170 Vector64 res(NrCol());
00171 GetDiagonal(res.GetData(), res.Size());
00172 return res;
00173 }
00174
00175 int
00176 GetDiagonal(Real64* buffer, int bufferSize)
00177 {
00178 if (NrRow() != NrCol())
00179 {
00180 ILOG_ERROR("[GetDiagonal] Only works for square matrices!");
00181 return 0;
00182 }
00183 if (bufferSize < NrCol())
00184 {
00185 ILOG_ERROR("[GetDiagonal] Buffer too small");
00186 return 0;
00187 }
00188 return GetDiagonalImpl(buffer, bufferSize);
00189 }
00190
00191 int
00192 Diff(VirtualMatrix* arg)
00193 {
00194 if (NrRow() != arg->NrRow())
00195 {
00196 ILOG_ERROR("[Diff] NrRow differs: " << NrRow() << " vs " <<
00197 arg->NrRow());
00198 return 1;
00199 }
00200 if (NrCol() != arg->NrCol())
00201 {
00202 ILOG_ERROR("[Diff] NrCol differs: " << NrCol() << " vs " <<
00203 arg->NrCol());
00204 return 1;
00205 }
00206 int nDiff = 0;
00207 Real64* row = new Real64[NrCol()];
00208 Real64* rowArg = new Real64[NrCol()];
00209 for (int i=0 ; i<NrRow() ; i++)
00210 {
00211 GetRow(i, row, NrCol());
00212 arg->GetRow(i, rowArg, NrCol());
00213 for (int j=0 ; j<NrCol() ; j++)
00214 {
00215 if (fabs(row[j] - rowArg[j]) > 0.00001)
00216 {
00217 ILOG_DEBUG("elem " << i << "," << j << " differs: "
00218 << row[j] << " vs " << rowArg[j]);
00219 nDiff++;
00220 }
00221 }
00222 }
00223 delete row;
00224 delete rowArg;
00225 if (nDiff > 0)
00226 ILOG_ERROR("Found " << nDiff << " differences");
00227 return nDiff;
00228 }
00229
00230 void
00231 CopyFrom(VirtualMatrix* arg)
00232 {
00233 if (arg->HasGetRowImplReal64())
00234 return CopyFromImpl<Real64>(arg);
00235 if (arg->HasGetRowImplReal32())
00236 return CopyFromImpl<Real32>(arg);
00237 ILOG_ERROR("[CopyFrom] arg has no GetRow implementation");
00238 }
00239
00240
00241
00242
00243 virtual Mat*
00244 GetStorage()
00245 {
00246 return 0;
00247 }
00248
00249 private:
00250
00251 virtual bool
00252 HasGetRowImplReal64()
00253 {
00254 return false;
00255 }
00256
00257 virtual int
00258 GetRowImpl(int rowNr, Real64* buffer, int bufferSize)
00259 {
00260 ILOG_ERROR("[GetRowImpl] 64bit version should not be called");
00261 return 0;
00262 }
00263
00264 virtual bool
00265 HasGetRowImplReal32()
00266 {
00267 return false;
00268 }
00269
00270 virtual int
00271 GetRowImpl(int rowNr, Real32* buffer, int bufferSize)
00272 {
00273 ILOG_ERROR("[GetRowImpl] 32bit version should not be called");
00274 return 0;
00275 }
00276
00277 virtual bool
00278 HasAddRowImplReal64()
00279 {
00280 return false;
00281 }
00282
00283 virtual int
00284 AddRowImpl(int rowNr, Real64* buffer)
00285 {
00286 ILOG_ERROR("[AddRowImpl] 64bit version should not be called");
00287 return 0;
00288 }
00289
00290 virtual int
00291 AddRowPartImpl(int rowNr, int colNr, Real64* buffer, int bufSize)
00292 {
00293 ILOG_ERROR("[AddRowPartImpl] 64bit version should not be called");
00294 return 0;
00295 }
00296
00297 virtual bool
00298 HasAddRowImplReal32()
00299 {
00300 return false;
00301 }
00302
00303 virtual int
00304 AddRowImpl(int rowNr, Real32* buffer)
00305 {
00306 ILOG_ERROR("[AddRowImpl] 32bit version should not be called");
00307 return 0;
00308 }
00309
00310 virtual int
00311 AddRowPartImpl(int rowNr, int colNr, Real32* buffer, int bufSize)
00312 {
00313 ILOG_ERROR("[AddRowPartImpl] 32bit version should not be called");
00314 return 0;
00315 }
00316
00317 virtual int
00318 GetDiagonalImpl(Real64* buffer, int bufferSize) = 0;
00319
00320 template <class BufT>
00321 void
00322 CopyFromImpl(VirtualMatrix* arg)
00323 {
00324 BufT* buf = new BufT[NrCol()];
00325 for (int i=0 ; i<NrRow() ; i++)
00326 {
00327 int nr = arg->GetRow(i, buf, NrCol());
00328 if (nr != NrCol())
00329 break;
00330 nr = AddRow(i, buf);
00331 if (nr != NrCol())
00332 break;
00333 }
00334 delete buf;
00335 }
00336
00337 ILOG_VAR_DEC;
00338 };
00339
00340 ILOG_VAR_INIT(VirtualMatrix, Impala.Core.Matrix);
00341
00342 }
00343 }
00344 }
00345
00346 #endif