Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you use matrices in Nimrod?

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!

like image 361
cjohnson318 Avatar asked Jan 28 '14 20:01

cjohnson318


1 Answers

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.

like image 52
Grzegorz Adam Hankiewicz Avatar answered Nov 15 '22 11:11

Grzegorz Adam Hankiewicz