Matlab is rounding my sigmoid function - matlab

I have implemented a sigmoid function as follows in Matlab.
function [y] = sig(x)
y = 1.0 / (1.0 + exp(-x));
end
When I give it a large input such as 100, the function rounds off my result and gives me a 1.
How can I get its accurate value? Is it possible or am I limited to a low range for the value of x.

If you want the difference between 1 and your sigmoid function, you could define a function with the simplified mathematical expression:
1 - 1/(1+exp(-x)) = (1+exp(-x))/(1+exp(-x)) - 1/(1+exp(-x)) = exp(-x) / (1+exp(-x))
function [y] = one_minus_sig(x)
y = exp(-x) / (1+exp(-x));
end
And then:
one_minus_sig(100) = 3.7200759760208356e-44

1.0000000000000... is accurate to about 44 digits so I'm not sure what the problem would be?
Edit: In an earlier version, I said 300 digits - for some reason I had used x=900 in that computation. Here are a few digits:
0.99999999999999999999999999999999999999999996279924023979164037040304196136881662641107846012870706553139188204855222012652822147634307
Computed using Maple.

Related

Scipy laplace scaling

I want to check the calculation of the laplace filter from scipy.ndimage and compare it to my own method if differentiation. Below I have a piece of code that I ran
import scipy.ndimage.filters
n = 100
x_range = y_range = np.linspace(-1, 1, n)
X, Y = np.meshgrid(x_range, y_range)
f_fun = X ** 2 + Y ** 2
f_fun_laplace = 4 * np.ones(f_fun.shape)
res_laplace = scipy.ndimage.filters.laplace(f_fun, mode='constant')
I expect that the variable res_laplace will have the constant value of 4 over the whole domain (excluding the boundaries for simplicity), since this is what I would get by applying the laplace operator to my function f(x,y) = x^2 + y^2.
However, the value that res_laplace produces is 0.00163 in this case. So my question was.. why is this not equal to 4?
The answer, in this specific case, is that you need to multiply the output of scipy.ndimage.filters.laplace with a factor of (1/delta_x) ** 2. Where delta_x = np.diff(x_range)[0]
I simply assumed that the filter would take care of that, but in hindsight it is of course not able know the value delta_x.
And since we are differentiating twice, we need to square the inverse of this delta_x.

How to calculate out put definite integral in matlab

I have run the following for computing the numerical integration of the following function.
But in Matlab instead of a number as an output, it gives me a big expression.
gamma = sqrt(alpha^2 - beta^2);
K1=besselk(1,alpha*sqrt(delta^2+(x-mu)^2));
pdf = alpha*delta* K1/(pi*sqrt(delta^2+(x-mu)^2)) * exp(delta*gamma+ beta*(x-mu));
prob = int(pdf , x, 0,0.5);
with the following parameters :
mu = 0.034 ;
delta = 2.12;
alpha = 0.05;
beta = -0.001;
I have recived this result.
int((53*exp(59679899628370215233/562949953421312000000 - x/1000)*besselk(1, ((x - 17/500)^2 + 2809/625)^(1/2)/20))/(500*pi*((x - 17/500)^2 + 2809/625)^(1/2)), x, 0, 1/2)
I would appreciate any solution to answer this question. How can I compute this expression in Matlab?
The result you got is just not evaluated yet. To obtain a numerical answer with n significant digits, use,
prob_vpa = vpa(prob, n);
The result will still be a symbolic variable, for further symbolic computations. You can also convert it to double,
prob_double = double(prob);

Taylor series for (exp(x) - exp(-x))/(2*x)

I've been asked to write a function that calculates the Taylor series for (exp(x) - exp(-x))/(2*x) until the absolute error is smaller than the eps of the machine.
function k = tayser(xo)
f = #(x) (exp(x) - exp(-x))/(2*x);
abserror = 1;
sum = 1;
n=2;
while abserror > eps
sum = sum + (xo^n)/(factorial(n+1));
n=n+2;
abserror = abs(sum-f(xo));
disp(abserror);
end
k=sum;
My issue is that the abserror never goes below the eps of the machine which results to an infinite loop.
The problem is expression you're using. For small numbers exp(x) and exp(-x) are approximately equal, so exp(x)-exp(-x) is close to zero and definitely below 1. Since you start with 1 and only add positive numbers, you'll never reach the function value.
Rewriting the expression as
f = #(x) sinh(x)/x;
will work, because it's more stable for these small values.
You can also see this by plotting both functions:
x = -1e-14:1e-18:1e-14;
plot(x,(exp(x) - exp(-x))./(2*x),x,sinh(x)./x)
legend('(exp(x) - exp(-x))/(2*x)','sinh(x)/x')
gives

Inf*0 in Matlab

I have the following line in my code:
1 - sqrt(pi/2)*sig*sqrt(Eb)*theta_l*exp(theta_l^2*sig^2*Eb/2).*(1 + erf(-theta_l*sig*sqrt(Eb)/sqrt(2)));
When I evaluate this expression for the following parameters:
Eb = 6324.6;
sig = 1/sqrt(2);
theta = 0.7;, I get Nan. I know that this comes from the product of Infinity by 0.
However when I tested the same line in Mathematica, the result was a finite value. How can I solve this issue? Thanks.
The problematic part of your function is exp(Eb/2). The value of Eb is so large, that the result of its exponentiation cannot be represented by a double precision floating point number (The numerical precision in Mathematica is obviously higher, or dynamic probably at the cost of performance), so you get Inf.
However, you can just change the input units to your function to stop this happening. For example, if we define your function as an anonymous function ...
funky = #(Eb, sig, theta_l) ...
1 - sqrt(pi/2)*sig*sqrt(Eb)*theta_l*exp(theta_l^2*sig^2*Eb/2) .* ...
(1 + erf(-theta_l*sig*sqrt(Eb)/sqrt(2)));
Then
funky(6324.6 / 1000, (1/sqrt(2))/1000, 0.7 / 1000) == ...
funky(6324.6 / 1e6, (1/sqrt(2))/1e6, 0.7 / 1e6) == ...
funky(6324.6 / 1e10, (1/sqrt(2))/1e10, 0.7 / 1e10) % etc

Matlab gamma function: I get Inf for large values

I am writing my own code for the pdf of the multivariate t-distribution in Matlab.
There is a piece of code that includes the gamma function.
gamma((nu+D)/2) / gamma(nu/2)
The problem is that nu=1000, and so I get Inf from the gamma function.
It seems I will have to use some mathematical property of the gamma
function to rewrite it in a different way.
Thanks for any suggestions
You can use the function gammaln(x), which is the equivalent of log(gamma(x)) but avoids the overflow issue. The function you wrote is equivalent to:
exp(gammaln((nu+D)/2) - gammaln(nu/2))
The number gamma(1000/2) is larger than the maximum number MATLAB support. Thus it shows 'inf'. To see the maximum number in MATLAB, check realmax. For your case, if D is not very large, you will have to rewrite your formula. Let us assume that in your case 'D' is an even number. Then the formula you have will be: nu/2 * (nu/2 -1) * ....* (nu/2 - D/2 + 1).
sum1 = 1
for i = 1:D/2
sum1 = sum1*(nu/2 - i+1);
end
Then sum1 will be the result you want.