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

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)

Related

"Unable to prove literally" error when trying to create a symbolic function based on an existing function

I need to find inverse of virtual value function of lognormal random variables. This is what I tried to do:
syms flogn(x,p1,p2)
% assume(p2<=0); %Adding this doesn't change the error
flogn(x,p1,p2) = x - logncdf(x,p1,p2,'upper')/lognpdf(x,p1,p2);
glogn = finverse(flogn,x);
But I got the error:
Error using symengine
Unable to prove 'p2 <= 0' literally. Use 'isAlways' to test the statement mathematically.
Error in sym/subsindex (line 810)
X = find(mupadmex('symobj::logical',A.s,9)) - 1;
Error in sym/privsubsasgn (line 1085)
L_tilde2 = builtin('subsasgn',L_tilde,struct('type','()','subs',{varargin}),R_tilde);
Error in sym/subsasgn (line 922)
C = privsubsasgn(L,R,inds{:});
Error in logncdf>locallogncdf (line 73)
sigma(sigma <= 0) = NaN;
Error in logncdf (line 47)
[varargout{1:max(1,nargout)}] = locallogncdf(uflag,x,varargin{:});
Error in Untitled5 (line 3)
flogn(x,p1,p2) = x - logncdf(x,p1,p2,'upper')/lognpdf(x,p1,p2);
I also tried with beta distribution, and got a similar error. How can I use logncdf with symbolic variables?
Note that you could have minimalize your sample code even more, like this:
syms flogn(x,p1,p2)
flogn(x,p1,p2) = logncdf(x,p1,p2);
It's shorter, produces the same error and helps us to focus on the source of the error message.
So, the error doesn't come from trying to inverse a function, but from trying to use an existing function for numerical calculations with symbolic variables.
The error comes from the fact that you want to create a symbolic function flogn based on existing function logncdf, and logncdf has a multiple comparisons.
With the command edit logncdf, you can read the source code of the function and see comparison at lines 73 and 76.
% Return NaN for out of range parameters.
sigma(sigma <= 0) = NaN;
% Negative data would create complex values, which erfc cannot handle.
x(x < 0) = 0;
Matlab cannot compare symbols so it throws errors.
Depending on what you really need, you can have different solutions.
Do you really need to symbolize the function flogn? Couldn't you just write it as a function then calculate the inverse of it (if it can be inversed...)?
If you really want to keep the symbolization, you can also rewrite your own function logncdf (with another name) so it does not have the comparisons. But it's still not guaranteed that you will find an inverse.

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).

Trying to implement Richardson's Extrapolation - Basic Syntax Assistance

I so far have the following
y = log(x);
% Ask user for input values for h and M
% M denotes the number of steps of the algorithm.
h = input('Input value h: ');
M = input('Input value M: ');
%Initialize an MxM matrix
D = zeros(M);
phi = (1/(2*h)) * (y(x+h) - y(x-h));
print(phi);
I obtain the error
Error using symengine (line 58) Index exceeds matrix dimensions.
Error in sym/subsref (line 696)
B = mupadmex('symobj::subsref',A.s,inds{:});
Error in RE (line 12) phi = (1/(2*h)) * (y(x+h) - y(x-h));
First, I believe I should be getting an error message about x not being defined. Second, I have no idea what the matrix dimension error is about. Third, and most importantly, how can I declare the function phi so that it becomes what I wrote?
First, I believe I should be getting an error message about x not being defined.
I'm guessing that x is defined, or you would get that error upon the line defining phi. To check whether x is defined, type "who" or "whos".
Second, I have no idea what the matrix dimension error is about.
This is most likely because y is a scalar, x + h is equal to some nonzero integer that is not 1, and you're trying to access y(x + h). For your own edification try setting y equal to a scalar (e.g. y = 5;) and seeing what errors are produced by indexing it in various legitimate and non-legitimate ways (e.g. y(1), y(0), y(3), y(-1), y(1.5)).
Third, and most importantly, how can I declare the function phi so that it becomes what I wrote?
Based on the context it looks like you want y to be defined as a function of x instead of a scalar. In other words:
y = #(x)log(x);
phi = (1/(2*h)) * (y(x+h) - y(x-h));
The code runs without error when you change the definitions to the above.
One other error you will run into: the print command is not what you're looking for - this prints a figure to a file. You're probably looking for:
disp(phi);

Matlab: mix-up of built-in and external functions

