Trouble with horner function in MATLAB - matlab

I have the following homework question:
Apply linear least squares with the two models S1(A, B, C) = Ax^2 + Bx
+ C and S2(A, B, C, D) = Ax^3 + Bx^2 + Cx + D to the data set (0, 4), (1, −1), (2, 6), (3, 1), (4, −4), (5, −9). Solve in MATLAB using
lspoly. Report the values of the parameters A, B, C and D clearly, and
produce a plot showing the data and both fitting curves.
I am working with the following function in MATLAB:
Function 1
function y = horner(a,c)
n=length(a)-1;
y=a(n+1);
for k = n:-1:1
y = a(k)+ c*y;
end
Function 2
function C = lspoly(x,y,M)
n = length(x);
F = zeros(n,M+1);
for k = 1:M+1
F(:,k) = x'.^(k-1);
end
A = F'*F;
B = F'*y';
C = A\B;
And this is the code I wrote for the problem:
clc
clear all
close all
x = [0, 1, 2, 3, 4, 5];
y = [4, -1, 6, 1, -4, -9];
C = lspoly(x,y,2); % finds the parameters
xx = 0:0.01:5;
yy = zeros(1, length(xx));
for i=1:length(xx)
yy(i) = horner(C,xx(i));
end
CC = lspoly(x,y,3); % finds the parameters
xxx = 0:0.1:5;
yyy = zeros(1, length(xxx));
for i=1:length(xxx)
yyy(i) = horner(CC,xxx(i));
end
figure(1)
plot(x, y, 'o', xx, yy, 'r-', xxx, yyy, 'b-')
I am encountering some issues with this code. When I try to run the program, I get the following error:
In an assignment A(I) = B, the number of elements in B and I must be
the same.
Error in HW7_1 (line 14) yy(i) = horner(C,xx(i));
I can't really wrap my head around what exactly I need to do to fix this issue. I tried breaking down my program piece by piece to determine results at different spots in the code, but so far nothing of note has been found.
Can someone help me fix this error?

It works just fine for me in Octave 3.8. The only thing I can think of is there a built-in function called horner in MATLAB (part of the Symbolic Math Toolbox), so maybe your code is calling that function instead of yours. Maybe try renaming it to something different, like my_horner or similar.

Related

Graphing functions while varying one parameter

I have a Matlab function, and I want to graph it while varying a certain parameter from 100 to 1000
it goes like this: [c, errorrange, i] = function [g1, g2, x];
I want to graph x and c while varying x
The function itself
...............
function [root,e, i]=func(xl,xu,e_stopping, z)
if ((((xl^4)/(20*z)-(3*z^2*xl^2)/50)*((xu^4)/(20*z)-(3*z^2*xu^2)/50)) > 0)
error('the intials wont work');
end
root = z/2+z*2;
e = 2;
i = 2;
end
...............
I thought of something like this:
...
for i = 100: 1000
[c, error] = fund(1000, 2000,0, i);
A(i) = c;
end
for i = 1: 99
A(i) = 0;
end
plot(A);
...
but it won't work; sorry, if my question is not good, I am new to Matlab.
Thank you
Your question is not clear because the variables you say you want to plot are not identified in your code. Although it doesn't matter what you call them in your function (like you say in your comments), if you are not clear in your question, then we have to guess that i=x, or A=x, or whatever you intended.
I'm still not sure exactly what you want to plot, but this should be close enough to get you started. Basically, it looks like you don't need any for loops, you just need to pass a vector input into your function.
A = 1:1:100; % create this vector however you need
[c, error] = func(1000, 2000, 0, A);
plot(A, c)
xlabel('my input A', 'FontSize', 10)
ylabel('my function output c', 'FontSize', 10)
title("my graph", 'FontSize', 12)
function [root, e, i] = func(xl, xu, e_stopping, z)
root = z/2 + z*2;
e = 2;
i = 2;
end

