|
1 | 1 | # MatrixChainMultiply |
2 | 2 |
|
3 | 3 | [](https://travis-ci.org/AustinPrivett/MatrixChainMultiply.jl) |
4 | | - |
5 | 4 | [](https://ci.appveyor.com/project/AustinPrivett/matrixchainmultiply-jl) |
6 | | - |
7 | 5 | [](https://coveralls.io/github/AustinPrivett/MatrixChainMultiply.jl?branch=master) |
8 | 6 |
|
9 | 7 | The cost of multiplying a chain of matrices can vary significantly depending on the order in which the multiplication steps are applied. The [Matrix chain multiplication](https://www.wikiwand.com/en/Matrix_chain_multiplication) algorithm applied here (described in *Introduction to Algorithms, 3rd Edition* by Cormen et al.) finds the optimal multiplication sequence. |
| 8 | + |
| 9 | +With Julia, it is easy to allow for specialization on the matrix types. |
| 10 | +For example, the types given in the ArrayFire.jl package should work here, too. |
| 11 | + |
| 12 | +## Installing this Package |
| 13 | + |
| 14 | +Since this package is not registered, you must install it by cloning. To add this package, use: |
| 15 | + |
| 16 | +```julia |
| 17 | +Pkg.clone("https://github.com/AustinPrivett/MatrixChainMultiply.jl") |
| 18 | +``` |
| 19 | + |
| 20 | +## Using this Package |
| 21 | + |
| 22 | +The only function most users should need is `matrixchainmultiply`, |
| 23 | +added to the scope by writing: |
| 24 | + |
| 25 | +```julia |
| 26 | +using MatrixChainMultiply |
| 27 | + |
| 28 | +a = rand(1000) |
| 29 | +b = rand(1000,20) |
| 30 | +c = rand(20,4500) |
| 31 | +d = rand(4500) |
| 32 | +e = 29.3 / 380.2 |
| 33 | + |
| 34 | +result1 = matrixchainmultiply(a',b,c,d,e; printout=true) |
| 35 | +result2 = *(a',b,c,d,e) |
| 36 | +``` |
| 37 | + |
| 38 | +Note that the optional keyword argument `printout=true` prints out the |
| 39 | +optimal multiplication order and the number of FLOPS in case you want |
| 40 | +to investigate. It is `false` by default. |
| 41 | + |
| 42 | +To test this package and see an example speedup on your system, |
| 43 | + |
| 44 | +```julia |
| 45 | +Pkg.test("MatrixChainMultiply") |
| 46 | +``` |
| 47 | + |
| 48 | +On my system, the `matrixchainmultiply(...)` generates results |
| 49 | +**~17.4 times faster** than the standard Julia `*(...)` function (which |
| 50 | +evaluates left-to-right instead of optimally). It is certainly |
| 51 | +possible to see speedups of one or two orders of magnitude through the |
| 52 | +use of the optimal operation order generated here. |
| 53 | + |
| 54 | +## When to use this |
| 55 | + |
| 56 | +If all matrices are the same size, the overhead of the optimization is |
| 57 | +not worth the (non-existing) benefit. |
| 58 | + |
| 59 | +## Further improvements to be made |
| 60 | + |
| 61 | +* Recognize situations that don't need the analysis to eliminate the |
| 62 | +overhead (allowing for a more ubiquitous use of `matrixchainmultiply(...)` |
| 63 | +instead of `*(...)`). |
| 64 | +* For repeated uses, given some matrix size sequence, produce the |
| 65 | +function a single time so that the analysis isn't done unnecessarily. |
0 commit comments