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: DiCubicSpline Function/Interpolation (Header/Implementation) 00023 * 00024 * Last Update: $Author: meichel $ 00025 * Update Date: $Date: 2005/12/08 16:48:10 $ 00026 * CVS/RCS Revision: $Revision: 1.19 $ 00027 * Status: $State: Exp $ 00028 * 00029 * CVS/RCS Log at end of file 00030 * 00031 */ 00032 00033 00034 #ifndef DISPLINT_H 00035 #define DISPLINT_H 00036 00037 #include "dcmtk/config/osconfig.h" 00038 #include "dcmtk/ofstd/ofcast.h" 00039 00040 00041 /*--------------------* 00042 * macro definition * 00043 *--------------------*/ 00044 00045 // SunCC 4.x does not support default values for template types :-/ 00046 #define T3_ double 00047 00048 00049 /*------------------* 00050 * template class * 00051 *------------------*/ 00052 00055 template <class T1, class T2 /*, class T3 = double*/> 00056 class DiCubicSpline 00057 { 00058 00059 public: 00060 00075 static int Function(const T1 *x, 00076 const T2 *y, 00077 const unsigned int n, 00078 T3_ *y2, 00079 const T3_ yp1 = 1.0e30, 00080 const T3_ ypn = 1.0e30) 00081 { 00082 if ((x != NULL) && (y != NULL) && (n > 0) && (y2 != NULL)) 00083 { 00084 T3_ *u = new T3_[n]; // temporary vector 00085 if (u != NULL) 00086 { 00087 register unsigned int i; 00088 T3_ p, qn, sig, un; 00089 if (yp1 > 0.99e30) // ignore value for first derivative at point 1 00090 y2[0] = u[0] = 0.0; 00091 else 00092 { 00093 y2[0] = -0.5; 00094 u[0] = (3.0 / (OFstatic_cast(T3_, x[1]) - OFstatic_cast(T3_, x[0]))) * 00095 ((OFstatic_cast(T3_, y[1]) - OFstatic_cast(T3_, y[0])) / 00096 (OFstatic_cast(T3_, x[1]) - OFstatic_cast(T3_, x[0])) - yp1); 00097 } 00098 for (i = 1; i < n - 1; ++i) 00099 { 00100 sig = (OFstatic_cast(T3_, x[i]) - OFstatic_cast(T3_, x[i - 1])) / 00101 (OFstatic_cast(T3_, x[i + 1]) - OFstatic_cast(T3_, x[i - 1])); 00102 p = sig * y2[i - 1] + 2.0; 00103 y2[i] = (sig - 1.0) / p; 00104 u[i] = (OFstatic_cast(T3_, y[i + 1]) - OFstatic_cast(T3_, y[i])) / 00105 (OFstatic_cast(T3_, x[i + 1]) - OFstatic_cast(T3_, x[i])) - 00106 (OFstatic_cast(T3_, y[i]) - OFstatic_cast(T3_, y[i - 1])) / 00107 (OFstatic_cast(T3_, x[i]) - OFstatic_cast(T3_, x[i - 1])); 00108 u[i] = (6.0 * u[i] / (OFstatic_cast(T3_, x[i + 1]) - 00109 OFstatic_cast(T3_, x[i - 1])) - sig * u[i - 1]) / p; 00110 } 00111 if (ypn > 0.99e30) // ignore value for first derivative at point 1 00112 qn = un = 0.0; 00113 else 00114 { 00115 qn = 0.5; 00116 un = (3.0 / (OFstatic_cast(T3_, x[n - 1]) - OFstatic_cast(T3_, x[n - 2]))) * 00117 (ypn - (OFstatic_cast(T3_, y[n - 1]) - OFstatic_cast(T3_, y[n - 2])) / 00118 (OFstatic_cast(T3_, x[n - 1]) - OFstatic_cast(T3_, x[n - 2]))); 00119 } 00120 y2[n - 1] = (un - qn * u[n - 2]) / (qn * y2[n - 2] + 1.0); 00121 for (i = n - 1; i > 0; --i) 00122 y2[i - 1] = y2[i - 1] * y2[i] + u[i - 1]; 00123 delete[] u; 00124 return 1; 00125 } 00126 } 00127 return 0; 00128 } 00129 00130 00146 static int Interpolation(const T1 *xa, 00147 const T2 *ya, 00148 const T3_ *y2a, 00149 const unsigned int na, 00150 const T1 *x, 00151 T2 *y, 00152 const unsigned int n) 00153 { 00154 if ((xa != NULL) && (ya != NULL) && (y2a != NULL) && (na > 0) && (x != NULL) && (y != NULL) && (n > 0)) 00155 { 00156 register unsigned int k, i; 00157 register unsigned int klo = 0; 00158 register unsigned int khi = na - 1; 00159 T3_ h, b, a; 00160 for (i = 0; i < n; ++i) 00161 { 00162 if ((xa[klo] > x[i]) || (xa[khi] < x[i])) // optimization 00163 { 00164 klo = 0; 00165 khi = na - 1; 00166 } 00167 while (khi - klo > 1) // search right place in the table, if necessary 00168 { 00169 k = (khi + klo) >> 1; 00170 if (xa[k] > x[i]) 00171 khi = k; 00172 else 00173 klo = k; 00174 } 00175 if (xa[khi] == x[i]) // optimization: use known values 00176 y[i] = ya[khi]; 00177 else 00178 { 00179 h = OFstatic_cast(T3_, xa[khi]) - OFstatic_cast(T3_, xa[klo]); 00180 if (h == 0.0) // bad xa input, values must be distinct ! 00181 return 0; 00182 a = (OFstatic_cast(T3_, xa[khi]) - OFstatic_cast(T3_, x[i])) / h; 00183 b = (OFstatic_cast(T3_, x[i]) - OFstatic_cast(T3_, xa[klo])) / h; 00184 y[i] = OFstatic_cast(T2, a * OFstatic_cast(T3_, ya[klo]) + b * OFstatic_cast(T3_, ya[khi]) + 00185 ((a * a * a - a) * y2a[klo] + (b * b * b - b) * y2a[khi]) * (h * h) / 6.0); 00186 } 00187 } 00188 return 1; 00189 } 00190 return 0; 00191 } 00192 }; 00193 00194 00195 #endif 00196 00197 00198 /* 00199 * 00200 * CVS/RCS Log: 00201 * $Log: displint.h,v $ 00202 * Revision 1.19 2005/12/08 16:48:10 meichel 00203 * Changed include path schema for all DCMTK header files 00204 * 00205 * Revision 1.18 2003/12/23 15:53:22 joergr 00206 * Replaced post-increment/decrement operators by pre-increment/decrement 00207 * operators where appropriate (e.g. 'i++' by '++i'). 00208 * 00209 * Revision 1.17 2003/12/08 19:20:47 joergr 00210 * Adapted type casts to new-style typecast operators defined in ofcast.h. 00211 * Removed leading underscore characters from preprocessor symbols (reserved 00212 * symbols). Updated copyright header. 00213 * 00214 * Revision 1.16 2002/07/18 12:30:59 joergr 00215 * Removed unused code. 00216 * 00217 * Revision 1.15 2001/06/01 15:49:51 meichel 00218 * Updated copyright header 00219 * 00220 * Revision 1.14 2000/03/08 16:24:24 meichel 00221 * Updated copyright header. 00222 * 00223 * Revision 1.13 2000/02/02 14:33:54 joergr 00224 * Replaced 'delete' statements by 'delete[]' for objects created with 'new[]'. 00225 * 00226 * Revision 1.12 1999/10/21 08:29:42 joergr 00227 * Renamed template type definition from 'T3' to 'T3_' to avoid naming 00228 * conflicts. 00229 * 00230 * Revision 1.11 1999/10/20 18:38:50 joergr 00231 * Eliminated default values for template types since this features is not 00232 * supported by SunCC 4.x (temporarily introduced '#define' instead). 00233 * 00234 * Revision 1.10 1999/10/15 09:38:31 joergr 00235 * Fixed typos. 00236 * 00237 * Revision 1.9 1999/10/14 19:05:17 joergr 00238 * Fixed typo. 00239 * 00240 * Revision 1.8 1999/10/01 13:25:35 joergr 00241 * Enhanced template class for cubic spline interpolation to support 00242 * non-floating point classes/types as y-coordinates. 00243 * 00244 * Revision 1.7 1999/07/23 14:11:25 joergr 00245 * Added preliminary support for 2D bi-cubic spline interpolation (currently 00246 * not used). 00247 * 00248 * Revision 1.6 1999/05/03 11:09:31 joergr 00249 * Minor code purifications to keep Sun CC 2.0.1 quiet. 00250 * 00251 * Revision 1.5 1999/04/29 13:49:08 joergr 00252 * Renamed class CubicSpline to DiCubicSpline. 00253 * 00254 * Revision 1.4 1999/03/24 17:20:26 joergr 00255 * Added/Modified comments and formatting. 00256 * 00257 * Revision 1.3 1999/03/22 08:52:43 joergr 00258 * Added/Changed comments. 00259 * 00260 * Revision 1.2 1999/02/25 16:17:16 joergr 00261 * Initialize local variables to avoid compiler warnings (reported by gcc 00262 * 2.7.2.1 on Linux). 00263 * 00264 * Revision 1.1 1999/02/11 16:36:29 joergr 00265 * Renamed file to indicate the use of templates. 00266 * 00267 * Revision 1.2 1999/02/09 14:21:54 meichel 00268 * Removed default parameters from template functions, required for Sun CC 4.2 00269 * 00270 * Revision 1.1 1999/02/04 17:59:23 joergr 00271 * Added support for calibration according to Barten transformation (incl. 00272 * a DISPLAY file describing the monitor characteristic). 00273 * 00274 * 00275 */