How to optimise a function with parameters bounds correctly in Matlab? - 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);

Related

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

Extract coefficients from linear combination of kroneckerDelta functions

I want to extract coeffients from the sum of kroneckerDelta functions. I have calculated z transform and by taking inverse z transform the results is a linear combination of kroneckerDelta functions. When I use sym2poly, I get the error that it is not a valid function. I have following code
clc;
clear all;
syms z
f=[2 4 6 4 2 0];
% f=h0;
c=length(f)
for i=1:c
z_t(i)=[f(i)*z^-(i-1)];
end
ztransfn=sum(z_t);
invztransfn= iztrans(ztransfn)
the result is
invztransfn =
4*kroneckerDelta(n - 1, 0) + 6*kroneckerDelta(n - 2, 0) + 4*kroneckerDelta(n - 3, 0) + 2*kroneckerDelta(n - 4, 0) + 2*kroneckerDelta(n, 0)
using
sym2poly(invztransfn)
I get
Error using sym/sym2poly (line 31) Not a polynomial.
Error in ztransform (line 22) sym2poly(invztransfn)
How about using coeffs function?
If you type the following text in in Command Window in Matlab:
>> coeffs(invztransfn)
you will get as a result:
[ 2, 2, 4, 6, 4]
coeffs
I hope this helps. Best regards.

Trouble with horner function in 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.

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!

Z Transform Matlab Ezplot Error

First of all, I'm using sym, so I need a step (Heaviside) function. I know there exists a heaviside(t) in Matlab, so I'm using that.
Now, let's say I have function: x = -2^(-n+1)*heaviside(n-2) with syms n before. Now:
X = ztrans(x); // z transform
x = iztrans(X); // inverse z transform
(This should return the original x function)
This returns x = kroneckerDelta(n - 1, 0) + kroneckerDelta(n - 2, 0)/4 - 2*(1/2)^n + 2*kroneckerDelta(n, 0)
When I try to plot x now, by using ezplot(x) it returns a bunch of errors:
Error using inlineeval (line 15)
Error in inline expression ==> kroneckerDelta(n - 1, 0) + kroneckerDelta(n - 2, 0)./4 - 2.*(1./2).^n + 2.*kroneckerDelta(n, 0)
Undefined function 'kroneckerDelta' for input arguments of type 'double'.
Error in inline/feval (line 34)
INLINE_OUT_ = inlineeval(INLINE_INPUTS_, INLINE_OBJ_.inputExpr, INLINE_OBJ_.expr);
Error in ezplotfeval (line 52)
z = feval(f,x(1));
Error in ezplot>ezplot1 (line 467)
[y, f, loopflag] = ezplotfeval(f, x);
How can I plot the function x or stop these errors from appearing? I've only used Matlab inherent functions, dunno what to do...
I bet ezplot works by evaluating the function for some real-values substituted into the symbolic variable n. In this case, kroneckerDelta only accepts integer valued (non-double) inputs. So an idea is to use subs to put integers into kroneckerDelta.
x =
kroneckerDelta(n - 1, 0) + kroneckerDelta(n - 2, 0)/4 - 2*(1/2)^n + 2*kroneckerDelta(n, 0)
>> subs(x,-5:5)
ans =
[ -64, -32, -16, -8, -4, 0, 0, -1/4, -1/4, -1/8, -1/16]
>> plot(-5:5,ans)