cisst-saw
Loading...
Searching...
No Matches
nmrLinearRegression.h
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3
4/*
5 Author(s): Peter Kazanzides
6 Created on: 2016-04-29
7
8 (C) Copyright 2016 Johns Hopkins University (JHU), All Rights Reserved.
9
10--- begin cisst license - do not edit ---
11
12This software is provided "as is" under an open source license, with
13no warranty. The complete license can be found in license.txt and
14http://www.cisst.org/cisst/license.txt.
15
16--- end cisst license ---
17
18*/
19
20
25
26#pragma once
27
28#ifndef _nmrLinearRegression_h
29#define _nmrLinearRegression_h
30
31#include <vector>
36
37// Always the last file to include!
38// (Not really needed since everything is templated)
40
108
109template <class _elementType>
111{
112public:
113 typedef _elementType ElementType;
115
120 : numpts(0), Sx(0), Sy(0), Sxx(0), Sxy(0), Syy(0), tolerance(tol) {}
122
124 size_t NumPoints() const { return numpts; }
125
127 _elementType GetTolerance() const { return tolerance; }
128
130 void SetTolerance(_elementType tol) { tolerance = tol; }
131
133 virtual void Clear()
134 { numpts = 0; Sx = Sy = Sxx = Sxy = Syy = 0; }
135
138 virtual bool Sample(const _elementType &x, const _elementType &y);
139
142 { return Sample(in.X(), in.Y()); }
143
146 { return Sample(in.X(), in.Y()); }
147
153
157
160 virtual bool Sample(const std::vector<_elementType> &x, const std::vector<_elementType> &y)
161 {
162 // C++11 introduces std::vector::data, which would allow x.data() instead of &x.front()
163 return SampleVector(vctDynamicConstVectorRef<_elementType>(x.size(), &x.front()),
164 vctDynamicConstVectorRef<_elementType>(y.size(), &y.front()));
165 }
166
172 virtual bool EstimateAsFractions(SummationType &slope_num, SummationType &yint_num,
173 SummationType &denom, SummationType *tse_num = 0);
174
177 virtual bool Estimate(_elementType &slope, _elementType &yint, _elementType *mse = 0);
178
179protected:
180 size_t numpts; // Number of data points
181 SummationType Sx, Sy; // Sums of X and Y values
182 SummationType Sxx, Sxy, Syy; // Sums of X*X, X*Y, and Y*Y
183 SummationType tolerance; // Tolerance for avoiding divide by 0
184
186 virtual bool ComputeSums(const _elementType &x, const _elementType &y);
187
190 template <class _vectorOwnerType>
193 {
194 if (x.size() != y.size()) return false;
195 numpts += x.size();
196 Sx += x.SumOfElements();
197 Sy += y.SumOfElements();
198 Sxx += x.DotProduct(x);
199 Syy += y.DotProduct(y);
200 Sxy += x.DotProduct(y);
201 return true;
202 }
203
204};
205
206template <class _elementType>
207bool nmrLinearRegressionSolver<_elementType>::ComputeSums(const _elementType &x, const _elementType &y)
208{
209 Sx += x;
210 Sy += y;
211 Sxx += x*x;
212 Sxy += x*y;
213 Syy += y*y;
214 return true;
215}
216
217template <class _elementType>
218bool nmrLinearRegressionSolver<_elementType>::Sample(const _elementType &x, const _elementType &y)
219{
220 // ComputeSums always returns true, but in future could check for overflow
221 bool ret = ComputeSums(x,y);
222 if (ret) numpts++;
223 return ret;
224}
225
226template <class _elementType>
228 SummationType &yint_num, SummationType &denom,
229 SummationType *tse_num)
230{
231 denom = static_cast<SummationType>(numpts)*Sxx - Sx*Sx;
232 slope_num = static_cast<SummationType>(numpts)*Sxy - Sx*Sy;
233 yint_num = Sxx*Sy - Sx*Sxy;
234 // Terms in equation for tse_num are grouped to try to reduce likelihood of fixed point overflow
235 if (tse_num)
236 *tse_num = (Syy*denom - static_cast<SummationType>(numpts)*Sxy*Sxy) - Sy*(yint_num - Sx*Sxy);
237 return true;
238}
239
240template <class _elementType>
241bool nmrLinearRegressionSolver<_elementType>::Estimate(_elementType &slope, _elementType &yint,
242 _elementType *mse)
243{
244 SummationType slope_num, yint_num, denom, tse_num;
245 EstimateAsFractions(slope_num, yint_num, denom, &tse_num);
246
247 // Following check is to avoid division by 0 or by very small number.
248 // Note that for fixed point numbers, the default tolerance is 0 so we
249 // also check whether we are equal to the tolerance.
250 if ((denom >= -tolerance) && (denom <= tolerance))
251 return false;
252
253 slope = static_cast<_elementType>(slope_num/denom);
254 yint = static_cast<_elementType>(yint_num/denom);
255 if (mse)
256 *mse = static_cast<_elementType>(tse_num/(denom*static_cast<SummationType>(numpts)));
257 return true;
258}
259
279
280template <class _vectorType>
281bool nmrLinearRegression(const _vectorType &x, const _vectorType &y,
282 typename _vectorType::value_type &slope, typename _vectorType::value_type &yint,
283 typename _vectorType::value_type *mse = 0,
284 typename _vectorType::value_type tolerance = cmnTypeTraits<typename _vectorType::value_type>::DefaultTolerance)
285{
287 bool ret = solver.Sample(x,y);
288 if (ret)
289 ret = solver.Estimate(slope, yint, mse);
290 return ret;
291}
292
303
304template <class _elementType>
306{
307protected:
310 typedef typename std::vector<vctFixedSizeVector<_elementType, 2> > WindowType;
311 typedef typename std::vector<vctFixedSizeVector<_elementType, 2> >::iterator WindowTypeIterator;
314public:
316 { iter = window.begin(); }
318
319 virtual size_t WindowLength() const { return window.size(); }
320
321 bool Sample(const _elementType &x, const _elementType &y)
322 {
323 // Update the window
325 if (iter == window.end())
326 iter = window.begin();
327 // Increment numpts up to size of window
328 if (this->numpts < window.size())
329 this->numpts++;
330 return true;
331 }
332
333 // The methods that take vector inputs are not currently implemented, as they
334 // are less likely to be useful with a moving window.
337 { return false; }
341 bool Sample(const std::vector<_elementType> & CMN_UNUSED(x),
342 const std::vector<_elementType> & CMN_UNUSED(y))
343 { return false; }
344
346 virtual bool Recalculate()
347 {
348 size_t num = this->numpts;
350 for (size_t i = 0; i < num; i++)
352 this->numpts = num;
353 return true;
354 }
355
357 SummationType &denom, SummationType *tse_num = 0)
358 {
359 Recalculate();
360 return BaseClass::EstimateAsFractions(slope_num, yint_num, denom, tse_num);
361 }
362
363};
364
375
376template <class _elementType>
378{
380 typedef typename BaseClass::SummationType SummationType;
381 typedef typename BaseClass::ElementType ElementType;
382
383public:
384 nmrLinearRegressionWindowRecursiveSolver(size_t length) : BaseClass(length) {}
386
388 bool Sample(const _elementType &x, const _elementType &y)
389 {
390 if (this->numpts >= this->window.size()) {
391 // First, remove the oldest sample
392 ElementType old_x = this->iter->X();
393 ElementType old_y = this->iter->Y();
394 this->Sx -= old_x;
395 this->Sy -= old_y;
396 this->Sxx -= old_x*old_x;
397 this->Sxy -= old_x*old_y;
398 this->Syy -= old_y*old_y;
399 }
400 // Add the new value
401 bool ret = BaseClass::ComputeSums(x,y);
402 // Update the window (and increment numpts if needed)
403 if (ret)
404 ret = BaseClass::Sample(x,y);
405 return ret;
406 }
407
409 bool EstimateAsFractions(SummationType &slope_num, SummationType &yint_num,
410 SummationType &denom, SummationType *tse_num = 0)
411 {
412 return nmrLinearRegressionSolver<_elementType>::EstimateAsFractions(slope_num, yint_num, denom, tse_num);
413 }
414
415};
416
417#endif
cmnVaArgPromotion< _elementType >::Type VaArgPromotion
Definition cmnTypeTraits.h:167
static CISST_EXPORT const Type DefaultTolerance
Definition cmnTypeTraits.h:250
Definition nmrLinearRegression.h:111
SummationType Syy
Definition nmrLinearRegression.h:182
cmnTypeTraits< _elementType >::VaArgPromotion SummationType
Definition nmrLinearRegression.h:114
SummationType Sxy
Definition nmrLinearRegression.h:182
void SetTolerance(_elementType tol)
Definition nmrLinearRegression.h:130
SummationType Sx
Definition nmrLinearRegression.h:181
virtual bool Sample(const vctFixedSizeVector< _elementType, 2 > &in)
Definition nmrLinearRegression.h:141
bool SampleVector(const vctDynamicConstVectorBase< _vectorOwnerType, _elementType > &x, const vctDynamicConstVectorBase< _vectorOwnerType, _elementType > &y)
Definition nmrLinearRegression.h:191
SummationType Sxx
Definition nmrLinearRegression.h:182
nmrLinearRegressionSolver(_elementType tol=cmnTypeTraits< _elementType >::DefaultTolerance)
Definition nmrLinearRegression.h:119
SummationType Sy
Definition nmrLinearRegression.h:181
virtual bool ComputeSums(const _elementType &x, const _elementType &y)
Definition nmrLinearRegression.h:207
virtual bool Sample(const vctFixedSizeConstVectorRef< _elementType, 2, 1 > &in)
Definition nmrLinearRegression.h:145
virtual bool Sample(const vctDynamicConstVectorRef< _elementType > &x, const vctDynamicConstVectorRef< _elementType > &y)
Definition nmrLinearRegression.h:154
size_t numpts
Definition nmrLinearRegression.h:180
_elementType GetTolerance() const
Definition nmrLinearRegression.h:127
virtual void Clear()
Definition nmrLinearRegression.h:133
virtual bool Estimate(_elementType &slope, _elementType &yint, _elementType *mse=0)
Definition nmrLinearRegression.h:241
virtual bool Sample(const vctDynamicVector< _elementType > &x, const vctDynamicVector< _elementType > &y)
Definition nmrLinearRegression.h:150
virtual bool Sample(const std::vector< _elementType > &x, const std::vector< _elementType > &y)
Definition nmrLinearRegression.h:160
virtual bool Sample(const _elementType &x, const _elementType &y)
Definition nmrLinearRegression.h:218
SummationType tolerance
Definition nmrLinearRegression.h:183
virtual ~nmrLinearRegressionSolver()
Definition nmrLinearRegression.h:121
_elementType ElementType
Definition nmrLinearRegression.h:113
size_t NumPoints() const
Definition nmrLinearRegression.h:124
virtual bool EstimateAsFractions(SummationType &slope_num, SummationType &yint_num, SummationType &denom, SummationType *tse_num=0)
Definition nmrLinearRegression.h:227
bool EstimateAsFractions(SummationType &slope_num, SummationType &yint_num, SummationType &denom, SummationType *tse_num=0)
Definition nmrLinearRegression.h:409
~nmrLinearRegressionWindowRecursiveSolver()
Definition nmrLinearRegression.h:385
nmrLinearRegressionWindowRecursiveSolver(size_t length)
Definition nmrLinearRegression.h:384
bool Sample(const _elementType &x, const _elementType &y)
Definition nmrLinearRegression.h:388
bool Sample(const vctDynamicConstVectorRef< _elementType > &CMN_UNUSED(x), const vctDynamicConstVectorRef< _elementType > &CMN_UNUSED(y))
Definition nmrLinearRegression.h:338
WindowType window
Definition nmrLinearRegression.h:312
bool Sample(const std::vector< _elementType > &CMN_UNUSED(x), const std::vector< _elementType > &CMN_UNUSED(y))
Definition nmrLinearRegression.h:341
bool Sample(const _elementType &x, const _elementType &y)
Definition nmrLinearRegression.h:321
WindowTypeIterator iter
Definition nmrLinearRegression.h:313
nmrLinearRegressionWindowSolver(size_t length)
Definition nmrLinearRegression.h:315
std::vector< vctFixedSizeVector< _elementType, 2 > >::iterator WindowTypeIterator
Definition nmrLinearRegression.h:311
BaseClass::SummationType SummationType
Definition nmrLinearRegression.h:309
bool EstimateAsFractions(SummationType &slope_num, SummationType &yint_num, SummationType &denom, SummationType *tse_num=0)
Definition nmrLinearRegression.h:356
bool Sample(const vctDynamicVector< _elementType > &CMN_UNUSED(x), const vctDynamicVector< _elementType > &CMN_UNUSED(y))
Definition nmrLinearRegression.h:335
nmrLinearRegressionSolver< _elementType > BaseClass
Definition nmrLinearRegression.h:308
virtual size_t WindowLength() const
Definition nmrLinearRegression.h:319
virtual bool Recalculate()
Definition nmrLinearRegression.h:346
std::vector< vctFixedSizeVector< _elementType, 2 > > WindowType
Definition nmrLinearRegression.h:310
~nmrLinearRegressionWindowSolver()
Definition nmrLinearRegression.h:317
Definition vctForwardDeclarations.h:119
Dynamic vector referencing existing memory (const).
Definition vctDynamicConstVectorRef.h:79
Definition vctForwardDeclarations.h:131
Definition vctForwardDeclarations.h:86
value_type & Y(void)
Definition vctFixedSizeVectorBase.h:572
value_type & X(void)
Definition vctFixedSizeVectorBase.h:559
Implementation of a fixed-size vector using template metaprogramming.
Definition vctFixedSizeVector.h:54
vctFixedSizeVector()
Definition vctFixedSizeVector.h:76
#define CMN_UNUSED(argument)
Definition cmnPortability.h:497
Declaration of the class cmnTypeTraits.
bool nmrLinearRegression(const _vectorType &x, const _vectorType &y, typename _vectorType::value_type &slope, typename _vectorType::value_type &yint, typename _vectorType::value_type *mse=0, typename _vectorType::value_type tolerance=cmnTypeTraits< typename _vectorType::value_type >::DefaultTolerance)
Definition nmrLinearRegression.h:281
Rules of exporting.
OwnerType::iterator iterator
Definition vctDynamicConstMatrixBase.h:92
const value_type & Y(void) const
Definition vctDynamicConstVectorBase.h:271
const value_type & X(void) const
Definition vctDynamicConstVectorBase.h:263
Typedef for dynamic vectors.
Typedef for fixed size vectors.
Forward declarations and #define for cisstVector.