Prokop Hapala
Prokop Hapala

Reputation: 2444

Destructing Iterator.product in Julia

I wonder if I have Iterator.product generating pairs (x,y) how I get only x-componnet out of it?

I'm trying to convert from Python/numpy to julia using this cheatsheet. Simple thing:

xs = np.arange(0,2*np.pi,0.1)
ys = np.arange(0,2*np.pi,0.1)
Xs,Ys = np.meshgrid(xs,ys)
F = sin(Xs)*cos(Ys)

Now in Julia I got I should use Iterator.product

xs = 0.0 : 0.1 : 2*pi
ys = 0.0 : 0.1 : 2*pi
XYs = Iterators.product(xs,ys)
for (i, (x,y)) in enumerate( XYs ) println("$i $x $y") end
# as far as good

# Now what?
 (Xs,Ys)=XYs ;  println(Xs); println(Ys)  # Nope
.(Xs,Ys)=XYs ; println(Xs); println(Ys)   # syntax: invalid identifier name "."    
Xs=xy[:,0]  ;  println(Xs)                # MethodError: no method matching getindex( ... 
XYs_T = transpose(XYs) ; println(XYs_T)   # MethodError: no method matching transpose( 

# this seems to work, but how to address index which is not "first" or "last" ?
Xs = first.(XYs)
Ys = last.(XYs)

# I guess I know how to continue
F = sin.(Xs)*cos.(Ys)

imshow(F)    # yes, corrent

Upvotes: 1

Views: 234

Answers (2)

DNF
DNF

Reputation: 12654

You can use comprehensions, but I like broadcasting:

xs = range(0, 2π, step=0.1)
ys = range(0, 2π, step=0.1)
F = sin.(xs) .* cos.(ys')  # notice the adjoint '

You should avoid creating the intermediate meshgrid, that's just wasted. In fact, you should go read the manual section on broadcasting: https://docs.julialang.org/en/v1/manual/functions/#man-vectorized-1

The same thing applies in Python, btw, there is no need for meshgrid, just make sure that xs is a row vector and ys a column vector (or vice versa), then you can directly multiply np.sin(xs) * np.cos(ys), and they will broadcast to matrix form automatically.

Upvotes: 2

Bill
Bill

Reputation: 6086

You can avoid using the routines in Iterators if you use a comprehension:

julia> F = [sin(x) * cos(y) for x in xs, y in ys]
63×63 Array{Float64,2}:
  0.0         0.0         0.0         0.0         0.0        …   0.0         0.0         0.0         0.0
  0.0998334   0.0993347   0.0978434   0.0953745   0.0919527      0.0925933   0.0958571   0.098163    0.0994882
  0.198669    0.197677    0.194709    0.189796    0.182987       0.184262    0.190756    0.195345    0.197982
  0.29552     0.294044    0.289629    0.282321    0.272192       0.274089    0.28375     0.290576    0.294498
...

Remember that since Julia organizes arrays in memory by column first and Python row first, if you want the arrays to display the same in the REPL, you will need to reverse the order of x and y in the array reference, as in the 'ij' matrix indexing option of numpy's meshgrid:

F = [sin(x) * cos(y) for y in ys, x in xs] # BUT reference elements as e = F[y, x] now

Upvotes: 2

Related Questions