Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have made this function which outputs the equation of a nth degree polynomial:

polynomial[degree_] := (
  result = 0;
  For[count = 1,
        count <= degree,
        result +=
    ToExpression[FromCharacterCode[96 + count]]*x^(degree - count);
        count++;
    ];
  result)

This works fine until you set a variable named a. Now the a in the equation gets replaced by the new value of a.

How can I stop this from happening so that polynomial[1] always would result in a and not the value of a even if it is defined.

I would prefer the output of polynomial to be an expression and not a string and a would also prefer not to clear the variables.

Example:

polynomial[1] (* == a *)

a = 2;
polynomial[1] (* == 2 *)
fixedPolynomial[1] (* == a *)
share|improve this question
    
Do you want to use the polynomials produced for computations or is it just their visual form you are interested in ? –  image_doctor Dec 6 '12 at 11:32

4 Answers 4

up vote 5 down vote accepted

Introduction

Questions like this one often suggests that it is not clear how Mathematica works and that it always tries to evaluate expressions. Assume the following simple example

a = 1;
a + a
a*x + 1

In the first line I set a to 1 and in the other two I write down an expression. Now I want that in a+a the result is 2 like one would expect, but in the a*x+1 line I want that a stays unevaluated. How should Mathematica know that? It always evaluates your expressions if you write it down.

Changing this behavior is not as obvious as it might seem in the first place. It is called non-standard evaluation in Mathematica and for a novice programmer this might be confusion. You style of code suggests that you maybe come from an iterative programming language and that you not have used Mathematica for long.

First let me point out, that your loop-construct can simply be written as Sum

Clear[a];
Sum[ToExpression[FromCharacterCode[96 + count]]*x^(5 - count), {count, 5}]

(* e + d x + c x^2 + b x^3 + a x^4 *)

I will use this in my code below.

Solution

My first example showed you, that you can never have an expression like a+a which stays that way when a has a value, but we can use HoldForm[a+a] to make it look like that. HoldForm is only one of the functions in the Hold family.

First lets create your list of parameters. If you replace ToExpression with MakeExpression every parameter is wrapped in HoldComplete which prevents evaluation

Table[MakeExpression[FromCharacterCode[96+count]],{count,5}]
(*  
 {HoldComplete[a],HoldComplete[b],HoldComplete[c],
 HoldComplete[d],HoldComplete[e]}
*)

Now we create your polynomial using this list of parameters and we simply replace HoldComplete with HoldForm. This prevents the parameters from evaluation and show them as like they would have no value

fixedPolynomial[degree_] := With[
 {parameters = Table[MakeExpression[FromCharacterCode[96 + count]], {count, degree}]},
 Sum[ HoldForm @@ parameters[[count]]*x^(degree - count), {count, 1, degree}]
]

Now you always get an unevaluated form

a=1;
b=2;
c=3;
poly=fixedPolynomial[5]
(* x^4 a+x^3 b+x^2 c+x d+e *)

Although you should always be aware of, that it is only displayed as it would be a, b, etc. In truth, it is wrapped:

InputForm[poly]
(* x^4*HoldForm[a] + x^3*HoldForm[b] + x^2*HoldForm[c] + x*HoldForm[d] + HoldForm[e] *)
share|improve this answer

The implementation of your function polynomial can be made simpler. But for your question, The problem (as I said in the little comment above) is in evaluation of your "a" to the Symbol a which is global and has value.

Better to use a method like shown by Bill above and other ways to avoid these sorts of things in first place.

You can see the problem easily:

ToExpression@FromCharacterCode[97]
Out[1]= a

a = 1;
ToExpression[FromCharacterCode[97]]
Out[3]= 1

But to do what you want, you can use the third option of ToExpression using HoldForm. But notice that the resulting polynomial will have HoldForm in it, so it can't be used as is for computation.

ClearAll[polynomial]
polynomial[degree_, x_Symbol] := Module[{count, p, result = 0},

  For[count = 1, count <= degree, count++,

   p = ToExpression[FromCharacterCode[96 + count], InputForm, HoldForm];
   result += p*x^(degree - count)

   ];

  result
  ]

now

a=1;
polynomial[#, x] & /@ Range[5]

gives

enter image description here

But again, this is just using HoldForm in it. Only for display.

share|improve this answer

Here's an alternative way to define the polynomials:

 poly[n_] := Total[Array[a, n] Flatten[x^{Range[n] - 1}]]

Instead of using a,b,c as variables, it uses a[1], a[2], etc. This has the advantage that is works for any n (the original stops working around 26 or 27 because of the character string).

share|improve this answer

Strings

In addition to HoldForm, you may wish to know that strings themselves can be used where you need an inert object, and in output they even appear as symbols.

Mathematica graphics

The a in the output line is still a string, but by default string delimiters are not printed in output.

Because of this you could simply leave out the ToExpression part of your code to avoid evaluation you do not want. Using halirutan's Sum:

poly1[degree_] := 
  Sum[FromCharacterCode[96 + i]*"x"^(degree - i), {i, degree}]

{a, b, c} = {1, 2, 3};

poly1[6]

Mathematica graphics

Formal Symbols

Formal Symbols exist specifically for cases like this. They all have the Attribute Protected so that they cannot have global values assigned. Formal Symbols are entered Esc$xEsc where x is an upper or lower case letter (a-z, A-Z).

This is the method I recommend unless you can't stand the appearance of the dots in the Formal Symbols, in which case you will need to fall back to Strings or HoldForm.

poly2[degree_] := 
  Sum[ToExpression @ FromCharacterCode[63487 + i] * \[FormalX]^(degree - i), {i, degree}]

poly2[6]

Mathematica graphics

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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