00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include "MArray.h"
00029 #include "Array-util.h"
00030 #include "lo-error.h"
00031
00032 #include "MArray-defs.h"
00033 #include "mx-inlines.cc"
00034
00035 template <class T>
00036 struct _idxadds_helper
00037 {
00038 T *array;
00039 T val;
00040 _idxadds_helper (T *a, T v) : array (a), val (v) { }
00041 void operator () (octave_idx_type i)
00042 { array[i] += val; }
00043 };
00044
00045 template <class T>
00046 struct _idxadda_helper
00047 {
00048 T *array;
00049 const T *vals;
00050 _idxadda_helper (T *a, const T *v) : array (a), vals (v) { }
00051 void operator () (octave_idx_type i)
00052 { array[i] += *vals++; }
00053 };
00054
00055 template <class T>
00056 void
00057 MArray<T>::idx_add (const idx_vector& idx, T val)
00058 {
00059 octave_idx_type n = this->length ();
00060 octave_idx_type ext = idx.extent (n);
00061 if (ext > n)
00062 {
00063 this->resize1 (ext);
00064 n = ext;
00065 }
00066
00067 octave_quit ();
00068
00069 octave_idx_type len = idx.length (n);
00070 idx.loop (len, _idxadds_helper<T> (this->fortran_vec (), val));
00071 }
00072
00073 template <class T>
00074 void
00075 MArray<T>::idx_add (const idx_vector& idx, const MArray<T>& vals)
00076 {
00077 octave_idx_type n = this->length ();
00078 octave_idx_type ext = idx.extent (n);
00079 if (ext > n)
00080 {
00081 this->resize1 (ext);
00082 n = ext;
00083 }
00084
00085 octave_quit ();
00086
00087 octave_idx_type len = std::min (idx.length (n), vals.length ());
00088 idx.loop (len, _idxadda_helper<T> (this->fortran_vec (), vals.data ()));
00089 }
00090
00091 template <class T, T op (typename ref_param<T>::type, typename ref_param<T>::type)>
00092 struct _idxbinop_helper
00093 {
00094 T *array;
00095 const T *vals;
00096 _idxbinop_helper (T *a, const T *v) : array (a), vals (v) { }
00097 void operator () (octave_idx_type i)
00098 { array[i] = op (array[i], *vals++); }
00099 };
00100
00101 template <class T>
00102 void
00103 MArray<T>::idx_min (const idx_vector& idx, const MArray<T>& vals)
00104 {
00105 octave_idx_type n = this->length ();
00106 octave_idx_type ext = idx.extent (n);
00107 if (ext > n)
00108 {
00109 this->resize1 (ext);
00110 n = ext;
00111 }
00112
00113 octave_quit ();
00114
00115 octave_idx_type len = std::min (idx.length (n), vals.length ());
00116 idx.loop (len, _idxbinop_helper<T, xmin> (this->fortran_vec (), vals.data ()));
00117 }
00118
00119 template <class T>
00120 void
00121 MArray<T>::idx_max (const idx_vector& idx, const MArray<T>& vals)
00122 {
00123 octave_idx_type n = this->length ();
00124 octave_idx_type ext = idx.extent (n);
00125 if (ext > n)
00126 {
00127 this->resize1 (ext);
00128 n = ext;
00129 }
00130
00131 octave_quit ();
00132
00133 octave_idx_type len = std::min (idx.length (n), vals.length ());
00134 idx.loop (len, _idxbinop_helper<T, xmax> (this->fortran_vec (), vals.data ()));
00135 }
00136
00137 #include <iostream>
00138
00139 template <class T>
00140 void MArray<T>::idx_add_nd (const idx_vector& idx, const MArray<T>& vals, int dim)
00141 {
00142 int nd = std::max (this->ndims (), vals.ndims ());
00143 if (dim < 0)
00144 dim = vals.dims ().first_non_singleton ();
00145 else if (dim > nd)
00146 nd = dim;
00147
00148
00149 dim_vector ddv = Array<T>::dims ().redim (nd);
00150 dim_vector sdv = vals.dims ().redim (nd);
00151
00152 octave_idx_type ext = idx.extent (ddv (dim));
00153
00154 if (ext > ddv(dim))
00155 {
00156 ddv(dim) = ext;
00157 Array<T>::resize (ddv);
00158 ext = ddv(dim);
00159 }
00160
00161 octave_idx_type l,n,u,ns;
00162 get_extent_triplet (ddv, dim, l, n, u);
00163 ns = sdv(dim);
00164
00165 sdv(dim) = ddv(dim) = 0;
00166 if (ddv != sdv)
00167 (*current_liboctave_error_handler)
00168 ("accumdim: dimension mismatch");
00169
00170 T *dst = Array<T>::fortran_vec ();
00171 const T *src = vals.data ();
00172 octave_idx_type len = idx.length (ns);
00173
00174 if (l == 1)
00175 {
00176 for (octave_idx_type j = 0; j < u; j++)
00177 {
00178 octave_quit ();
00179
00180 idx.loop (len, _idxadda_helper<T> (dst + j*n, src + j*ns));
00181 }
00182 }
00183 else
00184 {
00185 for (octave_idx_type j = 0; j < u; j++)
00186 {
00187 octave_quit ();
00188 for (octave_idx_type i = 0; i < len; i++)
00189 {
00190 octave_idx_type k = idx(i);
00191
00192 mx_inline_add2 (l, dst + l*k, src + l*i);
00193 }
00194
00195 dst += l*n;
00196 src += l*ns;
00197 }
00198 }
00199 }
00200
00201
00202 template <class T>
00203 void
00204 MArray<T>::changesign (void)
00205 {
00206 if (Array<T>::is_shared ())
00207 *this = - *this;
00208 else
00209 do_mx_inplace_op<T> (*this, mx_inline_uminus2);
00210 }
00211
00212
00213
00214 template <class T>
00215 MArray<T>&
00216 operator += (MArray<T>& a, const T& s)
00217 {
00218 if (a.is_shared ())
00219 a = a + s;
00220 else
00221 do_ms_inplace_op<T, T> (a, s, mx_inline_add2);
00222 return a;
00223 }
00224
00225 template <class T>
00226 MArray<T>&
00227 operator -= (MArray<T>& a, const T& s)
00228 {
00229 if (a.is_shared ())
00230 a = a - s;
00231 else
00232 do_ms_inplace_op<T, T> (a, s, mx_inline_sub2);
00233 return a;
00234 }
00235
00236 template <class T>
00237 MArray<T>&
00238 operator *= (MArray<T>& a, const T& s)
00239 {
00240 if (a.is_shared ())
00241 a = a * s;
00242 else
00243 do_ms_inplace_op<T, T> (a, s, mx_inline_mul2);
00244 return a;
00245 }
00246
00247 template <class T>
00248 MArray<T>&
00249 operator /= (MArray<T>& a, const T& s)
00250 {
00251 if (a.is_shared ())
00252 a = a / s;
00253 else
00254 do_ms_inplace_op<T, T> (a, s, mx_inline_div2);
00255 return a;
00256 }
00257
00258
00259
00260 template <class T>
00261 MArray<T>&
00262 operator += (MArray<T>& a, const MArray<T>& b)
00263 {
00264 if (a.is_shared ())
00265 a = a + b;
00266 else
00267 do_mm_inplace_op<T, T> (a, b, mx_inline_add2, mx_inline_add2, "+=");
00268 return a;
00269 }
00270
00271 template <class T>
00272 MArray<T>&
00273 operator -= (MArray<T>& a, const MArray<T>& b)
00274 {
00275 if (a.is_shared ())
00276 a = a - b;
00277 else
00278 do_mm_inplace_op<T, T> (a, b, mx_inline_sub2, mx_inline_sub2, "-=");
00279 return a;
00280 }
00281
00282
00283 template <class T>
00284 MArray<T>&
00285 product_eq (MArray<T>& a, const MArray<T>& b)
00286 {
00287 if (a.is_shared ())
00288 return a = product (a, b);
00289 else
00290 do_mm_inplace_op<T, T> (a, b, mx_inline_mul2, mx_inline_mul2, ".*=");
00291 return a;
00292 }
00293
00294 template <class T>
00295 MArray<T>&
00296 quotient_eq (MArray<T>& a, const MArray<T>& b)
00297 {
00298 if (a.is_shared ())
00299 return a = quotient (a, b);
00300 else
00301 do_mm_inplace_op<T, T> (a, b, mx_inline_div2, mx_inline_div2, "./=");
00302 return a;
00303 }
00304
00305
00306
00307 #define MARRAY_NDS_OP(OP, FN) \
00308 template <class T> \
00309 MArray<T> \
00310 operator OP (const MArray<T>& a, const T& s) \
00311 { \
00312 return do_ms_binary_op<T, T, T> (a, s, FN); \
00313 }
00314
00315 MARRAY_NDS_OP (+, mx_inline_add)
00316 MARRAY_NDS_OP (-, mx_inline_sub)
00317 MARRAY_NDS_OP (*, mx_inline_mul)
00318 MARRAY_NDS_OP (/, mx_inline_div)
00319
00320
00321
00322 #define MARRAY_SND_OP(OP, FN) \
00323 template <class T> \
00324 MArray<T> \
00325 operator OP (const T& s, const MArray<T>& a) \
00326 { \
00327 return do_sm_binary_op<T, T, T> (s, a, FN); \
00328 }
00329
00330 MARRAY_SND_OP (+, mx_inline_add)
00331 MARRAY_SND_OP (-, mx_inline_sub)
00332 MARRAY_SND_OP (*, mx_inline_mul)
00333 MARRAY_SND_OP (/, mx_inline_div)
00334
00335
00336
00337 #define MARRAY_NDND_OP(FCN, OP, FN) \
00338 template <class T> \
00339 MArray<T> \
00340 FCN (const MArray<T>& a, const MArray<T>& b) \
00341 { \
00342 return do_mm_binary_op<T, T, T> (a, b, FN, FN, FN, #FCN); \
00343 }
00344
00345 MARRAY_NDND_OP (operator +, +, mx_inline_add)
00346 MARRAY_NDND_OP (operator -, -, mx_inline_sub)
00347 MARRAY_NDND_OP (product, *, mx_inline_mul)
00348 MARRAY_NDND_OP (quotient, /, mx_inline_div)
00349
00350 template <class T>
00351 MArray<T>
00352 operator + (const MArray<T>& a)
00353 {
00354 return a;
00355 }
00356
00357 template <class T>
00358 MArray<T>
00359 operator - (const MArray<T>& a)
00360 {
00361 return do_mx_unary_op<T, T> (a, mx_inline_uminus);
00362 }