I am performing comparisons to generate a similarity matrix. The comparisons in the upper triangle matrix are the inverse of the ones in the lower triangle matrix but they result in the same value. My actual code is much more complicated than that shown below but the example code below demonstrates the point.

inmatrix = {{1}, {2}, {3}, {4}};
multifunc = Function[x, Abs[Part[x, 1] - Part[x, 2]]];
comparisons = Tuples[inmatrix, 2];
outmatrix = Map[multifunc, comparisons]
outmatrix2 = Partition[outmatrix, 4]

This results in the matrix: enter image description here

There is no need to calculate both the lower and upper triangle matrix because the values are redundant. Is there a simple way to calculate only the upper or lower triangle matrix?

  • $\begingroup$ Have you looked st DistanceMatrix? You can specify your own DistanceFunction. $\endgroup$
    – bill s
    Commented Apr 30, 2020 at 12:51

2 Answers 2


One possible solution is with Subsets.

These are the items that you wish to compute a distance between. Let the distance function be distFun.

The indices of the upper triangular part are Subsets[Range@Length[items], {2}]

The matrix can be obtained as

  # -> distFun @@ Part[items, #] & /@ Subsets[Range@Length[items], {2}]

This would make sense if distFun takes long to evaluate.


Giving your distance function the Orderless attribute and applying memoization you make sure that the function will be only called for one triangular side of the matrix (and the diagonal). You can use Outer to create the matrix.

multifunc[x_, y_] := multifunc[x, y] = Abs[x - y];
SetAttributes[multifunc, Orderless]

inmatrix = {1, 2, 3, 4};
(comparisons = Outer[multifunc, inmatrix, inmatrix, 1] )//MatrixForm

enter image description here


Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.