Multiple iterators in "for", "lfor", etc. with something like "dct.items()" - hy

How could I convert the following to hy?
dct = { 1:2, 3:4 }
print([i*j for i, j in dct.items()])
# => [2, 12]

I'm puzzled by your title, since there's only one iteration clause in your example, but anyway, here's a literal Hy translation:
(setv dct {1 2 3 4})
(print (lfor [i j] (.items dct) (* i j)))
; => [2, 12]
But you could also do this with the shadow multiplication operator:
(import hy.pyops *)
(setv dct {1 2 3 4})
(print #* (map * (.keys dct) (.values dct)))
; => 2 12

Related

HyLang : Howto simplest for loop in hy?

I wanna get Hy!
How, In Hylang, do I do the simple Python loop:
for i in range(5):
print(i)
The tutorial provides this example:
(for [x [1 2 3]]
(print x)) ; => 1 2 3
Changing the variable name, and using range in place of a list, we get:
(for [i (range 5)]
(print i))

What is the mathematical explanation of adding 2d Array and 1d Array?

I can't seem to replicate this numpy arithmetic. I'm using Julia, but want to know the mathematical explanation for this code. It seems to break what I know about Linear Algebra.
X = np.arange(-5, 5, 0.2).reshape(-1, 1)
X.shape ## (50, 1)
test = np.sum(X**2, 1).reshape(-1, 1) + np.sum(X**2, 1)
test.shape ## (50, 50)
In Julia, I would write
X = reshape(collect(range(-5, stop=5, length=N)), :, 1);
size(X) ## (50, 1)
test = sum(X.^2, dims=2) + vec(sum(X.^2, dims=2));
size(test) ## (50, 1)
I'm trying to think how a 50x50 matrix would be the result of adding two vectors? I know numpy uses a lot of broadcasting under the hood, but it doesn't seem clear to me what this is doing.
What is the mathematical notation or Julia equivalent for what numpy is doing here?
Your are doing a lot of stuff that really obscures your point, which, I believe, concerns how to add arrays of different shapes.
Python:
In [21]: x = np.random.rand(5, 1)
In [22]: x.shape
Out[22]: (5, 1)
In [23]: y = np.random.rand(1, 4)
In [24]: y.shape
Out[24]: (1, 4)
In [25]: (x + y).shape
Out[25]: (5, 4)
Julia:
julia> x = rand(5);
julia> y = rand(1, 4);
julia> x + y
ERROR: DimensionMismatch("dimensions must match")
julia> x .+ y
5×4 Array{Float64,2}:
1.95779 1.31897 1.23345 1.32423
1.78126 1.14244 1.05692 1.14771
1.08306 0.444243 0.35872 0.449509
1.69756 1.05874 0.97322 1.06401
1.18661 0.547789 0.462265 0.553054
julia> size(x .+ y)
(5, 4)
As you can tell, Python broadcasts arrays by default, while Julia requires that you specifically ask for it, by using the dot operator, ..
It is exactly because it does not make sense to add two arrays of different shapes, that Julia does not broadcast by default. Similarly, with multiplication, * and .* differ:
julia> A = [1 2; 3 4]
2×2 Array{Int64,2}:
1 2
3 4
julia> B = [4 5; 6 7]
2×2 Array{Int64,2}:
4 5
6 7
julia> A * B
2×2 Array{Int64,2}:
16 19
36 43
julia> A .* B
2×2 Array{Int64,2}:
4 10
18 28
The ordinary * is matrix multiplication, while the latter is elementwise array multiplication.
Another example:
julia> A = [1 2 3; 4 5 6]
2×3 Array{Int64,2}:
1 2 3
4 5 6
julia> b = [7, 8]
2-element Array{Int64,1}:
7
8
julia> A * b
ERROR: DimensionMismatch("matrix A has dimensions (2,3), vector B has length 2")
julia> A .* b
2×3 Array{Int64,2}:
7 14 21
32 40 48

How to zip a 2D and a 1D array row-wise in Julia?

How do I zip a two-dimensional array with a "vector" row-wise in Julia?
This
X = [1 2; 3 4]
ndims(X)
Y = [-1 -2]
ndims(Y)
first(zip(X,Y))
gives (1, -1) while I want to get ([1 2], -1).
If you're ok with using column-vectors for the input and output, then you can use the eachrow function, which iterates over the rows of a matrix and returns the rows as column-vectors:
julia> X = [1 2; 3 4];
julia> Y = [-1, -2];
julia> collect(zip(eachrow(X), Y))
2-element Array{Tuple{Array{Int64,1},Int64},1}:
([1, 2], -1)
([3, 4], -2)
On the other hand, if you need the first elements of your zipped tuples to be row-vectors (as is shown in your question), then you could convert your matrix into a vector of rows and then use zip:
julia> X = [1 2; 3 4];
julia> Y = [-1 -2];
julia> rows = [X[[i], :] for i in 1:size(X, 1)]
2-element Array{Array{Int64,2},1}:
[1 2]
[3 4]
julia> collect(zip(rows, Y))
2-element Array{Tuple{Array{Int64,2},Int64},1}:
([1 2], -1)
([3 4], -2)
Note that I've used X[[i], :] inside the comprehension instead of X[i, :], so that we get an array of rows rather than an array of column-vectors.
Finally, just to be clear, note that Y = [-1 -2] produces a row-vector. We usually represent vectors as column vectors:
julia> Y = [-1, -2]
2-element Array{Int64,1}:
-1
-2
There are iterator builders in Julia: eachrow and eachcol, which work for arrays and are concise (at least in this case):
X = [1 2; 3 4]
Y = [-1 -2]
z = zip(eachrow(X), eachcol(Y))
Then
for el in z
print(el)
end
gives
([1, 2], [-1])
([3, 4], [-2])

clojure loop see values

When using reduce there is the reductions function to see the list of successive reductions. Is there something similar to debug a loop in Clojure ?
#progo is right, you can always add another accumulator, but if you don't really want to do it every time, you could make some utility macro doing that for you, while being semantically equal to the default loop/recur (i am thinking of pair of loop+/recur+ (the latter would be used implicitly):
(defmacro recur+ [& args]
(let [names (repeatedly (count args) gensym)]
`(let ~(vec (interleave names args))
(recur ~#names (conj ~'&loop-history [~#names])))))
(defmacro loop+ [bindings & body]
(let [val-names (repeatedly (/ (count bindings) 2) gensym)
vals (take-nth 2 (rest bindings))
binding-lefts (take-nth 2 bindings)]
`(let [~#(interleave val-names vals)]
(loop [~#(interleave binding-lefts val-names)
~'&loop-history [~(vec val-names)]]
~#(clojure.walk/postwalk-replace
{'recur 'recur+
'loop 'loop+}
body)))))
as you can see, loop+ introduces the implicit value &loop-history, and replaces all the inner loops and recurs with loop+ and recur+, while recur+ adds this implicit var to the recur call (the part with val-names, vals and binging-lefts is essential to avoid the double evaluation of the forms passed to the loop+).
so, imagine you have some loop like this:
user> (loop [a 1 b 2]
(if (<= b 10)
(recur a (inc b))
(str a " " b)))
"1 11"
to use the new loop just call loop+ instead of loop:
user> (loop+ [a 1 b 2]
(if (<= b 10)
(recur a (inc b))
(str a " " b)))
"1 11"
it is expanded into the following:
(let*
[G__20054 1 G__20055 2]
(loop*
[a G__20054 b G__20055 &loop-history [[G__20054 G__20055]]]
(if (<= b 10)
(let*
[G__20056 a G__20057 (inc b)]
(recur
G__20056
G__20057
(conj &loop-history [G__20056 G__20057])))
(str a " " b))))
now &loop-history is totally accessible anywhere inside loop+:
user> (loop+ [a 1 b 2]
(if (<= b 10)
(do
(println "history length: " (count &loop-history)
"last item: " (last &loop-history))
(recur a (inc b)))
{:result (str a " " b)
:history &loop-history}))
;; history length: 1 last item: [1 2]
;; history length: 2 last item: [1 3]
;; history length: 3 last item: [1 4]
;; history length: 4 last item: [1 5]
;; history length: 5 last item: [1 6]
;; history length: 6 last item: [1 7]
;; history length: 7 last item: [1 8]
;; history length: 8 last item: [1 9]
;; history length: 9 last item: [1 10]
;; {:result "1 11", :history [[1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [1 8] [1 9] [1 10] [1 11]]}
notice, that it also introduces &loop-history for inner loops, without the need to change the source code:
user> (loop+ [a 1 b 2]
(if (<= b 10)
(do (println :outer-hist &loop-history)
(recur a (inc b)))
(loop [a a]
(if (>= a -4)
(do (println :inner-hist &loop-history)
(recur (dec a)))
(str a b)))))
:outer-hist [[1 2]]
:outer-hist [[1 2] [1 3]]
:outer-hist [[1 2] [1 3] [1 4]]
:outer-hist [[1 2] [1 3] [1 4] [1 5]]
:outer-hist [[1 2] [1 3] [1 4] [1 5] [1 6]]
:outer-hist [[1 2] [1 3] [1 4] [1 5] [1 6] [1 7]]
:outer-hist [[1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [1 8]]
:outer-hist [[1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [1 8] [1 9]]
:outer-hist [[1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [1 8] [1 9] [1 10]]
:inner-hist [[1]]
:inner-hist [[1] [0]]
:inner-hist [[1] [0] [-1]]
:inner-hist [[1] [0] [-1] [-2]]
:inner-hist [[1] [0] [-1] [-2] [-3]]
:inner-hist [[1] [0] [-1] [-2] [-3] [-4]]
"-511"
loop/recur is more imperative than reductions; you may very well just insert your own logging to the loop body yourself, or maintain an atom list of values, or most functionally, introduce an(other) accumulator to the loop arguments.

How to stack arrays in repa (Haskell)

Suppose there are two 1-D arrays of the same length:
let x = fromListUnboxed (ix1 4) [1, 2, 3, 4]
let y = fromListUnboxed (ix1 4) [5, 6, 7, 8]
Now I would like to stack these two arrays into one 2-D array so that these arrays form the rows. How can I do it in repa?
Basically, I'm looking for an equivalent of numpy's row_stack:
>>> x = np.array([1, 2, 3, 4])
>>> y = np.array([5, 6, 7, 8])
>>> np.row_stack((x, y))
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
Note. The two arrays, x and y, come from outside, i.e. I cannot create the 2-D array from scratch.
As I mentioned in the initial comment, all you need is to reshape then append (both in Data.Array.Repa.
ghci> let x' = reshape (ix2 4 1) x
ghci> let y' = reshape (ix2 4 1) y
ghci> z <- computeP $ x' `append` y' :: IO (Array U DIM2 Int)
ghci> z
AUnboxed ((Z :. 4) :. 2) [1,5,2,6,3,7,4,8]
As for pretty-printing, repa isn't very good (likely because there is no good pretty printing for higher dimensions). Here is a one-line hack to display z
ghci> putStr $ unlines [ unwords [ show $ z ! ix2 i j | i<-[0..3] ] | j<-[0..1] ]
1 2 3 4
5 6 7 8

Resources