How to find argmin/best fit/optimize for an overdetermined quadratic system for multiple variables in Matlab - matlab

I have 100 equations with 5 variables. Is there a function in Matlab which I can use to find the optimal solution of these equations?
My problem is to find argmin ||(a-ic)^2 + (b-jd)^2 + e - h(i,j)|| over all i, j from -10 to 10. ie.
%% Note: not Matlab code. Just showing the Math.
for i = -10:10
for j = -10:10
(a-ic)^2 + (b-jd)^2 + e = h(i,j)
known: h(i,j) is a 10*10 matrix,and i,j are indexes
expected: the optimal result of a,b,c,d,e

You can try using lsqnonlin as follows.
%% define a helper function in your .m file
function f = fun(x)
a=x(1); b=x(2); c=x(3); d=x(4); e=x(5); % Using variable names from your question. In other situations, be careful when overwriting e.
f=zeros(21*21,0); % size(f) is taken from your question. You should make this a variable for good practice.
for i = -10:10
for j = -10:10
f(10*(i+10+1)+(j+10+1)) = (a-i*c)^2 + (b-j*d)^2 + e - h(i,j); % 10 is taken from your question.
end
end
end
(Aside, why is your h(i,j) taking negative indices??)
In your main function you can simply write
function out=myproblem(x0)
out=lsqnonlin(#fun,x0);
end
In your cmd, you can call with specific initial try such as
myproblem([0,0,0,0,0])
Helper function over anonymous because in my experience helpers get sped up by JIT while anonymous do not. I also opted to reshape in the loops as an opposed to actually call reshape after because I expect reshape to cost significant extra time. Remember that O(1) in fun is not O(1) in lsqnonlin.
(As always, a solution to a nonlinear problem is not guaranteed.)

Related

How to solve multiple non-linear and independent equations in MATLAB

I have 16 non-linear equations which are independent of each other i.e. they are not a system of equations. One way is to create 16 separate sub-routines and use fsolve to solve which i generally do.
But i need to reduce the number of sub-routines from 16 to one. Let me try to give an example of what i'm doing so far:
u01 = .001;....u016 = .001;
options=optimset('Display','notify','MaxFunEvals',10^7,'TolX',1e-,'TolFun',1e-6,'MaxIter',10^5);
u1 = fsolve(#polsim1,u01,options);
..
..
u16 = fsolve(#polsim16,u016,options);
So, in the above example i have 16 subroutines i.e. polsim1-polsim16 where each includes 1 non-linear equation to solve for u's. This method is very cumbersome and messy. I need to do that in one subroutine. I believe i need to use index n = 1 to 16. But i'm not sure how to use it and where to use it.
Just create an array of functions and initial guesses, as shown in the first example of the documentation for fsolve.
% Array of equations, nx1 in size for n equations.
% Ensure that the input (x) is indexed in each equation, e.g. x(1) in eqn 1
polsim = #(x) [x(1).^2 - 1
2*x(2) + 3];
% Array of initial guesses, corresponding element-wise to eqn array
u0 = [0.01; 0.01];
% Solver options
options = optimset('Display','notify','MaxFunEvals',10^7,'TolX',1e-5,'TolFun',1e-6,'MaxIter',10^5);
% Solve
u = fsolve(F, u0, options);
>> u = [1.000; -1.500] % As expected for the equations in F and intial guesses
You should rewrite your code to use vectors/cell arrays as follows:
% Write the initial point as a vector
u0(1) = .001;
..
u0(16) = .001;
% Write the equations as a cell array
polsim{1} = #polsim1;
..
polsim{16} = #polsim16;
options=optimset('Display','notify','MaxFunEvals',10^7,'TolX',1e-1,'TolFun',1e-6,'MaxIter',10^5);
u = zeros(u0); % Allocate output space for efficiency
% loop over all the equations
for i=1:length(u0)
u(i) = fzero(polsim{i},u0(i),options);
end
Note that I used fzero instead of fsolve to improve the efficiency, see this post for more information.
Trick to automatically construct vector/cell array (Deprecated)
For completeness, I should mention that you can initialise u0 and polsim automatically using eval:
for i=1:16
eval(['u0(', num2str(i), ') = u0', num2str(i),';']);
eval(['polsim{', num2str(i), '} = polsim', num2str(i),';']);
end
Note that I do not recommend this method. It is much better to directly define them as a vector/cell array.

generate periodic function from given function

let say that from given function f(t), we want to construct new function which is given from existed function by this way
where T is some constant let say T=3; of course k can't be from -infinity to infinity in reality because we can't do infinity summation using computer,so it is first my afford
first let us define our function
function y=f(t);
y=-1/(t^2);
end
and second program
k=-1000:1:999;
F=zeros(1,length(k));
T=3;
for t=1:length(k)
F(t)=sum(f(t+k*T));
end
but when i am running second program ,i am getting
>> program
Error using ^
Inputs must be a scalar and a square matrix.
To compute elementwise POWER, use POWER (.^) instead.
Error in f (line 2)
y=-1/(t^2);
Error in program (line 5)
F(t)=sum(f(t+k*T));
so i have two question related to this program :
1.first what is error why it shows me mistake
how can i do it in excel? can i simplify it somehow? thanks in advance
EDITED :
i have changed my code by this way
k=-1000:1:999;
F=zeros(1,length(k));
T=3;
for t=1:length(k)
result=0;
for l=1:length(k)
result=result+f(t+k(l)*T);
end
F(t)=result;
end
is it ok?
To solve your problem in a vectorized way, you'll have to change the function f such that it can be called with vectors as input. This is, as #patrik suggested, achieved by using the element-wise operators .* ./ .^ (Afaik, no .+ .- exist). Unfortunately the comment of #rayryeng is not entirely correct, which may have lead to confusion. The correct way is to use the element-wise operators for both the division ./ and the square .^:
function y = f(t)
y = -1 ./ (t.^2);
end
Your existing code (first version)
k = -1000:1:999;
F = zeros(1,length(k));
T = 3;
for t=1:length(k)
F(t) = sum(f(t+k*T));
end
then works as expected (and is much faster then the version you posted in the edit).
You can even eliminate the for loop and use arrayfun instead. For simple functions f, you can also use function handles instead of creating a separate file. This gives
f = #(t) -1 ./ (t.^2);
k = -1000:1:999;
t = 1:2000;
T = 3;
F = arrayfun(#(x)sum(f(x+k*T)), t);
and is even faster and a simple one-liner. arrayfun takes any function handle as first input. We create a function handle which takes an argument x and does the sum over all k: #(x) sum(f(x+k*T). The second argument, the vector t, contains all values for which the function handle is evaluated.
As proposed by #Divakar in comments, you can also use the bsxfun function:
f = #(t) -1 ./ (t.^2);
k = -1000:1:999;
t = 1:2000;
T = 3;
F = sum(f(bsxfun(#plus,k*T,t.')),2);
where bsxfun creates a matrix containing all combinations between t and k*T, they are all evaluated using f(...) and last, the sum along the second dimension sums over all k's.
Benchmarking
Lets compare these solutions:
Combination of for loop and sum (original question):
Elapsed time is 0.043969 seconds.
Go through all combinations in 2 for loops (edited question):
Elapsed time is 1.367181 seconds.
Vectorized approach with arrayfun:
Elapsed time is 0.063748 seconds.
Vectorized approach with bsxfun as proposed by #Divakar:
Elapsed time is 0.099399 seconds.
So (sadly) the first solution including a for loop beats both vectorized approaches. For larger k vectors (-10000:1:9999), this behavior can be reproduced. The conclusion seems to be that MATLAB has indeed learned how to optimize for loops.

How can i create a multivariable function in matlab out of matrix data?

but i want to make a program in which i can generate a function of multiple variables that depend on the number of rows of a matrix.
for k = 1:sizel;
f(k)=(alpha(k,1)+(beta(k,1)*p(k))+(gamma(k,1)*p(k)^2));
end
cost=(sum(f))
this is for the purpose of optimization so i need that at the end the variables are declares as p(1),p(2),p(3)... these will be the input for my function.
Note: i dont want to assign values to the variables because this will be done be the optimization algorithm in the optimization toolbox.
here is the complete code
function cost = cost(p) ;
clc
clear
costfunctionconstantsmatrix;
sizel=size(CostFormulaconstants);
alpha=CostFormulaconstants(:,1);
beta=CostFormulaconstants(:,2);
gamma=CostFormulaconstants(:,3);
for k = 1:sizel;
f(k)=(alpha(k,1)+(beta(k,1)*p(k))+(gamma(k,1)*p(k)^2));
end
cost=(sum(f))
end
i used the symbolic approach and i got the correct answer for the cost indeed, i got something like this: (53*p(1))/10 + (11*p(2))/2 + (29*p(3))/5 + p(1)^2/250 + (3*p(2)^2)/500 + (9*p(3)^2)/1000 + 1100. But when i try to specify my function to be optimized in the optimization toolbox it tells me that the variables p are sym and cannot be converted to double. the trouble is how to convert this expression to double so that the optimization algorithm can input values for the variable p(1), p(2) and p(3)
Can you pass the matrix as an argument to the function?
function cost = fcn(my_mat)
[m,n] = size(my_mat);
f = zeros(m,1);
for k = 1:m % for example
f(k)=(alpha(k,1)+(beta(k,1)*p(k))+(gamma(k,1)*p(k)^2));
end
cost = sum(f);
end
Your problem is not entirely clear to me but I believe you wish to generate a series of functions in which the variables alpha, beta, gamma are constants with different values for each function, and the vector p is an argument.
What confuses me in your question is that you use the index k for both the constants and the arguments, which I think is not what you intended to write. Assuming I understand your goal, a solution may make use of function handles.
The notation f(k) = #(p) p(1)+p(2) for example, generates a function that adds p(1) and p(2). Abbreviating CostFormulaconstants to cf, the following would generate a series of functions, one for each row in cf.
for k = 1 : size(cf, 1)
f{k} = #(p) cf(k,1) + cf(k,2)*p(1) + cf(k,3)*p(2)^2;
end
You can supply individual function handles to callers from the optimization toolbox simply with f{3} for the third function, for example. A call to f{3} would look like
a = f{3}([3,4]);
If your functions are indeed all polynomials, polyval may be worth a look as well.
EDIT: After clarification, the problem seems a bit simpler, no need for function handles. Why not simply
function c = cost(p)
c = 0;
cf = [...]; % your coefficients here.
for k = 1 : size(cf, 1)
c = c + cf(k,1) + cf(k,2)*p(k) + cf(k,3)*p(k)^2;
end

Implementing iterative solution of integral equation in Matlab

We have an equation similar to the Fredholm integral equation of second kind.
To solve this equation we have been given an iterative solution that is guaranteed to converge for our specific equation. Now our only problem consists in implementing this iterative prodedure in MATLAB.
For now, the problematic part of our code looks like this:
function delta = delta(x,a,P,H,E,c,c0,w)
delt = #(x)delta_a(x,a,P,H,E,c0,w);
for i=1:500
delt = #(x)delt(x) - 1/E.*integral(#(xi)((c(1)-c(2)*delt(xi))*ms(xi,x,a,P,H,w)),0,a-0.001);
end
delta=delt;
end
delta_a is a function of x, and represent the initial value of the iteration. ms is a function of x and xi.
As you might see we want delt to depend on both x (before the integral) and xi (inside of the integral) in the iteration. Unfortunately this way of writing the code (with the function handle) does not give us a numerical value, as we wish. We can't either write delt as two different functions, one of x and one of xi, since xi is not defined (until integral defines it). So, how can we make sure that delt depends on xi inside of the integral, and still get a numerical value out of the iteration?
Do any of you have any suggestions to how we might solve this?
Using numerical integration
Explanation of the input parameters: x is a vector of numerical values, all the rest are constants. A problem with my code is that the input parameter x is not being used (I guess this means that x is being treated as a symbol).
It looks like you can do a nesting of anonymous functions in MATLAB:
f =
#(x)2*x
>> ff = #(x) f(f(x))
ff =
#(x)f(f(x))
>> ff(2)
ans =
8
>> f = ff;
>> f(2)
ans =
8
Also it is possible to rebind the pointers to the functions.
Thus, you can set up your iteration like
delta_old = #(x) delta_a(x)
for i=1:500
delta_new = #(x) delta_old(x) - integral(#(xi),delta_old(xi))
delta_old = delta_new
end
plus the inclusion of your parameters...
You may want to consider to solve a discretized version of your problem.
Let K be the matrix which discretizes your Fredholm kernel k(t,s), e.g.
K(i,j) = int_a^b K(x_i, s) l_j(s) ds
where l_j(s) is, for instance, the j-th lagrange interpolant associated to the interpolation nodes (x_i) = x_1,x_2,...,x_n.
Then, solving your Picard iterations is as simple as doing
phi_n+1 = f + K*phi_n
i.e.
for i = 1:N
phi = f + K*phi
end
where phi_n and f are the nodal values of phi and f on the (x_i).

Matlab: Optimizing speed of function call and cosine sign-finding in a loop

The code in question is here:
function k = whileloop(odefun,args)
...
while (sign(costheta) == originalsign)
y=y(:) + odefun(0,y(:),vars,param)*(dt); % Line 4
costheta = dot(y-normpt,normvec);
k = k + 1;
end
...
end
and to clarify, odefun is F1.m, an m-file of mine. I pass it into the function that contains this while-loop. It's something like whileloop(#F1,args). Line 4 in the code-block above is the Euler method.
The reason I'm using a while-loop is because I want to trigger upon the vector "y" crossing a plane defined by a point, "normpt", and the vector normal to the plane, "normvec".
Is there an easy change to this code that will speed it up dramatically? Should I attempt learning how to make mex files instead (for a speed increase)?
Edit:
Here is a rushed attempt at an example of what one could try to test with. I have not debugged this. It is to give you an idea:
%Save the following 3 lines in an m-file named "F1.m"
function ydot = F1(placeholder1,y,placeholder2,placeholder3)
ydot = y/10;
end
%Run the following:
dt = 1.5e-12 %I do not know about this. You will have to experiment.
y0 = [.1,.1,.1];
normpt = [3,3,3];
normvec = [1,1,1];
originalsign = sign(dot(y0-normpt,normvec));
costheta = originalsign;
y = y0;
k = 0;
while (sign(costheta) == originalsign)
y=y(:) + F1(0,y(:),0,0)*(dt); % Line 4
costheta = dot(y-normpt,normvec);
k = k + 1;
end
disp(k);
dt should be sufficiently small that it takes hundreds of thousands of iterations to trigger.
Assume I must use the Euler method. I have a stochastic differential equation with state-dependent noise if you are curious as to why I tell you to take such an assumption.
I would focus on your actual ODE integration. The fewer steps you have to take, the faster the loop will run. I would only worry about the speed of the sign check after you've optimized the actual integration method.
It looks like you're using the first-order explicit Euler method. Have you tried a higher-order integrator or an implicit method? Often you can increase the time step significantly.