2
* Fitting Models for Geom Types
5
* Marco Cecchetti <mrcekets at gmail.com>
7
* Copyright 2008 authors
9
* This library is free software; you can redistribute it and/or
10
* modify it either under the terms of the GNU Lesser General Public
11
* License version 2.1 as published by the Free Software Foundation
12
* (the "LGPL") or, at your option, under the terms of the Mozilla
13
* Public License Version 1.1 (the "MPL"). If you do not alter this
14
* notice, a recipient may use your version of this file under either
15
* the MPL or the LGPL.
17
* You should have received a copy of the LGPL along with this library
18
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
* You should have received a copy of the MPL along with this library
21
* in the file COPYING-MPL-1.1
23
* The contents of this file are subject to the Mozilla Public License
24
* Version 1.1 (the "License"); you may not use this file except in
25
* compliance with the License. You may obtain a copy of the License at
26
* http://www.mozilla.org/MPL/
28
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
29
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
30
* the specific language governing rights and limitations.
34
#ifndef _NL_FITTING_MODEL_H_
35
#define _NL_FITTING_MODEL_H_
39
#include <2geom/sbasis.h>
40
#include <2geom/bezier.h>
41
#include <2geom/bezier-curve.h>
42
#include <2geom/poly.h>
43
#include <2geom/ellipse.h>
44
#include <2geom/circle.h>
45
#include <2geom/utils.h>
48
namespace Geom { namespace NL {
51
* A model is an abstraction for an expression dependent from a parameter where
52
* the coefficients of this expression are the unknowns of the fitting problem.
53
* For a ceratain number of parameter values we know the related values
54
* the expression evaluates to: from each parameter value we get a row of
55
* the matrix of the fitting problem, from each expression value we get
56
* the related constant term.
57
* Example: given the model a*x^2 + b*x + c = 0; from x = 1 we get
58
* the equation a + b + c = 0, in this example the constant term is always
59
* the same for each parameter value.
61
* A model is required to implement 3 methods:
63
* - size : returns the number of unknown coefficients that appear in
64
* the expression of the fitting problem;
65
* - feed : its input is a parameter value and the related expression value,
66
* it generates a matrix row and a new entry of the constant vector
67
* of the fitting problem;
68
* - instance : it has an input parameter represented by the raw vector
69
* solution of the fitting problem and an output parameter
70
* of type InstanceType that return a specific object that is
71
* generated using the fitting problem solution, in the example
72
* above the object could be a Poly type.
76
* completely unknown models must inherit from this template class;
77
* example: the model a*x^2 + b*x + c = 0 to be solved wrt a, b, c;
78
* example: the model A(t) = known_sample_value_at(t) to be solved wrt
79
* the coefficients of the curve A(t) expressed in S-Basis form;
80
* parameter type: the type of x and t variable in the examples above;
81
* value type: the type of the known sample values (in the first example
83
* instance type: the type of the objects produced by using
84
* the fitting raw data solution
86
template< typename ParameterType, typename ValueType, typename InstanceType >
87
class LinearFittingModel
90
typedef ParameterType parameter_type;
91
typedef ValueType value_type;
92
typedef InstanceType instance_type;
94
static const bool WITH_FIXED_TERMS = false;
97
* a LinearFittingModel must implement the following methods:
99
* void feed( VectorView & vector,
100
* parameter_type const& sample_parameter ) const;
102
* size_t size() const;
104
* void instance(instance_type &, raw_type const& raw_data) const;
111
* partially known models must inherit from this template class
112
* example: the model a*x^2 + 2*x + c = 0 to be solved wrt a and c
114
template< typename ParameterType, typename ValueType, typename InstanceType >
115
class LinearFittingModelWithFixedTerms
118
typedef ParameterType parameter_type;
119
typedef ValueType value_type;
120
typedef InstanceType instance_type;
122
static const bool WITH_FIXED_TERMS = true;
125
* a LinearFittingModelWithFixedTerms must implement the following methods:
127
* void feed( VectorView & vector,
128
* value_type & fixed_term,
129
* parameter_type const& sample_parameter ) const;
131
* size_t size() const;
133
* void instance(instance_type &, raw_type const& raw_data) const;
141
// incomplete model, it can be inherited to make up different kinds of
142
// instance type; the raw data is a vector of coefficients of a polynomial
143
// rapresented in standard power basis
144
template< typename InstanceType >
146
: public LinearFittingModel<double, double, InstanceType>
149
LFMPowerBasis(size_t degree)
154
void feed( VectorView & coeff, double sample_parameter ) const
158
for (size_t i = 1; i < coeff.size(); ++i)
160
x_i *= sample_parameter;
175
// this model generates Geom::Poly objects
177
: public LFMPowerBasis<Poly>
180
LFMPoly(size_t degree)
181
: LFMPowerBasis<Poly>(degree)
185
void instance(Poly & poly, ConstVectorView const& raw_data) const
189
for (size_t i = 0; i < raw_data.size(); ++i)
191
poly[i] = raw_data[i];
197
// incomplete model, it can be inherited to make up different kinds of
198
// instance type; the raw data is a vector of coefficients of a polynomial
199
// rapresented in standard power basis with leading term coefficient equal to 1
200
template< typename InstanceType >
201
class LFMNormalizedPowerBasis
202
: public LinearFittingModelWithFixedTerms<double, double, InstanceType>
205
LFMNormalizedPowerBasis(size_t _degree)
206
: m_model( _degree - 1)
212
void feed( VectorView & coeff,
214
double sample_parameter ) const
216
m_model.feed(coeff, sample_parameter);
217
known_term = coeff[m_model.size()-1] * sample_parameter;
222
return m_model.size();
226
LFMPowerBasis<InstanceType> m_model;
230
// incomplete model, it can be inherited to make up different kinds of
231
// instance type; the raw data is a vector of coefficients of the equation
232
// of an ellipse curve
233
template< typename InstanceType >
234
class LFMEllipseEquation
235
: public LinearFittingModelWithFixedTerms<Point, double, InstanceType>
238
void feed( VectorView & coeff, double & fixed_term, Point const& p ) const
240
coeff[0] = p[X] * p[Y];
241
coeff[1] = p[Y] * p[Y];
245
fixed_term = p[X] * p[X];
255
// this model generates Ellipse curves
257
: public LFMEllipseEquation<Ellipse>
260
void instance(Ellipse & e, ConstVectorView const& coeff) const
262
e.set(1, coeff[0], coeff[1], coeff[2], coeff[3], coeff[4]);
267
// incomplete model, it can be inherited to make up different kinds of
268
// instance type; the raw data is a vector of coefficients of the equation
270
template< typename InstanceType >
271
class LFMCircleEquation
272
: public LinearFittingModelWithFixedTerms<Point, double, InstanceType>
275
void feed( VectorView & coeff, double & fixed_term, Point const& p ) const
280
fixed_term = p[X] * p[X] + p[Y] * p[Y];
290
// this model generates Ellipse curves
292
: public LFMCircleEquation<Circle>
295
void instance(Circle & c, ConstVectorView const& coeff) const
297
c.set(1, coeff[0], coeff[1], coeff[2]);
302
// this model generates SBasis objects
304
: public LinearFittingModel<double, double, SBasis>
307
LFMSBasis( size_t _order )
308
: m_size( 2*(_order+1) ),
313
void feed( VectorView & coeff, double t ) const
320
for (size_t i = 2; i < size(); i+=2)
334
void instance(SBasis & sb, ConstVectorView const& raw_data) const
337
sb.resize(m_order+1);
338
for (unsigned int i = 0, k = 0; i < raw_data.size(); i+=2, ++k)
340
sb[k][0] = raw_data[i];
341
sb[k][1] = raw_data[i+1];
351
// this model generates D2<SBasis> objects
353
: public LinearFittingModel< double, Point, D2<SBasis> >
356
LFMD2SBasis( size_t _order )
361
void feed( VectorView & coeff, double t ) const
371
void instance(D2<SBasis> & d2sb, ConstMatrixView const& raw_data) const
373
mosb.instance(d2sb[X], raw_data.column_const_view(X));
374
mosb.instance(d2sb[Y], raw_data.column_const_view(Y));
382
// this model generates Bezier objects
384
: public LinearFittingModel<double, double, Bezier>
387
LFMBezier( size_t _order )
388
: m_size(_order + 1),
391
binomial_coefficients(m_bc, m_order);
394
void feed( VectorView & coeff, double t ) const
397
for (size_t i = 0; i < size(); ++i)
399
coeff[i] = s * m_bc[i];
404
for (size_t i = size()-1; i > 0; --i)
417
void instance(Bezier & b, ConstVectorView const& raw_data) const
419
assert(b.size() == raw_data.size());
420
for (unsigned int i = 0; i < raw_data.size(); ++i)
429
std::vector<size_t> m_bc;
433
// this model generates Bezier curves
434
template< unsigned int N >
436
: public LinearFittingModel< double, Point, BezierCurve<N> >
439
LFMBezierCurve( size_t _order )
444
void feed( VectorView & coeff, double t ) const
454
void instance(BezierCurve<N> & bc, ConstMatrixView const& raw_data) const
458
mob.instance(bx, raw_data.column_const_view(X));
459
mob.instance(by, raw_data.column_const_view(Y));
460
bc = BezierCurve<N>(bx, by);
467
} // end namespace NL
468
} // end namespace Geom
471
#endif // _NL_FITTING_MODEL_H_
477
c-file-style:"stroustrup"
478
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
483
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :