Random generator function in Python - python

I have been learning Java since September, but have been given an assignment for a science course by a professor to create a program in Python that will generate a random diameter using a max and minimum value, and 15 random points within this sphere (x, y, z).
I need to make a random number generator that generates a number between 0.0 and 1.0 so I can plug it into my formula to find a random diameter. If the random number is RN, it would be: [(RN*(max-min))+min]
At first I used this random function:
from random import*
RN=random():
The problem is, this random function is [0.0, 1.0). In other words, it does not include 1.0.
How can I create a function that includes 1.0?
Also, if you don't mind, can you help me with finding the y and z coordinates? I know how to find x.
The formula for the y value is y=+ or - sqrt(r^2-x^2) (to be randomly generated too).
I would have the x value, which is the result from the random function [0.0-1.0], and the radius which would be half my diameter. I am a complete beginner at Python, how do I initialize my x and y and put the above formula in?
The formula for z is similar, z=+ or - sqrt(-x^2-y^2+r^2) (to be randomly generated as well)
These are using the formulas for a circle:
radius: r=sqrt(x^2+y^2)
sphere:r=sqrt(x^2+y^2+z^2)
I would be incredibly grateful if you could answer any part of my question, thank you so much for taking the time to read this!!
**by the way, I am usinHi! I have been learning Java since September, but have been given an assignment for a science course by a professor to create a program in Python that will generate a random diameter using a max and minimum value, and 15 random points within this sphere (x, y, z).
I need to make a random number generator that generates a number between 0.0 and 1.0 so I can plug it into my formula to find a random diameter. If the random number is RN, it would be: [(RN*(max-min))+min]
At first I used this random function:
from random import*
RN=random():
The problem is, this random function is [0.0, 1.0). In other words, it does not include 1.0.
How can I create a function that includes 1.0?
Also, if you don't mind, can you help me with finding the y and z coordinates? I know how to find x.
The formula for the y value is y=+ or - sqrt(r^2-x^2) (to be randomly generated too).
I would have the x value, which is the result from the random function [0.0-1.0], and the radius which would be half my diameter. I am a complete beginner at Python, how do I initialize my x and y and put the above formula in?
The formula for z is similar, z=+ or - sqrt(-x^2-y^2+r^2) (to be randomly generated as well)
These are using the formulas for a circle:
radius: r=sqrt(x^2+y^2)
sphere:r=sqrt(x^2+y^2+z^2)
I would be incredibly grateful if you could answer any part of my question, thank you so much for taking the time to read this!!!
**by the way, I am using python x,y spyder!

random.uniform will give you a uniformly distributed random number between a given minimum and maximum.
Just generate random points and check if they are within the sphere. If they are not, discard them and try again.
import math
import random
def generate_points(n_points, min_diameter=0, max_diameter=1):
diameter = random.uniform(min_diameter, max_diameter)
radius = diameter / 2
count = 0
while count < n_points:
x, y, z = [random.uniform(-radius, radius) for _ in range(3)]
distance = math.sqrt(x * x + y * y + z * z)
if distance <= radius:
yield (x, y, z)
count += 1
for x, y, z in generate_points(10):
print x, y, z
Note: this may bias what points are generated. (I'm not sure, it's probably okay actually.) Another approach might be to use polar coordinates, choosing two random angles and a random radius (offset from center).
Here is the math for that approach:
theta = random.uniform(0, 2 * math.pi)
phi = random.uniform(-math.pi / 2, math.pi / 2)
x = r * cos(theta) * cos(phi)
y = r * sin(phi)
z = r * sin(theta) * cos(phi)
See here for more on distribution:
https://math.stackexchange.com/questions/87230/picking-random-points-in-the-volume-of-sphere-with-uniform-probability
http://mathworld.wolfram.com/SpherePointPicking.html (this one is about points on the surface of the sphere, so might not be as useful)

