00001
00015 #ifndef _DLRNUMERIC_BOXINTEGRATOR2D_H_
00016 #define _DLRNUMERIC_BOXINTEGRATOR2D_H_
00017
00018 #include <dlrNumeric/array2D.h>
00019 #include <dlrNumeric/index2D.h>
00020
00021
00022 namespace dlr {
00023
00024 namespace numeric {
00025
00038 template <class Type0, class Type1>
00039 class BoxIntegrator2D {
00040 public:
00041
00046 inline
00047 BoxIntegrator2D();
00048
00049
00060 explicit
00061 BoxIntegrator2D(const Array2D<Type0>& inputArray);
00062
00063
00077 template <class Functor>
00078 explicit
00079 BoxIntegrator2D(const Array2D<Type0>& inputArray, Functor functor);
00080
00081
00100 BoxIntegrator2D(const Array2D<Type0>& inputArray,
00101 const Index2D& corner0,
00102 const Index2D& corner1);
00103
00104
00114 BoxIntegrator2D(const BoxIntegrator2D& other);
00115
00116
00166 Type1
00167 getIntegral(const Index2D& corner0, const Index2D& corner1);
00168
00169
00199 Type1
00200 getIntegral(const Index2D& corner0, const Index2D& corner1, bool dummy);
00201
00202
00220 Type1
00221 getRawIntegral(size_t row, size_t column);
00222
00223
00234 Type1
00235 getRawIntegral(size_t index0);
00236
00237
00249 void
00250 setArray(const Array2D<Type0>& inputArray);
00251
00252
00268 template <class Functor>
00269 void
00270 setArray(const Array2D<Type0>& inputArray, Functor functor);
00271
00272
00291 void
00292 setArray(const Array2D<Type0>& inputArray,
00293 const Index2D& corner0,
00294 const Index2D& corner1);
00295
00296
00317 template <class Functor>
00318 void
00319 setArray(const Array2D<Type0>& inputArray,
00320 const Index2D& corner0,
00321 const Index2D& corner1,
00322 Functor functor);
00323
00324
00325 protected:
00326
00327
00344 template <class Functor>
00345 void
00346 fillCache(typename Array2D<Type0>::const_iterator inIter,
00347 int roiRows,
00348 int roiColumns,
00349 int inputArrayColumns,
00350 Functor functor);
00351
00352
00353 Array2D<Type1> m_cache;
00354 Index2D m_corner0;
00355 };
00356
00357
00358 }
00359
00360 }
00361
00362
00363
00364
00365
00366
00367
00368 #include <dlrCommon/functional.h>
00369
00370
00371 namespace dlr {
00372
00373 namespace numeric {
00374
00375
00376
00377
00378 template <class Type0, class Type1>
00379 BoxIntegrator2D<Type0, Type1>::
00380 BoxIntegrator2D()
00381 : m_cache(),
00382 m_corner0(0, 0)
00383 {
00384
00385 }
00386
00387
00388
00389
00390
00391 template <class Type0, class Type1>
00392 BoxIntegrator2D<Type0, Type1>::
00393 BoxIntegrator2D(const Array2D<Type0>& inputArray)
00394 : m_cache(),
00395 m_corner0(0, 0)
00396 {
00397 this->setArray(inputArray);
00398 }
00399
00400
00401
00402
00403
00404 template <class Type0, class Type1>
00405 template <class Functor>
00406 BoxIntegrator2D<Type0, Type1>::
00407 BoxIntegrator2D(const Array2D<Type0>& inputArray, Functor functor)
00408 : m_cache(),
00409 m_corner0(0, 0)
00410 {
00411 this->setArray(inputArray, functor);
00412 }
00413
00414
00415
00416
00417
00418 template <class Type0, class Type1>
00419 BoxIntegrator2D<Type0, Type1>::
00420 BoxIntegrator2D(const Array2D<Type0>& inputArray,
00421 const Index2D& corner0,
00422 const Index2D& corner1)
00423 : m_cache(),
00424 m_corner0(0, 0)
00425 {
00426 this->setArray(inputArray, corner0, corner1);
00427 }
00428
00429
00430
00431
00432
00433
00434 template <class Type0, class Type1>
00435 BoxIntegrator2D<Type0, Type1>::
00436 BoxIntegrator2D(const BoxIntegrator2D& other)
00437 : m_cache(other.m_cache),
00438 m_corner0(other.m_corner0)
00439 {
00440
00441 }
00442
00443
00444
00445
00446
00447 template <class Type0, class Type1>
00448 Type1
00449 BoxIntegrator2D<Type0, Type1>::
00450 getIntegral(const Index2D& corner0, const Index2D& corner1)
00451 {
00452 return (m_cache(corner1.getRow(), corner1.getColumn())
00453 - m_cache(corner1.getRow(), corner0.getColumn())
00454 - m_cache(corner0.getRow(), corner1.getColumn())
00455 + m_cache(corner0.getRow(), corner0.getColumn()));
00456 }
00457
00458
00459
00460
00461
00462
00463 template <class Type0, class Type1>
00464 Type1
00465 BoxIntegrator2D<Type0, Type1>::
00466 getIntegral(const Index2D& corner0, const Index2D& corner1, bool dummy)
00467 {
00468 int row0 = corner0.getRow() - m_corner0.getRow();
00469 int row1 = corner1.getRow() - m_corner0.getRow();
00470 int column0 = corner0.getColumn() - m_corner0.getColumn();
00471 int column1 = corner1.getColumn() - m_corner0.getColumn();
00472 return (m_cache(row1, column1)
00473 - m_cache(row1, column0)
00474 - m_cache(row0, column1)
00475 + m_cache(row0, column0));
00476 }
00477
00478
00479
00480
00481 template <class Type0, class Type1>
00482 Type1
00483 BoxIntegrator2D<Type0, Type1>::
00484 getRawIntegral(size_t row, size_t column)
00485 {
00486 return m_cache(row, column);
00487 }
00488
00489
00490
00491
00492 template <class Type0, class Type1>
00493 Type1
00494 BoxIntegrator2D<Type0, Type1>::
00495 getRawIntegral(size_t index0)
00496 {
00497 return m_cache(index0);
00498 }
00499
00500
00501
00502
00503
00504
00505 template <class Type0, class Type1>
00506 void
00507 BoxIntegrator2D<Type0, Type1>::
00508 setArray(const Array2D<Type0>& inputArray)
00509 {
00510 this->setArray(inputArray, common::StaticCastFunctor<Type0, Type1>());
00511 }
00512
00513
00514
00515
00516
00517
00518
00519 template <class Type0, class Type1>
00520 template <class Functor>
00521 void
00522 BoxIntegrator2D<Type0, Type1>::
00523 setArray(const Array2D<Type0>& inputArray, Functor functor)
00524 {
00525 m_corner0.setValue(0, 0);
00526 this->fillCache(
00527 inputArray.begin(), inputArray.rows(), inputArray.columns(),
00528 inputArray.columns(), functor);
00529 }
00530
00531
00532
00533
00534
00535 template <class Type0, class Type1>
00536 void
00537 BoxIntegrator2D<Type0, Type1>::
00538 setArray(const Array2D<Type0>& inputArray,
00539 const Index2D& corner0,
00540 const Index2D& corner1)
00541 {
00542 this->setArray(inputArray, corner0, corner1,
00543 common::StaticCastFunctor<Type0, Type1>());
00544 }
00545
00546
00547
00548
00549
00550
00551 template <class Type0, class Type1>
00552 template <class Functor>
00553 void
00554 BoxIntegrator2D<Type0, Type1>::
00555 setArray(const Array2D<Type0>& inputArray,
00556 const Index2D& corner0,
00557 const Index2D& corner1,
00558 Functor functor)
00559 {
00560 int row0 = corner0.getRow();
00561 int row1 = corner1.getRow();
00562 int column0 = corner0.getColumn();
00563 int column1 = corner1.getColumn();
00564 if(row1 < row0) {
00565 std::swap(row0, row1);
00566 }
00567 if(column1 < column0) {
00568 std::swap(column0, column1);
00569 }
00570
00571 int roiRows = row1 - row0;
00572 int roiColumns = column1 - column0;
00573
00574 m_corner0.setValue(row0, column0);
00575 this->fillCache(
00576 inputArray.begin() + (row0 * inputArray.columns() + column0),
00577 roiRows, roiColumns, inputArray.columns(), functor);
00578 }
00579
00580
00581
00582
00583
00584 template <class Type0, class Type1>
00585 template <class Functor>
00586 void
00587 BoxIntegrator2D<Type0, Type1>::
00588 fillCache(typename Array2D<Type0>::const_iterator inIter,
00589 int roiRows,
00590 int roiColumns,
00591 int inputArrayColumns,
00592 Functor functor)
00593 {
00594 int rowIncrement = inputArrayColumns - roiColumns;
00595 m_cache.reinit(roiRows + 1, roiColumns + 1);
00596
00597
00598
00599 std::fill(m_cache.rowBegin(0), m_cache.rowEnd(0),
00600 static_cast<Type1>(functor(0)));
00601
00602
00603 typename Array2D<Type0>::const_iterator endIter = inIter + roiColumns;
00604 typename Array2D<Type1>::iterator outIter =
00605 m_cache.begin() + m_cache.columns();
00606 *(outIter++) = static_cast<Type1>(functor(0));
00607 while(inIter != endIter) {
00608 *outIter = *(outIter - 1) + static_cast<Type1>(functor(*inIter));
00609 ++outIter;
00610 ++inIter;
00611 }
00612
00613
00614 typename Array2D<Type1>::iterator previousRowIter =
00615 m_cache.begin() + m_cache.columns();
00616 for(int row = 1; row < roiRows; ++row) {
00617 inIter += rowIncrement;
00618 Type1 rowSum = static_cast<Type1>(0);
00619 *(outIter++) = rowSum;
00620 ++previousRowIter;
00621 for(int column = 0; column < roiColumns; ++column) {
00622 rowSum += static_cast<Type1>(functor(*inIter));
00623 *outIter = rowSum + (*previousRowIter);
00624 ++inIter;
00625 ++outIter;
00626 ++previousRowIter;
00627 }
00628 }
00629 }
00630
00631
00632 }
00633
00634 }
00635
00636 #endif