00001
00015 #ifndef DLR_NUMERIC_NORMALIZEDCORRELATOR_H
00016 #define DLR_NUMERIC_NORMALIZEDCORRELATOR_H
00017
00018 #include <cmath>
00019 #include <deque>
00020 #include <dlrNumeric/array2D.h>
00021
00022 namespace dlr {
00023
00024 namespace numeric {
00025
00026
00115 template <class Type>
00116 class NormalizedCorrelator
00117 {
00118 public:
00119
00129 NormalizedCorrelator(bool trackInput = false);
00130
00131
00161 template <class IterType0, class IterType1>
00162 NormalizedCorrelator(IterType0 begin0,
00163 IterType0 end0,
00164 IterType1 begin1,
00165 bool trackInput = false);
00166
00167
00172 ~NormalizedCorrelator();
00173
00174
00191 inline void
00192 addSample(Type sample0, Type sample1);
00193
00194
00210 inline void
00211 addSampleWithoutTracking(Type sample0, Type sample1);
00212
00213
00239 template <class IterType0, class IterType1>
00240 void
00241 addSamples(IterType0 begin0, IterType0 end0, IterType1 begin1);
00242
00243
00248 void
00249 clear();
00250
00251
00287 void
00288 enableInputTracking(bool trackInput = true);
00289
00290
00301 inline size_t
00302 getCount() const;
00303
00304
00313 Type
00314 getNormalizedCorrelation() const;
00315
00316
00325 inline bool
00326 isInputTrackingEnabled() const {return m_inputTracker0Ptr != 0;}
00327
00328
00341 void
00342 removeOldestSamples(size_t count);
00343
00344
00356 void
00357 removeSample(Type sample0, Type sample1);
00358
00359
00375 inline void
00376 removeSampleWithoutTracking(Type sample0, Type sample1);
00377
00378
00400 template <class IterType0, class IterType1>
00401 void
00402 removeSamples(IterType0 begin0, IterType0 end0, IterType1 begin1);
00403
00404 private:
00405
00406 size_t m_count;
00407 std::deque<Type>* m_inputTracker0Ptr;
00408 std::deque<Type>* m_inputTracker1Ptr;
00409 Type m_sum0;
00410 Type m_sum1;
00411 Type m_sum00;
00412 Type m_sum01;
00413 Type m_sum11;
00414
00415 };
00416
00417 }
00418
00419 }
00420
00421
00422
00423
00424 namespace dlr {
00425
00426 namespace numeric {
00427
00428
00429
00430 template <class Type>
00431 NormalizedCorrelator<Type>::
00432 NormalizedCorrelator(bool trackInput)
00433 : m_count(0),
00434 m_inputTracker0Ptr(0),
00435 m_inputTracker1Ptr(0),
00436 m_sum0(static_cast<Type>(0)),
00437 m_sum1(static_cast<Type>(0)),
00438 m_sum00(static_cast<Type>(0)),
00439 m_sum01(static_cast<Type>(0)),
00440 m_sum11(static_cast<Type>(0))
00441 {
00442 if(trackInput) {
00443 this->enableInputTracking();
00444 }
00445 }
00446
00447
00448
00449
00450
00451 template <class Type>
00452 template <class IterType0, class IterType1>
00453 NormalizedCorrelator<Type>::
00454 NormalizedCorrelator(IterType0 begin0, IterType0 end0, IterType1 begin1,
00455 bool trackInput)
00456 : m_count(0),
00457 m_inputTracker0Ptr(0),
00458 m_inputTracker1Ptr(0),
00459 m_sum0(static_cast<Type>(0)),
00460 m_sum1(static_cast<Type>(0)),
00461 m_sum00(static_cast<Type>(0)),
00462 m_sum01(static_cast<Type>(0)),
00463 m_sum11(static_cast<Type>(0))
00464 {
00465 if(trackInput) {
00466 this->enableInputTracking();
00467 }
00468 this->addSamples(begin0, end0, begin1);
00469 }
00470
00471
00472
00473
00474 template <class Type>
00475 NormalizedCorrelator<Type>::
00476 ~NormalizedCorrelator()
00477 {
00478 this->enableInputTracking(false);
00479 }
00480
00481
00482
00483
00484
00485 template <class Type>
00486 void
00487 NormalizedCorrelator<Type>::
00488 addSample(Type sample0, Type sample1)
00489 {
00490
00491 if(this->isInputTrackingEnabled()) {
00492 m_inputTracker0Ptr->push_back(sample0);
00493 m_inputTracker1Ptr->push_back(sample1);
00494 }
00495 this->addSampleWithoutTracking(sample0, sample1);
00496 }
00497
00498
00499
00500
00501 template <class Type>
00502 inline void
00503 NormalizedCorrelator<Type>::
00504 addSampleWithoutTracking(Type sample0, Type sample1)
00505 {
00506 m_sum0 += sample0;
00507 m_sum1 += sample1;
00508 m_sum00 += sample0 * sample0;
00509 m_sum01 += sample0 * sample1;
00510 m_sum11 += sample1 * sample1;
00511 ++m_count;
00512 }
00513
00514
00515
00516
00517
00518 template <class Type>
00519 template <class IterType0, class IterType1>
00520 void
00521 NormalizedCorrelator<Type>::
00522 addSamples(IterType0 begin0, IterType0 end0, IterType1 begin1)
00523 {
00524
00525 if(this->isInputTrackingEnabled()) {
00526 IterType0 begin0Copy = begin0;
00527 IterType1 begin1Copy = begin1;
00528 while(begin0Copy != end0) {
00529 m_inputTracker0Ptr->push_back(*begin0Copy);
00530 m_inputTracker1Ptr->push_back(*begin1Copy);
00531 ++begin0Copy;
00532 ++begin1Copy;
00533 }
00534 }
00535
00536
00537 while(begin0 != end0) {
00538 this->addSampleWithoutTracking(*begin0, *begin1);
00539 ++begin0;
00540 ++begin1;
00541 }
00542 }
00543
00544
00545
00546
00547 template <class Type>
00548 void
00549 NormalizedCorrelator<Type>::
00550 clear()
00551 {
00552 if(this->isInputTrackingEnabled) {
00553
00554
00555
00556
00557 this->enableInputTracking(true);
00558 }
00559 m_count = 0;
00560 m_sum0 = static_cast<Type>(0);
00561 m_sum1 = static_cast<Type>(0);
00562 m_sum00 = static_cast<Type>(0);
00563 m_sum01 = static_cast<Type>(0);
00564 m_sum11 = static_cast<Type>(0);
00565 }
00566
00567
00568
00569
00570
00571
00572 template <class Type>
00573 void
00574 NormalizedCorrelator<Type>::
00575 enableInputTracking(bool trackInput)
00576 {
00577 if(trackInput) {
00578 if(m_inputTracker0Ptr == 0) {
00579 m_inputTracker0Ptr = new std::deque<Type>;
00580 } else {
00581 m_inputTracker0Ptr->clear();
00582 }
00583 if(m_inputTracker1Ptr == 0) {
00584 m_inputTracker1Ptr = new std::deque<Type>;
00585 } else {
00586 m_inputTracker1Ptr->clear();
00587 }
00588 } else {
00589 if(m_inputTracker0Ptr != 0) {
00590 delete m_inputTracker0Ptr;
00591 m_inputTracker0Ptr = 0;
00592 }
00593 if(m_inputTracker1Ptr != 0) {
00594 delete m_inputTracker1Ptr;
00595 m_inputTracker1Ptr = 0;
00596 }
00597 }
00598 }
00599
00600
00601
00602
00603 template <class Type>
00604 inline size_t
00605 NormalizedCorrelator<Type>::
00606 getCount() const
00607 {
00608 return m_count;
00609 }
00610
00611
00612
00613
00614 template <class Type>
00615 Type
00616 NormalizedCorrelator<Type>::
00617 getNormalizedCorrelation() const
00618 {
00619 if(m_count == 0) {
00620 return static_cast<Type>(1);
00621 }
00622 Type oneOverN = static_cast<Type>(1) / static_cast<Type>(m_count);
00623 Type numerator = m_sum01 - oneOverN * m_sum0 * m_sum1;
00624 Type denominator = std::sqrt((m_sum00 - oneOverN * m_sum0 * m_sum0)
00625 * (m_sum11 - oneOverN * m_sum1 * m_sum1));
00626 return numerator / denominator;
00627 }
00628
00629
00630
00631
00632
00633 template <class Type>
00634 void
00635 NormalizedCorrelator<Type>::
00636 removeOldestSamples(size_t count)
00637 {
00638 if(!(this->isInputTrackingEnabled())) {
00639 DLR_THROW(LogicException,
00640 "NormalizedCorrelator::removeInputSamples()",
00641 "Attempt to call removeOldestSamples() method of a "
00642 "NormalizedCorrelator instance that does not have "
00643 "input tracking enabled.");
00644 }
00645 if(count > (m_inputTracker0Ptr->size())) {
00646 DLR_THROW(ValueException,
00647 "NormalizedCorrelator::removeInputSamples()",
00648 "Trying to remove more samples than have been added.");
00649 }
00650 while(count != 0) {
00651
00652
00653
00654 this->removeSampleWithoutTracking(m_inputTracker0Ptr->front(),
00655 m_inputTracker1Ptr->front());
00656 m_inputTracker0Ptr->pop_front();
00657 m_inputTracker1Ptr->pop_front();
00658 --count;
00659 }
00660 }
00661
00662
00663
00664
00665 template <class Type>
00666 void
00667 NormalizedCorrelator<Type>::
00668 removeSample(Type sample0, Type sample1)
00669 {
00670 if(this->isInputTrackingEnabled()) {
00671 DLR_THROW(NotImplementedException,
00672 "NormalizedCorrelator::removeSample()",
00673 "Currently, removeSample() can only be called if "
00674 "input tracking is not enabled.");
00675 }
00676 this->removeSampleWithoutTracking(sample0, sample1);
00677 }
00678
00679
00680
00681
00682 template <class Type>
00683 inline void
00684 NormalizedCorrelator<Type>::
00685 removeSampleWithoutTracking(Type sample0, Type sample1)
00686 {
00687 m_sum0 -= sample0;
00688 m_sum1 -= sample1;
00689 m_sum00 -= sample0 * sample0;
00690 m_sum01 -= sample0 * sample1;
00691 m_sum11 -= sample1 * sample1;
00692 --m_count;
00693 }
00694
00695
00696
00697
00698
00699
00700 template <class Type>
00701 template <class IterType0, class IterType1>
00702 void
00703 NormalizedCorrelator<Type>::
00704 removeSamples(IterType0 begin0, IterType0 end0, IterType1 begin1)
00705 {
00706 if(this->isInputTrackingEnabled()) {
00707 DLR_THROW(NotImplementedException,
00708 "NormalizedCorrelator::removeSamples()",
00709 "Currently, removeSamples() can only be called if "
00710 "input tracking is not enabled.");
00711 }
00712
00713 while(begin0 != end0) {
00714 this->removeSampleWithoutTracking(*begin0, *begin1);
00715 ++begin0;
00716 ++begin1;
00717 }
00718 }
00719
00720
00721 }
00722
00723 }
00724
00725 #endif