# Selecting terms from a matrix

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] &];


## 5 Answers

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}]

• (it should be fine now, I forgot the HoldPattern. Please let me know if it isn't) – Pinguin Dirk Sep 18 '13 at 14:07
• +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}]. – Leonid Shifrin Sep 18 '13 at 14:40
• 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 – Pinguin Dirk Sep 18 '13 at 14:45
• No problem at all. This is a minor issue anyway. – Leonid Shifrin Sep 18 '13 at 14:48
• To work for more than Times you can use Replace[m, a_ /; FreeQ[a, x^2] -> 0, {2}] – 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:

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

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


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

• 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}] – Mr.Wizard Sep 18 '13 at 19:47
• @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 – Kuba Sep 18 '13 at 19:55
• 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. – 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}}