# A function which performs multiple steps

I'm trying to figure out how I can define a function which takes an input, performs an operation on it, then produces a table from the result. For example, I have a function Msum[x_] which takes a list of values x and produces a $2N \times 2N$ matrix (where $N$ is fixed). I want to define a new function f[x_] which computes the matrix from Msum[x] and returns a list of the sums of pairs of diagonal elements. For example, I could do

f[x_]:=Table[m = Msum[x]; m[[i,i]] + m[[i+1,i+1]] , {i,1,2N-1,2}]

But obviously this is not ideal, because I will recompute the same matrix $N$ times. Is there a way I can define a single function which computes the matrix once then produces the table? Is there a general way to write a single function which encompasses multiple steps like in a regular programming language?

• Look at Module or Block, or for this specific case something like f[x_] := (m = Msum[x]; Table[m[[i]] + m[[i + 1]], {i, 1, 2 N - 1, 2}]) – bill s Feb 4 '18 at 5:23
• Thank you, I had no idea I could do that, although I assumed there must be a way – Kai Feb 4 '18 at 5:25
• I can't find any documentation on the ( ) notation, any references? – Kai Feb 4 '18 at 5:28
• It' s actually the ; that means CompoundExpression. The parentheses just control grouping. The default grouping is (f[x_] := m = Msum[x]); Table[m[[i]] + m[[i + 1]], {i, 1, 2 N - 1, 2}] – Carl Woll Feb 4 '18 at 6:26
• Ah that makes sense, thank you, I didn't know I could use parentheses outside of mathematical expressions, this is extremely useful to know – Kai Feb 4 '18 at 7:28

There are several constructs that can be used here, but it seems like the best for this construction would be With:

f[x_] := With[{m = Msum[x]}, Table[m[[i, i]] + m[[i + 1, i + 1]], {i, 1, 2 N - 1, 2}]]


With allows you to locally define constant values to be used inside of it, and since presumable Msum[x] is in fact constant for any evaluation of x, this makes it ideal.

Block and Module are similar constructs that have uses when you need to be able to change the value of the local variable. This is useful for temporary variables or other values which will change during evaluation, such as accumulator variables in loops. See the documentation and this answer for more information on them.

As mentioned by bill s and Carl Woll in the comments, you can also use CompoundExpression (;), but be aware that this provides no scope control by itself. Thus, this kind of construction:

f[x_] := (m = Msum[x]; Table[m[[i]] + m[[i + 1]], {i, 1, 2 N - 1, 2}])


While perfectly effective, may interfere with other uses of m in your code. It may not, and it may be fine, but you should take it into consideration.

For the sake of understanding what's going on with the parentheses in that last example, note that () is being used in exactly the same sense that it would be used in a mathematical expression. That is, the parentheses are overriding the ordinary operator precedence rules. Ordinarily, Mathematica would split the expression around ; before considering :=, but by using the parentheses you can force the := to be established first and take the whole compound expression as its right hand side.

One other possibility is to simply chain the functions together:

f[x_] := Table[#[[i,i]] + #[[i+1,i+1]], {i,1,2 N - 1, 2}] & [Msum[x]]


This constructs a function which takes x as the argument, calculates Msum[x], and passes it inside into a function which calculates the requested Table. At this point it's equally simple to just create f such that you'll always use it in conjunction with Msum though.

• Thanks for the clarification about () vs With[], that's good to know. By the way what is the technical name of the # and & symbols in the context of Mathematica? I know how to use them for basic purposes but I have trouble finding documentation about them. – Kai Feb 13 '18 at 19:21
• @Kai # (or #1, #2, etc if there are multiple) is the argument of an anonymous function. & ends an anonymous function. For example, #^2& is another way of writing Function[{x},x^2], which is similar (though not precisely identical) to writing f[x_] := x^2. – eyorble Feb 13 '18 at 22:18