I used this for a random generator and it works, i'm not sure if it's the right one you're looking for but I hope it helps
import random
maths_operator_list=['+','-','*']
maths_operator = random.choice(maths_operator_list)
number_one = random.randint(0,20)
number_two = random.randint(0,20)
correct_answer = 0
print(str(number_one), str(maths_operator), number_two)
if maths_operator == '+':
correct_answer = number_one + number_two
elif maths_operator == '-':
correct_answer = number_one - number_two
elif maths_operator == '*':
correct_answer = number_one * number_two
print(correct_answer)

You can use random.range
random.randrange(-15,15,.1)
That will find a number between -15 and 15 that is divisible by 0.1.

As answer to the random number generator :
RN = random.uniform(a, b)
Return a random integer N such that a <= N <= b.
As how to initiate x and y, y will be initialize when you set y = to something, it does it automatically.

Related

Plotting the mean square displacement of a 2D random walk as a function of δt

I've already created a code for random walk of 10000 steps and then repeated it 12 times and stored each run in a separate text file (which was required in the question). I then calculated the mean square displacement of it(not sure if it's done correct). I now need to 'plot my Mean Square Displacement as a function of δt, including errorbars σ = std(MSD)/√N, where std(MSD) is the standard deviation among the different runs and N is the number of runs.' and then compute the diffusion constant D from the curve and check that D = 2 (∆/dt) where dt = 1.
Here is my code so far:
import numpy as np
import matplotlib.pyplot as plt
import random as rd
import math
a = (np.zeros((10000, 2), dtype=np.float))
def randwalk(x,y):
theta= 2*math.pi*rd.random()
x+=math.cos(theta); # This uses the equation given, since we are told the spatial unit = 1
y+=math.sin(theta);
return (x,y)
x, y = 0.,0.
for i in range(10000): # Using for loop and range function to initialize the array
x, y = randwalk(x,y)
a[i,:] = x,y
fn_base = "random_walk_%i.txt" # Saves each run in a numbered text file, fn_base is a varaible to hold format
N = 12
for j in range(N):
rd.seed(j) # seed(j) explicitly sets the seed to random numbers
x , y = 0., 0.
for i in range(10000):
x, y = randwalk(x,y)
a[i,:] = x, y
fn = fn_base % j
np.savetxt(fn, a)
destinations = np.zeros((12, 2), dtype=np.float)
for j in range(12):
x, y = 0., 0.
for i in range(10000):
x, y = randwalk(x, y)
destinations[j] = x, y
square_distances = destinations[:,0] ** 2 + destinations[:,1] ** 2
m_s_d = np.mean(square_distances)
I think that to do it I just have to plot the msd against the number of steps? But I'm not sure how to do this. I saw a similar question on stackoverflow but the code for it is different than mine and I don't understand how to use that for my code.
I tried to do next
plt.figure()
t = 10000
plt.plot(m_s_d, t)
plt,show()
But this gives an error as the dimensions are not equal.
Edit ** I think my issue is that I am trying to plot it against number of steps when I should be plotting it against the change in time. However I can’t work out how to calculate the change in time dt?
Apologies in advance is question isn't formulated well, I am fairly new to computing. Thank you.

Approximating derivatives using python

