comparison liboctave/mx-inlines.cc @ 5523:451ad352b288

[project @ 2005-10-31 03:18:21 by jwe]
author jwe
date Mon, 31 Oct 2005 03:18:22 +0000
parents b99404352541
children 79d833090bdc
comparison
equal deleted inserted replaced
5522:98691610b386 5523:451ad352b288
403 } \ 403 } \
404 } \ 404 } \
405 } \ 405 } \
406 else if (dim >= nd) \ 406 else if (dim >= nd) \
407 { \ 407 { \
408 /* One more than the number of dimensions will yield the same \
409 result as N more, so there is no point in creating an \
410 unnecesarily large dimension vector padded with ones. \
411 Remember that dim is in the range of 0:nd-1. */ \
412 \
413 dim = nd++; \ 408 dim = nd++; \
414 dv.resize (nd, 1); \ 409 dv.resize (nd, 1); \
415 } \ 410 } \
416 \ 411 \
417 /* The strategy here is to loop over all the elements once, \ 412 /* R = op (A, DIM) \
418 adjusting the index into the result array so that we do the right \ 413 \
419 thing with respect to the DIM argument. */ \ 414 The strategy here is to access the elements of A along the \
420 \ 415 dimension specified by DIM. This means that we loop over each \
421 octave_idx_type result_offset = 0; \ 416 element of R and adjust the index into A as needed. */ \
422 \ 417 \
423 Array<octave_idx_type> tsz (nd, 1); \ 418 Array<octave_idx_type> cp_sz (nd, 1); \
424 for (int i = 1; i < nd; i++) \ 419 for (int i = 1; i < nd; i++) \
425 tsz(i) = tsz(i-1)*dv(i-1); \ 420 cp_sz(i) = cp_sz(i-1)*dv(i-1); \
426 \ 421 \
427 octave_idx_type reset_at = tsz(dim); \ 422 octave_idx_type reset_at = cp_sz(dim); \
428 octave_idx_type offset_increment_ctr = 1; \ 423 octave_idx_type base_incr = cp_sz(dim+1); \
429 octave_idx_type result_ctr = 1; \ 424 octave_idx_type incr = cp_sz(dim); \
430 \ 425 octave_idx_type base = 0; \
431 octave_idx_type result_offset_increment_point = 1; \ 426 octave_idx_type next_base = base + base_incr; \
432 for (int i = 0; i <= dim; i++) \ 427 octave_idx_type iter_idx = base; \
433 result_offset_increment_point *= dv(i); \ 428 octave_idx_type n_elts = dv(dim); \
434 \
435 octave_idx_type result_offset_increment_amount = 1; \
436 for (int i = 0; i <= dim-1; i++) \
437 result_offset_increment_amount *= dv(i); \
438 \ 429 \
439 dv(dim) = 1; \ 430 dv(dim) = 1; \
440 \ 431 \
441 retval.resize (dv, INIT_VAL); \ 432 retval.resize (dv, INIT_VAL); \
442 \ 433 \
443 octave_idx_type result_idx = 0; \ 434 octave_idx_type nel = dv.numel (); \
444 \ 435 \
445 octave_idx_type num_iter = this->numel (); \ 436 octave_idx_type k = 1; \
446 \ 437 \
447 for (octave_idx_type iter_idx = 0; iter_idx < num_iter; iter_idx++) \ 438 for (octave_idx_type result_idx = 0; result_idx < nel; result_idx++) \
448 { \ 439 { \
449 EVAL_EXPR; \ 440 OCTAVE_QUIT;
450 \ 441 \
451 if (result_ctr == reset_at) \ 442 for (octave_idx_type j = 0; j < n_elts; j++) \
443 { \
444 OCTAVE_QUIT;
445 \
446 EVAL_EXPR; \
447 \
448 iter_idx += incr; \
449 } \
450 \
451 if (k == reset_at) \
452 { \ 452 { \
453 result_idx = result_offset; \ 453 base = next_base; \
454 result_ctr = 1; \ 454 next_base += base_incr; \
455 iter_idx = base; \
456 k = 1; \
455 } \ 457 } \
456 else \ 458 else \
457 { \ 459 { \
458 result_ctr++; \ 460 base++; \
459 result_idx++; \ 461 iter_idx = base; \
462 k++; \
460 } \ 463 } \
461 \
462 if (offset_increment_ctr == result_offset_increment_point) \
463 { \
464 result_offset += result_offset_increment_amount; \
465 result_idx = result_offset; \
466 offset_increment_ctr = 1; \
467 } \
468 else \
469 offset_increment_ctr++; \
470 } \ 464 } \
471 \ 465 \
472 retval.chop_trailing_singletons (); \ 466 retval.chop_trailing_singletons (); \
473 \ 467 \
474 return retval 468 return retval
480 MX_ND_REDUCTION (retval(result_idx) ASN_EXPR, INIT_VAL, ComplexNDArray) 474 MX_ND_REDUCTION (retval(result_idx) ASN_EXPR, INIT_VAL, ComplexNDArray)
481 475
482 #define MX_ND_ANY_ALL_REDUCTION(EVAL_EXPR, VAL) \ 476 #define MX_ND_ANY_ALL_REDUCTION(EVAL_EXPR, VAL) \
483 MX_ND_REDUCTION (EVAL_EXPR, VAL, boolNDArray) 477 MX_ND_REDUCTION (EVAL_EXPR, VAL, boolNDArray)
484 478
485 #define MX_ND_CUMULATIVE_OP(RET_TYPE, ACC_TYPE, VAL, OP) \ 479 #define MX_ND_CUMULATIVE_OP(RET_TYPE, ACC_TYPE, INIT_VAL, OP) \
480 \
486 RET_TYPE retval; \ 481 RET_TYPE retval; \
487 \ 482 \
488 dim_vector dv = this->dims (); \ 483 dim_vector dv = this->dims (); \
484 int nd = this->ndims (); \
489 \ 485 \
490 int empty = true; \ 486 int empty = true; \
491 \ 487 \
492 /* If dim is larger then number of dims, return array as is */ \ 488 for (int i = 0; i < nd; i++) \
493 if (dim >= dv.length ()) \
494 { \
495 retval = RET_TYPE (*this); \
496 return retval; \
497 } \
498 \
499 /* Check if all dims are empty */ \
500 for (int i = 0; i < dv.length (); i++) \
501 { \ 489 { \
502 if (dv(i) > 0) \ 490 if (dv(i) > 0) \
503 { \ 491 { \
504 empty = false; \ 492 empty = false; \
505 break; \ 493 break; \
506 } \ 494 } \
507 } \ 495 } \
508 \ 496 \
509 if (empty) \ 497 if (empty) \
510 { \ 498 { \
511 retval.resize (dv); \ 499 dim_vector retval_dv (1, 1); \
500 retval.resize (retval_dv, INIT_VAL); \
512 return retval; \ 501 return retval; \
513 } \ 502 } \
514 \ 503 \
515 /* We need to find first non-singleton dim */ \ 504 /* We need to find first non-singleton dim. */ \
505 \
516 if (dim == -1) \ 506 if (dim == -1) \
517 { \ 507 { \
518 for (int i = 0; i < dv.length (); i++) \ 508 dim = 0; \
509 \
510 for (int i = 0; i < nd; i++) \
519 { \ 511 { \
520 if (dv (i) != 1) \ 512 if (dv(i) != 1) \
521 { \ 513 { \
522 dim = i; \ 514 dim = i; \
523 break; \ 515 break; \
524 } \ 516 } \
525 } \ 517 } \
526 \ 518 } \
527 if (dim == -1) \ 519 else if (dim >= nd) \
528 dim = 0; \ 520 { \
529 } \ 521 dim = nd++; \
530 \ 522 dv.resize (nd, 1); \
531 /* Check to see if we have an empty array */ \ 523 } \
532 /* ie 1x2x0x3. */ \ 524 \
533 int squeezed = 0; \ 525 /* R = op (A, DIM) \
534 \ 526 \
535 for (int i = 0; i < dv.length (); i++) \ 527 The strategy here is to access the elements of A along the \
536 { \ 528 dimension specified by DIM. This means that we loop over each \
537 if (dv(i) == 0) \ 529 element of R and adjust the index into A as needed. */ \
530 \
531 Array<octave_idx_type> cp_sz (nd, 1); \
532 for (int i = 1; i < nd; i++) \
533 cp_sz(i) = cp_sz(i-1)*dv(i-1); \
534 \
535 octave_idx_type reset_at = cp_sz(dim); \
536 octave_idx_type base_incr = cp_sz(dim+1); \
537 octave_idx_type incr = cp_sz(dim); \
538 octave_idx_type base = 0; \
539 octave_idx_type next_base = base + base_incr; \
540 octave_idx_type iter_idx = base; \
541 octave_idx_type n_elts = dv(dim); \
542 \
543 retval.resize (dv, INIT_VAL); \
544 \
545 octave_idx_type nel = dv.numel () / n_elts; \
546 \
547 octave_idx_type k = 1; \
548 \
549 for (octave_idx_type i = 0; i < nel; i++) \
550 { \
551 OCTAVE_QUIT; \
552 \
553 ACC_TYPE prev_val = INIT_VAL; \
554 \
555 for (octave_idx_type j = 0; j < n_elts; j++) \
556 { \
557 OCTAVE_QUIT; \
558 \
559 if (j == 0) \
560 { \
561 retval(iter_idx) = elem (iter_idx); \
562 prev_val = retval(iter_idx); \
563 } \
564 else \
565 { \
566 prev_val = prev_val OP elem (iter_idx); \
567 retval(iter_idx) = prev_val; \
568 } \
569 \
570 iter_idx += incr; \
571 } \
572 \
573 if (k == reset_at) \
538 { \ 574 { \
539 squeezed = 1; \ 575 base = next_base; \
540 break; \ 576 next_base += base_incr; \
577 iter_idx = base; \
578 k = 1; \
541 } \ 579 } \
542 } \ 580 else \
543 \ 581 { \
544 if (squeezed) \ 582 base++; \
545 { \ 583 iter_idx = base; \
546 retval.resize (dv); \ 584 k++; \
547 return retval; \ 585 } \
548 } \ 586 } \
549 \ 587 \
550 /* Make sure retval has correct dimensions */ \ 588 retval.chop_trailing_singletons (); \
551 retval.resize (dv, VAL); \ 589 \
552 \
553 /* Length of Dimension */ \
554 octave_idx_type dim_length = 1; \
555 \
556 dim_length = dv (dim); \
557 \
558 dv (dim) = 1; \
559 \
560 /* This finds the number of elements in retval */ \
561 octave_idx_type num_iter = (this->numel () / dim_length); \
562 \
563 Array<octave_idx_type> iter_idx (dv.length (), 0); \
564 \
565 /* Filling in values. */ \
566 /* First loop finds new index */ \
567 \
568 for (octave_idx_type j = 0; j < num_iter; j++) \
569 { \
570 for (octave_idx_type i = 0; i < dim_length; i++) \
571 { \
572 if (i > 0) \
573 { \
574 iter_idx (dim) = i - 1; \
575 \
576 ACC_TYPE prev_sum = retval (iter_idx); \
577 \
578 iter_idx (dim) = i; \
579 \
580 retval (iter_idx) = elem (iter_idx) OP prev_sum; \
581 } \
582 else \
583 retval (iter_idx) = elem (iter_idx); \
584 } \
585 \
586 if (dim > -1) \
587 iter_idx (dim) = 0; \
588 \
589 increment_index (iter_idx, dv); \
590 } \
591 \
592 return retval 590 return retval
593 591
594 #endif 592 #endif
595 593
596 /* 594 /*