How to resolve this Out of memory. The likely cause is an infinite recursion within the program error - matlab

I am tagging my question and code along with output please into it tell where I did wrong.
Write a function
function p=r1p(a,n,x)
that computes and return p=P*x where P is a 2x2 projection matrix of rank 1
with column space consisting of the scalar multiples of a and
with null space consisting of the scalar multiples of n.
Notes:
The function must be named r1p
a is a nonzero column vector with two components.
n is a nonzero column vector with two components.
x is a nonzero column vector with two components.
My code:
function p = r1p(a,n,x)
% computes the action of P, the 2x2 projection matrix of rank 1 having
% a as an eigenvector with eigenvalue 1 and
% n as an eigenvector with eigenvalue
a=[1; 0.01]
n=[0.01; 1]
x=[1; 0]
p=r1p(a,n,x)
end
Error:
Out of memory. The likely cause is an infinite recursion within the program.
Error in r1p (line 8)
p=r1p(a,n,x)

from the reason that are described in the comment, the function just calls itself each time. The stack, which is a memory that holds details about all the chain of function calls, just fills up till it catch the whole allocated memory, and can't make more call since there is no memory to write the additional call.
It seems that you are missing the point of the recursion. On each stage, the input for the recursion should be changed, getting closer to a "basic" input that will be calculated directly. So this is a stage that is missing at your code - the recursive call for the function must be under a certain condition, and this condition should be fulfilled in some stage.
in addition, it seems that your function does not perform any calculation with your inputs.
see here a simple example:
myFactorial = factorial(5)
function output=factorial(input)
if (input<=0)
output=1;
else
output=input*factorial(input-1);
end
end
you can see that:
the internal call for factorial is under condition
the input is decreased so finally the input is 1 and the function is not called again.
there is an internal calculation, that implements what the programmer wanted.

Related

Receiving unknown errors when trying to use fsolve to find the solutions of a function

