How do you use matrices in Nimrod? - math

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!

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.

Related

Converting a list of integers to a map of vertices containing the elements coordinates

This is what i have at the moment
(string -> int list)
let read filename = ....
this is working as intended, returning a list of integers from a textfile looking like this:
530070000
600195000
098000060
800600003
400803001
700020006
060000280
000419005
000080079
Yes you are correct, it is a sudoku board. This is what i have to work with:
type vertex = int * int (*Cells in the sudoku board*)
type gamma = int (*representing colors 1-9*)
(* [Vertex = Map.Make(Vertex)] *)
module Vertex = Map.Make(struct
type t = vertex
let compare = Stdlib.compare
end)
(* [Gamma = Set.Make(Gamma)] *)
module Gamma = Set.Make(struct
type t = gamma
let compare = Stdlib.compare
end)
The gamma set is for solving the sudoku board using graph coloring. I need help understanding how i can convert the list of integers to a suitable map for this kind of task. According to the structure i provided, so i can access each element in the map using it coordinates (x, y). Hope you understand, otherwise i will try to provide more info. I'm reaaally bad at OCaml but trying to learn. I'm sorry for body errors etc, first time posting here.
As far as I can understand your task, the text file contains a grid of digits with the initial disposition for sudoku. So you shouldn't interpret a line in the file as a single integer but rather as a list of integers. You can either change your read function so that it returns int list list instead of int list and then use List.fold_left over the list that will also count the position of an element in the list, but it is tedious. It is much easier to read the grid directly from the file, e.g.,
let read_matrix chan =
let rec loop i j grid =
match input_char chan with
| exception End_of_file -> grid
| '\n' -> loop (i+1) 0 grid
| '0'..'9' as c ->
loop i (j+1) ##
Vertex.add (i,j) (ascii_digit c) grid
| _ -> invalid_arg "invalid input" in
loop 0 0 Vertex.empty
where ascii_digit is defined as,
let ascii_digit c = Char.code c - Char.code '0'
The read_matrix function takes the channel as input so to read the grid from a file you can define,
let matrix_from_file file =
let chan = open_in file in
let r = read_matrix chan in
close_in chan;
r
Hint: you probably also don't want to include positions with 0 in your grid. It is easy to achieve, just add another case to the pattern in the loop function that will skip it, e.g.,
...
| '0' -> loop i (j+1) grid
...

Find all even number in array in purescript but getting type mismatch error

I am solving a problem in which I have to count all the even numbers in an array in purescript. I have written down code but I am facing type mismatch error.
import Data.Array (null)
import Data.Array.Partial (tail,head)
import Partial.Unsafe (unsafePartial)
import Math
iseven :: Int -> Boolean
iseven a = mod a 2 == 0
len :: forall a. Array a -> Int
len arr =
if null arr
then 0
else
if iseven unsafePartial head arr
then 1 + len (unsafePartial tail arr)
else len (unsafePartial tail arr)
But I am getting an error.
Error found:
in module $PSCI
at :6:18 - 6:40 (line 6, column 18 - line 6, column 40)
Could not match type
a1
with type
Int
while checking that type t0
is at least as general as type Int
while checking that expression (unsafePartial head) arr
has type Int
in binding group len
where a1 is a rigid type variable
bound at (line 0, column 0 - line 0, column 0)
t0 is an unknown type
I am new to purescript so I am not able to understand the error.
When you write unsafePartial head arr, that means "apply function unsafePartial to two arguments, first argument head and second argument arr, but this is not what you want to do.
What you want to do is first calculate head arr, and only then apply unsafePartial to the result of that.
To achieve this, use parentheses:
unsafePartial (head arr)
Or the $ operator:
unsafePartial $ head arr
After you have fixed that, the next error you're getting is about what iseven expects as argument and what you're passing to it. The signature of len says forall a. Array a ->, which means "I will work with arrays of any type", but in reality it's trying to pass an element of that array to iseven, which expects an Int. So your function promised to work with anything, but actually wants Int.
To fix, make the signature tell the truth: the function wants an array of Ints:
len :: Array Int -> Int

Automatic detection of domain for dependent type function in Idris

