How do you use matrices in Nimrod?

math, matrix, nim-lang

Solution

I'd like to first point out that the matrix library you refer to is three years old. For a programming language in development that's a lot of time due to changes, and it doesn't compile any more with the current Nimrod git version:

$ nimrod c matrix
...
private/tmp/n/matrix/matrix.nim(97, 8) Error: ']' expected

It fails on the double array accessor, which seems to have changed syntax. I guess your attempt to create a double `[][]` accessor is problematic, it could be ambiguous: are you accessing the double array accessor of the object or are you accessing the nested array returned by the first brackets? I had to change the `proc` to the following:

proc `[]`*[T](x: TMatrix[T], r,c: int): T =

After that change you also need to change the way to access the matrix. Here's what I got:

for x in 0 .. <2:
  for y in 0 .. <2:
    echo "x: ", x, " y: ", y, " = ", m[x,y]

Basically, instead of specifying two bracket accesses you pass all the parameters inside a single bracket. That code generates:

x: 0 y: 0 = 1
x: 0 y: 1 = 2
x: 1 y: 0 = 3
x: 1 y: 1 = 4

With regards to finding software for Nimrod, I would like to recommend you using Nimble, Nimrod's package manager. Once you have it installed you can search available and maintained packages. The command `nimble search math` shows two potential packages: linagl and extmath. Not sure if they are what you are looking for, but at least they seem more fresh.

Problem

I found this project on GitHub; it was the only search term returned for "nimrod matrix". I took the bare bones of it and changed it a little bit so that it compiled without errors, and then I added the last two lines to build a simple matrix, and then output a value, but the "getter" function isn't working for some reason. I adapted the instructions for adding properties found here, but something isn't right. Here is my code so far. I'd like to use the GNU Scientific Library from within Nimrod, and I figured that this was the first logical step. ``` type TMatrix*[T] = object transposed: bool dataRows: int dataCols: int data: seq[T] proc index[T](x: TMatrix[T], r,c: int): int {.inline.} = if r<0 or r>(x.rows()-1): raise newException(EInvalidIndex, "matrix index out of range") if c<0 or c>(x.cols()-1): raise newException(EInvalidIndex, "matrix index out of range") result = if x.transposed: c*x.dataCols+r else: r*x.dataCols+c proc rows*[T](x: TMatrix[T]): int {.inline.} = ## Returns the number of rows in the matrix `x`. result = if x.transposed: x.dataCols else: x.dataRows proc cols*[T](x: TMatrix[T]): int {.inline.} = ## Returns the number of columns in the matrix `x`. result = if x.transposed: x.dataRows else: x.dataCols proc matrix*[T](rows, cols: int, d: openarray[T]): TMatrix[T] = ## Constructor. Initializes the matrix by allocating memory ## for the data and setting the number of rows and columns ## and sets the data to the values specified in `d`. result.dataRows = rows result.dataCols = cols newSeq(result.data, rows*cols) if len(d)>0: if len(d)<(rows*cols): raise newException(EInvalidIndex, "insufficient data supplied in matrix constructor") for i in countup(0,rows*cols-1): result.data[i] = d[i] proc `[][]`*[T](x: TMatrix[T], r,c: int): T = ## Element access. Returns the element at row `r` column `c`. result = x.data[x.index(r,c)] proc `[][]=`*[T](x: var TMatrix[T], r,c: int, a: T) = ## Sets the value of the element at row `r` column `c` to ## the value supplied in `a`. x.data[x.index(r,c)] = a var m = matrix( 2, 2, [1,2,3,4] ) echo( $m[0][0] ) ``` This is the error I get: ``` c:\program files (x86)\nimrod\config\nimrod.cfg(36, 11) Hint: added path: 'C:\Users\H127\.babel\libs\' [Path] Hint: used config file 'C:\Program Files (x86)\Nimrod\config\nimrod.cfg' [Conf] Hint: system [Processing] Hint: mat [Processing] mat.nim(48, 9) Error: type mismatch: got (TMatrix[int], int literal(0)) but expected one of: system.[](a: array[Idx, T], x: TSlice[Idx]): seq[T] system.[](a: array[Idx, T], x: TSlice[int]): seq[T] system.[](s: string, x: TSlice[int]): string system.[](s: seq[T], x: TSlice[int]): seq[T] ``` Thanks you guys!

Original source