Add list to Matplotlib - python

I am doing a randomly generated world and I'm starting of with basic graphing trying to be similar to Perlin Noise. I did everything and the last thing that I've written (important one) did work.
import math
import random
import matplotlib.pyplot as plt
print('ur seed')
a = input()
seed = int(a)
b = (math.cos(seed) * 100)
c = round(b)
# print(c)
for i in range(10):
z = (random.randint(-1, 2))
change = (z + c)
gener = []
gener.append(change)
time = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#print(gener)
#print(change)
plt.ylabel('generated')
plt.xlabel('time')
#Here I wanna add them to the graph and it is Erroring a lot
plt.scatter(time, gener)
plt.title('graph')
plt.show()

the problem is that you're setting gener to [] in the loop not out of the loop. also, you don't need the time variable inside the loop either.
change
for i in range(10):
z = (random.randint(-1, 2))
change = (z + c)
gener = []
gener.append(change)
time = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
to
gener = []
for i in range(10):
z = (random.randint(-1, 2))
change = (z + c)
gener.append(change)
time = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Related

realize FFT and IFFT using python3

When I multiply two big integers using FFT, I find the result of FFT and IFFT is always not right.
method
To realize FFT, I just follow the pseudocode as followed:
the pseudocode of FFT
The equations of FFT and IFFT are as followed. So, when realizing IFFT, I just replace a with y, replace omega with omega ^^ -1 and divide it by n. And, use flag to distinguish them in my function.
For FFT, y will be
For IFFT, a will be
problem
To find the problem, I try to compare the results between numpy.fft and my function.
FFT.
The results of numpy and my function look the same, but the sign of images is the opposite. For example (the second element of case2 below):
my function result: -4-9.65685424949238j
numpy result: -4+9.65685424949238j
IFFT. I just find it wrong, and can't find any rule.
python code
Here is my function FFT, and comparison:
from typing import List
from cmath import pi, exp
from numpy.fft import fft, ifft
def FFT(a: List, flag: bool) -> List:
"""realize DFT using FFT"""
n = len(a)
if n == 1:
return a
# complex root
omg_n = exp(2 * pi * 1j / n)
if flag:
# IFFT
omg_n = 1 / omg_n
omg = 1
# split a into 2 part
a0 = a[::2] # even
a1 = a[1::2] # odd
# corresponding y
y0 = FFT(a0, flag)
y1 = FFT(a1, flag)
# result y
y = [0] * n
for k in range(n // 2):
y[k] = y0[k] + omg * y1[k]
y[k + n // 2] = y0[k] - omg * y1[k]
omg = omg * omg_n
# IFFT
if flag:
y = [i / n for i in y]
return y
if __name__ == '__main__':
test_cases = [
[1, 1],
[1, 2, 3, 4, 5, 6, 7, 8],
[1, 4, 2, 9, 0, 0, 3, 8, 9, 1, 4, 0, 0, 0, 0, 0, ],
]
print("test FFT")
for i, case in enumerate(test_cases):
print(f"case{i + 1}", case)
manual_result = FFT(case, False)
numpy_result = fft(case).tolist()
print("manual_result:", manual_result)
print("numpy_result:", numpy_result)
print("difference:", [i - j for i, j in zip(manual_result, numpy_result)])
print()
print("test IFFT")
for i, case in enumerate(test_cases):
print(f"case{i + 1}", case)
manual_result = FFT(case, True)
numpy_result = ifft(case).tolist()
print("manual_result:", manual_result)
print("numpy_result:", numpy_result)
print("difference:", [i - j for i, j in zip(manual_result, numpy_result)])
print()
The FFT output:
test FFT
case1 [1, 1]
manual_result: [2, 0]
numpy_result: [(2+0j), 0j]
difference: [0j, 0j]
case2 [1, 2, 3, 4, 5, 6, 7, 8]
manual_result: [36, (-4-9.65685424949238j), (-4-4.000000000000001j), (-4-1.6568542494923815j), -4, (-4+1.6568542494923806j), (-4+4.000000000000001j), (-3.999999999999999+9.656854249492381j)]
numpy_result: [(36+0j), (-4+9.65685424949238j), (-4+4j), (-4+1.6568542494923806j), (-4+0j), (-4-1.6568542494923806j), (-4-4j), (-4-9.65685424949238j)]
difference: [0j, -19.31370849898476j, -8j, -3.313708498984762j, 0j, 3.313708498984761j, 8j, (8.881784197001252e-16+19.31370849898476j)]
case3 [1, 4, 2, 9, 0, 0, 3, 8, 9, 1, 4, 0, 0, 0, 0, 0]
manual_result: [41, (-12.710780677203363+13.231540329804117j), (12.82842712474619+7.2426406871192865j), (-14.692799048494296+7.4256307475248935j), (1.0000000000000013-12j), (5.763866860359768+6.0114171851517995j), (7.171572875253808+1.2426406871192839j), (-10.360287134662114+11.817326767431025j), -3, (-10.360287134662112-11.817326767431021j), (7.17157287525381-1.2426406871192848j), (5.763866860359771-6.011417185151798j), (0.9999999999999987+12j), (-14.692799048494292-7.425630747524895j), (12.828427124746192-7.242640687119286j), (-12.710780677203362-13.23154032980412j)]
numpy_result: [(41+0j), (-12.710780677203363-13.231540329804115j), (12.82842712474619-7.242640687119286j), (-14.692799048494292-7.4256307475248935j), (1+12j), (5.763866860359768-6.011417185151798j), (7.17157287525381-1.2426406871192857j), (-10.360287134662112-11.81732676743102j), (-3+0j), (-10.360287134662112+11.81732676743102j), (7.17157287525381+1.2426406871192857j), (5.763866860359768+6.011417185151798j), (1-12j), (-14.692799048494292+7.4256307475248935j), (12.82842712474619+7.242640687119286j), (-12.710780677203363+13.231540329804115j)]
difference: [0j, 26.46308065960823j, 14.485281374238571j, (-3.552713678800501e-15+14.851261495049787j), (1.3322676295501878e-15-24j), 12.022834370303597j, (-1.7763568394002505e-15+2.4852813742385695j), (-1.7763568394002505e-15+23.634653534862046j), 0j, -23.63465353486204j, -2.4852813742385704j, (3.552713678800501e-15-12.022834370303595j), (-1.3322676295501878e-15+24j), -14.851261495049789j, (1.7763568394002505e-15-14.485281374238571j), (1.7763568394002505e-15-26.463080659608238j)]
The IFFT result:
test IFFT
case1 [1, 1]
manual_result: [1.0, 0.0]
numpy_result: [(1+0j), 0j]
difference: [0j, 0j]
case2 [1, 2, 3, 4, 5, 6, 7, 8]
manual_result: [0.5625, (-0.0625+0.15088834764831843j), (-0.0625+0.062499999999999986j), (-0.0625+0.025888347648318405j), -0.0625, (-0.0625-0.025888347648318433j), (-0.0625-0.062499999999999986j), (-0.062499999999999986-0.1508883476483184j)]
numpy_result: [(4.5+0j), (-0.5-1.2071067811865475j), (-0.5-0.5j), (-0.5-0.20710678118654757j), (-0.5+0j), (-0.5+0.20710678118654757j), (-0.5+0.5j), (-0.5+1.2071067811865475j)]
difference: [(-3.9375+0j), (0.4375+1.357995128834866j), (0.4375+0.5625j), (0.4375+0.23299512883486598j), (0.4375+0j), (0.4375-0.232995128834866j), (0.4375-0.5625j), (0.4375-1.357995128834866j)]
case3 [1, 4, 2, 9, 0, 0, 3, 8, 9, 1, 4, 0, 0, 0, 0, 0]
manual_result: [0.0400390625, (-0.01241287175508141-0.012921426103324331j), (0.012527760864009951-0.007072891296014926j), (-0.014348436570795205-0.007251592526879778j), (0.0009765625000000013+0.01171875j), (0.005628776230820083-0.005870524594874804j), (0.007003489135990047-0.0012135162960149274j), (-0.01011746790494347-0.011540358171319353j), -0.0029296875, (-0.010117467904943469+0.011540358171319355j), (0.007003489135990049+0.0012135162960149274j), (0.005628776230820081+0.005870524594874803j), (0.0009765624999999987-0.01171875j), (-0.014348436570795205+0.0072515925268797805j), (0.012527760864009953+0.007072891296014926j), (-0.012412871755081408+0.01292142610332433j)]
numpy_result: [(2.5625+0j), (-0.7944237923252102+0.8269712706127572j), (0.8017766952966369+0.45266504294495535j), (-0.9182999405308933+0.46410192172030584j), (0.0625-0.75j), (0.3602416787724855+0.37571357407198736j), (0.44822330470336313+0.07766504294495535j), (-0.647517945916382+0.7385829229644387j), (-0.1875+0j), (-0.647517945916382-0.7385829229644387j), (0.44822330470336313-0.07766504294495535j), (0.3602416787724855-0.37571357407198736j), (0.0625+0.75j), (-0.9182999405308933-0.46410192172030584j), (0.8017766952966369-0.45266504294495535j), (-0.7944237923252102-0.8269712706127572j)]
difference: [(-2.5224609375+0j), (0.7820109205701288-0.8398926967160816j), (-0.7892489344326269-0.45973793424097026j), (0.903951503960098-0.47135351424718563j), (-0.0615234375+0.76171875j), (-0.3546129025416654-0.38158409866686216j), (-0.4412198155673731-0.07887855924097029j), (0.6374004780114385-0.7501232811357581j), (0.1845703125+0j), (0.6374004780114385+0.7501232811357581j), (-0.4412198155673731+0.07887855924097029j), (-0.3546129025416654+0.38158409866686216j), (-0.0615234375-0.76171875j), (0.903951503960098+0.47135351424718563j), (-0.7892489344326269+0.45973793424097026j), (0.7820109205701288+0.8398926967160816j)]
#pjs, Thank you for your reminder that FFT requires len(data) to be a power of 2.
As was pointed out in comments, you used a positive sign in the computation of omg_n. There are different definitions of the DFT, so it isn't wrong by itself. However this would naturally lead to differences if you compare your results with an implementation that uses a negative sign, as is the case with numpy.fft.fft. Adjusting your implementation to also use a negative sign would cover all forward transform cases (leaving only small roundoff errors on the order of ~10-16).
For the inverse transform cases, your implementation ends up scaling the result by 1/n at every stage, instead of only the final stage. To correct this, simply remove the scaling from the recursion, and normalize only on the final stage:
def FFTrecursion(a: List, flag: bool) -> List:
"""Recursion of the FFT implementation"""
n = len(a)
if n == 1:
return a
# complex root
omg_n = exp(-2 * pi * 1j / n)
if flag:
# IFFT
omg_n = 1 / omg_n
omg = 1
# split a into 2 part
a0 = a[::2] # even
a1 = a[1::2] # odd
# corresponding y
y0 = FFTrecursion(a0, flag)
y1 = FFTrecursion(a1, flag)
# result y
y = [0] * n
for k in range(n // 2):
y[k] = y0[k] + omg * y1[k]
y[k + n // 2] = y0[k] - omg * y1[k]
omg = omg * omg_n
return y
def FFT(a: List, flag: bool) -> List:
"""realize DFT using FFT"""
y = FFTrecursion(a, flag)
# IFFT final scaling
if flag:
n = len(a)
y = [i / n for i in y]
return y

How do I insert a value into a two-dimensional array in python

I have been trying to get a personal homework to work properly but I can't seem to get it right. I need to insert a random value into a 2D array using two For cycles and print the array. This is what I have but it's not finished and it's the barebones of my struggle.
import numpy as np
import random
arr = np.array([], [])
for i in range(0, 6):
for j in range(0, 6):
value = random.randint(0, 6)
arr[i][j] = value
print(arr(i, j))
print('')
I want to know how to insert the random value into the array's position, like if the for cycle is telling me I'm at the position 0,0 , then I want to insert a number into that position.
In general, you should do everything you can to avoid loops with Numpy. It defeats the purpose. For almost anything you want to do, there is a Numpy way that doesn't require a loop.
Here you can use numpy.random.randint and built the array directly without the loop. This will be much faster:
import numpy as np
# arguments are low, high, shape
arr = np.random.randint(0, 6, (6, 6))
# array([[0, 4, 0, 5, 3, 4],
# [2, 2, 0, 0, 3, 1],
# [1, 3, 5, 0, 4, 2],
# [3, 1, 1, 4, 5, 2],
# [2, 5, 4, 3, 2, 3],
# [2, 3, 0, 2, 0, 0]])
Some changes:
Define the array with np.zeros
print(arr(i, j)) To print(arr[i, j])
arr = np.zeros((6, 6))
import random
for i in range(0, 6):
for j in range(0, 6):
value = random.randint(0, 6)
arr[i][j] = value
print(arr[i, j])
If you want to print the entire array, you can do this:
arr = np.zeros((6, 6))
import random
for i in range(0, 6):
for j in range(0, 6):
value = random.randint(0, 6)
arr[i][j] = value
print(arr)
Creating an array with arr = np.array([], []) gives you an array with no rows and no columns, so you'll be using indexes that are out of bounds as soon as you try to set a value. You need to give some dimension to the array when you create it, even if you don't provided initial values. There are several ways to do that, but try this:
import numpy as np
import random
arr = np.empty(shape=(6, 6)) # np.zeroes would also work
print(arr)
for i in range(0, 6):
for j in range(0, 6):
value = random.randint(0, 6)
arr[i][j] = value
print(arr)

Finding if there are n data points in a row that are less than a certain number

I am working with a spectrum in Python and I have fit a line to that spectrum. I want a code that can detect if there have been let's say, 10, data points on the spectrum in a row that are less than the fitted line. Does anyone know how a simple and quick way to do this?
I currently have something like this:
count = 0
for i in range(lowerbound, upperbound):
if spectrum[i] < fittedline[i]
count += 1
if count > 15:
*do whatever*
If I changed the first if statement line to be:
if spectrum[i] < fittedline[i] & spectrum[i+1] < fittedline[i+1] & so on
I'm sure the algorithm would work, but is there a smarter way for me to automate this in the case where I want the user to input a number for how many data points in a row must be less than the fitted line?
Your attempt is pretty close to working! For consecutive points, all you need to do is reset the count if one point doesn't satisfy your condition.
num_points = int(input("How many points must be less than the fitted line? "))
count = 0
for i in range(lowerbound, upperbound):
if spectrum[i] < fittedline[i]:
count += 1
else: # If the current point is NOT below the threshold, reset the count
count = 0
if count >= num_points:
print(f"{count} consecutive points found at location {i-count+1}-{i}!")
Let's test this:
lowerbound = 0
upperbound = 10
num_points = 5
spectrum = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
fittedline = [1, 2, 10, 10, 10, 10, 10, 8, 9, 10]
Running the code with these values gives:
5 consecutive points found at location 2-6!
My recommendation would be to research and use existing libraries before developing ad-hoc functionality
In this case some super smart people developed numerical python library numpy. This library, widely use in science projects, has a ton of useful functionality implementations of the shelf that are tested and optimized
Your needs can be covered with the following line:
number_of_points = (np.array(spectrum) < np.array(fittedline)).sum()
But lets go step by step:
spectrum = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
fittedline = [1, 2, 10, 10, 10, 10, 10, 8, 9, 10]
# Import numerical python module
import numpy as np
# Convert your lists to numpy arrays
spectrum_array = np.array(spectrum)
gittedline_array = np.array(fittedline)
# Substract fitted line to spectrum
difference = spectrum_array - gittedline_array
#>>> array([ 0, 0, -7, -6, -5, -4, -3, 0, 0, 0])
# Identify points where condition is met
condition_check_array = difference < 0.0
# >>> array([False, False, True, True, True, True, True, False, False, False])
# Get the number of points where condition is met
number_of_points = condition_check_array.sum()
# >>> 5
# Get index of points where condition is met
index_of_points = np.where(difference < 0)
# >>> (array([2, 3, 4, 5, 6], dtype=int64),)
print(f"{number_of_points} points found at location {index_of_points[0][0]}-{index_of_points[0][-1]}!")
# Now same functionality in a simple function
def get_point_count(spectrum, fittedline):
return (np.array(spectrum) < np.array(fittedline)).sum()
get_point_count(spectrum, fittedline)
Now let's consider instead of having 10 points in your spectrum, you have 10M. Code efficience is a key thing to consider and numpy can save help there:
number_of_samples = 1000000
spectrum = [1] * number_of_samples
# >>> [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...]
fittedline = [0] * number_of_samples
fittedline[2:7] =[2] * 5
# >>> [0, 0, 2, 2, 2, 2, 2, 0, 0, 0, ...]
# With numpy
start_time = time.time()
number_of_points = (np.array(spectrum) < np.array(fittedline)).sum()
numpy_time = time.time() - start_time
print("--- %s seconds ---" % (numpy_time))
# With ad hoc loop and ifs
start_time = time.time()
count=0
for i in range(0, len(spectrum)):
if spectrum[i] < fittedline[i]:
count += 1
else: # If the current point is NOT below the threshold, reset the count
count = 0
adhoc_time = time.time() - start_time
print("--- %s seconds ---" % (adhoc_time))
print("Ad hoc is {:3.1f}% slower".format(100 * (adhoc_time / numpy_time - 1)))
number_of_samples = 1000000
spectrum = [1] * number_of_samples
# >>> [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...]
fittedline = [0] * number_of_samples
fittedline[2:7] =[2] * 5
# >>> [0, 0, 2, 2, 2, 2, 2, 0, 0, 0, ...]
# With numpy
start_time = time.time()
number_of_points = (np.array(spectrum) < np.array(fittedline)).sum()
numpy_time = time.time() - start_time
print("--- %s seconds ---" % (numpy_time))
# With ad hoc loop and ifs
start_time = time.time()
count=0
for i in range(0, len(spectrum)):
if spectrum[i] < fittedline[i]:
count += 1
else: # If the current point is NOT below the threshold, reset the count
count = 0
adhoc_time = time.time() - start_time
print("--- %s seconds ---" % (adhoc_time))
print("Ad hoc is {:3.1f}% slower".format(100 * (adhoc_time / numpy_time - 1)))
>>>--- 0.20999646186828613 seconds ---
>>>--- 0.28800177574157715 seconds ---
>>>Ad hoc is 37.1% slower

Unexpected result with polyfit in python

Permit me first to introduce the background of the question:
I came into a quiz, which gave me a data set and a Logistic equation:
Then it asked whether that model can be linearized, and if it is, use the linear model to evaluate the value of a and k.
I tried to linearize it like this:
And coded in python:
t = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
y = np.array([43.65, 109.86, 187.21, 312.67, 496.58, 707.65, 960.25, 1238.75, 1560, 1824.29, 2199, 2438.89, 2737.71])
yAss = np.log(3000/y - 1)
cof = np.polyfit(t, yAss, deg = 1)
a = math.e**(cof[0]);
k = -cof[1];
yAfter = 3000 / (1 + a*math.e**(-k*t))
sizeScalar = 10
fig = plt.figure(figsize = (sizeScalar*1.1, sizeScalar))
plt.plot(t, y, 'o', markersize = sizeScalar*0.75)
plt.plot(t, yAfter, 'r-')
plt.grid(True)
plt.show()
And got that, which is obviously incorrect:
Then by coincident, I changed some part of the code:
t = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
y = np.array([43.65, 109.86, 187.21, 312.67, 496.58, 707.65, 960.25, 1238.75, 1560, 1824.29, 2199, 2438.89, 2737.71])
yAss = np.log(3000/y - 1)
cof = np.polyfit(t, yAss, deg = 1)
a = math.e**(-cof[1]); #<<<===============here. Before: a = math.e**(cof[0])
k = cof[0]; #<<<==========================and here, Before: k = -cof[1]
temp = 3000 / (1 + a*math.e**(-k*t))
yAfter = []
for itera in temp: #<<<=======================add this
yAfter.append(3000 - itera)
sizeScalar = 10
fig = plt.figure(figsize = (sizeScalar*1.1, sizeScalar))
plt.plot(t, y, 'o', markersize = sizeScalar*0.75)
plt.plot(t, yAfter, 'r-')
plt.grid(True)
plt.show()
And received a sequence that seems to be right?
But how could it be? I think cof[0] IS beta, and cof1 IS -k, if it is, my previous code should just have some wrong concept. But change the order and sign of the coefficient, I got a result that fits well?! Is it purely coincident?
And what might be the right answer of the quiz?
np.polyfit returns the highest degree first: https://docs.scipy.org/doc/numpy/reference/generated/numpy.polyfit.html#numpy.polyfit
Use:
k = -cof[0]
a = exp(cof[1])
Also, you can use NumPy's exponential:
yAfter = 3000/(1+a*np.exp(-k*t)))

How to use LSTM for sequence labelling in python?

I want to build a classifier that provides labels given a time series of vectors. I have the code for a static LSTM-based classifier, but I don't know how I can incorporate the time information:
Training set:
time = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18]
f1 = [1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2]
f2 = [2, 1, 3, 2, 4, 2, 3, 1, 9, 2, 1, 2, 1, 6, 1, 8, 2, 2]
labels = [a, a, b, b, a, a, b, b, a, a, b, b, a, a, b, b, a, a]
Test set:
time = [1, 2, 3, 4, 5, 6]
f1 = [2, 2, 2, 1, 1, 1]
f2 = [2, 1, 2, 1, 6, 1]
labels = [?, ?, ?, ?, ?, ?]
Following this post, I implemented the following in pybrain:
from pybrain.datasets import SequentialDataSet
from itertools import cycle
import matplotlib.pyplot as plt
from pybrain.tools.shortcuts import buildNetwork
from pybrain.structure.modules import LSTMLayer
from pybrain.supervised import RPropMinusTrainer
from sys import stdout
data = [1,2,3,4,5,6,7]
ds = SequentialDataSet(1, 1)
for sample, next_sample in zip(data, cycle(data[1:])):
ds.addSample(sample, next_sample)
print ds
net = buildNetwork(2, 5, 1, hiddenclass=LSTMLayer, outputbias=False, recurrent=True)
trainer = RPropMinusTrainer(net, dataset=ds)
train_errors = [] # save errors for plotting later
EPOCHS_PER_CYCLE = 5
CYCLES = 100
EPOCHS = EPOCHS_PER_CYCLE * CYCLES
for i in xrange(CYCLES):
trainer.trainEpochs(EPOCHS_PER_CYCLE)
train_errors.append(trainer.testOnData())
epoch = (i+1) * EPOCHS_PER_CYCLE
print("\r epoch {}/{}".format(epoch, EPOCHS))
stdout.flush()
print()
print("final error =", train_errors[-1])
plt.plot(range(0, EPOCHS, EPOCHS_PER_CYCLE), train_errors)
plt.xlabel('epoch')
plt.ylabel('error')
plt.show()
for sample, target in ds.getSequenceIterator(0):
print(" sample = %4.1f" % sample)
print("predicted next sample = %4.1f" % net.activate(sample))
print(" actual next sample = %4.1f" % target)
print()
This trains a classifier, but I don't know how to incorporate the time information. How can I include the information about the order of the vectors?
This is how I implemented my sequence labeling. I have six classes of labels. I have 20 sample sequence for each class. Each sequence consist of 100 timesteps of datapoints with 10 variables.
input_variable = 10
output_class = 1
trndata = SequenceClassificationDataSet(input_variable,output_label, nb_classes=6)
# input 1st sequence into dataset for class label 0
for i in range(100):
trndata.appendLinked(sequence1_class0[i,:], [0])
trndata.newSequence()
# input 2nd sequence into dataset for class label 0
for i in range(100):
trndata.appendLinked(sequence2_class0[i,:], [0])
trndata.newSequence()
......
......
# input 20th sequence into dataset for class label 5
for i in range(100):
trndata.appendLinked(sequence20_class5[i,:], [5])
trndata.newSequence()
You could put all of them in a for loop eventually. The trndata.newSequence() is called every time a new sample sequence is given as dataset.
The training of the network should be similar to your existing code.

Categories

Resources