Search code examples
matrixtypesjuliasliceargument-error

Accessing arbitrary rows in Julia matrix


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.


Solution

  • 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