;;; Scheme bindings to Multidimensional Interpolation with Radial Basis Functions
;;; by John Burkardt
;;;
;;; This program is free software: you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation, either version 3 of the License, or
;;; (at your option) any later version.
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;; You should have received a copy of the GNU General Public License
;;; along with this program. If not, see .
;;; -------------------------------------------------------------------------------
(module
rbf
(
make-interpolant
eval-interpolant
)
(import scheme (chicken base) (chicken foreign) (chicken format) srfi-4)
(define-record-type
(make-RBFInterpolant rank basis scale npoints xpoints weights)
RBFInterpolant?
(rank RBFInterpolant-rank)
(basis RBFInterpolant-basis)
(scale RBFInterpolant-scale)
(npoints RBFInterpolant-npoints)
(xpoints RBFInterpolant-xpoints)
(weights RBFInterpolant-weights))
#>
#include
<#
(define cphi1 (foreign-value "phi1" (function void (int (c-pointer double) double (c-pointer double)))))
(define cphi2 (foreign-value "phi2" (function void (int (c-pointer double) double (c-pointer double)))))
(define cphi3 (foreign-value "phi3" (function void (int (c-pointer double) double (c-pointer double)))))
(define cphi4 (foreign-value "phi4" (function void (int (c-pointer double) double (c-pointer double)))))
;; Evaluates a radial basis function interpolant.
;; Input, int M, the spatial dimension.
;;
;; Input, int ND, the number of data points.
;;
;; Input, double XD[M*ND], the data points.
;;
;; Input, double R0, a scale factor. R0 should be larger than the typical
;; separation between points, but smaller than the maximum separation.
;; The value of R0 has a significant effect on the resulting interpolant.
;;
;; Input, void PHI ( int N, double R[], double R0, double V[] ), a
;; function to evaluate the radial basis functions.
;;
;; Input, double W[ND], the weights, as computed by RBF_WEIGHTS.
;;
;; Input, int NI, the number of interpolation points.
;;
;; Input, double XI[M*NI], the interpolation points.
;;
;; Output, double RBF_INTERP_ND[NI], the interpolated values.
;; void rbf_interp_nd ( int m, int nd, double xd[], double r0,
;; void phi ( int n, double r[], double r0, double v[] ), double w[],
;; int ni, double xi[], double fi[] );
(define crbf_interp_nd (foreign-lambda void "rbf_interp_nd"
int int f64vector double
(function void (int (c-pointer double) double (c-pointer double)))
f64vector int f64vector f64vector))
;; Computes weights for radial basis function interpolation.
;; Input, int M, the spatial dimension.
;;
;; Input, int ND, the number of data points.
;;
;; Input, double XD[M*ND], the data points.
;;
;; Input, double R0, a scale factor. R0 should be larger than the typical
;; separation between points, but smaller than the maximum separation.
;; The value of R0 has a significant effect on the resulting interpolant.
;;
;; Input, void PHI ( int N, double R[], double R0, double V[] ), a
;; function to evaluate the radial basis functions.
;;
;; Input, double FD[ND], the function values at the data points.
;;
;; Output, double RBF_WEIGHT[ND], the weights.
;; void rbf_weight ( int m, int nd, double xd[], double r0,
;; void phi ( int n, double r[], double r0, double v[] ),
;; double fd[], double fi[] );
(define crbf_weight (foreign-lambda void "rbf_weight"
int int f64vector double
(function void (int f64vector double f64vector))
f64vector f64vector))
(define (make-interpolant basis m scale xpoints ypoints)
(let ((npoints (quotient (f64vector-length xpoints) m)))
(assert (= npoints (f64vector-length ypoints)))
(let ((weights (make-f64vector npoints))
(basis-ptr (case basis
((mq multiquadric) cphi1)
((imq inverse-multiquadric) cphi2)
((tp thin-plate) cphi3)
((ga gaussian) cphi4)
(else (error 'make-interpolant "unknown basis" basis)))))
(crbf_weight m npoints xpoints scale basis-ptr ypoints weights)
(make-RBFInterpolant m basis scale npoints xpoints weights))
))
(define (eval-interpolant interpolant ipoints)
(let* (
(m (RBFInterpolant-rank interpolant))
(basis (RBFInterpolant-basis interpolant))
(xpoints (RBFInterpolant-xpoints interpolant))
(nd (RBFInterpolant-npoints interpolant))
(scale (RBFInterpolant-scale interpolant))
(weights (RBFInterpolant-weights interpolant))
(ni (quotient (f64vector-length ipoints) m))
(fpoints (make-f64vector ni))
(basis-ptr (case basis
((mq multiquadric) cphi1)
((imq inverse-multiquadric) cphi2)
((tp thin-plate) cphi3)
((ga gaussian) cphi4)
(else (error 'make-interpolant "unknown basis" basis))))
)
(crbf_interp_nd m nd xpoints scale basis-ptr weights ni ipoints fpoints)
fpoints))
) ; end of library