using a numerical (e.g., trapezoidal) method. Is should be understood that there is a mathematical relationship between x and y, e.g., x= g(y), and this relationship is what we want to find out numerically.
Numerical methods return functions as an explicit set of pairs (x,
y) instead of as an analytic expression. We need to supply the
boundaries x0 and xn-1 of the interval in which the function
is to be calculated, and the number of points n to be taken into
account in that interval. Thus, n is the number of integration
steps, x0 and xn-1 the integration limits, and
the integration step--the distance between
two consecutive sampling points. Then the equation
can be used to numerically approximate the function y = g(x) (this is the expression of the trapezoidal method of integration).
Note that the expression for yi+1 involves yi+1 itself. The effect of the above formula, applied to all the points in the integration segment, is to originate a set of equations; for them to be solved we need at least one yi to be defined. The top level call gives us access both to y0 and yn-1, but setting any yiwill actually suffice.
Modelling the recurrence equation:
yn1(H, Xi, Yi, Xi1, Yi1):- Yi1 = Yi + H*(Fi+Fi1)/2, Xi1 = Xi + H, f(Xi, Yi, Fi), f(Xi1, Yi1, Fi1).
The recurrent loop relates points of yi = g(xi) using the previous predicate:
loop(_H, Xn, Yn, Xn, Yn, [Xn], [Yn]). loop( H, Xi, Yi, Xn, Yn, [Xi|Xs], [Yi|Ys]):- lelin(Xi, Xn), yn1(H, Xi, Yi, Xi1, Yi1), loop(H, Xi1, Yi1, Xn, Yn, Xs, Ys).
In this predicate the first clause implements the stop condition of the loop, and the recursive clause extends the recurrence equation to the selected interval:
The top level call computes the integration step, the list of xcoordinates and the corresponding y values, and writes the result. We could return the results as two lists of x coordinates and yvalues, but we will do a little of formatting:
sv(X0, Y0, Xn, Yn, N):- H = (Xn - X0)/N, loop(H, X0, Y0, Xn, Yn, Xs, Ys), write_res(Xs, Ys). write_res([], []). write_res([X|Xs], [Y|Ys]):- write(y(X) = Y), nl, write_res(Xs, Ys).
To solve, for example, y' = -2xy, we just need to define the relationship among x, y and f(x,y):
f(X, Y, -2*X*Y).
(the program above will work for other differential
equations just changing this clause). An example call, where the
integration bounds are -3 and 3, twenty sampling
points where used, and
is the following:
?- sv(-3, 1/2000, 3, Yn, 20). y(-3)=1/2000 y(-27/10)=1/200 y(-12/5)=181/5600 y(-21/10)=7783/51800 y(-9/5)=1268629/2382800 y(-3/2)=1268629/851000 y(-6/5)=36790241/10892800 y(-9/10)=625434097/99396800 y(-3/5)=79430130319/8150537600 y(-3/10)=4686377688821/370849460800 y(0)=510815168081489/37084946080000 y(3/10)=4686377688821/370849460800 y(3/5)=79430130319/8150537600 y(9/10)=625434097/99396800 y(6/5)=36790241/10892800 y(3/2)=1268629/851000 y(9/5)=1268629/2382800 y(21/10)=7783/51800 y(12/5)=181/5600 y(27/10)=1/200 y(3)=1/2000 Yn = 1/2000.