In a question about improving performance of a TensorContract of a TensorProduct, user jose suggested replacing

TensorContract[TensorProduct[A, B], {{2, 5}, {4, 6}}]


Activate @ TensorContract[Inactive[TensorProduct][A, B], {{2, 5}, {4, 6}}]

where e.g. for a minimal example:

n = 10;
A = RandomReal[1, {n, n, n, n}];
B = RandomReal[1, {n, n}];

Using this example, the version with Inactivate/Activate is about 30 times faster (according to RepeatedTiming) and uses about 200 times less memory (according to MaxMemoryUsed).

Obviously Mathematica uses some special algorithm to contract the two tensors without actually constructing the whole tensor product.

Now my questions is:

When does using Activate and Inactivate improve performance as drastically as above? How could I've known that using Activate and Inactivate lets Mathematica use more powerful tools? I'm looking for examples, heuristics or hidden Documentation.

  • $\begingroup$ Everywhere where deeper evaluations are heavy but will not affect the result. Activate@Length@{Inactive[Pause][5]} $\endgroup$
    – Kuba
    Commented Sep 8, 2016 at 9:56
  • $\begingroup$ Thanks @Kuba, that seems a good heuristic although it fails for e.g. Activate@Part[Inactive[RandomReal][{0,1},10^9],1;;10] where I would've expected only the first 10 elements to be generated. $\endgroup$
    – AndreasP
    Commented Sep 8, 2016 at 10:03
  • 1
    $\begingroup$ Maybe I should improve the wording but Part[Inactive[RandomReal][{0, 1}, 10^9], 1 ;; 10] doesn't make sense while Length@{Inactive[Pause][5]} does. $\endgroup$
    – Kuba
    Commented Sep 8, 2016 at 10:15
  • $\begingroup$ @kuba, my assumption was that Part[Inactive[RandomReal[{0,1},10^9],1;;10] create the "promise of a list" and then just take the first 10 elements and actually evaluate them, similar to lazy behaviour in e.g. haskell. If you have a moment I would appreciate a short answer with a few examples if you can think of any. $\endgroup$
    – AndreasP
    Commented Sep 9, 2016 at 7:39
  • $\begingroup$ I see, I'm afraid that concept doesn't exist in WL but something similar happens for Datasets querying: 85363 $\endgroup$
    – Kuba
    Commented Sep 9, 2016 at 7:47


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.