Want to use a function like numpy.broadcast_to()

I’m porting some Python code to Julia, and I’d like to use the equivalent of the numpy.broadcast_to() function in it.

An idea I’ve tried.

Given an Array x and a Tuple shape,

  • Use x .+ zeros(shape) instead of broadcast_to(x, shape)

This is simple and works a little fast, but I don’t think it’s a good solution.

  • Implement broadcast_to by myself.
    Unfortunately, this worked slower than the first idea I tried.

If you have a function that corresponds to numpy.broadcast_to, or an implementation that would be helpful, please let me know.

I can’t speak English very well, so I use machine translation.
Sorry if my English is strange.

Thank you.

x is a scalar, which should be in each element of the resulting n-dimensional array, right?
There are multiple ways, but this is probably the nicest one:

fill(x, shape)
2 Likes

@lungben’s suggestion is very nice: fill(x, shape) is, believe, the canonical solution to this. But keep in mind that you often don’t need to instantiate the array at all. If you are using x in operations with other arrays you would just write

A .+ x

for example. Otherwise, fill is the best way.

2 Likes

@lungben @DNF
I am very sorry.
I didn’t explain myself well enough.
The x is an array, not a scalar.

Could you give an example of where you would like to use broadcast_to? I.e. the value of x in that case and what you would want to do with it.

For non scalar x, this doesn’t match the documented result of broadcast_to:

np.broadcast_to(x, (3, 3))
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])
1 Like

No problem, I see now that your explanation was ok. Perhaps an example would have made it easier to understand.

You could try repeat, which is ok in this particular case:

julia> x = [1,2,3]';

julia> repeat(x, 2, 1)
2×3 Array{Int64,2}:
 1  2  3
 1  2  3

But I don’t know of a solution in Base that has exactly the same functionality as numpy.broadcast_to (there might be, though). I think this is because you rarely need to actually create the broadcasted array. You just do it lazily by using broadcasted operations instead. Are you sure that is not an acceptable solution? What do you need this for, if I may ask?

1 Like

Is this what you are looking for?

julia> function broadcast_to(x, shape)
           x isa Number && return fill(x, shape)
           repetitions = ntuple(length(shape)) do i
               oldsize, newsize = size(x, i), shape[i]
               if oldsize == 1
                   newsize
               elseif oldsize == newsize
                   1
               else
                   throw(ArgumentError("Sizes $oldsize and $newsize in dimension $i are incompatible!"))
               end
           end
           return repeat(x, repetitions...)
       end
broadcast_to (generic function with 1 method)

julia> broadcast_to(2, (3, 3))
3×3 Array{Int64,2}:
 2  2  2
 2  2  2
 2  2  2

julia> broadcast_to([1,2,3], (3, 3))
3×3 Array{Int64,2}:
 1  1  1
 2  2  2
 3  3  3

Just note that as others already pointed out, this is usually not necessary and can be quite slow, because it allocates a new array.

2 Likes

It’s worth noting that the difference between the python broadcast_to and the ones offered here is that in python the returned array is “A readonly view on the original array with the given shape.” rather than featuring copies. This is possible because multi dimensional numpy arrays are just arrays of arrays internally.

Do you mind linking to or writing out the exact operation that required broadcast_to :sweat_smile:
I agree with others in this thread that probably you don’t need it at all, and it’s just the numpy approach seeping into julia.

1 Like

@tomerarnon
Thank you.
I’ll try to write some code that works with the minimum

@tomerarnon
Sorry for the delay in getting back to you.
After thinking about it for a while, I’ve found that it’s good enough without using broadcasts.
I’m very sorry for the inconvenience.
Thank you for your kindness and insight.