Return a np.array that encodes the optimal order of mutiplications. The optimal order array is then used by `_multi_dot()` to do the multiplication. Also return the cost matrix if `return_costs` is `True` The implementation CLOSELY follows Cormen, "Introduction to Algorithms"
(arrays, return_costs=False)
| 2783 | |
| 2784 | |
| 2785 | def _multi_dot_matrix_chain_order(arrays, return_costs=False): |
| 2786 | """ |
| 2787 | Return a np.array that encodes the optimal order of mutiplications. |
| 2788 | |
| 2789 | The optimal order array is then used by `_multi_dot()` to do the |
| 2790 | multiplication. |
| 2791 | |
| 2792 | Also return the cost matrix if `return_costs` is `True` |
| 2793 | |
| 2794 | The implementation CLOSELY follows Cormen, "Introduction to Algorithms", |
| 2795 | Chapter 15.2, p. 370-378. Note that Cormen uses 1-based indices. |
| 2796 | |
| 2797 | cost[i, j] = min([ |
| 2798 | cost[prefix] + cost[suffix] + cost_mult(prefix, suffix) |
| 2799 | for k in range(i, j)]) |
| 2800 | |
| 2801 | """ |
| 2802 | n = len(arrays) |
| 2803 | # p stores the dimensions of the matrices |
| 2804 | # Example for p: A_{10x100}, B_{100x5}, C_{5x50} --> p = [10, 100, 5, 50] |
| 2805 | p = [a.shape[0] for a in arrays] + [arrays[-1].shape[1]] |
| 2806 | # m is a matrix of costs of the subproblems |
| 2807 | # m[i,j]: min number of scalar multiplications needed to compute A_{i..j} |
| 2808 | m = zeros((n, n), dtype=double) |
| 2809 | # s is the actual ordering |
| 2810 | # s[i, j] is the value of k at which we split the product A_i..A_j |
| 2811 | s = empty((n, n), dtype=intp) |
| 2812 | |
| 2813 | for l in range(1, n): |
| 2814 | for i in range(n - l): |
| 2815 | j = i + l |
| 2816 | m[i, j] = Inf |
| 2817 | for k in range(i, j): |
| 2818 | q = m[i, k] + m[k+1, j] + p[i]*p[k+1]*p[j+1] |
| 2819 | if q < m[i, j]: |
| 2820 | m[i, j] = q |
| 2821 | s[i, j] = k # Note that Cormen uses 1-based index |
| 2822 | |
| 2823 | return (s, m) if return_costs else s |
| 2824 | |
| 2825 | |
| 2826 | def _multi_dot(arrays, order, i, j, out=None): |