Mercurial > octave-nkf
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 ()); |