Suppose I have a list of Matrices saved in the variable G
and apply the following operations:
top[g_] = Minors[g]
Diagonal[top /@ G]
Minors
returns a matrix where each element is the determinant with the (i,j) row/col deleted, and Diagonal
returns a list of the diagonal elements of a matrix.
My question is on the evaluation of these commands - clearly I do not want all entries evaluated. Is Mathematica lazy in the sense that Diagonal is parsed first which only extracts the elements needed from Minors or is the minor matrix constructed and then its diagonal elements are pulled out?
This is a general question for lazy evaluation, however being new to Mathematica I would appreciate any tips on how to improve the syntax for the specific problem.
See Why Functional Programming Matters on the benefit of the lazy evaluation. Haskell is well recognized as a programming language that totally adopts lazy evaluation. Scheme also adopts it (even the adoption is partially).
The benefits of lazy evaluation include: The ability to define control flow (structures) as abstractions instead of primitives. The ability to define potentially infinite data structures. This allows for more straightforward implementation of some algorithms.
Lazy evaluation or call-by-need is a evaluation strategy where an expression isn't evaluated until its first use i.e to postpone the evaluation till its demanded. Functional programming languages like Haskell use this strategy extensively.
To implement lazy evaluation in our interpreter we need to modify the applica- tion expression evaluation rule to delay evaluating the operand expressions until they are needed. To do this, we introduce a new datatype known as a thunk. We define a Python class, Thunk for representing thunks.
It's late so only a short answer: investigate Hold[]
and its relatives. With them you can implement lazy evaluating functions. Most intrinsic Mathematica functions are not lazy, a few are. In general, as a beginner, you should avoid modifying the behaviour of Mathematica's intrinsic functions, though it is very good fun to do so and can very easily make the entire system unusable.
You can solve this problem by building up the list of diagonal minors by yourself and then applying Det
, for a matrix M
:
Map[Det,Drop[Transpose[Drop[M,{#}]],{#}]& /@ Range[1,Dimensions[M][[1]]]]
This is a bit of a cludge but it is about 50 times faster than using Mathematica's built in Minors
and picking off just the diagonal elements (tested on 100x100 random matrices).
No mathematica is not lazy in general.
top/@G
Will produce a matrix that Diagonal will operate on. Since Minors does not operate on individual elements of the matrix, what you are asking for is not, from my knowledge, just lazy evaluation either.
I think I have a solution for you though.
Clear[f];
Diagonal[Minors[G,Length[G],f]]/.f->Det
This solution will only produce the Minors of the Diagonal elements to be summed by Diagonal. But I have only moved the excess computation to an excess memory usage problem. Since the submatrix of off diagonal elements is still produced only to be thrown away. I will post again if I think of a way to prevent that as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With