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 "dcmtk/config/osconfig.h"
00038 #include "dcmtk/ofstd/ofcast.h"
00039
00040 #define INCLUDE_CMATH
00041 #include "dcmtk/ofstd/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
00398
00399
00400