Why does MATLAB give a negative value for this integration? - matlab

I'm trying do the following integration:
where d >= 0.
I try to get an explicit expression and I think the result should be a positive value since the integrand is greater or equal to 0, but the symbolic integration of MATLAB gave me this result:
syms y d
assume(d>=0)
int(y^2*sqrt(-y^2+d*y),y,0,d)
ans =
-(5*pi*d^4)/128
So I am wondering why a negative value appeared. Do you know how to interpret this result?

This is very clearly a bug, and I've already submitted a bug report with The MathWorks. You can confirm it by plotting the integrand and noting it is always positive over the range [0 d], thus assuring that the integral should yield a positive value:
h = [];
for d = 1:5,
y = linspace(0, d, 1000);
h = [h; plot(y, f(y, d))];
hold on;
end
legend(h, strcat({'d = '}, int2str((1:5).')));
xlabel('y');
ylabel('f(y)');
title('f(y) = y^2*sqrt(d*y - y^2)');
Update #1:
A response from The MathWorks suggest that this may be an issue with the MuPad command limit. Below is the indefinite integral found in MuPad:
Evaluating this at y=d gives the correct result, but evaluating it in the limit as y approaches 0 gives different results based on whether d is substituted before or after the limit calculation. Here's an example with d=1:
Note the change in sign of the first term. In this case, substituting for d before the limit calculation results in a positive (and correct) evaluation of the integral. MATLAB therefore appears to be substituting for d after the limit calculation, giving the erroneous negative result for the definite integral.
Update #2:
I received a follow-up response stating that this bug has now been addressed in the latest release, R2018b. I was able to confirm in the R2018b pre-release that the two limit calculations above produce the same result, and that the integration result now has the proper sign:
syms y d
assume(d >= 0)
int(y^2*sqrt(-y^2+d*y), y, 0, d)
ans =
(5*pi*d^4)/128

Related

Evaluating an integral numerically using Matlab

fun= #(x)exp(- a*(d+1).*(t-x)./(d-(t-x)) ) *b.*exp(-b*x);
int= integral(fun,0,t);
Since I did not find a closed form solution, I am using the above code in Matlab to numericaly evaluate the integral.
I am evaluating this integral for different values of d.
The problem is that when I take d<t I get inf. Any idea what is the problem ? and what approach can be used to evaluate the integral in this case ?
Note that a, b, d, and t are all positive. Ex: a=0.1, b=1, t=4.
If you look at the denominator of the first term of fun you see that it depends on t, x and d. So what happens if d == t and x == 0? The denominator goes to 0.0. If d > t there is no positive value for x that will cause the denominator to go to 0.0.
If we let d == t and plot that first term for values of x = 3:.001:5 we see this:
That discontinuity causes the values to be in the range [-Inf, Inf]. Now if we plot exp of these values we see this:

Matlab : Help in modulus operation

I am trying to implement a map / function which has the equation Bernoulli Shift Map
x_n+1 = 2* x_n mod 1
The output of this map will be a binary number which will be either 0/1.
So, I generated the first sample x_1 using rand. The following is the code. The problem is I am getting real numbers. When using a digital calculator, I can get binary, whereas when using Matlab, I am getting real numbers. Please help where I am going wrong. Thank you.
>> x = rand();
>> x
x =
0.1647
>> y = mod(2* x,1)
y =
0.3295
The dyadic transformation seems to be a transformation from [0,1) continuous to [0,1) continuous. I see nothing wrong with your test code if you are trying to implement the dyadic mapping. You should be expecting output in the [0,1)
I misunderstood your question because I focused on the assumption you had that the output should be binary [0 or 1], which is wrong.
To reproduce the output of the dyadic transformation as in the link you provided, your code works fine (for 1 value), and you can use this function to calculate N terms (assuming a starting term x0) :
function x = dyadic(x0,n)
x = zeros(n,1) ; %// preallocate output vector
x(1) = x0 ; %// assign first term
for k=2:n
x(k) = mod( 2*x(k-1) , 1) ; %// calculate all terms of the serie
end
Note that the output does not have to be binary, it has to be between 0 and 1.
In the case of integers, the result of mod(WhateverInteger,1) is always 0, but in the case of Real numbers (which is what you use here), the result of mod(AnyRealNumber,1) will be the fractional part, so a number between 0 and 1. (1 is mathematically excluded, 0 is possible by the mod(x,1) operation, but in the case of your serie it means all the successive term will be zero too).

calculating the function limit interatively

How to calculate the limit of a function interatively in Matlab, by closer to the given limit value? The accuracy of closing is 10^(-7)
I suppose that that the taylor formula should be used, but don't know how to apply it there.
The function itself is :
The limit is 88.
In other words, the assignment is to present limits as series with assigned variables, compute them step-by-step, approach the limits' value with 10^(-7) precision.
example code of task:
syms x;
F=log(1+sin(x))/(sin(4*x));
a=limit(F,x,0);
disp(a)
sum=taylor(F,x,0,'Order',7);
disp(sum)
disp (subs(sum,x,0))
Calculating it with MATLAB is quite easy, when using the Symbolic Toolbox. The limit function is what you need:
syms x
limit((x^2-9*x-10)/(sqrt(x+6)-4),x,10)
ans =
88
If you want to calculate it by hand, you don't need Taylor series, you'll need L'Hopital's rule, which states
(image: wikipedia)
This leads to
To calculate this in MATLAB, you could use the diff function to get the derivative and do something like
syms x
f(x) = x^2-9*x-10;
g(x) = sqrt(x+6)-4;
r(x) = diff(f(x)) / diff(g(x));
r(10)
ans =
88
Well, as we are using MATLAB, we can of course just use Taylor series expansion and let MATLAB do the job. MATLAB has a taylor function which creates the Taylor expansion. As the Taylor expansion is exact around the expansion point and the error increases, the further away you are from that point, it is best to use 10 as expansion point.
syms x
t(x) = taylor((x^2-9*x-10)/(sqrt(x+6)-4),x,10,'Order',6);
t(10)
ans =
88
OK, now that I know what you're after, what you could perhaps do is use that taylor command and expand about a point that is quite far off from where you want to compute the limit. If we set the expansion point to be where you want to evaluate the limit, no matter what order polynomial you choose, you will get the correct result which is what I'm assuming you're not after.
Start at an expansion point that is far away, then keep incrementally increasing the order of polynomial of the Taylor series until you get your desired accuracy. You don't want to choose an expansion point that is too far away, or you will never get the right answer. As such, I'm going to expand at x = 7.
Something like this:
true_val = 88; %// Define true value
syms x;
f = (x^2-9*x-10)/(sqrt(x+6)-4); %// Define function
order = 2; %// Start with second order
format long g; %// For better formatting
while true %// Keep iterating...
% // Get Taylor polynomial centered at x = 7 of the current order
pol = taylor(f, x, 7, 'Order', order);
%// Evaluate the Taylor series
val = double(subs(pol, x, 10));
%// Show the results
disp(['Order: ' num2str(order)]);
disp('Result');
disp(val);
%// Check to see if we have at least 1e-7 accuracy then break out if yes
if abs(true_val - val) < 1e-7
break;
end
%// Increment the order by 1
order = order + 1;
end
This is what I get:
Order: 2
Result
86.9892652074553
Order: 3
Result
88.0453290425764
Order: 4
Result
87.9954798755339
Order: 5
Result
88.0005926106152
Order: 6
Result
87.9999105029301
Order: 7
Result
88.0000147335223
Order: 8
Result
87.999997429935
Order: 9
Result
88.0000004672668
Order: 10
Result
87.9999999123696

matlab wrong modulo result when the divident is raised to a power

Just wondering... I tried doing by hand (with the multiply and square method) the operation (111^11)mod143 and I got the result 67. I also checked that this is correct, in many online tools. Yet, in matlab plugging:
mod(111^11,143)
gives 127! Is there any particular reason for this? I didn't find anything in the documentation...
The value of 111^11 (about 3.1518e+022) exceeds the maximum integer that is guaranteed to be represented exactly as a double, which is 2^53 (about 9.0072e+015). So the result is spoilt by insufficient numerical precision.
To achieve the correct result, use symbolic computation:
>> syms x y z
>> r = mod(x^y, z);
>> subs(r, [x y z], [111 11 143])
ans =
67
Alternatively, for this specific operation (modulo of a large number that is expressed as a product of small numbers), you can do the computation very easily using the following fact (where ∗ denotes product):
mod(a∗b, z) = mod(mod(a,z)∗mod(b,z), z)
That is, you can apply the modulo operation to factors of your large number and the final result is unchanged. If you choose factors sufficiently small so that they can be represented exactly as double, you can do the computation numerically without any loss of precision.
For example: using the decomposition 111^11 = 111^4*111^4*111^3, since all factors are small enough, gives the correct result:
>> mod((mod(111^4, 143))^2 * mod(111^3, 143), 143)
ans =
67
Similarly, using 111^2 and 111 as factors,
>> mod((mod(111^2, 143))^5 * mod(111, 143), 143)
ans =
67
from the matlab website they recommend using powermod(b, e, m) (b^e mod m)
"If b and m are numbers, the modular power b^e mod m can also be computed by the direct call b^e mod m. However, powermod(b, e, m) avoids the overhead of computing the intermediate result be and computes the modular power much more efficiently." ...
Another way is to use symfun
syms x y z
f = symfun(mod(x^y,z), [x y z])
f(111,11,143)

Is there anyway to calculate mean of beta distribution with MATLAB?

This is my code for calculate the mean:
syms a b x
f=1/(beta(a,b))*x^(a-1)*(1-x)^(b-1);
int(x*f,x,0,1)
Warning: Explicit integral could not be found.
ans =
int((x*x^(a - 1)*(1 - x)^(b - 1))/beta(a, b), x == 0..1)
How can I fix this?
This is my result for TryHArd's:
syms x a b
f=int(x^(a-1)*(1-x)^(b-1),x,0,1)
Warning: Explicit integral could not be found.
f =
piecewise([0 < real(a) and 0 < real(b), beta(a, b)], [real(a) <= 0 or real(b) <= 0, int(x^(a - 1)*(1 - x)^(b - 1), x == 0..1)])
My result did not show the same gamma(a)*gamma(b)/gamma(a+b) as TryHard did.
I assume by beta you mean
beta(z,w) = integral from 0 to 1 of t.^(z-1) .* (1-t).^(w-1) dt.
Then break down the problem:
>> int((x^(a-1))*((1-x)^(b-1)),x,0,1)
ans =
gamma(b)*gamma(a)/gamma(a+b)
The desired integral is equivalent to:
>> bint=int((x^(a-1))*((1-x)^(b-1)),x,0,1);
>> int( x*((x^(a-1))*((1-x)^(b-1)))/bint,x,0,1)
ans =
a/(a+b)
(This was computed with an earlier version of the Matlab SMT (on R14), but should serve as a guide.)
The mean of the Beta distritution is 1/(1+b/a). See for example here
Wolfram alpha is capable of it.
Computing the definite integral directly exceeds maximum standard computation time, but it can find the indefinite integral. Limiting that expression to x between 0 and 1, means simply equating x to 1. This results in this expression, the alternate form of which is the standard form of the mean of the beta distribution.
Wolfram Mathematica (& Alpha) is simply better at symbolic math than MuPad. I'd advise to use MATLAB only for what it rocks at: numerical math. Other than perhaps some fringe cases, I do not expect MuPad to ever come close to what has been achieved by Wolfram.
If you need the result for some specific parameters alpha and beta, you can use betastat. This function can be used also with vectors, like that:
A=[4 4 4];
B=[5 6 7];
[m,v]=betastat(A,B)
This will give you a 3-elements vector for both m (mean) and v (variance). For this example, m will be the means of beta(4,5), beta(4,6) and beta(4,7). (Note that "beta" here denotes the distribution, not the beta-function, like beta function on Matlab).
If you need a general (mathematical) solution, see Rody's answer. Wolfram is much appropriate for this.
EDIT: You can define f (in your code) by the function betapdf instead of the whole formula you wrote over there.