There are similar questions to this on the forum but none fit the purpose here:

I would like to extract certain elements of a matrix depending on whether a factor is present or not, and create another matrix of the same size with those elements and zeros everywhere else. For example, given

\begin{equation} \left [ \begin{array}{c c} a x & b x^2 \\ c y & d y^2 \end{array} \right ] \end{equation}

I would like to create a new matrix with just the elements that have $x^2$ as a member and zeros everywhere else.

\begin{equation} \left [ \begin{array}{c c} 0 & b x^2 \\ 0 & 0 \end{array} \right ] \end{equation}

I've tried variants of things like this but can't get it to work

SIGMA = {{ a x , b x^2},{c y , d y^2}};

SIGMAx2 = Select[SIGMA , MemberQ[#, x^2] &];

Using Replace (assuming you only want to replace on level 2, as you mention "matrix"):

Using Except

My first version (I kept this version to point out the usage/impact of Orderless)

Replace[SIGMA, Except[HoldPattern[___ x^2 ___]] -> 0, {2}]

{{0, b x^2}, {0, 0}}

Improved version, thanks to Leonid

Replace[SIGMA, Except[___ x^2] -> 0, {2}]

as he explains below, this can be done since Times is Orderless.

Version using FreeQ

Thanks to @ssch, we have a similar version, which is more general:

Replace[SIGMA, a_ /; FreeQ[a, x^2] -> 0, {2}]
  • $\begingroup$ (it should be fine now, I forgot the HoldPattern. Please let me know if it isn't) $\endgroup$ – Pinguin Dirk Sep 18 '13 at 14:07
  • 3
    $\begingroup$ +1. Note that Times is Orderless, therefore you don't need two blanks. This in turn allows to ditch HoldPattern, so that you could just use: Replace[SIGMA, Except[___ x^2 ] -> 0, {2}]. $\endgroup$ – Leonid Shifrin Sep 18 '13 at 14:40
  • $\begingroup$ ah, I had it that way in the beginning - then I added the second blank (obviously not thinking of Orderless) which screwed things up (I looked at Trace and couldn't make sense of it). Introducing HoldPattern solved it then (with the 2 blanks) (hence my first commend above). Thanks for pointing that out, @LeonidShifrin $\endgroup$ – Pinguin Dirk Sep 18 '13 at 14:45
  • $\begingroup$ No problem at all. This is a minor issue anyway. $\endgroup$ – Leonid Shifrin Sep 18 '13 at 14:48
  • 4
    $\begingroup$ To work for more than Times you can use Replace[m, a_ /; FreeQ[a, x^2] -> 0, {2}] $\endgroup$ – ssch Sep 18 '13 at 15:46

For polynomials:

x^2 Coefficient[SIGMA, x, 2]
{{0, b x^2}, {0, 0}}

$\left[ \begin{array}{cc} 0 & b x^2 \\ 0 & 0 \end{array} \right]$


Maybe something like this:

    If[Length@Cases[#, x^2, Infinity] > 0, #, 0] &,
{{0, b x^2}, {0, 0}}

This solution will work with more complex patterns than Times too.

  • 1
    $\begingroup$ It would be shorter to use FreeQ as by default that function uses a levelspec of {0, Infinity}: Map[If[FreeQ[#, x^2], 0, #] &, SIGMA, {2}] $\endgroup$ – Mr.Wizard Sep 18 '13 at 19:47
  • $\begingroup$ @Mr.Wizard of course, not many solutions would be worse than this :P I just was to hasty and then had a bus. After that, the battle was over :P $\endgroup$ – Kuba Sep 18 '13 at 19:55
  • $\begingroup$ Kuba the basic idea is sound, though Replace is a bit cleaner. I'd personally like to see you include the FreeQ form in your answer; I think you'd have arrived at it too given a bit more time to think about it. $\endgroup$ – Mr.Wizard Sep 18 '13 at 19:57
SIGMAx2 = Map[If[MemberQ[#, x^2, Infinity], #, 0] &, SIGMA, {2}]
{{0, b x^2}, {0, 0}}

Assuming your list as A

 Table[If[(SameQ[A[[i, j]], #]) & /@ Cases[A, _*x^2, Infinity] /. 
       List -> Or, A[[i, j]], 0], {i, Length[A]}, {j, 1, Length[A[[i]]]}]

{{0, b x^2}, {0, 0}}

In case you have more terms matching criteria than it will work as well,

A = {{a x, b x^2}, {c y x^2, d y^2}};

{{0,b x^2},{c x^2 y,0}}


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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