I am trying to implement a program using fsolve in matlab. I want the program to be able to compare n elements pairwise and where each comparison is a row in a function vector F of which fsolve is then applied to.
So far I have written the program for 3 elements (comparing 1 and 2,1 and 3, 2 and 3), writing each function explicitly which works as wanted. But I have now tried constructing the function vector in a loop inside a matlab function. However this does not seem to work since the function is called in every iteration of fsolve and therefore the values change in a unexpected way. Any advise on what could be done?
And the main program looks as follows:
A = [1 1;-1 -1;-1 1;1 -1];
U =[0 0];
Ustart= [6 7];
f= #(Uest)TimeDiffs(U,A,Ustart);
And the function TimeDiffs looks as follow:
function F = TimeDiffs(U,A,Uest)
F=[];
funcnum=1;
for q= 1:length(A)
for p= q+1:length(A)
td= norm(U-A(q,:))-norm(U-A(p,:));
F(funcnum)= norm(Uest-A(q,:))-norm(Uest-A(p,:))-td;
funcnum=funcnum+1;
end
end
end
There seems to be an issue when using a loop in a function that is used in fsolve. Has anyone had any similiar experience?
Related
I am currently trying to parallelize my script for runtime benefits.
My code includes a segment, which has the following form when represented in a very abstract way:
x=zeros(5,1);
y{1}=[1; 3; 5];
y{2}=[2; 4];
parfor i=1:2
x(y{i})= func(y{i});
end
So, I want to populate the indices of the variable x not sequentially, but in a parallel way. This gives me, however, the following error:
The variable x in a parfor cannot be classified.
The indices to be assigned are always disjoint (such as the example [1; 3; 5] and [2; 4]) i.e. no overwriting of entries will occur during the parallel run, which would have otherwise jeopardized the non-sequential processing.
Is there perhaps another way to reformulate this functionality?
I would use structs since output size is changing.
x=zeros(5,1);
y{1}=[1; 3; 5];
y{2}=[2; 4];
parfor i=1:2
temp{i}= sin(y{i});
end
for i=1:2
x(y{i})=temp{i};
end
x=1;
f=#(x) x^3 - (5/x^2)-4*sin(x)-2;
fzero(f,x)
ans =
1.9227
I am supposed to find the root of the equation, x^3 - (5/x^2)-4*sin(x)-2, and the above code is the solution for it.
I don't understand the general mechanism of this code.
(1) What does # operator do?
I know its something like function handle, but I don't understand what function handle is.
(2) How does it work when it includes x in the parenthesis?
(3) How can there be a function fzero(), when I haven't made a script for fzero()?
(4) why are there two variables inside fzero()?
I don't understand that the variable 'f' does there
(5) Why did it declare x=1 in the beginning?
Please consider that I am pretty much new to MATLAB, and don't know much.
f = #(x) ... is the way to declare an anonymous function in MATLAB, actually not very different than creating a function normally in MATLAB such as function output = f(input) .... It is just the pratical way especially when you are working with mathematical functions.
#(x) defines that x is the variable of which is the same as f(x) in mathematics. fzero() is MATLAB's existing function to calculate the x value for f(x) = 0 which means calculating roots of defined funtion. Giving your x a real value at the beginning does mean the starting point to find the root. It will find the roots greater than 1 in your case. It will be very clear for you when you read existing documentation of MATLAB.
Edit:
If you give an interval such as x = [0 1] instead of x = 1, fzero(f,x) would try to calculate roots of f function in given interval, if there is no roots exist in that interval it woud return a NaN value.
I'm trying to perform a sliding neighborhood operation using colfilt.
I am basically trying to run a 2X2 window on an image while running some functions:
f = #(x,y) (func(diff(x:x+1,y:y+1),s(x:x+1,y:y+1)));
e = colfilt(img, [2 2], 'silding', f);
where diff and s are same size as the img (responses calculated in various ways).
func is a function that performs some computations on diff and s.
I keep getting this error:
Matrix dimensions must agree.
Error in colfilt (line 133)
if all(block>=size(a)), % Process the whole matrix at once.
Error in create_e (line 14)
e = colfilt(img, [2 2], 'silding', f);
any thoughts would be appreciated.
Thanks a lot.
I think you are wanting to use a different function, nlfilter, or you need to adapt your function, because it seems you're assuming the input of your function is a 2-by-2 array.
colfilt reshapes each block into a nElementsInBlock-by-1 array and arranges them in a nElementsInBlock-by-nBlocks array, so that you can calculate the function (e.g. kurtosis) in a single step.
nlfilter applies a function on a sliding window, passing each block as a n-by-m array to a user-defined function.
I was wondering if someone could help me with my problem.
Let say that I have the coordinates of MxN vectors in a tensor r of dimensions [M,N,3]. I would like to save in a 3M-by-3N block matrix all dyadic products r_0'*r_0, where r_0 is the vector r_0 = r(m,n,:) for some m and n, and I would like to do this without using for loops.
If haven't explain myself correctly, here is an example code that shows what I would like to obtain (but using for loops, of course):
N=10;
M=5;
r=rand(M,N,3);
Dyadic=zeros(3*M,3*N);
for m=1:M
a1=3*m-2;
a2=3*m;
for n=1:N
b1=3*n-2;
b2=3*n;
aux(3)=r(m,n,3);
aux(2)=r(m,n,2);
aux(1)=r(m,n,1);
Dyadic(a1:a2,b1:b2)=transpose(aux)*aux
end
end
Thanks in advance!
You need to use bsxfun(#times and then re-arrange elements to have the desired output -
%// Get the multipliication result
mat_mult = bsxfun(#times,permute(r,[1 2 4 3]),r);
%// OR if you would like to keep mat_mult as 3D that could be potentially faster -
%// mat_mult = bsxfun(#times,reshape(r,[],3),permute(reshape(r,[],3),[1 3 2]));
%// Re-arrange elements to have them the way you are indexing in nested loops
Dyadic = reshape(permute(reshape(mat_mult,M,N,3,[]),[3 1 4 2]),M*3,N*3);
The major play about this solution is really the re-arrangement of elements after we have the multiplication result.
Quick runtime tests with the input r as 1000 x 1000 x 3 sized array, show that this bsxfun based approach gives over 20x speedup over the nested loop code listed in the question!
I have a function to optimize, say f,in matlab, the function depends on variable x=(x(1),x(2))over which I want to optimize and two parameters n and c which does not need to be optimize, In other words, I have an matrix of values for n and c and I want to find optimal x values for each n and c.
Here is my code:
clear all;
clc;
close all;
f=#(x,n,c)n*x(1)+(x(2)+3*c)/(x(1)+c);
for n=1:10
for c=1:20
x=zeros(length(n),length(c));
fun{n,c}=#(x)f(x,n,c);
options=optimset('Algorithm','interior-point')
x(n,c)=fmincon(fun{n,c},[0;0],[1 0;-1 0;0 1;0 -1],[40;0;40;0],[],[],[],[],[],options);
end
end
??? Subscripted assignment dimension mismatch.
Error in ==> forloop2 at 10
x(n,c)=fmincon(fun{n,c},[0;0],[1 0;-1 0;0 1;0
-1],[40;0;40;0],[],[],[],[],[],options);
Any helps? Thank you so much!
I'm afraid you didn't actually ask a Question, but here's an answer:
function myOptimization
clear all;
clc;
close all;
results=cell(10,20);
for n=1:10
for c=1:20
options=optimset('Algorithm','interior-point');
fmincon(#(x)fun(x,n,c),[0;0],[1 0;-1 0;0 1;0 -1],[40;0;40;0],[],[],[],[],[],options);
resultingCoordinates=fmincon(#(x)fun(x,n,c),[0;0],[1 0;-1 0;0 1;0 -1],[40;0;40;0],[],[],[],[],[],options);
results{n,c}=resultingCoordinates;
end
end
results
end
function f=fun(x,n,c)
f=n*x(1)+(x(2)+3*c)/(x(1)+c);
end
You made at least 3 errors in your original code.
First, x(n,c) = fmincon... doesn't work because fmincon returns an vector with the optimal coordinates as the first output argument. Therefore, you are trying to assign a vector to a single location in the matrix "x", which is the source of your error. I put the optimal coordinates in a cell array, so that I can store all the output coordinates. If you wanted the optimal "f-value" to be assigned to your results as a matrix, you can use [~,f(n,c)]=fmincon... .
Second, "x" is a really bad name for your output matrix, even if you wanted to save the coordinates. It may even cause you errors as it's used to represent the input to your objective function, not the optimum coordinates. Use a different name for the optimum coordinates or optimal function values, which reflects that these are results.
Third, you don't need to continuously re-allocate the output matrix/cell array each time you change your parameters. Your essentially trying to clear the results each iteration, which doesn't work if you want to save them.
I also split up your objective function to be a function, and the optimization of that function to be another.
I hope this helps. In the future, please try to define a clear question on Stack Overflow.