00001
00002
00003
00004
00005
00006
00007
00008 #ifndef SYNAPS_LINALG_MATRSTR_H
00009 #define SYNAPS_LINALG_MATRSTR_H
00010
00011 #include <sstream>
00012 #include <synaps/init.h>
00013 #include <synaps/base/Range.h>
00014 #include <synaps/arithm/traits.h>
00015 #include <synaps/arithm/texp.h>
00016 #include <synaps/linalg/VECTOR.m>
00017 #include <synaps/linalg/MATRIX.m>
00018 #include <synaps/linalg/VectDse.h>
00019 #include <synaps/linalg/texp.h>
00020
00021 __BEGIN_NAMESPACE_SYNAPS
00022
00023
00034 template<class R> struct MatrStr {
00035
00036 typedef VectDse<typename R::value_type> vector_type;
00037 typedef vector_type col_type;
00038 typedef vector_type row_type;
00039 shared_object<R> data;
00040 R & rep() {return (*data);}
00041 R rep() const {return (*data);}
00042
00043 typedef typename R::size_type size_type;
00044 typedef typename R::value_type value_type;
00045 typedef MatrStr<R> self_t;
00046
00047 MatrStr(): data() {}
00048 MatrStr(const R & r): data(r) {}
00049 MatrStr(int m, int n) {rep().resize(m,n);}
00050 MatrStr(int m, int n, value_type* t): data(R(m,n,t)) {}
00051 MatrStr(unsigned m, unsigned n, char *t);
00052
00053
00054 MatrStr(const self_t & M): data(M.data) {}
00055
00056 self_t & operator=(const self_t & M) {rep()=M.rep(); return *this;}
00057 template<class X>
00058 self_t & operator=(const X & M);
00059
00060 size_type nbrow() const {return rep().nbrow();}
00061 size_type nbcol() const {return rep().nbcol();}
00062
00063 value_type operator()(size_type i, size_type j) const {return rep()(i,j);}
00064
00065 typedef typename binary_operator_prototype< linalg::_submatrix_, self_t, Range2d >::F submatrix_t;
00066 submatrix_t operator()(const Range & I, const Range & J)
00067 { return submatrix(*this,Range2d(I,J)); };
00068
00069 template<class X>
00070 self_t & operator+=(const X & x) { return *this = *this + x; };
00071 template<class X>
00072 self_t & operator-=(const X & x) { return *this = *this - x; };
00073 template<class X>
00074 self_t & operator*=(const X & x) { return *this = *this * x; };
00075
00076 self_t & transpose() {rep().transpose(); return *this;}
00077
00078 };
00079
00080 template<class M, class S> inline
00081 void submatrix( M & r, const MatrStr<S> & a, const Range2d & b )
00082 {
00083 std::cout << a << " " << b << std::endl;
00084 using namespace MATRIX;
00085 submatrix(r.rep(),a.rep(),b);
00086 };
00087
00088 template<class V, class R> inline
00089 void row( V & v, const MatrStr<R> & m, int i )
00090 {
00091 using MATRIX::getrow;
00092 v.resize( m.nbcol() );
00093 getrow( v.rep(), m.rep(), i );
00094 };
00095 template<class V, class R> inline
00096 void col( V & v, const MatrStr<R> & m, int i )
00097 {
00098 using MATRIX::getcol;
00099 v.resize( m.nbrow() );
00100 getcol( v.rep(), m.rep(), i );
00101 };
00102
00103 template<class S> inline
00104 void col( MatrStr<S>& sm, const MatrStr<S> & m, const Range & rg )
00105 {
00106 submatrix(sm,m,Range2d(0,m.nbrow()-1,rg.i1,rg.i2));
00107 };
00108
00109 template<class S> inline
00110 void row( MatrStr<S>& sm, const MatrStr<S> & m, const Range & rg )
00111 {
00112 submatrix(sm,m,Range2d(rg.i1,rg.i2,0,m.nbcol()-1));
00113 };
00114
00115
00116
00117 template<class R,class S> inline
00118 void add( MatrStr<R> & r, const MatrStr<S> & a, const MatrStr<S> & b )
00119 {
00120 r.rep().resize(a.nbrow(),b.nbcol());
00121 using namespace VECTOR;
00122 add(r.rep(),a.rep(),b.rep());
00123 };
00124
00125 template<class R> inline
00126 void sub(MatrStr<R> & r, const MatrStr<R> & a ,const MatrStr<R> & b )
00127 {
00128 r.rep().resize(a.nbrow(),b.nbcol());
00129 using namespace VECTOR;
00130 sub(r.rep(),a.rep(),b.rep());
00131 }
00132
00133 template<class S> inline
00134 void mul(MatrStr<S> & r, const MatrStr<S> & a, const typename MatrStr<S>::value_type & b )
00135 {
00136 r.rep().resize(a.nbrow(),b.nbcol());
00137 using namespace VECTOR; mul_ext(r.rep(),a.rep(),b);
00138 };
00139 template<class R,class S,class C> inline
00140 void mul(MatrStr<R> & r, const MatrStr<S> & a, const C & b )
00141 {
00142 r.rep().resize(a.nbrow(),b.nbcol());
00143 using namespace VECTOR; mul_ext(r.rep(),a.rep(),b);
00144 }
00145
00146 template<class R,class S,class C> inline
00147 void mul(MatrStr<R> & r, const C & b, const MatrStr<S> & a )
00148 {
00149 mul(r,a,b);
00150 }
00151
00152 template<class Ca, class Ra,
00153 class S,
00154 class Cb, class Rb>
00155 void mul(VectDse<Ca,Ra> & r, const MatrStr<S> & m, const VectDse<Cb,Rb> & v )
00156 {
00157 assert(m.nbcol()==v.size());
00158 r.resize(m.nbrow());
00159 using namespace MATRIX;
00160 mul_vect(r.rep(),m.rep(),v.rep());
00161 };
00162
00163
00164
00165 template<class C,class S> struct MatrDse;
00166 namespace let {
00167
00168 template<class R,class C, class S> inline
00169 void assign(MatrStr<R> & r, const MatrDse<C,S> & M)
00170 {
00171 using MATRIX::assign;
00172 assign(r.rep(), M.rep());
00173 }
00174
00175
00176 template<class R> inline
00177 void assign(MatrStr<R> & r, const MatrStr<R>* M)
00178 {
00179 assign(r.rep(), &M->rep());
00180 }
00181 }
00182
00184 template<class R>
00185 std::ostream & operator<<(std::ostream & os, const MatrStr<R> & p)
00186 {
00187 using namespace MATRIX; return print(os,p.rep());
00188 }
00189
00195 template<class R> inline
00196 std::istream & operator>>(std::istream & is, MatrStr<R> & M)
00197 {
00198 return read(is,M.rep());
00199 }
00200
00201
00202 namespace type
00203 {
00204 template<class C, class S>
00205 struct instanceof< MatrStr<S>, C > { typedef MatrStr< typename instanceof<S,C>::T > T; };
00206 };
00207 namespace arithm
00208 {
00209 template<class S> struct structureof< MatrStr<S> > { typedef structure::matrix T; };
00210
00211 #define head template<class R>
00212 #define parm0 MatrStr<R>
00213 #define parm1 MatrStr<R>
00214 declare_binary_operator(head,parm0,int,linalg::_col_,col);
00215 declare_binary_operator(head,parm0,int,linalg::_row_,row);
00216 declare_binary_operator(head,parm0,Range,linalg::_col_,col);
00217 declare_binary_operator(head,parm0,Range,linalg::_row_,row);
00218 declare_binary_operator(head,parm0,Range2d,linalg::_submatrix_,submatrix);
00219 declare_binary_operator(head,parm0,parm1,_add_,operator+);
00220 declare_binary_operator(head,parm0,parm1,_sub_,operator-);
00221 declare_binary_operator(head,parm0,parm1,_mul_,operator*);
00222 declare_unary_operator(head,parm0,_neg_,operator-);
00223 #undef head
00224 #undef parm0
00225 #undef parm1
00226 #define head template<class R, class C, class Rc>
00227 #define parm0 MatrStr<R>
00228 #define parm1 VectDse<C,Rc>
00229 declare_binary_operator(head,parm0,parm1,_mul_,operator*);
00230 #undef head
00231 #undef parm0
00232 #undef parm1
00233 #define head template<class R>
00234 #define parm0 MatrStr<R>
00235 #define parm1 typename MatrStr<R>::value_type
00236 declare_binary_operator(head,parm0,parm1,_mul_,operator*);
00237 declare_binary_operator(head,parm1,parm0,_mul_,operator*);
00238 declare_binary_operator(head,parm0,parm1,_div_,operator/);
00239 #undef head
00240 #undef parm0
00241 #undef parm1
00242
00243
00244 }
00245
00246 template<class S>
00247 template<class X>
00248 MatrStr<S> & MatrStr<S>::operator=( const X & x )
00249 {
00250 using let::assign; assign(*this,x);
00251 return *this;
00252 };
00253
00254
00255
00256
00257 __END_NAMESPACE_SYNAPS
00258
00259 #ifndef SEPARATE_COMPILATION
00260 #include "synaps/linalg/MatrStr.C"
00261 #endif
00262
00263
00264 #endif // SYNAPS_LINALG_MATRSTR_H
00265