I want to start from an array like
A = zeros( nK , nK , m , m )
and reshape it into an matrix of size (nK,nK) where each element is an mxm matrix.
I have tried the basis reshape function, reshape(A , nK , nK ), but it gives me
DimensionMismatch("new dimensions (nK, nK) must be consistent with array size mxmxnKxnK")
On Julia 1.9, you want eachslice:
julia> x = rand(Int8,3,3,2,2)
3×3×2×2 Array{Int8, 4}:
[:, :, 1, 1] =
127 107 27
31 -90 95
-50 -92 117
...
julia> eachslice(x; dims=(3,4))
2×2 Slices{Array{Int8, 4}, Tuple{Colon, Colon, Int64, Int64}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, SubArray{Int8, 2, Array{Int8, 4}, Tuple{Base.Slice{Base.OneTo{Int64}}, Base.Slice{Base.OneTo{Int64}}, Int64, Int64}, true}, 2}:
[127 107 27; 31 -90 95; -50 -92 117] [-58 7 -16; -77 -110 32; -82 25 -48]
[-40 13 -43; -63 121 47; 28 -64 57] [62 -61 19; 117 42 101; 70 -82 -62]
julia> eachslice(x; dims=(1,2))
3×3 Slices{Array{Int8, 4}, Tuple{Int64, Int64, Colon, Colon}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, SubArray{Int8, 2, Array{Int8, 4}, Tuple{Int64, Int64, Base.Slice{Base.OneTo{Int64}}, Base.Slice{Base.OneTo{Int64}}}, true}, 2}:
[127 -58; -40 62] [107 7; 13 -61] [27 -16; -43 19]
[31 -77; -63 117] [-90 -110; 121 42] [95 32; 47 101]
[-50 -82; 28 70] [-92 25; -64 -82] [117 -48; 57 -62]
As noted above, usually it's best to use slices containing the leading dimensions, like x[:,:,i,j] produced by eachslice(x; dims=(3,4)).
On Julia 1.8 & lower, ideally Compat.jl#663 will make this work.
If I understand your problem correctly, I think you can do it this:
julia> x = rand(1:10, 2, 4, 3, 3)
2×4×3×3 Array{Int64, 4}:
[:, :, 1, 1] =
9 5 4 1
2 2 2 10
[:, :, 2, 1] =
8 1 4 9
9 5 5 8
...
julia> # With copy:
julia> [x[i, j, :, :] for i in axes(x, 1), j in axes(x, 2)]
2×4 Matrix{Matrix{Int64}}:
[9 5 4; 8 2 6; 5 7 5] [5 8 5; 1 6 1; 1 5 5] [4 10 4; 4 3 10; 4 7 10] [1 10 5; 9 2 5; 7 1 10]
[2 7 1; 9 5 3; 7 1 7] [2 3 9; 5 7 10; 4 1 4] [2 1 2; 5 1 1; 1 2 4] [10 1 3; 8 3 8; 9 10 2]
julia> # With views:
julia> [view(x, i, j, :, :) for i in axes(x, 1), j in axes(x, 2)]
2×4 Matrix{SubArray{Int64, 2, Array{Int64, 4}, Tuple{Int64, Int64, Base.Slice{Base.OneTo{Int64}}, Base.Slice{Base.OneTo{Int64}}}, true}}:
[9 5 4; 8 2 6; 5 7 5] [5 8 5; 1 6 1; 1 5 5] [4 10 4; 4 3 10; 4 7 10] [1 10 5; 9 2 5; 7 1 10]
[2 7 1; 9 5 3; 7 1 7] [2 3 9; 5 7 10; 4 1 4] [2 1 2; 5 1 1; 1 2 4] [10 1 3; 8 3 8; 9 10 2]
I hope it helps you.
Related
I have a numpy array X = [[3 4 5 6] [6 5 3 3] [9 8 5 2]]
I would like to add 1 in each array like so:
X = [[1 3 4 5 6] [1 6 5 3 3] [1 9 8 5 2]]
I wanted to do it using np.ones() and np.hstack()
This is what I tried to do
X = [[3 4 5 6] [6 5 3 3] [9 8 5 2]]
ones = np.ones(len(X))
X = np.hstack((ones, X))
I am trying to figure out how to slice a matrix every 2 columns. For example, if we have
A=[[1 2 3 4 5 6];[7 8 9 10 11 12]]
2×6 Matrix{Int64}:
1 2 3 4 5 6
7 8 9 10 11 12
then I would like to return 3 matrices sliced every 2 columns, i.e. a 3 dimensional array with 3 matrices,
2×2×3 Array{Int64, 3}:
[:, :, 1] =
1 2
7 8
[:, :, 2] =
3 4
9 10
[:, :, 3] =
5 6
11 12
One thing I have tried is the eachslice function,
collect(eachslice(A,dims=2))
6-element Vector{SubArray{Int64, 1, Matrix{Int64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}}:
[1, 7]
[2, 8]
[3, 9]
[4, 10]
[5, 11]
[6, 12]
but this slices along every column, but I want to slice along every two columns!
Thanks in advance.
That's just a reshape. Reshapes share memory (like views), so you should copy it if you want it to be independent of the original A:
julia> reshape(A, 2, 2, 3)
2×2×3 Array{Int64, 3}:
[:, :, 1] =
1 2
7 8
[:, :, 2] =
3 4
9 10
[:, :, 3] =
5 6
11 12
But if you really want, you can express it as indexing, too:
julia> A[:, [1:2 3:4 5:6]]
2×2×3 Array{Int64, 3}:
[:, :, 1] =
1 2
7 8
[:, :, 2] =
3 4
9 10
[:, :, 3] =
5 6
11 12
In Julia, I want to convert data defined as Vector of 2D array to a 2D array of Matrix.
As described in the following example, I want to convert data s into data t, but I have not been successful so far.
How should I deal with the case?
julia> s = [[1 2 3], [4 5 6], [7 8 9]]
3-element Array{Array{Int64,2},1}:
[1 2 3]
[4 5 6]
[7 8 9]
julia> t = [[1 2 3]; [4 5 6]; [7 8 9]]
3××3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
julia> s |> typeof
Array{Array{Int64,2},1}
julia> t |> typeof
Array{Int64,2}
julia> convert(Array{Int64, 2}, s)
ERROR: MethodError: Cannot `convert` an object of type Array{Array{Int64,2},1} to an object of type Array{Int64,2}
This may have arisen from a call to the constructor Array{Int64,2}(...),
since type constructors fall back to convert methods.
julia> reshape(s, 3, 3)
ERROR: DimensionMismatch("new dimensions (3,3) must be consistent with array size 3")
in reshape(::Array{Array{Int64,2},1}, ::Tuple{Int64,Int64}) at .\array.jl:113
in reshape(::Array{Array{Int64,2},1}, ::Int64, ::Int64, ::Vararg{Int64,N}) at .\reshapedarray.jl:39
As in the following example, if you define 2D array or 1D array as source data, I can then reshape them successfully into a 2D array of Matrix.
julia> u = [1 2 3 4 5 6 7 8 9]
1××9 Array{Int64,2}:
1 2 3 4 5 6 7 8 9
julia> u |> typeof
Array{Int64,2}
julia> reshape(u, 3, 3)
3××3 Array{Int64,2}:
1 4 7
2 5 8
3 6 9
julia> v = [1, 2, 3, 4, 5, 6, 7, 8, 9]
9-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
julia> v |> typeof
Array{Int64,1}
julia> reshape(v, 3, 3)
3××3 Array{Int64,2}:
1 4 7
2 5 8
3 6 9
You can use vcat and splatting
julia> t = vcat(s...)
3×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
I am trying to create a bezier surface using MATLAB code. For this I have to input co-ordinates in the form of [[x1 y1] [x2 y2] [x3 y3];[x4 y4] [x5 y5] [x6 y6]]. I have tried using cell array but arithmetical operations with other matrices or array isn't possible while using cell array. Please help
example:
C=[[2 3] [3 4] [4 5] [5 6];[2 5] [5 2] [7 8] [8 9]];
A=C(1,3);
ans=[4 5]
Also
C=[[2 3] [3 4] [4 5] [5 6];[2 5] [5 2] [7 8] [8 9]];
D=[1 2;2 1;3 1;2 3];
E=C*D
ans=[[30 38] [26 33];[49 51] [40 47]]
you can try using cat(3,..):
C = cat(3,[[2 3] ;[3 4] ;[4 5]; [5 6]],[[2 5]; [5 2] ;[7 8] ;[8 9]]);
A = C(3,:,1)
You could use a 3D matrix, with the second "layer" being your second coordinate pair, or simply use 2 matrices!
Using your example:
C1 = [2 3 4 5; 2 5 7 8];
C2 = [3 4 5 6; 5 2 8 9];
D = [1 2; 2 1; 3 1; 2 3];
E1 = C1*D; E2 = C2*D;
In 3D matrices:
% Make 3D matrix of same size as C1 but 2 layers
C = zeros([size(C1), 2]);
C(:,:,1) = C1; C(:,:,2) = C2;
E = cat(3, C(:,:,1)*D, C(:,:,2)*D);
% ans is a 3D matrix, with the 2 layers representing the pairs in your example.
Indexing the 3D matrix like you wanted:
C13 = reshape(C(1,3,:),1,2) % C13 = [4, 5]
% or
C13 = squeeze(C(1,3,:))' % C13 = [4, 5]
I am working with some documentation and wish to portray an array of this form
>>> a_3d
array([[[4, 6, 4],
[1, 1, 8],
[0, 7, 5],
[5, 3, 3],
[8, 9, 5]],
[[8, 8, 4],
[3, 4, 4],
[0, 0, 9],
[3, 7, 3],
[3, 4, 7]],
[[9, 5, 4],
[7, 7, 3],
[9, 5, 9],
[8, 7, 8],
[5, 8, 8]]], dtype=int32)
as text in a similar fashion as I can do it using MatPlotLib as a graph/map.
I have managed to simply decompress the original array and provide some additional information into this form.
array...
shape (3, 5, 3) ndim 3 size 45
a[0]...
[[[4 6 4]
[1 1 8]
[0 7 5]
[5 3 3]
[8 9 5]]
a[1]....
[[8 8 4]
[3 4 4]
[0 0 9]
[3 7 3]
[3 4 7]]
a[2]....
[[9 5 4]
[7 7 3]
[9 5 9]
[8 7 8]
[5 8 8]]]
But I have tried every combination of reshaping, transposing to get it into a row representation. I haven't found a soution, short of reconstructing the array from first principles so that the three 2D blocks appear in one row.
Again, this is for teaching and visualization purposes and not for analysis. If I have overlooked the obvious, I would appreciate any comments.
EDIT
[[[4, 6, 4], [[8, 8, 4], [[9, 5, 4],
[1, 1, 8],
[0, 7, 5], etc etc
[5, 3, 3],
[8, 9, 5]], [3, 4, 7]], [5, 8, 8]]]
or similar... if this helps
apparently the kludge workaround I am using might help, it would be nice to work with the original data and restructure it, rather than to have to say...we will flip out to using lists and object arrays for awhile...
def to_row(a):
""" kludge workaround """
n, rows, cols = a.shape
e = np.empty((rows, cols), dtype='object')
for r in range(rows):
for c in range(cols):
e[r][c] = (a[c][r]).tolist()
return e
So you have an array with shape (3,5,3), and the default array function displays it has 3 planes, each a (5,3) 2d array.
Reshaping and transposing does not change this basic display format - it still splits the array on the 1st axis, and formats each block.
The formatting is handled by a builtin numpy function:
In [112]: arr=np.arange(2*3*4).reshape(2,3,4)
In [113]: arr.__format__('')
Out[113]: '[[[ 0 1 2 3]\n [ 4 5 6 7]\n [ 8 9 10 11]]\n\n [[12 13 14 15]\n [16 17 18 19]\n [20 21 22 23]]]'
np.array2string(arr) produces the same string.
Conceivably you could split this string on \n, and rearrange the pieces.
In [116]: np.get_printoptions()
Out[116]:
{'edgeitems': 3,
'formatter': None,
'infstr': 'inf',
'linewidth': 75,
'nanstr': 'nan',
'precision': 8,
'suppress': False,
'threshold': 1000}
the set_options function's doc describes these values. You might also look at np.set_string_function
Here's a first stab at rearranging the lines:
In [137]: astr=np.array2string(arr)
In [138]: lines=astr.splitlines()
In [139]: lines
Out[139]:
['[[[ 0 1 2 3]',
' [ 4 5 6 7]',
' [ 8 9 10 11]]',
'',
' [[12 13 14 15]',
' [16 17 18 19]',
' [20 21 22 23]]]']
In [140]: print '\n'.join([' '.join((lines[i],lines[i+4])) for i in range(3)])
[[[ 0 1 2 3] [[12 13 14 15]
[ 4 5 6 7] [16 17 18 19]
[ 8 9 10 11]] [20 21 22 23]]]
Brackets need to be cleaned up, but overall the shape looks right.
Another way to get such a set of lines is to format each plane:
In [151]: alist=[np.array2string(i).splitlines() for i in arr]
In [152]: alist
Out[152]:
[['[[ 0 1 2 3]', ' [ 4 5 6 7]', ' [ 8 9 10 11]]'],
['[[12 13 14 15]', ' [16 17 18 19]', ' [20 21 22 23]]']]
In [153]: zip(*alist) # a list form of transpose
Out[153]:
[('[[ 0 1 2 3]', '[[12 13 14 15]'),
(' [ 4 5 6 7]', ' [16 17 18 19]'),
(' [ 8 9 10 11]]', ' [20 21 22 23]]')]
which then can be joined. \t (tab) cleans up the bracket spacing.
In [155]: '\n'.join(['\t'.join(k) for k in zip(*alist)])
Out[155]: '[[ 0 1 2 3]\t[[12 13 14 15]\n [ 4 5 6 7]\t [16 17 18 19]\n [ 8 9 10 11]]\t [20 21 22 23]]'
In [156]: print _
[[ 0 1 2 3] [[12 13 14 15]
[ 4 5 6 7] [16 17 18 19]
[ 8 9 10 11]] [20 21 22 23]]
for 3 blocks - it still needs work :(
In [157]: arr1=np.arange(2*3*4).reshape(3,4,2)
In [158]: alist=[np.array2string(i).splitlines() for i in arr1]
In [159]: print '\n'.join(['\t'.join(k) for k in zip(*alist)])
[[0 1] [[ 8 9] [[16 17]
[2 3] [10 11] [18 19]
[4 5] [12 13] [20 21]
[6 7]] [14 15]] [22 23]]
In a sense it's the same problem you have with text when you want to display it in columns. May be there's a multi-column print utility.
Even though you are thinking in terms of blocks side by side, the display is still based on lines.