diff options
author | jthorn <jthorn@df1f8a13-aa1d-4dd4-9681-27ded5b42416> | 2002-08-20 16:46:06 +0000 |
---|---|---|
committer | jthorn <jthorn@df1f8a13-aa1d-4dd4-9681-27ded5b42416> | 2002-08-20 16:46:06 +0000 |
commit | e617c3d0032b85d8bc369fc4e57b3aacc3190263 (patch) | |
tree | f8c3bd4f3cc0ba662bd0d6323dbe6e840af3ada6 /src/GeneralizedPolynomial-Uniform/interpolate.maple | |
parent | d5b49cab5a99a22dd26bd55fcf65659aa7f7e020 (diff) |
switch from $Id:$ to $Header:$
git-svn-id: http://svn.cactuscode.org/arrangements/CactusBase/LocalInterp/trunk@93 df1f8a13-aa1d-4dd4-9681-27ded5b42416
Diffstat (limited to 'src/GeneralizedPolynomial-Uniform/interpolate.maple')
-rw-r--r-- | src/GeneralizedPolynomial-Uniform/interpolate.maple | 139 |
1 files changed, 119 insertions, 20 deletions
diff --git a/src/GeneralizedPolynomial-Uniform/interpolate.maple b/src/GeneralizedPolynomial-Uniform/interpolate.maple index 23ca9e0..3f627db 100644 --- a/src/GeneralizedPolynomial-Uniform/interpolate.maple +++ b/src/GeneralizedPolynomial-Uniform/interpolate.maple @@ -1,5 +1,5 @@ # interpolate.maple -- compute interpolation formulas/coefficients -# $Id$ +# $Header$ # # <<<representation of numbers, data values, etc>>> @@ -85,21 +85,70 @@ end proc; # # This function computes a Hermite polynomial interpolant in any -# number of dimensions. +# number of dimensions. This is a polynomial which +# has values which match the given data DATA() at a specified set of +# points, and +# * has derivatives which match the specified finite-difference derivatives +# of the given data DATA() at a specified set of points +# +# For the derivative matching, we actually match all possible products +# of 1st derivatives, i.e. in 2-D we match dx, dy, and dxy, in 3-D we +# match dx, dy, dz, dxy, dxz, dyz, and dxyz, etc etc. # # Arguments: # fn = The interpolation function. This should be a procedure in the # coordinates, having the coefficients as global variables. For # example, -# proc(x,y) c00 + c10*x + c01*y end proc +# proc(x,y) +# + c03*y^3 + c13*x*y^3 + c23*x^2*y^3 + c33*x^3*y^3 +# + c02*y^2 + c12*x*y^2 + c22*x^2*y^2 + c32*x^3*y^2 +# + c01*y + c11*x*y + c21*x^2*y + c31*x^3*y +# + c00 + c10*x + c20*x^2 + c30*x^3 +# end proc; # coeff_list = A set of the interpolation coefficients (coefficients in -# the interpolation function), for example [c00, c10, c01]. +# the interpolation function), for example +# [ +# c03, c13, c23, c33, +# c02, c12, c22, c32, +# c01, c11, c21, c31, +# c00, c10, c20, c30 +# ] # coord_list = A list of the coordinates (independent variables in the # interpolation function), for example [x,y]. -# posn_list = A list of positions (each a list of numeric values) where the -# interpolant is to use data, for example hypercube([0,0], [1,1]). -# Any positions may be used; if they're redundant (as in the -# example) the least-squares interpolant is computed. +# deriv_coord_list = A list of lists of coordinates specifying which +# derivatives are computed by the deriv_proc_list[] +# procedures, for example +# [[x], [y], [x,y]] +# deriv_proc_list = A list of procedures for computing finite-difference +# derivatives. Each procedure should take N_dims integer +# arguments specifying an evaluation point, and return +# a suitable linear combination of the DATA() for the +# derivative at that point. For example +# example, +# [ +# proc(i::integer, j::integer) +# - 1/2*DATA(i-1,j) + 1/2*DATA(i+1,j) +# end proc +# , +# proc(i::integer, j::integer) +# - 1/2*DATA(i,j-1) + 1/2*DATA(i,j+1) +# end proc +# , +# proc(i::integer, j::integer) +# - 1/4*DATA(i-1,j+1) + 1/4*DATA(i+1,j+1) +# + 1/4*DATA(i-1,j-1) - 1/4*DATA(i+1,j-1) +# end proc +# ] +# fn_posn_list = A list of positions (each a list of numeric values) +# where the interpolant is to match the given data DATA(), +# for example +# [[0,0], [0,1], [1,0], [1,1]] +# deriv_posn_list = A list of positions (each a list of numeric values) +# where the interpolant is to match each possible product +# of 1st derivatives"1st" +# derivatives (actually all derivatives the given data DATA(), +# for example +# [[0,0], [0,1], [1,0], [1,1]] # # Results: # This function returns the interpolating polynomial, in the form of @@ -107,20 +156,71 @@ end proc; # Hermite_polynomial_interpolant := proc( - fn::procedure, coeff_list::list(name), - coord_list::list(name), posn_list::list(list(numeric)) + fn::procedure, coeff_list::list(name), coord_list::list(name), + deriv_coord_list::list(list(name)), fd_deriv_proc_list::list(procedure), + fn_posn_list::list(list(numeric)), deriv_posn_list::list(list(numeric)) ) -local posn, data_eqns, coeff_eqns; +local fn_eset, + fn_expr, deriv_eset; + +# set of equations {fn(posn) = DATA(posn)} +fn_eset := map( + # return equation that fn(this point) = DATA(this point) + proc(posn::list(integer)) + fn(op(posn)) = 'DATA'(op(posn)); + end proc + , + {op(fn_posn_list)} + ); + +# set of sets of equations +# { +# { deriv1(posn1) = fd_deriv1(posn1), +# deriv2(posn1) = fd_deriv2(posn1), +# ... }, +# { deriv1(posn2) = fd_deriv1(posn2), +# deriv2(posn2) = fd_deriv2(posn2), +# ... }, +# ... +# } +fn_expr := fn(op(coord_list)); +map( + # return set of equations + # {deriv(posn) = fd_deriv(posn)} + # for this point + proc(posn::list(integer)) + { + op( + zip( + # return equation that + # deriv(posn) = fd_deriv(posn) + # for this deriv and this point + proc(deriv_coords::list(name), fd_deriv_proc::procedure) + local fn_deriv_proc; + fn_deriv_proc := unapply( diff(fn_expr,deriv_coords), + op(coord_list) ); + fn_deriv_proc(op(posn)) = fd_deriv_proc(op(posn)); + end proc + , + [op(deriv_coord_list)] + , + [op(fd_deriv_proc_list)] + ) + ) + } + end proc + , + {op(deriv_posn_list)} + ); -# coefficients of interpolating polynomial -data_eqns := { seq( fn(op(posn))='DATA'(op(posn)) , posn=posn_list ) }; -coeff_eqns := linalg[leastsqrs](data_eqns, {op(coeff_list)}); -if (has(coeff_eqns, '_t')) - then error "interpolation coefficients aren't uniquely determined!"; -end if; +# set of equations {deriv-i(posn-j) = fd_deriv-i(posn-j)} +deriv_eset := `union`(op(%)); + +# solve equations for coeffs +solve(fn_eset union deriv_eset, {op(coeff_list)}); # interpolant as a polynomial in the coordinates -return subs(coeff_eqns, eval(fn))(op(coord_list)); +return subs(%, eval(fn))(op(coord_list)); end proc; ################################################################################ @@ -133,8 +233,7 @@ end proc; # Arguments: # interpolant = The interpolating polynomial (an algebraic expression # in the coordinates and the data values). -# posn_list = The same list of positions as was used to compute the -# interpolating polynomial. +# posn_list = The same list of data positions used in the interpolant. # # Results: # This function returns the coefficients, as a list of equations of the |