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
00214 void
00215 setArray(const Array2D<Type0>& inputArray);
00216
00217
00233 template <class Functor>
00234 void
00235 setArray(const Array2D<Type0>& inputArray, Functor functor);
00236
00237
00256 void
00257 setArray(const Array2D<Type0>& inputArray,
00258 const Index2D& corner0,
00259 const Index2D& corner1);
00260
00261
00282 template <class Functor>
00283 void
00284 setArray(const Array2D<Type0>& inputArray,
00285 const Index2D& corner0,
00286 const Index2D& corner1,
00287 Functor functor);
00288
00289
00290 protected:
00291
00292
00309 template <class Functor>
00310 void
00311 fillCache(typename Array2D<Type0>::const_iterator inIter,
00312 int roiRows,
00313 int roiColumns,
00314 int inputArrayColumns,
00315 Functor functor);
00316
00317
00318 Array2D<Type1> m_cache;
00319 Index2D m_corner0;
00320 };
00321
00322
00323 }
00324
00325 }
00326
00327
00328
00329
00330
00331
00332
00333 #include <dlrCommon/functional.h>
00334
00335
00336 namespace dlr {
00337
00338 namespace numeric {
00339
00340
00341
00342
00343 template <class Type0, class Type1>
00344 BoxIntegrator2D<Type0, Type1>::
00345 BoxIntegrator2D()
00346 : m_cache(),
00347 m_corner0(0, 0)
00348 {
00349
00350 }
00351
00352
00353
00354
00355
00356 template <class Type0, class Type1>
00357 BoxIntegrator2D<Type0, Type1>::
00358 BoxIntegrator2D(const Array2D<Type0>& inputArray)
00359 : m_cache(),
00360 m_corner0(0, 0)
00361 {
00362 this->setArray(inputArray);
00363 }
00364
00365
00366
00367
00368
00369 template <class Type0, class Type1>
00370 BoxIntegrator2D<Type0, Type1>::
00371 BoxIntegrator2D(const Array2D<Type0>& inputArray,
00372 const Index2D& corner0,
00373 const Index2D& corner1)
00374 : m_cache(),
00375 m_corner0(0, 0)
00376 {
00377 this->setArray(inputArray, corner0, corner1);
00378 }
00379
00380
00381
00382
00383
00384
00385 template <class Type0, class Type1>
00386 BoxIntegrator2D<Type0, Type1>::
00387 BoxIntegrator2D(const BoxIntegrator2D& other)
00388 : m_cache(other.m_cache),
00389 m_corner0(other.m_corner0)
00390 {
00391
00392 }
00393
00394
00395
00396
00397
00398 template <class Type0, class Type1>
00399 Type1
00400 BoxIntegrator2D<Type0, Type1>::
00401 getIntegral(const Index2D& corner0, const Index2D& corner1)
00402 {
00403 return (m_cache(corner1.getRow(), corner1.getColumn())
00404 - m_cache(corner1.getRow(), corner0.getColumn())
00405 - m_cache(corner0.getRow(), corner1.getColumn())
00406 + m_cache(corner0.getRow(), corner0.getColumn()));
00407 }
00408
00409
00410
00411
00412
00413
00414 template <class Type0, class Type1>
00415 Type1
00416 BoxIntegrator2D<Type0, Type1>::
00417 getIntegral(const Index2D& corner0, const Index2D& corner1, bool dummy)
00418 {
00419 int row0 = corner0.getRow() - m_corner0.getRow();
00420 int row1 = corner1.getRow() - m_corner0.getRow();
00421 int column0 = corner0.getColumn() - m_corner0.getColumn();
00422 int column1 = corner1.getColumn() - m_corner0.getColumn();
00423 return (m_cache(row1, column1)
00424 - m_cache(row1, column0)
00425 - m_cache(row0, column1)
00426 + m_cache(row0, column0));
00427 }
00428
00429
00430
00431
00432
00433
00434 template <class Type0, class Type1>
00435 void
00436 BoxIntegrator2D<Type0, Type1>::
00437 setArray(const Array2D<Type0>& inputArray)
00438 {
00439 this->setArray(inputArray, common::StaticCastFunctor<Type0, Type1>());
00440 }
00441
00442
00443
00444
00445
00446
00447
00448 template <class Type0, class Type1>
00449 template <class Functor>
00450 void
00451 BoxIntegrator2D<Type0, Type1>::
00452 setArray(const Array2D<Type0>& inputArray, Functor functor)
00453 {
00454 m_corner0.setValue(0, 0);
00455 this->fillCache(
00456 inputArray.begin(), inputArray.rows(), inputArray.columns(),
00457 inputArray.columns(), functor);
00458 }
00459
00460
00461
00462
00463
00464 template <class Type0, class Type1>
00465 void
00466 BoxIntegrator2D<Type0, Type1>::
00467 setArray(const Array2D<Type0>& inputArray,
00468 const Index2D& corner0,
00469 const Index2D& corner1)
00470 {
00471 this->setArray(inputArray, corner0, corner1,
00472 common::StaticCastFunctor<Type0, Type1>());
00473 }
00474
00475
00476
00477
00478
00479
00480 template <class Type0, class Type1>
00481 template <class Functor>
00482 void
00483 BoxIntegrator2D<Type0, Type1>::
00484 setArray(const Array2D<Type0>& inputArray,
00485 const Index2D& corner0,
00486 const Index2D& corner1,
00487 Functor functor)
00488 {
00489 int row0 = corner0.getRow();
00490 int row1 = corner1.getRow();
00491 int column0 = corner0.getColumn();
00492 int column1 = corner1.getColumn();
00493 if(row1 < row0) {
00494 std::swap(row0, row1);
00495 }
00496 if(column1 < column0) {
00497 std::swap(column0, column1);
00498 }
00499
00500 int roiRows = row1 - row0;
00501 int roiColumns = column1 - column0;
00502
00503 m_corner0.setValue(row0, column0);
00504 this->fillCache(
00505 inputArray.begin() + (row0 * inputArray.columns() + column0),
00506 roiRows, roiColumns, inputArray.columns(), functor);
00507 }
00508
00509
00510
00511
00512
00513 template <class Type0, class Type1>
00514 template <class Functor>
00515 void
00516 BoxIntegrator2D<Type0, Type1>::
00517 fillCache(typename Array2D<Type0>::const_iterator inIter,
00518 int roiRows,
00519 int roiColumns,
00520 int inputArrayColumns,
00521 Functor functor)
00522 {
00523 int rowIncrement = inputArrayColumns - roiColumns;
00524 m_cache.reinit(roiRows + 1, roiColumns + 1);
00525
00526
00527
00528 std::fill(m_cache.rowBegin(0), m_cache.rowEnd(0),
00529 static_cast<Type1>(functor(0)));
00530
00531
00532 typename Array2D<Type0>::const_iterator endIter = inIter + roiColumns;
00533 typename Array2D<Type1>::iterator outIter =
00534 m_cache.begin() + m_cache.columns();
00535 *(outIter++) = static_cast<Type1>(functor(0));
00536 while(inIter != endIter) {
00537 *outIter = *(outIter - 1) + static_cast<Type1>(functor(*inIter));
00538 ++outIter;
00539 ++inIter;
00540 }
00541
00542
00543 typename Array2D<Type1>::iterator previousRowIter =
00544 m_cache.begin() + m_cache.columns();
00545 for(int row = 1; row < roiRows; ++row) {
00546 inIter += rowIncrement;
00547 Type1 rowSum = static_cast<Type1>(0);
00548 *(outIter++) = rowSum;
00549 ++previousRowIter;
00550 for(int column = 0; column < roiColumns; ++column) {
00551 rowSum += static_cast<Type1>(functor(*inIter));
00552 *outIter = rowSum + (*previousRowIter);
00553 ++inIter;
00554 ++outIter;
00555 ++previousRowIter;
00556 }
00557 }
00558 }
00559
00560
00561 }
00562
00563 }
00564
00565 #endif