3
$\begingroup$

I have a module that computes a very long expression. I need to count the number of terms in the expression and how many are preceded by a minus sign.

Example: in a + bc - e + df - gh we have 5 terms and two are preceded by a minus sign.

I was looking at the Cases command but I could not find any similar examples.

$\endgroup$

4 Answers 4

4
$\begingroup$

Generalizing a bit to expressions whose coefficients are not just ±1, one has the following:

expr = a + bc - 2 e + 3 df - gh;
Length@expr
Count[expr, _?Internal`SyntacticNegativeQ]
(*
  5
  2
*)

Count[expr, _?Negative * Optional[__]]
(*  2  *)

They are not strictly equivalent. Internal`SyntacticNegativeQ is true if the term is typeset with a minus sign. The following shows the difference:

expr2 = Cos[1] x y + Cos[3] y;
Count[expr2, _?Negative * Optional[__]]
Count[expr2, _?Internal`SyntacticNegativeQ]
(*
  1
  0
*)

The use of Optional[__] is in case there is a term that is simply a number and not a product of a number and an expression (note that y-x is Plus[Times[-1, x], y] internally):

expr3 = expr - 3
Count[expr3, _?Negative*Optional[__]]
Count[expr3, _?Internal`SyntacticNegativeQ]
(*
  -3 + a + bc + 3 df - 2 e - gh
  3
  3
*)
$\endgroup$
6
$\begingroup$

If your expression is a sum, as in your example, you can do the following:

expr = a + bc - e + df - gh

make a list:

lexpr = List @@ expr

Count the expressions with a preceding minus sign

Count[lexpr, -x_]
(* 2 *)
$\endgroup$
3
$\begingroup$
expr = a + bc - 2 e + 3 df - gh + Sin[ij] - Cos[klm];

neg = Length @ Select[CoefficientRules @ expr, #[[2]] < 0 &]
pos = Length @ expr - neg

3

4

$\endgroup$
1
$\begingroup$
expr = a + bc - e + df - gh
If[StringMatchQ[ToString@#, "-" ~~ ___], "-", "+"] & /@ 
  List @@ expr // Tally

{{"+", 3}, {"-", 2}}

note this breaks if you have ratios within terms, eg expr = a - b/c the -b/c becomes Times[-1, b, Power[c, -1]] and appears to not have a lead -. Some of the other answers have the same issue, ( I didn't try all.. )

$\endgroup$

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.