00001
00007 #ifndef __MATRIXADAPTER_H__
00008 #define __MATRIXADAPTER_H__
00009
00010 #include "matrix.h"
00011 #include "generic_stdlib.h"
00012 #include "allocatingpointer.h"
00013 #include "scale.h"
00014 #include "aarectangle.h"
00015
00016 namespace mat {
00017
00018
00037 template <class M,
00038 class T=typename M::value_type,
00039 class ScaleT=Scale::Linear<T>,
00040 class RegionT=Boundary::AAArbitraryRectangle<double,int> >
00041 class MatrixAdapter {
00042 typedef MatrixAdapter<M,T,ScaleT,RegionT> self;
00043 public:
00044
00045 typedef typename M::size_type size_type;
00046 typedef T value_type;
00047 typedef ScaleT ScaleType;
00048 typedef RegionT Region;
00049 typedef int Coordinate;
00050
00078 inline MatrixAdapter(const M& x,
00079 const ScaleType& vscale_i=ScaleType(),
00080 const Region& region=Region(),
00081 const double& size_multiplier=1.0)
00082 : m(x), vscale(vscale_i),
00083 height(size_type(size_multiplier*(!region.isinfinite()? region.height() : x.nrows()))),
00084 width( size_type(size_multiplier*(!region.isinfinite()? region.width() : x.ncols()))),
00085 originr(Coordinate(region.corners().yl)), originc(Coordinate(region.corners().xl)),
00086 size_divisor(size_multiplier? 1.0/size_multiplier : 0)
00087 { assert(region.corners().xh<=region.corners().xl); assert(region.corners().yh<=region.corners().yl); }
00088
00091 inline MatrixAdapter(M* x,
00092 const ScaleType& vscale_i=ScaleType(),
00093 const Region& region=Region(),
00094 const double& size_multiplier=1.0)
00095 : m(*x), allocated(x), vscale(vscale_i),
00096 height(size_type(size_multiplier*(!region.isinfinite()? region.height() : x->nrows()))),
00097 width( size_type(size_multiplier*(!region.isinfinite()? region.width() : x->ncols()))),
00098 originr(Coordinate(region.corners().yl)), originc(Coordinate(region.corners().xl)),
00099 size_divisor(size_multiplier? 1.0/size_multiplier : 0)
00100 { assert(region.corners().xh<=region.corners().xl); assert(region.corners().yh<=region.corners().yl); }
00101
00109 inline value_type operator()(const size_type row, const size_type col) const {
00110 const size_type lower_bound=MatIndex(0);
00111 const value_type default_value=0;
00112 const Coordinate r=row-lower_bound;
00113 const Coordinate c=col-lower_bound;
00114
00115
00116 const Coordinate sr=Coordinate(floor((r*size_divisor)+0.000001))-originr;
00117 const Coordinate sc=Coordinate(floor((c*size_divisor)+0.000001))-originc;
00118
00119 return value_type(vscale(inbounds(sr,sc)? mat::elem(m,sr,sc): default_value));
00120 }
00121
00122
00124 inline size_type nrows() const { return height; }
00125
00127 inline size_type ncols() const { return width; }
00128
00129 protected:
00130 const M& m;
00131 MemoryReference<M> allocated;
00132
00133 ScaleT vscale;
00134 size_type height,width;
00135 Coordinate originr,originc;
00136 double size_divisor;
00137
00139 inline bool inbounds(const size_type r, const size_type c) const {
00140 return (int(r)>=0 && r<m.nrows() &&
00141 int(c)>=0 && c<m.ncols());
00142 }
00143 };
00144
00145
00147 template <class T, class Array>
00148 class CArrayMatrixAdapter {
00149 typedef CArrayMatrixAdapter<T,Array> self;
00150 public:
00151
00152 typedef size_t size_type;
00153 typedef T value_type;
00154
00155 inline CArrayMatrixAdapter(const Array& x, const size_type nrows, const size_type ncols)
00156 : a(x), height(nrows), width(ncols) { }
00157
00158 inline value_type operator()(const size_type row, const size_type col) const {
00159 const size_type lower_bound=MatIndex(0);
00160 assert((row-lower_bound)<height);
00161 assert((col-lower_bound)<width);
00162
00163 return a[col-lower_bound][row-lower_bound];
00164 }
00165
00167 inline size_type nrows() const { return height; }
00168
00170 inline size_type ncols() const { return width; }
00171
00172 protected:
00173 const Array& a;
00174 const size_type height, width;
00175 };
00176
00177
00178
00194 template <class T>
00195 class MatrixInterface {
00196 typedef MatrixInterface<T> self;
00197 public:
00198
00199 typedef int size_type;
00200 typedef T value_type;
00201
00202 virtual ~MatrixInterface() { };
00203
00204 virtual value_type operator()(const size_type row, const size_type col) const =0;
00205
00207 virtual size_type nrows() const =0;
00208
00210 virtual size_type ncols() const =0;
00211 };
00212
00213
00214
00223 template <class M,
00224 class T=typename M::value_type,
00225 class ScaleT=Scale::Linear<T>,
00226 class RegionT=Boundary::AAArbitraryRectangle<double,int> >
00227 class MatrixInterfaceAdapter : public MatrixInterface<T> {
00228 typedef MatrixInterfaceAdapter<M,T,ScaleT,RegionT> self;
00229
00230 public:
00231 typedef typename MatrixInterface<T>::size_type size_type;
00232 typedef typename MatrixInterface<T>::value_type value_type;
00233 typedef ScaleT ScaleType;
00234 typedef RegionT Region;
00235
00238 inline MatrixInterfaceAdapter(const M& x,
00239 const ScaleType& vscale=ScaleType(),
00240 const Region& region=Region(),
00241 const double& size_multiplier=1.0)
00242 : ma(x,vscale,region,size_multiplier) { }
00243
00246 inline MatrixInterfaceAdapter(M* x,
00247 const ScaleType& vscale=ScaleType(),
00248 const Region& region=Region(),
00249 const double& size_multiplier=1.0)
00250 : ma(x,vscale,region,size_multiplier) { }
00251
00252 inline value_type operator()(const size_type row, const size_type col) const
00253 { return value_type(ma(typename M::size_type(row),
00254 typename M::size_type(col))); }
00255
00257 inline size_type nrows() const { return ma.nrows(); }
00258
00260 inline size_type ncols() const { return ma.ncols(); }
00261
00262 protected:
00263 MatrixAdapter<M,value_type> ma;
00264 };
00265
00266
00267
00270 template <class T=double>
00271 class MatrixInterfaceConstant : public MatrixInterface<T> {
00272 typedef MatrixInterfaceConstant<T> self;
00273
00274 public:
00275 typedef typename MatrixInterface<T>::size_type size_type;
00276 typedef typename MatrixInterface<T>::value_type value_type;
00277
00279 inline MatrixInterfaceConstant(const value_type& a=1.0, size_type nr=1, size_type nc=1)
00280 : val(a), height(nr), width(nc) { }
00281
00282 inline value_type operator()(const size_type, const size_type) const
00283 { return val; }
00284
00286 inline size_type nrows() const { return height; }
00287
00289 inline size_type ncols() const { return width; }
00290
00291 protected:
00292 const T val;
00293 const size_type height,width;
00294 };
00295
00296
00302 template <class M, class BinaryFunction, class T=typename M::value_type >
00303 class MatrixInterfaceBinaryAdapter : public MatrixInterface<T> {
00304 typedef MatrixInterfaceBinaryAdapter<M,T> self;
00305
00306 public:
00307 typedef typename MatrixInterface<T>::size_type size_type;
00308 typedef typename MatrixInterface<T>::value_type value_type;
00309
00311 inline MatrixInterfaceBinaryAdapter(const M& A, const M& B, const BinaryFunction& fn)
00312 : MA(A), MB(B), op(fn) {
00313 assert(MA.nrows()==MB.nrows());
00314 assert(MA.ncols()==MB.ncols());
00315 }
00316
00317 virtual value_type operator()(const size_type row, const size_type col) const
00318 { return value_type( op( MA(row,col), MB(row,col) )); }
00319
00321 virtual size_type nrows() const { return MA.nrows(); }
00322
00324 virtual size_type ncols() const { return MA.ncols(); }
00325
00326 protected:
00327 const M& MA;
00328 const M& MB;
00329 const BinaryFunction& op;
00330 };
00331
00332
00333 }
00334
00335
00336 #endif