pyret-lang
pyret-lang copied to clipboard
Matrix Library Pull Request
Hi,
As was requested by the core Pyret team, William Sun and I wrote this library containing core linear algebra features.
What The Library Does :
- Core Linear Algebra Functions (Inverse , Determinant , Orthogonalization)
- Manipulate matrices and vectors
- An advantage of Pyret's number system is that Inverse(A) * A = Identity.
What The Library Does Not Do :
- Handle Complex Numbers, Tensors
- More Complex Linear Algebra / any sort of statistical functions (Eigenvalues ... )
Setup
- There are two datatypes Matrix and Vector . A Matrix is a nxn 2D array of numbers while a vector is equivalent to an array of numbers
- Representation wise both matrices and vectors are a 1D Javascript Array. These are then appropriately wrapped to create Pyret objects
- You create a matrix by :
[mat(2,2):12,4,5,6]and a vector by[vector(3):1,3,-42] - Generally all operations are functions. However basic arithmetic (+,-,*) are available as methods along with element access. These are also available as functions.
Naming Conventions
- Most functions are of the form
func-matsuch asrref-mat. However some functions are given by just their name.
Phillip Blair's Library A few years ago Phillip Blair wrote a matrix library (https://github.com/brownplt/pyret-lang/blob/8bf1d79c283d50a04daae1d3e4a7682e606c1c02/src/arr/trove/matrices.arr). Ours is equivalent , the critical difference being that it is Javascript rather than Pyret. You can find the modern version of Phillip's library compliant with 2021 (https://code.pyret.org/editor#share=1_UVB6S9ad3F9KRcrdNx3yrUyAw-rGdfo&v=1599623)
This makes a huge performance difference. The Pyret version times out for matrices as small as 50x50 (takes > 5mins) whereas the Javascript version (ours) does not show any lag.
Issues To Address Before Adding
- Mapping functions such as
build-matusesafeCalls to avoid blowing up the stack. However Pyret decides at some time to just halt the computation. So : - build-mat(30,30,lam(i,j): (3 + i) / (5 + j ) end) (Building a 30x30 matrix) works fine
- build-mat(40,40,lam(i,j): (3 + i) / (5 + j ) end) (Building a 40x40 matrix) returns [mat(40,40): ]
I'm unsure as to how to solve this while still keeping these functions safe.
Other Things To Address
-
Right now matrix output is displayed as a 1d List

-
Matrices are keeping with Pyret principles immutable. Is a mutable version required or should matrices be by default mutable .
Anirudh Narsipur
I've addressed all comments and increased test coverage. There are still 2 issues :
build-mat(100,100,lam(i,j): i + j end)times out. I think I've wrapped it in safeCalls appropriately as suggested.- I chunked up multiplication which works for the most part. However it's creating some strange behaviour in
exp-matwhich raises a matrix to a power by repeatedly multiplying it ( line 873):
res = duplicateMatrix(self);
for (i = 1; i < n; i++) {
res = multMatrix(res, self);
}
Calling exp-mat(a,3) for a = [mat(2,2):1,~4,-5,6.53] results in a roughnum overflow error. For some reason the loop instead of running just twice runs dozens of times and causes this error.
Addressed both comments and made similar fix in map-mat. I've left the other multMatrix calls unchanged for now but my understanding is that each of them need to individually wrapped but where does this end ? If I have f calling multMatrix and g calling f . Do both g and f now need to be wrapped in safeCalls?