Constants not recognized in integral

7 views (last 30 days)
Florian Spicher
Florian Spicher on 17 Oct 2021
Edited: John D'Errico on 17 Oct 2021
I'm a begginer with Matlab, so I bet this is obvious but I don't understand the error I have. Can you please help me correcting it?
It says that my variable a (and I guess b and c as well) is unknown even though I defined it at the very beggining of the script.
Also, side question: I had an error telling me I couldn't square "my matrix" because of its dimensions but when I put points before my ^2 the problem vanish. Any (brief) explanation please?
double a; double b; double c;
integral(@(x) f(x),0,1)
function p=p(x)
p=a*x.^2+b*x+c;
end
function f=f(x)
f=(exp(x)-p(x)).^2;
end

Answers (2)

Geoff Hayes
Geoff Hayes on 17 Oct 2021
@Florian Spicher - rather than using a script, try including the above code in a function instead (see functions vs scripts
function myFunctionName
a = 0;
b = 1;
c = 2;
integral(@(x) f(x),0,1)
function p=p(x)
p=a*x.^2+b*x+c;
end
function f=f(x)
f=(exp(x)-p(x)).^2;
end
end
and define values for your a, b, and c variables (rather than just declaring as doubles). See power for an explanation on the use of .^.

John D'Errico
John D'Errico on 17 Oct 2021
Edited: John D'Errico on 17 Oct 2021
You are still thinking that you are using some other language, where you need to declare variables as doubles.
This line does not do what you think:
double a; double b; double c;
In fact, it does not even create variables with that name. What did it do?
whos
Name Size Bytes Class Attributes ans 1x1 8 double
So when I tried whos there after having used the line you had written, it shows that NOTHING useful was done. No variables were created. What did those calls do?
double a
ans = 97
Here, we see that call takes the character 'a', converts it to its ascii equivalent (97), then puts the result in the variable ans, effectively dumping it in the bit bucket.
In the case where you want to define those variables as unknown constants, which is what it looks like you want to do? I say that because you never did assign any value to those unknown constants. If so, then you might have done this:
syms a b c % this does create new SYMBOLIC variables with those names
whos
Name Size Bytes Class Attributes a 1x1 8 sym ans 1x1 8 double b 1x1 8 sym c 1x1 8 sym
So you can see that now, a,b, and c now exist, and are symbolic variables. They are now effectively unknown constants. syms is the one case where you will want to declare the variables you use as symbolic. Everything else is a double by default.
syms x
p = a*x.^2+b*x+c
p = 
So p is a symbolic polynomial, with unknown coefficients a,b,c. Now we can form the expression you had, and integrate it over the interval [0,1], given the unknown constants a,b,c.
I = int((exp(x) - p).^2,x,[0,1])
I = 
Note that the variable e shown in that expression is exp(1).
See that integral cannot be used with symbolic parameters. You needed to use int for that.
Alternatively, suppose a,b, and c had actual numeric values? Now I would suggest you learn to use function handles.
a = 1.5;
b = -2.345;
c = -2;
P = @(X) a*X.^2 + b*X + c
P = function_handle with value:
@(X)a*X.^2+b*X+c
P is now a function handle. It encapsulates the current values of a, b and c. You can pass p around as a variable, and then use it as a function. I used a new variable X here to not confuse you.
f = @(X) (exp(X) - P(X)).^2
f = function_handle with value:
@(X)(exp(X)-P(X)).^2
f is also a function handle. It knows what P is, and since P already knows the values of a, b, and c, everything will work. We can now form the integral, as
integral(f,0,1)
ans = 19.8171
We have a simple numerical value for this result.
Finally, I can imagine where you are going with this little task. Suppose we wanted to find the optimzl values of a, b, anc c to best approximate exp(x) over the interval [0,1]? Now we might do this:
p = @(x,a,b,c) a*x.^2 + b*x + c
p = function_handle with value:
@(x,a,b,c)a*x.^2+b*x+c
Hee a,b,c,x are all expected to be variables passed into the function handle p. They are all currently unknowns.
f = @(x,a,b,c) (exp(x) - p(x,a,b,c)).^2;
I = @(a,b,c) integral(@(x) f(x,a,b,c),0,1);
At this point, NO integral has yet been computed. All I have done is to set up the functions to be used. So finally, minimize the integral, over the unkown constants a,b,c. We can use fminsearch for this.
abcstart = randn(1,3) % not very creative starting values
abcstart = 1×3
1.4337 -0.6460 -0.6480
[abcopt,minI] = fminsearch(@(abc) I(abc(1),abc(2),abc(3)), abcstart)
abcopt = 1×3
0.8392 0.8511 1.0130
minI = 2.7835e-05
How well did we do? minI is pretty small, so I expect we did well.
fplot(@exp,[0,1])
hold on
fplot(@(x) p(x,abcopt(1),abcopt(2),abcopt(3)),[0,1])
xlabel 'X'
grid on
title 'Approximating exp(x) with a quadratic polynomial'
The approximation is seen to be quite good, as the two curves are almost impossible to distinguish from each other.
figure
fplot(@(x) exp(x) - p(x,abcopt(1),abcopt(2),abcopt(3)),[0,1])
xlabel X
ylabel error
grid on
title 'Error in approx of exp(x) with a quadratic polynomial'
As one would expect, the difference between the two should look very much like a cubic polynomial, with three zero crossings on the interval.
Your side question:
Why do you need to use .^ to square a matrix or vector, if you intend to square the elements?
Suppose we create the matrix A as:
A = magic(3)
A = 3×3
8 1 6 3 5 7 4 9 2
Now what happens when we square A?
A^2
ans = 3×3
91 67 67 67 91 67 67 67 91
This is equivalent to writing A*A, where this is a MATRIX multiplication. If your goal is to square the elements of A, you need to write
A.^2
ans = 3×3
64 1 36 9 25 49 16 81 4
The same thing applies to vectors. But if V is a vector, and you wanted to square the elements of V?
V = [1 2 3];
If I write V*V now, MATLAB will generate an error, because V*V does not conform for a MATRIX multiplication, thus a dot product. Squaring the elements of V requires we write
V.^2
ans = 1×3
1 4 9

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by