Mercurial > octave-nkf
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 /* |