Matlab minimization with fminsearch and parametrized function - matlab

I am writing a program in Matlab and I have a function defined this way.
sum (i=1...100) (a*x(i) + b*y(i) + c)
x and y are known, while a, b and c are not: I need to find values for them such that the total value of the function is minimized. There is no additional constraint for the problem.
I thought of using fminsearch to solve this minimization problem, but from Mathworks I get that functions which are suitable inputs for fminsearch are defined like this (an example):
square = #(x) x.^2
So in my case I could use a vector p=[a, b, c] as the value to minimize, but then I don't know how to define the remaining part of the function. As you can see the number of possible values for the index i is huge, so I cannot simply sum everything together explicitly, but I need to represent the summation in some way. If I write the function somewhere else then I am forced to use symbolic calculus for a, b and c (declaring them with syms) and I'm not sure fminsearch would accept that.
What can I do? Of course if fminsearch turns out to be unfeasible for my situation I accept links to use something else.

The most general solution is to use x and y in the definition of the objective function:
>> objfun = #(p) sum( p(1).*x + p(2).*y + p(3) );
>> optp = fminsearch( objfun, po, ... );

Related

fzero() Matlab function for complicated functions

Having such a function:
y=1.2*sin(x)+2*log(x+2)-5; I am looking for zeros of that function using fzero() functon- just for testing, I indicate other methods.
I received error and I am looking for the solution of that. fzero() is for nonlinear functions but for complex ones...? Doyou know similar method to fzero()?
The function in the example has a pole, but you can treat this case by looking at it's real part, get the zero and check it to see the imaginary part is zero:
syms x y yr
yr= #(x) real(1.2*sin(x)+2*log(x+2)-5);
fr=fzero(yr,0);
fr =
6.8458
y= #(x) (1.2*sin(x)+2*log(x+2)-5);
y(fr)
ans =
-8.8818e-16

double integral implementation in matlab

I am in trouble to implement the following double integral. there is a summation inside the integral which make things a bit complicated. The matlab code I did is as follows and always has error like "Matrix dimensions must agree." , any hint to implement it? thanks
n=3;
nn=1:n;
aa=gamma([1:n])
thre=3;
lapha=4;
r=3;
fun1= #(theta, x) (1-sum( lambda *pi *( (x-r).^2+r^2-(x-r).*r.*cos(theta)).^(nn-1)./aa).*exp(-1*lambda *pi*((x-r).^2+r^2-(x-r).*r.*cos(theta)))).*lambda/n*(1-1/2^n).*thre.*r.^alpha.*(x-r).^(1-alpha) ;
answer=integral2( fun1, 0, 2*pi, 0, inf )
The double integral:
Your problem is the way you calculate the sum in the integrated function. The documentation of intergal2 says that the function argument must accept arrays X and Y of the same size and return an array of corresponding values. But this expression inside the function definition:
((x-r).^2 + r^2 - (x-r).*r.*cos(theta)).^(nn-1)./aa
is not working the way you expect, because it's you who decide the size of nn and aa, while it's integral2 that decides the size of the vectors x and theta; no wonder that there are disagreements on it.

How to find coefficients for a possible exponential approximation

