Reshape "filling" by row - julia

Is there any easy way to reshape a vector into an array in which the "filling" is by row?
More specifically, suppose I have a vector
v = collect(1:8)
reshape "fills" the resulting array by column:
reshape(v, (2,2,2))
2x2x2 Array{Int64,3}:
[:, :, 1] =
1 3
2 4
[:, :, 2] =
5 7
6 8
But I want to get:
a = Array{Int}(2,2,2)
a[:, :, 1] = [1 2; 3 4]
a[:, :, 2] = [5 6; 7 8]
a
2x2x2 Array{Int64,3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
5 6
7 8
This would be a nice option to add to reshape.

mapslices(transpose,reshape(v, (2,2,2)),[1,2])
The keyword you were missing is "transpose". The rest I just took from the docs

Related

How can I determine if an array contains some element?

How can I tell if an array contains some element?
I have been manually checking with a loop:
for x in xs
if x == a
return true
end
end
return false
Is there a more idiomatic way?
The in operator will iterate over an array and check if some element exists:
julia> xs = [5, 9, 2, 3, 3, 8, 7]
julia> 8 in xs
true
julia> 1 in xs
false
It is important to remember that missing values can alter the behavior you might otherwise expect:
julia> 2 in [1, missing]
missing
in can be used on general collections. In particular, matrices:
julia> A = [1 4 7
2 5 8
3 6 9]
3×3 Array{Int64,2}:
1 4 7
2 5 8
3 6 9
julia> 7 in A
true
julia> 10 in A
false

How to apply one argument to Array{Function, 1} element-wise smartly in Julia?

I understand Julia can apply element-wise argument to a function by f.(x)
in v0.6
x = [1, 2, 3]
f = x->3x
#assert f.(x) = [3, 6, 9]
Now, I define f as Array{Function, 1}.
f1(x) = 3x
f2(x) = 4x
f = [f1, f2]
x = 2
#assert isa(f, Array{Function,1}) == true
# f.(x) is unavailable
I want to apply arguments to element-wise function like above syntax, not using map, [_f(x) for _f in f]
Can someone be familiar with this issue?
You can broadcast the pipe operator (|>), e.g.
x .|> f
You have to take care how to define x and f, in some cases you will fail. Your first x applied on your last f will fail.
julia> 5 .|> [x->2x, x->7x]
2-element Array{Int64,1}:
10
35
julia> [2, 5] .|> [x->2x, x->7x]
2-element Array{Int64,1}:
4
35
julia> [2 5] .|> [x->2x, x->7x]
2-element Array{Int64,2}:
4 10
14 35
julia> [2 5] .|> [x->2x x->7x]
1×2 Array{Int64,2}:
4 35
julia> [2, 5] .|> [x->2x x->7x]
2×2 Array{Int64,2}:
4 14
10 35
julia> [2 3 5] .|> [x->2x x->7x]
ERROR: DimensionMismatch("arrays could not be broadcast to a common")
julia> [2, 3, 5] .|> [x->2x, x->7x]
ERROR: DimensionMismatch("arrays could not be broadcast to a common")
julia> x = [1, 2, 3]; f = [x->2x, x->3x]; x .|> f
ERROR: DimensionMismatch("arrays could not be broadcast to a common")
Here's another possibility:
((f, x)->f(x)).([f1, f2], x)

Equivalent of the dot prefix for an arbitrary function?

Julia allows me to do elementwise binary operators on arrays/matrices with .:
[1 2 3] .+ [3 2 1]
[1 2 3] .> [3 2 1]
Is there a standard way to apply an arbitrary function f elementwise to a pair of arrays?
If you just want to apply a binary function to each pair of values from two lists, you can use map:
f(x,y) = 2x - y^2
julia> map(f, [1, 2, 3], [3, 2, 1])
3-element Array{Int64,1}:
-7
0
5
The .+ and .> operators also have the additional behavior that singleton dimensions are broadcast, like so:
julia> [1, 2, 3] .+ [-1 -2 -3]
3x3 Array{Int64,2}:
0 -1 -2
1 0 -1
2 1 0
julia> rand(3,4) .+ [1, 2, 3]
3x4 Array{Float64,2}:
1.73798 1.84132 1.12923 1.30192
2.10961 2.17835 2.52779 2.3028
3.16457 3.04659 3.67604 3.08869
julia> rand(3,4) .+ [1 2 3 4]
3x4 Array{Float64,2}:
1.40294 2.31384 3.34001 4.60027
1.13289 2.99275 3.50606 4.51049
1.31486 2.7585 3.64655 4.59647
If you also want this kind of behavior, you can use the broadcast function:
julia> broadcast(f, [1 2 3], [3, 2, 1])
3x3 Array{Int64,2}:
-7 -5 -3
-2 0 2
1 3 5

Declare and initialise 3-dimensional array

I want to initialise a 3-dimensional array in Julia with constant entries. For the 2d case I can use
A = [1 2; 3 4]
Is there a similar short syntax for 3d arrays?
Not at this time, although something like the following isn't too bad
A = zeros(2,2,2)
A[:,:,1] = [1 2; 3 4]
A[:,:,2] = [10 20; 30 40]
One can use either the cat or the reshape functions to accomplish the task: (tested with Julia-1.0.0):
julia> cat([1 2; 3 4], [5 6; 7 8], dims=3)
2×2×2 Array{Int64,3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
5 6
7 8
For higher Array dimensions, the cat calls must be nested: cat(cat(..., dims=3), cat(..., dims=3), dims=4).
The reshape function allows building higher dimension Arrays "at once", i.e., without nested calls:
julia> reshape([(1:16)...], 2, 2, 2, 2)
2×2×2×2 Array{Int64,4}:
[:, :, 1, 1] =
1 3
2 4
[:, :, 2, 1] =
5 7
6 8
[:, :, 1, 2] =
9 11
10 12
[:, :, 2, 2] =
13 15
14 16
It is actually possible to declare a multidimensional array in julia using only list comprehension
julia> a = [x + y + z for x in 1:2, y ∈ 2:3, z = 3:4]
2×2×2 Array{Int64,3}:
[:, :, 1] =
6 7
7 8
[:, :, 2] =
7 8
8 9
julia> size(a)
(2, 2, 2)
julia> ndims(a)
3
Julia documentation about Multi-dimensional Arrays is a good place to learn more about array creation.
For a 3-dimensional array, you can do the following:
julia> [1; 2;; 3; 4;; 5; 6;;;
7; 8;; 9; 10;; 11; 12]
2×3×2 Array{Int64, 3}:
[:, :, 1] =
1 3 5
2 4 6
[:, :, 2] =
7 9 11
8 10 12
From the documentation, "... ; and ;; concatenate in the first and second dimension, using more semicolons extends this same general scheme. The number of semicolons in the separator specifies the particular dimension, so ;;; concatenates in the third dimension, ;;;; in the 4th, and so on."

How can express this imperative function in a functional, array-based language like K (or Q)?

How can express this imperative function in a functional, array-based language like K (or Q)?
In sloppy C++:
vector<int> x(10), y(10); // Assume these are initialized with some values.
// BTW, 4 is just a const -- it's part of the algorithm and is arbitrarily chosen.
vector<int> result1(x.size() - 4 + 1); // A place to hold a resulting array.
vector<int> result2(x.size() - 4 + 1); // A place to hold another resulting array.
// Here's the code I want to express functionally.
for (int i = 0; i <= x.size() - 4; i++) {
int best = x[i + 0] - y[i + 0];
int bad = best;
int worst = best;
for(int j = 0; j < 4; j++) {
int tmp = x[i + j] - y[i + 0];
bad = min(bad, tmp);
if(tmp > best) {
best = tmp;
worst = bad;
}
}
result1[i] = best
result2[i] = worst
}
I would most like to see this in kdb and Q but other functional languages are welcome.
porting #silentbicycle's k directly to q yields
q)a:1+til 8
q)b:8#0
q){(max x;min x)}flip{4#y _ x}[a+b;]each til count a
4 5 6 7 8 8 8 8
1 2 3 4 5 6 7 8
another approach, slightly more vectorized (imao):
q){(max;min)#\:flip 4#'(til count x)_\:x+y}[a;b]
4 5 6 7 8 8 8 8
1 2 3 4 5 6 7 8
In Kona (an open-source K dialect):
First, set some example values (using same as the Clojure solution):
a:1+!8;b:8#0 / a is 1..8, b is eight 0s
Then:
{(|/x;&/x)}#+{4#y _ x}[a+b;]'!#a
Where a and b are your x and y variables above. (K makes a special case for the variables x, y, and z.)
To break that up a bit more:
maxmin:{(|/x;&/x)} / (max;min) pairs of x
get4:{4#y _ x} / next 4 from x, starting at y
/ with <4 remaining, will repeat; doesn't matter for min or max
/ maxmin applied to flipped results of get4(a-b) at each index 0..(length a)-1
maxmin#+get4[a-b;]'!#a
/ result
(4 5 6 7 8 8 8 8
1 2 3 4 5 6 7 8)
In Clojure (a dialect of Lisp):
(defn minmax [x y](map #(vector (- (apply max %1) %2) (- (apply min %1) %2)))(partition-all 4 1 x) y)
(minmax [1 2 3 4 5 6 7 8] [0 0 0 0 0 0 0 0])
will give
[([4 1] [5 2] [6 3] [7 4] [8 5] [8 6] [8 7] [8 8])`(result 1, result 2) as output..
Then
(map #(first %1) result) is result1
(map #(last %1) result) is result2

Resources