Mercurial > octave-nkf
comparison src/ov-base-mat.cc @ 8679:280fae940bb0
optimize scalar indexing
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Thu, 05 Feb 2009 13:58:11 +0100 |
parents | 1dce30ab0e72 |
children | c141078e083a |
comparison
equal
deleted
inserted
replaced
8678:e2b4c19c455c | 8679:280fae940bb0 |
---|---|
1 /* | 1 /* |
2 | 2 |
3 Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006, | 3 Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006, |
4 2007 John W. Eaton | 4 2007 John W. Eaton |
5 Copyright (C) 2009 VZLU Prague | |
5 | 6 |
6 This file is part of Octave. | 7 This file is part of Octave. |
7 | 8 |
8 Octave is free software; you can redistribute it and/or modify it | 9 Octave is free software; you can redistribute it and/or modify it |
9 under the terms of the GNU General Public License as published by the | 10 under the terms of the GNU General Public License as published by the |
145 case 1: | 146 case 1: |
146 { | 147 { |
147 idx_vector i = idx (0).index_vector (); | 148 idx_vector i = idx (0).index_vector (); |
148 | 149 |
149 if (! error_state) | 150 if (! error_state) |
150 retval = MT (matrix.index (i, resize_ok, MT::resize_fill_value ())); | 151 { |
152 // optimize single scalar index. | |
153 if (i.is_scalar () && i(0) < matrix.numel ()) | |
154 retval = const_cast<const MT&> (matrix)(i(0)); | |
155 else | |
156 retval = MT (matrix.index (i, resize_ok)); | |
157 } | |
158 } | |
159 break; | |
160 | |
161 case 2: | |
162 { | |
163 idx_vector i = idx (0).index_vector (); | |
164 | |
165 if (! error_state) | |
166 { | |
167 idx_vector j = idx (1).index_vector (); | |
168 | |
169 if (! error_state) | |
170 { | |
171 // optimize two scalar indices. | |
172 if (i.is_scalar () && j.is_scalar () && nd == 2 | |
173 && i(0) < matrix.rows () && j(0) < matrix.columns ()) | |
174 retval = const_cast<const MT&> (matrix)(i(0), j(0)); | |
175 else | |
176 retval = MT (matrix.index (i, j, resize_ok)); | |
177 } | |
178 } | |
151 } | 179 } |
152 break; | 180 break; |
153 | 181 |
154 default: | 182 default: |
155 { | 183 { |
156 if (n_idx == 2 && nd == 2) | 184 Array<idx_vector> idx_vec (n_idx); |
157 { | 185 bool scalar_opt = n_idx == nd; |
158 idx_vector i = idx (0).index_vector (); | 186 const dim_vector dv = matrix.dims (); |
159 | 187 |
160 if (! error_state) | 188 for (octave_idx_type i = 0; i < n_idx; i++) |
161 { | 189 { |
162 idx_vector j = idx (1).index_vector (); | 190 idx_vec(i) = idx(i).index_vector (); |
163 | 191 |
164 if (! error_state) | 192 if (error_state) |
165 retval = MT (matrix.index (i, j, resize_ok, | 193 break; |
166 MT::resize_fill_value ())); | 194 |
167 } | 195 scalar_opt = (scalar_opt && idx_vec(i).is_scalar () |
168 } | 196 && idx_vec(i)(0) < dv(0)); |
169 else | 197 } |
170 { | 198 |
171 Array<idx_vector> idx_vec (n_idx); | 199 if (! error_state) |
172 | 200 { |
173 for (octave_idx_type i = 0; i < n_idx; i++) | 201 if (scalar_opt) |
174 { | 202 { |
175 idx_vec(i) = idx(i).index_vector (); | 203 // optimize all scalar indices. Don't construct an index array, |
176 | 204 // but rather calc a scalar index directly. |
177 if (error_state) | 205 octave_idx_type k = 1, j = 0; |
178 break; | 206 for (octave_idx_type i = 0; i < n_idx; i++) |
179 } | 207 { |
180 | 208 j += i * k; |
181 if (! error_state) | 209 k *= dv (i); |
182 retval = MT (matrix.index (idx_vec, resize_ok, | 210 } |
183 MT::resize_fill_value ())); | 211 retval = const_cast<const MT&> (matrix)(j); |
184 } | 212 } |
213 else | |
214 retval = MT (matrix.index (idx_vec, resize_ok)); | |
215 } | |
185 } | 216 } |
186 break; | 217 break; |
187 } | 218 } |
188 | 219 |
189 return retval; | 220 return retval; |
191 | 222 |
192 template <class MT> | 223 template <class MT> |
193 void | 224 void |
194 octave_base_matrix<MT>::assign (const octave_value_list& idx, const MT& rhs) | 225 octave_base_matrix<MT>::assign (const octave_value_list& idx, const MT& rhs) |
195 { | 226 { |
196 octave_idx_type len = idx.length (); | 227 octave_idx_type n_idx = idx.length (); |
197 | 228 |
198 Array<idx_vector> ra_idx (len); | 229 switch (n_idx) |
199 | 230 { |
200 for (octave_idx_type i = 0; i < len; i++) | 231 case 0: |
201 ra_idx(i) = idx(i).index_vector (); | 232 panic_impossible (); |
202 | 233 break; |
203 matrix.assign (ra_idx, rhs, MT::resize_fill_value ()); | 234 |
235 case 1: | |
236 { | |
237 idx_vector i = idx (0).index_vector (); | |
238 | |
239 if (! error_state) | |
240 matrix.assign (i, rhs); | |
241 } | |
242 break; | |
243 | |
244 case 2: | |
245 { | |
246 idx_vector i = idx (0).index_vector (); | |
247 | |
248 if (! error_state) | |
249 { | |
250 idx_vector j = idx (1).index_vector (); | |
251 | |
252 if (! error_state) | |
253 matrix.assign (i, j, rhs); | |
254 } | |
255 } | |
256 break; | |
257 | |
258 default: | |
259 { | |
260 Array<idx_vector> idx_vec (n_idx); | |
261 | |
262 for (octave_idx_type i = 0; i < n_idx; i++) | |
263 { | |
264 idx_vec(i) = idx(i).index_vector (); | |
265 | |
266 if (error_state) | |
267 break; | |
268 } | |
269 | |
270 if (! error_state) | |
271 matrix.assign (idx_vec, rhs); | |
272 } | |
273 break; | |
274 } | |
275 | |
276 // Invalidate the matrix type | |
277 typ.invalidate_type (); | |
278 } | |
279 | |
280 template <class MT> | |
281 void | |
282 octave_base_matrix<MT>::assign (const octave_value_list& idx, | |
283 typename MT::element_type rhs) | |
284 { | |
285 octave_idx_type n_idx = idx.length (); | |
286 | |
287 int nd = matrix.ndims (); | |
288 | |
289 MT mrhs (dim_vector (1), rhs); | |
290 | |
291 switch (n_idx) | |
292 { | |
293 case 0: | |
294 panic_impossible (); | |
295 break; | |
296 | |
297 case 1: | |
298 { | |
299 idx_vector i = idx (0).index_vector (); | |
300 | |
301 if (! error_state) | |
302 { | |
303 // optimize single scalar index. | |
304 if (i.is_scalar () && i(0) < matrix.numel ()) | |
305 matrix(i(0)) = rhs; | |
306 else | |
307 matrix.assign (i, mrhs); | |
308 } | |
309 } | |
310 break; | |
311 | |
312 case 2: | |
313 { | |
314 idx_vector i = idx (0).index_vector (); | |
315 | |
316 if (! error_state) | |
317 { | |
318 idx_vector j = idx (1).index_vector (); | |
319 | |
320 if (! error_state) | |
321 { | |
322 // optimize two scalar indices. | |
323 if (i.is_scalar () && j.is_scalar () && nd == 2 | |
324 && i(0) < matrix.rows () && j(0) < matrix.columns ()) | |
325 matrix(i(0), j(0)) = rhs; | |
326 else | |
327 matrix.assign (i, j, mrhs); | |
328 } | |
329 } | |
330 } | |
331 break; | |
332 | |
333 default: | |
334 { | |
335 Array<idx_vector> idx_vec (n_idx); | |
336 bool scalar_opt = n_idx == nd; | |
337 const dim_vector dv = matrix.dims (); | |
338 | |
339 for (octave_idx_type i = 0; i < n_idx; i++) | |
340 { | |
341 idx_vec(i) = idx(i).index_vector (); | |
342 | |
343 if (error_state) | |
344 break; | |
345 | |
346 scalar_opt = (scalar_opt && idx_vec(i).is_scalar () | |
347 && idx_vec(i)(0) < dv(0)); | |
348 } | |
349 | |
350 if (! error_state) | |
351 { | |
352 if (scalar_opt) | |
353 { | |
354 // optimize all scalar indices. Don't construct an index array, | |
355 // but rather calc a scalar index directly. | |
356 octave_idx_type k = 1, j = 0; | |
357 for (octave_idx_type i = 0; i < n_idx; i++) | |
358 { | |
359 j += i * k; | |
360 k *= dv (i); | |
361 } | |
362 matrix(k) = rhs; | |
363 } | |
364 else | |
365 matrix.assign (idx_vec, mrhs); | |
366 } | |
367 } | |
368 break; | |
369 } | |
204 | 370 |
205 // Invalidate the matrix type | 371 // Invalidate the matrix type |
206 typ.invalidate_type (); | 372 typ.invalidate_type (); |
207 } | 373 } |
208 | 374 |