pyret-lang icon indicating copy to clipboard operation
pyret-lang copied to clipboard

Matrix Library Pull Request

Open AnirudhNarsipur opened this issue 4 years ago • 2 comments

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 formfunc-matsuch as rref-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-mat use safeCalls 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 Screen Shot 2021-06-12 at 11 47 22 PM

  • Matrices are keeping with Pyret principles immutable. Is a mutable version required or should matrices be by default mutable .

Anirudh Narsipur

AnirudhNarsipur avatar Jun 13 '21 03:06 AnirudhNarsipur

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-mat which 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.

AnirudhNarsipur avatar Jun 13 '21 23:06 AnirudhNarsipur

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?

AnirudhNarsipur avatar Jun 15 '21 05:06 AnirudhNarsipur