How can one obtain more accurate numerical approximations to an integral involving the floor function in Wolfram Alpha? - integral

After reading sections of the following book by Furdui and a page on the AoPS forum, I got interested in the integral
                                                                 
Let's denote the value of this integral by A. Then we have that the value to 20 digits approximately comes down to:
A = 0.6449340668482264365
However, when one puts in the code
integrate 1/(floor(1/x)) from x=0 to 1 to 20 digits
In Wolfram Alpha, it generates the following approximation:
A* = 0.64493701331278272222
As one can see, the numbers start to deviate from one another after the seventh digit. So my question is:
Question: how, if at all, can one obtain more accurate numerical approximations to the value of the integral above in Wolfram Alpha?

Related

Project Euler #206

I was solving problem 206 of project Euler from Hackerrank's competitive set here.
It states -
Find the unique positive integer whose square's decimal representation has the form -
where are known single digits and are unknown single digits.
In other words, find the unique positive integer when given the every other digit of its square, starting with the first digit and including the last digit of the square.
My Algorithm:
Before any optimizations, I have developed the most obvious algorithm. Say, for example, the input is 8_7_6, where _'s are unknown digits.
As we know that, we have to find x such that x^2 takes the form 8_7_6.
The range of x is nothing but, x = [ sqrt(80706), sqrt(89796) ] = [ 284, 299 ].
Now, I run a loop in this range squaring every number. The correct result comes out at 286, which gives - 286^2 = 81796.
Now, I don't understand the flaw in this algorithm. Any number outside the range can never be an answer, right?. I will optimize the code with the properties of squares (like in this case, we could have just checked {284, 286, 294, 296} because since the unit digit of the given input is 6, x must have either 4 or 6 in the unit's place) so that the number of iterations is minimized.
But the problem is, Hackerrank shows me that my algorithm gives the wrong answer in certain test cases. At some, the time limit exceeds,
which is absolutely fine since I have not yet optimized my code, but
why "wrong answer"?
ps: This passed in the first 8 test cases though.

Numerical instability?

