Python - lambda in list comprehension gives wrong result - python-2.7

I got a numpy.ndarray of electromagnetic samples as complex numbers, where the format is as follows:
ex1:
[[ 8.23133235e-15, -1.59200901e-15, -4.39818917e-13, 7.68089585e-13]
[ 6.98151957e-15, -1.20306059e-15, 9.83923013e-13, 1.64838108e-11]
[ 8.41053742e-15, -1.77702007e-15, -5.98961364e-13, 8.97436205e-13]
[ 7.08443026e-15, -1.25262430e-15, 1.11415868e-12, 1.69346186e-11]]
where rows make up real and imaginary part alternately:
[[z1Ex.real, z1Ey.real, z1Hx.real, z1Hy.real],
[z1Ex.imag, z1Ey.imag, z1Hx.imag, z1Hy.imag],
[z2Ex.real, z2Ey.real, z2Hx.real, z2Hy.real],
[z2Ex.imag, z2Ey.imag, z2Hx.imag, z2Hy.imag],
...etc.]
What I want is to create a new array which expresses the data in magnitude and phase, but keep the same format (i.e. replace real rows with magnitude rows and imaginary with phase rows).
I managed to put up list comprehensions for both calculations (which I´m fairly proud of, being an 2-week amateur, so please be gentle;)). The result for magnitude is what I´d expect, but the phase is terribly off and I don´t have any idea why...
My approach:
Slice the original array in real and imag sub-arrays:
import numpy, cmath
real = ex1[::2] #numpy.ndarray
imag = ex1[1::2] #numpy.ndarray
Define lambdas outside of list comprehension:
magcalc = lambda z, y: abs(complex(z, y))
phasecalc = lambda z,y: cmath.phase(complex(z, y))
Define list comprehension to do math on sub-arrays:
real[:] = np.array([[magcalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(real))])
imag[:] = np.array([[phasecalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(imag))])
Check results in original array:
print ex1[:4]
If I do that, the phase result for the first Ex sample is 0.574 rad. If I check the phase manually (i.e. cmath.phase(complex(z1Ex.real,z1Ex.imag))), then I get 0.703 rad. I would accept if there was smth wrong in my list comprehensions, but the magnitude results are completely correct, so I doubt that that´s it.
Where am I doing it wrong? I really tried to find out for 2 days straight now, no luck... Also, I can´t think of another way to achieve what I want.
Please help... (Using Python 2.7)
Thanks
Nils

Oh jeez.. Now I saw the problem, can´t believe how dense I am... Credit goes to John, for making me re-think variable assignments.
In imag[:] = np.array([[phasecalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(imag))]), I refer to real[], as if it was still populated with real values. But I changed real[] the line before to contain magnitude... So, just changing the variable names for the list comprehensions will do it:
Define list comprehension to do math on sub-arrays:
realcopy[:] = np.array([[magcalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(real))])
imagcopy[:] = np.array([[phasecalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(imag))])
And then re-assign to original mag, phase arrays:
Check original results
real[:] = realcopy
imag[:] = imagcopy
print ex1[:4]
Sorry for the waste of time and bytes...
Cheers
Nils

Related

Fortran element wise multiplication of a matrix and a vector

Is there a simple and quick way to multiply a column of a matrix with element of a vector. We can do this explicitly,
program test
integer :: x(3,3), y(3), z(3,3)
x = reshape([(i,i=1,9)],[3,3])
y = [1,2,3]
do i=1,3
z(:,i) = x(:,i) * y(i)
print *, z(:,i)
enddo
end program test
Is there a way to perform the do loop in one line. For example in Numpy python we can do this to do the job in one shot
z = np.einsum('ij,i->ij',x,y)
#or
z = x*y[:,None]
Try
z = x * spread(y,1,3)
and if that doesn't work (no Fortran on this computer so I haven't checked) fiddle around with spread until it does. In practice you'll probably want to replace the 3 by size(x,1) or suchlike.
I expect that this will cause the compiler to create temporary arrays. And I expect it will be easy to find situations where it underperforms the explicit looping scheme in the question. 'neat' one-liners often have a cost in both time and space. And often tried-and-trusted Fortran approach of explicit looping is the one to go with.
Why replace clear easy to read code with garbage?
program test
implicit none
integer i,j
integer :: x(3,3), y(3), z(3,3)
x = reshape([(i,i=1,9)],[3,3])
y = [1,2,3]
z = reshape ([((x(j,i)*y(i) ,j=1,3),i=1,3)], [3,3])
print *, z(1,:)
print *, z(2,:)
print *, z(3,:)
end program test

If statment with an array of numbers

I have an array of numbers
x = np.arange(-5., 5., .001)
and an equation that is
y=somefunction(x*r)
When absolute value of x is less than .1, I want to let r=5, otherwise r=0. Then, I should get len(x) many values of y.
This is what I've tried:
if abs(x) < .1 :
r=5
else:
r=0
Try this it will work. Instead of using if-else use vectorization method. This method is faster than if-else. My suggestion is that always try to use vectorization methods for the speedy process instead of using if-else,for-loops,etc.
x = np.arange(-5., 5., .001)
print(x)
output: array([-5. , -4.999, -4.998, ..., 4.997, 4.998, 4.999])
x[abs(x)< .1]=5
x[abs(x)> .1]=0
Again you can print values of x variable and you will see the change.
Hopefully, this will help you. Good Luck!

Why is my delete_all method returning a list with a random memory location in prolog?

