Creating an array for values of a square wave function - python

I have a function shown below
f(t) = 1 : if 2t rounded down to the next lowest integer is even
f(t) = -1 : if 2t rounded down to the next lowest integer is odd
I am trying to eventually carry out fourier transformations on the function but first I need to write a program to create an array of N=1000 elements containing 1000 equally spaced samples from a single cycle of this function which is a square wave.
How do I create this array ?

As you ask for the values of the square function within a cycle, first you have to create the values for the time samples. Starting at t=0 the function you mentioned has a cycle of 1, after t=1 the function repeates itself.
For creating a sequence of equally spaced values between 0 and 1 there are several alternatives, but a straitght one is numpy.linspace. The first parameter is the starting time of the cycle, the second the end of the cycle and the third the number of samples (equally spaced). By using this you create the t_samples.
After that you just need to feed the square wave function (square_func in the code below) with the values stored in t_samples.
See an example here of how you can use it:
import numpy
def square_func(t):
if int(2*t)%2 == 0:
return 1
else:
return -1
t_samples = numpy.linspace(0.0,1.0,1000)
samples = [square_func(i) for i in t_samples]
The variable samples stores a list with the values you need (half of them are '1s' and the other half '-1s', as we are referring to one cycle). The cycle of the function produced with this code is shown in the following figure:

The function can be defined this way.
def f(t):
return 1 if int(2 * t) % 2 == 0 else -1
And if you are using python 2.x you can use map to create the list.
N = 1000
sample = map(f, xrange(N)) # Or alternatively map(lambda n: f(n), xrange(N))

Let's assume you have a method returning the sample value:
import math
def f(t):
"""
f(t) = 1 if ⌊2t⌋ is even, −1 if ⌊2t⌋ is odd
"""
if math.floor(2 * t) % 2 == 0:
return 1
else:
return -1
The easiest way to generate your array would be to do:
a = [f(n) for n in xrange(1000)]
Note: This assumes Python 2.x, use range if Python 3.x

I ended up answering it in this way
F=zeros(1000)
F[0:500]=1
F[500:1000]=-1

Related

Creating and plotting an array as a function of values in another array in Python

I'm quite a programming noob and I've only been using Python more intensively for a few weeks, however, I currently need it for an application in statistics, I am trying to do the following:
Create an array of integers N from 1 up to Q=A q (so N=[1,2,...,Q-1,Q]), and use this to create and plot an array with values for the function P(N) which sums over binomial coefficients. A and q are integer constants (N>q is in there as a true/false statement on purpose). I currently have the following code:
#Constants {A,Q,S,sigma} are set
q=Q/A
n = np.linspace(1,Q,Q,dtype=int) #variable array
Sum = np.zeros((1,Q))
Iteration = np.zeros((1,Q))
alpha = 0
while alpha < A:
alpha=alpha+1
Iteration = sigma^alpha * (comb(n-1,alpha-1) -(n>q)*alpha*comb( max(0,n-q-1), alpha-1) )
Sum = Sum + Iteration
This returns a typeError "only integer scalar arrays can be converted to a scalar index" in the line "Iteration=..." (and probably in the next line as well), and I can't find out what exactly the problem is and how to fix this.
Also; I might be doing the summation in a convoluted way; if there is a better way to sum over this in python, help to that end are also welcome.
Thanks in advance for any help!
The problem comes from the following line:
Iteration = sigma^alpha * (comb(n-1,alpha-1) -(n>q)*alpha*comb( max(0,n-q-1), alpha-1) )
As the parameters for comb has to be two non negative integers, see here, when you pass in n, which is an ndarray, to comb it will return the TypeError you mentioned.
Potentially you could wrap around the while loop and make it a function? Then you can iterate it and append the result to a list.
def this_fun(n):
Sum = 0
Q = 1000
A = 100
sigma = 1
q = int(Q / A)
alpha = 0
while alpha < A:
alpha = alpha+1
Iteration = sigma^alpha * (comb(n-1,alpha-1) -(n>q)*alpha*comb( max(0,n-q-1), alpha-1) )
Sum += Iteration
return Sum
P_N=[]
N = 100
for i in range(1,N):
P_N.append(this_fun(i))
You have to double check the logic on the Iteration line to make sure you are implementing what the maths notication is intended to and put in some sensible value for Q, A and N.
The function looks as if I plot P_N against N, is it what you are expecting?

