0
votes

I want my Taylor method to be able to prompt for functions when executed. I tried using input(prompt) as described in MATLAB's documentation. The problem is, it prompts me to enter the function every time it's encountered in the code.

function taylorMethod(a, b, h, alpha, order)

    f = @(t, y) input('Enter f(t, y): ');
    fPrime = @(t, y) input('Enter f''(t, y): ');
    taylor2 = @(t, w) f(t, w) + h/2*fPrime(t, w);

    if order > 2
        f2Prime = @(t, y) input('Enter f''''(t, y): ');
        taylor3 = @(t, w) taylor2(t, w) + h^2/factorial(3)*f2Prime(t, w);
        if order == 4
            f3Prime = @(t, y) input('Enter f''''''(t, y): ');
            taylor4 = @(t, w) taylor3(t, w) + h^3/factorial(4)*f3Prime(t, w);
        end
    end

    function res = t(i)
        if i == a
            res = a;
            return;
        end
        res = h + t(i - 1);
    end

    idx = a;
    for i = a:h:b
        fprintf('i = %d; t_i = %.2f; w(i) = %.10f\n', idx, t(idx), w(idx));
        idx = idx + 1;
    end


    function res = w(i)
        j = i - 1;
        if i == a
            res = alpha;
            return;
        end
        if order == 2
            res = w(j) + h*taylor2(t(j), w(j));
        elseif order == 3
            res = w(j) + h*taylor3(t(j), w(j));
        elseif order == 4
            res = w(j) + h*taylor4(t(j), w(j));
        end
        return;
    end

end

I also tried to store the user input in a string like this:

fString = input('Enter f(t, y): ', 's');
fPrimeString = input('Enter f''(t, y): ', 's');
f = @(t, y) fString;
fPrime = @(t, y) fPrimeString;
taylor2 = @(t, w) f(t, w) + h/2*fPrime(t, w);

But I got an error:

Error using + Matrix dimensions must agree.

Error in taylorMethod>@(t,w)f(t,w)+h/2*fPrime(t,w) (line 13) taylor2 = @(t, w) f(t, w) + h/2*fPrime(t, w);

Error in taylorMethod/w (line 47) res = w(j) + h*taylor2(t(j), w(j));

Error in taylorMethod (line 35) fprintf('i = %d; t_i = %.2f; w(i) = %.10f\n', idx, t(idx), w(idx));

The reason I'm not passing the functions in as arguments is because I want to use the same code for different orders... and different orders won't have the same number of functions needed.

Is there a way that I can prompt the user once for the functions, and use the functions throughout without prompting again?

2

2 Answers

2
votes

If you want to store the expression as a string, you can use eval. But that's a very powerful solution; use it only if you completely trust the input not to do anything malicious.

fString = input('Enter f(t, y): ', 's');
fPrimeString = input('Enter f''(t, y): ', 's');
f = @(t, y) eval(fString);
fPrime = @(t, y) eval(fPrimeString);
taylor2 = @(t, w) f(t, w) + h/2*fPrime(t, w);

A cleaner method is to convert the user input into a function:

f = str2func(['@(t, y)' input('Enter f(t, y): ', 's')]);
fPrime = str2func(['@(t, y)' input('Enter f''(t, y): ', 's')]);
taylor2 = @(t, w) f(t, w) + h/2*fPrime(t, w);
1
votes

Rather than asking for user input, couldn't you just take a cell array of functions? That solves the problem with different numbers of functions, and opens your code up to much more flexible kinds of uses.

Your code might then look something like:

function taylorMethod(a, b, h, alpha, order, funcs)

    f = funcs{1}; % first element is f(t, y)
    fPrime = funcs{2}; % f'(t, y)
    taylor2 = @(t, w) f(t, w) + h/2*fPrime(t, w);

    if order > 2
        f2Prime = funcs{3}; % f''(t, y)
        taylor3 = @(t, w) taylor2(t, w) + h^2/factorial(3)*f2Prime(t, w);
        if order == 4
            f3Prime = funcs{4}; % f'''(t, y)
            taylor4 = @(t, w) taylor3(t, w) + h^3/factorial(4)*f3Prime(t, w);
        end
    end

   % the rest is the same

which you might call like

taylorMethod(a, b, h, alpha, 3, {@(t, y) y^3, @(t, y) 3*y^2, @(t, y) 6*y})

providing as many derivatives as necessary (or more; it doesn't care).