The Fib multimedia system
Fib is a system for storing multimedia data (like images or films).
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cSpline.h
Go to the documentation of this file.
1 /**
2  * @file cSpline
3  * file name: cSpline.h
4  * @author Betti Oesterholz
5  * @date 25.06.2011
6  * @mail webmaster@BioKom.info
7  *
8  * System: C++
9  *
10  * This header specifies a class for a one dimensional spline.
11  * Copyright (C) @c GPL3 2010 Betti Oesterholz
12  *
13  * This program is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License (GPL) as
15  * published by the Free Software Foundation, either version 3 of the
16  * License, or any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program. If not, see <http://www.gnu.org/licenses/>.
25  *
26  *
27  * This header specifies a class for a one dimensional spline.
28  * A spline is a interpolation of a function by polynome (@see cPolynom).
29  * The second template parameter should always be a floating point datatype.
30  *
31  */
32 /*
33 History:
34 25.06.2011 Oesterholz created
35 24.09.2012 Oesterholz FEATURE_C_SPLINE_USE_GLP_LIB_LINAR_PROBLEM_SOLVING:
36  evalueSpline(): the glp library (extern package) linear solver will be
37  used to find a spline for a vector of range data points
38 13.12.2012 Oesterholz parameter ulMaxPolynoms added for evalueSpline()
39 */
40 
41 #ifndef ___N_D_1_C_SPLINE_H__
42 #define ___N_D_1_C_SPLINE_H__
43 
44 #include "version.h"
45 
46 #include "nD1.h"
47 #include "cDataPoint.h"
48 #include "cPolynom.h"
49 #include "cOneAryFunction.h"
50 
51 #include "cUnderFunction.h"
52 #include "cFibVariable.h"
53 
54 #include <vector>
55 
56 using namespace fib;
57 using namespace fib::algorithms::nLinearInequation;
58 
59 
60 namespace fib{
61 
62 namespace algorithms{
63 
64 namespace nD1{
65 
66 template <class tX, class tY>
67 class cSpline: public cOneAryFunction<tX, tY>{
68 
69 #ifdef TEST
70 public:
71 #else //TEST
72 protected:
73 #endif //TEST
74  /**
75  * The the polynomes of the spline.
76  * The interpolate the function betwean ther borders.
77  * The i'th polynom vecPolynoms[ i ] interpolats the function betwaen
78  * the border i - 1 vecBorders[ i-1 ] (inclusive it) to border i
79  * vecBorders[ i ] (exclusive it).
80  * The first and last polynom are unbound.
81  * So ther have to be one border less as ther are splines.
82  * @see cPolynom
83  * @see vecBorders
84  * @see evalue()
85  */
86  vector< cPolynom< tX, tY> > vecPolynoms;
87 
88  /**
89  * The the borders for the polynoms of the spline.
90  * The interpolate the function betwean ther borders.
91  * The i'th polynom vecPolynoms[ i ] interpolats the function betwaen
92  * the border i - 1 vecBorders[ i-1 ] (inclusive it) to border i
93  * vecBorders[ i ] (exclusive it).
94  * The first and last polynom are unbound.
95  * So ther have to be one border less as ther are splines.
96  * All borders have to be sorted in increasing order.
97  * vecBorders[ i ] < vecBorders[ i + 1 ]
98  * @see vecPolynoms
99  * @see evalue()
100  */
101  vector< tY > vecBorders;
102 
103 
104 public:
105 
106 
107  /**
108  * Standartconstructor
109  */
110  cSpline();
111 
112  /**
113  * This method evalues the value of this spline.
114  * For this the polynom in which borders the value is will be evalued.
115  *
116  * @see vecPolynoms
117  * @see vecBorders
118  * @see cPolynom::evalue()
119  * @param x the input value for the spline
120  * @return the evalued value f( x )
121  */
122  virtual tY evalue( const tX & x ) const;
123 
124  /**
125  * This method prints this spline to the given stream.
126  *
127  * @param outputStream the stream wher to print this spline to
128  */
129  virtual void print( ostream & outputStream ) const;
130 
131  /**
132  * This method evalues the error of the given datapoints to the values
133  * this spline evalues to.
134  *
135  * The evaluation of the spline will be done by evalue().
136  * The error will just be counted, if it is greater than the SAVE_BOUNDERY.
137  * @see evalue()
138  *
139  * @param vecInputData the data for wich the error is to evalue
140  * @return a pair with two values:
141  * - the first value is the number of datapoints evalued wrong
142  * - the second value is the sum of the error of all datapoints
143  */
144  virtual pair<unsigned long, tY> evalueError(
145  const vector< cDataPoint< tX, tY> > & vecInputData ) const;
146 
147  /**
148  * This method evalues the error of the given datapoints to the values
149  * this spline evalues to.
150  * This function will stop the evaluation, if the maximum error maxYError
151  * was reached.
152  *
153  * The evaluation of the spline will be done by evalue().
154  * The error will just be counted, if it is greater than the SAVE_BOUNDERY.
155  * @see evalue()
156  *
157  * @param vecInputData the data for wich the error is to evalue
158  * @param maxYError the maximum error, at which the evaluation should stop;
159  * if maxYError is 0 the maximum error is unlimeted
160  * @return the sum of the error of all datapoints, but maximal maxYError
161  */
162  virtual tY evalueErrorMax( const vector< cDataPoint< tX, tY> > & vecData,
163  const tY maxYError ) const;
164 
165  /**
166  * This method evalues the error of the given range datapoints to the
167  * values this spline evalues to.
168  *
169  * The evaluation of the spline will be done by evalue().
170  * A datapoint has an error, if it lay outside the datpoint range. The
171  * error is it's distance to the neares datapoint boundery.
172  * The error will just be counted, if it is greater than the SAVE_BOUNDERY.
173  * @see evalue()
174  *
175  * @param vecInputData the data for wich the error is to evalue
176  * @return a pair with two values:
177  * - the first value is the number of datapoints evalued wrong
178  * - the second value is the sum of the error of all datapoints
179  */
180  virtual pair<unsigned long, tY> evalueError(
181  const vector< cDataPointRange< tX, tY> > & vecInputData ) const;
182 
183  /**
184  * This method evalues the error of the given datapoints to the values
185  * this spline evalues to.
186  * This function will stop the evaluation, if the maximum error maxYError
187  * was reached.
188  *
189  * The evaluation of the spline will be done by evalue().
190  * A datapoint has an error, if it lay outside the datpoint range. The
191  * error is it's distance to the neares datapoint boundery.
192  * The error will just be counted, if it is greater than the SAVE_BOUNDERY.
193  * @see evalue()
194  *
195  * @param vecInputData the data for wich the error is to evalue
196  * @param maxYError the maximum error, at which the evaluation should stop;
197  * if maxYError is 0 the maximum error is unlimeted
198  * @return the sum of the error of all datapoints, but maximal maxYError
199  */
200  virtual tY evalueErrorMax( const vector< cDataPointRange< tX, tY> > & vecData,
201  const tY maxYError ) const;
202 
203  /**
204  * This method converts this spline, into an fib-underfunction.
205  * Beware: You have to delete the returned fib-underfunction.
206  *
207  * @param pVariable the variable (x) for the spline
208  * @return a pointer to the fib-underfunction, wich represents the
209  * same spline as this spline
210  */
211  virtual cUnderFunction * toFibUnderFunction(
212  cFibVariable * pVariable ) const;
213 
214 
215  /**
216  * This function evalues the function for the given data.
217  * The evalued function will have the order n of the number of given
218  * datapoints.
219  * It will call @see cPolynom::evalue( vecData ) and add the created polynom.
220  *
221  * @param vecData the data for which to evalue the function
222  * @return if the function for the datapoints could be evalued: the
223  * elements of the evalued function in this function and true, else
224  * false and the elements of this function not changed
225  */
226  virtual bool evalue( const vector< cDataPoint< tX, tY> > & vecData );
227 
228 #ifdef FEATURE_C_SPLINE_USE_GLP_LIB_LINAR_PROBLEM_SOLVING
229 
230  /**
231  * This functions evalues a spline, which matches all points of the
232  * given range data vecData (if possible).
233  * The y value, to wich the spline evalues the x value, will be in the
234  * bound of the range data point, so that:
235  * vecData[i].minY <= spline( vecData[i].x ) + error_i <= vecData[i].maxY,
236  * with maxError <= sum error_i
237  * for i = 0 till vecData.size()
238  *
239  * The evalued spline (this spline) consists of a number of polynoms
240  * seperated by border points.
241  * The evalued polynoms (@see cPolynom) will have the form:
242  * y = vecFactors[ 0 ] + vecFactors[ 1 ] * x +
243  * vecFactors[ 2 ] * x^2 + ... +
244  * vecFactors[ uiNumberOfParameters - 1 ] *
245  * x^(uiNumberOfParameters - 1)
246  * The upper border point of a polynom is the first point at wich the
247  * polynom dosn't match the given data vecData anymore.
248  *
249  * The method will iterativ increase the number of parameters for the
250  * polynoms (from 1 to uiMaxNumberOfParameters) and will try to not use
251  * all of the given range points to find the polynoms.
252  *
253  * @see evalue()
254  * @see evalue()
255  * @see cPolynom::evalueSplineIterativFast()
256  * @param vecInputData the data which the returend spline should match
257  * @param uiMaxNumberOfParameters the number of parameters for the spline;
258  * Don't choose this number to big, because the evaluation time will
259  * grow exponentialy with this number. Even splines with 8
260  * parameters will take some time.
261  * @param maxValue the maximum possible value in all parameters
262  * the evalued spline will allways have parameters vecFactors[i] with
263  * -1 * maxValue <= vecFactors[i] <= maxValue for 0 <= i < vecFactors.size()
264  * @param maxError the maximal error for the spline to find;
265  * the error on the interpolated spline for vecData will be equal or
266  * less than maxError
267  * @param maxErrorPerValue the maximal error for the spline to find on
268  * one data point; the error on the interpolated spline for every data
269  * point in vecData will be equal or less than maxErrorPerValue;
270  * if maxErrorPerValue is 0 and maxError is not 0, maxErrorPerValue will
271  * be set to maxError / vecInputData.size()
272  * @param dWeightParameter a value for the weight of the parameters;
273  * with this value greater 0 it will be searched for smaal parameter;
274  * when searching for a solution the error is minimized and the
275  * spline parameter will be multiplied with this value and also minimized;
276  * when set to 1 a parameter increas of 1 is as bad as an error increas
277  * of 1, when set to 0.01 parameter increas of 100 is as bad an error increas
278  * of 1
279  * @param ulMaxPolynoms the maximum number of polynoms the spline shoulc be
280  * build of, if 0 the maximum number infinity
281  * @return the number n of data points vecData, which the spline matches;
282  * the data points vecData[0] to vecData[ return - 1 ] will be
283  * matched by the spline
284  */
285  virtual unsigned long evalueSpline(
286  const vector< cDataPointRange< tX, tY> > & vecInputData,
287  unsigned int uiMaxNumberOfParameters = 4,
288  const tY maxValue = 1E+36,
289  const tY maxError = 0,
290  const tY maxErrorPerValue = 0,
291  const double dWeightParameter = 0.0000000001,
292  const unsigned long ulMaxPolynoms = 0 );
293 
294 #else //FEATURE_C_SPLINE_USE_GLP_LIB_LINAR_PROBLEM_SOLVING
295 
296  /**
297  * This functions evalues a spline, which matches all points of the
298  * given range data vecData (if possible).
299  * The y value, to wich the spline evalues the x value, will be in the
300  * bound of the range data point, so that:
301  * vecData[i].minY <= spline( vecData[i].x ) + error_i <= vecData[i].maxY,
302  * with maxError <= sum error_i
303  * for i = 0 till vecData.size()
304  *
305  * The evalued spline (this spline) consists of a number of polynoms
306  * seperated by border points.
307  * The evalued polynoms (@see cPolynom) will have the form:
308  * y = vecFactors[ 0 ] + vecFactors[ 1 ] * x +
309  * vecFactors[ 2 ] * x^2 + ... +
310  * vecFactors[ uiNumberOfParameters - 1 ] *
311  * x^(uiNumberOfParameters - 1)
312  * The upper border point of a polynom is the first point at wich the
313  * polynom dosn't match the given data vecData anymore.
314  *
315  * The method will iterativ increase the number of parameters for the
316  * polynoms (from 1 to uiMaxNumberOfParameters) and will try to not use
317  * all of the given range points to find the polynoms.
318  *
319  * @see evalue()
320  * @see cPolynom::evalueSplineIterativFast()
321  * @param vecInputData the data which the returend spline should match
322  * @param uiMaxNumberOfParameters the number of parameters for the spline;
323  * Don't choose this number to big, because the evaluation time will
324  * grow exponentialy with this number. Even splines with 8
325  * parameters will take some time.
326  * @param uiMinBitsToStoreMantissa the minimal number of bits to store
327  * the mantissa of the parameters, when the parameter is in the
328  * form: mantissa * 2^exponent ;
329  * the method will try to reduce the bits, to store a parameter of the
330  * returned vector, to the uiMinBitsToStoreMantissa value;
331  * if uiMinBitsToStoreMantissa is 0, no optimization for the mantissa
332  * bits will be done
333  * @param maxValue the maximum possible value in all parameters
334  * the evalued spline will allways have parameters vecFactors[i] with
335  * -1 * maxValue <= vecFactors[i] <= maxValue for 0 <= i < vecFactors.size()
336  * @param maxError the maximal error for the spline to find;
337  * the error on the interpolated spline for vecData will be equal or
338  * less than maxError
339  * @param ulMaxMemoryCost a number for the maximum memory cost this
340  * method is allowed to use; if 0 the maximum memory cost is unbounded
341  * @return the number n of data points vecData, which the spline matches;
342  * the data points vecData[0] to vecData[ return - 1 ] will be
343  * matched by the spline
344  */
345  virtual unsigned long evalueSpline(
346  const vector< cDataPointRange< tX, tY> > & vecInputData,
347  unsigned int uiMaxNumberOfParameters = 4,
348  const unsigned int uiMinBitsToStoreMantissa = 1,
349  const tY maxValue = 1E+36,
350  const tY maxError = 0,
351  const unsigned long ulMaxMemoryCost = 0 );
352 
353 #endif //FEATURE_C_SPLINE_USE_GLP_LIB_LINAR_PROBLEM_SOLVING
354 
355 
356  /**
357  * @param dataPoint the spline to compare this spline with
358  * @return true if the given spline is equal to this, else false
359  * (@see x, @see y)
360  */
361  virtual bool operator==( const cSpline<tX, tY> & spline ) const;
362 
363  /**
364  * @param dataPoint the spline to compare this spline with
365  * @return true if the given spline is not equal to this, else false
366  * (@see x, @see y)
367  */
368  virtual bool operator!=( const cSpline<tX, tY> & spline ) const;
369 
370  /**
371  * @return the a const pointer to the vector with the polynoms of this
372  * spline (@see vecPolynoms)
373  */
374  const vector< cPolynom< tX, tY> > * getPolynoms() const;
375 
376  /**
377  * @return the a const pointer to the vector with the borders of this
378  * spline (@see vecBorders)
379  */
380  const vector< tY > * getBorders() const;
381 
382 /*TODO
383  cPolynom * getPolynom( unsigned int uiNumber )
384  tY getBorder( unsigned int uiNumber )
385 
386  bool setPolynom( unsigned int uiNumber, const cPolynom & polynome )
387  bool setBorder( unsigned int uiNumber, const tY & border )
388 
389 
390  * Add border in correct position
391  *
392  bool addPolynom( const cPolynom & polynome, const tY & border )
393 
394 */
395 
396 protected:
397  /**
398  * This function generates an subfunction for the given part spline
399  * as an balanced tree of if subfunctions.
400  *
401  * @param vecInPolynoms the vector with the polynoms for the splines
402  * @see vecPolynoms
403  * @param vecInBorders the vector with the borders for the splines
404  * @see vecBorders
405  * @param pVariable the variable (x) for the spline
406  * @return the subfunction for the given spline
407  */
408  cUnderFunction * generateSubfunctionTree(
409  const vector< const cPolynom< tX, tY> * > & vecInPolynoms,
410  const vector< tY > & vecInBorders,
411  cFibVariable * pVariable ) const;
412 
413 
414 };//end class cSpline
415 };//end namespace nD1
416 };//end namespace algorithms
417 };//end namespace fib
418 
419 //include template implementation
420 #include "../src/cSpline.cpp"
421 
422 
423 #endif //___N_D_1_C_SPLINE_H__
424 
425 
426 
427 
428