comparison src/pt-eval.cc @ 8662:af72c8137d64

improve looping over arrays
author Jaroslav Hajek <highegg@gmail.com>
date Wed, 04 Feb 2009 13:53:57 +0100
parents 73c4516fae10
children 33783e94fb16
comparison
equal deleted inserted replaced
8661:9c092b111b1d 8662:af72c8137d64
256 \ 256 \
257 quit = quit_loop_now (); \ 257 quit = quit_loop_now (); \
258 } \ 258 } \
259 while (0) 259 while (0)
260 260
261 #define DO_ND_LOOP(MTYPE, TYPE, CONV, ARG) \
262 do \
263 { \
264 dim_vector dv = ARG.dims (); \
265 \
266 bool quit = false; \
267 \
268 TYPE *atmp = ARG.fortran_vec (); \
269 \
270 octave_idx_type steps = dv(1); \
271 \
272 octave_idx_type nrows = dv(0); \
273 \
274 int ndims = dv.length (); \
275 if (ndims > 2) \
276 { \
277 for (int i = 2; i < ndims; i++) \
278 steps *= dv(i); \
279 dv(1) = steps; \
280 dv.resize (2); \
281 } \
282 \
283 if (steps > 0) \
284 { \
285 if (nrows == 0) \
286 { \
287 MTYPE tarray (dim_vector (0, 1)); \
288 \
289 octave_value val (tarray); \
290 \
291 for (octave_idx_type i = 0; i < steps; i++) \
292 { \
293 DO_SIMPLE_FOR_LOOP_ONCE (val); \
294 \
295 if (quit) \
296 break; \
297 } \
298 } \
299 else if (nrows == 1) \
300 { \
301 for (octave_idx_type i = 0; i < steps; i++) \
302 { \
303 octave_value val (CONV (*atmp++)); \
304 \
305 DO_SIMPLE_FOR_LOOP_ONCE (val); \
306 \
307 if (quit) \
308 break; \
309 } \
310 } \
311 else \
312 { \
313 if (ndims > 2) \
314 ARG = ARG.reshape (dv); \
315 \
316 MTYPE tmp (dim_vector (nrows, 1)); \
317 \
318 TYPE *ftmp = tmp.fortran_vec (); \
319 \
320 for (octave_idx_type i = 0; i < steps; i++) \
321 { \
322 for (int j = 0; j < nrows; j++) \
323 ftmp[j] = *atmp++; \
324 \
325 octave_value val (tmp); \
326 \
327 DO_SIMPLE_FOR_LOOP_ONCE (val); \
328 quit = (i == steps - 1 ? true : quit); \
329 \
330 if (quit) \
331 break; \
332 } \
333 } \
334 } \
335 } \
336 while (0)
337
338 void 261 void
339 tree_evaluator::visit_simple_for_command (tree_simple_for_command& cmd) 262 tree_evaluator::visit_simple_for_command (tree_simple_for_command& cmd)
340 { 263 {
341 if (error_state) 264 if (error_state)
342 return; 265 return;
396 { 319 {
397 bool quit = false; 320 bool quit = false;
398 321
399 DO_SIMPLE_FOR_LOOP_ONCE (rhs); 322 DO_SIMPLE_FOR_LOOP_ONCE (rhs);
400 } 323 }
401 else if (rhs.is_string ()) 324 else if (rhs.is_matrix_type ()
325 || rhs.is_cell () || rhs.is_string ())
402 { 326 {
403 charMatrix chm_tmp = rhs.char_matrix_value (); 327 // A matrix or cell is reshaped to 2 dimensions and iterated by
404 octave_idx_type nr = chm_tmp.rows (); 328 // columns.
405 octave_idx_type steps = chm_tmp.columns (); 329
406 bool quit = false; 330 bool quit = false;
407 331
408 if (error_state) 332 dim_vector dv = rhs.dims ().redim (2);
409 goto cleanup; 333
410 334 octave_idx_type steps = dv(1);
411 if (nr == 1) 335
412 { 336 if (steps > 0)
413 for (octave_idx_type i = 0; i < steps; i++) 337 {
414 { 338 octave_value arg = rhs;
415 octave_value val (chm_tmp.xelem (0, i)); 339 if (rhs.ndims () > 2)
416 340 arg = arg.reshape (dv);
417 DO_SIMPLE_FOR_LOOP_ONCE (val); 341
418 342 //octave_value_list idx(2, octave_value ());
419 if (quit) 343 octave_value_list idx(2, octave_value ());
420 break; 344 idx(0) = octave_value::magic_colon_t;
421 } 345
422 } 346 for (octave_idx_type i = 1; i <= steps; i++)
423 else 347 {
424 { 348 // do_index_op expects one-based indices.
425 for (octave_idx_type i = 0; i < steps; i++) 349 idx(1) = i;
426 { 350 octave_value val = arg.do_index_op (idx);
427 octave_value val (chm_tmp.extract (0, i, nr-1, i), true); 351 DO_SIMPLE_FOR_LOOP_ONCE (val);
428 352
429 DO_SIMPLE_FOR_LOOP_ONCE (val); 353 if (quit)
430 354 break;
431 if (quit) 355 }
432 break; 356 }
433 }
434 }
435 }
436 else if (rhs.is_matrix_type ())
437 {
438 if (rhs.is_real_type ())
439 {
440 NDArray m_tmp = rhs.array_value ();
441
442 if (error_state)
443 goto cleanup;
444
445 DO_ND_LOOP (NDArray, double, , m_tmp);
446 }
447 else
448 {
449 ComplexNDArray cm_tmp = rhs.complex_array_value ();
450
451 if (error_state)
452 goto cleanup;
453
454 DO_ND_LOOP (ComplexNDArray, Complex, , cm_tmp);
455 }
456 } 357 }
457 else if (rhs.is_map ()) 358 else if (rhs.is_map ())
458 { 359 {
459 Octave_map tmp_val (rhs.map_value ()); 360 Octave_map tmp_val (rhs.map_value ());
460 361
472 DO_SIMPLE_FOR_LOOP_ONCE (val); 373 DO_SIMPLE_FOR_LOOP_ONCE (val);
473 374
474 if (quit) 375 if (quit)
475 break; 376 break;
476 } 377 }
477 }
478 else if (rhs.is_cell ())
479 {
480 Cell c_tmp = rhs.cell_value ();
481
482 DO_ND_LOOP (Cell, octave_value, Cell, c_tmp);
483 } 378 }
484 else 379 else
485 { 380 {
486 ::error ("invalid type in for loop expression near line %d, column %d", 381 ::error ("invalid type in for loop expression near line %d, column %d",
487 cmd.line (), cmd.column ()); 382 cmd.line (), cmd.column ());