Mercurial > hg > octave-lyh
comparison liboctave/MArray.cc @ 10350:12884915a8e4
merge MArray classes & improve Array interface
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Sat, 23 Jan 2010 21:41:03 +0100 |
parents | 4c0cdbe0acca |
children | b47ab50a6aa8 |
comparison
equal
deleted
inserted
replaced
10349:d4d13389c957 | 10350:12884915a8e4 |
---|---|
29 #include "MArray.h" | 29 #include "MArray.h" |
30 #include "Array-util.h" | 30 #include "Array-util.h" |
31 #include "lo-error.h" | 31 #include "lo-error.h" |
32 | 32 |
33 #include "MArray-defs.h" | 33 #include "MArray-defs.h" |
34 | 34 #include "mx-inlines.cc" |
35 // One dimensional array with math ops. | 35 |
36 | 36 template <class T> |
37 template <class T> | 37 struct _idxadds_helper |
38 double | 38 { |
39 MArray<T>::norm (double) const | 39 T *array; |
40 { | 40 T val; |
41 (*current_liboctave_error_handler) | 41 _idxadds_helper (T *a, T v) : array (a), val (v) { } |
42 ("norm: only implemented for double and complex values"); | 42 void operator () (octave_idx_type i) |
43 | 43 { array[i] += val; } |
44 return 0; | 44 }; |
45 } | 45 |
46 | 46 template <class T> |
47 template <class T> | 47 struct _idxadda_helper |
48 float | 48 { |
49 MArray<T>::norm (float) const | 49 T *array; |
50 { | 50 const T *vals; |
51 (*current_liboctave_error_handler) | 51 _idxadda_helper (T *a, const T *v) : array (a), vals (v) { } |
52 ("norm: only implemented for double and complex values"); | 52 void operator () (octave_idx_type i) |
53 | 53 { array[i] += *vals++; } |
54 return 0; | 54 }; |
55 | |
56 template <class T> | |
57 void | |
58 MArray<T>::idx_add (const idx_vector& idx, T val) | |
59 { | |
60 octave_idx_type n = this->length (); | |
61 octave_idx_type ext = idx.extent (n); | |
62 if (ext > n) | |
63 { | |
64 this->resize1 (ext); | |
65 n = ext; | |
66 } | |
67 | |
68 octave_quit (); | |
69 | |
70 octave_idx_type len = idx.length (n); | |
71 idx.loop (len, _idxadds_helper<T> (this->fortran_vec (), val)); | |
72 } | |
73 | |
74 template <class T> | |
75 void | |
76 MArray<T>::idx_add (const idx_vector& idx, const MArray<T>& vals) | |
77 { | |
78 octave_idx_type n = this->length (); | |
79 octave_idx_type ext = idx.extent (n); | |
80 if (ext > n) | |
81 { | |
82 this->resize1 (ext); | |
83 n = ext; | |
84 } | |
85 | |
86 octave_quit (); | |
87 | |
88 octave_idx_type len = std::min (idx.length (n), vals.length ()); | |
89 idx.loop (len, _idxadda_helper<T> (this->fortran_vec (), vals.data ())); | |
90 } | |
91 | |
92 template <class T, T op (typename ref_param<T>::type, typename ref_param<T>::type)> | |
93 struct _idxbinop_helper | |
94 { | |
95 T *array; | |
96 const T *vals; | |
97 _idxbinop_helper (T *a, const T *v) : array (a), vals (v) { } | |
98 void operator () (octave_idx_type i) | |
99 { array[i] = op (array[i], *vals++); } | |
100 }; | |
101 | |
102 template <class T> | |
103 void | |
104 MArray<T>::idx_min (const idx_vector& idx, const MArray<T>& vals) | |
105 { | |
106 octave_idx_type n = this->length (); | |
107 octave_idx_type ext = idx.extent (n); | |
108 if (ext > n) | |
109 { | |
110 this->resize1 (ext); | |
111 n = ext; | |
112 } | |
113 | |
114 octave_quit (); | |
115 | |
116 octave_idx_type len = std::min (idx.length (n), vals.length ()); | |
117 idx.loop (len, _idxbinop_helper<T, xmin> (this->fortran_vec (), vals.data ())); | |
118 } | |
119 | |
120 template <class T> | |
121 void | |
122 MArray<T>::idx_max (const idx_vector& idx, const MArray<T>& vals) | |
123 { | |
124 octave_idx_type n = this->length (); | |
125 octave_idx_type ext = idx.extent (n); | |
126 if (ext > n) | |
127 { | |
128 this->resize1 (ext); | |
129 n = ext; | |
130 } | |
131 | |
132 octave_quit (); | |
133 | |
134 octave_idx_type len = std::min (idx.length (n), vals.length ()); | |
135 idx.loop (len, _idxbinop_helper<T, xmax> (this->fortran_vec (), vals.data ())); | |
136 } | |
137 | |
138 // N-dimensional array with math ops. | |
139 template <class T> | |
140 void | |
141 MArray<T>::changesign (void) | |
142 { | |
143 if (Array<T>::is_shared ()) | |
144 *this = - *this; | |
145 else | |
146 do_mx_inplace_op<MArray<T> > (*this, mx_inline_uminus2); | |
55 } | 147 } |
56 | 148 |
57 // Element by element MArray by scalar ops. | 149 // Element by element MArray by scalar ops. |
58 | 150 |
59 template <class T> | 151 template <class T> |
122 else | 214 else |
123 do_mm_inplace_op<MArray<T>, MArray<T> > (a, b, mx_inline_sub2, "-="); | 215 do_mm_inplace_op<MArray<T>, MArray<T> > (a, b, mx_inline_sub2, "-="); |
124 return a; | 216 return a; |
125 } | 217 } |
126 | 218 |
219 | |
127 template <class T> | 220 template <class T> |
128 MArray<T>& | 221 MArray<T>& |
129 product_eq (MArray<T>& a, const MArray<T>& b) | 222 product_eq (MArray<T>& a, const MArray<T>& b) |
130 { | 223 { |
131 if (a.is_shared ()) | 224 if (a.is_shared ()) |
146 return a; | 239 return a; |
147 } | 240 } |
148 | 241 |
149 // Element by element MArray by scalar ops. | 242 // Element by element MArray by scalar ops. |
150 | 243 |
151 #define MARRAY_AS_OP(OP, FN) \ | 244 #define MARRAY_NDS_OP(OP, FN) \ |
152 template <class T> \ | 245 template <class T> \ |
153 MArray<T> \ | 246 MArray<T> \ |
154 operator OP (const MArray<T>& a, const T& s) \ | 247 operator OP (const MArray<T>& a, const T& s) \ |
155 { \ | 248 { \ |
156 return do_ms_binary_op<MArray<T>, MArray<T>, T> (a, s, FN); \ | 249 return do_ms_binary_op<MArray<T>, MArray<T>, T> (a, s, FN); \ |
157 } | 250 } |
158 | 251 |
159 MARRAY_AS_OP (+, mx_inline_add) | 252 MARRAY_NDS_OP (+, mx_inline_add) |
160 MARRAY_AS_OP (-, mx_inline_sub) | 253 MARRAY_NDS_OP (-, mx_inline_sub) |
161 MARRAY_AS_OP (*, mx_inline_mul) | 254 MARRAY_NDS_OP (*, mx_inline_mul) |
162 MARRAY_AS_OP (/, mx_inline_div) | 255 MARRAY_NDS_OP (/, mx_inline_div) |
163 | 256 |
164 // Element by element scalar by MArray ops. | 257 // Element by element scalar by MArray ops. |
165 | 258 |
166 #define MARRAY_SA_OP(OP, FN) \ | 259 #define MARRAY_SND_OP(OP, FN) \ |
167 template <class T> \ | 260 template <class T> \ |
168 MArray<T> \ | 261 MArray<T> \ |
169 operator OP (const T& s, const MArray<T>& a) \ | 262 operator OP (const T& s, const MArray<T>& a) \ |
170 { \ | 263 { \ |
171 return do_sm_binary_op<MArray<T>, T, MArray<T> > (s, a, FN); \ | 264 return do_sm_binary_op<MArray<T>, T, MArray<T> > (s, a, FN); \ |
172 } | 265 } |
173 | 266 |
174 MARRAY_SA_OP(+, mx_inline_add) | 267 MARRAY_SND_OP (+, mx_inline_add) |
175 MARRAY_SA_OP(-, mx_inline_sub) | 268 MARRAY_SND_OP (-, mx_inline_sub) |
176 MARRAY_SA_OP(*, mx_inline_mul) | 269 MARRAY_SND_OP (*, mx_inline_mul) |
177 MARRAY_SA_OP(/, mx_inline_div) | 270 MARRAY_SND_OP (/, mx_inline_div) |
178 | 271 |
179 // Element by element MArray by MArray ops. | 272 // Element by element MArray by MArray ops. |
180 | 273 |
181 #define MARRAY_AA_OP(FCN, OP, FN) \ | 274 #define MARRAY_NDND_OP(FCN, OP, FN) \ |
182 template <class T> \ | 275 template <class T> \ |
183 MArray<T> \ | 276 MArray<T> \ |
184 FCN (const MArray<T>& a, const MArray<T>& b) \ | 277 FCN (const MArray<T>& a, const MArray<T>& b) \ |
185 { \ | 278 { \ |
186 return do_mm_binary_op<MArray<T>, MArray<T>, MArray<T> > (a, b, FN, #FCN); \ | 279 return do_mm_binary_op<MArray<T>, MArray<T>, MArray<T> > (a, b, FN, #FCN); \ |
187 } | 280 } |
188 | 281 |
189 MARRAY_AA_OP (operator +, +, mx_inline_add) | 282 MARRAY_NDND_OP (operator +, +, mx_inline_add) |
190 MARRAY_AA_OP (operator -, -, mx_inline_sub) | 283 MARRAY_NDND_OP (operator -, -, mx_inline_sub) |
191 MARRAY_AA_OP (product, *, mx_inline_mul) | 284 MARRAY_NDND_OP (product, *, mx_inline_mul) |
192 MARRAY_AA_OP (quotient, /, mx_inline_div) | 285 MARRAY_NDND_OP (quotient, /, mx_inline_div) |
193 | |
194 // Unary MArray ops. | |
195 | 286 |
196 template <class T> | 287 template <class T> |
197 MArray<T> | 288 MArray<T> |
198 operator + (const MArray<T>& a) | 289 operator + (const MArray<T>& a) |
199 { | 290 { |