00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
#ifndef DICRVFIT_H
00035
#define DICRVFIT_H
00036
00037
#include "osconfig.h"
00038
#include "ofcast.h"
00039
00040
#define INCLUDE_CMATH
00041
#include "ofstdinc.h"
00042
00043
00044
00045
00046
00047
00048
00049
#define T3_ double
00050
00051
00052
00053
00054
00055
00058
template <
class T1,
class T2 >
00059 class DiCurveFitting
00060 {
00061
00062
public:
00063
00077 static int calculateCoefficients(
const T1 *x,
00078
const T2 *y,
00079
const unsigned int n,
00080
const unsigned int o,
00081 T3_ *c)
00082 {
00083
int result = 0;
00084
if ((x != NULL) && (y != NULL) && (c !=NULL) && (n > 0))
00085 {
00086
const unsigned int order = o + 1;
00087
const unsigned int order2 = order * order;
00088 T3_ *basis =
new T3_[order * n];
00089 T3_ *alpha =
new T3_[order2];
00090 T3_ *beta =
new T3_[order];
00091
if ((basis != NULL) && (alpha != NULL) && (beta != NULL))
00092 {
00093
register unsigned int i;
00094
register unsigned int j;
00095
register unsigned int k;
00096
for (i = 0; i < order; ++i)
00097 {
00098
for (j = 0; j < n; ++j)
00099 {
00100 k = i + j * order;
00101
if (i == 0)
00102 basis[k] = 1;
00103
else
00104 basis[k] = OFstatic_cast(T3_, x[j]) * basis[k - 1];
00105 }
00106 }
00107 T3_ sum;
00108
for (i = 0; i < order; ++i)
00109 {
00110
const unsigned int i_order = i * order;
00111
for (j = 0; j <= i; ++j)
00112 {
00113 sum = 0;
00114
for (k = 0; k < n; ++k)
00115 sum += basis[i + k * order] * basis[j + k * order];
00116 alpha[i + j * order] = sum;
00117
if (i != j)
00118 alpha[j + i_order] = sum;
00119 }
00120 }
00121
for (i = 0; i < order; ++i)
00122 {
00123 sum = 0;
00124
for (j = 0; j < n; ++j)
00125 sum += OFstatic_cast(T3_, y[j]) * basis[i + j * order];
00126 beta[i] = sum;
00127 }
00128
if (
solve(alpha, beta, order))
00129 {
00130
for (i = 0; i < order; ++i)
00131 c[i] = beta[i];
00132 result = 1;
00133 }
00134 }
00135
delete[] basis;
00136
delete[] alpha;
00137
delete[] beta;
00138 }
00139
return result;
00140 }
00141
00142
00158 static int calculateValues(
const T1 xs,
00159
const T1 xe,
00160 T2 *y,
00161
const unsigned int n,
00162
const unsigned int o,
00163
const T3_ *c)
00164 {
00165
int result = 0;
00166
if ((y != NULL) && (c != NULL) && (n > 0) && (xe > xs))
00167 {
00168
register unsigned int i;
00169
register unsigned int j;
00170 T3_ x;
00171 T3_ x2;
00172 T3_ w;
00173
const T3_ xo = OFstatic_cast(T3_, xs);
00174
const T3_ xi = OFstatic_cast(T3_, (OFstatic_cast(T3_, xe) - OFstatic_cast(T3_, xs)) / (n - 1));
00175
for (i = 0; i < n; ++i)
00176 {
00177 x = xo + OFstatic_cast(T3_, i) * xi;
00178 x2 = 1;
00179 w = 0;
00180
for (j = 0; j <= o; ++j)
00181 {
00182 w += c[j] * x2;
00183 x2 *= x;
00184 }
00185
convertValue(w, y[i]);
00186 }
00187 result = 1;
00188 }
00189
return result;
00190 }
00191
00192
00193
private:
00194
00202 static void convertValue(
const T3_ input, Uint8 &output)
00203 {
00204 output = (input <= 0) ? 0 : ((input >= 255) ? 255 : OFstatic_cast(Uint8, input));
00205 }
00206
00214 static void convertValue(
const T3_ input, Sint8 &output)
00215 {
00216 output = (input <= -128) ? -128 : ((input >= 127) ? 127 : OFstatic_cast(Sint8, input));
00217 }
00218
00226 static void convertValue(
const T3_ input, Uint16 &output)
00227 {
00228 output = (input <= 0) ? 0 : ((input >= 65535) ? 65535 : OFstatic_cast(Uint16, input));
00229 }
00230
00238 static void convertValue(
const T3_ input, Sint16 &output)
00239 {
00240 output = (input <= -32768) ? -32768 : ((input >= 32767) ? 32767 : OFstatic_cast(Sint16, input));
00241 }
00242
00250 static inline void convertValue(
const T3_ input,
double &output)
00251 {
00252 output = OFstatic_cast(
double, input);
00253 }
00254
00264 static int solve(T3_ *a,
00265 T3_ *b,
00266
const unsigned int n)
00267 {
00268
int result = 0;
00269
if ((a != NULL) && (b != NULL) && (n > 0))
00270 {
00271
register unsigned int i;
00272
register unsigned int j;
00273
register unsigned int k;
00274
signed int pivot;
00275 T3_ mag;
00276 T3_ mag2;
00277 T3_ temp;
00278
for (i = 0; i < n; ++i)
00279 {
00280 mag = 0;
00281 pivot = -1;
00282
for (j = i; j < n; ++j)
00283 {
00284 mag2 = fabs(a[i + j * n]);
00285
if (mag2 > mag)
00286 {
00287 mag = mag2;
00288 pivot = j;
00289 }
00290 }
00291
if ((pivot == -1) || (mag == 0))
00292
break;
00293
else
00294 {
00295
const unsigned int piv = OFstatic_cast(
unsigned int, pivot);
00296
const unsigned int i_n = i * n;
00297
if (piv != i)
00298 {
00299
const unsigned int piv_n = piv * n;
00300
for (j = i; j < n; ++j)
00301 {
00302 temp = a[j + i_n];
00303 a[j + i_n] = a[j + piv_n];
00304 a[j + piv_n] = temp;
00305 }
00306 temp = b[i];
00307 b[i] = b[piv];
00308 b[piv] = temp;
00309 }
00310 mag = a[i + i_n];
00311
for (j = i; j < n; ++j)
00312 a[j + i_n] /= mag;
00313 b[i] /= mag;
00314
for (j = 0; j < n; ++j)
00315 {
00316
if (i == j)
00317
continue;
00318
const unsigned int j_n = j * n;
00319 mag2 = a[i + j_n];
00320
for (k = i; k < n; ++k)
00321 a[k + j_n] -= mag2 * a[k + i_n];
00322 b[j] -= mag2 * b[i];
00323 }
00324 result = 1;
00325 }
00326
00327 }
00328 }
00329
return result;
00330 }
00331 };
00332
00333
00334
#endif
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397