Using Euler's method to graph in MATLAB

I'm having some trouble with this code. My professor asked us to create a function "feuler.m" in MATLAB to solve the initial-value problem given by the differential equation u′(t) = (2+2t)e^t and the initial condition u(0) = 0 over the interval [0, 5] that uses (forward) Euler’s method to graph the exact solution along with the approximate solution.
The input should be: n, the number of subintervals into which the interval [0,5] should be divided.
The output should be a graph of the exact solution and the numerical solution and print the value of the maximum error between the true solution and the numerical solution.
Note that the exact solution is given by u(t) = 2tet.
So far I have written the code:
function myeuler(N)
t = linspace(0, 5, N+1)';
ua = zeros(N+1,1);
ue = 2*t.*exp(t);
h = 5/N;
A = zeros(N,N);
A(2:N,1:N-1) = -eye(N-1);
A = A + eye(N);
b = h*(2+2*t(1:N)).*exp(t(1:N));
b(1) = b(1) + ua(1);
ua(2:N+1) = A\b;
plot(t, ua, 'r', t, ue, 'g')
end
I'm unsure if this is right.

The function "triplequad" doesn't return the right volume (Octave/Matlab)

I am trying to get the volume under a profile by using Octave. I have built a simple model for this:
function F1 = f_x(x)
F1 = x-1;
endfunction
function F2 = f_y(y)
F2 = y;
endfunction
function F3 = f_z(z)
F3 = z;
endfunction
f_xyz = inline('f_x(x).*f_y(y).*f_z(z);', 'x', 'y', 'z');
Volume = triplequad(f_xyz,0,3,0,3,0,4)
x = 1:1:2;
y = 1:1:2;
z = 1:1:2;
f_plot=f_x(x).*f_y(y).*f_z(z)';
%Lines for plotting the 3D plot
tx = linspace (0, 3, numel(x))';
ty = linspace (0, 3, numel(y))';
[xx, yy] = meshgrid (tx, ty);
tz = f_plot;
mesh (tx, ty, tz);
which gives a plot that looks like in the picture below:
I am using the triplequad function (which works also on Matlab) to get the volume under that profile, but it doesn't look like it works. The function return a volume of 54 units, which is not really true. Calculating the volume of a parallelepiped using the full dimensions gives 36 units (3 x 3 x 4), which proves that it calculates it wrongly. The questions is... what am I doing wrong here? Why doesn't "triplequad" give the right volume?
I think you might be misunderstanding the dimensionality of your problem. You're dealing with a 4D function:
f = #(x, y, z) (x-1).*y.*z;
You have a value returned by f (i.e. the dependent variable) determined by a set of 3 independent variables, thus a 4D function. You have to talk in terms of hypervolume instead of volume in this case, since volume is a 3D measurement. The triplequad function will evaluate a triple integral of f over a given set of ranges for the independent variables, giving you the hypervolume:
>> triplequad(f, 0, 3, 0, 3, 0, 4) % Integrate over 0 <= x <= 3, 0 <= y <= 3, 0 <= z <= 4
ans =
53.999999999999986 % Just shy of 54
Your visualization of a 3D surface doesn't make any sense, and is leading you astray in thinking that the result is wrong.
NOTE 1: In MATLAB, the function triplequad appears slated for deprecation in a future release, so you should use integral3 instead. It also appears to give more accurate results:
>> integral3(f, 0, 3, 0, 3, 0, 4)
ans =
54
NOTE 2: In regards to your comment, the function f(x,y,z) = 1 is constant and has no dependence on x, y, or z. A triple integral over this function is the equivalent of computing the volume of the area over which you're integrating (3*3*4 = 36) multiplied by the constant function value (which is just 1 in this case). You can confirm it like so:
>> f = #(x, y, z) ones(size(x));
>> triplequad(f, 0, 3, 0, 3, 0, 4)
ans =
36
EDIT: Regarding your follow-up problem, I actually get an error when trying to run that example in R2016b, so I'm not sure how you got it to work (although the resulting value is correct):
>> V = triplequad(h_xxyy,0,3,0,3,0,15)
Error using inline/subsref (line 14)
Too many inputs to inline function.
The problem is that triplequad is used to perform triple integrals over functions of 3 variables, but your function only has 2 inputs (x and y). When calculating the volume under a function of 2 variables, you only need to integrate over those 2 variables, so you should be using the MATLAB function integral2 instead (or dblquad in Octave):
>> f = #(x, y) x.^2.*sqrt(y);
>> V = integral2(f, 0, 3, 0, 3)
V =
31.176914536244894
Note that f has no z-dependence, so f(x, y) is constant with respect to z (i.e. for a given x and y, it always returns the same value regardless of z). As a result, if you were to perform a third integration over the z dimension it would be the same as multiplying the result by the integration range:
>> V*15
ans =
467.6537 % Same result you got from triplequad

