|
1 |
| -# Matrix Stitcher (under development) |
| 1 | +# Matrix Stitcher |
2 | 2 |
|
3 |
| -A numpy wrapper for learning matrix analysis that combines the advantage of eager and lazy execution. It runs dynamically and automatically tracks your elementary transformations applied on the origin matrix. |
| 3 | +A numpy wrapper for learning matrix analysis that combines the advantage of eager and lazy execution. It runs dynamically and automatically tracks your transformations applied on the origin matrix. |
4 | 4 |
|
5 | 5 | - Intuitive implementation for educational purposes
|
6 | 6 | - Index from 1 which is consistent with the mathematical declaration
|
7 |
| -- Dynamicaly track the elementary transformations applied on the orgin matrix |
8 |
| -- Easily extend your operations |
| 7 | +- Dynamicaly track the transformations applied on the orgin matrix |
| 8 | +- Easily extend your transforms and methods |
9 | 9 |
|
10 | 10 | ## Quick Guide
|
11 | 11 | ```python
|
12 | 12 | import matrixstitcher as mats
|
13 |
| -from matrixstitcher.transform import LUFactorization |
| 13 | +from matrixstitcher.method import LUFactorization |
14 | 14 |
|
15 | 15 | # you can define matrix using int, float, list,
|
16 | 16 | # tuple and numpy array
|
17 |
| -A = [[1, 2, -3, 4], |
18 |
| - [4, 8, 12, -8], |
19 |
| - [2, 3, 2, 1], |
20 |
| - [-3, -1, 1, -4]] |
| 17 | +A = [[1, 2, -3], |
| 18 | + [4, 8, 12], |
| 19 | + [2, 3, 2]] |
21 | 20 |
|
22 | 21 | A = mats.Matrix(A) # get the matrix object from MatrixStitcher
|
23 |
| -P, L, U = LUFactorization()(A) # apply LU Factorization on matrix A and get the results |
| 22 | +P, L, U = LUFactorization()(A) # apply LU Factorization on matrix A and get the factorization results |
24 | 23 |
|
25 |
| -# show the transformations applied on the matrix A |
| 24 | +# show the execution state of the matrix A |
26 | 25 | print('Execution Path:')
|
27 | 26 | result = A.forward(display=True)
|
28 | 27 | ```
|
29 | 28 | Here is the execution result:
|
30 | 29 | ```
|
31 | 30 | Execution Path:
|
32 |
| -
|
33 | 31 | -> Origin matrix:
|
34 |
| -array([[ 1., 2., -3., 4.], |
35 |
| - [ 4., 8., 12., -8.], |
36 |
| - [ 2., 3., 2., 1.], |
37 |
| - [-3., -1., 1., -4.]]) |
| 32 | +array([[ 1., 2., -3.], |
| 33 | + [ 4., 8., 12.], |
| 34 | + [ 2., 3., 2.]]) |
38 | 35 |
|
39 | 36 | -> Stage 1, RowTransform(1, -4.0, 2):
|
40 |
| -array([[ 1., 2., -3., 4.], |
41 |
| - [ 0., 0., 24., -24.], |
42 |
| - [ 2., 3., 2., 1.], |
43 |
| - [ -3., -1., 1., -4.]]) |
| 37 | +array([[ 1., 2., -3.], |
| 38 | + [ 0., 0., 24.], |
| 39 | + [ 2., 3., 2.]]) |
44 | 40 |
|
45 | 41 | -> Stage 2, RowTransform(1, -2.0, 3):
|
46 |
| -array([[ 1., 2., -3., 4.], |
47 |
| - [ 0., 0., 24., -24.], |
48 |
| - [ 0., -1., 8., -7.], |
49 |
| - [ -3., -1., 1., -4.]]) |
50 |
| -
|
51 |
| --> Stage 3, RowTransform(1, 3.0, 4): |
52 |
| -array([[ 1., 2., -3., 4.], |
53 |
| - [ 0., 0., 24., -24.], |
54 |
| - [ 0., -1., 8., -7.], |
55 |
| - [ 0., 5., -8., 8.]]) |
56 |
| -
|
57 |
| --> Stage 4, RowSwap(2, 3): |
58 |
| -array([[ 1., 2., -3., 4.], |
59 |
| - [ 0., -1., 8., -7.], |
60 |
| - [ 0., 0., 24., -24.], |
61 |
| - [ 0., 5., -8., 8.]]) |
62 |
| -
|
63 |
| --> Stage 5, RowTransform(2, 5.0, 4): |
64 |
| -array([[ 1., 2., -3., 4.], |
65 |
| - [ 0., -1., 8., -7.], |
66 |
| - [ 0., 0., 24., -24.], |
67 |
| - [ 0., 0., 32., -27.]]) |
68 |
| -
|
69 |
| --> Stage 6, RowTransform(3, -1.3333333333333333, 4): |
70 |
| -array([[ 1., 2., -3., 4.], |
71 |
| - [ 0., -1., 8., -7.], |
72 |
| - [ 0., 0., 24., -24.], |
73 |
| - [ 0., 0., 0., 5.]]) |
| 42 | +array([[ 1., 2., -3.], |
| 43 | + [ 0., 0., 24.], |
| 44 | + [ 0., -1., 8.]]) |
| 45 | +
|
| 46 | +-> Stage 3, RowSwap('i=2', 'j=3'): |
| 47 | +array([[ 1., 2., -3.], |
| 48 | + [ 0., -1., 8.], |
| 49 | + [ 0., 0., 24.]]) |
| 50 | +
|
| 51 | +-> Stage 4, RowTransform(2, 0.0, 3): |
| 52 | +array([[ 1., 2., -3.], |
| 53 | + [ 0., -1., 8.], |
| 54 | + [ 0., 0., 24.]]) |
| 55 | +``` |
| 56 | + |
| 57 | +If you don't want to track the transformations, `no_tape()` would be helpful. |
| 58 | +```python |
| 59 | +import matrixstitcher as mats |
| 60 | + |
| 61 | +# construct data ... |
| 62 | + |
| 63 | +with mats.no_tape(): |
| 64 | + P, L, U = LUFactorization()(A) |
| 65 | + |
| 66 | +A.forward(display=True) |
| 67 | + |
| 68 | +# Output |
| 69 | +# Execution Path: |
| 70 | +# -> Origin matrix: |
| 71 | +# array([[ 1., 2., -3.], |
| 72 | +# [ 4., 8., 12.], |
| 73 | +# [ 2., 3., 2.]]) |
74 | 74 | ```
|
| 75 | +You can also get the correct factorization results P, L, U. But the transformations would not be recorded into A's tape history. |
| 76 | + |
| 77 | +## Extend Transform and Method |
| 78 | + |
| 79 | +You can esaily extend your transform and method. Here are two simple examples. |
| 80 | +```python |
| 81 | +import numpy as np |
| 82 | +import matrixstitcher.transform as T |
| 83 | +from matrixstitcher.method import Method |
| 84 | +from matrixstitcher.transform import Tranform |
| 85 | + |
| 86 | + |
| 87 | +class LeastSquareTech(Method): |
| 88 | + def __init__(self): |
| 89 | + ''' |
| 90 | + A `Method` can be seen as a container of several |
| 91 | + `Transform`s |
| 92 | + ''' |
| 93 | + super().__init__() |
| 94 | + self.tape = False # setting whether the transformations |
| 95 | + # used under this method would be tracked |
| 96 | + self.parameter = None |
| 97 | + self.error = None |
| 98 | + |
| 99 | + def perform(self, X, y): # you must finish `perform` function |
| 100 | + self.parameter = T.Inverse()(X.T() * X) * X.T() * y |
| 101 | + self.error = (self.predict(X) - y).T() * (self.predict(X) - y) |
| 102 | + return self.parameter, self.error |
| 103 | + |
| 104 | + def predict(self, X): |
| 105 | + return X * self.parameter |
| 106 | + |
| 107 | + |
| 108 | +class Rank(Transform): |
| 109 | + def __init__(self, *args, **kwargs): |
| 110 | + ''' |
| 111 | + In order to represent your transoform correctly, you must |
| 112 | + tell the base object parameters you have used. |
| 113 | + ''' |
| 114 | + super().__init__(*args, **kwargs) |
| 115 | + |
| 116 | + def perform(self, matrix): # you must finish `perform` function |
| 117 | + return np.linalg.matrix_rank(matrix.matrix) |
| 118 | +``` |
0 commit comments