Idris language tutorial has simple and understandable example of the idea of Dependent Types:
http://docs.idris-lang.org/en/latest/tutorial/typesfuns.html#first-class-types
Here is the code:
isSingleton : Bool -> Type
isSingleton True = Int
isSingleton False = List Int
mkSingle : (x : Bool) -> isSingleton x
mkSingle True = 0
mkSingle False = []
sum : (single : Bool) -> isSingleton single -> Int
sum True x = x
sum False [] = 0
sum False (x :: xs) = x + sum False xs
I decided to spend more time on this example. What bothers me in sum function is that I need to explicitly pass single : Bool value to function. I don't want to do this and I want compiler to guess what this boolean value should be. Hence I pass only Int or List Int to sum function there should be 1-to-1 correspondence between boolean value and type of argument (if I pass some other type this just mustn't type check).
Of course, I understand, this is not possible in general case. Such compiler tricks require my function isSingleton (or any other similar function) be injective. But for this case it should be possible as it seems to me...
So I started with next implementation: I just made single argument implicit.
sum : {single : Bool} -> isSingleton single -> Int
sum {single = True} x = x
sum {single = False} [] = 0
sum {single = False} (x :: xs) = x + sum' {single = False} xs
Well, it doesn't really solve my problem because I still need to call this function in the next way:
sum {single=True} 1
But I read in tutorial about auto keyword. Though I don't quite understand what auto does (because I didn't find description of it) I decided to patch my function just a little bit more:
sum' : {auto single : Bool} -> isSingleton single -> Int
sum' {single = True} x = x
sum' {single = False} [] = 0
sum' {single = False} (x :: xs) = x + sum' {single = False} xs
And it works for lists!
*DepFun> :t sum'
sum' : {auto single : Bool} -> isSingleton single -> Int
*DepFun> sum' [1,2,3]
6 : Int
But doesn't work for single value :(
*DepFun> sum' 3
When checking an application of function Main.sum':
List Int is not a numeric type
Can someone explain is it actually possible to achieve my goal in such injective function usages currently? I watched this short video about proving something is injective:
https://www.youtube.com/watch?v=7Ml8u7DFgAk
But I don't understand how I can use such proofs in my example.
If this is not possible what is the best way to write such functions?
The auto keyword basically tells Idris, "Find me any value of this type". So you're liable to get the wrong answer unless that type only contains one value. Idris sees {auto x : Bool} and fills it in with any old Bool, namely False. It doesn't use its knowledge of later arguments to help it choose - information doesn't flow from right to left.
One fix would be to make the information flow in the other direction. Rather using a universe-style construction as you have above, write a function accepting an arbitrary type and use a predicate to refine it to the two options you want. This way Idris can look at the type of the preceding argument and pick the only value of IsListOrInt whose type matches.
data IsListOrInt a where
IsInt : IsListOrInt Int
IsList : IsListOrInt (List Int)
sum : a -> {auto isListOrInt : IsListOrInt a} -> Int
sum x {IsInt} = x
sum [] {IsList} = 0
sum (x :: xs) {IsList} = x + sum xs
Now, in this case the search space is small enough (two values - True and False) that Idris could feasibly explore every option in a brute-force fashion and pick the first one that results in a program which passes the type checker, but that algorithm doesn't scale well when the types are much bigger than two, or when trying to infer multiple values.
Compare the left-to-right nature of the information flow in the above example with the behaviour of regular non-auto braces, which instruct Idris to find the result in a bidirectional fashion using unification. As you note, this could only succeed when the type functions in question are injective. You could structure your input as a separate, indexed datatype, and allow Idris to look at the constructor to find b using unification.
data OneOrMany isOne where
One : Int -> OneOrMany True
Many : List Int -> OneOrMany False
sum : {b : Bool} -> OneOrMany b -> Int
sum (One x) = x
sum (Many []) = 0
sum (Many (x :: xs)) = x + sum (Many xs)
test = sum (One 3) + sum (Many [29, 43])
Predicting when the machine will or won't be able to guess what you mean is an important skill in dependently-typed programming; you'll find yourself getting better at it with more experience.
Of course, in this case it's all moot because lists already have one-or-many semantics. Write your function over plain old lists; then if you need to apply it to a single value you can just wrap it in a singleton list.

Groovy map creation, use value assigned to previous key

Is there a way to use the values assigned to the previous key in map, for eg:
def x = [
a: someList.sum(),
b: anotherList.sum(),
c: someList.sum() / anotherList.sum()
]
I want the value of 'c' to be a/b, so is there a shortcut so that I don't have to recompute the sums while computing 'c'
In order to use previously-added key/values to compute new key/values, you must be able to control the order in which the keys/values are added. I know that's obvious, but what may not be obvious is that Groovy Map declarations do not take order into account. For example, if you write this...
def x = [
a: 8,
b: 2,
c: a / b
]
..., when evaluating the expression for the value of key c, Groovy will attempt to access a variable or property named a, which will fail because the variable/property does not exist. However, you can take advantage of that property lookup and do this:
def x = [:].with {
a = 8
b = 2
c = a / b
delegate
}
You start by creating an empty Map. Then, use with(Closure) to execute putAt() and get() against the Map. The example above is the equivalent to...
def x = [:].with {
putAt('a', 8)
putAt('b', 2)
putAt('c', get('a') / get('b'))
delegate
}
Finally, return the Map itself so that it's assigned to x.

ERROR: `*` has no method matching *(::Variable)

I wrote the following code:
using JuMP
m = Model()
const A =
[ :a0 ,
:a1 ,
:a2 ]
const T = [1:5]
const U =
[
:a0 => [9 9 9 9 999],
:a1 => [11 11 11 11 11],
:a2 => [1 1 1 1 1]
]
#defVar(m, x[A,T], Bin)
#setObjective(m, Max, sum{sum{x[i,j] * U[i,j], i=A}, j=T} )
print(m)
status = solve(m)
println("Objective value: ", getObjectiveValue(m))
println("x = ", getValue(x))
When I run it I get the following error
ERROR: `*` has no method matching *(::Variable)
in anonymous at /home/username/.julia/v0.3/JuMP/src/macros.jl:71
in include at ./boot.jl:245
in include_from_node1 at loading.jl:128
in process_options at ./client.jl:285
in _start at ./client.jl:354
while loading /programs/julia-0.2.1/models/a003.jl, in expression starting on line 21
What's the correct way of doing this?
As the manual says:
There is one key restriction on the form of the expression in the second case: if there is a product between coefficients and variables, the variables must appear last. That is, Coefficient times Variable is good, but Variable times Coefficient is bad
Let me know if there is another place I could put this that would have helped you out.
This situation isn't desirable but unfortunately we haven't got a good solution yet that retains the fast model construction capabilities of JuMP.
I believe the problem with U is that it is a dictionary of arrays, thus you first need to index into the dictionary to return the correct array, then index into the array. JuMP's variables have more powerful indexing, so allow you to do it in one set of [].
I resolved my problem: constants must preceed variables as I read somewhere, moreover it seems that an array of constants must be used as an array of arrays while variables can be used as matrices.
Here's the correct line:
#setObjective(m, Max, sum{sum{U[i][j]*x[i,j], i=A}, j=T} )

Resources