How to optimise a function with parameters bounds correctly in Matlab?

I'm using Matlab 2015a.
Here is the function I want to optimise:
function result = fig_of_merit(x, a, b, c, d)
result = 1;
end
This is how I want to optimise the function:
x1 = [10*10^-6, 120];
x2 = [300*10^-6, 175];
fminbnd(#(x) fig_of_merit(x, 1, 2, 3, 4),x1,x2);
I keep getting the following error:
Error using *
Inner matrix dimensions must agree.
Error in fminbnd (line 291)
x = xf + si * max( abs(d), tol1 );
Error in test (line 5)
fminbnd(#(x) fig_of_merit(x, 1, 2, 3, 4),x1,x2);
What's wrong with my code? I did the same for optimisation without bounds using the fminsearch function and everything was fine.
It has something to do with the anonymous function I used - when I reduced the vectors x1 and x2 to scalars, it worked:
fminbnd(#(x) fig_of_merit(x, 1, 2, 3, 4),-4, 5);
It doesn't satisfy me, because I want to optimise 2 parameters at once.
The fminbnd function only works on scalar parameters. It can't optimize two parameters at once. However, the fmincon function can do this:
x1 = [10*10^-6, 120];
x2 = [300*10^-6, 175];
fmincon(#(x) fig_of_merit(x, 1, 2, 3, 4),ones(size(x1)),[],[],[],[],x1,x2);

Don't know why error with indices occurs in Matlab

Consider the following matlab code fragment:
g = #(x, t)x.*0;
u_explizit = explizit_Euler(20, 800, 1, 1, zeros(21,1), g, [1;2], 0, 0.1);
figure
surf(u_explizit);
shading flat;
title('Aufgabe 2 - Explizit Euler');
u_implizit = implizit_Euler(20, 800, 1, 1, zeros(21,1), g, [1;2], 0, 0.1);
Both functions explizit_Euler and implizit_Euler start with the same commands (here shown for explizit_Euler:
function [u] = explizit_Euler(n, nt, T, kappa, u0, f, b, gN, gD)
tau = T/nt;
[A, z] = prepare_system(n, f, b, gN, gD);
z = z';
...
end
The function prepare_system looks like this:
function [ A, z] = prepare_system(n, f, b, gN, gD)
%PREPARE_MATRIX_SYSTEM Prepares A_h and solution vector f_h
h = 1/n;
z = f((0:n)./n);
...
end
The call of prepare_system from within explizit_Euler works just fine. However, the call from within implizit_Euler delivers an error message and I just can't figure out why:
Subscript indices must either be real positive integers or logicals.
Error in implizit_Euler (line 5)
z = f((0:n)./n);
It seems that matlab thinks f is a vector, and thus it can't access f(0), which makes sense if f was a vector. But f is a function handle! And how come the exact same code works fine in an earlier code from within explizit_Euler?
I missplaced the parameters in the signature of implizit_Euler (!) - sorry, guys!