Signal filtering in Python - python

Trying to create a filter for a signal i made, but can't seem to get. I keep getting error about '/' whenever i call my filter function.
import numpy as np
from numpy import sqrt
import matplotlib.pyplot as plt
import scipy as sp
import math
def sinyal(N,c,f,p):
y=np.zeros(N)
t=np.linspace(0,2*np.pi,N)
Nf=len(c)
for i in range(Nf):
y+=c[i]*np.sin(f[i]*t)
return y;
def filter (w,wn):
yf=1.0/sqrt(1.0+(w/wn)**(2.0*n))
return yf;
c=[2,5,10]
f=[50, 150, 300]
p=[0,0]
N=2000
w=[50,150,300]
x=np.linspace(0,2.0*math.pi,N)
y=sinyal(N,c,f,p)
yf=filter(w,200)
plt.plot(x[:100],y[:100])
plt.show()

w is a list, wn is an int, so w/wn raises
TypeError: unsupported operand type(s) for /: 'list' and 'int'
You could fix the error by making w a NumPy array:
w = np.array([50, 150, 300])
You'll also need to define n.
filter is called but the result is never used.
Tip: note that filter is the name of a Python builtin. It's
best not to define a function or variable the same name as a builtin,
since it makes it harder to access the builtin and may be confusing
to others.
Tip: Python does not need semicolons at the end of statements.

Related

How Can I Convert a String to a Ufunc?

I am trying to write a simple function that converts an input written in LaTeX to a ufunc that can be read by numpy. So far, I'm testing the function by converting \sin(x) to np.sin(x) (ignoring the conversion from {} to (). I'm not that familiar with ufuncs so I keep running into an error when trying to convert the \sin(x) string to the np.sin(x) ufunc for any given x.
import numpy as np
latexEq = input()
def latexMap(latexEq):
if "\sin" in latexEq:
sinLatex = latexEq.replace("\sin", "np.sin")
else:
pass
return sinLatex
npOutput = np.ufunc(latexMap(latexEq))
print(f"f(x)={numpyOutput}")
Similar to how an integer may be converted into a string str(2), I tried enclosed both sinLatex, latexEq, "np.sin", and npOutput but the error I always receive is
TypeError: cannot create 'numpy.ufunc' instances
Any explanation would be appreciated.
So if you just have npOutput = "np.sin" (without the (x)) you can do
# function_name = getattr(module, function_name_string)
npOutput = getattr(np, npOutput.lstrip("np."))
which gives you the function np.sin. The parentheses have to be gone because otherwise it would be a function call, not a function.

How to type hint a generic numpy array?

Is there any way to type a Numpy array as generic?
I'm currently working with Numpy 1.23.5 and Python 3.10, and I can't type hint the following example.
import numpy as np
import numpy.typing as npt
E = TypeVar("E") # Should be bounded to a numpy type
def double_arr(arr: npt.NDArray[E]) -> npt.NDArray[E]:
return arr * 2
What I expect
arr = np.array([1, 2, 3], dtype=np.int8)
double_arr(arr) # npt.NDAarray[np.int8]
arr = np.array([1, 2.3, 3], dtype=np.float32)
double_arr(arr) # npt.NDAarray[np.float32]
But I end up with the following error
arr: npt.NDArray[E]
^^^
Could not specialize type "NDArray[ScalarType#NDArray]"
Type "E#double_arr" cannot be assigned to type "generic"
"object*" is incompatible with "generic"
If i bound the E to numpy datatypes (np.int8, np.uint8, ...) the type-checker fails to evaluate the multiplication due to the multiple data-types.
Looking at the source, it seems the generic type variable used to parameterize numpy.dtype of numpy.typing.NDArray is bounded by numpy.generic (and declared covariant). Thus any type argument to NDArray must be a subtype of numpy.generic, whereas your type variable is unbounded. This should work:
from typing import TypeVar
import numpy as np
from numpy.typing import NDArray
E = TypeVar("E", bound=np.generic, covariant=True)
def double_arr(arr: NDArray[E]) -> NDArray[E]:
return arr * 2
But there is another problem, which I believe lies in insufficient numpy stubs. An example of it is showcased in this issue. The overloaded operand (magic) methods like __mul__ somehow mangle the types. I just gave the code a cursory look right now, so I don't know what is missing. But mypy will still complain about the last line in that code:
error: Returning Any from function declared to return "ndarray[Any, dtype[E]]" [no-any-return]
error: Unsupported operand types for * ("ndarray[Any, dtype[E]]" and "int") [operator]
The workaround right now is to use the functions instead of the operands (via the dunder methods). In this case using numpy.multiply instead of * solves the issue:
from typing import TypeVar
import numpy as np
from numpy.typing import NDArray
E = TypeVar("E", bound=np.generic, covariant=True)
def double_arr(arr: NDArray[E]) -> NDArray[E]:
return np.multiply(arr, 2)
a = np.array([1, 2, 3], dtype=np.int8)
reveal_type(double_arr(a))
No more mypy complaints and the type is revealed as follows:
numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy._typing._8Bit]]]
It's worth keeping an eye on that operand issue and maybe even report the specific error of Unsupported operand types for * separately. I haven't found that in the issue tracker yet.
PS: Alternatively, you could use the * operator and add a specific type: ignore. That way you'll notice, if/once the annotation error is eventually fixed by numpy because mypy complains about unused ignore-directives in strict mode.
def double_arr(arr: NDArray[E]) -> NDArray[E]:
return arr * 2 # type: ignore[operator,no-any-return]