Matlab (2015a) is behaving weirdly: a number of builtin functions are not responding as expected. For instance, typing
ttest([1 2], [1 2])
results in
Error using size
Dimension argument must be a positive integer scalar within indexing range.
Error in nanstd (line 59)
tile(dim) = size(x,dim);
Error in ttest (line 132)
sdpop = nanstd(x,[],dim);
If I do a which for each of these functions:
which size
which nanstd
which ttest
I get, respetively:
built-in (C:\Program Files\MATLAB\R2015a\toolbox\matlab\elmat\size)
C:\Program Files\MATLAB\R2015a\toolbox\stats\eml\nanstd.m
C:\Program Files\MATLAB\R2015a\toolbox\stats\stats\ttest.m
Each of these files looks fine, except that size.m has each one of its rows commented out.
What could be the problem here?
Perhaps related to your problem:
ttest for R2013a makes the following call:
sdpop = nanstd(x,[],dim);
The helpfile for R2013a version of nanstd states:
Y = nanstd(X,FLAG,DIM) takes the standard deviation along dimension DIM of X.
On the other hand, nanstd in the 2005 nansuite package downloaded off Mathworks file exchange states:
FORMAT: Y = nanstd(X,DIM,FLAG)
Notice how DIM and FLAG are reversed!
If I call R2013a's ttest such that it makes a call to the old, 2005 nansuite function nanstd, Matlab generates an error similar to yours:
Error using size
Dimension argument must be a positive integer scalar within indexing range.
Error in nanmean (line 46)
count = size(x,dim) - sum(nans,dim);
Error in nanstd (line 54)
avg = nanmean(x,dim);
Error in ttest (line 132)
sdpop = nanstd(x,[],dim);
If [] is passed as DIM instead of FLAG, then nanstd's call to size(x, DIM) triggers an error because [] is not a positive integer scalar. If something like this is the cause, the broader question is, what's going on with your Matlab install or setup or downloads or whatever such that you're calling archaic code? Or why is that archaic code even around? I don't know at what point in Matlab's release history that nanstd(x, FLAG, DIM) became supported (instead of simply nanstd(x, DIM))?
Archive: below is my old answer which misdiagnosed your problem
Both of your sample vectors x and y are the same (i.e. [1,2]). The estimated variance of the difference is 0, and all your stats are going to blow up with NaN.
Do the stats step by step, and it will be clear what's going on.
x = [1; 2]; % Data you used in the example.
y = [1; 2]; % Data you used in the example.
z = x - y; % Your call to ttest tests whether this vector is different from zero at a statistically significant level.
Now we do all the stats on z
r.n = length(z);
r.mu = mean(z);
r.standard_error = sqrt(var(z,1) / (r.n-1)); % For your data, this will be zero since z is constant!
r.t = r.mu ./ r.standard_error; % For your data, this will be inf because dividing by zero!
r.df = r.n - 1;
r.pvals(r.t >= 0) = 2 * (1 - tcdf(r.t(r.t>=0), r.df)); % For your data, tcdf returns NaN and this all fails...
r.pvals(r.t < 0) = 2 * tcdf(r.t(r.t<0), r.df);
etc...
This should match a call to
[h, p, ci, stats] = ttest(x-y);

Why does the following expression result in error?

Disclaimer. I am familiar with Mathematica but not Matlab, so I apologize if this is a neophyte question.
I am getting a strange error on Matlab on the the following at using Matlab's solve command:
solve(0.2 = (1.4+1/2)^((1.4+1)/(2*(1.4-1)))*(M)/((1+(1.4-1)/2*M^2))^((1.4+1)/(2*(1.4-1))), M)
The error is:
Error: The expression to the left of the equals sign is not a valid target for an assignment.
The equivalent Solve command in Mathematica (using the same expression) works perfectly, so I don't think my expression itself is invalid.
Moreover, I get the same error when I try to use the examples on the doc site: http://www.mathworks.com/help/symbolic/mupad_ref/solve.html
Is it a configuration problem or is there something about the syntax of the command I am misinterpreting?
Edit: I also tried with == instead of =, and I get a different error:
Undefined function or variable 'M'.
Also, as a note, I am running Matlab R2011b (7.13.0.564) 64-bit (glnxa64).
Edit2: I tried the first suggested solution with syms:
>> syms M
>> solve(0.2 == (1.4+1/2)^((1.4+1)/(2*(1.4-1)))*(M)/((1+(1.4-1)/2*M^2))^((1.4+1)/(2*(1.4-1))), M)
Error using char
Conversion to char from logical is not possible.
Error in solve>getEqns (line 245)
vc = char(v);
Error in solve (line 141)
[eqns,vars,options] = getEqns(varargin{:});
Edit3: I have been able to reproduce this issue with even the simplest of equations
>> syms x
>> solve(x^2 -4 == 0, x)
Error using char
Conversion to char from logical is not possible.
Error in solve>getEqns (line 245)
vc = char(v);
Error in solve (line 141)
[eqns,vars,options] = getEqns(varargin{:});
Moreover, I tried the solution suggested here too: MATLAB examples are failing
Matlab's fsolve command assumes the expression is set to zero. If solving numerically, you would not do:
x=solve(2=x+1,x)
but rather:
x=fsolve(#(x) x+1-2,0)
Where the equation is already set to zero, #(x) is what you are solving for, and 0 is the initial guess. Which you must include.
Using solve symbolically, it looks like this:
syms x
val=solve(x+1-2)
Or for your system:
syms M
solve(-0.2+ (1.4+1/2)^((1.4+1)/(2*(1.4-1)))*(M)/((1+(1.4-1)/2*M^2))^((1.4+1)/(2*(1.4-1))))
ans =
4.7161724968093348297842999805458
0.029173662296926424763929809009225
- 3.8716404782846254923900841980317 - 3.4984412176176158766571497649425*i
1.4989673987314948651159693032542 + 5.5784387926679222829321168661041*i
1.4989673987314948651159693032542 - 5.5784387926679222829321168661041*i
- 3.8716404782846254923900841980317 + 3.4984412176176158766571497649425*i
you should define M as sym, and use == instead of =
syms M
solve(0.2 == (1.4+1/2)^((1.4+1)/(2*(1.4-1)))*(M)/((1+(1.4-1)/2*M^2))^((1.4+1)/(2*(1.4-1))), M)
ans =
4.7161724968093348297842999805458
0.029173662296926424763929809009225
- 3.8716404782846254923900841980317 - 3.4984412176176158766571497649425*i
1.4989673987314948651159693032542 + 5.5784387926679222829321168661041*i
1.4989673987314948651159693032542 - 5.5784387926679222829321168661041*i
- 3.8716404782846254923900841980317 + 3.4984412176176158766571497649425*i