00001
#include <volume_io/internal_volume_io.h>
00002
#include <bicpl/numerical.h>
00003
00004 public void initialize_quadratic(
00005
int n_parameters,
00006 Real *constant_term,
00007
float *linear_terms[],
00008
float *square_terms[],
00009
int *n_cross_terms[],
00010
int **cross_parms[],
00011
float **cross_terms[] )
00012 {
00013
int parm;
00014
00015 ALLOC( *linear_terms, n_parameters );
00016 ALLOC( *square_terms, n_parameters );
00017 ALLOC( *n_cross_terms, n_parameters );
00018 ALLOC( *cross_parms, n_parameters );
00019 ALLOC( *cross_terms, n_parameters );
00020
00021 *constant_term = 0.0;
00022
00023 for_less( parm, 0, n_parameters )
00024 {
00025 (*linear_terms)[parm] = 0.0f;
00026 (*square_terms)[parm] = 0.0f;
00027 (*n_cross_terms)[parm] = 0;
00028 }
00029 }
00030
00031 public void zero_quadratic(
00032
int n_parameters,
00033 Real *constant_term,
00034
float linear_terms[],
00035
float square_terms[],
00036
int n_cross_terms[],
00037
int *cross_parms[],
00038
float *cross_terms[] )
00039 {
00040
int parm, n;
00041
00042 *constant_term = 0.0;
00043
00044 for_less( parm, 0, n_parameters )
00045 {
00046 linear_terms[parm] = 0.0f;
00047 square_terms[parm] = 0.0f;
00048 for_less( n, 0, n_cross_terms[parm] )
00049 cross_terms[parm][n] = 0.0f;
00050 }
00051 }
00052
00053 public void add_to_quadratic_cross_term(
00054
int *n_cross_terms[],
00055
int **cross_parms[],
00056
float **cross_terms[],
00057
int parm1,
00058
int parm2,
00059 Real value,
00060
int alloc_increment )
00061 {
00062
int p1, p2, t;
00063
00064 p1 = MIN( parm1, parm2 );
00065 p2 = MAX( parm1, parm2 );
00066
00067 for_less( t, 0, (*n_cross_terms)[p1] )
00068 {
00069
if( (*cross_parms)[p1][t] == p2 )
00070
break;
00071 }
00072
00073
if( t >= (*n_cross_terms)[p1] )
00074 {
00075 t = (*n_cross_terms)[p1];
00076 SET_ARRAY_SIZE( (*cross_terms)[p1], t, t+1, alloc_increment );
00077 SET_ARRAY_SIZE( (*cross_parms)[p1], t, t+1, alloc_increment );
00078 (*cross_parms)[p1][t] = p2;
00079 (*cross_terms)[p1][t] = 0.0f;
00080 ++(*n_cross_terms)[p1];
00081 }
00082
00083 (*cross_terms)[p1][t] += (
float) value;
00084 }
00085
00086 public void realloc_quadratic_cross_terms(
00087
int n_parameters,
00088
int n_cross_terms[],
00089
int **cross_parms[],
00090
float **cross_terms[] )
00091 {
00092
int p;
00093
00094 for_less( p, 0, n_parameters )
00095 {
00096
if( n_cross_terms[p] > 0 )
00097 {
00098 REALLOC( (*cross_terms)[p], n_cross_terms[p] );
00099 REALLOC( (*cross_parms)[p], n_cross_terms[p] );
00100 }
00101 }
00102 }
00103
00104 public void delete_quadratic(
00105
int n_parameters,
00106
float linear_terms[],
00107
float square_terms[],
00108
int n_cross_terms[],
00109
int *cross_parms[],
00110
float *cross_terms[] )
00111 {
00112
int p;
00113
00114 for_less( p, 0, n_parameters )
00115 {
00116
if( n_cross_terms[p] > 0 )
00117 {
00118 FREE( cross_parms[p] );
00119 FREE( cross_terms[p] );
00120 }
00121 }
00122
00123 FREE( linear_terms );
00124 FREE( square_terms );
00125 FREE( n_cross_terms );
00126 FREE( cross_terms );
00127 FREE( cross_parms );
00128 }
00129
00130 public Real
evaluate_quadratic(
00131
int n_parameters,
00132
float parameters[],
00133 Real constant,
00134
float linear[],
00135
float square[],
00136
int n_cross_terms[],
00137
int *cross_parms[],
00138
float *cross_terms[] )
00139 {
00140
int parm, c;
00141 Real fit, x, inc;
00142
00143 fit = constant;
00144
00145 for_less( parm, 0, n_parameters )
00146 {
00147 x = (Real) parameters[parm];
00148
00149 inc = (Real) linear[parm] + x * (Real) square[parm];
00150
00151 for_less( c, 0, n_cross_terms[parm] )
00152 inc += (Real) parameters[cross_parms[parm][c]] *
00153 (Real) cross_terms[parm][c];
00154
00155 fit += x * inc;
00156 }
00157
00158
return( fit );
00159 }
00160
00161 public void evaluate_quadratic_deriv(
00162
int n_parameters,
00163
float parameters[],
00164
float linear[],
00165
float square[],
00166
int n_cross_terms[],
00167
int *cross_parms[],
00168
float *cross_terms[],
00169
float deriv[] )
00170 {
00171
int parm, c, n_index;
00172
float tx, dx, x;
00173
00174 for_less( parm, 0, n_parameters )
00175 {
00176 x = parameters[parm];
00177
00178 dx = linear[parm] + 2.0f * x * square[parm];
00179
00180 for_less( c, 0, n_cross_terms[parm] )
00181 {
00182 n_index = cross_parms[parm][c];
00183 tx = cross_terms[parm][c];
00184
00185 deriv[n_index] += x * tx;
00186 dx += parameters[n_index] * tx;
00187 }
00188
00189 deriv[parm] += dx;
00190 }
00191 }