I have attempted to solve the following problem. I tried to solve it first with a set step size h using 0.1. However I need to change this in my code and use a for loop to loop through the values 0,1,..,20. I am a little confused how to do this problem but I was hoping to get some help with fixing the code I produced so far. Thanks!
import numpy as np
from math import sin
def derivative(func , x, h ):
for h in range(20):
return (func(x+h)-func(x))/h
def f(x):
return sin(x)
print(derivative(f, pi/4))
Gives the output
0.6706029729039897
MY EDIT:
def derivative(func , x, h ):
for h in range(20):
return (func(x+h)-func(x))/h
The exercise is asking you to compute the derivative using varying precision (represented using the variable h), and compare that to the exact/real derivative of the function.
Let h = 10 ^ -j, with j varying from 0 to 20. This means h will go (discretely) from 10⁻⁰ to 10⁻²⁰. You can use a for-loop and the range(...) function for that. Then pass that to the derivative function (to which you can a third parameter for the value of h)
def derivative(func, x, h):
return (func(x + h) - func(x)) / h
Next, you need to compare that to the exact derivative. The function f(x) = sin(x) has a known (exact) derivative which is cos(x). In math notation, d(sin x)/dx = cos x. This means that for any x, cos(x) will give you the exact derivative of sin at that x.
So you need to compare the result of the derivative(...) function to the value of cos(x). This will give you the difference. You can then use the basic Python function abs(x) to get the absolute value of that difference, which will give you the absolute difference, which is the desired result. Do that for each j from 0 to 20 and store the results somewhere, in an array or a dict.
from math import sin, cos, pi
x = pi / 4
diffs = {}
for j in range(21): # range is exclusive so range(21) will stop at 20
h = 10 ** -j
deriv = derivative(sin, x, h)
exact = cos(x)
diff = abs(deriv - exact)
diffs[h] = diff
Then, you can use pyplot's loglog function to plot those results on a graph, passing as X the range(...) result and as Y the array containing the results.
import matplotlib.pyplot as plt
ordered = sorted(diffs.items())
x, y = zip(*ordered)
plt.loglog(x, y)

Calculate PI using Random Numbers

