'Julia error when trying to modify last number of an Array {Float 64}

I'm now starting using Julia and I need to interpolate a Brownian motion. I run the following codes but the following error appear.

N = 3
B = zeros(N)
B[N] = randn(1)

Which throws:

MethodError: Cannot `convert` an object of type Vector{Float64} to an object of type Float64


Solution 1:[1]

The element type of B is Float64. This means that B can only contain values of type Float64. rand(1) returns a vector of length 1, with type Vector{Float64}, so this can not be stored in B.

julia> N = 3;

julia> B = zeros(N);

julia> eltype(B)
Float64

julia> x = randn(1);

julia> typeof(x)
Vector{Float64}

Perhaps you want to generate a single Float64 and place in B? Then you can simply use randn(), which return a Float64:

julia> x = randn();

julia> typeof(x)
Float64

julia> B[N] = x
-0.2771343068955318

julia> B
3-element Vector{Float64}:
  0.0
  0.0
 -0.2771343068955318

Solution 2:[2]

It's often helpful when you're stumped by something to evaluate individual pieces in the Julia REPL to see what they do. In this case, if you evaluate randn(1) by itself, you'll see something like this:

julia> randn(1)
1-element Vector{Float64}:
 1.1308545762168796

It returns a single-element vector containing a random floating-point value. Now, when you do

B[2^N] = randn(1)

you are trying to assign a vector as the last value in an array of floating-point values. That might work in some languages like R and Matlab where there aren't actual scalars and scalars are instead approximated by single-element arrays (this has a host of problems which I won't go into here), but in Julia a scalar and an array containing a scalar are different things. That's why you get this error.

So how to fix the error? There are a number of ways. You could extract the value on the right hand side before assigning it like so:

B[2^N] = randn(1)[1]

That works, but it unnecessarily constructs a single-element vector only to immediately throw away the vector and take the element out of it, which is slow and wasteful (probably doesn't matter here, but if this was in some performance-sensitive code you wouldn't want to do that). Instead, you can generate just one scalar value not in an array by calling randn() with no dimension arguments:

julia> randn()
1.2990863797503651

This value can be assigned into B as is:

B[2^N] = randn()

That is the best way to do the specific thing you're trying to do here.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 fredrikekre
Solution 2 StefanKarpinski