5
$\begingroup$

Here's a simple example. Suppose we want to find the off-diagonal matrix of m:

m={{1,2},{3,4}}

This can be solved fairly simply by extracting a list of the diagonal elements, re-creating the diagonal matrix from these, and removing them from the full matrix to get the off-diagonal elements:

m - DiagonalMatrix[Diagonal[m]]  

to get

{{0,2},{3,0}}

Now, this was a fairly simple solution to the given problem, but what I'm wondering is if there is a way to write something akin to

(Identity - DiagonalMatrix@Diagonal)[m]  

To get the same result. In this simple example, not much would be gained by doing this, but I just thought it could be interesting in more complicated problems and help make the code resemble more closely the underlying mathematics in some cases.

$\endgroup$
14
  • 1
    $\begingroup$ # - DiagonalMatrix[Diagonal[#]] &[m] ? Of course you can add Identity[#] at the beginning. $\endgroup$
    – Kuba
    Commented Feb 18, 2014 at 20:39
  • 4
    $\begingroup$ Also look at Composition for chaining long functions. It will greatly improve the clarity of your code. $\endgroup$
    – rm -rf
    Commented Feb 18, 2014 at 20:45
  • 6
    $\begingroup$ You should look at Through too, e.g. Through[(f + g + h)[x]] gives f[x] + g[x] + h[x]. $\endgroup$ Commented Feb 18, 2014 at 21:32
  • 1
    $\begingroup$ @Steve It doesn't work for two reasons: @ doesn't denote function composition, but function application (use Composition for function composition) and because Through only goes in one level while here we actually have an expression of the form (a + (-1)*b), not of a simpler form a-b. I'm afraid there's no easy and simple solution to your problem other than building pure functions as in (Identity[#] - DiagonalMatrix@Diagonal[#]) &[m]. $\endgroup$
    – Szabolcs
    Commented Feb 18, 2014 at 22:42
  • 2
    $\begingroup$ Following Rojo's idea, you can do operatorApply[f_[x__]] := Replace[f, s_Symbol :> s[x], {0, Infinity}, Heads -> False]. See where this goes wrong: operatorApply[(Sin + 1)[x]] transforms to Sin[x]+1, all is fine. Now what about operatorApply[(Sin + Pi)[x]]? You get Pi[x] + Sin[x], wrong! This is probably why it's not a built-in function. I don't see a good way around this problem, i.e. it's not a problem with my implementation but an inherent problem to the idea: it's not possible to distinguish functions from other symbols, e.g. constants. $\endgroup$
    – Szabolcs
    Commented Feb 18, 2014 at 23:35

1 Answer 1

0
$\begingroup$

In version 10 we can use the new shorthand notation for Composition to write

Through@(Identity + Minus@*DiagonalMatrix@*Diagonal)[m]

(* {{0, 2}, {3, 0}} *)

As noted in the comments, Through@(a - b)[x] won't work the way we'd like because a - b is represented internally as a + (-1)*b. Composing with Minus gets around this problem.

$\endgroup$

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