Finding the error in my Python function to plot a histogram and return a list?

*The instruction is as following:
plotRandomUniformSum(M, N, nBins)
Let’s consider what happens when we add M uniform random numbers together. Since each random number can be between 0 and 1, we expect this sum will be between 0 and M, but somehow we expect that it is more likely for the sum to be near the middle (M/2) than near the ends (0 and M) for M > 1. First write a function randomUniformSum(M) that adds up M uniform random numbers between 0 and 1. Second, write a function that forms a list of N such numbers by calling randomUniformSum a total of N times. Third, plot the result in a histogram and return the list.
Remember that return means to exit the function. Therefore, you should first plot the histogram and then return the list.
What values should you use for binMin and binMax?
To answer this, consider the minimum and maximum values that randomUniformSum may assume. Try calling your function four times with M = 1, 2, 3, 10 setting N = 1000000 and nBins = 100 in each case. You will notice that as M increases, the distribution looks more and more like a Normal (or Gaussian) distribution. This is an illustration of the Central Limit Theorem, a very important theorem from Statistics which states that as you add more and more independent random variables (from any distribution, doesn’t have to be uniform) the sum approaches a Normal distribution - very cool :-).*
This is what I have so far:
def randomUniformSum(M):
sum = 0
for i in range(M):
sum += random.uniform(0,1)
return sum
def plotRandomUniformSum(M, N, nBins):
L = []
for i in range(N+1):
x = randomUniformSum(M)
L.append(x)
hist.plotHistogram(L, nBins = nBins)
My autograder for this assignment returns an error that:
"Test Failed: None != [0.793340083761663, 0.8219540423197268, 0[202687
chars]9087]"
with different numbers for all tests.
Where is my error? I can't seem to find where I went wrong.
You're not returning the list from the plotRandomUniformSum(M, N, nBins) function
def randomUniformSum(M):
sum = 0
for i in range(M):
sum += random.uniform(0,1)
return sum
def plotRandomUniformSum(M, N, nBins):
L = []
for i in range(N+1):
x = randomUniformSum(M)
L.append(x)
hist.plotHistogram(L, nBins = nBins)
return L # you missed this out
list_of_random_sums = plotRandomUniformSum(10, 1000000, 100)
Second, write a function that forms a list of N such numbers by calling randomUniformSum a total of N times.
Hello, welcome to SO. For me it seems unclear that you've formed a list consisting of N+1 elements instead of N. Try to change for i in range(N+1): line with for i in range(N):.

Split up a number as the sum of two powers

