3

I have the following code, where given i I want to find the ith row of a matrix. My code is the following:

function f(mat,i)
     println(mat[:i,:])
end

However, I get the following error:

ArgumentError: invalid index: :i of type Symbol

I have tried printing the type of i using typeof and it says it is Int64. Further, if I attempt to just find the first row then mat[:1,:] does the job so I don't think the problem is with the slicing syntax.

newtothis
  • 495
  • 3
  • 10
  • It is with the slicing syntax I believe – logankilpatrick Oct 28 '21 at 18:46
  • But why does the syntax work stand alone? – newtothis Oct 28 '21 at 19:03
  • Because for Julia parser `:1` is the same as just `1`. In Julia you do not need to slice to get the row of the matrix - just passing a row number is enough. – Bogumił Kamiński Oct 28 '21 at 19:07
  • The answer below goes into detail, but the short answer is to just write `mat[i, :]`. The colon in front of `i` makes it into a symbol, which is not the same as the value of the variable `i`. Why did you put the colon there, btw? – DNF Oct 28 '21 at 20:39

1 Answers1

5

You can get e.g. the first row of a matrix like this:

julia> x = rand(4, 5)
4×5 Matrix{Float64}:
 0.995364  0.00204836  0.0821081  0.732777   0.705893
 0.4392    0.151428    0.0978743  0.184995   0.867329
 0.863659  0.367339    0.252248   0.235425   0.0343476
 0.756938  0.119276    0.857559   0.0982663  0.938148

julia> x[1, :]
5-element Vector{Float64}:
 0.9953642825497493
 0.0020483620556226434
 0.0821081267390984
 0.7327765477421397
 0.7058932509878071

julia> x[1:1, :]
1×5 Matrix{Float64}:
 0.995364  0.00204836  0.0821081  0.732777  0.705893

Note that normally you just pass a row number (in my case 1) to signal the row you want to fetch. In this case as a result you get a Vector.

However, you can use slicing 1:1 which gets a 1-element range of rows. In this case the result is a Matrix having one row.


Now the issue of :1. See below:

julia> :1
1

julia> typeof(:1)
Int64

julia> :1 == 1
true

julia> :x
:x

julia> typeof(:x)
Symbol

As you can see :1 is just the same as 1. However, e.g. :x is a special type called Symbol. Its most common use is to represent field names in structs. Since field names cannot start with a number (variable names in Julia, as also in other programming languages) have to start with something else, e.g. a letter x as in my example, there is no ambiguity here. Putting : in front of a number is a no-op, while putting it in front of a valid variable identifier creates a Symbol. See the help for Symbol in the Julia REPL for more examples.


In Julia ranges always require passing start and end i.e. a:b is a range starting from a and ending with b inclusive, examples:

julia> 1:1
1:1

julia> collect(1:1)
1-element Vector{Int64}:
 1

julia> 2:4
2:4

julia> collect(2:4)
3-element Vector{Int64}:
 2
 3
 4
Bogumił Kamiński
  • 66,844
  • 3
  • 80
  • 107