00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include "Quad.h"
00028 #include "f77-fcn.h"
00029 #include "lo-error.h"
00030 #include "quit.h"
00031 #include "sun-utils.h"
00032
00033 static integrand_fcn user_fcn;
00034 static float_integrand_fcn float_user_fcn;
00035
00036
00037
00038
00039
00040 int quad_integration_error = 0;
00041
00042 typedef octave_idx_type (*quad_fcn_ptr) (double*, int&, double*);
00043 typedef octave_idx_type (*quad_float_fcn_ptr) (float*, int&, float*);
00044
00045 extern "C"
00046 {
00047 F77_RET_T
00048 F77_FUNC (dqagp, DQAGP) (quad_fcn_ptr, const double&, const double&,
00049 const octave_idx_type&, const double*,
00050 const double&, const double&, double&,
00051 double&, octave_idx_type&, octave_idx_type&,
00052 const octave_idx_type&, const octave_idx_type&,
00053 octave_idx_type&, octave_idx_type*, double*);
00054
00055 F77_RET_T
00056 F77_FUNC (dqagi, DQAGI) (quad_fcn_ptr, const double&,
00057 const octave_idx_type&, const double&,
00058 const double&, double&, double&,
00059 octave_idx_type&, octave_idx_type&,
00060 const octave_idx_type&, const octave_idx_type&,
00061 octave_idx_type&, octave_idx_type*, double*);
00062
00063 F77_RET_T
00064 F77_FUNC (qagp, QAGP) (quad_float_fcn_ptr, const float&, const float&,
00065 const octave_idx_type&, const float*, const float&,
00066 const float&, float&, float&, octave_idx_type&,
00067 octave_idx_type&, const octave_idx_type&,
00068 const octave_idx_type&, octave_idx_type&,
00069 octave_idx_type*, float*);
00070
00071 F77_RET_T
00072 F77_FUNC (qagi, QAGI) (quad_float_fcn_ptr, const float&,
00073 const octave_idx_type&, const float&,
00074 const float&, float&, float&, octave_idx_type&,
00075 octave_idx_type&, const octave_idx_type&,
00076 const octave_idx_type&, octave_idx_type&,
00077 octave_idx_type*, float*);
00078 }
00079
00080 static octave_idx_type
00081 user_function (double *x, int& ierr, double *result)
00082 {
00083 BEGIN_INTERRUPT_WITH_EXCEPTIONS;
00084
00085 #if defined (__sparc) && defined (__GNUC__)
00086 double xx = access_double (x);
00087 #else
00088 double xx = *x;
00089 #endif
00090
00091 quad_integration_error = 0;
00092
00093 double xresult = (*user_fcn) (xx);
00094
00095 #if defined (__sparc) && defined (__GNUC__)
00096 assign_double (result, xresult);
00097 #else
00098 *result = xresult;
00099 #endif
00100
00101 if (quad_integration_error)
00102 ierr = -1;
00103
00104 END_INTERRUPT_WITH_EXCEPTIONS;
00105
00106 return 0;
00107 }
00108
00109 static octave_idx_type
00110 float_user_function (float *x, int& ierr, float *result)
00111 {
00112 BEGIN_INTERRUPT_WITH_EXCEPTIONS;
00113
00114 quad_integration_error = 0;
00115
00116 *result = (*float_user_fcn) (*x);
00117
00118 if (quad_integration_error)
00119 ierr = -1;
00120
00121 END_INTERRUPT_WITH_EXCEPTIONS;
00122
00123 return 0;
00124 }
00125
00126 double
00127 DefQuad::do_integrate (octave_idx_type& ier, octave_idx_type& neval, double& abserr)
00128 {
00129 octave_idx_type npts = singularities.capacity () + 2;
00130 double *points = singularities.fortran_vec ();
00131 double result = 0.0;
00132
00133 octave_idx_type leniw = 183*npts - 122;
00134 Array<octave_idx_type> iwork (dim_vector (leniw, 1));
00135 octave_idx_type *piwork = iwork.fortran_vec ();
00136
00137 octave_idx_type lenw = 2*leniw - npts;
00138 Array<double> work (dim_vector (lenw, 1));
00139 double *pwork = work.fortran_vec ();
00140
00141 user_fcn = f;
00142 octave_idx_type last;
00143
00144 double abs_tol = absolute_tolerance ();
00145 double rel_tol = relative_tolerance ();
00146
00147 F77_XFCN (dqagp, DQAGP, (user_function, lower_limit, upper_limit,
00148 npts, points, abs_tol, rel_tol, result,
00149 abserr, neval, ier, leniw, lenw, last,
00150 piwork, pwork));
00151
00152 return result;
00153 }
00154
00155 float
00156 DefQuad::do_integrate (octave_idx_type&, octave_idx_type&, float&)
00157 {
00158 (*current_liboctave_error_handler) ("incorrect integration function called");
00159 return 0.0;
00160 }
00161
00162 double
00163 IndefQuad::do_integrate (octave_idx_type& ier, octave_idx_type& neval, double& abserr)
00164 {
00165 double result = 0.0;
00166
00167 octave_idx_type leniw = 128;
00168 Array<octave_idx_type> iwork (dim_vector (leniw, 1));
00169 octave_idx_type *piwork = iwork.fortran_vec ();
00170
00171 octave_idx_type lenw = 8*leniw;
00172 Array<double> work (dim_vector (lenw, 1));
00173 double *pwork = work.fortran_vec ();
00174
00175 user_fcn = f;
00176 octave_idx_type last;
00177
00178 octave_idx_type inf;
00179 switch (type)
00180 {
00181 case bound_to_inf:
00182 inf = 1;
00183 break;
00184
00185 case neg_inf_to_bound:
00186 inf = -1;
00187 break;
00188
00189 case doubly_infinite:
00190 inf = 2;
00191 break;
00192
00193 default:
00194 assert (0);
00195 break;
00196 }
00197
00198 double abs_tol = absolute_tolerance ();
00199 double rel_tol = relative_tolerance ();
00200
00201 F77_XFCN (dqagi, DQAGI, (user_function, bound, inf, abs_tol, rel_tol,
00202 result, abserr, neval, ier, leniw, lenw,
00203 last, piwork, pwork));
00204
00205 return result;
00206 }
00207
00208 float
00209 IndefQuad::do_integrate (octave_idx_type&, octave_idx_type&, float&)
00210 {
00211 (*current_liboctave_error_handler) ("incorrect integration function called");
00212 return 0.0;
00213 }
00214
00215 double
00216 FloatDefQuad::do_integrate (octave_idx_type&, octave_idx_type&, double&)
00217 {
00218 (*current_liboctave_error_handler) ("incorrect integration function called");
00219 return 0.0;
00220 }
00221
00222 float
00223 FloatDefQuad::do_integrate (octave_idx_type& ier, octave_idx_type& neval, float& abserr)
00224 {
00225 octave_idx_type npts = singularities.capacity () + 2;
00226 float *points = singularities.fortran_vec ();
00227 float result = 0.0;
00228
00229 octave_idx_type leniw = 183*npts - 122;
00230 Array<octave_idx_type> iwork (dim_vector (leniw, 1));
00231 octave_idx_type *piwork = iwork.fortran_vec ();
00232
00233 octave_idx_type lenw = 2*leniw - npts;
00234 Array<float> work (dim_vector (lenw, 1));
00235 float *pwork = work.fortran_vec ();
00236
00237 float_user_fcn = ff;
00238 octave_idx_type last;
00239
00240 float abs_tol = single_precision_absolute_tolerance ();
00241 float rel_tol = single_precision_relative_tolerance ();
00242
00243 F77_XFCN (qagp, QAGP, (float_user_function, lower_limit, upper_limit,
00244 npts, points, abs_tol, rel_tol, result,
00245 abserr, neval, ier, leniw, lenw, last,
00246 piwork, pwork));
00247
00248 return result;
00249 }
00250
00251 double
00252 FloatIndefQuad::do_integrate (octave_idx_type&, octave_idx_type&, double&)
00253 {
00254 (*current_liboctave_error_handler) ("incorrect integration function called");
00255 return 0.0;
00256 }
00257
00258 float
00259 FloatIndefQuad::do_integrate (octave_idx_type& ier, octave_idx_type& neval, float& abserr)
00260 {
00261 float result = 0.0;
00262
00263 octave_idx_type leniw = 128;
00264 Array<octave_idx_type> iwork (dim_vector (leniw, 1));
00265 octave_idx_type *piwork = iwork.fortran_vec ();
00266
00267 octave_idx_type lenw = 8*leniw;
00268 Array<float> work (dim_vector (lenw, 1));
00269 float *pwork = work.fortran_vec ();
00270
00271 float_user_fcn = ff;
00272 octave_idx_type last;
00273
00274 octave_idx_type inf;
00275 switch (type)
00276 {
00277 case bound_to_inf:
00278 inf = 1;
00279 break;
00280
00281 case neg_inf_to_bound:
00282 inf = -1;
00283 break;
00284
00285 case doubly_infinite:
00286 inf = 2;
00287 break;
00288
00289 default:
00290 assert (0);
00291 break;
00292 }
00293
00294 float abs_tol = single_precision_absolute_tolerance ();
00295 float rel_tol = single_precision_relative_tolerance ();
00296
00297 F77_XFCN (qagi, QAGI, (float_user_function, bound, inf, abs_tol, rel_tol,
00298 result, abserr, neval, ier, leniw, lenw,
00299 last, piwork, pwork));
00300
00301 return result;
00302 }