dicrvfit.h

00001 /*
00002  *
00003  *  Copyright (C) 1996-2005, OFFIS
00004  *
00005  *  This software and supporting documentation were developed by
00006  *
00007  *    Kuratorium OFFIS e.V.
00008  *    Healthcare Information and Communication Systems
00009  *    Escherweg 2
00010  *    D-26121 Oldenburg, Germany
00011  *
00012  *  THIS SOFTWARE IS MADE AVAILABLE,  AS IS,  AND OFFIS MAKES NO  WARRANTY
00013  *  REGARDING  THE  SOFTWARE,  ITS  PERFORMANCE,  ITS  MERCHANTABILITY  OR
00014  *  FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES  OR
00015  *  ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND
00016  *  PERFORMANCE OF THE SOFTWARE IS WITH THE USER.
00017  *
00018  *  Module:  dcmimgle
00019  *
00020  *  Author:  Joerg Riesmeier
00021  *
00022  *  Purpose: DiCurveFitting (header/implementation)
00023  *
00024  *  Last Update:      $Author: meichel $
00025  *  Update Date:      $Date: 2005/12/08 16:47:35 $
00026  *  CVS/RCS Revision: $Revision: 1.17 $
00027  *  Status:           $State: Exp $
00028  *
00029  *  CVS/RCS Log at end of file
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  *  macro definitions  *
00046  *---------------------*/
00047 
00048 // SunCC 4.x does not support default values for template types :-/
00049 #define T3_ double
00050 
00051 
00052 /*------------------*
00053  *  template class  *
00054  *------------------*/
00055 
00058 template <class T1, class T2 /*, class T3 = double*/>
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]);          // cut value if necessary
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  * CVS/RCS Log:
00340  * $Log: dicrvfit.h,v $
00341  * Revision 1.17  2005/12/08 16:47:35  meichel
00342  * Changed include path schema for all DCMTK header files
00343  *
00344  * Revision 1.16  2003/12/23 15:53:22  joergr
00345  * Replaced post-increment/decrement operators by pre-increment/decrement
00346  * operators where appropriate (e.g. 'i++' by '++i').
00347  *
00348  * Revision 1.15  2003/12/08 18:54:16  joergr
00349  * Adapted type casts to new-style typecast operators defined in ofcast.h.
00350  * Removed leading underscore characters from preprocessor symbols (reserved
00351  * symbols). Updated copyright header.
00352  *
00353  * Revision 1.14  2002/11/27 14:08:03  meichel
00354  * Adapted module dcmimgle to use of new header file ofstdinc.h
00355  *
00356  * Revision 1.13  2002/11/26 18:18:35  joergr
00357  * Replaced include for "math.h" with <math.h> to avoid inclusion of math.h in
00358  * the makefile dependencies.
00359  *
00360  * Revision 1.12  2002/10/31 10:10:45  meichel
00361  * Added workaround for a bug in the Sparc optimizer in gcc 3.2
00362  *
00363  * Revision 1.11  2002/07/19 08:23:12  joergr
00364  * Added missing doc++ comments.
00365  *
00366  * Revision 1.10  2002/07/18 12:28:11  joergr
00367  * Added explicit type casts to keep Sun CC 2.0.1 quiet.
00368  *
00369  * Revision 1.9  2001/06/01 15:49:40  meichel
00370  * Updated copyright header
00371  *
00372  * Revision 1.8  2000/03/08 16:24:14  meichel
00373  * Updated copyright header.
00374  *
00375  * Revision 1.7  2000/03/06 15:58:39  meichel
00376  * Changed static template functions to methods. Required for xlC 1.0 on AIX 3.2.
00377  *
00378  * Revision 1.6  1999/10/21 08:29:41  joergr
00379  * Renamed template type definition from 'T3' to 'T3_' to avoid naming
00380  * conflicts.
00381  *
00382  * Revision 1.5  1999/10/20 18:38:49  joergr
00383  * Eliminated default values for template types since this features is not
00384  * supported by SunCC 4.x (temporarily introduced '#define' instead).
00385  *
00386  * Revision 1.4  1999/10/20 10:32:44  joergr
00387  * Added generic specification for template function convertValue to avoid
00388  * compiler warnings reported by MSVC (with additional options?).
00389  *
00390  * Revision 1.3  1999/10/18 10:15:15  joergr
00391  * Fixed typos.
00392  *
00393  * Revision 1.2  1999/10/15 09:38:31  joergr
00394  * Fixed typos.
00395  *
00396  * Revision 1.1  1999/10/14 19:04:09  joergr
00397  * Added new template class that supports polynomial curve fitting algorithm.
00398  *
00399  *
00400  */


Generated on 20 Dec 2005 for OFFIS DCMTK Version 3.5.4 by Doxygen 1.4.5