So, I'm trying to delete all elements where Y is a. It seems to work but the problem I'm getting is that it is returning the wrong thing. This the result of my return.
Result = [b, c, d|_G1355]
This is my code so far.
mydelete_all([],Y,Result).
mydelete_all([X|T], Y, [X|Result]):-
X \= Y,
mydelete_all(T, Y, Result).
mydelete_all([ThowAway|Tail], Y, Result):-
mydelete_all(Tail, Y, Result).
First, when you loaded your program, you got a warning or two about the variables Y, Result and ThowAway. Such warnings should be removed, before you run your program.
Your concrete query was
?- mydelete_all([a,b,c,d],a,Result).
The toplevel SWI-Prolog showed you this with a randomly named variable. Actually, in your version of SWI-Prolog that is as you have guessed more or less the memory location. Newer versions of SWI show a non-reproducible number instead — and without a G.
Other systems give more readable names, as e.g. SICStus or GNU.
So what does this answer
Result = [b,c,d|_A]
actually mean? It comprises all lists that start with b,c,d. So [b,c,d], but also [b,c,d,a] are solutions. Didn't you want to delete all occurrences of a, and now one of the solutions for Result contains a again?
But the situation is worse. Type ; to get further solutions:
?- mydelete_all([a,b,c,d],a,Result).
Result = [b,c,d|_A]
; Result = [b,c|_A]
; Result = [b,d|_A]
; Result = [b|_A]
; Result = [c,d|_A]
; Result = [c|_A]
; Result = [d|_A]
; false.
Even worse:
?- mydelete_all([a],a,[a]).
true.
?- mydelete_all([],a,[a]).
true.
This last query can only use your fact. So this fact is way too general. Another error is X \= Y replace it by dif(X, Y). And then the last rule!

calculating w coefficients for iir filter

I am trying to implement an IIR filter I have designed in Matlab into a c++ program to filter out an unwanted signal from a wave file. The fdatool in Matlab generated this C header to use (it is a bandstop filter):
#include "tmwtypes.h"
/*
* Expected path to tmwtypes.h
* C:\Program Files (x86)\MATLAB\R2013a Student\extern\include\tmwtypes.h
*/
const int al = 7;
const real64_T a[7] = {
0.9915141178644, -5.910578456199, 14.71918523779, -19.60023964796,
14.71918523779, -5.910578456199, 0.9915141178644
};
const int bl = 7;
const real64_T b[7] = {
1, -5.944230431733, 14.76096188047, -19.60009655976,
14.67733658492, -5.877069568864, 0.9831002459245
};
After hours of exhausting research, I still can't figure out the proper way to use these values to determine the W values and then how to use those W values to properly calculate my Y outputs. If anyone has any insight into the ordering these values should be used to do all these conversions, it would be a major help.
All the methods I've developed and tried to this point do not generate a valid wave file, the header values all translate correctly, but everything beyond cannot be evaluated by a media player.
Thanks.
IIR filters work this way:
Assuming an array of samples A and and array of ceof named 'c' the result array B will be:
B[i] = (A[i] * c[0]) + (B[i-1] * c[1]) + ... + (B[n] * c[n])
Note that only the newest element is taken from A.
This is easier to do in-place, just update A as you move along.
These filter coefs are very violent, are you sure you got them right?
The first one is also symmetrical which probably indicates it's an FIR filter.
It appears to me that you have a 3 pole IIR filter with the coefficients given for an Nth order implementation (as opposed to a series of 2nd order sections). Since this is a band reject (or band pass) the polynomial order is twice the pole count.
I am not sure what you mean by W values, unless you are trying to evaluate the frequency response of this filter.
To calculate the Y values, as you put it, see this link for code on implementing IIR filters. See the Nth order implementation code in particular.
http://www.iowahills.com/A7ExampleCodePage.html
BTW: I assumed these were Nth order coefficients and simulated them. I got a 10 dB notch at 0.05 Pi. Sound about right?
where
B6 = 0.9915141178644
.
.
.
b0 = 0.9915141178644
a6 = 0.9831002459245
.
.
.
a0 = 1
Also, you may want to post a question like this on:
https://dsp.stackexchange.com/

python and weierstrass function

based on this function. I'm trying to create two empty arrays (one for x and other for y), which later I will use to plot in python. But before anything this is what I have so far...
import math
x1=-2.0
x2=2.0
arr1 = []
arr2 = []
i=0
n=10
delta=(x2-x1)/n
for i in range (0,n+1):
x=x1+delta*i
arr1.append(x)
print arr1
# I have not called the w function yet
the code above creates a list of 10 numbers for now to keep it simple. Then it will send the elements of the array to the function below and compute the equation with certain numbers(infinite loop).
#This function will create the array list for y
import math
def w(x, limit):# the limit here to compare when the number is really small
suma = 0.0
sumb = 0.0
m=1
x=0
suma=suma+((1/(math.pow(2,m))*(math.sin(math.pow(2,m)*x)))
sumb=suma+((1/(math.pow(2,m+1))*(math.sin(math.pow(2,m+1)*x))) # I'm having a
#syntax error
#here
x+=0
if (abs (suma-sumb)<limit):
break:
else m+=1:
if (m<20):
break:
I will appreciate any help with my syntax errors or any suggestion. I just hope I was clear enough.
Thanks ahead of time
The syntax error is actually on the previous line, where the parenthesis are not balanced. You need an extra ) at the end of that line (and at the one you indicated as giving an error too btw).
There are also a few other issues
suma is set to zero, so suma = suma + ... is the same as suma = ..., but I'm guessing you still need to add while loop before this line.
On the line indicated, you have sumb = suma +, which is probably a copy/paste mistake.
The code block starting at x+=0 is indented by only 3 spaces instead of 4. This is probably not the case in your actual code, but if it is, Python will complain about that too.
else m+=1: should be else: m+=1 (colon directly after else, not at the end of the line.
break: should just be break (without to colon).