Implementation of NLMS for a one dimensional array with padasip - python

I am trying to implement an NLMS filter per the Padasipexample:
https://matousc89.github.io/padasip/sources/filters/nlms.html
I need to filter a one dimensional array. I adjusted the code but I'm getting an error
File "C:\Python310\lib\site-packages\padasip\filters\base_filter.py", line 194, in run
self.n = len(x[0])
TypeError: object of type 'numpy.float64' has no len()
I understand that a int doesn't have a length, however I'm not clear how do implement NLMS with a single array.
Full Code:
import numpy as np
import matplotlib.pylab as plt
import padasip as pa
# creation of data
N = 10000
x = np.random.normal(0, 1, N) # input matrix
v = np.random.normal(0, 0.1, N) # noise
d = x + v
# identification
TAP=5000
f = pa.filters.FilterNLMS(n=TAP, mu=0.1, w="random")
y, e, w = f.run(d, x)
# show results
plt.figure(figsize=(15,9))
plt.subplot(211);plt.title("Adaptation");plt.xlabel("samples - k")
plt.plot(d,"b", label="d - target")
plt.plot(y,"g", label="y - output");plt.legend()
plt.subplot(212);plt.title("Filter error");plt.xlabel("samples - k")
plt.plot(10*np.log10(e**2),"r", label="e - error [dB]");plt.legend()
plt.tight_layout()
plt.show()

Related

graphing non-linear decision boundary

data can be found here: ex2data2.txt
I'm not sure what call to plt.contour() I should be using to reproduce this.
the related Matlab function call would be:
contour(u, v, z, [0, 0], 'LineWidth', 2)
I'm trying to plot the decision boundary for a non-linear logistic regression like the following image
import scikitplot.plotters as skplt
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification
from sklearn import metrics
from ggplot import *
import time
def mapFeature(X1, X2, df=True):
"""
X1, X2: dtype = pd.DataFrame, float, int
either a single value or a vector of values
df : dtype = boolean
whether it's a single scalar value or a vector of values
----------
Return: dtype = m row vector or m x n vector of feature values
Calculates each feature and returns its value
"""
# add a column of ones for intercept parameter
out = pd.DataFrame({'1':np.ones(X1.size)})
# max 6th degree polynomial
for i in range(1,7):
for j in range(i+1):
# all the combinations of polynomials up to 7th degree
value = (X1**(i-j))*(X2**j)
col_name = 'X1**{} * X2**{}'.format(i-j, j)
# When we give a vector with only one dimension, we need to specify
# whether to add it as a column or a row. 0 denotes adding a row,
# and 1 would be a column.
if df:
out = out.join(pd.DataFrame({col_name: value}))
else:
out = out.join(pd.DataFrame({col_name: value}, index=[0]))
return out
if __name__ == '__main__':
data = pd.read_csv('ex2data2.txt', header=None,
names=['Test1', 'Test2', 'Pass'])
X = data.iloc[:, :2]
y = data.iloc[:,2]
X = mapFeature(X.iloc[:,0], X.iloc[:,1])
clf = LogisticRegression().fit(X, y)
theta = clf.coef_
u = np.linspace(start, end, 30)
v = np.linspace(start, end, 30)
uu, vv = np.meshgrid(u, v)
z = np.zeros((30, 30))
for i in range(30):
for j in range(30):
z[i,j] = mapFeature(u[i], v[i], df=False).values.dot(theta.T)
plt.contour(uu, vv, z, [0])
plt.show()

How can I map a vectorized function to a numpy array without using a for loop?