Having trouble with the following question:
In geometry the ratio of the circumference of a circle to its diameter is known as π. The value of π can be estimated from an infinite series of the form:
π / 4 = 1 - (1/3) + (1/5) - (1/7) + (1/9) - (1/11) + ...
There is another novel approach to calculate π. Imagine that you have a dart board that is 2 units square. It inscribes a circle of unit radius. The center of the circle coincides with the center of the square. Now imagine that you throw darts at that dart board randomly. Then the ratio of the number of darts that fall within the circle to the total number of darts thrown is the same as the ratio of the area of the circle to the area of the square dart board. The area of a circle with unit radius is just π square unit. The area of the dart board is 4 square units. The ratio of the area of the circle to the area of the square is π / 4.
To simuluate the throwing of darts we will use a random number generator. The Random module has several random number generating functions that can be used. For example, the function uniform(a, b) returns a floating point random number in the range a (inclusive) and b (exclusive).
Imagine that the square dart board has a coordinate system attached to it. The upper right corner has coordinates ( 1.0, 1.0) and the lower left corner has coordinates ( -1.0, -1.0 ). It has sides that are 2 units long and its center (as well as the center of the inscribed circle) is at the origin.
A random point inside the dart board can be specified by its x and y coordinates. These values are generated using the random number generator. The way we achieve that is:
xPos = random.uniform (-1.0, 1.0)
yPos = random.uniform (-1.0, 1.0)
To determine if a point is inside the circle its distance from the center of the circle must be strictly less than the radius of the circle. The distance of a point with coordinates ( xPos, yPos ) from the center is math.hypot (xPos, yPos). The radius of the circle is 1 unit.
The program that you will be writing will be called CalculatePI. It will have the following structure:
import math
import random
def computePI ( numThrows ):
...
def main ():
...
main()
Your function main() will call the function computePI() for a given number of throws. The function computePI() will simulate the throw of a dart by generating random numbers for the x and y coordinates. You will determine if that randomly generated point is inside the circle or not. You will do this as many times as specified by the number of throws. You will keep a count of the number of times a dart lands within the circle. That count divided by the total number of throws is the ratio π/4. The function computePI() will then return the computed value of PI.
In your function main() you want to experiment and see if the accuracy of PI increases with the number of throws on the dartboard. You will compare your result with the value given by math.pi. The quantity Difference in the output is your calculated value of PI minus math.pi. Use the following number of throws to run your experiment - 100, 1000, 10,000, 100,000, 1,000,000, and 10,000,000. You will call the function computePI() with these numbers as input parameters. Your output will be similar to the following, i.e. the actual values of your Calculated PI and Difference will be different but close to the ones shown:
Computation of PI using Random Numbers
num = 100 Calculated PI = 3.320000 Difference = +0.178407
num = 1000 Calculated PI = 3.080000 Difference = -0.061593
num = 10000 Calculated PI = 3.120400 Difference = -0.021193
num = 100000 Calculated PI = 3.144720 Difference = +0.003127
num = 1000000 Calculated PI = 3.142588 Difference = +0.000995
num = 10000000 Calculated PI = 3.141796 Difference = +0.000204
Difference = Calculated PI - math.pi
Your output must be in the above format. The number of throws must be left justified. The calculated value of π and the difference must be expressed correct to six places of decimal. There should be plus or minus sign on the difference. Read the relevant sections in the book on formatting.
Till now I have done:
import math
import random
def computePI (numThrows):
xPos = random.uniform (-1.0, 1.0)
yPos = random.uniform (-1.0, 1.0)
in_circle = 0
throws = 0
while (throws < numThrows):
if math.hypot (xPos, yPos) <= 1:
in_circle += 1
throws += 1
pi = (4 * in_circle) / numThrows
return pi
def main ():
throws = (100, 1000, 10000, 100000, 1000000, 10000000)
for numThrows in throws[0:7]:
main ()
I am having trouble calling the ComputePI function in the Main function. Also how do I print num with left indentation and ensure that all numbers have the required decimal space? Thank you!
Your program has three main issues:
Generating random numbers in the wrong place
xPos = random.uniform (-1.0, 1.0)
yPos = random.uniform (-1.0, 1.0)
These lines are executed only once when you enter the computePI() function. You then proceed to calculate the exact same value of hypot for hundreds or even thousands of iterations. Put these lines inside the while loop.
Integer arithmetic
pi = (4 * in_circle) / numThrows
Since in_circle and numThrows are both integers, this calculation will be performed using integer arithmetic (in Python 2, at least). Changing the constant from 4 to 4.0 will change this to a floating point calculation:
pi = (4.0 * in_circle) / numThrows
Incomplete main() function:
There's no need to use a subset of your throws tuple, and you haven't added a body to your for loop. Try this:
for numThrows in (100, 1000, 10000, 100000, 1000000, 10000000):
randpi = computePI(numThrows)
diff = randpi - math.pi
print "num = %-8d Calculated PI = %8.6f Difference = %+9.6f" % \
(numThrows, randpi, diff)
This is how I find it easy.
import random
import math
def approximate_pi():
total_points = 0
within_circle = 0
for i in range (10000):
x = random.random()
y = random.random()
total_points += 1
distance = math.sqrt(x**2+y**2)
if distance < 1:
within_circle += 1
if total_points % 1000 == 0:
pi_estimate = 4 * within_circle / total_points
yield pi_estimate
set total point generated and points withing the circle to zero
total_points = 0
within_circle = 0
generate the random values of x and y for multiple times. Calculate the distance of the point from the center of the circle or (0,0). Then if the distance is less than one it means that it's within the circle so it is incremented.
distance = math.sqrt(x**2+y**2)
if distance < 1:
within_circle += 1
Now if you have generated let's say multiple of 1000(1000 because we have taken the range for 10,000 so 1000 to get 10 values of pi), calculate the estimated value of pi using this formula which you know already.and the tied the estimate value(pi_estmate)
if total_points % 1000 == 0:
pi_estimate = 4 * within_circle / total_points
yield pi_estimate
pi_estimates = list(es for es in approximate_pi())
errors = list(estimate-math.pi for estimate in approximate_pi())
print(pi_estimates)
print(errors)
OUTPUT:
Estimates
[3.096, 3.142, 3.1253333333333333, 3.121, 3.1384, 3.136, 3.1314285714285712, 3.133, 3.1342222222222222]
Errors
[0.04240734641020705, 0.02240734641020703, 0.03307401307687341, 0.020407346410206806, 0.02320734641020694, 0.0017406797435404187, -0.009021225018364554, -0.011592653589793223, -0.016703764700904067]
Hope you understood, I hope my explanation was easy to understand, I am a beginner and learning stuff if there is anything wrong please feel free to notify.
Thank you
Essentially what the statement you've written above says:
import math
def find_pi(iterations):
return sum(
1 for _ in range(iterations) if math.hypot(
random.random(), random.random()) <= 1) * 4.0/iterations

