0
$\begingroup$

I am learning mathematica, and I am stuck at the point where I want to pass an unevaluated expression (a polynomial) to a function and work with that expression / polynomial inside the function. For simplification reason, assume the following setup, which should give me the coefficients of the polynomial:

SetAttributes[myCoef, HoldAll]
myCoef[exp_] := CoefficientList[exp, Variables[exp]]

This works fine for the following call:

p = myCoef[5*x^3 + 4*x^2 + 3]
(* Returns {3, 0, 4, 5} *)

The problem is, when I set x on the global scope:

x = 5
p = myCoef[5*x^3 + 4*x^2 + 3]
(* Returns 728 *)

How can I prevent the evaluation of 5*x^3 + 4*x^2 + 3 to 728? What would I have to change in myCoef to make it work, even if x is defined globally?

$\endgroup$
11
  • $\begingroup$ You could use \[FormalX] (and similar) or maybe use pure functions as in myCoef[5*#^3 + 4*#^2 + 3]. $\endgroup$ May 25, 2017 at 14:56
  • 1
    $\begingroup$ SetAttributes[newPoly, HoldAll] should probably have myCoef rather than newPoly? $\endgroup$
    – jjc385
    May 25, 2017 at 17:24
  • $\begingroup$ Oh yes, that was just a typo when I wrote the example, for sure it is myCoef, I edit it. $\endgroup$ May 25, 2017 at 18:24
  • 1
    $\begingroup$ Weird. For me it returns {0,1} which I just glossed over as being the right answer, but obviously it's a) wrong, b) in the correct form for an answer from CoefficientList. Obviously my suggestion wasn't correct, but I'm curious why it's giving two different answers. What version are you using? $\endgroup$
    – N.J.Evans
    May 25, 2017 at 18:38
  • 1
    $\begingroup$ @N.J.Evans OK, I'm now getting the same output as you -- {0,1}. Somehow I'd replaced HoldForm with something that looked the same but contained non-printing characters -- its FullForm was HoldFor\:200c\:200bm. Weird, but explains why what looked like HoldForm showed up in blue rather than black. $\endgroup$
    – jjc385
    May 25, 2017 at 22:58

1 Answer 1

2
$\begingroup$

Of course, the simplest solution is to make sure you haven't defined the variables you're using in your polynomials, but there are other ways to go.

You could wrap the code in Module or Block :

Block[{x},
 myCoef[5*x^3 + 4*x^2 + 3]
 ]
{3, 0, 4, 5}

If you wanted to, you could build this into myCoef by adding a second argument :

myCoef[exp_, varsToBlock_List] :=
 Block[varsToBlock,
  CoefficientList[exp, Variables[exp]]
  ]

x=2;
myCoef[5*x^3 + 4*x^2 + 3, {x}]
{3, 0, 4, 5}

Note that the original form of myCoef still works for a variable that doesn't have a definition:

myCoef[5*y^3 + 4*y^2 + 3]
{3, 0, 4, 5}

Of course, it would be nice to solve the problem without having to explicitly specify the variables which need to be held. I'm unsure how to do this, but perhaps someone else will come up with a solution.

$\endgroup$
2
  • $\begingroup$ That's a nice solution! I will try this one when I come home, thanks! :) $\endgroup$ May 25, 2017 at 18:25
  • $\begingroup$ I appreciate the accept, but I would strongly recommend waiting ~24 hours for others to submit solutions, particularly because I suspect a better solution is possible. $\endgroup$
    – jjc385
    May 25, 2017 at 18:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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