So here's what I already have:
import numpy as np
import matplotlib.pyplot as plt
def monteCarloPi(n):
np.random.seed() #seed the random number generator
y = np.random.rand(n)*2 - 1 #n random samples on (-1,1)
x = np.linspace(-1,1,n) #x axis to plot against
square = np.array([x,y]) #collecting axes as a single object
mask1 = ((x**2 + y**2) < 1) #filters
hits = np.sum(mask1) #calculating approximation
ratio = hits/n
pi_approx = ratio * 4
return pi_approx
Here is what I would like to do:
x = np.arange(100,1000)
y = monteCarloPi(x)
plt.scatter(x,y)
However, when I run the above code block, I get the following error:
---------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-52-bf4dcedaa309> in <module>()
1 x = np.arange(100,1000)
----> 2 y = monteCarloPi(x)
3 plt.scatter(x,y)
<ipython-input-51-8d5b36e22d4b> in monteCarloPi(n)
1 def monteCarloPi(n):
2 np.random.seed() #seed the random number generator
----> 3 y = np.random.rand(n)*2 - 1 #n random samples on (-1,1)
4 x = np.linspace(-1,1,n) #x axis to plot against
5
mtrand.pyx in mtrand.RandomState.rand()
mtrand.pyx in mtrand.RandomState.random_sample()
mtrand.pyx in mtrand.cont0_array()
TypeError: only integer scalar arrays can be converted to a scalar index
Based on my understanding of how broadcasting works in numpy, this should work. I could just use a for loop but that gets really slow really quickly as the number of samples goes up.
halp
Here is one option, where the maximum sample size is based, then subsampling occurs if start>0 (error handling not included).
import numpy as np
import matplotlib.pyplot as plt
def monteCarloPi(n,start=0,stride=1):
np.random.seed() # seed the random number generator
y = np.random.rand(n)*2 - 1 # n random samples on (-1,1)
x = np.linspace(-1,1,n) # x axis to plot against
mask = ( x**2 + y**2 ) < 1 # masking
samples = {}
inds = arange(n)
for k in range(n-start,n+1,stride):
sub_inds = np.random.choice(inds,k,replace=False)
sub_mask = mask[sub_inds]
sub_hits = np.sum(sub_mask)
ratio = sub_hits/n
pi_approx = ratio * 4
samples[k]=pi_approx
return pi_approx
This still requires a for loop, but it's handled inside the method quickly, since you're subsampling from one large random sample. To recreate your original call (running from n=100 to n=1000 [note that I am going up to n=1000 here]):
estimates = monteCarloPi(1000,start=900)
plt.plot(estimates.keys(),estimates.values())
You could of course pass the original x=arange(100,1001), but then there would need to be error checking in the method (to make sure an array or list was passed), and then n would be equal to the last element of x (n=x[-1]), and finally, the looping would be done over the elements of x (for k in x:).

Creating a bifurcation diagram in python

I am trying to come up with a code that will allow me to plot a diagram for period doubling bifurcation.
I am using the equation x = rx − 1(1 − x), and am trying to model it with r values from 0.5 to 4. Here is code that I am working with
startr = 0.5
finalr = 4
max_time = 200
x = [0.1]
r= np.linspace(.5,4,200)
for n in range(0,200):
x = np.append(r * x[n] * (1-x[n]))
plt.plot(x, label='x');
plt.xlabel('t');
This keeps getting kicked out
TypeError: append() missing 1 required positional argument: 'values'
The are the two absolutely necessary arguments for numpy.append(), taken from the Numpy reference.
arr : array_like Values are appended to a copy of this array.
values :
array_like These values are appended to a copy of arr. It must be of
the correct shape (the same shape as arr, excluding axis). If axis is
not specified, values can be any shape and will be flattened before
use.
Therefore, try using
np.append(x, r * x[n] * (1-x[n]))
inside your loop.
Logistic Map
Save file and run, png image file of graph will save in the same folder
import numpy as np
import matplotlib.pyplot as plt
Many =50000
x = np.random.rand(Many)
r = np.linspace(0,4.0, num= Many)
for i in range(1, 54):
x_a = 1-x
Data= np.multiply(x,r)
Data= np.multiply(Data, x_a)
x = Data
plt.title(r'Logistic map: $x_{n+1} = r x_{n} (1-x_{n}).$ n = '+ str(i) )
plt.ylabel('x-Random number')
plt.xlabel('r-Rate')
plt.scatter(r, Data, s=0.1, c='k')
plt.show()
plt.savefig(str(i) + " Logistic Map.png", dpi = 300)
plt.clf()

TypeError: 'numpy.float64' object is not iterable