x is my input.
I need to find i,j>=0 and n,m>1 such as x = i**m+j**n
For now I have been doing this , but it is way to slow !! How can I improve it ?
from math import sqrt
import numpy as np
def check(x):
for i in range(1,int(np.ceil(sqrt(x)))):
for j in range(1,int(np.ceil(sqrt(x)))):
for m in range(2,x/2+1):
for n in range(2,x/2+1):
if((pow(i,m) +pow(j,n))==x):
print 'Yes';
return ;
print 'No';
thank you !
You could reverse the process, by finding all powers (i**m) smaller than x. Then you just check if any pair of these powers adds up to x.
def check(x):
all_powers = set([1]) #add 1 as a special case
#find all powers smaller than x
for base in range(2,int(math.ceil(sqrt(x)))):
exponent = 2;
while pow(base, exponent) < x:
all_powers.add(pow(base, exponent))
exponent+=1
#check if a pair of elements in all_powers adds up to x
for power in all_powers:
if (x - power) in all_powers:
print 'Yes'
return
print 'No'
The code above is simple but can be optimized, e.g., by integrating the check if a pair adds up to x in the while loop you can stop early in most cases.
From time to time a question pops up here about determining if a positive integer is the integral power of another positive integer. I.e. given positive integer z find positive integers j and n such that z == j**n. This can be done in time complexity O(log(z)) so it is fairly fast.
So find or develop such a routine: call it is_a_power(z) which returns a tuple (j, n) if z is such a power of (0, 0) if it is not. Then loop over i and m, then check if x - i**m is a power. When it becomes one, you are done.
I'll let you finish the code from here, except for one more pointer. Given x and i where i > 1, you can find the upper limit on m such that i**m <= x with
m <= log(x) / log(i)
Note that i == 1 is a special case, since i**m does not actually depend on m in that case.
from math import sqrt
import numpy as np
def build(x):
# this function creates number that are in form of
# a^b such that a^b <= x and b>1
sq=sqrt(x);
dict[1]:1; # 1 is always obtainable
dict[0]:1; # also 0 is always obtainable
for i in range(1,sq): # try the base
number=i*i; # firstly our number is i^2
while number<=x:
dict[number]:1; # this number is in form of a^b
number*=i; # increase power of the number
def check(x):
sq=sqrt(x);
for i in range(1,sq): # we will try base of the first number
firstnumber=1;
while firstnumber<=x: # we are trying powers of i
remaining=x-firstnumber; # this number is remaining number when we substract firstnumber from x
if dict[remaining]==1: # if remaining number is in dictionary which means it is representable as a^b
print("YES"); # then print YES
return ;
firstnumber*=i; # increase the power of the base
print("NO");
return ;
Above code works in O( sqrt(x) * log(x) * log(x) ) which is faster.
You can read comments in code to understand it.

Using python how do I repeatedly divide a number by 2 until it is less than 1.0?

I am unsure of how to create the loop to keep dividing the number by two? Please help. I know you you can divide a number by 2 don't know how to create the loop to keep dividing until it is less than 1.0.
It depends on what exactly you're after as it isn't clear from the question. A function that just divides a number by zero until it is less than 1.0 would look like this:
def dividingBy2(x):
while x > 1.0:
x = x/2
But this serves no purpose other than understanding while loops, as it gives you no information. If you wanted to see how many times you can divide by 2 before a number is less than 1.0, then you could always add a counter:
def dividingBy2Counter(x):
count = 0
while x > 1.0:
x = x/2
count = count + 1
return count
Or if you wanted to see each number as x becomes increasingly small:
def dividingBy2Printer(x):
while x > 1.0:
x = x/2
print(x)
b=[] #initiate a list to store the result of each division
#creating a recursive function replaces the while loop
#this enables the non-technical user to call the function easily
def recursive_func(a=0): #recursive since it will call itself later
if a>=1: #specify the condition that will make the function run again
a = a/2 #perform the desired calculation(s)
recursive_func(a) #function calls itself
b.append(a) #records the result of each division in a list
#this is how the user calls the function as an example
recursive_func(1024)
print (b)

Project Euler 2 python3

I've got, what I think is a valid solution to problem 2 of Project Euler (finding all even numbers in the Fibonacci sequence up to 4,000,000). This works for lower numbers, but crashes when I run it with 4,000,000. I understand that this is computationally difficult, but shouldn't it just take a long time to compute rather than crash? Or is there an issue in my code?
import functools
def fib(limit):
sequence = []
for i in range(limit):
if(i < 3):
sequence.append(i)
else:
sequence.append(sequence[i-1] + sequence[i-2])
return sequence
def add_even(x, y):
if(y % 2 == 0):
return x + y
return x + 0
print(functools.reduce(add_even,fib(4000000)))
The problem is about getting the Fibonacci numbers that are smaller than 4000000. Your code tries to find the first 4000000 Fibonacci values instead. Since Fibonacci numbers grow exponentially, this will reach numbers too large to fit in memory.
You need to change your function to stop when the last calculated value is more than 4000000.
Another possible improvement is to add the numbers as you are calculating them instead of storing them in a list, but this won't be necessary if you stop at the appropriate time.

Categories