# How to apply a transformation rule to integer coefficients without affecting integer exponents?

When working with finite fields, I often want to apply some transformation rules to the integers that appear either as coefficients in expressions. This becomes a problem when the transformation also gets applied to integral exponents.

As a simple example, suppose that I want to transform all the integer coefficients using the rule

n_Integer -> Mod[n + 2, 5] - 2


If I apply this rule to 13 x^3, both the coefficient and the exponent get transformed, so the result I get is

-(2/x^2)

...instead of the desired

-2*x^3

I've tried so many approaches, I can't list them all. Here's one example. This works for simple cases:

13 x^3
/. {Power[x, n_Integer] :> Power[x, ToString[n]]}
/. {n_Integer -> Mod[n + 2, 5] - 2}
/. {x_String -> ToExpression[x]}


-2*x^3

In general, however, I'd end up with expressions like

-2 x^(1 + "3")


...that would be impervious to the x_String -> ToExpression[x] transformation. (WHY?????)

Therefore I need a way to protect the exponents from transformation that can be more reliably reversed than converting them to strings.

Either that, or some other approach altogether, to transform the coefficients without transforming the exponents.

(FWIW, the "coefficient" corresponding to the constant term in a polynomial expression often does not belong to a Times expression.)

EDIT: OK, I found that changing the last transformation to {x_String :> ToExpression[x]} solves the problem (though I don't really understand why this delay is needed). Still, this solution strikes me as too-desperate a hack; there has to be better ways to solve this problem, so I'll let the question stand.

• I'd use PolynomialMod for this. – Daniel Lichtblau Feb 25 '18 at 21:02

When you want to do replacements with a pattern that shouldn't be changed, I like to use multiple replacement rules. In your example:

ReplaceAll[
13 x^3,
{
p_Power :> p, (* pattern to avoid *)
n_Integer :> Mod[n+2, 5] - 2
}
]


-2 x^3

 16 + 13 x^3 + 22 x^5 y^3 /. n_Integer rest_. :> (Mod[n + 2, 5] - 2) rest


1 - 2 x^3 + 2 x^5 y^3

You need to develop your pattern. See the Patterns and Transformation Rules tutorial.

For a single variable

13 x^3 /. n_Integer p_Power :> (Mod[n + 2, 5] - 2) p

-2 x^3


For multiple variables

13 x^3 y^4 /. n_Integer (p : _Power ..) :> (Mod[n + 2, 5] - 2) p

-2 x^3 y^4


Hope this helps.

• This does not work for constant terms and constants times x. For example, try 13 + 13 x + 13 x^3 – Bob Hanlon Feb 25 '18 at 19:19
• @BobHanlon kglr posted the generalized answer before I updated. I was answered to OP example. – Edmund Feb 25 '18 at 20:10

Note that Mod[n + 2, 5] - 2 is the same as Mod[n, 5, -2].

This performs algebraically the transformation you seem to be seeking:

modForm[p_, x_, m_, d_] :=
x^Range[0, Length[#] - 1].# &@ Mod[CoefficientList[p, x], m, d]

p = (1 - 3 x^5) (2 - x^3)^2;
p // Expand
modForm[p, x, 5, -2]
(*
4 - 4 x^3 - 12 x^5 + x^6 + 12 x^8 - 3 x^11
-1 +   x^3 -  2 x^5 + x^6 +  2 x^8 + 2 x^11
*)