I am working in a program that concerns the optimization of some objective function obj over the scalar beta. The true global minimum beta0 is set at beta0=1.
In the mwe below you can see that obj is constructed as the sum of the 100-R (here I use R=3) smallest eigenvalues of the 100x100 symmetric matrix u'*u. While around the true global minimum obj "looks good" when I plot the objective function evaluated at much larger values of beta the objective function becomes very unstable (here or running the mwe you can see that multiple local minima (and maxima) appear, associated with values of obj(beta) smaller than the true global minimum).
My guess is that there is some sort of "numerical instability" going on, but I am unable to find the source.
%Matrix dimensions
N=100;
T=100;
%Reproducibility
rng('default');
%True global minimum
beta0=1;
%Generating data
l=1+randn(N,2);
s=randn(T+1,2);
la=1+randn(N,2);
X(1,:,:)=1+(3*l+la)*(3*s(1:T,:)+s(2:T+1,:))';
s=s(1:T,:);
a=(randn(N,T));
Y=beta0*squeeze(X(1,:,:))+l*s'+a;
%Give "beta" a large value
beta=1e6;
%Compute objective function
u=Y-beta*squeeze(X(1,:,:));
ev=sort(eig(u'*u)); % sort eigenvalues
obj=sum(ev(1:100-3))/(N*T); % "obj" is sum of 97 smallest eigenvalues
This evaluates the objective function at obj(beta=1e6). I have noticed that some of the eigenvalues from eig(u'*u) are negative (see object ev), when by construction the matrix u'*u is positive semidefinite
I am guessing this may have to do with floating point arithmetic issues and may (partly) be the answer to the instability of my function, but I am not sure.
Finally, this is what the objective function obj evaluated at a wide range of values for betalooks like:
% Now plot "obj" for a wide range of values of "beta"
clear obj
betaGrid=-5e5:100:5e5;
for i=1:length(betaGrid)
u=Y-betaGrid(i)*squeeze(X(1,:,:));
ev=sort(eig(u'*u));
obj(i)=sum(ev(1:100-3))/(N*T);
end
plot(betaGrid,obj,"*")
xlabel('\beta')
ylabel('obj')
This gives this figure, which shows how unstable it becomes for extreme values for beta.
The key here is noticing that computing eigenvalues can be a hard problem.
Actually the condition number for this problem is K = norm(A) * norm(inv(A)) (don't compute it this way, use cond(). This means the the an (relative) perturbation in the inpute (i.e. the matrix entries) gets amplified by the condition number when computing the output. I modified your code a little bit to compute and plot the condition number in each step. It turns out that for a large part of the range you are interested in it is greater than 10^17, which is abysmal. (Note that the double floating point numbers are accurate to not quite 16 significant (decimal) digits. This means even the representation error of double floating point numbers will here produce errors that make every digit "insignificant".) This already explains the bad behaviour. You should note that usually we can compute the largest eigenvalues quite accurately, the errors in the smaller (in magnitude) ones usually increase.
If the condition number was better (closer to 1) I would have suggested
computing the singular values, as they happen to be the eigenvalues (due to the symmetry). The svd is numerically more stable, but with this really bad
condition even this will not help. In the following modification of the
final snippet I added a graph that plots the condition number.
The only case where anything is salvageable is for R=0, then we actually
want to compute the sum of all eigenvalues, which happens to be the
trace of our matrix, which can easily be computed by just summing the
diagonal entries.
To summarize: This problem seems to have an inherent bad condition, so it doesn't really matter how you compute it. If you have a completely different formulation for the same problem that might help.
% Now plot "obj" for a wide range of values of "beta"
clear obj
L = 5e5; % decrease to 5e-1 to see that the condition number is still >1e9 around the optimum
betaGrid=linspace(-L,L,1000);
condition = nan(size(betaGrid));
for i=1:length(betaGrid)
disp(i/length(betaGrid))
u=Y-betaGrid(i)*squeeze(X(1,:,:));
A = u'*u;
ev=sort(eig(A));
condition(i) = cond(A);
obj(i)=sum(ev(1:100-3))/(N*t); % for R=0 use trace(A)/(N*T);
end
subplot(1,2,1);
plot(betaGrid,obj,"*")
xlabel('\beta')
ylabel('obj')
subplot(1,2,2);
semilogy(betaGrid, condition);
title('condition number');

Parametric Scoring Function or Algorithm

I'm trying to come up with a way to arrive at a "score" based on an integer number of "points" that is adjustable using a small number (3-5?) of parameters. Preferably it would be simple enough to reasonably enter as a function/calculation in a spreadsheet for tuning the parameters by the "designer" (not a programmer or mathematician). The first point has the most value and eventually additional points have a fixed or nearly fixed value. The transition from the initial slope of point value to final slope would be smooth. See example shapes below.
Points values are always positive integers (0 pts = 0 score)
At some point, curve is linear (or nearly), all additional points have fixed value
Preferably, parameters are understandable to a lay person, e.g.: "smoothness of the curve", "value of first point", "place where the additional value of points is fixed", etc
For parameters, an example of something ideal would be:
Value of first point: 10
Value of point #: 3 is: 5
Minimum value of additional points: 0.75
Exact shape of curve not too important as long as the corner can be more smooth or more sharp.
This is not for a game but more of a rating system with multiple components (several of which might use this kind of scale) will be combined.
This seems like a non-traditional kind of question for SO/SE. I've done mostly financial software in my career, I'm hoping there some domain wisdom for this kind of thing I can tap into.
Implementation of Prune's Solution:
Google Sheet
Parameters:
Initial value (a)
Second value (b)
Minimum value (z)
Your decay ratio is b/a. It's simple from here: iterate through your values, applying the decay at each step, until you "peg" at the minimum:
x[n] = max( z, a * (b/a)^n )
// Take the larger of the computed "decayed" value,
// and the specified minimum.
The sequence x is your values list.
You can also truncate intermediate results if you want integers up to a certain point. Just apply the floor function to each computed value, but still allow z to override that if it gets too small.
Is that good enough? I know there's a discontinuity in the derivative function, which will be noticeable if the minimum and decay aren't pleasantly aligned. You can adjust this with a relative decay, translating the exponential decay curve from y = 0 to z.
base = z
diff = a-z
ratio = (b-z) / diff
x[n] = z + diff * ratio^n
In this case, you don't need the max function, since the decay has a natural asymptote of 0.

Does adding random numbers make them more random?

This is a purely theoretical question.
We all know that most, if not all, random-number generators actually only generate pseudo-random numbers.
Let's say I want a random number from 10 to 20. I can do this as follows (myRandomNumber being an integer-type variable):
myRandomNumber = rand(10, 20);
However, if I execute this statement:
myRandomNumber = rand(5, 10) + rand(5, 10);
Is this method more random?
No.
The randomness is not cumulative. The rand() function uses a uniform distribution between your two defined endpoints.
Adding two uniformly distributions invalidates the uniform distribution. It will make a strange looking pyramid, with the most probability tending toward the center. This is because of accumulation of the probability density function with increasing degrees of freedom.
I urge you to read this:
Uniform Distribution
and this:
Convolution
Pay special attention to what happens with the two uniform distributions on the top right of the screen.
You can prove this to yourself by writing to a file all the sums and then plotting in excel. Make sure you give yourself a large enough sample size. 25000 should be sufficient.
The best way to understand this is by considering the popular fair ground game "Lucky Seven".
If we roll a six sided die, we know that the probability of obtaining any of the six numbers is the same - 1/6.
What if we roll two dice and add the numbers that appear on the two ?
The sum can range from 2 ( both dice show 'one') uptil 12 (both dice show 'six')
The probabilities of obtaining different numbers from 2 to 12 are no longer uniform. The probability of obtaining a 'seven' is the highest. There can be a 1+6, a 6+1, a 2+5, a 5+2, a 3+4 and a 4+3. Six ways of obtaining a 'seven' out of 36 possibilities.
If we plot the distribution we get a pyramid. The probabilities would be 1,2,3,4,5,6,5,4,3,2,1 (of course each of these has to be divided by 36).
The pyramidal figure (and the probability distribution) of the sum can be obtained by 'convolution.
If we know the 'expected value' and standard deviation ('sigma') for the two random numbers, we can perform a quick a ready calculation of the expected value of the sum of the two random numbers.
The expected value is simply the addition of the two individual expected values.
The sigma is obtained by applying the "pythagoras theorem" on the two individual sigmas (square root of the sum of the square of each sigma).

How do pocket calculators simplify fractions and keep imprecise numbers as fractions?

Could someone explain how calculators (such as casio pocket ones) manage equations such as '500/12' and are able to return '125/3' as the result, alternately can someone name some algorithms which do this?
By imprecise numbers I mean numbers which cannot be represented in a fixed number of decimal places, such as 0.333 recurring.
Windows calculator is able to demonstrate this, if you perform '1/3' you will get '0.3333333333333333' as the answer, but then if you multiply this by 3 you will arrive back at '1'.
My HP's fraction display let's you set several modes for fraction display:
Set a maximum denominator. The displayed the fraction is n/d closest to the internal floating point value without d exceeding the maximum. For example, if the maximum is set to 10, the floating point number for pi is nearest the fraction 22/7. However, if the maximum is 1000, then the nearest fraction is 355/113.
Set an exact denominator and reduce the result. The displayed fraction is the n/d closest to the internal floating point value where d is equal to the exact denominator. Having computed n, the fraction is then reduced by the greatest-common-denominator. For example, if the denominator is fixed to be 32, then the floating point number 0.51 is nearest to 16/32 which gets reduced to 1/2. Likewise, the floating point number 0.516 is nearest to 17/32 which is irreducible.
Set an exact denominator and do not reduce the result. For example, 0.51 is shown as 16/32, an unreduced fraction.
The algorithm for the maximum-denominator approach uses continued fractions. An easy to follow example in Python can be found in the limit_denominator method at http://hg.python.org/cpython/file/2.7/Lib/fractions.py#l206 .
The method for the exact-denominator approach is easier. Given a denominator d and a floating point number x, the numerator is just d * x rounded to the nearest integer. Then reduce the fraction n/d by computing the greatest common divisor.
Optionally, the original floating point number can be replaced by the displayed fraction. This is known as a snap-to-grid. That way, you can enter 0.333 to create a fraction that is exactly equal to 1/3. This lets you do exact fractional arithmetic without round-off.
Hope this answer clears everything up for you :-) Let me know if any part needs elaboration or further explanation.
I'd suggest you look at the GMP library's rational number functions. At some point, you will need to accept finite precision in your calculations, unless the sequence of operations is particularly simple. The irrationals (transcendental functions / constants) can only be approximated, e.g., as continued fractions.

Resources