Specifying variable in CoefficientRules

I am trying to determine the number of terms in an expression, but I have created a matrix to represent variables:

xMat = Table[sGain[[i, 1]] + 4, {i, 1, 3}]


Where sGain is my representative variable. I need to count the number of terms at each position in xMat, but using

Table[CoefficientRules[xMat[[i]]], {i, 1, 3}]


it uses sGain as a coefficient and doesn't count the 1/sGain part as a term. In functions like Solve I can specify the variable. Is there some way to do that here?

• Can you give us sGain, or at least a way to generate something similar? – aardvark2012 Sep 11 '17 at 0:24
• You could say sGain is a zero matrix (actually for what I provided just an array), but sGain[[1,1]]=s, where s is a variable. I'm trying to avoid allowing Mathematica to factor future expressions involving xMat. – Haff Sep 11 '17 at 17:21
• To clarify further, I want the output to be: {{{-1}->1,{0}->4},{{-1}->1,{0}->4},{{-1}->1,{0}->4}} so that I can see the coefficients of all the terms. – Haff Sep 12 '17 at 0:25

If I can be a bit more general: Suppose you've got an expression of the form

expr = Array[a, 5, -2].Array[s^# &, 5, -2]


$$\frac{a(-2)}{s^2} + \frac{a(-1)}{s} + a(1) s+a(0)+a(2) s^2$$

Then CoefficentRules will fail since it only works on polynomials (ie, no negative powers). You could mess around to try and use CoefficientRules, but it would probably be easier to use Exponent and Coefficient.

Exponent[expr, s, List]

(* {-2, -1, 0, 1, 2} *)


gives a list of the powers of s in expr, and

Coefficient[expr, s, #] & /@ Exponent[expr, s, List]

(* {a[-2], a[-1], a[0], a[1], a[2]} *)


gives the coefficients for each of those powers. If you want the same output you'd get from CoefficientRules you can use

{#} -> Coefficient[expr, s, #] & /@ Exponent[expr, s, List]

(* {{-2} -> a[-2], {-1} -> a[-1], {0} -> a[0], {1} -> a[1], {2} -> a[2]} *)


You can put this in a function as

npCoefficientRules[nonpoly_, var_] :=
{#} -> Coefficient[nonpoly, var, #] & /@ Exponent[nonpoly, var, List]


(Note that this won't work as is if you have more than one variable, say s and t.)

If your expressions only involve negative powers of s, then you could use CoefficientRules by specifying the variable as s^-1. Or if you have positive and negative powers you could multiply through by some power of s. But they both seem like horrible options to me:

sGain = ConstantArray[1/s, 3];
xMat = Table[sGain[[i]] + 4, {i, 1, 3}];
Table[CoefficientRules[xMat[[i]], s^-1], {i, 1, 3}]
Table[CoefficientRules[s xMat[[i]], s], {i, 1, 3}]

(* {{{1} -> 1, {0} -> 4}, {{1} -> 1, {0} -> 4}, {{1} -> 1, {0} -> 4}}
{{{1} -> 4, {0} -> 1}, {{1} -> 4, {0} -> 1}, {{1} -> 4, {0} -> 1}} *)


With npCoefficientRules

npCoefficientRules[#, s] & /@ xMat

(* {{{-1} -> 1, {0} -> 4}, {{-1} -> 1, {0} -> 4}, {{-1} -> 1, {0} -> 4}} *)


For a little extra convenience, you can make npCoefficientRules Listable

SetAttributes[npCoefficientRules, Listable];


Then

npCoefficientRules[xMat, s]


returns the same thing.

(If you are in fact "trying to determine the number of terms in an expression", you could just use Length; Length /@ xMat returns {2, 2, 2}. You'd have to be careful about how your expressions are represented, but Collect or Simplify should help there.)

• Thanks, this is useful. I did try using a combination of Collect and CoefficientRules, but I am unable to determine the order which I will not know. Your function solves the issue, though. – Haff Sep 13 '17 at 2:07
• @Haff Glad it helped. Don't forget you can upvote answers and accept an answer if you feel it has adequately answered your question. That's not a hint -- you are welcome to leave your question open if you're looking for a better answer. But look here for more info. – aardvark2012 Sep 13 '17 at 2:52
• Thanks for the tip, yesterday it would not let me. Looks like StackExchange recognizes me as not a machine now. – Haff Sep 13 '17 at 22:37