.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/plot_benchmark_associative.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_plot_benchmark_associative.py: .. _l-example-associativity: Associativity and matrix multiplication ======================================= The matrix multiplication `m1 @ m2 @ m3` can be done in two different ways: `(m1 @ m2) @ m3` or `m1 @ (m2 @ m3)`. Are these two orders equivalent or is there a better order? .. contents:: :local: .. GENERATED FROM PYTHON SOURCE LINES 15-23 .. code-block:: default import pprint import numpy import matplotlib.pyplot as plt from pandas import DataFrame from tqdm import tqdm from td3a_cpp.tools import measure_time .. GENERATED FROM PYTHON SOURCE LINES 24-27 First try +++++++++ .. GENERATED FROM PYTHON SOURCE LINES 27-47 .. code-block:: default m1 = numpy.random.rand(100, 100) m2 = numpy.random.rand(100, 10) m3 = numpy.random.rand(10, 100) m = m1 @ m2 @ m3 print(m.shape) mm1 = (m1 @ m2) @ m3 mm2 = m1 @ (m2 @ m3) print(mm1.shape, mm2.shape) t1 = measure_time(lambda: (m1 @ m2) @ m3, context={}, number=100, repeat=100) pprint.pprint(t1) t2 = measure_time(lambda: m1 @ (m2 @ m3), context={}, number=100, repeat=100) pprint.pprint(t2) .. rst-class:: sphx-glr-script-out .. code-block:: none (100, 100) (100, 100) (100, 100) {'average': 0.0003212100610136986, 'context_size': 232, 'deviation': 3.68551974980911e-07, 'max_exec': 0.0003237356524914503, 'min_exec': 0.0003209231933578849, 'number': 100, 'repeat': 100} {'average': 0.0003866767174098639, 'context_size': 232, 'deviation': 1.337162285443633e-06, 'max_exec': 0.0003964086202904582, 'min_exec': 0.0003854487417265773, 'number': 100, 'repeat': 100} .. GENERATED FROM PYTHON SOURCE LINES 48-50 With different sizes ++++++++++++++++++++ .. GENERATED FROM PYTHON SOURCE LINES 50-73 .. code-block:: default obs = [] for i in tqdm([50, 100, 125, 150, 175, 200]): m1 = numpy.random.rand(i, i) m2 = numpy.random.rand(i, 10) m3 = numpy.random.rand(10, i) t1 = measure_time(lambda: (m1 @ m2) @ m3, context={}, number=100, repeat=100) t1['formula'] = "(m1 @ m2) @ m3" t1['size'] = i obs.append(t1) t2 = measure_time(lambda: m1 @ (m2 @ m3), context={}, number=100, repeat=100) t2['formula'] = "m1 @ (m2 @ m3)" t2['size'] = i obs.append(t2) df = DataFrame(obs) piv = df.pivot(index="size", columns="formula", values="average") piv .. rst-class:: sphx-glr-script-out .. code-block:: none 0%| | 0/6 [00:00
formula (m1 @ m2) @ m3 m1 @ (m2 @ m3)
size
50 0.000114 0.000230
100 0.000321 0.000386
125 0.000479 0.000633
150 0.000668 0.000941
175 0.000267 0.000988
200 0.000316 0.001391


.. GENERATED FROM PYTHON SOURCE LINES 74-76 Graph +++++ .. GENERATED FROM PYTHON SOURCE LINES 76-85 .. code-block:: default fig, ax = plt.subplots(1, 2, figsize=(12, 4)) piv.plot(logx=True, logy=True, ax=ax[0], title=f"{m1.shape!r} @ {m2.shape!r} @ " f"{m3.shape!r}".replace("200", "size")) piv["ratio"] = piv["m1 @ (m2 @ m3)"] / piv["(m1 @ m2) @ m3"] piv[['ratio']].plot(ax=ax[1]) plt.show() .. image-sg:: /auto_examples/images/sphx_glr_plot_benchmark_associative_001.png :alt: (size, size) @ (size, 10) @ (10, size) :srcset: /auto_examples/images/sphx_glr_plot_benchmark_associative_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 1 minutes 15.997 seconds) .. _sphx_glr_download_auto_examples_plot_benchmark_associative.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_benchmark_associative.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_benchmark_associative.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_