mypy error in returning a numpy array slice

Considering the following code:
import numpy as np
import numpy.typing as npt
class Point:
def __init__(self, coordinates: npt.NDArray[np.float64]) -> None:
self.coordinates = coordinates
def get_x(self) -> np.float64:
return self.coordinates[0]
where coordinates is always a 1D numpy array defined with dtype=np.float64.
mypy gives the following error on the return of the get_x method:
Returning Any from function declared to return "floating[_64Bit]"mypy(error)
The question is: which is the proper way to please mypy?
I found two ways:
# type: ignore
or
from typing import cast
...
return cast(np.float64, self.coordinates[0])
However, using cast slows down the performance of get_x by a factor of 1.5-2.0 and this is not something I really love.
Are there other ways?

Import Variable Substitution Matrices based on string input Python

I am trying to import a substitution matrix to implement the Needleman-Wunsch algorithm in Python based on a given input.
If I want to select one Matrix I can do it like this:
from Bio.SubsMat import MatrixInfo as matlist
scoring_mat = matlist.blosum62
What would I have to do If I wanted to import any matrix based on an input? I have this for the moment:
def blosum(name):
index = str(name)
x= "blosum"+index
return x
a= blosum(62)
scoring_mat = matlist.a
Unfortunately, it is giving me the following error:
AttributeError: module 'Bio.SubsMat.MatrixInfo' has no attribute 'a'
What would I have to do to make it work?
Thanks in advance!
Try scoring_mat = getattr(matlist,a) instead. It worked for me.

Numexpr Error: "a = global_dict[name]"

I'm trying to use Numexpr to make a fast Vector Norm function to compare with Numpy's. I try the following:
import numexpr as ne
import numpy as np
def L2_Norm(vector_in):
vector1 = ne.evaluate("abs(vector_in)")
vector2 = ne.evaluate("vector1**2")
vector3 = ne.evaluate("sum(vector2)")
vector_out = ne.evaluate("sqrt(vector3)")
return vector_out`
ve = np.arange(10)
L2_Norm(ve)
and I get this:
File "C:\Folder1\Folder2\src\test.py", line 11, in L2_Norm
vector3 = ne.evaluate("sum(vector2)")<br>
File "C:\Python27\lib\site-packages\numexpr\necompiler.py", line 701, in evaluate
a = global_dict[name]<br>
KeyError: 'a'
I basically followed the same steps on their User Guide (which seems to be the only reference around). The only clue i have is this:
umexpr's principal routine is this:
evaluate(ex, local_dict=None, global_dict=None, **kwargs)
where ex is a string forming an expression, like "2*a+3*b". The values
for a and b will by default be taken from the calling function's frame
(through the use of sys._getframe()). Alternatively, they can be
specified using the local_dict or global_dict arguments, or passed as
keyword arguments
... which I don't really understand - I assume the author kept it simple because the package is simple. What have I overlooked?
Turns out the "local_dict=None, global_dict=None" parameters aren't default afterall. You need to specifically add them into your numexpr.evaluate function.

Categories

Resources