Mold matrix of the same size

question

#1

Hi,
I want to define a matrix with the size of the existing one:

sz = size(A);
Id = eye(sz);

This produces an error:

ERROR: MethodError: no method matching eye(::Tuple{Int64,Int64})

How do I create a matrix of the same fast, without element-wise access to the tuple?


#2

If your array A has one or two dimensions, then you can do:

eye(sz...)

which, if sz is of length 2, is equivalent to:

eye(sz[1], sz[2])

This is called “splatting”: http://docs.julialang.org/en/release-0.5/manual/faq/#splits-one-argument-into-many-different-arguments-in-function-calls

edit: @DNF has an even better suggestion below.


#3

You can just do

Id = eye(A)

and then you get Id with the same shape and element type as A.


#4

@DNF @rdeits
Is there a fast way to double the dimensions, smth like:
eye(2*size(a))
to create a matrix of (2n,2m) size?


#5

Interestingly it seems * doesn’t broadcast properly along tuples in 0.5 (I seem to remember reading that in 0.5 the .* syntax is actually a special function and not actually broadcasting * but I may be wrong), but likely in 0.6 you could do 2.*size(a) to get a tuple (2n, 2m) like you’d expect.

In 0.5 you could do 2.*collect(size(a)) although it’s far from elegant. If this is something you want to do a lot I’d likely make some function like

function scaled_eye(a, N)
    return eye(N.*collect(size(a))...)
end

and then you’d be able to do scaled_eye(a, 2) to get the result you want without worrying about the correct operations you need to multiple a tuple and splat it


#6

This works too:

eye(2.*[size(A)...]...)

though it’s not exactly elegant, either.

It’s slightly surprising that eye doesn’t accept tuples, while zeros and ones do, but it might be related to the fact that eye can only accept at most two size parameters, while the others can take an arbitrary number of dimensions.

In many cases, though, you are better off using the UniformScaling operator I instead of eye. See: http://docs.julialang.org/en/stable/manual/linear-algebra/#the-uniform-scaling-operator


#7

Unfortunately, I cannot be a block in a matrix.

The problem is not that eye() doesn’t accept tuples, but that I cannot multiply tuple by scalar, that BTW seems to be reasonable.