Computing pi through series summation in Fortran - sum

Note: LaTeX isn't supported on this site. I'm not sure if there is a better way to write math equations other than to write them in code.
I'm writing a Fortran program to estimate pi through the summation of series:
A = Sum of a_i from i=1 to N
where
pi/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 ...
To compute pi through the series summation, the suggested approach is to set
a_i = (-1)^(i+1)/(2i-1)
To do this, I wrote the following Fortran program -
program cpi
double precision val, pi
integer i
num = 1000
val = 0
do i = 1, num
val = val + ((-1)**(i+1))/(2*i-1)
end do
pi = val
print *, 'Estimated Value of PI:', pi
end program cpi
When I run this program, the output is
Estimated Value of PI: 1.0000000000000000
I must have made a mistake (likely in the /(2*i-1)). I new to Fortran and don't know what I did wrong.

I see my mistake! I need to write out 1.d0 and 2.d0 instead of 1 and 2 so that the calculations are evaluated in double format. I also forgot to multiply pi = val*4.d0. Changing the cpi program to
program cpi
double precision val, pi, MFLOPS
integer i, T1, T2
num = 1000000
val = 0.d0
call system_clock(T1) ! get time stamp
do i = 1, num
val = val + ((-1.d0)**(i+1.d0))/(2.d0*i-1.d0)
end do
call system_clock(T2) ! get time stamp
MFLOPS = num*2.d0/((T2-T1)*1.d8) ! compute MFlop/sec rate
pi = val*4.d0
print *, 'Estimated Value of PI:', pi
print *, 'The calculated number of MFLOPS is:', MFLOPS
end program cpi
returns
Estimated Value of PI: 3.1415916535897743
The calculated number of MFLOPS is: 3.0303030303030304E-002
I also added a MFLOPS calculation to see the computational speed.

Related

Evaluating time complexity for the binomial coefficient

I'm new to Theoretical Computer Science, and I would like to calculate the time complexity of the following algorithm that evaluates the binomial coefficient defined as
nf = 1;
for i = 2 to n do nf = nf * i;
kf = 1;
for i = 2 to k do kf = kf * i;
nkf = 1;
for i = 2 to n-k do nkf = nkf * i;
c = nf / (kf * nkf);
My textbook suggests to use Stirling's approximation
However, I can get the same result by considering that for i = 2 to n do nf = nf * i; have complexity O(n-2)=O(n), that is predominant.
Stirling's approximation seems a little bit overkill. Is my approach wrong?
In your first approach you calculate n!, k! and (n-k)! separately and then calculate the binomial coefficient. Therefore since all of those terms can be calculated with at most operations you have O(n) time complexity.
However, you are wrong about the time complexity of calculating the Stirling's formula. You only need log(n) in base 2 operations to calculate it. This is because when trying to calculate p'th power of some real number, instead of multiplicating it p times, you can instead keep squaring the number to calculate it quickly. For example:
If you want to calculate 2^17, instead of doing 17 operations like this:
return 2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2
you can do this:
a = 2*2
b = a*a
c = b*b
d = c*c
return d * 2
which is only 5 operations.
Note: However keep in mind that the Stirling's formula is not equal to the factorial. It is only an approximation but a good one.
Edit: Also you can consider a^n as e^(log(a)*n) and then calculate it by the quickly converging series expansion
1 + (log(a)n) + ((log(a)n)^2)/2! + ((log(a)n)^3)/3! + ...
Since the series converges very quickly you can get really close approximations in no time.

VB challenge/ help MONTE CARLO INTEGRATION

Im trying to create Monte-Carlo simulation that can be used to derive estimates for integration problems (summing up the area under
a curve). Have no idea what to do now and i am stuck
"to solve this problem we generate a number (say n) of random number pairs for x and y between 0 and 1, for each pair we see if the point (x,y) falls above or below the line. We count the number of times this happens (say c). The area under the curve is computed as c/n"
Really confused please help thank you
Function MonteCarlo()
Dim a As Integer
Dim b As Integer
Dim x As Double
Dim func As Double
Dim total As Double
Dim result As Double
Dim j As Integer
Dim N As Integer
Console.WriteLine("Enter a")
a = Console.ReadLine()
Console.WriteLine("Enter b")
b = Console.ReadLine()
Console.WriteLine("Enter n")
N = Console.ReadLine()
For j = 1 To N
'Generate a new number between a and b
x = (b - a) * Rnd()
'Evaluate function at new number
func = (x ^ 2) + (2 * x) + 1
'Add to previous value
total = total + func
Next j
result = (total / N) * (b - a)
Console.WriteLine(result)
Console.ReadLine()
Return result
End Function
You are using the rejection method for MC area under the curve.
Do this:
Divide the range of x into, say, 100 equally-spaced, non-overlapping bins.
For your function y = f(x) = (x ^ 2) + (2 * x) + 1, generate e.g. 10,000 values of y for 10,000 values of x = (b - a) * Rnd().
Count the number of y-values in each bin, and divide by 10,000 to get a "bin probability." --> p(x).
Next, the proper way to randomly simulate your function is to use the rejection method, which goes as follows:
4a. Draw a random x-value using x = (b - a) * Rnd()
4b. Draw a random uniform U(0,1). If U(0,1) is less than p(x) add a count to the bin.
4c. Continue steps 4a-4b 10000 times.
You will now be able to simulate your y=f(x) function using the rejection method.
Overall, you need to master these approaches before you do what you want since it sounds like you have little experience in bin counts, simulation, etc. Area under the curve is always one using this approach, so just be creative for integrating using MC.
Look at some good textbooks on MC integration.

