opticspy / lightpipes

LightPipes for Python, "Pure Python version"
https://opticspy.github.io/lightpipes/
BSD 3-Clause "New" or "Revised" License
227 stars 52 forks source link

indexing into a field? #42

Closed new2python2020 closed 3 years ago

new2python2020 commented 4 years ago

A is a list, F0 is a field, B is a list and N is an int. This piece of code worked with LightPipes 1.2.0 using Python 2.7, but is giving me TypeErrors in LightPipes 2.0.5 in Python 3.8.2. I'm not sure how to index into the field F0, and any help is appreciated.

for y in range(N): for x in range(N): A[y][x] = complex(F0[y][x].real B[x][y] , F0[y][x].imag B[x][y])

FredvanGoor commented 4 years ago

Dear new2python2020,

The new version of LightPipes for Python (2.05) is pure Python ( so no longer a C++ package). This has many advantages and is as fast as the old C++ version (1.2.0). For this we made use of the numpy package and for that we had to change the type of the field from 'list' to numpy array. We thought that nobody would notice that because we anticipated that people would not use the field array elements in their code.....

Please change your code according to the example below. I hope it will work now.

Fred van Goor

from LightPipes import *

wavelength=5*um
size=20.0*mm
N=5

F0=Begin(size,wavelength,N)

print(F0.field.real[1][2])
print(F0.grid_dimension)
print(F0.lam)
print(F0.siz)

# for y in range(N):
    # for x in range(N):
        # B[x][y] =123*x + 456*y
        # A[y][x] = complex(F0[y][x].real * B[x][y] , F0[y][x].imag * B[x][y])

B = [[1 for i in range(N)] for j in range(N)]
A = [[0 for i in range(N)] for j in range(N)]

for y in range(N):
    for x in range(N):
        A[y][x] = complex(F0.field[y][x].real * B[x][y] , F0.field[y][x].imag * B[x][y])

print(A)
new2python2020 commented 3 years ago

Thanks Fred, that seemed to have worked!

new2python2020 commented 3 years ago

Apologies, I have a follow-up question. The variable A from my previous post is a list, but I'd like to propagate it forward as a field to functions such as Fresnel, Intensity, etc. Is this field input supposed to be any type of array? I tried to convert it to an array using numpy.array(A), but continue to get the error that "Field is neither first nor last parameter..."

A2 = numpy.array(A) F2 = lp.Fresnel(A2,d0); # d0 is type int

FredvanGoor commented 3 years ago

Try this:

from LightPipes import *

wavelength=5*um
size=20.0*mm
N=5

F0=Begin(size,wavelength,N)

print(F0.field.real[1][2])
print(F0.grid_dimension)
print(F0.lam)
print(F0.siz)

# for y in range(N):
    # for x in range(N):
        # B[x][y] =123*x + 456*y
        # A[y][x] = complex(F0[y][x].real * B[x][y] , F0[y][x].imag * B[x][y])

B = [[1 for i in range(N)] for j in range(N)]
A = [[0 for i in range(N)] for j in range(N)]

for y in range(N):
    for x in range(N):
        A[y][x] = complex(F0.field.real[y][x] * B[x][y] , F0.field[y][x].imag * B[x][y])

print(A)

#A2 = numpy.array(A)
#F2 = lp.Fresnel(A2,d0); # d0 is type int
F1=F0
for y in range(N):
    for x in range(N):
        F1.field.real[y][x] = A[y][x].real
        F1.field.imag[y][x] = A[y][x].imag

print(F1.field)
d0=100
F2=Fresnel(F1,d0)
print(F2.field)

You can write the second for loop as (the benefit of using numpy!):

F1.field = A

It gives the same result.

from LightPipes import *

wavelength=5*um
size=20.0*mm
N=5

F0=Begin(size,wavelength,N)

print(F0.field.real[1][2])
print(F0.grid_dimension)
print(F0.lam)
print(F0.siz)

# for y in range(N):
    # for x in range(N):
        # B[x][y] =123*x + 456*y
        # A[y][x] = complex(F0[y][x].real * B[x][y] , F0[y][x].imag * B[x][y])

B = [[1 for i in range(N)] for j in range(N)]
A = [[0 for i in range(N)] for j in range(N)]

for y in range(N):
    for x in range(N):
        A[y][x] = complex(F0.field.real[y][x] * B[x][y] , F0.field[y][x].imag * B[x][y])

print(A)

#A2 = numpy.array(A)
#F2 = lp.Fresnel(A2,d0); # d0 is type int
F1=F0
F1.field = A 
print(F1.field)
d0=100
F2=Fresnel(F1,d0)
print(F2.field)
new2python2020 commented 3 years ago

Wonderful, thanks!