Using fgoalattain() or solve() for Matlab - matlab

I am trying to solve a problem (think excel "goal seek") where given a specific rate of return, matlab can solve for the variable "y" (which is used to multiply a matrix).
I've tried using fgoalattain (i don't understand it) and solve
here is the function which basically adds some arrays together to make a cashflow with y being a double. ppam_gen is a n*1 matrix. other_tot is a n*1 matrix.
down_pmt is a double.
function ansirr = cirr(y)
cf_gen_oth = y*ppam_gen + oth_tot
dp = [-down_pmt]
cashflow = [dp;cf_gen_oth]
ansirr = irr(cashflow)
%ansirr = irr([dp; y*ppam_gen + oth_tot])
end
x = fgoalattain(#cirr,0.001,.15,abs(.15))
does not work, the following error is given:
Error using roots (line 28)
Input to ROOTS must not contain NaN or Inf.
Error in irr (line 134)
coeff = roots(fliplr(cf(:,loop)')); % Find roots of polynomial
Error in ppa_model/cirr (line 139)
ansirr = irr(cashflow)
Error in goalcon (line 26)
f = feval(funfcn{3},x,varargin{:});
Error in
fgoalattain>#(y,varargin)feval(cfun{3},y,neqgoals,funfcn,confcn,WEIGHT,GOAL,x,errCheck,varargin{:})
(line 473)
cfun{3} = #(y,varargin)
feval(cfun{3},y,neqgoals,funfcn,confcn,WEIGHT,GOAL,x,errCheck,varargin{:});
Error in nlconst (line 746)
[nctmp,nceqtmp] = feval(confcn{3},x,varargin{:});
Error in fgoalattain (line 519)
[xnew,ATTAINFACTOR,LAMBDA,EXITFLAG,OUTPUT]=...
Error in ppa_model (line 152)
r = fgoalattain(#cirr,0.001,.15,abs(.15))
and using symbolic toolbox doesn't work either.
syms y
solve(irr([-down_pmt ; y*ppam_gen + oth_tot]) == 0.15)
throws the error:
Error using assignin
Attempt to add "y" to a static workspace.
See MATLAB Programming, Restrictions on Assigning to Variables for details.
Error in syms (line 66)
assignin('caller',x,sym(x));
Error in ppa_model (line 152)
syms y

Related

Error while using multiplication in MATLAB

I'm trying to workaround with the DCT function with the exact code on MATLAB's website but when I replicate it, it doesn't work as it should be.
I = imread('exp1.jpg');
I = im2double(I);
T = dctmtx(8);
dct = #(block_struct) T * block_struct.data * T';
B = blockproc(I,[8 8],dct);
This is the code that I used but there is an error when I run code from 4-6
Error:
BLOCKPROC encountered an error while evaluating the user-supplied function handle, FUN.
The cause of the error was:
Error using *
Arguments must be 2-D, or at least one argument must be scalar. Use TIMES (.*) for elementwise multiplication, use PAGEMTIMES to
apply matrix multiplication to the pages of N-D arrays, or use TENSORPROD to find a product between two N-D arrays.
Error in DCTExperiment>#(block_struct)Tblock_struct.dataT' (line 5)
dct = #(block_struct) T * block_struct.data * T';
Error in blockprocFunDispatcher (line 13)
output_block = fun(block_struct);
Error in blockprocInMemory (line 80)
[ul_output fun_nargout] = blockprocFunDispatcher(fun,block_struct,...
Error in blockproc (line 251)
result_image = blockprocInMemory(source,fun,options);
Error in DCTExperiment (line 6)
B = blockproc(I,[8 8],dct);

How can I Minimize this function with MATLAB?

I wrote the following function in MATLAB:
function EX_EFFICIENCY=EXERGY_EFFICIENCY_FUNCTION(CR,ER,PC,T0,P0)
I used the following order (ga):
x = ga(#EXERGY_EFFICIENCY_FUNCTION,5)
But it gets the error:
Not enough input arguments.
Error in EXERGY_EFFICIENCY_FUNCTION (line 22)
T7p=T0.*(PC.^((k-1)./k));
Error in createAnonymousFcn>#(x)fcn(x,FcnArgs{:}) (line 11) fcn_handle
= #(x) fcn(x,FcnArgs{:});
Error in makeState (line 47)
firstMemberScore = FitnessFcn(state.Population(initScoreProvided+1,:));
Error in gaunc (line 40) state =
makeState(GenomeLength,FitnessFcn,Iterate,output.problemtype,options);
Error in ga (line 398)
[x,fval,exitFlag,output,population,scores] = gaunc(FitnessFcn,nvars, ...
Caused by:
Failure in initial user-supplied fitness function evaluation. GA cannot continue.
How can I minimize this function?
What are the variables you want to minimize over? All five CR,ER,PC,T0,P0? Then you need to tell ga to use a length-5-vector and deal its elements to the input arguments of the function. Like this:
xopt = ga(#(x) EXERGY_EFFICIENCY_FUNCTION(x(1),x(2),x(3),x(4),x(5)), 5);
You can also fix some and optimize over the others of course, like this:
xopt = ga(#(x) EXERGY_EFFICIENCY_FUNCTION(x(1),x(2),PC,T0,P0), 2);
optimizes CR, ER for fixed values of PC,T0, and P0.

Division by zero error when evaluating symbolic expression in MATLAB

clear all
syms s w
G = 1/((s)*(s+1)*(s+2)); %transfer function
G_w = subs(G,s,j*w);
W= [-100:0.01:100]; %[min_range:step size:max_range]
nyq = eval(subs(G_w,w,W));
x = real(nyq)
y = imag(nyq)
plot(x,y)
I can't seem to run this code and it keeps displaying error in line 100++ where I've only less than 20 lines.
Error using symengine (line 59)
Division by zero.
Error in sym/subs>mupadsubs (line 139)
G = mupadmex('symobj::fullsubs',F.s,X2,Y2);
Error in sym/subs (line 124)
G = mupadsubs(F,X,Y);
Error in nyquist2 (line 8)
nyq = eval(subs(G_w,w,W)); %replace W with w in equation G_w
This are the errors shown, any expert could help me in this ?
The error is because you are computing G_w using the array W and this array contains the value 0 resulting in a division by zero and therefore the error.
Error using symengine (line 59)
Division by zero.
What you can do to get around this, is to replace the 0 in W with eps.
% Replace zeros with epsilon
W(W == 0) = eps;
nyq = eval(subs(G_w,w,W));
x = real(nyq)
y = imag(nyq)
plot(x,y)
As a side-note, the error isn't complaining about an issue with line 100+ of your code, but rather the stack trace is stating that the error actually originated from within a function that you're calling
The stack trace is ordered from where the error occured to the code that you called to create it
Error using symengine (line 59) <--- WHERE THE ERROR HAPPENED
Division by zero. <--- THIS IS THE ERROR MESSAGE
Error in sym/subs>mupadsubs (line 139) <--- THIS FUNCTION CALLED symengine
G = mupadmex('symobj::fullsubs',F.s,X2,Y2); <--- THIS IS THE LINE THAT CALLED symengine
Error in sym/subs (line 124) <--- THIS FUNCTION CALLED mupadsubs
G = mupadsubs(F,X,Y); <--- THIS IS THE LINE THAT CALLED mupadsubs
Error in nyquist2 (line 8) <--- THIS FUNCTION (YOURS) CALLED subs
nyq = eval(subs(G_w,w,W)) <--- THIS IS THE LINE THAT CALLED subs
#Suever's answer is definitely a better solution in this case where a large number of values must be computed, but another solution if you are looking to evaluate the function at only one value (0) and want to avoid the division-by-zero error, you can do this:
>> limit(G_w,w,0)
ans =
NaN
This is quite computationally intensive though, so it's only worth using when you expect a division-by-zero (e.g. at w = 0).

MATLAB errors when using Lagrange Multipliers?

I have code that, when run, should correctly use Lagrange Multipliers to find the maximum/minimum of a function here:
clear all
syms x y L;
f = x^4+2*y^4;
g = x^2+5*y^2+2*y^2-10;
firstpart=jacobian(f,[x y])-L*jacobian(g,[x y]);
[Lsoln,xsoln,ysoln]=solve(firstpart,x^2+5*y^2+2*y^2-10);
subs(f,{x,y},{xsoln,ysoln})
% The coordinates that correspond with the greatest and smallest values
% above are the maximum and minimum, respectively.
However, when I run it, I get four errors:
Error using sym.getEqnsVars>checkVariables (line 92) The second
argument must be a vector of symbolic variables.
Error in sym.getEqnsVars (line 62)
checkVariables(vars);
Error in solve>getEqns (line 450) [eqns, vars] =
sym.getEqnsVars(argv{:});
Error in solve (line 225) [eqns,vars,options] = getEqns(varargin{:});
Could anyone help?
You are passing two equations as individual arguments zu solve, that is not possible. You have to put both into an array
[Lsoln,xsoln,ysoln]=solve([firstpart,x^2+5*y^2+2*y^2-10] );

"Unable to prove `expr` literally..." error when trying to compare a symbol inside a function

I just started learning MATLAB and I'm trying to normalize a bump function given by
function b = bump(x)
region1 = abs(x) < 1
b(region1) = (exp(-1./(1 - x(region1).^2)))
region2 = abs(x) >= 1
b(region2) = 0
end
To do this, I need to divide by the definite integral from -1 to 1. However, when I input
syms x;
int(bump(x), -1, 1)
I get a long error message, which says
Error using symengine (line 58)
Unable to prove 'abs(x) < 1' literally. To test the statement mathematically, use isAlways.
Error in sym/subsindex (line 1554)
X = find(mupadmex('symobj::logical',A.s,9)) - 1;
Error in sym>privformat (line 2357)
x = subsindex(x)+1;
Error in sym/subsref (line 1578)
[inds{k},refs{k}] = privformat(inds{k});
Error in bump (line 3)
b(region1) = (exp(-1./(1 - x(region1).^2)))
I tried replacing abs(x)<1 with what I think is the suggested isAlways(abs(x)<1), and that removes the error, although it gives the wrong answer (it says the integral is zero).
I don't understand what does the error message means.
syms x defines x as a symbolic variable, invoking symbolic computation on x. This probably isn't what you want.
Instead, define x as some kind of input matrix, e.g. x = zeros(3);. Or, to do numeric integration, use the integral function:
integral(#bump, -1, 1)