How to calculate this simple animation effect (physics engine)?

I am implementing a very simple animation effect for a game. The scenario is like this:
there is a elastic rubber line, length is 1 meter, when it is extended over 1 meter, it is elastic.
the line connects two dots A and B like this, the distance is S, S > 1 meter
A <------------- B
then fix dot A, and releases B, the line takes B to the direction of A
I want to know how to calculate time T, which B costs to move X meters towards A (X <= S).
Any ideas?
Thanks!
I have been meaning to learn how to animate these kinds of images in sage (a python based platform for math) for a while, so i used this as an excuse. I hope this code snippet and image is helpful.
A = 3
w = 0.5
# x = f(t) = A cos(wt) inside elastic region
# with x = displacement from 1 meter mark
# in the below code, x is the displacement from origin (x = A cos(wt) + 1)
# find speed when we cross the one meter mark
# f'(t) = -Aw sin(wt), but this is also max speed
# ie f'(t at one meter mark) = -Aw
speed_max = -A * w
# time to reach max speed + time to cross last meter
eta = float(pi/2 * 1/w + 1/abs(speed_max))
# the function you were looking for
def time_left(x):
if x < 1:
return x/abs(speed_max)
else:
return 1/w * arccos((x-1)/A)
It may not be clear in the image but within one meter of the origin there is no acceleration.

I need some help on designing a program that will perform a minimization using VBA Excel

How do I use Excel VBA to find the minimum value of an equation?
For example, if I have the equation y = 2x^2 + 14, and I want to make a loop that will slowly increase/decrease the value of x until it can find the smallest value possible for y, and then let me know what the corresponding value of x is, how would I go about doing that?
Is there a method that would work for much more complicated equations?
Thank you for your help!
Edit: more details
I'm trying to design a program that will find a certain constant needed to graph a nuclear decay. This constant is a part of an equation that gets me a calculated decay. I'm comparing this calculated decay against a measured decay. However, the constant changes very slightly as the decay happens, which means I have to use something called a residual-square to find the best constant to use that will fit the entire decay best to make my calculated decay as accurate as possible.
It works by doing (Measured Decay - Calculated Decay) ^2
You do that for the decay at several times, and add them all up. What I need my program to do is to slowly increase and decrease this constant until I can find a minimum value for the value I get when I add up the residual-squared results for all the times using this decay. The residual-squared that has the smallest value has the value of the constant that I want.
I already drafted a program that does all the calculations and such. I'm just not sure how to find this minimum value. I'm sure if a method works for something like y = x^2 + 1, I can adapt it to work for my needs.
Test the output while looping to look for the smallest output result.
Here's an Example:
Sub FormulaLoop()
Dim x As Double
Dim y As Double
Dim yBest As Double
x = 1
y = (x ^ 2) + 14
yBest = y
For x = 2 To 100
y = (x ^ 2) + 14
If y < yBest Then
yBest = y
End If
Next x
MsgBox "The smallest output of y was: " & yBest
End Sub
If you want to loop through all the possibilities of two variables that make up x then I'd recommend looping in this format:
Sub FormulaLoop_v2()
Dim MeasuredDecay As Double
Dim CalculatedDecay As Double
Dim y As Double
Dim yBest As Double
MeasuredDecay = 1
CalculatedDecay = 1
y = ((MeasuredDecay - CalculatedDecay) ^ 2) + 14
yBest = y
For MeasuredDecay = 2 To 100
For CalculatedDecay = 2 To 100
y = ((MeasuredDecay - CalculatedDecay) ^ 2) + 14
If y < yBest Then
yBest = y
End If
Next CalculatedDecay
Next MeasuredDecay
MsgBox "The smallest output of y was: " & yBest
End Sub

How do you use a moving average to filter out accelerometer values in iPhone OS

I want to filter the accelerometer values using a moving average, how is this done?
Thanks
A simple, single pole, low pass, recursive IIR filter is quick and easy to implement, e.g.
xf = k * xf + (1.0 - k) * x;
yf = k * yf + (1.0 - k) * y;
where x, y are the raw (unfiltered) X/Y accelerometer signals, xf, yf are the filtered output signals, and k determines the time constant of the filters (typically a value between 0.9 and 0.9999..., where a bigger k means a longer time constant).
You can determine k empirically, or if you know your required cut-off frequency, Fc, then you can use the formula:
k = 1 - exp(-2.0 * PI * Fc / Fs)
where Fs is the sample rate.
Note that xf, yf are the previous values of the output signal on the RHS, and the new output values on the LHS of the expression above.
Note also that we are assuming here that you will be sampling the accelerometer signals at regular time intervals, e.g. every 10 ms. The time constant will be a function both of k and of this sampling interval.