I have data like this:
y = [0.001
0.0042222222
0.0074444444
0.0106666667
0.0138888889
0.0171111111
0.0203333333
0.0235555556
0.0267777778
0.03]
and
x = [3.52E-06
9.72E-05
0.0002822918
0.0004929136
0.0006759156
0.0008199029
0.0009092797
0.0009458332
0.0009749509
0.0009892005]
and I want y to be a function of x with y = a(0.01 − b*n^−cx).
What is the best and easiest computational approach to find the best combination of the coefficients a, b and c that fit to the data?
Can I use Octave?
Your function
y = a(0.01 − b*n−cx)
is in quite a specific form with 4 unknowns. In order to estimate your parameters from your list of observations I would recommend that you simplify it
y = β1 + β2β3x
This becomes our objective function and we can use ordinary least squares to solve for a good set of betas.
In default Matlab you could use fminsearch to find these β parameters (lets call it our parameter vector, β), and then you can use simple algebra to get back to your a, b, c and n (assuming you know either b or n upfront). In Octave I'm sure you can find an equivalent function, I would start by looking in here: http://octave.sourceforge.net/optim/index.html.
We're going to call fminsearch, but we need to somehow pass in your observations (i.e. x and y) and we will do that using anonymous functions, so like example 2 from the docs:
beta = fminsearch(#(x,y) objfun(x,y,beta), beta0) %// beta0 are your initial guesses for beta, e.g. [0,0,0] or [1,1,1]. You need to pick these to be somewhat close to the correct values.
And we define our objective function like this:
function sse = objfun(x, y, beta)
f = beta(1) + beta(2).^(beta(3).*x);
err = sum((y-f).^2); %// this is the sum of square errors, often called SSE and it is what we are trying to minimise!
end
So putting it all together:
y= [0.001; 0.0042222222; 0.0074444444; 0.0106666667; 0.0138888889; 0.0171111111; 0.0203333333; 0.0235555556; 0.0267777778; 0.03];
x= [3.52E-06; 9.72E-05; 0.0002822918; 0.0004929136; 0.0006759156; 0.0008199029; 0.0009092797; 0.0009458332; 0.0009749509; 0.0009892005];
beta0 = [0,0,0];
beta = fminsearch(#(x,y) objfun(x,y,beta), beta0)
Now it's your job to solve for a, b and c in terms of beta(1), beta(2) and beta(3) which you can do on paper.

Symbolic integration vs numeric integration in MATLAB

I have an expression with three variables x,y and v. I want to first integrate over v, and so I use int function in MATLAB.
The command that I use is the following:
g =int((1-fxyz)*pv, v, y,+inf)%
PS I haven't given you what the function fxyv is but it is very complicated and so int is taking so long and I am afraid after waiting it might not solve it.
I know one option for me is to integrate numerically using for example integrate, however I want to note that the second part of this problem requires me to integrate exp[g(x,y)] over x and y from 0 to infinity and from x to infinity respectively. So I can't take numerical values of x and y when I want to integrate over v I think or maybe not ?
Thanks
Since the question does not contain sufficient detail to attempt analytic integration, this answer focuses on numeric integration.
It is possible to solve these equations numerically. However, because of complex dependencies between the three integrals, it is not possible to simply use integral3. Instead, one has to define functions that compute parts of the expressions using a simple integral, and are themselves fed into other calls of integral. Whether this approach leads to useful results in terms of computation time and precision cannot be answered generally, but depends on the concrete choice of the functions f and p. Fiddling around with precision parameters to the different calls of integral may be necessary.
I assume that the functions f(x, y, v) and p(v) are defined in the form of Matlab functions:
function val = f(x, y, v)
val = ...
end
function val = p(v)
val = ...
end
Because of the way they are used later, they have to accept multiple values for v in parallel (as an array) and return as many function values (again as an array, of the same size). x and y can be assumed to always be scalars. A simple example implementation would be val = ones(size(v)) in both cases.
First, let's define a Matlab function g that implements the first equation:
function val = g(x, y)
val = integral(#gIntegrand, y, inf);
function val = gIntegrand(v)
% output must be of the same dimensions as parameter v
val = (1 - f(x, y, v)) .* p(v);
end
end
The nested function gIntegrand defines the object of integration, the outer performs the numeric integration that gives the value of g(x, y). Integration is over v, parameters x and y are shared between the outer and the nested function. gIntegrand is written in such a way that it deals with multiple values of v in the form of arrays, provided f and p do so already.
Next, we define the integrand of the outer integral in the second equation. To do so, we need to compute the inner integral, and therefore also have a function for the integrand of the inner integral:
function val = TIntegrandOuter(x)
val = nan(size(x));
for i = 1 : numel(x)
val(i) = integral(#TIntegrandInner, x(i), inf);
end
function val = TIntegrandInner(y)
val = nan(size(y));
for j = 1 : numel(y)
val(j) = exp(g(x(i), y(j)));
end
end
end
Because both function are meant to be fed as an argument into integral, they need to be able to deal with multiple values. In this case, this is implemented via an explicit for loop. TIntegrandInner computes exp(g(x, y)) for multiple values of y, but the fixed value of x that is current in the loop in TIntegrandOuter. This value x(i) play both the role of a parameter into g(x, y) and of an integration limit. Variables x and i are shared between the outer and the nested function.
Almost there! We have the integrand, only the outermost integration needs to be performed:
T = integral(#TIntegrandOuter, 0, inf);
This is a very convoluted implementation, which is not very elegant, and probably not very efficient. Again, whether results of this approach prove to be useful needs to be tested in practice. However, I don't see any other way to implement these numeric integrations in Matlab in a better way in general. For specific choices of f(x, y, v) and p(v), there might be possible improvements.

How to vectorize a function for integral2?

I want to evaluate a double integral of the form
$$\int_{-\infty}^a \int_{-\infty}^b \sum_{i,j}^K a_ia_jx^iy^j\exp(-x^2 - y^2 + xy)dx dy $$
where $a_i$ and $a_j$ are constants. Since the integral is linear, I can interchange summation and integration, but in this case I have to evaluate $K^2$ integrals and it takes too long. In that case I do the following:
for i = 1:K
for j = 1:K
fun = #(x,y) x.^i.*y.^j.*exp(-2.*(x.^2 + y.^2 - 2.*x.*y))
part(i,j) = alpha(i)*alpha(j)*integral2(fun,-inf,a,-inf,b)
end
end
It takes too long, so I want to evaluate only one integral, but I don't know how to vectorize $\sum_{i,j}^K a_ia_jx^iy^j\exp(-x^2 - y^2 + xy)$, namely, how to supply it to integral2. I would be very grateful for any help.
It looks like you'll need to have i and j be third and fourth dimensions, in order for there to be a chance that the code will work.
I also don't have integral2 (I use octave, integral2 is a new matlab function that octave doesn't yet have), so I can't test it, but I'd think something like this might work:
alphaset=zeros(1,1,K,K);
alphaset(1,1,1:K,1:K)=alpha(1:K)'*alpha(1:K);
i_set=zeros(1,1,K,1);
j_set=zeros(1,1,1,K);
i_set(:)=1:K;
j_set(:)=1:K;
fun=#(x,y) x.^i_set.*y.^j_set.*exp(-2.*(x.^2 + y.^2 - 2.*x.*y));
part = squeeze(alphaset.*integral2(fun,-inf,a,-inf,b));
As I said, I can't promise that it'll work, because I don't know how integral2 works. But if you replace the integral2 with simply "sum(sum(fun([1,2,4],[3,-1,2])))", then it works as intended for that operation (that is, it sums over the x and y values, and the result is a matrix over the set of indices).
If you just want to improve speed, you may try parfor.
Let $X=(x,x^2,\cdots,x^K)$, $Y=(y,y^2,\cdots,y^K)$, $A=(a_{ij})$ be a matrix with $a_{ij}=a_{i}a_{j}$, then
$$\sum_{i,j}^K a_{i}a_{j}x^iy^j=XAY^{T}$$
I don't have integral2 function on my matlab, so I didn't test if it will improve the speed a lot.
Also, I think you need to use syms x and y, after you compute the $$XAY^{T}$$, then use matlabFunction to convert symbolic expression to function handle. Here it is my test code: syms x y; X=[x,x^2]; Y=[y,y^2]; Z=X*Y'; fun =matlabFunction(Z); ff=#(x,y) x^2+y^2; gg=fun(x,y).*ff(x,y);