I'm currently trying to fit some parameters to an existing data file. After adding a fitting routine I keep getting the 'TypeError: '*numpy.float64' object is not iterable*' error, which seems to have something to do with the Dl function that i defined. I haven't been able to solve this myself, so I'd be really grateful for any tips concerning this matter.
import pylab as p
import scipy as s
from scipy.integrate import odeint,quad
import numpy as np
import matplotlib.pyplot as plt
import math
z = np.arange(0.00, 1.5, 0.02)
z1, m1, sigma_m = np.loadtxt('data.txt', unpack=True, usecols=[0,1,2])
yerr = sigma_m
def H(z,omega_m,H0):
return H0*p.sqrt(omega_m*(1+z)**3+1-omega_m)
def Dl(z,omega_m,H0):
c = 3*10**5
y = []
for i in z:
y1 = c*(1+i)*quad(f,0.0,i, args=(omega_m,H0))[0]
y.append(y1)
return p.asarray(y)
def f(z,omega_m,H0):
return 1./H(z,omega_m,H0)
def m(z,omega_m,H0,M):
q = []
for j in Dl(z,omega_m,H0):
q1 = M+5*np.log10(j)+25.0
q.append(q1)
return p.asarray(q)
def chi2(omega_m, M):
return sum((m(z1,omega_m,70,M)-m1)/sigma_m)**2
chi2_min=1*10**30
o = np.arange(0.00, 1.5, 0.02)
Mrange = np.arange(-1.5, 1.5, 0.02)
for omega_m in o:
for M in Mrange:
if chi2(omega_m, M) < chi2_min:
omega_min=omega_m
M_min=M
chi2_min=m(omega_min, M_min, 70, M)
print(M_min)
print(chi2_min)
In your routine Dl, the iteration over z is invalid. z is a scalar at each invokation.
Transform your program so that either Dl is given an array or remove the loop in Dl.
Your problem seems to be here:
chi2_min=m(omega_min, M_min, 70, M)
omega_min is a float, which gets passed to Dl() in m() here:
for j in Dl(z,omega_m,H0):
and then Dl() tries to iterate it:
for i in z:
which raises your error
To fix, I recommend you pass omega_min as a list:
chi2_min=m([omega_min], M_min, 70, M)

Vectorize compressed sparse matrix from array in Python

I am trying to apply graph theory methods to an image processing problem. I want to generate an adjacency matrix from an array containing the points I want to graph. I want to generate a complete graph of the points in the array. If I have N points in the array that I need to graph, I will need an NxN matrix. The weights should be the distances between the points, so this is the code that I have:
''' vertexarray is an array where the points that are to be
included in the complete graph are True and all others False.'''
import numpy as np
def array_to_complete_graph(vertexarray):
vertcoords = np.transpose(np.where(vertexarray == True))
cg_array = np.eye(len(vertcoords))
for idx, vals in enumerate(vertcoords):
x_val_1, y_val_1 = vals
for jdx, wals in enumerate(vertcoords):
x_diff = wals[0] - vals[0]
y_diff = wals[1] - vals[1]
cg_array[idx,jdx] = np.sqrt(x_diff**2 + y_diff**2)
return cg_array
This works, of course, but my question is: can this same array be generated without the nested for loops?
Use the function scipy.spatial.distance.cdist():
import numpy as np
def array_to_complete_graph(vertexarray):
vertcoords = np.transpose(np.where(vertexarray == True))
cg_array = np.eye(len(vertcoords))
for idx, vals in enumerate(vertcoords):
x_val_1, y_val_1 = vals
for jdx, wals in enumerate(vertcoords):
x_diff = wals[0] - vals[0]
y_diff = wals[1] - vals[1]
cg_array[idx,jdx] = np.sqrt(x_diff**2 + y_diff**2)
return cg_array
arr = np.random.rand(10, 20) > 0.75
from scipy.spatial.distance import cdist
y, x = np.where(arr)
p = np.c_[x, y]
dist = cdist(p, p)
np.allclose(array_to_complete_graph(arr), dist)

Categories

Resources