Improving a Monte Carlo code to find the volume of sphere in Higher dimension. (PYTHON)

Considering Gaussian shape we can find the volume of n dimensional volume of a sphere. My intention is to find the volume using Monte Carlo method.
Using the gaussian integral I have found the formula
What I understand that the ratio of the points inside the n-dimensional sphere to the total number of points will then be roughly the same as the ratio of the volume of the ball to that of the cube. I mean the mass density would never change , whatever dimension I use.
Therefore I assume I should follow the same technique what I used to find the value of pi using Monte Carlo method.
I don't understand how to follow the code which I evaluated to find the value of pi.
import random
TIMES_TO_REPEAT = 10**5
LENGTH = 10**5
def in_circle(x, y):
return x**2 + y**2 < LENGTH**2
inside_count = 0
for _ in range(TIMES_TO_REPEAT):
point = random.randint(0,LENGTH), random.randint(0,LENGTH)
if in_circle(*point):
inside_count += 1
pi = (inside_count / TIMES_TO_REPEAT) * 4
print(pi)
How can I apply the inequality condition in the code I have mentioned so the mass density would be same and I can find the value of volume in Higher dimension.?
import random
N = 10**5 # number of trials (ie, number of points to sample)
R = 10**5 # circle radius
def in_sphere(x, y, z):
return x**2 + y**2 + z**2 < R**2
c = 0
for _ in range(N):
p = random.randint(0,R), random.randint(0,R), random.randint(0,R)
if in_sphere(*p):
c += 1
pi = 6 * c / N
print(pi)
The basic idea: if a circle (radius R) is inscribed inside a square (then, its edge must be 2R), then the ratio (the area of circle over the area of square) will be π/4. So, if you pick N points at random inside the square, approximately N * π/4 of those points should fall inside the circle.
hope the annotated/revised code help you understand the MC logic
import random
N = 10**5 # number of trials (ie, number of points to sample)
R = 10**5 # circle radius
# whether p(x,y) is inside a circle
def in_circle(x, y):
return x**2 + y**2 < R**2
# use integer ops as much as possible for speed
c = 0
for i in range(N):
x, y = random.randint(0,R), random.randint(0,R)
if in_circle(x, y):
c += 1
pi = 4 * c / N
print(pi) # pi-> 3.14

Trigonometry: sin(x) getting negative value

I am trying to solve a homework: I am required to write a program which will calculate the length of a ladder based on two inputs, that is the desired height to be reached and the angle created by leaning the ladder toward the wall.
I used the following formula to convert degrees to radians :
radians = (math.pi / 180) * x # x is the given angle by the user.
I imported the math library as well to use its functions.
def main():
import math
print("this program calculates the length of a ladder after you give the height and the angle")
h = eval(input("enter the height you want to reach using the ladder"))
x = eval(input("enter the angle which will be created be leaning the ladder to the wall"))
radians = ( math.pi / 180 ) * x
length = h / math.sin(x)
print("the length is:", length)
main()
What exactly am I doing wrong?
I know the code is missing something and would appreciate it if someone could help me fill the gap.
You never used radians after you calculate it.
i.e. length = h / math.sin(radians)
To make crickt_007's right answer absolutely clear: radians which you did not use after you calculate it should be the argument of the sine:
length = h / math.sin(radians)
you calculate radians,thats ok,but problem is you never used that radians value. i think your code must be changed as follows :)
def main():
import math
print("this program calculates the length of a ladder after you give the height and the angle")
h = eval(input("enter the height you want to reach using the ladder"))
x = eval(input("enter the angle which will be created be leaning the ladder to the wall"))
radians = ( math.pi / 180 ) * x
length = h / math.sin(radians)
print("the length is:", length)
main()
if your both input will be 5,output is the length is: 57.36856622834928

Categories