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
cPolynom.h
Go to the documentation of this file.
1 /**
2  * @file cPolynom
3  * file name: cPolynom.h
4  * @author Betti Oesterholz
5  * @date 07.06.2010
6  * @mail webmaster@BioKom.info
7  *
8  * System: C++
9  *
10  * This header specifies methods and functions for a one dimensional
11  * polynom.
12  * Copyright (C) @c GPL3 2010 Betti Oesterholz
13  *
14  * This program is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License (GPL) as
16  * published by the Free Software Foundation, either version 3 of the
17  * License, or any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program. If not, see <http://www.gnu.org/licenses/>.
26  *
27  *
28  * This header specifies methods and functions for a one dimensional
29  * polynom functions.
30  * The second template parameter should always be a floating point datatype.
31  *
32  */
33 /*
34 History:
35 07.06.2010 Oesterholz created
36 12.02.2011 Oesterholz method evalueSpline() added
37 27.03.2011 Oesterholz method getLastFactorIndexNotNull() added
38 29.12.2012 Oesterholz FEATURE_C_SPLINE_USE_GLP_LIB_LINAR_PROBLEM_SOLVING:
39  evalueSplineIterativFast(): the glp library (extern package) linear
40  solver will be used to find a spline for a vector of range data points
41 */
42 
43 #ifndef ___N_D_1_C_POLYNOM_H__
44 #define ___N_D_1_C_POLYNOM_H__
45 
46 #include "version.h"
47 
48 #include "nD1.h"
49 #include "cDataPoint.h"
50 #include "cLinearEquation.h"
51 #include "cOneAryFunction.h"
52 #include "cInequation.h"
53 
54 #include "cUnderFunction.h"
55 #include "cFibVariable.h"
56 
57 #include <vector>
58 
59 using namespace fib;
60 using namespace fib::algorithms::nLinearInequation;
61 
62 
63 namespace fib{
64 
65 namespace algorithms{
66 
67 namespace nD1{
68 
69 template <class tX, class tY>
70 class cPolynom: public cOneAryFunction<tX, tY>{
71 
72 public:
73  /**
74  * The factors for the polynom.
75  * @see evalue()
76  */
77  vector< tY > vecFactors;
78 
79  /**
80  * Standartconstructor
81  */
82  cPolynom();
83 
84  /**
85  * This method evalues the value of this polynom.
86  *
87  * The evalued function is:
88  * f( x ) = vecFactors[ 0 ] + vecFactors[ 1 ] * x +
89  * vecFactors[ 2 ] * x^2 + ... +
90  * vecFactors[ vecFactors.size() - 1 ] *
91  * x^(vecFactors.size() - 1)
92  *
93  * @param x the input value for the polynom
94  * @return the evalued value f( x )
95  */
96  virtual tY evalue( const tX & x ) const;
97 
98  /**
99  * This method prints this polynom to the given stream.
100  *
101  * @param outputStream the stream wher to print this polynom to
102  */
103  virtual void print( ostream & outputStream ) const;
104 
105  /**
106  * This method evalues the error of the given datapoints to the values
107  * this polynom evalues to.
108  *
109  * The evaluation of the polynom will be done by evalue().
110  * The error will just be counted, if it is greater than the SAVE_BOUNDERY.
111  * @see evalue()
112  *
113  * @param vecInput the data for wich the error is to evalue
114  * @return a pair with two values:
115  * - the first value is the number of datapoints evalued wrong
116  * - the second value is the sum of the error of all datapoints
117  */
118  virtual pair<unsigned long, tY> evalueError(
119  const vector< cDataPoint< tX, tY> > & vecInput ) const;
120 
121  /**
122  * This method evalues the error of the given datapoints to the values
123  * this polynom evalues to.
124  * This function will stop the evaluation, if the maximum error maxYError
125  * was reached.
126  *
127  * The evaluation of the polynom will be done by evalue().
128  * The error will just be counted, if it is greater than the SAVE_BOUNDERY.
129  * @see evalue()
130  *
131  * @param vecInput the data for wich the error is to evalue
132  * @param maxYError the maximum error, at which the evaluation should stop;
133  * if maxYError is 0 the maximum error is unlimeted
134  * @return the sum of the error of all datapoints, but maximal maxYError
135  */
136  virtual tY evalueErrorMax( const vector< cDataPoint< tX, tY> > & vecData,
137  const tY maxYError ) const;
138 
139  /**
140  * This method evalues the error of the given range datapoints to the
141  * values this polynom evalues to.
142  *
143  * The evaluation of the polynom will be done by evalue().
144  * A datapoint has an error, if it lay outside the datpoint range. The
145  * error is it's distance to the neares datapoint boundery.
146  * The error will just be counted, if it is greater than the SAVE_BOUNDERY.
147  * @see evalue()
148  *
149  * @param vecInput the data for wich the error is to evalue
150  * @return a pair with two values:
151  * - the first value is the number of datapoints evalued wrong
152  * - the second value is the sum of the error of all datapoints
153  */
154  virtual pair<unsigned long, tY> evalueError(
155  const vector< cDataPointRange< tX, tY> > & vecInput ) const;
156 
157  /**
158  * This method evalues the error of the given datapoints to the values
159  * this polynom evalues to.
160  * This function will stop the evaluation, if the maximum error maxYError
161  * was reached.
162  *
163  * The evaluation of the polynom will be done by evalue().
164  * A datapoint has an error, if it lay outside the datpoint range. The
165  * error is it's distance to the neares datapoint boundery.
166  * The error will just be counted, if it is greater than the SAVE_BOUNDERY.
167  * @see evalue()
168  *
169  * @param vecInput the data for wich the error is to evalue
170  * @param maxYError the maximum error, at which the evaluation should stop;
171  * if maxYError is 0 the maximum error is unlimeted
172  * @return the sum of the error of all datapoints, but maximal maxYError
173  */
174  virtual tY evalueErrorMax( const vector< cDataPointRange< tX, tY> > & vecData,
175  const tY maxYError ) const;
176 
177  /**
178  * This function creats the linear equiations ( @see cLinearEquation )
179  * for the given datapoints.
180  * The linear equiations will have the form:
181  * vecData.y = x_0 + vecData.x * x_1 + vecData.x^2 * x_2 + ... +
182  * vecData.x^(uiMaxPolynomOrder - 1) * x_{uiMaxPolynomOrder - 1}
183  *
184  * @param vecData the with the datapoints, for which to evalue the
185  * linear equiations
186  * @param uiMaxPolynomOrder the maximal order of the polynom to generate
187  * the factor ranges for
188  * @return a vector with the linear equiations for the datapoints
189  */
190  virtual vector< cLinearEquation<tY> > createLinearEquations(
191  const vector< cDataPoint< tX, tY> > & vecData,
192  unsigned int uiMaxPolynomOrder ) const;
193 
194  /**
195  * This function creats the two inequiations for the range data point.
196  * This inequiations restrict the values in the same way as the range
197  * data point and have the form:
198  * minY <= a_0 + a_1 * x + a_2 * x^2 + ...
199  * ... + a_{uiPolynomOrder-1} * x^(uiPolynomOrder-1)
200  * and
201  * -1 * maxY <= -1 * a_0 - a_1 * x - a_2 * x^2 - ...
202  * ... - a_{uiPolynomOrder-1} * x^(uiPolynomOrder-1)
203  *
204  * @param dataPoint the range datapoint, for which to create the
205  * inequiations
206  * @param uiPolynomOrder the order for the polynom, which builds the
207  * inequiations
208  * @return the two polynom inequiations as a pair, which restrict the
209  * values in the same way as the range datapoint
210  */
211  pair< cInequation< tY >, cInequation< tY > >
212  createInequiationsForRangePoint(
213  const cDataPointRange< tX, tY> & dataPoint,
214  unsigned int uiPolynomOrder ) const;
215 
216 
217  /**
218  * @return the index of the last factor, wich is not 0.
219  * (counting from 0, eg. if 0 is return the polynom is constant)
220  */
221  long getLastFactorIndexNotNull() const;
222 
223  /**
224  * This method converts this polynom, into an fib -underfunction.
225  * Beware: You have to delete the returned fib -underfunction.
226  *
227  * @param pVariable the variable (x) for the polynom
228  * @return a pointer to the fib -underfunction, wich represents the
229  * same polynom as this polynom
230  */
231  virtual cUnderFunction * toFibUnderFunction(
232  cFibVariable * pVariable ) const;
233 
234 
235  /**
236  * This function evalues the polynom for the given data.
237  * The evalued polynom will have the order n of the number of given
238  * datapoints.
239  *
240  * @param vecInputData the data for which to evalue the polynom
241  * @return if an polynom for the datapoints could be evalued, the factors
242  * of the evalued polynom in this polynom and true, else false
243  */
244  virtual bool evalue( const vector< cDataPoint< tX, tY> > & vecInputData );
245 
246  /**
247  * This method trys to find a polynom for the given data vecData by
248  * choosen n random points from vecData and create a polynom of order n
249  * for them.
250  * The number n will at the beginning be 1 and then canged random in an
251  * reange near the best found polynomorder till now.
252  * The creation of the polynom from random datapoints is tryed
253  * ulMaxIterations times and the polynom with the smales error on the data
254  * is returned.
255  *
256  * @see evalue() for the type of the polynom
257  * @param vecInputData the data which the returend polynom should match
258  * @param ulMaxIterations the maximal number of iterations / polynoms to
259  * generate
260  * @return the error of the best found function
261  * and the values of the evalued polynom in this polynom
262  */
263  virtual tY findFunctionRand( const vector< cDataPointRange< tX, tY> > & vecInputData,
264  unsigned long ulMaxIterations = 256 * 256 * 256 );
265 
266  /**
267  * This method evalues the a good polynom, which matches the given
268  * range data vecData.
269  * For this a polynom which evalues a low error on the given data point
270  * ranges is evalued.
271  *
272  * @see evalue()
273  * @param vecInputData the data which the returend polynom should match
274  * @param ulTimeNeed a value for the time, wich can be used to optimize
275  * the result, the (additional) evaluation time will scale linear with
276  * this factor
277  * @return the factors of the evalued polynom in this polynom and
278  * the error for the evalued polynom on the given data
279  */
280  virtual tY evalueGoodPolynom(
281  const vector< cDataPointRange< tX, tY> > & vecInputData,
282  unsigned long ulTimeNeed = 1024 );
283 
284  /**
285  * This functions evalues a spline, which matches the given range vecInputData
286  * The vector vecData is the sorted vector vecInputData.
287  * vecData
288  * The y value, to wich the spline evalues the x value, will be in the
289  * bound of the range data point, so that:
290  * vecData[i].minY <= spline( vecData[i].x ) <= vecData[i].maxY,
291  * for i = 0 till n, with n <= vecData.size()
292  * The first sorted n range data points will be matched by the spline.
293  * The first sorted n+1'th data points can't be matched by a spline/polynom
294  * with uiNumberOfParameters parameters.
295  * The evalued spline (this polynom) will have the form:
296  * y = vecFactors[ 0 ] + vecFactors[ 1 ] * x +
297  * vecFactors[ 2 ] * x^2 + ... +
298  * vecFactors[ uiNumberOfParameters - 1 ] *
299  * x^(uiNumberOfParameters - 1)
300  *
301  * @see evalue()
302  * @see evalueSplineIterativFast()
303  * @param vecInputData the data which the returend polynom should match
304  * @param uiNumberOfParameters the number of parameters for the spline;
305  * Don't choose this number to big, because the evaluation time will
306  * grow exponentialy with this number. Even splines with 8
307  * parameters will take some time.
308  * @param uiMinBitsToStoreMantissa the minimal number of bits to store
309  * the mantissa of the parameters, when the parameter is in the
310  * form: mantissa * 2^exponent ;
311  * the method will try to reduce the bits, to store a parameter of the
312  * returned vector, to the uiMinBitsToStoreMantissa value;
313  * if uiMinBitsToStoreMantissa is 0, no optimization for the mantissa
314  * bits will be done
315  * @param maxValue the maximum possible value in all parameters
316  * the evalued polynom will allways have parameters vecFactors[i] with
317  * -1 * maxValue <= vecFactors[i] <= maxValue for 0 <= i < vecFactors.size()
318  * @param ulMaxMemoryCost a number for the maximum memory cost this
319  * method is allowed to use; if 0 the maximum memory cost is unbounded
320  * @return the number n of data points vecData, which the spline matches;
321  * the sorted data points vecData[0] to vecData[ return - 1 ] will be
322  * matched by the spline
323  */
324  virtual unsigned long evalueSpline(
325  const vector< cDataPointRange< tX, tY> > & vecInputData,
326  unsigned int uiNumberOfParameters = 4,
327  const unsigned int uiMinBitsToStoreMantissa = 1,
328  const tY maxValue = 1E+36,
329  const unsigned long ulMaxMemoryCost = 0 );
330 
331 
332 #ifdef FEATURE_C_SPLINE_USE_GLP_LIB_LINAR_PROBLEM_SOLVING
333 
334  /**
335  * This functions evalues a spline, which matches all points of the
336  * given range data vecData (if possible).
337  * The y value, to wich the spline evalues the x value, will be in the
338  * bound of the range data point, so that:
339  * vecData[i].minY <= spline( vecData[i].x ) + error_i <= vecData[i].maxY,
340  * with maxError <= sum error_i
341  * for i = 0 till vecData.size()
342  *
343  * The evalued spline (this polynom) will have the form:
344  * The evalued polynoms (@see cPolynom) will have the form:
345  * y = vecFactors[ 0 ] + vecFactors[ 1 ] * x +
346  * vecFactors[ 2 ] * x^2 + ... +
347  * vecFactors[ uiNumberOfParameters - 1 ] *
348  * x^(uiNumberOfParameters - 1)
349  *
350  * The method will iterativ increase the number of parameters for the
351  * polynoms (from 1 to uiMaxNumberOfParameters) and will try to use
352  * all of the given range points to find the polynoms.
353  *
354  * @see evalue()
355  * @see cPolynom::evalueSplineIterativFast()
356  * @param vecInputData the data which the returend spline should match
357  * @param uiMaxNumberOfParameters the number of parameters for the spline;
358  * Don't choose this number to big, because the evaluation time will
359  * grow exponentialy with this number. Even splines with 8
360  * parameters will take some time.
361  * @param maxValue the maximum possible value in all parameters
362  * the evalued spline will allways have parameters vecFactors[i] with
363  * -1 * maxValue <= vecFactors[i] <= maxValue for 0 <= i < vecFactors.size()
364  * @param maxError the maximal error for the spline to find;
365  * the error on the interpolated spline for vecData will be equal or
366  * less than maxError
367  * @param maxErrorPerValue the maximal error for the spline to find on
368  * one data point; the error on the interpolated spline for every data
369  * point in vecData will be equal or less than maxErrorPerValue;
370  * if maxErrorPerValue is 0 and maxError is not 0, maxErrorPerValue will
371  * be set to maxError * 2 / vecInputData.size()
372  * @param dWeightParameter a value for the weight of the parameters;
373  * with this value greater 0 it will be searched for smaal parameter;
374  * when searching for a solution the error is minimized and the
375  * spline parameter will be multiplied with this value and also minimized;
376  * when set to 1 a parameter increas of 1 is as bad as an error increas
377  * of 1, when set to 0.01 parameter increas of 100 is as bad an error increas
378  * of 1
379  * @return the number n of data points vecData, which the spline matches;
380  * the data points vecData[0] to vecData[ return - 1 ] will be
381  * matched by the spline
382  */
383  virtual unsigned long evalueSplineIterativFast(
384  const vector< cDataPointRange< tX, tY> > & vecInputData,
385  unsigned int uiMaxNumberOfParameters = 4,
386  const tY maxValue = 1E+36,
387  const tY maxError = 0,
388  const tY maxErrorPerValue = 0,
389  const double dWeightParameter = 0.0000000001 );
390 
391 #else //FEATURE_C_SPLINE_USE_GLP_LIB_LINAR_PROBLEM_SOLVING
392 
393  /**
394  * This functions evalues a spline, which matches the given range data
395  * vecInputData
396  * The vector vecData is the sorted vector vecInputData.
397  * The y value, to wich the spline evalues the x value, will be in the
398  * bound of the range data point, so that:
399  * vecData[i].minY <= spline( vecData[i].x ) <= vecData[i].maxY,
400  * for i = 0 till n, with n <= vecData.size()
401  * The first sorted n range data points will be matched by the spline.
402  * The first sorted n+1'th data points can't be matched by a spline/polynom
403  * with uiNumberOfParameters parameters.
404  * The evalued spline (this polynom) will have the form:
405  * y = vecFactors[ 0 ] + vecFactors[ 1 ] * x +
406  * vecFactors[ 2 ] * x^2 + ... +
407  * vecFactors[ uiNumberOfParameters - 1 ] *
408  * x^(uiNumberOfParameters - 1)
409  *
410  * The method should give the same result as evalueSpline() but faster.
411  * It will iterativ increase the number of parameters for the spline
412  * (from 1 to uiMaxNumberOfParameters) and will try to not use all of
413  * the given range points to find the polynom.
414  *
415  * @see evalue()
416  * @see evalueSpline()
417  * @param vecInputData the data which the returend polynom should match
418  * @param uiMaxNumberOfParameters the number of parameters for the spline;
419  * Don't choose this number to big, because the evaluation time will
420  * grow exponentialy with this number. Even splines with 8
421  * parameters will take some time.
422  * @param uiMinBitsToStoreMantissa the minimal number of bits to store
423  * the mantissa of the parameters, when the parameter is in the
424  * form: mantissa * 2^exponent ;
425  * the method will try to reduce the bits, to store a parameter of the
426  * returned vector, to the uiMinBitsToStoreMantissa value;
427  * if uiMinBitsToStoreMantissa is 0, no optimization for the mantissa
428  * bits will be done
429  * @param maxValue the maximum possible value in all parameters
430  * the evalued polynom will allways have parameters vecFactors[i] with
431  * -1 * maxValue <= vecFactors[i] <= maxValue for 0 <= i < vecFactors.size()
432  * @param maxError the maximal error for the polynom to find;
433  * the error on the interpolated polynom for vecData will be equal or
434  * less than maxError
435  * @param ulMaxMemoryCost a number for the maximum memory cost this
436  * method is allowed to use; if 0 the maximum memory cost is unbounded
437  * @return the number n of data points vecData, which the spline matches;
438  * the sorted data points vecData[0] to vecData[ return - 1 ] will be
439  * matched by the spline
440  */
441  virtual unsigned long evalueSplineIterativFast(
442  const vector< cDataPointRange< tX, tY> > & vecInputData,
443  unsigned int uiMaxNumberOfParameters = 4,
444  const unsigned int uiMinBitsToStoreMantissa = 1,
445  const tY maxValue = 1E+36,
446  const tY maxError = 0,
447  const unsigned long ulMaxMemoryCost = 0 );
448 
449 #endif //FEATURE_C_SPLINE_USE_GLP_LIB_LINAR_PROBLEM_SOLVING
450 
451 
452  /**
453  * @param dataPoint the polynom to compare this polynom with
454  * @return true if the given polynom is equal to this, else false
455  * (@see x, @see y)
456  */
457  virtual bool operator==( const cPolynom<tX, tY> & polynom ) const;
458 
459  /**
460  * @param dataPoint the polynom to compare this polynom with
461  * @return true if the given polynom is not equal to this, else false
462  * (@see x, @see y)
463  */
464  virtual bool operator!=( const cPolynom<tX, tY> & polynom ) const;
465 
466 
467 };//end class cPolynom
468 };//end namespace nD1
469 };//end namespace algorithms
470 };//end namespace fib
471 
472 //include template implementation
473 #include "../src/cPolynom.cpp"
474 
475 
476 #endif //___N_D_1_C_POLYNOM_H__
477 
478 
479 
480 
481