# `rand()` vs. `rand.()`?

Consider the following example:

``````x = zeros(10)
x .= rand()
``````

All components of `x` will have the same (random) value. Now suppose I do instead:

``````x = zeros(10)
x .= rand.()
``````

Since `rand.()` is dotted, I’d expect it to apply to each element of `x` separatedly. In this case, I should obtain ten distinct random values. However the result is the same as above (a single random value fills the whole vector).

Even though `rand.()` has no arguments, it still should “apply to each element separatedly”. At least that’s what my intuition tells me.

Can someone explain this behavior?

`x .= a` just fills `x` with `a`’s when they are scalars, regardless of how you got `a`.

`rand.()` gives you a scalar. The dot has no effect here, as there is nothing to broadcast over, so it is the same as `rand()`.

1 Like

@Tamas_Papp The behavior I suggest could be useful. Don’t you agree?

It’s already fixed on master.

@yuyichao What do you mean? What’s the new behavior?

``````julia> x = zeros(10);

julia> x .= rand.();

julia> x
10-element Array{Float64,1}:
0.344676
0.0245599
0.276739
0.500142
0.256044
0.176647
0.406575
0.547504
0.913086
0.170801
``````
2 Likes

@yuyichao Nice. So it should be on 0.6.

Actually it seems @Tamas_Papp approach makes more sense.

The `.=` means do the operation in broadcasting way.
Now, broadcasting is operation which its input is array (Or arrays).
It shouldn’t be driven by `rand()` function.

Seems useful to have it but no coherent as a language.

@RoyiAvital This is fine if you do `x .= rand()`. However, the point is that if you use a dot in `rand.()` (as in `x .= rand.()`), it should be broadcasted too.

`x .= rand()` is equivalent to `broadcast!(identity, x, rand())`, so `rand` is called only once.

`x .= rand.()` is equivalent to `broadcast!(rand, x)`. So (in 0.6), `rand()` is called once for each element of `x`.

The nice thing about the latter is that you can do vectorized operations with random numbers without requiring a temporary array to fill with `rand(n)` or `rand!` first. For example, `x .+= y .* rand.()` occurs entirely in-place in a single loop, adding a random fraction of each element of `y` to each element of `x`. (Or equivalently, you can do `@. x += y * rand()` in 0.6, allowing you to omit all of the dots.)

8 Likes

Just to be clear, I was not making a normative statement, just describing how I think `0.5.0` works. I think the broadcasting semantics of `0.6` are very nice, including the example above by @stevengj and also the broadcasting on `Nullable`s; I am looking forward to both (and the inevitable corner cases which will be surprising ).

1 Like

Is there a syntax equivalent to `x .= rand.()` on Julia 0.6 that works on Julia 0.5 as well?

`rand!(x)`?

2 Likes