I have to plot the solution for masses between 4 and 8kg, which I wrote using the code below:
weight=linspace(4,8,100)
Then I use a for loop to find the solutions for the weights within this vector, while also declaring the variable a, and a guess of the time required:
for z=1:length(weight)
a=(weight./(1360*pi)).^(1/3)
tguess=14400
timeinseconds=fsolve(#(t)cookingtimes(t,a),tguess)
timeinhours=timeinseconds/(60*60)
end
The function that I mentioned previously is below:
function F=cookingtimes(t,a)
k=1:22;
alpha=0.7*10^(-7);
F(1)=(2./(pi*0.464))*sum(((-1).^(k-1))./k).*sin(k*pi*0.464).*exp(((-(k.^2)).*(pi.^2).*((alpha.*t))./(a.^2)))-57/80
end
Where F(1) represents the following equation 1, which will be equal to 57/80. Rather than adding until infinity, I chose the value of 22 as the equation converges to this value. r/a is equal to 0.464, which is why this is present within my function.
When running this code, I am given errors that I cant manage to solve.
Arrays have incompatible sizes for this operation.
Error in Homework1>cookingtimes (line 58)
F(1)=(2./(pi*0.464))*sum(((-1).^(k-1))./k).*sin(k*pi*0.464).*exp(((-(k.^2)).*(pi.^2).*.((alpha.*t))./(a.^2)))-57/80
Error in Homework1 (line 28)
timeinseconds=fsolve(#(t)cookingtimes(t,a),tguess)
Error in fsolve (line 264)
fuser = feval(funfcn{3},x,varargin{:});
Caused by:
Failure in initial objective function evaluation. FSOLVE cannot continue.
The arrays that I have produced are all of the same length, which is why I am very stuck on this issue.
You are trying to perform an operation on two arrays that have different sizes. In your case, the issue may be caused by the fact that you are defining the variable a as a vector inside the for loop, but using it in the function cookingtimes as a scalar. To fix this, you can modify your function to accept a vector of a values and return a corresponding vector of function values.
I modified the cookingtimes function to accept a vector of a values, and return a corresponding vector of function values.
function F=cookingtimes(t,a)
k=1:22;
alpha=0.7*10^(-7);
F=(2./(pi*0.464))*sum(((-1).^(k-1))./k).*sin(k*pi*0.464).*exp(((-(k.^2)).* (pi.^2).*((alpha.*t))./(a.^2)))-57/80;
end
In the for loop, You need to compute a for each weight value, and use a vector of a values in the call to fsolve. Also store the solutions in a vector timeinseconds instead of a scalar, as there are multiple solutions to be found.
for z=1:length(weight)
a=(weight(z)./(1360*pi)).^(1/3); % compute a for each weight value
tguess=14400;
timeinseconds(z)=fsolve(#(t)cookingtimes(t,a),tguess);
timeinhours=timeinseconds/(60*60);
end

Vectorization of function in Matlab

I'm trying to vectorize one function in Matlab, but I have a problem with assigning values.
function [val] = clenshaw(coeffs,x)
b=zeros(1,length(coeffs)+2);
for k=length(coeffs):-1:2
b(k)=coeffs(k)-b(k+2)+2*b(k+1).*x;
end
val=coeffs(1)-b(3)+b(2).*x;
The purpose of this function is to use Clenshaw's algorithm to compute a value of one polynomial with coefficients "coeffs" at point x.
It work fine when x is a single value, but I'd like it to work with vector of arguments too.
When I try to pass a vector I get an error:
Unable to perform assignment because the left
and right sides have a different number of
elements.
Error in clenshaw (line 7)
b(k)=coeffs(k)-b(k+2)+2*b(k+1).*x;
I understand that there is a problem, because I'm trying to assign vector to a scalar variable b(k).
I tried making b a matrix instead of a vector, however I still cannot get the return output I'd like to have which would be a vector of values of this function at points from vector x.
Thank you for helping and sorry if something isn't entirely clear, because English is not my native language.
The vectorized version of your function looks like this:
function [val] = clenshaw(coeffs,x)
b=zeros(length(x),length(coeffs)+2);
for k=length(coeffs):-1:2
b(:,k)=coeffs(k)-b(:,k+2)+2*b(:,k+1).*transpose(x);
end
val=coeffs(1)-b(:,3)+b(:,2).*transpose(x);
end
b needs to be a matrix. In your loop, you have to perform every operation per row of b. So you need to write b(:,k) instead of b(k). Since b(:,k) is a vector and not a scalar, you also have to be careful with the dimensions when using the .* operator. To get the correct results, you need to transpose x. The same goes for the calculation of val. If you don't like the transposition, just swap the rows and cols of b and you get this:
function [val] = clenshaw(coeffs,x)
b=zeros(length(coeffs)+2, length(x));
for k=length(coeffs):-1:2
b(k,:)=coeffs(k)-b(k+2,:)+2*b(k+1,:).*x;
end
val=coeffs(1)-b(3,:)+b(2,:).*x;
end
However, the first version returns a column vector and the second a row vector. So you might need to transpose the result if the vector type is important.

MATLAB: Using FZERO on a function which has a vector output

I am working on my thesis and running in some programming problems in Matlab. I am trying to implement the ''golden Bisection Method'' to speed up my code. To this end, I've consulted the build in function FZERO.
So I am determining the difference between two vectors which are both (1x20).
Difference = Clmax_dist-cl_vec;
Clmax_dist comes from a semi-empirical method and cl_vec comes from the excecution of an external AVL.exe file.
Essentially, this difference depends only on one single variable AOA because the Clmax_dist vector is a constant. Hence, I am constantly feeding a new AOA value to the AVL.exe to obtain a new cl_vec and compare this again to the constant Clmax_dist.
I am iterating this until one of the element in the vector becomes either zero or negative. My loop stops and reveals the final AOA. This is a time consuming method and I wanted to use FZERO to speed this up.
However, the FZERO documentation reveals that it only works on function which has a scalar as input. Hence, my question is: How can I use FZERO with a function which has a vector as an output. Or do i need to do something totally different?
I've tried the following:
[Difference] = obj.DATCOMSPANLOADING(AOA);
fun=#obj.DATCOMSPANLOADING;
AOA_init = [1 20];
AOA_root = fzero(fun,AOA_init,'iter');
this gave me the following error:
Operands to the || and && operators must be convertible to logical scalar values.
Error in fzero (line 423)
while fb ~= 0 && a ~= b
Error in CleanCLmax/run (line 11)
AOA_root = fzero(fun,AOA_init,'iter');
Error in InitiatorController/moduleRunner (line 11)
ModuleHandle.run;
Error in InitiatorController/runModule (line 95)
obj.moduleRunner(ModuleHandle);
Error in RunSteps (line 7)
C.runModule('CleanCLmax');
The DATCOMSPANDLOADING function contains the following:
function [Difference] = DATCOMSPANLOADING(obj,AOA)
[Input]= obj.CLmaxInput; % Creates Input structure and airfoil list
obj.writeAirfoils(Input); % Creates airfoil coordinate files in AVL directory
[Clmax_dist,YClmax,Cla_mainsections] = obj.Clmax_spanwise(Input); % Creates spanwise section CLmax with ESDU method
[CLa] = obj.WingLiftCurveSlope(Input,Cla_mainsections); % Wing lift curve slope
[Yle_wing,cl_vec] = obj.AVLspanloading(Input,CLa,AOA); % Creates spanloading with AVL
Difference = Clmax_dist-cl_vec;
end
If I need to elaborate further, feel free to ask. And of course, Thank you very much.
fzero indeed only works on scalars. However, you can turn your criterion into a scalar: You are interested in AOA where any of the elements in the vector becomes zero, in which case you rewrite your objective function to return two output arguments: minDifference, which is min(Difference), and Difference. The first output, minDifference is the minimum of the difference, i.e. what fzero should try to optimize (from your question, I'm assuming all values start positive). The second output you'd use to inspect your difference vector in the end.

Matlab index error

I have coded an algorithm in MATLAB which contains a loop. The code works well for a number of iterations, then suddenly stops due to the following error
??? Index exceeds matrix dimensions.
What could be the cause of this error?
This is part of the code.
[x,fval,exitflag,output]=cplexmilp(f,Aineq,bineq,Aeq,beq,sostype,sosind,soswt,lb,ub,ctype,x0,options)
for m=1:100
supply=[];
supply=x(1:p*w*t);
supply=reshape(supply,w,p*t)';
Failprob=[0.1927 0.1753 0.1728 0.1165 0.2375 0.1649];%Low
%Failprob=[0.3770 0.3061 0.2894 0.2682 0.3993 0.2983];%Med
Failprob=[0.5708 0.4842 0.4097 0.5144 0.4205 0.4312];%High
%Failprob=[0.4547 0.4958 0.4965 0.4158 0.4971 0.4957];%High
Epsilon=[.8 .9];%Low
%Epsilon=[.7 .9];%Med
Epsilon=[.6 .9];%High
Sigma=.05;%Low
%Sigma=.10;%Med
Sigma=.2;%High
Failprob=Failprob';
prob2=1-Failprob;
prob2=horzcat(prob2,Failprob);
prob2=repmat(prob2,t,1);
for n=1:t
for i=1+p*(n-1):p+p*(n-1)
for j=1:w
r=rand;
prob=prob2(i,:);
prob=cumsum(prob);
value=[supply(i,j),(Epsilon(1)+(Epsilon(2)-Epsilon(1))*rand(1))*supply(i,j)];
%values corresponding to the probabilities
ind=find(r<=prob,1,'first');
supply(i,j)=value(ind);
end
end
end
After some iterations, I have the following output.
Iteration 20 Current value 12020253.6911 Best value 12020253.6911
Iteration 21 Current value 10841341.9259 Best value 10841341.9259
Iteration 22 Current value 11307742.3543 Best value 10841341.9259
Iteration 23 Current value 10784746.9812 Best value 10784746.9812
??? Index exceeds matrix dimensions.
Error in ==> CodefinalTwelveGuMulti at 1947
supply=x(1:p*w*t);
I don't even know how that code could even run. x is not defined anywhere and you suddenly are starting to use it in your for loop at the beginning. My guess is that you have some code defined somewhere earlier on, those iterations start happening and then once those iterations end, this function runs. That makes sense since I don't see any print-out statements anywhere in your code.
That's what the error is alluding to. It is stating that you are trying to index into x with indices that exceed the dimensions of x. In this case, x has no dimensions (i.e. empty). As such, no matter what indices you are using to try to index into x, MATLAB will give you an index exceeding error.
You need to either define x by providing it as an input into your function, or define it inside the function itself.

in matlab exit the entire loop and more

I am using this function to get a column vector in which every element is supposed to be 1,
but after n gets large, sometimes some element is not 1, this is due to the method constraint, I want to find out how large is n and return the value. the problem are: 1.it seems that 1 is stored as 1.0000, don't know how to convert it, and how to compare(location in comments) 2. don't know how to exit a loop completely. thank you.
function x = findn(n)
for m = 1:n
[a,b]=Hilbert(m);
m1 = GaussNaive(a,b);
m2 = size(m1,1);
% m1 is a n*1 matrix (a column vector) which every element is supposed
% to be 1, but when n gets large, some element is not 1.
for i = 1:m2
if (m1(i) ~= 1)
% this compare isn't really working, since 1 is stored as 1.0000 for whatever
% for whatever reason and they are not equal or not not equal.
% I doubt whether it really compared.
x = m;
break;
% it just exit the inner for loop, not entirely
end
end
end
In Matlab all numeric variables are, by default, double precision floating-point numbers. (Actually strings and logicals can look like f-p numbers too but forget that for the moment.) So, unless you take steps that your code doesn't show, you are working with f-p numbers. The sort of steps you can take include declaring your variables to have specific types, such as int32 or uint16, and taking care over the arithmetic operations you perform on them. Matlab's attraction to double-precision floating-point is very strong and it's easy to operate on ints (for example) and end up with floating-point numbers again. Start reading about those types in the documentation.
The reasons for avoiding (in-)equality tests on f-p numbers are explained on an almost daily basis here on SO, I won't repeat them, have a look around. The straightforward way to modify your code would be to replace the test with
if (m1(i) ~= 1)
with
if ((abs(m1(i)-1)>tol)
where tol is some small number such that any number larger than 1+tol (or smaller than 1-tol) is to be considered not equal to 1 for your purposes.
Unfortunately, as far as I know, Matlab lacks a statement to break from an inner loop to outside a containing loop. However, in this case, you can probably replace the break with a return which will return control to the function which called your function, or to the command-line if you invoked it from there.